diff options
Diffstat (limited to 'drivers/ide/pdc202xx_new.c')
-rw-r--r-- | drivers/ide/pdc202xx_new.c | 588 |
1 files changed, 588 insertions, 0 deletions
diff --git a/drivers/ide/pdc202xx_new.c b/drivers/ide/pdc202xx_new.c new file mode 100644 index 000000000000..211ae46e3e0c --- /dev/null +++ b/drivers/ide/pdc202xx_new.c | |||
@@ -0,0 +1,588 @@ | |||
1 | /* | ||
2 | * Promise TX2/TX4/TX2000/133 IDE driver | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * Split from: | ||
10 | * linux/drivers/ide/pdc202xx.c Version 0.35 Mar. 30, 2002 | ||
11 | * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org> | ||
12 | * Copyright (C) 2005-2007 MontaVista Software, Inc. | ||
13 | * Portions Copyright (C) 1999 Promise Technology, Inc. | ||
14 | * Author: Frank Tiernan (frankt@promise.com) | ||
15 | * Released under terms of General Public License | ||
16 | */ | ||
17 | |||
18 | #include <linux/module.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/pci.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/ide.h> | ||
25 | |||
26 | #include <asm/io.h> | ||
27 | |||
28 | #ifdef CONFIG_PPC_PMAC | ||
29 | #include <asm/prom.h> | ||
30 | #include <asm/pci-bridge.h> | ||
31 | #endif | ||
32 | |||
33 | #define DRV_NAME "pdc202xx_new" | ||
34 | |||
35 | #undef DEBUG | ||
36 | |||
37 | #ifdef DEBUG | ||
38 | #define DBG(fmt, args...) printk("%s: " fmt, __func__, ## args) | ||
39 | #else | ||
40 | #define DBG(fmt, args...) | ||
41 | #endif | ||
42 | |||
43 | static const char *pdc_quirk_drives[] = { | ||
44 | "QUANTUM FIREBALLlct08 08", | ||
45 | "QUANTUM FIREBALLP KA6.4", | ||
46 | "QUANTUM FIREBALLP KA9.1", | ||
47 | "QUANTUM FIREBALLP LM20.4", | ||
48 | "QUANTUM FIREBALLP KX13.6", | ||
49 | "QUANTUM FIREBALLP KX20.5", | ||
50 | "QUANTUM FIREBALLP KX27.3", | ||
51 | "QUANTUM FIREBALLP LM20.5", | ||
52 | NULL | ||
53 | }; | ||
54 | |||
55 | static u8 max_dma_rate(struct pci_dev *pdev) | ||
56 | { | ||
57 | u8 mode; | ||
58 | |||
59 | switch(pdev->device) { | ||
60 | case PCI_DEVICE_ID_PROMISE_20277: | ||
61 | case PCI_DEVICE_ID_PROMISE_20276: | ||
62 | case PCI_DEVICE_ID_PROMISE_20275: | ||
63 | case PCI_DEVICE_ID_PROMISE_20271: | ||
64 | case PCI_DEVICE_ID_PROMISE_20269: | ||
65 | mode = 4; | ||
66 | break; | ||
67 | case PCI_DEVICE_ID_PROMISE_20270: | ||
68 | case PCI_DEVICE_ID_PROMISE_20268: | ||
69 | mode = 3; | ||
70 | break; | ||
71 | default: | ||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | return mode; | ||
76 | } | ||
77 | |||
78 | /** | ||
79 | * get_indexed_reg - Get indexed register | ||
80 | * @hwif: for the port address | ||
81 | * @index: index of the indexed register | ||
82 | */ | ||
83 | static u8 get_indexed_reg(ide_hwif_t *hwif, u8 index) | ||
84 | { | ||
85 | u8 value; | ||
86 | |||
87 | outb(index, hwif->dma_base + 1); | ||
88 | value = inb(hwif->dma_base + 3); | ||
89 | |||
90 | DBG("index[%02X] value[%02X]\n", index, value); | ||
91 | return value; | ||
92 | } | ||
93 | |||
94 | /** | ||
95 | * set_indexed_reg - Set indexed register | ||
96 | * @hwif: for the port address | ||
97 | * @index: index of the indexed register | ||
98 | */ | ||
99 | static void set_indexed_reg(ide_hwif_t *hwif, u8 index, u8 value) | ||
100 | { | ||
101 | outb(index, hwif->dma_base + 1); | ||
102 | outb(value, hwif->dma_base + 3); | ||
103 | DBG("index[%02X] value[%02X]\n", index, value); | ||
104 | } | ||
105 | |||
106 | /* | ||
107 | * ATA Timing Tables based on 133 MHz PLL output clock. | ||
108 | * | ||
109 | * If the PLL outputs 100 MHz clock, the ASIC hardware will set | ||
110 | * the timing registers automatically when "set features" command is | ||
111 | * issued to the device. However, if the PLL output clock is 133 MHz, | ||
112 | * the following tables must be used. | ||
113 | */ | ||
114 | static struct pio_timing { | ||
115 | u8 reg0c, reg0d, reg13; | ||
116 | } pio_timings [] = { | ||
117 | { 0xfb, 0x2b, 0xac }, /* PIO mode 0, IORDY off, Prefetch off */ | ||
118 | { 0x46, 0x29, 0xa4 }, /* PIO mode 1, IORDY off, Prefetch off */ | ||
119 | { 0x23, 0x26, 0x64 }, /* PIO mode 2, IORDY off, Prefetch off */ | ||
120 | { 0x27, 0x0d, 0x35 }, /* PIO mode 3, IORDY on, Prefetch off */ | ||
121 | { 0x23, 0x09, 0x25 }, /* PIO mode 4, IORDY on, Prefetch off */ | ||
122 | }; | ||
123 | |||
124 | static struct mwdma_timing { | ||
125 | u8 reg0e, reg0f; | ||
126 | } mwdma_timings [] = { | ||
127 | { 0xdf, 0x5f }, /* MWDMA mode 0 */ | ||
128 | { 0x6b, 0x27 }, /* MWDMA mode 1 */ | ||
129 | { 0x69, 0x25 }, /* MWDMA mode 2 */ | ||
130 | }; | ||
131 | |||
132 | static struct udma_timing { | ||
133 | u8 reg10, reg11, reg12; | ||
134 | } udma_timings [] = { | ||
135 | { 0x4a, 0x0f, 0xd5 }, /* UDMA mode 0 */ | ||
136 | { 0x3a, 0x0a, 0xd0 }, /* UDMA mode 1 */ | ||
137 | { 0x2a, 0x07, 0xcd }, /* UDMA mode 2 */ | ||
138 | { 0x1a, 0x05, 0xcd }, /* UDMA mode 3 */ | ||
139 | { 0x1a, 0x03, 0xcd }, /* UDMA mode 4 */ | ||
140 | { 0x1a, 0x02, 0xcb }, /* UDMA mode 5 */ | ||
141 | { 0x1a, 0x01, 0xcb }, /* UDMA mode 6 */ | ||
142 | }; | ||
143 | |||
144 | static void pdcnew_set_dma_mode(ide_drive_t *drive, const u8 speed) | ||
145 | { | ||
146 | ide_hwif_t *hwif = HWIF(drive); | ||
147 | struct pci_dev *dev = to_pci_dev(hwif->dev); | ||
148 | u8 adj = (drive->dn & 1) ? 0x08 : 0x00; | ||
149 | |||
150 | /* | ||
151 | * IDE core issues SETFEATURES_XFER to the drive first (thanks to | ||
152 | * IDE_HFLAG_POST_SET_MODE in ->host_flags). PDC202xx hardware will | ||
153 | * automatically set the timing registers based on 100 MHz PLL output. | ||
154 | * | ||
155 | * As we set up the PLL to output 133 MHz for UltraDMA/133 capable | ||
156 | * chips, we must override the default register settings... | ||
157 | */ | ||
158 | if (max_dma_rate(dev) == 4) { | ||
159 | u8 mode = speed & 0x07; | ||
160 | |||
161 | if (speed >= XFER_UDMA_0) { | ||
162 | set_indexed_reg(hwif, 0x10 + adj, | ||
163 | udma_timings[mode].reg10); | ||
164 | set_indexed_reg(hwif, 0x11 + adj, | ||
165 | udma_timings[mode].reg11); | ||
166 | set_indexed_reg(hwif, 0x12 + adj, | ||
167 | udma_timings[mode].reg12); | ||
168 | } else { | ||
169 | set_indexed_reg(hwif, 0x0e + adj, | ||
170 | mwdma_timings[mode].reg0e); | ||
171 | set_indexed_reg(hwif, 0x0f + adj, | ||
172 | mwdma_timings[mode].reg0f); | ||
173 | } | ||
174 | } else if (speed == XFER_UDMA_2) { | ||
175 | /* Set tHOLD bit to 0 if using UDMA mode 2 */ | ||
176 | u8 tmp = get_indexed_reg(hwif, 0x10 + adj); | ||
177 | |||
178 | set_indexed_reg(hwif, 0x10 + adj, tmp & 0x7f); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | static void pdcnew_set_pio_mode(ide_drive_t *drive, const u8 pio) | ||
183 | { | ||
184 | ide_hwif_t *hwif = drive->hwif; | ||
185 | struct pci_dev *dev = to_pci_dev(hwif->dev); | ||
186 | u8 adj = (drive->dn & 1) ? 0x08 : 0x00; | ||
187 | |||
188 | if (max_dma_rate(dev) == 4) { | ||
189 | set_indexed_reg(hwif, 0x0c + adj, pio_timings[pio].reg0c); | ||
190 | set_indexed_reg(hwif, 0x0d + adj, pio_timings[pio].reg0d); | ||
191 | set_indexed_reg(hwif, 0x13 + adj, pio_timings[pio].reg13); | ||
192 | } | ||
193 | } | ||
194 | |||
195 | static u8 pdcnew_cable_detect(ide_hwif_t *hwif) | ||
196 | { | ||
197 | if (get_indexed_reg(hwif, 0x0b) & 0x04) | ||
198 | return ATA_CBL_PATA40; | ||
199 | else | ||
200 | return ATA_CBL_PATA80; | ||
201 | } | ||
202 | |||
203 | static void pdcnew_quirkproc(ide_drive_t *drive) | ||
204 | { | ||
205 | const char **list, *m = (char *)&drive->id[ATA_ID_PROD]; | ||
206 | |||
207 | for (list = pdc_quirk_drives; *list != NULL; list++) | ||
208 | if (strstr(m, *list) != NULL) { | ||
209 | drive->quirk_list = 2; | ||
210 | return; | ||
211 | } | ||
212 | |||
213 | drive->quirk_list = 0; | ||
214 | } | ||
215 | |||
216 | static void pdcnew_reset(ide_drive_t *drive) | ||
217 | { | ||
218 | /* | ||
219 | * Deleted this because it is redundant from the caller. | ||
220 | */ | ||
221 | printk(KERN_WARNING "pdc202xx_new: %s channel reset.\n", | ||
222 | HWIF(drive)->channel ? "Secondary" : "Primary"); | ||
223 | } | ||
224 | |||
225 | /** | ||
226 | * read_counter - Read the byte count registers | ||
227 | * @dma_base: for the port address | ||
228 | */ | ||
229 | static long read_counter(u32 dma_base) | ||
230 | { | ||
231 | u32 pri_dma_base = dma_base, sec_dma_base = dma_base + 0x08; | ||
232 | u8 cnt0, cnt1, cnt2, cnt3; | ||
233 | long count = 0, last; | ||
234 | int retry = 3; | ||
235 | |||
236 | do { | ||
237 | last = count; | ||
238 | |||
239 | /* Read the current count */ | ||
240 | outb(0x20, pri_dma_base + 0x01); | ||
241 | cnt0 = inb(pri_dma_base + 0x03); | ||
242 | outb(0x21, pri_dma_base + 0x01); | ||
243 | cnt1 = inb(pri_dma_base + 0x03); | ||
244 | outb(0x20, sec_dma_base + 0x01); | ||
245 | cnt2 = inb(sec_dma_base + 0x03); | ||
246 | outb(0x21, sec_dma_base + 0x01); | ||
247 | cnt3 = inb(sec_dma_base + 0x03); | ||
248 | |||
249 | count = (cnt3 << 23) | (cnt2 << 15) | (cnt1 << 8) | cnt0; | ||
250 | |||
251 | /* | ||
252 | * The 30-bit decrementing counter is read in 4 pieces. | ||
253 | * Incorrect value may be read when the most significant bytes | ||
254 | * are changing... | ||
255 | */ | ||
256 | } while (retry-- && (((last ^ count) & 0x3fff8000) || last < count)); | ||
257 | |||
258 | DBG("cnt0[%02X] cnt1[%02X] cnt2[%02X] cnt3[%02X]\n", | ||
259 | cnt0, cnt1, cnt2, cnt3); | ||
260 | |||
261 | return count; | ||
262 | } | ||
263 | |||
264 | /** | ||
265 | * detect_pll_input_clock - Detect the PLL input clock in Hz. | ||
266 | * @dma_base: for the port address | ||
267 | * E.g. 16949000 on 33 MHz PCI bus, i.e. half of the PCI clock. | ||
268 | */ | ||
269 | static long detect_pll_input_clock(unsigned long dma_base) | ||
270 | { | ||
271 | struct timeval start_time, end_time; | ||
272 | long start_count, end_count; | ||
273 | long pll_input, usec_elapsed; | ||
274 | u8 scr1; | ||
275 | |||
276 | start_count = read_counter(dma_base); | ||
277 | do_gettimeofday(&start_time); | ||
278 | |||
279 | /* Start the test mode */ | ||
280 | outb(0x01, dma_base + 0x01); | ||
281 | scr1 = inb(dma_base + 0x03); | ||
282 | DBG("scr1[%02X]\n", scr1); | ||
283 | outb(scr1 | 0x40, dma_base + 0x03); | ||
284 | |||
285 | /* Let the counter run for 10 ms. */ | ||
286 | mdelay(10); | ||
287 | |||
288 | end_count = read_counter(dma_base); | ||
289 | do_gettimeofday(&end_time); | ||
290 | |||
291 | /* Stop the test mode */ | ||
292 | outb(0x01, dma_base + 0x01); | ||
293 | scr1 = inb(dma_base + 0x03); | ||
294 | DBG("scr1[%02X]\n", scr1); | ||
295 | outb(scr1 & ~0x40, dma_base + 0x03); | ||
296 | |||
297 | /* | ||
298 | * Calculate the input clock in Hz | ||
299 | * (the clock counter is 30 bit wide and counts down) | ||
300 | */ | ||
301 | usec_elapsed = (end_time.tv_sec - start_time.tv_sec) * 1000000 + | ||
302 | (end_time.tv_usec - start_time.tv_usec); | ||
303 | pll_input = ((start_count - end_count) & 0x3fffffff) / 10 * | ||
304 | (10000000 / usec_elapsed); | ||
305 | |||
306 | DBG("start[%ld] end[%ld]\n", start_count, end_count); | ||
307 | |||
308 | return pll_input; | ||
309 | } | ||
310 | |||
311 | #ifdef CONFIG_PPC_PMAC | ||
312 | static void apple_kiwi_init(struct pci_dev *pdev) | ||
313 | { | ||
314 | struct device_node *np = pci_device_to_OF_node(pdev); | ||
315 | u8 conf; | ||
316 | |||
317 | if (np == NULL || !of_device_is_compatible(np, "kiwi-root")) | ||
318 | return; | ||
319 | |||
320 | if (pdev->revision >= 0x03) { | ||
321 | /* Setup chip magic config stuff (from darwin) */ | ||
322 | pci_read_config_byte (pdev, 0x40, &conf); | ||
323 | pci_write_config_byte(pdev, 0x40, (conf | 0x01)); | ||
324 | } | ||
325 | } | ||
326 | #endif /* CONFIG_PPC_PMAC */ | ||
327 | |||
328 | static unsigned int init_chipset_pdcnew(struct pci_dev *dev) | ||
329 | { | ||
330 | const char *name = DRV_NAME; | ||
331 | unsigned long dma_base = pci_resource_start(dev, 4); | ||
332 | unsigned long sec_dma_base = dma_base + 0x08; | ||
333 | long pll_input, pll_output, ratio; | ||
334 | int f, r; | ||
335 | u8 pll_ctl0, pll_ctl1; | ||
336 | |||
337 | if (dma_base == 0) | ||
338 | return -EFAULT; | ||
339 | |||
340 | #ifdef CONFIG_PPC_PMAC | ||
341 | apple_kiwi_init(dev); | ||
342 | #endif | ||
343 | |||
344 | /* Calculate the required PLL output frequency */ | ||
345 | switch(max_dma_rate(dev)) { | ||
346 | case 4: /* it's 133 MHz for Ultra133 chips */ | ||
347 | pll_output = 133333333; | ||
348 | break; | ||
349 | case 3: /* and 100 MHz for Ultra100 chips */ | ||
350 | default: | ||
351 | pll_output = 100000000; | ||
352 | break; | ||
353 | } | ||
354 | |||
355 | /* | ||
356 | * Detect PLL input clock. | ||
357 | * On some systems, where PCI bus is running at non-standard clock rate | ||
358 | * (e.g. 25 or 40 MHz), we have to adjust the cycle time. | ||
359 | * PDC20268 and newer chips employ PLL circuit to help correct timing | ||
360 | * registers setting. | ||
361 | */ | ||
362 | pll_input = detect_pll_input_clock(dma_base); | ||
363 | printk(KERN_INFO "%s %s: PLL input clock is %ld kHz\n", | ||
364 | name, pci_name(dev), pll_input / 1000); | ||
365 | |||
366 | /* Sanity check */ | ||
367 | if (unlikely(pll_input < 5000000L || pll_input > 70000000L)) { | ||
368 | printk(KERN_ERR "%s %s: Bad PLL input clock %ld Hz, giving up!" | ||
369 | "\n", name, pci_name(dev), pll_input); | ||
370 | goto out; | ||
371 | } | ||
372 | |||
373 | #ifdef DEBUG | ||
374 | DBG("pll_output is %ld Hz\n", pll_output); | ||
375 | |||
376 | /* Show the current clock value of PLL control register | ||
377 | * (maybe already configured by the BIOS) | ||
378 | */ | ||
379 | outb(0x02, sec_dma_base + 0x01); | ||
380 | pll_ctl0 = inb(sec_dma_base + 0x03); | ||
381 | outb(0x03, sec_dma_base + 0x01); | ||
382 | pll_ctl1 = inb(sec_dma_base + 0x03); | ||
383 | |||
384 | DBG("pll_ctl[%02X][%02X]\n", pll_ctl0, pll_ctl1); | ||
385 | #endif | ||
386 | |||
387 | /* | ||
388 | * Calculate the ratio of F, R and NO | ||
389 | * POUT = (F + 2) / (( R + 2) * NO) | ||
390 | */ | ||
391 | ratio = pll_output / (pll_input / 1000); | ||
392 | if (ratio < 8600L) { /* 8.6x */ | ||
393 | /* Using NO = 0x01, R = 0x0d */ | ||
394 | r = 0x0d; | ||
395 | } else if (ratio < 12900L) { /* 12.9x */ | ||
396 | /* Using NO = 0x01, R = 0x08 */ | ||
397 | r = 0x08; | ||
398 | } else if (ratio < 16100L) { /* 16.1x */ | ||
399 | /* Using NO = 0x01, R = 0x06 */ | ||
400 | r = 0x06; | ||
401 | } else if (ratio < 64000L) { /* 64x */ | ||
402 | r = 0x00; | ||
403 | } else { | ||
404 | /* Invalid ratio */ | ||
405 | printk(KERN_ERR "%s %s: Bad ratio %ld, giving up!\n", | ||
406 | name, pci_name(dev), ratio); | ||
407 | goto out; | ||
408 | } | ||
409 | |||
410 | f = (ratio * (r + 2)) / 1000 - 2; | ||
411 | |||
412 | DBG("F[%d] R[%d] ratio*1000[%ld]\n", f, r, ratio); | ||
413 | |||
414 | if (unlikely(f < 0 || f > 127)) { | ||
415 | /* Invalid F */ | ||
416 | printk(KERN_ERR "%s %s: F[%d] invalid!\n", | ||
417 | name, pci_name(dev), f); | ||
418 | goto out; | ||
419 | } | ||
420 | |||
421 | pll_ctl0 = (u8) f; | ||
422 | pll_ctl1 = (u8) r; | ||
423 | |||
424 | DBG("Writing pll_ctl[%02X][%02X]\n", pll_ctl0, pll_ctl1); | ||
425 | |||
426 | outb(0x02, sec_dma_base + 0x01); | ||
427 | outb(pll_ctl0, sec_dma_base + 0x03); | ||
428 | outb(0x03, sec_dma_base + 0x01); | ||
429 | outb(pll_ctl1, sec_dma_base + 0x03); | ||
430 | |||
431 | /* Wait the PLL circuit to be stable */ | ||
432 | mdelay(30); | ||
433 | |||
434 | #ifdef DEBUG | ||
435 | /* | ||
436 | * Show the current clock value of PLL control register | ||
437 | */ | ||
438 | outb(0x02, sec_dma_base + 0x01); | ||
439 | pll_ctl0 = inb(sec_dma_base + 0x03); | ||
440 | outb(0x03, sec_dma_base + 0x01); | ||
441 | pll_ctl1 = inb(sec_dma_base + 0x03); | ||
442 | |||
443 | DBG("pll_ctl[%02X][%02X]\n", pll_ctl0, pll_ctl1); | ||
444 | #endif | ||
445 | |||
446 | out: | ||
447 | return dev->irq; | ||
448 | } | ||
449 | |||
450 | static struct pci_dev * __devinit pdc20270_get_dev2(struct pci_dev *dev) | ||
451 | { | ||
452 | struct pci_dev *dev2; | ||
453 | |||
454 | dev2 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn) + 1, | ||
455 | PCI_FUNC(dev->devfn))); | ||
456 | |||
457 | if (dev2 && | ||
458 | dev2->vendor == dev->vendor && | ||
459 | dev2->device == dev->device) { | ||
460 | |||
461 | if (dev2->irq != dev->irq) { | ||
462 | dev2->irq = dev->irq; | ||
463 | printk(KERN_INFO DRV_NAME " %s: PCI config space " | ||
464 | "interrupt fixed\n", pci_name(dev)); | ||
465 | } | ||
466 | |||
467 | return dev2; | ||
468 | } | ||
469 | |||
470 | return NULL; | ||
471 | } | ||
472 | |||
473 | static const struct ide_port_ops pdcnew_port_ops = { | ||
474 | .set_pio_mode = pdcnew_set_pio_mode, | ||
475 | .set_dma_mode = pdcnew_set_dma_mode, | ||
476 | .quirkproc = pdcnew_quirkproc, | ||
477 | .resetproc = pdcnew_reset, | ||
478 | .cable_detect = pdcnew_cable_detect, | ||
479 | }; | ||
480 | |||
481 | #define DECLARE_PDCNEW_DEV(udma) \ | ||
482 | { \ | ||
483 | .name = DRV_NAME, \ | ||
484 | .init_chipset = init_chipset_pdcnew, \ | ||
485 | .port_ops = &pdcnew_port_ops, \ | ||
486 | .host_flags = IDE_HFLAG_POST_SET_MODE | \ | ||
487 | IDE_HFLAG_ERROR_STOPS_FIFO | \ | ||
488 | IDE_HFLAG_OFF_BOARD, \ | ||
489 | .pio_mask = ATA_PIO4, \ | ||
490 | .mwdma_mask = ATA_MWDMA2, \ | ||
491 | .udma_mask = udma, \ | ||
492 | } | ||
493 | |||
494 | static const struct ide_port_info pdcnew_chipsets[] __devinitdata = { | ||
495 | /* 0: PDC202{68,70} */ DECLARE_PDCNEW_DEV(ATA_UDMA5), | ||
496 | /* 1: PDC202{69,71,75,76,77} */ DECLARE_PDCNEW_DEV(ATA_UDMA6), | ||
497 | }; | ||
498 | |||
499 | /** | ||
500 | * pdc202new_init_one - called when a pdc202xx is found | ||
501 | * @dev: the pdc202new device | ||
502 | * @id: the matching pci id | ||
503 | * | ||
504 | * Called when the PCI registration layer (or the IDE initialization) | ||
505 | * finds a device matching our IDE device tables. | ||
506 | */ | ||
507 | |||
508 | static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_device_id *id) | ||
509 | { | ||
510 | const struct ide_port_info *d = &pdcnew_chipsets[id->driver_data]; | ||
511 | struct pci_dev *bridge = dev->bus->self; | ||
512 | |||
513 | if (dev->device == PCI_DEVICE_ID_PROMISE_20270 && bridge && | ||
514 | bridge->vendor == PCI_VENDOR_ID_DEC && | ||
515 | bridge->device == PCI_DEVICE_ID_DEC_21150) { | ||
516 | struct pci_dev *dev2; | ||
517 | |||
518 | if (PCI_SLOT(dev->devfn) & 2) | ||
519 | return -ENODEV; | ||
520 | |||
521 | dev2 = pdc20270_get_dev2(dev); | ||
522 | |||
523 | if (dev2) { | ||
524 | int ret = ide_pci_init_two(dev, dev2, d, NULL); | ||
525 | if (ret < 0) | ||
526 | pci_dev_put(dev2); | ||
527 | return ret; | ||
528 | } | ||
529 | } | ||
530 | |||
531 | if (dev->device == PCI_DEVICE_ID_PROMISE_20276 && bridge && | ||
532 | bridge->vendor == PCI_VENDOR_ID_INTEL && | ||
533 | (bridge->device == PCI_DEVICE_ID_INTEL_I960 || | ||
534 | bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) { | ||
535 | printk(KERN_INFO DRV_NAME " %s: attached to I2O RAID controller," | ||
536 | " skipping\n", pci_name(dev)); | ||
537 | return -ENODEV; | ||
538 | } | ||
539 | |||
540 | return ide_pci_init_one(dev, d, NULL); | ||
541 | } | ||
542 | |||
543 | static void __devexit pdc202new_remove(struct pci_dev *dev) | ||
544 | { | ||
545 | struct ide_host *host = pci_get_drvdata(dev); | ||
546 | struct pci_dev *dev2 = host->dev[1] ? to_pci_dev(host->dev[1]) : NULL; | ||
547 | |||
548 | ide_pci_remove(dev); | ||
549 | pci_dev_put(dev2); | ||
550 | } | ||
551 | |||
552 | static const struct pci_device_id pdc202new_pci_tbl[] = { | ||
553 | { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20268), 0 }, | ||
554 | { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20269), 1 }, | ||
555 | { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20270), 0 }, | ||
556 | { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20271), 1 }, | ||
557 | { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20275), 1 }, | ||
558 | { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20276), 1 }, | ||
559 | { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20277), 1 }, | ||
560 | { 0, }, | ||
561 | }; | ||
562 | MODULE_DEVICE_TABLE(pci, pdc202new_pci_tbl); | ||
563 | |||
564 | static struct pci_driver pdc202new_pci_driver = { | ||
565 | .name = "Promise_IDE", | ||
566 | .id_table = pdc202new_pci_tbl, | ||
567 | .probe = pdc202new_init_one, | ||
568 | .remove = __devexit_p(pdc202new_remove), | ||
569 | .suspend = ide_pci_suspend, | ||
570 | .resume = ide_pci_resume, | ||
571 | }; | ||
572 | |||
573 | static int __init pdc202new_ide_init(void) | ||
574 | { | ||
575 | return ide_pci_register_driver(&pdc202new_pci_driver); | ||
576 | } | ||
577 | |||
578 | static void __exit pdc202new_ide_exit(void) | ||
579 | { | ||
580 | pci_unregister_driver(&pdc202new_pci_driver); | ||
581 | } | ||
582 | |||
583 | module_init(pdc202new_ide_init); | ||
584 | module_exit(pdc202new_ide_exit); | ||
585 | |||
586 | MODULE_AUTHOR("Andre Hedrick, Frank Tiernan"); | ||
587 | MODULE_DESCRIPTION("PCI driver module for Promise PDC20268 and higher"); | ||
588 | MODULE_LICENSE("GPL"); | ||