Blame view

drivers/ata/pata_serverworks.c 14.2 KB
669a5db41   Jeff Garzik   [libata] Add a bu...
1
  /*
a0fcdc025   Jeff Garzik   [libata] Update s...
2
   * pata_serverworks.c 	- Serverworks PATA for new ATA layer
669a5db41   Jeff Garzik   [libata] Add a bu...
3
   *			  (C) 2005 Red Hat Inc
669a5db41   Jeff Garzik   [libata] Add a bu...
4
5
6
7
   *
   * based upon
   *
   * serverworks.c
85cd7251b   Jeff Garzik   [libata #pata-dri...
8
   *
669a5db41   Jeff Garzik   [libata] Add a bu...
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
   * Copyright (C) 1998-2000 Michel Aubry
   * Copyright (C) 1998-2000 Andrzej Krzysztofowicz
   * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
   * Portions copyright (c) 2001 Sun Microsystems
   *
   *
   * RCC/ServerWorks IDE driver for Linux
   *
   *   OSB4: `Open South Bridge' IDE Interface (fn 1)
   *         supports UDMA mode 2 (33 MB/s)
   *
   *   CSB5: `Champion South Bridge' IDE Interface (fn 1)
   *         all revisions support UDMA mode 4 (66 MB/s)
   *         revision A2.0 and up support UDMA mode 5 (100 MB/s)
   *
   *         *** The CSB5 does not provide ANY register ***
   *         *** to detect 80-conductor cable presence. ***
   *
   *   CSB6: `Champion South Bridge' IDE Interface (optional: third channel)
   *
   * Documentation:
   *	Available under NDA only. Errata info very hard to get.
   */
  
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/pci.h>
  #include <linux/init.h>
  #include <linux/blkdev.h>
  #include <linux/delay.h>
  #include <scsi/scsi_host.h>
  #include <linux/libata.h>
  
  #define DRV_NAME "pata_serverworks"
0f069788c   Alan Cox   pata_serverworks:...
43
  #define DRV_VERSION "0.4.3"
669a5db41   Jeff Garzik   [libata] Add a bu...
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
  
  #define SVWKS_CSB5_REVISION_NEW	0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */
  #define SVWKS_CSB6_REVISION	0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */
  
  /* Seagate Barracuda ATA IV Family drives in UDMA mode 5
   * can overrun their FIFOs when used with the CSB5 */
  
  static const char *csb_bad_ata100[] = {
  	"ST320011A",
  	"ST340016A",
  	"ST360021A",
  	"ST380021A",
  	NULL
  };
  
  /**
   *	dell_cable	-	Dell serverworks cable detection
   *	@ap: ATA port to do cable detect
   *
   *	Dell hide the 40/80 pin select for their interfaces in the top two
85cd7251b   Jeff Garzik   [libata #pata-dri...
64
   *	bits of the subsystem ID.
669a5db41   Jeff Garzik   [libata] Add a bu...
65
   */
85cd7251b   Jeff Garzik   [libata #pata-dri...
66

669a5db41   Jeff Garzik   [libata] Add a bu...
67
68
  static int dell_cable(struct ata_port *ap) {
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
85cd7251b   Jeff Garzik   [libata #pata-dri...
69

669a5db41   Jeff Garzik   [libata] Add a bu...
70
71
72
73
74
75
76
77
78
79
80
81
82
  	if (pdev->subsystem_device & (1 << (ap->port_no + 14)))
  		return ATA_CBL_PATA80;
  	return ATA_CBL_PATA40;
  }
  
  /**
   *	sun_cable	-	Sun Cobalt 'Alpine' cable detection
   *	@ap: ATA port to do cable select
   *
   *	Cobalt CSB5 IDE hides the 40/80pin in the top two bits of the
   *	subsystem ID the same as dell. We could use one function but we may
   *	need to extend the Dell one in future
   */
85cd7251b   Jeff Garzik   [libata #pata-dri...
83

669a5db41   Jeff Garzik   [libata] Add a bu...
84
85
  static int sun_cable(struct ata_port *ap) {
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
85cd7251b   Jeff Garzik   [libata #pata-dri...
86

669a5db41   Jeff Garzik   [libata] Add a bu...
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
  	if (pdev->subsystem_device & (1 << (ap->port_no + 14)))
  		return ATA_CBL_PATA80;
  	return ATA_CBL_PATA40;
  }
  
  /**
   *	osb4_cable	-	OSB4 cable detect
   *	@ap: ATA port to check
   *
   *	The OSB4 isn't UDMA66 capable so this is easy
   */
  
  static int osb4_cable(struct ata_port *ap) {
  	return ATA_CBL_PATA40;
  }
  
  /**
0f069788c   Alan Cox   pata_serverworks:...
104
   *	csb_cable	-	CSB5/6 cable detect
669a5db41   Jeff Garzik   [libata] Add a bu...
105
106
107
108
109
110
111
   *	@ap: ATA port to check
   *
   *	Serverworks default arrangement is to use the drive side detection
   *	only.
   */
  
  static int csb_cable(struct ata_port *ap) {
0f069788c   Alan Cox   pata_serverworks:...
112
  	return ATA_CBL_PATA_UNK;
669a5db41   Jeff Garzik   [libata] Add a bu...
113
114
115
116
117
118
119
120
121
122
123
124
  }
  
  struct sv_cable_table {
  	int device;
  	int subvendor;
  	int (*cable_detect)(struct ata_port *ap);
  };
  
  /*
   *	Note that we don't copy the old serverworks code because the old
   *	code contains obvious mistakes
   */
85cd7251b   Jeff Garzik   [libata #pata-dri...
125

669a5db41   Jeff Garzik   [libata] Add a bu...
126
127
128
129
  static struct sv_cable_table cable_detect[] = {
  	{ PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_VENDOR_ID_DELL, dell_cable },
  	{ PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_VENDOR_ID_DELL, dell_cable },
  	{ PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_VENDOR_ID_SUN,  sun_cable },
68d0d7abc   Alan Cox   [PATCH] pata_serv...
130
  	{ PCI_DEVICE_ID_SERVERWORKS_OSB4IDE, PCI_ANY_ID, osb4_cable },
669a5db41   Jeff Garzik   [libata] Add a bu...
131
132
133
134
135
136
137
138
  	{ PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_ANY_ID, csb_cable },
  	{ PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_ANY_ID, csb_cable },
  	{ PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2, PCI_ANY_ID, csb_cable },
  	{ PCI_DEVICE_ID_SERVERWORKS_HT1000IDE, PCI_ANY_ID, csb_cable },
  	{ }
  };
  
  /**
a0fcdc025   Jeff Garzik   [libata] Update s...
139
   *	serverworks_cable_detect	-	cable detection
669a5db41   Jeff Garzik   [libata] Add a bu...
140
141
   *	@ap: ATA port
   *
85cd7251b   Jeff Garzik   [libata #pata-dri...
142
   *	Perform cable detection according to the device and subvendor
669a5db41   Jeff Garzik   [libata] Add a bu...
143
144
   *	identifications
   */
85cd7251b   Jeff Garzik   [libata #pata-dri...
145

d4b2bab4f   Tejun Heo   libata: add deadl...
146
147
  static int serverworks_cable_detect(struct ata_port *ap)
  {
669a5db41   Jeff Garzik   [libata] Add a bu...
148
149
150
151
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
  	struct sv_cable_table *cb = cable_detect;
  
  	while(cb->device) {
85cd7251b   Jeff Garzik   [libata #pata-dri...
152
  		if (cb->device == pdev->device &&
669a5db41   Jeff Garzik   [libata] Add a bu...
153
154
  		    (cb->subvendor == pdev->subsystem_vendor ||
  		      cb->subvendor == PCI_ANY_ID)) {
a0fcdc025   Jeff Garzik   [libata] Update s...
155
  			return cb->cable_detect(ap);
669a5db41   Jeff Garzik   [libata] Add a bu...
156
157
158
159
160
161
162
  		}
  		cb++;
  	}
  
  	BUG();
  	return -1;	/* kill compiler warning */
  }
669a5db41   Jeff Garzik   [libata] Add a bu...
163
164
165
166
167
168
169
  /**
   *	serverworks_is_csb	-	Check for CSB or OSB
   *	@pdev: PCI device to check
   *
   *	Returns true if the device being checked is known to be a CSB
   *	series device.
   */
85cd7251b   Jeff Garzik   [libata #pata-dri...
170

669a5db41   Jeff Garzik   [libata] Add a bu...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
  static u8 serverworks_is_csb(struct pci_dev *pdev)
  {
  	switch (pdev->device) {
  		case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
  		case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE:
  		case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2:
  		case PCI_DEVICE_ID_SERVERWORKS_HT1000IDE:
  			return 1;
  		default:
  			break;
  	}
  	return 0;
  }
  
  /**
   *	serverworks_osb4_filter	-	mode selection filter
669a5db41   Jeff Garzik   [libata] Add a bu...
187
   *	@adev: ATA device
a76b62ca7   Alan Cox   libata: Change pr...
188
   *	@mask: Mask of proposed modes
669a5db41   Jeff Garzik   [libata] Add a bu...
189
190
191
192
193
   *
   *	Filter the offered modes for the device to apply controller
   *	specific rules. OSB4 requires no UDMA for disks due to a FIFO
   *	bug we hit.
   */
85cd7251b   Jeff Garzik   [libata #pata-dri...
194

a76b62ca7   Alan Cox   libata: Change pr...
195
  static unsigned long serverworks_osb4_filter(struct ata_device *adev, unsigned long mask)
669a5db41   Jeff Garzik   [libata] Add a bu...
196
197
198
  {
  	if (adev->class == ATA_DEV_ATA)
  		mask &= ~ATA_MASK_UDMA;
9363c3825   Tejun Heo   libata: rename SF...
199
  	return ata_bmdma_mode_filter(adev, mask);
669a5db41   Jeff Garzik   [libata] Add a bu...
200
201
202
203
204
  }
  
  
  /**
   *	serverworks_csb_filter	-	mode selection filter
669a5db41   Jeff Garzik   [libata] Add a bu...
205
   *	@adev: ATA device
a76b62ca7   Alan Cox   libata: Change pr...
206
   *	@mask: Mask of proposed modes
669a5db41   Jeff Garzik   [libata] Add a bu...
207
208
209
   *
   *	Check the blacklist and disable UDMA5 if matched
   */
a76b62ca7   Alan Cox   libata: Change pr...
210
  static unsigned long serverworks_csb_filter(struct ata_device *adev, unsigned long mask)
669a5db41   Jeff Garzik   [libata] Add a bu...
211
212
  {
  	const char *p;
8bfa79fcb   Tejun Heo   libata: use ata_i...
213
214
  	char model_num[ATA_ID_PROD_LEN + 1];
  	int i;
669a5db41   Jeff Garzik   [libata] Add a bu...
215

85cd7251b   Jeff Garzik   [libata #pata-dri...
216
  	/* Disk, UDMA */
669a5db41   Jeff Garzik   [libata] Add a bu...
217
  	if (adev->class != ATA_DEV_ATA)
9363c3825   Tejun Heo   libata: rename SF...
218
  		return ata_bmdma_mode_filter(adev, mask);
669a5db41   Jeff Garzik   [libata] Add a bu...
219
220
  
  	/* Actually do need to check */
8bfa79fcb   Tejun Heo   libata: use ata_i...
221
  	ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num));
85cd7251b   Jeff Garzik   [libata #pata-dri...
222

8bfa79fcb   Tejun Heo   libata: use ata_i...
223
224
  	for (i = 0; (p = csb_bad_ata100[i]) != NULL; i++) {
  		if (!strcmp(p, model_num))
6ddd68615   Alan Cox   pata_hpt*, pata_s...
225
  			mask &= ~(0xE0 << ATA_SHIFT_UDMA);
669a5db41   Jeff Garzik   [libata] Add a bu...
226
  	}
9363c3825   Tejun Heo   libata: rename SF...
227
  	return ata_bmdma_mode_filter(adev, mask);
669a5db41   Jeff Garzik   [libata] Add a bu...
228
  }
669a5db41   Jeff Garzik   [libata] Add a bu...
229
230
231
232
233
234
235
236
237
238
239
  /**
   *	serverworks_set_piomode	-	set initial PIO mode data
   *	@ap: ATA interface
   *	@adev: ATA device
   *
   *	Program the OSB4/CSB5 timing registers for PIO. The PIO register
   *	load is done as a simple lookup.
   */
  static void serverworks_set_piomode(struct ata_port *ap, struct ata_device *adev)
  {
  	static const u8 pio_mode[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 };
0f069788c   Alan Cox   pata_serverworks:...
240
  	int offset = 1 + 2 * ap->port_no - adev->devno;
669a5db41   Jeff Garzik   [libata] Add a bu...
241
242
243
244
245
246
  	int devbits = (2 * ap->port_no + adev->devno) * 4;
  	u16 csb5_pio;
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
  	int pio = adev->pio_mode - XFER_PIO_0;
  
  	pci_write_config_byte(pdev, 0x40 + offset, pio_mode[pio]);
85cd7251b   Jeff Garzik   [libata #pata-dri...
247

669a5db41   Jeff Garzik   [libata] Add a bu...
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
  	/* The OSB4 just requires the timing but the CSB series want the
  	   mode number as well */
  	if (serverworks_is_csb(pdev)) {
  		pci_read_config_word(pdev, 0x4A, &csb5_pio);
  		csb5_pio &= ~(0x0F << devbits);
  		pci_write_config_byte(pdev, 0x4A, csb5_pio | (pio << devbits));
  	}
  }
  
  /**
   *	serverworks_set_dmamode	-	set initial DMA mode data
   *	@ap: ATA interface
   *	@adev: ATA device
   *
   *	Program the MWDMA/UDMA modes for the serverworks OSB4/CSB5
   *	chipset. The MWDMA mode values are pulled from a lookup table
   *	while the chipset uses mode number for UDMA.
   */
  
  static void serverworks_set_dmamode(struct ata_port *ap, struct ata_device *adev)
  {
  	static const u8 dma_mode[] = { 0x77, 0x21, 0x20 };
  	int offset = 1 + 2 * ap->port_no - adev->devno;
36beb8239   Alan Cox   pata_serverworks:...
271
  	int devbits = 2 * ap->port_no + adev->devno;
669a5db41   Jeff Garzik   [libata] Add a bu...
272
273
274
275
276
  	u8 ultra;
  	u8 ultra_cfg;
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
  
  	pci_read_config_byte(pdev, 0x54, &ultra_cfg);
36beb8239   Alan Cox   pata_serverworks:...
277
278
  	pci_read_config_byte(pdev, 0x56 + ap->port_no, &ultra);
  	ultra &= ~(0x0F << (adev->devno * 4));
669a5db41   Jeff Garzik   [libata] Add a bu...
279
280
281
  
  	if (adev->dma_mode >= XFER_UDMA_0) {
  		pci_write_config_byte(pdev, 0x44 + offset,  0x20);
669a5db41   Jeff Garzik   [libata] Add a bu...
282
  		ultra |= (adev->dma_mode - XFER_UDMA_0)
36beb8239   Alan Cox   pata_serverworks:...
283
  					<< (adev->devno * 4);
669a5db41   Jeff Garzik   [libata] Add a bu...
284
285
  		ultra_cfg |=  (1 << devbits);
  	} else {
85cd7251b   Jeff Garzik   [libata #pata-dri...
286
  		pci_write_config_byte(pdev, 0x44 + offset,
669a5db41   Jeff Garzik   [libata] Add a bu...
287
288
289
  			dma_mode[adev->dma_mode - XFER_MW_DMA_0]);
  		ultra_cfg &= ~(1 << devbits);
  	}
36beb8239   Alan Cox   pata_serverworks:...
290
  	pci_write_config_byte(pdev, 0x56 + ap->port_no, ultra);
669a5db41   Jeff Garzik   [libata] Add a bu...
291
292
293
294
  	pci_write_config_byte(pdev, 0x54, ultra_cfg);
  }
  
  static struct scsi_host_template serverworks_sht = {
68d1d07b5   Tejun Heo   libata: implement...
295
  	ATA_BMDMA_SHT(DRV_NAME),
669a5db41   Jeff Garzik   [libata] Add a bu...
296
297
298
  };
  
  static struct ata_port_operations serverworks_osb4_port_ops = {
029cfd6b7   Tejun Heo   libata: implement...
299
300
301
  	.inherits	= &ata_bmdma_port_ops,
  	.cable_detect	= serverworks_cable_detect,
  	.mode_filter	= serverworks_osb4_filter,
669a5db41   Jeff Garzik   [libata] Add a bu...
302
303
  	.set_piomode	= serverworks_set_piomode,
  	.set_dmamode	= serverworks_set_dmamode,
85cd7251b   Jeff Garzik   [libata #pata-dri...
304
  };
669a5db41   Jeff Garzik   [libata] Add a bu...
305
306
  
  static struct ata_port_operations serverworks_csb_port_ops = {
029cfd6b7   Tejun Heo   libata: implement...
307
  	.inherits	= &serverworks_osb4_port_ops,
669a5db41   Jeff Garzik   [libata] Add a bu...
308
  	.mode_filter	= serverworks_csb_filter,
85cd7251b   Jeff Garzik   [libata #pata-dri...
309
  };
669a5db41   Jeff Garzik   [libata] Add a bu...
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
  
  static int serverworks_fixup_osb4(struct pci_dev *pdev)
  {
  	u32 reg;
  	struct pci_dev *isa_dev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
  		  PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL);
  	if (isa_dev) {
  		pci_read_config_dword(isa_dev, 0x64, &reg);
  		reg &= ~0x00002000; /* disable 600ns interrupt mask */
  		if (!(reg & 0x00004000))
  			printk(KERN_DEBUG DRV_NAME ": UDMA not BIOS enabled.
  ");
  		reg |=  0x00004000; /* enable UDMA/33 support */
  		pci_write_config_dword(isa_dev, 0x64, reg);
  		pci_dev_put(isa_dev);
  		return 0;
  	}
  	printk(KERN_WARNING "ata_serverworks: Unable to find bridge.
  ");
  	return -ENODEV;
  }
  
  static int serverworks_fixup_csb(struct pci_dev *pdev)
  {
669a5db41   Jeff Garzik   [libata] Add a bu...
334
  	u8 btr;
85cd7251b   Jeff Garzik   [libata #pata-dri...
335

669a5db41   Jeff Garzik   [libata] Add a bu...
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
  	/* Third Channel Test */
  	if (!(PCI_FUNC(pdev->devfn) & 1)) {
  		struct pci_dev * findev = NULL;
  		u32 reg4c = 0;
  		findev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
  			PCI_DEVICE_ID_SERVERWORKS_CSB5, NULL);
  		if (findev) {
  			pci_read_config_dword(findev, 0x4C, &reg4c);
  			reg4c &= ~0x000007FF;
  			reg4c |=  0x00000040;
  			reg4c |=  0x00000020;
  			pci_write_config_dword(findev, 0x4C, reg4c);
  			pci_dev_put(findev);
  		}
  	} else {
  		struct pci_dev * findev = NULL;
  		u8 reg41 = 0;
  
  		findev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
  				PCI_DEVICE_ID_SERVERWORKS_CSB6, NULL);
  		if (findev) {
  			pci_read_config_byte(findev, 0x41, &reg41);
  			reg41 &= ~0x40;
  			pci_write_config_byte(findev, 0x41, reg41);
  			pci_dev_put(findev);
  		}
  	}
  	/* setup the UDMA Control register
  	 *
  	 * 1. clear bit 6 to enable DMA
  	 * 2. enable DMA modes with bits 0-1
  	 * 	00 : legacy
  	 * 	01 : udma2
  	 * 	10 : udma2/udma4
  	 * 	11 : udma2/udma4/udma5
  	 */
  	pci_read_config_byte(pdev, 0x5A, &btr);
  	btr &= ~0x40;
  	if (!(PCI_FUNC(pdev->devfn) & 1))
  		btr |= 0x2;
  	else
44c10138f   Auke Kok   PCI: Change all d...
377
  		btr |= (pdev->revision >= SVWKS_CSB5_REVISION_NEW) ? 0x3 : 0x2;
669a5db41   Jeff Garzik   [libata] Add a bu...
378
  	pci_write_config_byte(pdev, 0x5A, btr);
85cd7251b   Jeff Garzik   [libata #pata-dri...
379

669a5db41   Jeff Garzik   [libata] Add a bu...
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
  	return btr;
  }
  
  static void serverworks_fixup_ht1000(struct pci_dev *pdev)
  {
  	u8 btr;
  	/* Setup HT1000 SouthBridge Controller - Single Channel Only */
  	pci_read_config_byte(pdev, 0x5A, &btr);
  	btr &= ~0x40;
  	btr |= 0x3;
  	pci_write_config_byte(pdev, 0x5A, btr);
  }
  
  
  static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
  {
1626aeb88   Tejun Heo   libata: clean up ...
396
  	static const struct ata_port_info info[4] = {
669a5db41   Jeff Garzik   [libata] Add a bu...
397
  		{ /* OSB4 */
1d2808fd3   Jeff Garzik   [libata] PATA dri...
398
  			.flags = ATA_FLAG_SLAVE_POSS,
14bdef982   Erik Inge Bolsø   [libata] convert ...
399
400
401
  			.pio_mask = ATA_PIO4,
  			.mwdma_mask = ATA_MWDMA2,
  			.udma_mask = ATA_UDMA2,
669a5db41   Jeff Garzik   [libata] Add a bu...
402
403
  			.port_ops = &serverworks_osb4_port_ops
  		}, { /* OSB4 no UDMA */
1d2808fd3   Jeff Garzik   [libata] PATA dri...
404
  			.flags = ATA_FLAG_SLAVE_POSS,
14bdef982   Erik Inge Bolsø   [libata] convert ...
405
406
407
  			.pio_mask = ATA_PIO4,
  			.mwdma_mask = ATA_MWDMA2,
  			/* No UDMA */
669a5db41   Jeff Garzik   [libata] Add a bu...
408
409
  			.port_ops = &serverworks_osb4_port_ops
  		}, { /* CSB5 */
1d2808fd3   Jeff Garzik   [libata] PATA dri...
410
  			.flags = ATA_FLAG_SLAVE_POSS,
14bdef982   Erik Inge Bolsø   [libata] convert ...
411
412
  			.pio_mask = ATA_PIO4,
  			.mwdma_mask = ATA_MWDMA2,
bf6263a85   Jeff Garzik   [libata] Use ATA_...
413
  			.udma_mask = ATA_UDMA4,
669a5db41   Jeff Garzik   [libata] Add a bu...
414
415
  			.port_ops = &serverworks_csb_port_ops
  		}, { /* CSB5 - later revisions*/
1d2808fd3   Jeff Garzik   [libata] PATA dri...
416
  			.flags = ATA_FLAG_SLAVE_POSS,
14bdef982   Erik Inge Bolsø   [libata] convert ...
417
418
  			.pio_mask = ATA_PIO4,
  			.mwdma_mask = ATA_MWDMA2,
bf6263a85   Jeff Garzik   [libata] Use ATA_...
419
  			.udma_mask = ATA_UDMA5,
669a5db41   Jeff Garzik   [libata] Add a bu...
420
421
422
  			.port_ops = &serverworks_csb_port_ops
  		}
  	};
1626aeb88   Tejun Heo   libata: clean up ...
423
  	const struct ata_port_info *ppi[] = { &info[id->driver_data], NULL };
f08048e94   Tejun Heo   libata: PCI devic...
424
425
426
427
428
  	int rc;
  
  	rc = pcim_enable_device(pdev);
  	if (rc)
  		return rc;
85cd7251b   Jeff Garzik   [libata #pata-dri...
429

669a5db41   Jeff Garzik   [libata] Add a bu...
430
431
432
433
434
435
436
  	/* Force master latency timer to 64 PCI clocks */
  	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
  
  	/* OSB4 : South Bridge and IDE */
  	if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
  		/* Select non UDMA capable OSB4 if we can't do fixups */
  		if ( serverworks_fixup_osb4(pdev) < 0)
1626aeb88   Tejun Heo   libata: clean up ...
437
  			ppi[0] = &info[1];
669a5db41   Jeff Garzik   [libata] Add a bu...
438
439
440
441
442
  	}
  	/* setup CSB5/CSB6 : South Bridge and IDE option RAID */
  	else if ((pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) ||
  		 (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
  		 (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) {
85cd7251b   Jeff Garzik   [libata #pata-dri...
443

669a5db41   Jeff Garzik   [libata] Add a bu...
444
445
446
  		 /* If the returned btr is the newer revision then
  		    select the right info block */
  		 if (serverworks_fixup_csb(pdev) == 3)
1626aeb88   Tejun Heo   libata: clean up ...
447
  		 	ppi[0] = &info[3];
85cd7251b   Jeff Garzik   [libata #pata-dri...
448

669a5db41   Jeff Garzik   [libata] Add a bu...
449
450
  		/* Is this the 3rd channel CSB6 IDE ? */
  		if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)
1626aeb88   Tejun Heo   libata: clean up ...
451
  			ppi[1] = &ata_dummy_port_info;
669a5db41   Jeff Garzik   [libata] Add a bu...
452
453
454
455
  	}
  	/* setup HT1000E */
  	else if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE)
  		serverworks_fixup_ht1000(pdev);
85cd7251b   Jeff Garzik   [libata #pata-dri...
456

669a5db41   Jeff Garzik   [libata] Add a bu...
457
  	if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
9363c3825   Tejun Heo   libata: rename SF...
458
  		ata_pci_bmdma_clear_simplex(pdev);
85cd7251b   Jeff Garzik   [libata #pata-dri...
459

9363c3825   Tejun Heo   libata: rename SF...
460
  	return ata_pci_sff_init_one(pdev, ppi, &serverworks_sht, NULL);
669a5db41   Jeff Garzik   [libata] Add a bu...
461
  }
438ac6d5e   Tejun Heo   libata: add missi...
462
  #ifdef CONFIG_PM
38e0d56e6   Alan Cox   [PATCH] pata_serv...
463
464
  static int serverworks_reinit_one(struct pci_dev *pdev)
  {
f08048e94   Tejun Heo   libata: PCI devic...
465
466
467
468
469
470
  	struct ata_host *host = dev_get_drvdata(&pdev->dev);
  	int rc;
  
  	rc = ata_pci_device_do_resume(pdev);
  	if (rc)
  		return rc;
38e0d56e6   Alan Cox   [PATCH] pata_serv...
471
472
  	/* Force master latency timer to 64 PCI clocks */
  	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
f20b16ff7   Jeff Garzik   [libata] trim tra...
473

f08048e94   Tejun Heo   libata: PCI devic...
474
  	switch (pdev->device) {
38e0d56e6   Alan Cox   [PATCH] pata_serv...
475
476
477
478
  		case PCI_DEVICE_ID_SERVERWORKS_OSB4IDE:
  			serverworks_fixup_osb4(pdev);
  			break;
  		case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
9363c3825   Tejun Heo   libata: rename SF...
479
  			ata_pci_bmdma_clear_simplex(pdev);
38e0d56e6   Alan Cox   [PATCH] pata_serv...
480
481
482
483
484
485
486
487
488
  			/* fall through */
  		case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE:
  		case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2:
  			serverworks_fixup_csb(pdev);
  			break;
  		case PCI_DEVICE_ID_SERVERWORKS_HT1000IDE:
  			serverworks_fixup_ht1000(pdev);
  			break;
  	}
f08048e94   Tejun Heo   libata: PCI devic...
489
490
491
  
  	ata_host_resume(host);
  	return 0;
38e0d56e6   Alan Cox   [PATCH] pata_serv...
492
  }
438ac6d5e   Tejun Heo   libata: add missi...
493
  #endif
38e0d56e6   Alan Cox   [PATCH] pata_serv...
494

2d2744fc8   Jeff Garzik   [libata] PCI ID t...
495
496
497
498
499
500
501
502
  static const struct pci_device_id serverworks[] = {
  	{ PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0},
  	{ PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE), 2},
  	{ PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE), 2},
  	{ PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2), 2},
  	{ PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE), 2},
  
  	{ },
669a5db41   Jeff Garzik   [libata] Add a bu...
503
504
505
506
507
508
  };
  
  static struct pci_driver serverworks_pci_driver = {
  	.name 		= DRV_NAME,
  	.id_table	= serverworks,
  	.probe 		= serverworks_init_one,
38e0d56e6   Alan Cox   [PATCH] pata_serv...
509
  	.remove		= ata_pci_remove_one,
438ac6d5e   Tejun Heo   libata: add missi...
510
  #ifdef CONFIG_PM
38e0d56e6   Alan Cox   [PATCH] pata_serv...
511
512
  	.suspend	= ata_pci_device_suspend,
  	.resume		= serverworks_reinit_one,
438ac6d5e   Tejun Heo   libata: add missi...
513
  #endif
669a5db41   Jeff Garzik   [libata] Add a bu...
514
515
516
517
518
519
  };
  
  static int __init serverworks_init(void)
  {
  	return pci_register_driver(&serverworks_pci_driver);
  }
669a5db41   Jeff Garzik   [libata] Add a bu...
520
521
522
523
  static void __exit serverworks_exit(void)
  {
  	pci_unregister_driver(&serverworks_pci_driver);
  }
669a5db41   Jeff Garzik   [libata] Add a bu...
524
525
526
527
528
529
530
531
  MODULE_AUTHOR("Alan Cox");
  MODULE_DESCRIPTION("low-level driver for Serverworks OSB4/CSB5/CSB6");
  MODULE_LICENSE("GPL");
  MODULE_DEVICE_TABLE(pci, serverworks);
  MODULE_VERSION(DRV_VERSION);
  
  module_init(serverworks_init);
  module_exit(serverworks_exit);