diff options
author | Alan Cox <alan@lxorguk.ukuu.org.uk> | 2008-01-10 17:33:10 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-01-23 05:24:16 -0500 |
commit | defc9cd826e4a99f550504a744f9407b518828ae (patch) | |
tree | 57d863dd941f66e37818e187006915fb99466c28 /drivers/ata/pata_legacy.c | |
parent | c294f1b32940d5bf853e006b9ccc72629c859749 (diff) |
pata_legacy: resychronize with upstream changes and resubmit
Update the legacy driver so it can handle VLB ports nicely, and has an
internal structure for nailing new ISA/VLB forms in. Anyone got an ALI14xx
and a spare day ;)
Also adds an "all" parameter so you can load this driver after all the PCI
ones in a boot time kernel and tell it to grab anything ST412 compatible
even if it is an unknown PCI device. That allows libata to offer the same
"just get me a disk somehow" fallback that old IDE did.
Obsoletes pata_qdi.
Signed-off-by: Alan Cox <alan@redhat.com>
Cc: Tejun Heo <htejun@gmail.com>
Cc: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/pata_legacy.c')
-rw-r--r-- | drivers/ata/pata_legacy.c | 750 |
1 files changed, 605 insertions, 145 deletions
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index c37ba324e71c..c4a939b506c9 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c | |||
@@ -68,8 +68,9 @@ | |||
68 | 68 | ||
69 | #define NR_HOST 6 | 69 | #define NR_HOST 6 |
70 | 70 | ||
71 | static int legacy_port[NR_HOST] = { 0x1f0, 0x170, 0x1e8, 0x168, 0x1e0, 0x160 }; | 71 | static int all; |
72 | static int legacy_irq[NR_HOST] = { 14, 15, 11, 10, 8, 12 }; | 72 | module_param(all, int, 0444); |
73 | MODULE_PARM_DESC(all, "Grab all legacy port devices, even if PCI(0=off, 1=on)"); | ||
73 | 74 | ||
74 | struct legacy_data { | 75 | struct legacy_data { |
75 | unsigned long timing; | 76 | unsigned long timing; |
@@ -80,21 +81,103 @@ struct legacy_data { | |||
80 | 81 | ||
81 | }; | 82 | }; |
82 | 83 | ||
84 | enum controller { | ||
85 | BIOS = 0, | ||
86 | SNOOP = 1, | ||
87 | PDC20230 = 2, | ||
88 | HT6560A = 3, | ||
89 | HT6560B = 4, | ||
90 | OPTI611A = 5, | ||
91 | OPTI46X = 6, | ||
92 | QDI6500 = 7, | ||
93 | QDI6580 = 8, | ||
94 | QDI6580DP = 9, /* Dual channel mode is different */ | ||
95 | |||
96 | UNKNOWN = -1 | ||
97 | }; | ||
98 | |||
99 | |||
100 | struct legacy_probe { | ||
101 | unsigned char *name; | ||
102 | unsigned long port; | ||
103 | unsigned int irq; | ||
104 | unsigned int slot; | ||
105 | enum controller type; | ||
106 | unsigned long private; | ||
107 | }; | ||
108 | |||
109 | struct legacy_controller { | ||
110 | const char *name; | ||
111 | struct ata_port_operations *ops; | ||
112 | unsigned int pio_mask; | ||
113 | unsigned int flags; | ||
114 | int (*setup)(struct legacy_probe *probe, struct legacy_data *data); | ||
115 | }; | ||
116 | |||
117 | static int legacy_port[NR_HOST] = { 0x1f0, 0x170, 0x1e8, 0x168, 0x1e0, 0x160 }; | ||
118 | |||
119 | static struct legacy_probe probe_list[NR_HOST]; | ||
83 | static struct legacy_data legacy_data[NR_HOST]; | 120 | static struct legacy_data legacy_data[NR_HOST]; |
84 | static struct ata_host *legacy_host[NR_HOST]; | 121 | static struct ata_host *legacy_host[NR_HOST]; |
85 | static int nr_legacy_host; | 122 | static int nr_legacy_host; |
86 | 123 | ||
87 | 124 | ||
88 | static int probe_all; /* Set to check all ISA port ranges */ | 125 | static int probe_all; /* Set to check all ISA port ranges */ |
89 | static int ht6560a; /* HT 6560A on primary 1, secondary 2, both 3 */ | 126 | static int ht6560a; /* HT 6560A on primary 1, second 2, both 3 */ |
90 | static int ht6560b; /* HT 6560A on primary 1, secondary 2, both 3 */ | 127 | static int ht6560b; /* HT 6560A on primary 1, second 2, both 3 */ |
91 | static int opti82c611a; /* Opti82c611A on primary 1, secondary 2, both 3 */ | 128 | static int opti82c611a; /* Opti82c611A on primary 1, sec 2, both 3 */ |
92 | static int opti82c46x; /* Opti 82c465MV present (pri/sec autodetect) */ | 129 | static int opti82c46x; /* Opti 82c465MV present(pri/sec autodetect) */ |
93 | static int autospeed; /* Chip present which snoops speed changes */ | 130 | static int qdi; /* Set to probe QDI controllers */ |
94 | static int pio_mask = 0x1F; /* PIO range for autospeed devices */ | 131 | static int autospeed; /* Chip present which snoops speed changes */ |
132 | static int pio_mask = 0x1F; /* PIO range for autospeed devices */ | ||
95 | static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */ | 133 | static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */ |
96 | 134 | ||
97 | /** | 135 | /** |
136 | * legacy_probe_add - Add interface to probe list | ||
137 | * @port: Controller port | ||
138 | * @irq: IRQ number | ||
139 | * @type: Controller type | ||
140 | * @private: Controller specific info | ||
141 | * | ||
142 | * Add an entry into the probe list for ATA controllers. This is used | ||
143 | * to add the default ISA slots and then to build up the table | ||
144 | * further according to other ISA/VLB/Weird device scans | ||
145 | * | ||
146 | * An I/O port list is used to keep ordering stable and sane, as we | ||
147 | * don't have any good way to talk about ordering otherwise | ||
148 | */ | ||
149 | |||
150 | static int legacy_probe_add(unsigned long port, unsigned int irq, | ||
151 | enum controller type, unsigned long private) | ||
152 | { | ||
153 | struct legacy_probe *lp = &probe_list[0]; | ||
154 | int i; | ||
155 | struct legacy_probe *free = NULL; | ||
156 | |||
157 | for (i = 0; i < NR_HOST; i++) { | ||
158 | if (lp->port == 0 && free == NULL) | ||
159 | free = lp; | ||
160 | /* Matching port, or the correct slot for ordering */ | ||
161 | if (lp->port == port || legacy_port[i] == port) { | ||
162 | free = lp; | ||
163 | break; | ||
164 | } | ||
165 | lp++; | ||
166 | } | ||
167 | if (free == NULL) { | ||
168 | printk(KERN_ERR "pata_legacy: Too many interfaces.\n"); | ||
169 | return -1; | ||
170 | } | ||
171 | /* Fill in the entry for later probing */ | ||
172 | free->port = port; | ||
173 | free->irq = irq; | ||
174 | free->type = type; | ||
175 | free->private = private; | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | |||
180 | /** | ||
98 | * legacy_set_mode - mode setting | 181 | * legacy_set_mode - mode setting |
99 | * @link: IDE link | 182 | * @link: IDE link |
100 | * @unused: Device that failed when error is returned | 183 | * @unused: Device that failed when error is returned |
@@ -113,7 +196,8 @@ static int legacy_set_mode(struct ata_link *link, struct ata_device **unused) | |||
113 | 196 | ||
114 | ata_link_for_each_dev(dev, link) { | 197 | ata_link_for_each_dev(dev, link) { |
115 | if (ata_dev_enabled(dev)) { | 198 | if (ata_dev_enabled(dev)) { |
116 | ata_dev_printk(dev, KERN_INFO, "configured for PIO\n"); | 199 | ata_dev_printk(dev, KERN_INFO, |
200 | "configured for PIO\n"); | ||
117 | dev->pio_mode = XFER_PIO_0; | 201 | dev->pio_mode = XFER_PIO_0; |
118 | dev->xfer_mode = XFER_PIO_0; | 202 | dev->xfer_mode = XFER_PIO_0; |
119 | dev->xfer_shift = ATA_SHIFT_PIO; | 203 | dev->xfer_shift = ATA_SHIFT_PIO; |
@@ -171,7 +255,7 @@ static struct ata_port_operations simple_port_ops = { | |||
171 | .irq_clear = ata_bmdma_irq_clear, | 255 | .irq_clear = ata_bmdma_irq_clear, |
172 | .irq_on = ata_irq_on, | 256 | .irq_on = ata_irq_on, |
173 | 257 | ||
174 | .port_start = ata_port_start, | 258 | .port_start = ata_sff_port_start, |
175 | }; | 259 | }; |
176 | 260 | ||
177 | static struct ata_port_operations legacy_port_ops = { | 261 | static struct ata_port_operations legacy_port_ops = { |
@@ -198,15 +282,16 @@ static struct ata_port_operations legacy_port_ops = { | |||
198 | .irq_clear = ata_bmdma_irq_clear, | 282 | .irq_clear = ata_bmdma_irq_clear, |
199 | .irq_on = ata_irq_on, | 283 | .irq_on = ata_irq_on, |
200 | 284 | ||
201 | .port_start = ata_port_start, | 285 | .port_start = ata_sff_port_start, |
202 | }; | 286 | }; |
203 | 287 | ||
204 | /* | 288 | /* |
205 | * Promise 20230C and 20620 support | 289 | * Promise 20230C and 20620 support |
206 | * | 290 | * |
207 | * This controller supports PIO0 to PIO2. We set PIO timings conservatively to | 291 | * This controller supports PIO0 to PIO2. We set PIO timings |
208 | * allow for 50MHz Vesa Local Bus. The 20620 DMA support is weird being DMA to | 292 | * conservatively to allow for 50MHz Vesa Local Bus. The 20620 DMA |
209 | * controller and PIO'd to the host and not supported. | 293 | * support is weird being DMA to controller and PIO'd to the host |
294 | * and not supported. | ||
210 | */ | 295 | */ |
211 | 296 | ||
212 | static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev) | 297 | static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev) |
@@ -221,8 +306,7 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
221 | local_irq_save(flags); | 306 | local_irq_save(flags); |
222 | 307 | ||
223 | /* Unlock the control interface */ | 308 | /* Unlock the control interface */ |
224 | do | 309 | do { |
225 | { | ||
226 | inb(0x1F5); | 310 | inb(0x1F5); |
227 | outb(inb(0x1F2) | 0x80, 0x1F2); | 311 | outb(inb(0x1F2) | 0x80, 0x1F2); |
228 | inb(0x1F2); | 312 | inb(0x1F2); |
@@ -231,7 +315,7 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
231 | inb(0x1F2); | 315 | inb(0x1F2); |
232 | inb(0x1F2); | 316 | inb(0x1F2); |
233 | } | 317 | } |
234 | while((inb(0x1F2) & 0x80) && --tries); | 318 | while ((inb(0x1F2) & 0x80) && --tries); |
235 | 319 | ||
236 | local_irq_restore(flags); | 320 | local_irq_restore(flags); |
237 | 321 | ||
@@ -250,7 +334,7 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
250 | } | 334 | } |
251 | 335 | ||
252 | static unsigned int pdc_data_xfer_vlb(struct ata_device *dev, | 336 | static unsigned int pdc_data_xfer_vlb(struct ata_device *dev, |
253 | unsigned char *buf, unsigned int buflen, int rw) | 337 | unsigned char *buf, unsigned int buflen, int rw) |
254 | { | 338 | { |
255 | if (ata_id_has_dword_io(dev->id)) { | 339 | if (ata_id_has_dword_io(dev->id)) { |
256 | struct ata_port *ap = dev->link->ap; | 340 | struct ata_port *ap = dev->link->ap; |
@@ -312,14 +396,14 @@ static struct ata_port_operations pdc20230_port_ops = { | |||
312 | .irq_clear = ata_bmdma_irq_clear, | 396 | .irq_clear = ata_bmdma_irq_clear, |
313 | .irq_on = ata_irq_on, | 397 | .irq_on = ata_irq_on, |
314 | 398 | ||
315 | .port_start = ata_port_start, | 399 | .port_start = ata_sff_port_start, |
316 | }; | 400 | }; |
317 | 401 | ||
318 | /* | 402 | /* |
319 | * Holtek 6560A support | 403 | * Holtek 6560A support |
320 | * | 404 | * |
321 | * This controller supports PIO0 to PIO2 (no IORDY even though higher timings | 405 | * This controller supports PIO0 to PIO2 (no IORDY even though higher |
322 | * can be loaded). | 406 | * timings can be loaded). |
323 | */ | 407 | */ |
324 | 408 | ||
325 | static void ht6560a_set_piomode(struct ata_port *ap, struct ata_device *adev) | 409 | static void ht6560a_set_piomode(struct ata_port *ap, struct ata_device *adev) |
@@ -366,14 +450,14 @@ static struct ata_port_operations ht6560a_port_ops = { | |||
366 | .irq_clear = ata_bmdma_irq_clear, | 450 | .irq_clear = ata_bmdma_irq_clear, |
367 | .irq_on = ata_irq_on, | 451 | .irq_on = ata_irq_on, |
368 | 452 | ||
369 | .port_start = ata_port_start, | 453 | .port_start = ata_sff_port_start, |
370 | }; | 454 | }; |
371 | 455 | ||
372 | /* | 456 | /* |
373 | * Holtek 6560B support | 457 | * Holtek 6560B support |
374 | * | 458 | * |
375 | * This controller supports PIO0 to PIO4. We honour the BIOS/jumper FIFO setting | 459 | * This controller supports PIO0 to PIO4. We honour the BIOS/jumper FIFO |
376 | * unless we see an ATAPI device in which case we force it off. | 460 | * setting unless we see an ATAPI device in which case we force it off. |
377 | * | 461 | * |
378 | * FIXME: need to implement 2nd channel support. | 462 | * FIXME: need to implement 2nd channel support. |
379 | */ | 463 | */ |
@@ -400,7 +484,7 @@ static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
400 | if (adev->class != ATA_DEV_ATA) { | 484 | if (adev->class != ATA_DEV_ATA) { |
401 | u8 rconf = inb(0x3E6); | 485 | u8 rconf = inb(0x3E6); |
402 | if (rconf & 0x24) { | 486 | if (rconf & 0x24) { |
403 | rconf &= ~ 0x24; | 487 | rconf &= ~0x24; |
404 | outb(rconf, 0x3E6); | 488 | outb(rconf, 0x3E6); |
405 | } | 489 | } |
406 | } | 490 | } |
@@ -425,13 +509,13 @@ static struct ata_port_operations ht6560b_port_ops = { | |||
425 | .qc_prep = ata_qc_prep, | 509 | .qc_prep = ata_qc_prep, |
426 | .qc_issue = ata_qc_issue_prot, | 510 | .qc_issue = ata_qc_issue_prot, |
427 | 511 | ||
428 | .data_xfer = ata_data_xfer, /* FIXME: Check 32bit and noirq */ | 512 | .data_xfer = ata_data_xfer, /* FIXME: Check 32bit and noirq */ |
429 | 513 | ||
430 | .irq_handler = ata_interrupt, | 514 | .irq_handler = ata_interrupt, |
431 | .irq_clear = ata_bmdma_irq_clear, | 515 | .irq_clear = ata_bmdma_irq_clear, |
432 | .irq_on = ata_irq_on, | 516 | .irq_on = ata_irq_on, |
433 | 517 | ||
434 | .port_start = ata_port_start, | 518 | .port_start = ata_sff_port_start, |
435 | }; | 519 | }; |
436 | 520 | ||
437 | /* | 521 | /* |
@@ -464,7 +548,8 @@ static u8 opti_syscfg(u8 reg) | |||
464 | * This controller supports PIO0 to PIO3. | 548 | * This controller supports PIO0 to PIO3. |
465 | */ | 549 | */ |
466 | 550 | ||
467 | static void opti82c611a_set_piomode(struct ata_port *ap, struct ata_device *adev) | 551 | static void opti82c611a_set_piomode(struct ata_port *ap, |
552 | struct ata_device *adev) | ||
468 | { | 553 | { |
469 | u8 active, recover, setup; | 554 | u8 active, recover, setup; |
470 | struct ata_timing t; | 555 | struct ata_timing t; |
@@ -551,7 +636,7 @@ static struct ata_port_operations opti82c611a_port_ops = { | |||
551 | .irq_clear = ata_bmdma_irq_clear, | 636 | .irq_clear = ata_bmdma_irq_clear, |
552 | .irq_on = ata_irq_on, | 637 | .irq_on = ata_irq_on, |
553 | 638 | ||
554 | .port_start = ata_port_start, | 639 | .port_start = ata_sff_port_start, |
555 | }; | 640 | }; |
556 | 641 | ||
557 | /* | 642 | /* |
@@ -683,77 +768,282 @@ static struct ata_port_operations opti82c46x_port_ops = { | |||
683 | .irq_clear = ata_bmdma_irq_clear, | 768 | .irq_clear = ata_bmdma_irq_clear, |
684 | .irq_on = ata_irq_on, | 769 | .irq_on = ata_irq_on, |
685 | 770 | ||
686 | .port_start = ata_port_start, | 771 | .port_start = ata_sff_port_start, |
687 | }; | 772 | }; |
688 | 773 | ||
774 | static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev) | ||
775 | { | ||
776 | struct ata_timing t; | ||
777 | struct legacy_data *qdi = ap->host->private_data; | ||
778 | int active, recovery; | ||
779 | u8 timing; | ||
780 | |||
781 | /* Get the timing data in cycles */ | ||
782 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); | ||
783 | |||
784 | if (qdi->fast) { | ||
785 | active = 8 - FIT(t.active, 1, 8); | ||
786 | recovery = 18 - FIT(t.recover, 3, 18); | ||
787 | } else { | ||
788 | active = 9 - FIT(t.active, 2, 9); | ||
789 | recovery = 15 - FIT(t.recover, 0, 15); | ||
790 | } | ||
791 | timing = (recovery << 4) | active | 0x08; | ||
792 | |||
793 | qdi->clock[adev->devno] = timing; | ||
794 | |||
795 | outb(timing, qdi->timing); | ||
796 | } | ||
689 | 797 | ||
690 | /** | 798 | /** |
691 | * legacy_init_one - attach a legacy interface | 799 | * qdi6580dp_set_piomode - PIO setup for dual channel |
692 | * @port: port number | 800 | * @ap: Port |
693 | * @io: I/O port start | 801 | * @adev: Device |
694 | * @ctrl: control port | ||
695 | * @irq: interrupt line | 802 | * @irq: interrupt line |
696 | * | 803 | * |
697 | * Register an ISA bus IDE interface. Such interfaces are PIO and we | 804 | * In dual channel mode the 6580 has one clock per channel and we have |
698 | * assume do not support IRQ sharing. | 805 | * to software clockswitch in qc_issue_prot. |
699 | */ | 806 | */ |
700 | 807 | ||
701 | static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl, int irq) | 808 | static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev) |
702 | { | 809 | { |
703 | struct legacy_data *ld = &legacy_data[nr_legacy_host]; | 810 | struct ata_timing t; |
704 | struct ata_host *host; | 811 | struct legacy_data *qdi = ap->host->private_data; |
705 | struct ata_port *ap; | 812 | int active, recovery; |
706 | struct platform_device *pdev; | 813 | u8 timing; |
707 | struct ata_port_operations *ops = &legacy_port_ops; | ||
708 | void __iomem *io_addr, *ctrl_addr; | ||
709 | int pio_modes = pio_mask; | ||
710 | u32 mask = (1 << port); | ||
711 | u32 iordy = (iordy_mask & mask) ? 0: ATA_FLAG_NO_IORDY; | ||
712 | int ret; | ||
713 | 814 | ||
714 | pdev = platform_device_register_simple(DRV_NAME, nr_legacy_host, NULL, 0); | 815 | /* Get the timing data in cycles */ |
715 | if (IS_ERR(pdev)) | 816 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); |
716 | return PTR_ERR(pdev); | 817 | |
818 | if (qdi->fast) { | ||
819 | active = 8 - FIT(t.active, 1, 8); | ||
820 | recovery = 18 - FIT(t.recover, 3, 18); | ||
821 | } else { | ||
822 | active = 9 - FIT(t.active, 2, 9); | ||
823 | recovery = 15 - FIT(t.recover, 0, 15); | ||
824 | } | ||
825 | timing = (recovery << 4) | active | 0x08; | ||
717 | 826 | ||
718 | ret = -EBUSY; | 827 | qdi->clock[adev->devno] = timing; |
719 | if (devm_request_region(&pdev->dev, io, 8, "pata_legacy") == NULL || | ||
720 | devm_request_region(&pdev->dev, ctrl, 1, "pata_legacy") == NULL) | ||
721 | goto fail; | ||
722 | 828 | ||
723 | ret = -ENOMEM; | 829 | outb(timing, qdi->timing + 2 * ap->port_no); |
724 | io_addr = devm_ioport_map(&pdev->dev, io, 8); | 830 | /* Clear the FIFO */ |
725 | ctrl_addr = devm_ioport_map(&pdev->dev, ctrl, 1); | 831 | if (adev->class != ATA_DEV_ATA) |
726 | if (!io_addr || !ctrl_addr) | 832 | outb(0x5F, qdi->timing + 3); |
727 | goto fail; | 833 | } |
728 | 834 | ||
729 | if (ht6560a & mask) { | 835 | /** |
730 | ops = &ht6560a_port_ops; | 836 | * qdi6580_set_piomode - PIO setup for single channel |
731 | pio_modes = 0x07; | 837 | * @ap: Port |
732 | iordy = ATA_FLAG_NO_IORDY; | 838 | * @adev: Device |
733 | } | 839 | * |
734 | if (ht6560b & mask) { | 840 | * In single channel mode the 6580 has one clock per device and we can |
735 | ops = &ht6560b_port_ops; | 841 | * avoid the requirement to clock switch. We also have to load the timing |
736 | pio_modes = 0x1F; | 842 | * into the right clock according to whether we are master or slave. |
737 | } | 843 | */ |
738 | if (opti82c611a & mask) { | 844 | |
739 | ops = &opti82c611a_port_ops; | 845 | static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev) |
740 | pio_modes = 0x0F; | 846 | { |
847 | struct ata_timing t; | ||
848 | struct legacy_data *qdi = ap->host->private_data; | ||
849 | int active, recovery; | ||
850 | u8 timing; | ||
851 | |||
852 | /* Get the timing data in cycles */ | ||
853 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); | ||
854 | |||
855 | if (qdi->fast) { | ||
856 | active = 8 - FIT(t.active, 1, 8); | ||
857 | recovery = 18 - FIT(t.recover, 3, 18); | ||
858 | } else { | ||
859 | active = 9 - FIT(t.active, 2, 9); | ||
860 | recovery = 15 - FIT(t.recover, 0, 15); | ||
741 | } | 861 | } |
742 | if (opti82c46x & mask) { | 862 | timing = (recovery << 4) | active | 0x08; |
743 | ops = &opti82c46x_port_ops; | 863 | qdi->clock[adev->devno] = timing; |
744 | pio_modes = 0x0F; | 864 | outb(timing, qdi->timing + 2 * adev->devno); |
865 | /* Clear the FIFO */ | ||
866 | if (adev->class != ATA_DEV_ATA) | ||
867 | outb(0x5F, qdi->timing + 3); | ||
868 | } | ||
869 | |||
870 | /** | ||
871 | * qdi_qc_issue_prot - command issue | ||
872 | * @qc: command pending | ||
873 | * | ||
874 | * Called when the libata layer is about to issue a command. We wrap | ||
875 | * this interface so that we can load the correct ATA timings. | ||
876 | */ | ||
877 | |||
878 | static unsigned int qdi_qc_issue_prot(struct ata_queued_cmd *qc) | ||
879 | { | ||
880 | struct ata_port *ap = qc->ap; | ||
881 | struct ata_device *adev = qc->dev; | ||
882 | struct legacy_data *qdi = ap->host->private_data; | ||
883 | |||
884 | if (qdi->clock[adev->devno] != qdi->last) { | ||
885 | if (adev->pio_mode) { | ||
886 | qdi->last = qdi->clock[adev->devno]; | ||
887 | outb(qdi->clock[adev->devno], qdi->timing + | ||
888 | 2 * ap->port_no); | ||
889 | } | ||
745 | } | 890 | } |
891 | return ata_qc_issue_prot(qc); | ||
892 | } | ||
746 | 893 | ||
747 | /* Probe for automatically detectable controllers */ | 894 | /* For the 6580 can we flip the FIFO on/off at this point ? */ |
748 | 895 | ||
749 | if (io == 0x1F0 && ops == &legacy_port_ops) { | 896 | static unsigned int qdi_data_xfer(struct ata_device *adev, unsigned char *buf, |
750 | unsigned long flags; | 897 | unsigned int buflen, int rw) |
898 | { | ||
899 | struct ata_port *ap = adev->link->ap; | ||
900 | int slop = buflen & 3; | ||
751 | 901 | ||
752 | local_irq_save(flags); | 902 | if (ata_id_has_dword_io(adev->id)) { |
903 | if (rw == WRITE) | ||
904 | iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); | ||
905 | else | ||
906 | ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); | ||
753 | 907 | ||
908 | if (unlikely(slop)) { | ||
909 | u32 pad; | ||
910 | if (rw == WRITE) { | ||
911 | memcpy(&pad, buf + buflen - slop, slop); | ||
912 | pad = le32_to_cpu(pad); | ||
913 | iowrite32(pad, ap->ioaddr.data_addr); | ||
914 | } else { | ||
915 | pad = ioread32(ap->ioaddr.data_addr); | ||
916 | pad = cpu_to_le32(pad); | ||
917 | memcpy(buf + buflen - slop, &pad, slop); | ||
918 | } | ||
919 | } | ||
920 | return (buflen + 3) & ~3; | ||
921 | } else | ||
922 | return ata_data_xfer(adev, buf, buflen, rw); | ||
923 | } | ||
924 | |||
925 | static struct ata_port_operations qdi6500_port_ops = { | ||
926 | .set_piomode = qdi6500_set_piomode, | ||
927 | |||
928 | .tf_load = ata_tf_load, | ||
929 | .tf_read = ata_tf_read, | ||
930 | .check_status = ata_check_status, | ||
931 | .exec_command = ata_exec_command, | ||
932 | .dev_select = ata_std_dev_select, | ||
933 | |||
934 | .freeze = ata_bmdma_freeze, | ||
935 | .thaw = ata_bmdma_thaw, | ||
936 | .error_handler = ata_bmdma_error_handler, | ||
937 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | ||
938 | .cable_detect = ata_cable_40wire, | ||
939 | |||
940 | .qc_prep = ata_qc_prep, | ||
941 | .qc_issue = qdi_qc_issue_prot, | ||
942 | |||
943 | .data_xfer = qdi_data_xfer, | ||
944 | |||
945 | .irq_handler = ata_interrupt, | ||
946 | .irq_clear = ata_bmdma_irq_clear, | ||
947 | .irq_on = ata_irq_on, | ||
948 | |||
949 | .port_start = ata_sff_port_start, | ||
950 | }; | ||
951 | |||
952 | static struct ata_port_operations qdi6580_port_ops = { | ||
953 | .set_piomode = qdi6580_set_piomode, | ||
954 | |||
955 | .tf_load = ata_tf_load, | ||
956 | .tf_read = ata_tf_read, | ||
957 | .check_status = ata_check_status, | ||
958 | .exec_command = ata_exec_command, | ||
959 | .dev_select = ata_std_dev_select, | ||
960 | |||
961 | .freeze = ata_bmdma_freeze, | ||
962 | .thaw = ata_bmdma_thaw, | ||
963 | .error_handler = ata_bmdma_error_handler, | ||
964 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | ||
965 | .cable_detect = ata_cable_40wire, | ||
966 | |||
967 | .qc_prep = ata_qc_prep, | ||
968 | .qc_issue = ata_qc_issue_prot, | ||
969 | |||
970 | .data_xfer = qdi_data_xfer, | ||
971 | |||
972 | .irq_handler = ata_interrupt, | ||
973 | .irq_clear = ata_bmdma_irq_clear, | ||
974 | .irq_on = ata_irq_on, | ||
975 | |||
976 | .port_start = ata_sff_port_start, | ||
977 | }; | ||
978 | |||
979 | static struct ata_port_operations qdi6580dp_port_ops = { | ||
980 | .set_piomode = qdi6580dp_set_piomode, | ||
981 | |||
982 | .tf_load = ata_tf_load, | ||
983 | .tf_read = ata_tf_read, | ||
984 | .check_status = ata_check_status, | ||
985 | .exec_command = ata_exec_command, | ||
986 | .dev_select = ata_std_dev_select, | ||
987 | |||
988 | .freeze = ata_bmdma_freeze, | ||
989 | .thaw = ata_bmdma_thaw, | ||
990 | .error_handler = ata_bmdma_error_handler, | ||
991 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | ||
992 | .cable_detect = ata_cable_40wire, | ||
993 | |||
994 | .qc_prep = ata_qc_prep, | ||
995 | .qc_issue = qdi_qc_issue_prot, | ||
996 | |||
997 | .data_xfer = qdi_data_xfer, | ||
998 | |||
999 | .irq_handler = ata_interrupt, | ||
1000 | .irq_clear = ata_bmdma_irq_clear, | ||
1001 | .irq_on = ata_irq_on, | ||
1002 | |||
1003 | .port_start = ata_sff_port_start, | ||
1004 | }; | ||
1005 | |||
1006 | static struct legacy_controller controllers[] = { | ||
1007 | {"BIOS", &legacy_port_ops, 0x1F, | ||
1008 | ATA_FLAG_NO_IORDY, NULL }, | ||
1009 | {"Snooping", &simple_port_ops, 0x1F, | ||
1010 | 0 , NULL }, | ||
1011 | {"PDC20230", &pdc20230_port_ops, 0x7, | ||
1012 | ATA_FLAG_NO_IORDY, NULL }, | ||
1013 | {"HT6560A", &ht6560a_port_ops, 0x07, | ||
1014 | ATA_FLAG_NO_IORDY, NULL }, | ||
1015 | {"HT6560B", &ht6560b_port_ops, 0x1F, | ||
1016 | ATA_FLAG_NO_IORDY, NULL }, | ||
1017 | {"OPTI82C611A", &opti82c611a_port_ops, 0x0F, | ||
1018 | 0 , NULL }, | ||
1019 | {"OPTI82C46X", &opti82c46x_port_ops, 0x0F, | ||
1020 | 0 , NULL }, | ||
1021 | {"QDI6500", &qdi6500_port_ops, 0x07, | ||
1022 | ATA_FLAG_NO_IORDY, NULL }, | ||
1023 | {"QDI6580", &qdi6580_port_ops, 0x1F, | ||
1024 | 0 , NULL }, | ||
1025 | {"QDI6580DP", &qdi6580dp_port_ops, 0x1F, | ||
1026 | 0 , NULL } | ||
1027 | }; | ||
1028 | |||
1029 | /** | ||
1030 | * probe_chip_type - Discover controller | ||
1031 | * @probe: Probe entry to check | ||
1032 | * | ||
1033 | * Probe an ATA port and identify the type of controller. We don't | ||
1034 | * check if the controller appears to be driveless at this point. | ||
1035 | */ | ||
1036 | |||
1037 | static int probe_chip_type(struct legacy_probe *probe) | ||
1038 | { | ||
1039 | int mask = 1 << probe->slot; | ||
1040 | |||
1041 | if (probe->port == 0x1F0) { | ||
1042 | unsigned long flags; | ||
1043 | local_irq_save(flags); | ||
754 | /* Probes */ | 1044 | /* Probes */ |
755 | inb(0x1F5); | ||
756 | outb(inb(0x1F2) | 0x80, 0x1F2); | 1045 | outb(inb(0x1F2) | 0x80, 0x1F2); |
1046 | inb(0x1F5); | ||
757 | inb(0x1F2); | 1047 | inb(0x1F2); |
758 | inb(0x3F6); | 1048 | inb(0x3F6); |
759 | inb(0x3F6); | 1049 | inb(0x3F6); |
@@ -762,29 +1052,83 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl | |||
762 | 1052 | ||
763 | if ((inb(0x1F2) & 0x80) == 0) { | 1053 | if ((inb(0x1F2) & 0x80) == 0) { |
764 | /* PDC20230c or 20630 ? */ | 1054 | /* PDC20230c or 20630 ? */ |
765 | printk(KERN_INFO "PDC20230-C/20630 VLB ATA controller detected.\n"); | 1055 | printk(KERN_INFO "PDC20230-C/20630 VLB ATA controller" |
766 | pio_modes = 0x07; | 1056 | " detected.\n"); |
767 | ops = &pdc20230_port_ops; | ||
768 | iordy = ATA_FLAG_NO_IORDY; | ||
769 | udelay(100); | 1057 | udelay(100); |
770 | inb(0x1F5); | 1058 | inb(0x1F5); |
1059 | local_irq_restore(flags); | ||
1060 | return PDC20230; | ||
771 | } else { | 1061 | } else { |
772 | outb(0x55, 0x1F2); | 1062 | outb(0x55, 0x1F2); |
773 | inb(0x1F2); | 1063 | inb(0x1F2); |
774 | inb(0x1F2); | 1064 | inb(0x1F2); |
775 | if (inb(0x1F2) == 0x00) { | 1065 | if (inb(0x1F2) == 0x00) |
776 | printk(KERN_INFO "PDC20230-B VLB ATA controller detected.\n"); | 1066 | printk(KERN_INFO "PDC20230-B VLB ATA " |
777 | } | 1067 | "controller detected.\n"); |
1068 | local_irq_restore(flags); | ||
1069 | return BIOS; | ||
778 | } | 1070 | } |
779 | local_irq_restore(flags); | 1071 | local_irq_restore(flags); |
780 | } | 1072 | } |
781 | 1073 | ||
1074 | if (ht6560a & mask) | ||
1075 | return HT6560A; | ||
1076 | if (ht6560b & mask) | ||
1077 | return HT6560B; | ||
1078 | if (opti82c611a & mask) | ||
1079 | return OPTI611A; | ||
1080 | if (opti82c46x & mask) | ||
1081 | return OPTI46X; | ||
1082 | if (autospeed & mask) | ||
1083 | return SNOOP; | ||
1084 | return BIOS; | ||
1085 | } | ||
1086 | |||
1087 | |||
1088 | /** | ||
1089 | * legacy_init_one - attach a legacy interface | ||
1090 | * @pl: probe record | ||
1091 | * | ||
1092 | * Register an ISA bus IDE interface. Such interfaces are PIO and we | ||
1093 | * assume do not support IRQ sharing. | ||
1094 | */ | ||
1095 | |||
1096 | static __init int legacy_init_one(struct legacy_probe *probe) | ||
1097 | { | ||
1098 | struct legacy_controller *controller = &controllers[probe->type]; | ||
1099 | int pio_modes = controller->pio_mask; | ||
1100 | unsigned long io = probe->port; | ||
1101 | u32 mask = (1 << probe->slot); | ||
1102 | struct ata_port_operations *ops = controller->ops; | ||
1103 | struct legacy_data *ld = &legacy_data[probe->slot]; | ||
1104 | struct ata_host *host = NULL; | ||
1105 | struct ata_port *ap; | ||
1106 | struct platform_device *pdev; | ||
1107 | struct ata_device *dev; | ||
1108 | void __iomem *io_addr, *ctrl_addr; | ||
1109 | u32 iordy = (iordy_mask & mask) ? 0: ATA_FLAG_NO_IORDY; | ||
1110 | int ret; | ||
1111 | |||
1112 | iordy |= controller->flags; | ||
1113 | |||
1114 | pdev = platform_device_register_simple(DRV_NAME, probe->slot, NULL, 0); | ||
1115 | if (IS_ERR(pdev)) | ||
1116 | return PTR_ERR(pdev); | ||
782 | 1117 | ||
783 | /* Chip does mode setting by command snooping */ | 1118 | ret = -EBUSY; |
784 | if (ops == &legacy_port_ops && (autospeed & mask)) | 1119 | if (devm_request_region(&pdev->dev, io, 8, "pata_legacy") == NULL || |
785 | ops = &simple_port_ops; | 1120 | devm_request_region(&pdev->dev, io + 0x0206, 1, |
1121 | "pata_legacy") == NULL) | ||
1122 | goto fail; | ||
786 | 1123 | ||
787 | ret = -ENOMEM; | 1124 | ret = -ENOMEM; |
1125 | io_addr = devm_ioport_map(&pdev->dev, io, 8); | ||
1126 | ctrl_addr = devm_ioport_map(&pdev->dev, io + 0x0206, 1); | ||
1127 | if (!io_addr || !ctrl_addr) | ||
1128 | goto fail; | ||
1129 | if (controller->setup) | ||
1130 | if (controller->setup(probe, ld) < 0) | ||
1131 | goto fail; | ||
788 | host = ata_host_alloc(&pdev->dev, 1); | 1132 | host = ata_host_alloc(&pdev->dev, 1); |
789 | if (!host) | 1133 | if (!host) |
790 | goto fail; | 1134 | goto fail; |
@@ -799,17 +1143,30 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl | |||
799 | ata_std_ports(&ap->ioaddr); | 1143 | ata_std_ports(&ap->ioaddr); |
800 | ap->private_data = ld; | 1144 | ap->private_data = ld; |
801 | 1145 | ||
802 | ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", io, ctrl); | 1146 | ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", io, io + 0x0206); |
803 | 1147 | ||
804 | ret = ata_host_activate(host, irq, ata_interrupt, 0, &legacy_sht); | 1148 | ret = ata_host_activate(host, probe->irq, ata_interrupt, 0, |
1149 | &legacy_sht); | ||
805 | if (ret) | 1150 | if (ret) |
806 | goto fail; | 1151 | goto fail; |
807 | |||
808 | legacy_host[nr_legacy_host++] = dev_get_drvdata(&pdev->dev); | ||
809 | ld->platform_dev = pdev; | 1152 | ld->platform_dev = pdev; |
810 | return 0; | ||
811 | 1153 | ||
1154 | /* Nothing found means we drop the port as its probably not there */ | ||
1155 | |||
1156 | ret = -ENODEV; | ||
1157 | ata_link_for_each_dev(dev, &ap->link) { | ||
1158 | if (!ata_dev_absent(dev)) { | ||
1159 | legacy_host[probe->slot] = host; | ||
1160 | ld->platform_dev = pdev; | ||
1161 | return 0; | ||
1162 | } | ||
1163 | } | ||
812 | fail: | 1164 | fail: |
1165 | if (host) | ||
1166 | ata_host_detach(host); | ||
1167 | /* FIXME: use devm for this */ | ||
1168 | if (ld->timing) | ||
1169 | release_region(ld->timing, 2); | ||
813 | platform_device_unregister(pdev); | 1170 | platform_device_unregister(pdev); |
814 | return ret; | 1171 | return ret; |
815 | } | 1172 | } |
@@ -820,13 +1177,15 @@ fail: | |||
820 | * @master: set this if we find an ATA master | 1177 | * @master: set this if we find an ATA master |
821 | * @master: set this if we find an ATA secondary | 1178 | * @master: set this if we find an ATA secondary |
822 | * | 1179 | * |
823 | * A small number of vendors implemented early PCI ATA interfaces on bridge logic | 1180 | * A small number of vendors implemented early PCI ATA interfaces |
824 | * without the ATA interface being PCI visible. Where we have a matching PCI driver | 1181 | * on bridge logic without the ATA interface being PCI visible. |
825 | * we must skip the relevant device here. If we don't know about it then the legacy | 1182 | * Where we have a matching PCI driver we must skip the relevant |
826 | * driver is the right driver anyway. | 1183 | * device here. If we don't know about it then the legacy driver |
1184 | * is the right driver anyway. | ||
827 | */ | 1185 | */ |
828 | 1186 | ||
829 | static void legacy_check_special_cases(struct pci_dev *p, int *primary, int *secondary) | 1187 | static void legacy_check_special_cases(struct pci_dev *p, int *primary, |
1188 | int *secondary) | ||
830 | { | 1189 | { |
831 | /* Cyrix CS5510 pre SFF MWDMA ATA on the bridge */ | 1190 | /* Cyrix CS5510 pre SFF MWDMA ATA on the bridge */ |
832 | if (p->vendor == 0x1078 && p->device == 0x0000) { | 1191 | if (p->vendor == 0x1078 && p->device == 0x0000) { |
@@ -842,7 +1201,8 @@ static void legacy_check_special_cases(struct pci_dev *p, int *primary, int *sec | |||
842 | if (p->vendor == 0x8086 && p->device == 0x1234) { | 1201 | if (p->vendor == 0x8086 && p->device == 0x1234) { |
843 | u16 r; | 1202 | u16 r; |
844 | pci_read_config_word(p, 0x6C, &r); | 1203 | pci_read_config_word(p, 0x6C, &r); |
845 | if (r & 0x8000) { /* ATA port enabled */ | 1204 | if (r & 0x8000) { |
1205 | /* ATA port enabled */ | ||
846 | if (r & 0x4000) | 1206 | if (r & 0x4000) |
847 | *secondary = 1; | 1207 | *secondary = 1; |
848 | else | 1208 | else |
@@ -852,6 +1212,117 @@ static void legacy_check_special_cases(struct pci_dev *p, int *primary, int *sec | |||
852 | } | 1212 | } |
853 | } | 1213 | } |
854 | 1214 | ||
1215 | static __init void probe_opti_vlb(void) | ||
1216 | { | ||
1217 | /* If an OPTI 82C46X is present find out where the channels are */ | ||
1218 | static const char *optis[4] = { | ||
1219 | "3/463MV", "5MV", | ||
1220 | "5MVA", "5MVB" | ||
1221 | }; | ||
1222 | u8 chans = 1; | ||
1223 | u8 ctrl = (opti_syscfg(0x30) & 0xC0) >> 6; | ||
1224 | |||
1225 | opti82c46x = 3; /* Assume master and slave first */ | ||
1226 | printk(KERN_INFO DRV_NAME ": Opti 82C46%s chipset support.\n", | ||
1227 | optis[ctrl]); | ||
1228 | if (ctrl == 3) | ||
1229 | chans = (opti_syscfg(0x3F) & 0x20) ? 2 : 1; | ||
1230 | ctrl = opti_syscfg(0xAC); | ||
1231 | /* Check enabled and this port is the 465MV port. On the | ||
1232 | MVB we may have two channels */ | ||
1233 | if (ctrl & 8) { | ||
1234 | if (chans == 2) { | ||
1235 | legacy_probe_add(0x1F0, 14, OPTI46X, 0); | ||
1236 | legacy_probe_add(0x170, 15, OPTI46X, 0); | ||
1237 | } | ||
1238 | if (ctrl & 4) | ||
1239 | legacy_probe_add(0x170, 15, OPTI46X, 0); | ||
1240 | else | ||
1241 | legacy_probe_add(0x1F0, 14, OPTI46X, 0); | ||
1242 | } else | ||
1243 | legacy_probe_add(0x1F0, 14, OPTI46X, 0); | ||
1244 | } | ||
1245 | |||
1246 | static __init void qdi65_identify_port(u8 r, u8 res, unsigned long port) | ||
1247 | { | ||
1248 | static const unsigned long ide_port[2] = { 0x170, 0x1F0 }; | ||
1249 | /* Check card type */ | ||
1250 | if ((r & 0xF0) == 0xC0) { | ||
1251 | /* QD6500: single channel */ | ||
1252 | if (r & 8) { | ||
1253 | /* Disabled ? */ | ||
1254 | release_region(port, 2); | ||
1255 | return; | ||
1256 | } | ||
1257 | legacy_probe_add(ide_port[r & 0x01], 14 + (r & 0x01), | ||
1258 | QDI6500, port); | ||
1259 | } | ||
1260 | if (((r & 0xF0) == 0xA0) || (r & 0xF0) == 0x50) { | ||
1261 | /* QD6580: dual channel */ | ||
1262 | if (!request_region(port + 2 , 2, "pata_qdi")) { | ||
1263 | release_region(port, 2); | ||
1264 | return; | ||
1265 | } | ||
1266 | res = inb(port + 3); | ||
1267 | /* Single channel mode ? */ | ||
1268 | if (res & 1) | ||
1269 | legacy_probe_add(ide_port[r & 0x01], 14 + (r & 0x01), | ||
1270 | QDI6580, port); | ||
1271 | else { /* Dual channel mode */ | ||
1272 | legacy_probe_add(0x1F0, 14, QDI6580DP, port); | ||
1273 | /* port + 0x02, r & 0x04 */ | ||
1274 | legacy_probe_add(0x170, 15, QDI6580DP, port + 2); | ||
1275 | } | ||
1276 | } | ||
1277 | } | ||
1278 | |||
1279 | static __init void probe_qdi_vlb(void) | ||
1280 | { | ||
1281 | unsigned long flags; | ||
1282 | static const unsigned long qd_port[2] = { 0x30, 0xB0 }; | ||
1283 | int i; | ||
1284 | |||
1285 | /* | ||
1286 | * Check each possible QD65xx base address | ||
1287 | */ | ||
1288 | |||
1289 | for (i = 0; i < 2; i++) { | ||
1290 | unsigned long port = qd_port[i]; | ||
1291 | u8 r, res; | ||
1292 | |||
1293 | |||
1294 | if (request_region(port, 2, "pata_qdi")) { | ||
1295 | /* Check for a card */ | ||
1296 | local_irq_save(flags); | ||
1297 | /* I have no h/w that needs this delay but it | ||
1298 | is present in the historic code */ | ||
1299 | r = inb(port); | ||
1300 | udelay(1); | ||
1301 | outb(0x19, port); | ||
1302 | udelay(1); | ||
1303 | res = inb(port); | ||
1304 | udelay(1); | ||
1305 | outb(r, port); | ||
1306 | udelay(1); | ||
1307 | local_irq_restore(flags); | ||
1308 | |||
1309 | /* Fail */ | ||
1310 | if (res == 0x19) { | ||
1311 | release_region(port, 2); | ||
1312 | continue; | ||
1313 | } | ||
1314 | /* Passes the presence test */ | ||
1315 | r = inb(port + 1); | ||
1316 | udelay(1); | ||
1317 | /* Check port agrees with port set */ | ||
1318 | if ((r & 2) >> 1 != i) { | ||
1319 | release_region(port, 2); | ||
1320 | continue; | ||
1321 | } | ||
1322 | qdi65_identify_port(r, res, port); | ||
1323 | } | ||
1324 | } | ||
1325 | } | ||
855 | 1326 | ||
856 | /** | 1327 | /** |
857 | * legacy_init - attach legacy interfaces | 1328 | * legacy_init - attach legacy interfaces |
@@ -869,15 +1340,17 @@ static __init int legacy_init(void) | |||
869 | int ct = 0; | 1340 | int ct = 0; |
870 | int primary = 0; | 1341 | int primary = 0; |
871 | int secondary = 0; | 1342 | int secondary = 0; |
872 | int last_port = NR_HOST; | 1343 | int pci_present = 0; |
1344 | struct legacy_probe *pl = &probe_list[0]; | ||
1345 | int slot = 0; | ||
873 | 1346 | ||
874 | struct pci_dev *p = NULL; | 1347 | struct pci_dev *p = NULL; |
875 | 1348 | ||
876 | for_each_pci_dev(p) { | 1349 | for_each_pci_dev(p) { |
877 | int r; | 1350 | int r; |
878 | /* Check for any overlap of the system ATA mappings. Native mode controllers | 1351 | /* Check for any overlap of the system ATA mappings. Native |
879 | stuck on these addresses or some devices in 'raid' mode won't be found by | 1352 | mode controllers stuck on these addresses or some devices |
880 | the storage class test */ | 1353 | in 'raid' mode won't be found by the storage class test */ |
881 | for (r = 0; r < 6; r++) { | 1354 | for (r = 0; r < 6; r++) { |
882 | if (pci_resource_start(p, r) == 0x1f0) | 1355 | if (pci_resource_start(p, r) == 0x1f0) |
883 | primary = 1; | 1356 | primary = 1; |
@@ -887,49 +1360,37 @@ static __init int legacy_init(void) | |||
887 | /* Check for special cases */ | 1360 | /* Check for special cases */ |
888 | legacy_check_special_cases(p, &primary, &secondary); | 1361 | legacy_check_special_cases(p, &primary, &secondary); |
889 | 1362 | ||
890 | /* If PCI bus is present then don't probe for tertiary legacy ports */ | 1363 | /* If PCI bus is present then don't probe for tertiary |
891 | if (probe_all == 0) | 1364 | legacy ports */ |
892 | last_port = 2; | 1365 | pci_present = 1; |
893 | } | 1366 | } |
894 | 1367 | ||
895 | /* If an OPTI 82C46X is present find out where the channels are */ | 1368 | if (primary == 0 || all) |
896 | if (opti82c46x) { | 1369 | legacy_probe_add(0x1F0, 14, UNKNOWN, 0); |
897 | static const char *optis[4] = { | 1370 | if (secondary == 0 || all) |
898 | "3/463MV", "5MV", | 1371 | legacy_probe_add(0x170, 15, UNKNOWN, 0); |
899 | "5MVA", "5MVB" | 1372 | |
900 | }; | 1373 | if (probe_all || !pci_present) { |
901 | u8 chans = 1; | 1374 | /* ISA/VLB extra ports */ |
902 | u8 ctrl = (opti_syscfg(0x30) & 0xC0) >> 6; | 1375 | legacy_probe_add(0x1E8, 11, UNKNOWN, 0); |
903 | 1376 | legacy_probe_add(0x168, 10, UNKNOWN, 0); | |
904 | opti82c46x = 3; /* Assume master and slave first */ | 1377 | legacy_probe_add(0x1E0, 8, UNKNOWN, 0); |
905 | printk(KERN_INFO DRV_NAME ": Opti 82C46%s chipset support.\n", optis[ctrl]); | 1378 | legacy_probe_add(0x160, 12, UNKNOWN, 0); |
906 | if (ctrl == 3) | ||
907 | chans = (opti_syscfg(0x3F) & 0x20) ? 2 : 1; | ||
908 | ctrl = opti_syscfg(0xAC); | ||
909 | /* Check enabled and this port is the 465MV port. On the | ||
910 | MVB we may have two channels */ | ||
911 | if (ctrl & 8) { | ||
912 | if (ctrl & 4) | ||
913 | opti82c46x = 2; /* Slave */ | ||
914 | else | ||
915 | opti82c46x = 1; /* Master */ | ||
916 | if (chans == 2) | ||
917 | opti82c46x = 3; /* Master and Slave */ | ||
918 | } /* Slave only */ | ||
919 | else if (chans == 1) | ||
920 | opti82c46x = 1; | ||
921 | } | 1379 | } |
922 | 1380 | ||
923 | for (i = 0; i < last_port; i++) { | 1381 | if (opti82c46x) |
924 | /* Skip primary if we have seen a PCI one */ | 1382 | probe_opti_vlb(); |
925 | if (i == 0 && primary == 1) | 1383 | if (qdi) |
926 | continue; | 1384 | probe_qdi_vlb(); |
927 | /* Skip secondary if we have seen a PCI one */ | 1385 | |
928 | if (i == 1 && secondary == 1) | 1386 | |
1387 | for (i = 0; i < NR_HOST; i++, pl++) { | ||
1388 | if (pl->port == 0) | ||
929 | continue; | 1389 | continue; |
930 | if (legacy_init_one(i, legacy_port[i], | 1390 | if (pl->type == UNKNOWN) |
931 | legacy_port[i] + 0x0206, | 1391 | pl->type = probe_chip_type(pl); |
932 | legacy_irq[i]) == 0) | 1392 | pl->slot = slot++; |
1393 | if (legacy_init_one(pl) == 0) | ||
933 | ct++; | 1394 | ct++; |
934 | } | 1395 | } |
935 | if (ct != 0) | 1396 | if (ct != 0) |
@@ -943,7 +1404,6 @@ static __exit void legacy_exit(void) | |||
943 | 1404 | ||
944 | for (i = 0; i < nr_legacy_host; i++) { | 1405 | for (i = 0; i < nr_legacy_host; i++) { |
945 | struct legacy_data *ld = &legacy_data[i]; | 1406 | struct legacy_data *ld = &legacy_data[i]; |
946 | |||
947 | ata_host_detach(legacy_host[i]); | 1407 | ata_host_detach(legacy_host[i]); |
948 | platform_device_unregister(ld->platform_dev); | 1408 | platform_device_unregister(ld->platform_dev); |
949 | if (ld->timing) | 1409 | if (ld->timing) |
@@ -962,9 +1422,9 @@ module_param(ht6560a, int, 0); | |||
962 | module_param(ht6560b, int, 0); | 1422 | module_param(ht6560b, int, 0); |
963 | module_param(opti82c611a, int, 0); | 1423 | module_param(opti82c611a, int, 0); |
964 | module_param(opti82c46x, int, 0); | 1424 | module_param(opti82c46x, int, 0); |
1425 | module_param(qdi, int, 0); | ||
965 | module_param(pio_mask, int, 0); | 1426 | module_param(pio_mask, int, 0); |
966 | module_param(iordy_mask, int, 0); | 1427 | module_param(iordy_mask, int, 0); |
967 | 1428 | ||
968 | module_init(legacy_init); | 1429 | module_init(legacy_init); |
969 | module_exit(legacy_exit); | 1430 | module_exit(legacy_exit); |
970 | |||