1c82ee6d3SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2669a5db4SJeff Garzik /*
3669a5db4SJeff Garzik * pata-legacy.c - Legacy port PATA/SATA controller driver.
4ab771630SAlan Cox * Copyright 2005/2006 Red Hat, all rights reserved.
5669a5db4SJeff Garzik *
6669a5db4SJeff Garzik * An ATA driver for the legacy ATA ports.
7669a5db4SJeff Garzik *
8669a5db4SJeff Garzik * Data Sources:
9669a5db4SJeff Garzik * Opti 82C465/82C611 support: Data sheets at opti-inc.com
10669a5db4SJeff Garzik * HT6560 series:
11669a5db4SJeff Garzik * Promise 20230/20620:
12669a5db4SJeff Garzik * http://www.ryston.cz/petr/vlb/pdc20230b.html
13669a5db4SJeff Garzik * http://www.ryston.cz/petr/vlb/pdc20230c.html
14669a5db4SJeff Garzik * http://www.ryston.cz/petr/vlb/pdc20630.html
159c7e0d22SBartlomiej Zolnierkiewicz * QDI65x0:
169c7e0d22SBartlomiej Zolnierkiewicz * http://www.ryston.cz/petr/vlb/qd6500.html
179c7e0d22SBartlomiej Zolnierkiewicz * http://www.ryston.cz/petr/vlb/qd6580.html
189c7e0d22SBartlomiej Zolnierkiewicz *
199c7e0d22SBartlomiej Zolnierkiewicz * QDI65x0 probe code based on drivers/ide/legacy/qd65xx.c
209c7e0d22SBartlomiej Zolnierkiewicz * Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by
219c7e0d22SBartlomiej Zolnierkiewicz * Samuel Thibault <samuel.thibault@ens-lyon.org>
22669a5db4SJeff Garzik *
23669a5db4SJeff Garzik * Unsupported but docs exist:
24669a5db4SJeff Garzik * Appian/Adaptec AIC25VL01/Cirrus Logic PD7220
25669a5db4SJeff Garzik *
26669a5db4SJeff Garzik * This driver handles legacy (that is "ISA/VLB side") IDE ports found
27669a5db4SJeff Garzik * on PC class systems. There are three hybrid devices that are exceptions
28669a5db4SJeff Garzik * The Cyrix 5510/5520 where a pre SFF ATA device is on the bridge and
29669a5db4SJeff Garzik * the MPIIX where the tuning is PCI side but the IDE is "ISA side".
30669a5db4SJeff Garzik *
31669a5db4SJeff Garzik * Specific support is included for the ht6560a/ht6560b/opti82c611a/
329c7e0d22SBartlomiej Zolnierkiewicz * opti82c465mv/promise 20230c/20630/qdi65x0/winbond83759A
33669a5db4SJeff Garzik *
346d981b9aSBartlomiej Zolnierkiewicz * Support for the Winbond 83759A when operating in advanced mode.
356d981b9aSBartlomiej Zolnierkiewicz * Multichip mode is not currently supported.
366d981b9aSBartlomiej Zolnierkiewicz *
37669a5db4SJeff Garzik * Use the autospeed and pio_mask options with:
38669a5db4SJeff Garzik * Appian ADI/2 aka CLPD7220 or AIC25VL01.
39669a5db4SJeff Garzik * Use the jumpers, autospeed and set pio_mask to the mode on the jumpers with
40669a5db4SJeff Garzik * Goldstar GM82C711, PIC-1288A-125, UMC 82C871F, Winbond W83759,
41669a5db4SJeff Garzik * Winbond W83759A, Promise PDC20230-B
42669a5db4SJeff Garzik *
43669a5db4SJeff Garzik * For now use autospeed and pio_mask as above with the W83759A. This may
44669a5db4SJeff Garzik * change.
45669a5db4SJeff Garzik */
46669a5db4SJeff Garzik
4745bc955bSJames Bottomley #include <linux/async.h>
48669a5db4SJeff Garzik #include <linux/kernel.h>
49669a5db4SJeff Garzik #include <linux/module.h>
50669a5db4SJeff Garzik #include <linux/pci.h>
51669a5db4SJeff Garzik #include <linux/init.h>
52669a5db4SJeff Garzik #include <linux/blkdev.h>
53669a5db4SJeff Garzik #include <linux/delay.h>
54669a5db4SJeff Garzik #include <scsi/scsi_host.h>
55669a5db4SJeff Garzik #include <linux/ata.h>
56669a5db4SJeff Garzik #include <linux/libata.h>
57669a5db4SJeff Garzik #include <linux/platform_device.h>
58669a5db4SJeff Garzik
59669a5db4SJeff Garzik #define DRV_NAME "pata_legacy"
60b8325487SAlan Cox #define DRV_VERSION "0.6.5"
61669a5db4SJeff Garzik
62669a5db4SJeff Garzik #define NR_HOST 6
63669a5db4SJeff Garzik
64defc9cd8SAlan Cox static int all;
65defc9cd8SAlan Cox module_param(all, int, 0444);
66426e2c6aSMaciej W. Rozycki MODULE_PARM_DESC(all,
67426e2c6aSMaciej W. Rozycki "Set to probe unclaimed pri/sec ISA port ranges even if PCI");
68426e2c6aSMaciej W. Rozycki
69426e2c6aSMaciej W. Rozycki static int probe_all;
70426e2c6aSMaciej W. Rozycki module_param(probe_all, int, 0);
71426e2c6aSMaciej W. Rozycki MODULE_PARM_DESC(probe_all,
72426e2c6aSMaciej W. Rozycki "Set to probe tertiary+ ISA port ranges even if PCI");
73426e2c6aSMaciej W. Rozycki
747d33004dSMaciej W. Rozycki static int probe_mask = ~0;
757d33004dSMaciej W. Rozycki module_param(probe_mask, int, 0);
767d33004dSMaciej W. Rozycki MODULE_PARM_DESC(probe_mask, "Probe mask for legacy ISA PATA ports");
777d33004dSMaciej W. Rozycki
78426e2c6aSMaciej W. Rozycki static int autospeed;
79426e2c6aSMaciej W. Rozycki module_param(autospeed, int, 0);
80426e2c6aSMaciej W. Rozycki MODULE_PARM_DESC(autospeed, "Chip present that snoops speed changes");
81426e2c6aSMaciej W. Rozycki
82426e2c6aSMaciej W. Rozycki static int pio_mask = ATA_PIO4;
83426e2c6aSMaciej W. Rozycki module_param(pio_mask, int, 0);
84426e2c6aSMaciej W. Rozycki MODULE_PARM_DESC(pio_mask, "PIO range for autospeed devices");
85426e2c6aSMaciej W. Rozycki
86426e2c6aSMaciej W. Rozycki static int iordy_mask = 0xFFFFFFFF;
87426e2c6aSMaciej W. Rozycki module_param(iordy_mask, int, 0);
88426e2c6aSMaciej W. Rozycki MODULE_PARM_DESC(iordy_mask, "Use IORDY if available");
89426e2c6aSMaciej W. Rozycki
90426e2c6aSMaciej W. Rozycki static int ht6560a;
91426e2c6aSMaciej W. Rozycki module_param(ht6560a, int, 0);
92426e2c6aSMaciej W. Rozycki MODULE_PARM_DESC(ht6560a, "HT 6560A on primary 1, second 2, both 3");
93426e2c6aSMaciej W. Rozycki
94426e2c6aSMaciej W. Rozycki static int ht6560b;
95426e2c6aSMaciej W. Rozycki module_param(ht6560b, int, 0);
96426e2c6aSMaciej W. Rozycki MODULE_PARM_DESC(ht6560b, "HT 6560B on primary 1, secondary 2, both 3");
97426e2c6aSMaciej W. Rozycki
98426e2c6aSMaciej W. Rozycki static int opti82c611a;
99426e2c6aSMaciej W. Rozycki module_param(opti82c611a, int, 0);
100426e2c6aSMaciej W. Rozycki MODULE_PARM_DESC(opti82c611a,
101426e2c6aSMaciej W. Rozycki "Opti 82c611A on primary 1, secondary 2, both 3");
102426e2c6aSMaciej W. Rozycki
103426e2c6aSMaciej W. Rozycki static int opti82c46x;
104426e2c6aSMaciej W. Rozycki module_param(opti82c46x, int, 0);
105426e2c6aSMaciej W. Rozycki MODULE_PARM_DESC(opti82c46x,
106426e2c6aSMaciej W. Rozycki "Opti 82c465MV on primary 1, secondary 2, both 3");
107426e2c6aSMaciej W. Rozycki
108426e2c6aSMaciej W. Rozycki #ifdef CONFIG_PATA_QDI_MODULE
109426e2c6aSMaciej W. Rozycki static int qdi = 1;
110426e2c6aSMaciej W. Rozycki #else
111426e2c6aSMaciej W. Rozycki static int qdi;
112426e2c6aSMaciej W. Rozycki #endif
113426e2c6aSMaciej W. Rozycki module_param(qdi, int, 0);
114426e2c6aSMaciej W. Rozycki MODULE_PARM_DESC(qdi, "Set to probe QDI controllers");
115426e2c6aSMaciej W. Rozycki
116426e2c6aSMaciej W. Rozycki #ifdef CONFIG_PATA_WINBOND_VLB_MODULE
117426e2c6aSMaciej W. Rozycki static int winbond = 1;
118426e2c6aSMaciej W. Rozycki #else
119426e2c6aSMaciej W. Rozycki static int winbond;
120426e2c6aSMaciej W. Rozycki #endif
121426e2c6aSMaciej W. Rozycki module_param(winbond, int, 0);
122426e2c6aSMaciej W. Rozycki MODULE_PARM_DESC(winbond,
123426e2c6aSMaciej W. Rozycki "Set to probe Winbond controllers, "
124426e2c6aSMaciej W. Rozycki "give I/O port if non standard");
125426e2c6aSMaciej W. Rozycki
126669a5db4SJeff Garzik
127defc9cd8SAlan Cox enum controller {
128defc9cd8SAlan Cox BIOS = 0,
129defc9cd8SAlan Cox SNOOP = 1,
130defc9cd8SAlan Cox PDC20230 = 2,
131defc9cd8SAlan Cox HT6560A = 3,
132defc9cd8SAlan Cox HT6560B = 4,
133defc9cd8SAlan Cox OPTI611A = 5,
134defc9cd8SAlan Cox OPTI46X = 6,
135defc9cd8SAlan Cox QDI6500 = 7,
136defc9cd8SAlan Cox QDI6580 = 8,
137defc9cd8SAlan Cox QDI6580DP = 9, /* Dual channel mode is different */
138b8325487SAlan Cox W83759A = 10,
139defc9cd8SAlan Cox
140defc9cd8SAlan Cox UNKNOWN = -1
141defc9cd8SAlan Cox };
142defc9cd8SAlan Cox
1438c7e8f94SBartlomiej Zolnierkiewicz struct legacy_data {
1448c7e8f94SBartlomiej Zolnierkiewicz unsigned long timing;
1458c7e8f94SBartlomiej Zolnierkiewicz u8 clock[2];
1468c7e8f94SBartlomiej Zolnierkiewicz u8 last;
1478c7e8f94SBartlomiej Zolnierkiewicz int fast;
1488c7e8f94SBartlomiej Zolnierkiewicz enum controller type;
1498c7e8f94SBartlomiej Zolnierkiewicz struct platform_device *platform_dev;
1508c7e8f94SBartlomiej Zolnierkiewicz };
151defc9cd8SAlan Cox
152defc9cd8SAlan Cox struct legacy_probe {
153defc9cd8SAlan Cox unsigned char *name;
154defc9cd8SAlan Cox unsigned long port;
155defc9cd8SAlan Cox unsigned int irq;
156defc9cd8SAlan Cox unsigned int slot;
157defc9cd8SAlan Cox enum controller type;
158defc9cd8SAlan Cox unsigned long private;
159defc9cd8SAlan Cox };
160defc9cd8SAlan Cox
161defc9cd8SAlan Cox struct legacy_controller {
162defc9cd8SAlan Cox const char *name;
163defc9cd8SAlan Cox struct ata_port_operations *ops;
164defc9cd8SAlan Cox unsigned int pio_mask;
165defc9cd8SAlan Cox unsigned int flags;
166e3cf95ddSAlan Cox unsigned int pflags;
167b8325487SAlan Cox int (*setup)(struct platform_device *, struct legacy_probe *probe,
168b8325487SAlan Cox struct legacy_data *data);
169defc9cd8SAlan Cox };
170defc9cd8SAlan Cox
171defc9cd8SAlan Cox static int legacy_port[NR_HOST] = { 0x1f0, 0x170, 0x1e8, 0x168, 0x1e0, 0x160 };
172defc9cd8SAlan Cox
173defc9cd8SAlan Cox static struct legacy_probe probe_list[NR_HOST];
174669a5db4SJeff Garzik static struct legacy_data legacy_data[NR_HOST];
175669a5db4SJeff Garzik static struct ata_host *legacy_host[NR_HOST];
176669a5db4SJeff Garzik
177669a5db4SJeff Garzik /**
178669a5db4SJeff Garzik * legacy_probe_add - Add interface to probe list
179669a5db4SJeff Garzik * @port: Controller port
180defc9cd8SAlan Cox * @irq: IRQ number
181defc9cd8SAlan Cox * @type: Controller type
182defc9cd8SAlan Cox * @private: Controller specific info
183defc9cd8SAlan Cox *
184defc9cd8SAlan Cox * Add an entry into the probe list for ATA controllers. This is used
185defc9cd8SAlan Cox * to add the default ISA slots and then to build up the table
186defc9cd8SAlan Cox * further according to other ISA/VLB/Weird device scans
187defc9cd8SAlan Cox *
188defc9cd8SAlan Cox * An I/O port list is used to keep ordering stable and sane, as we
189defc9cd8SAlan Cox * don't have any good way to talk about ordering otherwise
190defc9cd8SAlan Cox */
191defc9cd8SAlan Cox
legacy_probe_add(unsigned long port,unsigned int irq,enum controller type,unsigned long private)192defc9cd8SAlan Cox static int legacy_probe_add(unsigned long port, unsigned int irq,
193defc9cd8SAlan Cox enum controller type, unsigned long private)
194defc9cd8SAlan Cox {
195defc9cd8SAlan Cox struct legacy_probe *lp = &probe_list[0];
196defc9cd8SAlan Cox int i;
197defc9cd8SAlan Cox struct legacy_probe *free = NULL;
198defc9cd8SAlan Cox
199defc9cd8SAlan Cox for (i = 0; i < NR_HOST; i++) {
200defc9cd8SAlan Cox if (lp->port == 0 && free == NULL)
201defc9cd8SAlan Cox free = lp;
202defc9cd8SAlan Cox /* Matching port, or the correct slot for ordering */
203defc9cd8SAlan Cox if (lp->port == port || legacy_port[i] == port) {
204defc9cd8SAlan Cox if (!(probe_mask & 1 << i))
205defc9cd8SAlan Cox return -1;
2067d33004dSMaciej W. Rozycki free = lp;
2077d33004dSMaciej W. Rozycki break;
208defc9cd8SAlan Cox }
209defc9cd8SAlan Cox lp++;
210defc9cd8SAlan Cox }
211defc9cd8SAlan Cox if (free == NULL) {
212defc9cd8SAlan Cox printk(KERN_ERR "pata_legacy: Too many interfaces.\n");
213defc9cd8SAlan Cox return -1;
214defc9cd8SAlan Cox }
215defc9cd8SAlan Cox /* Fill in the entry for later probing */
216defc9cd8SAlan Cox free->port = port;
217defc9cd8SAlan Cox free->irq = irq;
218defc9cd8SAlan Cox free->type = type;
219defc9cd8SAlan Cox free->private = private;
220defc9cd8SAlan Cox return 0;
221defc9cd8SAlan Cox }
222defc9cd8SAlan Cox
223defc9cd8SAlan Cox
224defc9cd8SAlan Cox /**
225defc9cd8SAlan Cox * legacy_set_mode - mode setting
226defc9cd8SAlan Cox * @link: IDE link
227669a5db4SJeff Garzik * @unused: Device that failed when error is returned
2280260731fSTejun Heo *
229b229a7b0SAlan * Use a non standard set_mode function. We don't want to be tuned.
230669a5db4SJeff Garzik *
231669a5db4SJeff Garzik * The BIOS configured everything. Our job is not to fiddle. Just use
232669a5db4SJeff Garzik * whatever PIO the hardware is using and leave it at that. When we
233669a5db4SJeff Garzik * get some kind of nice user driven API for control then we can
234669a5db4SJeff Garzik * expand on this as per hdparm in the base kernel.
235669a5db4SJeff Garzik */
236669a5db4SJeff Garzik
legacy_set_mode(struct ata_link * link,struct ata_device ** unused)237669a5db4SJeff Garzik static int legacy_set_mode(struct ata_link *link, struct ata_device **unused)
238669a5db4SJeff Garzik {
2390260731fSTejun Heo struct ata_device *dev;
240669a5db4SJeff Garzik
241f58229f8STejun Heo ata_for_each_dev(dev, link, ENABLED) {
242669a5db4SJeff Garzik ata_dev_info(dev, "configured for PIO\n");
2431eca4365STejun Heo dev->pio_mode = XFER_PIO_0;
244a9a79dfeSJoe Perches dev->xfer_mode = XFER_PIO_0;
245669a5db4SJeff Garzik dev->xfer_shift = ATA_SHIFT_PIO;
246669a5db4SJeff Garzik dev->flags |= ATA_DFLAG_PIO;
247669a5db4SJeff Garzik }
248669a5db4SJeff Garzik return 0;
249669a5db4SJeff Garzik }
250b229a7b0SAlan
251669a5db4SJeff Garzik static const struct scsi_host_template legacy_sht = {
252669a5db4SJeff Garzik ATA_PIO_SHT(DRV_NAME),
253669a5db4SJeff Garzik };
25468d1d07bSTejun Heo
255669a5db4SJeff Garzik static const struct ata_port_operations legacy_base_port_ops = {
256669a5db4SJeff Garzik .inherits = &ata_sff_port_ops,
257029cfd6bSTejun Heo .cable_detect = ata_cable_40wire,
258029cfd6bSTejun Heo };
259029cfd6bSTejun Heo
260029cfd6bSTejun Heo /*
261029cfd6bSTejun Heo * These ops are used if the user indicates the hardware
262669a5db4SJeff Garzik * snoops the commands to decide on the mode and handles the
263669a5db4SJeff Garzik * mode selection "magically" itself. Several legacy controllers
264669a5db4SJeff Garzik * do this. The mode range can be set if it is not 0x1F by setting
265669a5db4SJeff Garzik * pio_mask as well.
266669a5db4SJeff Garzik */
267669a5db4SJeff Garzik
268669a5db4SJeff Garzik static struct ata_port_operations simple_port_ops = {
269669a5db4SJeff Garzik .inherits = &legacy_base_port_ops,
270669a5db4SJeff Garzik .sff_data_xfer = ata_sff_data_xfer32,
271029cfd6bSTejun Heo };
27223ebda2fSSebastian Andrzej Siewior
273669a5db4SJeff Garzik static struct ata_port_operations legacy_port_ops = {
274669a5db4SJeff Garzik .inherits = &legacy_base_port_ops,
275669a5db4SJeff Garzik .sff_data_xfer = ata_sff_data_xfer32,
276029cfd6bSTejun Heo .set_mode = legacy_set_mode,
27723ebda2fSSebastian Andrzej Siewior };
278029cfd6bSTejun Heo
279669a5db4SJeff Garzik /*
280669a5db4SJeff Garzik * Promise 20230C and 20620 support
281669a5db4SJeff Garzik *
282669a5db4SJeff Garzik * This controller supports PIO0 to PIO2. We set PIO timings
283669a5db4SJeff Garzik * conservatively to allow for 50MHz Vesa Local Bus. The 20620 DMA
284defc9cd8SAlan Cox * support is weird being DMA to controller and PIO'd to the host
285defc9cd8SAlan Cox * and not supported.
286defc9cd8SAlan Cox */
287defc9cd8SAlan Cox
pdc20230_set_piomode(struct ata_port * ap,struct ata_device * adev)288669a5db4SJeff Garzik static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev)
289669a5db4SJeff Garzik {
290669a5db4SJeff Garzik int tries = 5;
291669a5db4SJeff Garzik int pio = adev->pio_mode - XFER_PIO_0;
292669a5db4SJeff Garzik u8 rt;
293669a5db4SJeff Garzik unsigned long flags;
294669a5db4SJeff Garzik
295669a5db4SJeff Garzik /* Safe as UP only. Force I/Os to occur together */
296669a5db4SJeff Garzik
297669a5db4SJeff Garzik local_irq_save(flags);
298669a5db4SJeff Garzik
299669a5db4SJeff Garzik /* Unlock the control interface */
300669a5db4SJeff Garzik do {
301669a5db4SJeff Garzik inb(0x1F5);
302defc9cd8SAlan Cox outb(inb(0x1F2) | 0x80, 0x1F2);
303669a5db4SJeff Garzik inb(0x1F2);
304669a5db4SJeff Garzik inb(0x3F6);
305669a5db4SJeff Garzik inb(0x3F6);
306669a5db4SJeff Garzik inb(0x1F2);
307669a5db4SJeff Garzik inb(0x1F2);
308669a5db4SJeff Garzik }
309669a5db4SJeff Garzik while ((inb(0x1F2) & 0x80) && --tries);
310669a5db4SJeff Garzik
311669a5db4SJeff Garzik local_irq_restore(flags);
312669a5db4SJeff Garzik
313669a5db4SJeff Garzik outb(inb(0x1F4) & 0x07, 0x1F4);
314669a5db4SJeff Garzik
315669a5db4SJeff Garzik rt = inb(0x1F3);
316669a5db4SJeff Garzik rt &= ~(0x07 << (3 * !adev->devno));
317669a5db4SJeff Garzik if (pio)
318*171a9318SSergey Shtylyov rt |= (1 + 3 * pio) << (3 * !adev->devno);
319669a5db4SJeff Garzik outb(rt, 0x1F3);
320*171a9318SSergey Shtylyov
321*171a9318SSergey Shtylyov udelay(100);
322669a5db4SJeff Garzik outb(inb(0x1F2) | 0x01, 0x1F2);
323669a5db4SJeff Garzik udelay(100);
324669a5db4SJeff Garzik inb(0x1F5);
325669a5db4SJeff Garzik
326669a5db4SJeff Garzik }
327669a5db4SJeff Garzik
pdc_data_xfer_vlb(struct ata_queued_cmd * qc,unsigned char * buf,unsigned int buflen,int rw)328669a5db4SJeff Garzik static unsigned int pdc_data_xfer_vlb(struct ata_queued_cmd *qc,
329669a5db4SJeff Garzik unsigned char *buf, unsigned int buflen, int rw)
330989e0aacSBartlomiej Zolnierkiewicz {
33155dba312STejun Heo struct ata_device *dev = qc->dev;
332669a5db4SJeff Garzik struct ata_port *ap = dev->link->ap;
333989e0aacSBartlomiej Zolnierkiewicz int slop = buflen & 3;
33416e6aecaSZhenwen Xu
335989e0aacSBartlomiej Zolnierkiewicz /* 32bit I/O capable *and* we need to write a whole number of dwords */
33616e6aecaSZhenwen Xu if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3)
337c55af1f5SAlan Cox && (ap->pflags & ATA_PFLAG_PIO32)) {
338e3cf95ddSAlan Cox unsigned long flags;
339e3cf95ddSAlan Cox
340669a5db4SJeff Garzik local_irq_save(flags);
341669a5db4SJeff Garzik
342669a5db4SJeff Garzik /* Perform the 32bit I/O synchronization sequence */
343669a5db4SJeff Garzik ioread8(ap->ioaddr.nsect_addr);
344669a5db4SJeff Garzik ioread8(ap->ioaddr.nsect_addr);
3450d5ff566STejun Heo ioread8(ap->ioaddr.nsect_addr);
3460d5ff566STejun Heo
3470d5ff566STejun Heo /* Now the data */
348669a5db4SJeff Garzik if (rw == READ)
349669a5db4SJeff Garzik ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
35055dba312STejun Heo else
3510d5ff566STejun Heo iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
35255dba312STejun Heo
35355dba312STejun Heo if (unlikely(slop)) {
354669a5db4SJeff Garzik __le32 pad = 0;
355669a5db4SJeff Garzik
35601392347SDan Carpenter if (rw == READ) {
35701392347SDan Carpenter pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
35855dba312STejun Heo memcpy(buf + buflen - slop, &pad, slop);
359b50e56d8SAl Viro } else {
360669a5db4SJeff Garzik memcpy(&pad, buf + buflen - slop, slop);
36155dba312STejun Heo iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
36255dba312STejun Heo }
36355dba312STejun Heo buflen += 4 - slop;
364669a5db4SJeff Garzik }
36555dba312STejun Heo local_irq_restore(flags);
366669a5db4SJeff Garzik } else
367669a5db4SJeff Garzik buflen = ata_sff_data_xfer32(qc, buf, buflen, rw);
36855dba312STejun Heo
36923ebda2fSSebastian Andrzej Siewior return buflen;
37055dba312STejun Heo }
37155dba312STejun Heo
372669a5db4SJeff Garzik static struct ata_port_operations pdc20230_port_ops = {
373669a5db4SJeff Garzik .inherits = &legacy_base_port_ops,
374669a5db4SJeff Garzik .set_piomode = pdc20230_set_piomode,
375029cfd6bSTejun Heo .sff_data_xfer = pdc_data_xfer_vlb,
376669a5db4SJeff Garzik };
3775682ed33STejun Heo
378669a5db4SJeff Garzik /*
379669a5db4SJeff Garzik * Holtek 6560A support
380669a5db4SJeff Garzik *
381669a5db4SJeff Garzik * This controller supports PIO0 to PIO2 (no IORDY even though higher
382669a5db4SJeff Garzik * timings can be loaded).
383defc9cd8SAlan Cox */
384defc9cd8SAlan Cox
ht6560a_set_piomode(struct ata_port * ap,struct ata_device * adev)385669a5db4SJeff Garzik static void ht6560a_set_piomode(struct ata_port *ap, struct ata_device *adev)
386669a5db4SJeff Garzik {
387669a5db4SJeff Garzik u8 active, recover;
388669a5db4SJeff Garzik struct ata_timing t;
389669a5db4SJeff Garzik
390669a5db4SJeff Garzik /* Get the timing data in cycles. For now play safe at 50Mhz */
391669a5db4SJeff Garzik ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000);
392669a5db4SJeff Garzik
393669a5db4SJeff Garzik active = clamp_val(t.active, 2, 15);
394669a5db4SJeff Garzik recover = clamp_val(t.recover, 4, 15);
39507633b5dSHarvey Harrison
39607633b5dSHarvey Harrison inb(0x3E6);
397669a5db4SJeff Garzik inb(0x3E6);
398669a5db4SJeff Garzik inb(0x3E6);
399669a5db4SJeff Garzik inb(0x3E6);
400669a5db4SJeff Garzik
401669a5db4SJeff Garzik iowrite8(recover << 4 | active, ap->ioaddr.device_addr);
402669a5db4SJeff Garzik ioread8(ap->ioaddr.status_addr);
4030d5ff566STejun Heo }
4040d5ff566STejun Heo
405669a5db4SJeff Garzik static struct ata_port_operations ht6560a_port_ops = {
406669a5db4SJeff Garzik .inherits = &legacy_base_port_ops,
407669a5db4SJeff Garzik .set_piomode = ht6560a_set_piomode,
408029cfd6bSTejun Heo };
409669a5db4SJeff Garzik
410669a5db4SJeff Garzik /*
411669a5db4SJeff Garzik * Holtek 6560B support
412669a5db4SJeff Garzik *
413669a5db4SJeff Garzik * This controller supports PIO0 to PIO4. We honour the BIOS/jumper FIFO
414669a5db4SJeff Garzik * setting unless we see an ATAPI device in which case we force it off.
415defc9cd8SAlan Cox *
416defc9cd8SAlan Cox * FIXME: need to implement 2nd channel support.
417669a5db4SJeff Garzik */
418669a5db4SJeff Garzik
ht6560b_set_piomode(struct ata_port * ap,struct ata_device * adev)419669a5db4SJeff Garzik static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev)
420669a5db4SJeff Garzik {
421669a5db4SJeff Garzik u8 active, recover;
422669a5db4SJeff Garzik struct ata_timing t;
423669a5db4SJeff Garzik
424669a5db4SJeff Garzik /* Get the timing data in cycles. For now play safe at 50Mhz */
425669a5db4SJeff Garzik ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000);
426669a5db4SJeff Garzik
427669a5db4SJeff Garzik active = clamp_val(t.active, 2, 15);
428669a5db4SJeff Garzik recover = clamp_val(t.recover, 2, 16) & 0x0F;
42907633b5dSHarvey Harrison
43097163873SSergei Shtylyov inb(0x3E6);
431669a5db4SJeff Garzik inb(0x3E6);
432669a5db4SJeff Garzik inb(0x3E6);
433669a5db4SJeff Garzik inb(0x3E6);
434669a5db4SJeff Garzik
435669a5db4SJeff Garzik iowrite8(recover << 4 | active, ap->ioaddr.device_addr);
436669a5db4SJeff Garzik
4370d5ff566STejun Heo if (adev->class != ATA_DEV_ATA) {
438669a5db4SJeff Garzik u8 rconf = inb(0x3E6);
439669a5db4SJeff Garzik if (rconf & 0x24) {
440669a5db4SJeff Garzik rconf &= ~0x24;
441669a5db4SJeff Garzik outb(rconf, 0x3E6);
442669a5db4SJeff Garzik }
443669a5db4SJeff Garzik }
444669a5db4SJeff Garzik ioread8(ap->ioaddr.status_addr);
445669a5db4SJeff Garzik }
4460d5ff566STejun Heo
447669a5db4SJeff Garzik static struct ata_port_operations ht6560b_port_ops = {
448669a5db4SJeff Garzik .inherits = &legacy_base_port_ops,
449669a5db4SJeff Garzik .set_piomode = ht6560b_set_piomode,
450029cfd6bSTejun Heo };
451669a5db4SJeff Garzik
452669a5db4SJeff Garzik /*
453669a5db4SJeff Garzik * Opti core chipset helpers
454669a5db4SJeff Garzik */
455669a5db4SJeff Garzik
456669a5db4SJeff Garzik /**
457669a5db4SJeff Garzik * opti_syscfg - read OPTI chipset configuration
458669a5db4SJeff Garzik * @reg: Configuration register to read
459669a5db4SJeff Garzik *
460669a5db4SJeff Garzik * Returns the value of an OPTI system board configuration register.
461669a5db4SJeff Garzik */
462669a5db4SJeff Garzik
opti_syscfg(u8 reg)463669a5db4SJeff Garzik static u8 opti_syscfg(u8 reg)
464669a5db4SJeff Garzik {
465669a5db4SJeff Garzik unsigned long flags;
466669a5db4SJeff Garzik u8 r;
467669a5db4SJeff Garzik
468669a5db4SJeff Garzik /* Uniprocessor chipset and must force cycles adjancent */
469669a5db4SJeff Garzik local_irq_save(flags);
470669a5db4SJeff Garzik outb(reg, 0x22);
471669a5db4SJeff Garzik r = inb(0x24);
472669a5db4SJeff Garzik local_irq_restore(flags);
473669a5db4SJeff Garzik return r;
474669a5db4SJeff Garzik }
475669a5db4SJeff Garzik
476669a5db4SJeff Garzik /*
477669a5db4SJeff Garzik * Opti 82C611A
478669a5db4SJeff Garzik *
479669a5db4SJeff Garzik * This controller supports PIO0 to PIO3.
480669a5db4SJeff Garzik */
481669a5db4SJeff Garzik
opti82c611a_set_piomode(struct ata_port * ap,struct ata_device * adev)482669a5db4SJeff Garzik static void opti82c611a_set_piomode(struct ata_port *ap,
483669a5db4SJeff Garzik struct ata_device *adev)
484defc9cd8SAlan Cox {
485defc9cd8SAlan Cox u8 active, recover, setup;
486669a5db4SJeff Garzik struct ata_timing t;
487669a5db4SJeff Garzik struct ata_device *pair = ata_dev_pair(adev);
488669a5db4SJeff Garzik int clock;
489669a5db4SJeff Garzik int khz[4] = { 50000, 40000, 33000, 25000 };
490669a5db4SJeff Garzik u8 rc;
491669a5db4SJeff Garzik
492669a5db4SJeff Garzik /* Enter configuration mode */
493669a5db4SJeff Garzik ioread16(ap->ioaddr.error_addr);
494669a5db4SJeff Garzik ioread16(ap->ioaddr.error_addr);
4950d5ff566STejun Heo iowrite8(3, ap->ioaddr.nsect_addr);
4960d5ff566STejun Heo
4970d5ff566STejun Heo /* Read VLB clock strapping */
498669a5db4SJeff Garzik clock = 1000000000 / khz[ioread8(ap->ioaddr.lbah_addr) & 0x03];
499669a5db4SJeff Garzik
5000d5ff566STejun Heo /* Get the timing data in cycles */
501669a5db4SJeff Garzik ata_timing_compute(adev, adev->pio_mode, &t, clock, 1000);
502669a5db4SJeff Garzik
503669a5db4SJeff Garzik /* Setup timing is shared */
504669a5db4SJeff Garzik if (pair) {
505669a5db4SJeff Garzik struct ata_timing tp;
506669a5db4SJeff Garzik ata_timing_compute(pair, pair->pio_mode, &tp, clock, 1000);
507669a5db4SJeff Garzik
508669a5db4SJeff Garzik ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP);
509669a5db4SJeff Garzik }
510669a5db4SJeff Garzik
511669a5db4SJeff Garzik active = clamp_val(t.active, 2, 17) - 2;
512669a5db4SJeff Garzik recover = clamp_val(t.recover, 1, 16) - 1;
51307633b5dSHarvey Harrison setup = clamp_val(t.setup, 1, 4) - 1;
51407633b5dSHarvey Harrison
51507633b5dSHarvey Harrison /* Select the right timing bank for write timing */
516669a5db4SJeff Garzik rc = ioread8(ap->ioaddr.lbal_addr);
517669a5db4SJeff Garzik rc &= 0x7F;
5180d5ff566STejun Heo rc |= (adev->devno << 7);
519669a5db4SJeff Garzik iowrite8(rc, ap->ioaddr.lbal_addr);
520669a5db4SJeff Garzik
5210d5ff566STejun Heo /* Write the timings */
522669a5db4SJeff Garzik iowrite8(active << 4 | recover, ap->ioaddr.error_addr);
523669a5db4SJeff Garzik
5240d5ff566STejun Heo /* Select the right bank for read timings, also
525669a5db4SJeff Garzik load the shared timings for address */
526669a5db4SJeff Garzik rc = ioread8(ap->ioaddr.device_addr);
527669a5db4SJeff Garzik rc &= 0xC0;
5280d5ff566STejun Heo rc |= adev->devno; /* Index select */
529669a5db4SJeff Garzik rc |= (setup << 4) | 0x04;
530669a5db4SJeff Garzik iowrite8(rc, ap->ioaddr.device_addr);
531669a5db4SJeff Garzik
5320d5ff566STejun Heo /* Load the read timings */
533669a5db4SJeff Garzik iowrite8(active << 4 | recover, ap->ioaddr.data_addr);
534669a5db4SJeff Garzik
5350d5ff566STejun Heo /* Ensure the timing register mode is right */
536669a5db4SJeff Garzik rc = ioread8(ap->ioaddr.lbal_addr);
537669a5db4SJeff Garzik rc &= 0x73;
5380d5ff566STejun Heo rc |= 0x84;
539669a5db4SJeff Garzik iowrite8(rc, ap->ioaddr.lbal_addr);
540669a5db4SJeff Garzik
5410d5ff566STejun Heo /* Exit command mode */
542669a5db4SJeff Garzik iowrite8(0x83, ap->ioaddr.nsect_addr);
543669a5db4SJeff Garzik }
5440d5ff566STejun Heo
545669a5db4SJeff Garzik
546669a5db4SJeff Garzik static struct ata_port_operations opti82c611a_port_ops = {
547669a5db4SJeff Garzik .inherits = &legacy_base_port_ops,
548669a5db4SJeff Garzik .set_piomode = opti82c611a_set_piomode,
549029cfd6bSTejun Heo };
550669a5db4SJeff Garzik
551669a5db4SJeff Garzik /*
552669a5db4SJeff Garzik * Opti 82C465MV
553669a5db4SJeff Garzik *
554669a5db4SJeff Garzik * This controller supports PIO0 to PIO3. Unlike the 611A the MVB
555669a5db4SJeff Garzik * version is dual channel but doesn't have a lot of unique registers.
556669a5db4SJeff Garzik */
557669a5db4SJeff Garzik
opti82c46x_set_piomode(struct ata_port * ap,struct ata_device * adev)558669a5db4SJeff Garzik static void opti82c46x_set_piomode(struct ata_port *ap, struct ata_device *adev)
559669a5db4SJeff Garzik {
560669a5db4SJeff Garzik u8 active, recover, setup;
561669a5db4SJeff Garzik struct ata_timing t;
562669a5db4SJeff Garzik struct ata_device *pair = ata_dev_pair(adev);
563669a5db4SJeff Garzik int clock;
564669a5db4SJeff Garzik int khz[4] = { 50000, 40000, 33000, 25000 };
565669a5db4SJeff Garzik u8 rc;
566669a5db4SJeff Garzik u8 sysclk;
567669a5db4SJeff Garzik
568669a5db4SJeff Garzik /* Get the clock */
569669a5db4SJeff Garzik sysclk = (opti_syscfg(0xAC) & 0xC0) >> 6; /* BIOS set */
570669a5db4SJeff Garzik
571e0044c98SDan Carpenter /* Enter configuration mode */
572669a5db4SJeff Garzik ioread16(ap->ioaddr.error_addr);
573669a5db4SJeff Garzik ioread16(ap->ioaddr.error_addr);
5740d5ff566STejun Heo iowrite8(3, ap->ioaddr.nsect_addr);
5750d5ff566STejun Heo
5760d5ff566STejun Heo /* Read VLB clock strapping */
577669a5db4SJeff Garzik clock = 1000000000 / khz[sysclk];
578669a5db4SJeff Garzik
579669a5db4SJeff Garzik /* Get the timing data in cycles */
580669a5db4SJeff Garzik ata_timing_compute(adev, adev->pio_mode, &t, clock, 1000);
581669a5db4SJeff Garzik
582669a5db4SJeff Garzik /* Setup timing is shared */
583669a5db4SJeff Garzik if (pair) {
584669a5db4SJeff Garzik struct ata_timing tp;
585669a5db4SJeff Garzik ata_timing_compute(pair, pair->pio_mode, &tp, clock, 1000);
586669a5db4SJeff Garzik
587669a5db4SJeff Garzik ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP);
588669a5db4SJeff Garzik }
589669a5db4SJeff Garzik
590669a5db4SJeff Garzik active = clamp_val(t.active, 2, 17) - 2;
591669a5db4SJeff Garzik recover = clamp_val(t.recover, 1, 16) - 1;
59207633b5dSHarvey Harrison setup = clamp_val(t.setup, 1, 4) - 1;
59307633b5dSHarvey Harrison
59407633b5dSHarvey Harrison /* Select the right timing bank for write timing */
595669a5db4SJeff Garzik rc = ioread8(ap->ioaddr.lbal_addr);
596669a5db4SJeff Garzik rc &= 0x7F;
5970d5ff566STejun Heo rc |= (adev->devno << 7);
598669a5db4SJeff Garzik iowrite8(rc, ap->ioaddr.lbal_addr);
599669a5db4SJeff Garzik
6000d5ff566STejun Heo /* Write the timings */
601669a5db4SJeff Garzik iowrite8(active << 4 | recover, ap->ioaddr.error_addr);
602669a5db4SJeff Garzik
6030d5ff566STejun Heo /* Select the right bank for read timings, also
604669a5db4SJeff Garzik load the shared timings for address */
605669a5db4SJeff Garzik rc = ioread8(ap->ioaddr.device_addr);
606669a5db4SJeff Garzik rc &= 0xC0;
6070d5ff566STejun Heo rc |= adev->devno; /* Index select */
608669a5db4SJeff Garzik rc |= (setup << 4) | 0x04;
609669a5db4SJeff Garzik iowrite8(rc, ap->ioaddr.device_addr);
610669a5db4SJeff Garzik
6110d5ff566STejun Heo /* Load the read timings */
612669a5db4SJeff Garzik iowrite8(active << 4 | recover, ap->ioaddr.data_addr);
613669a5db4SJeff Garzik
6140d5ff566STejun Heo /* Ensure the timing register mode is right */
615669a5db4SJeff Garzik rc = ioread8(ap->ioaddr.lbal_addr);
616669a5db4SJeff Garzik rc &= 0x73;
6170d5ff566STejun Heo rc |= 0x84;
618669a5db4SJeff Garzik iowrite8(rc, ap->ioaddr.lbal_addr);
619669a5db4SJeff Garzik
6200d5ff566STejun Heo /* Exit command mode */
621669a5db4SJeff Garzik iowrite8(0x83, ap->ioaddr.nsect_addr);
622669a5db4SJeff Garzik
6230d5ff566STejun Heo /* We need to know this for quad device on the MVB */
624669a5db4SJeff Garzik ap->host->private_data = ap;
625669a5db4SJeff Garzik }
626669a5db4SJeff Garzik
627669a5db4SJeff Garzik /**
628669a5db4SJeff Garzik * opti82c46x_qc_issue - command issue
629669a5db4SJeff Garzik * @qc: command pending
630145f74faSLee Jones *
631669a5db4SJeff Garzik * Called when the libata layer is about to issue a command. We wrap
632669a5db4SJeff Garzik * this interface so that we can load the correct ATA timings. The
633669a5db4SJeff Garzik * MVB has a single set of timing registers and these are shared
634669a5db4SJeff Garzik * across channels. As there are two registers we really ought to
635669a5db4SJeff Garzik * track the last two used values as a sort of register window. For
636669a5db4SJeff Garzik * now we just reload on a channel switch. On the single channel
637669a5db4SJeff Garzik * setup this condition never fires so we do nothing extra.
638669a5db4SJeff Garzik *
639669a5db4SJeff Garzik * FIXME: dual channel needs ->serialize support
640669a5db4SJeff Garzik */
641669a5db4SJeff Garzik
opti82c46x_qc_issue(struct ata_queued_cmd * qc)642669a5db4SJeff Garzik static unsigned int opti82c46x_qc_issue(struct ata_queued_cmd *qc)
643669a5db4SJeff Garzik {
6449363c382STejun Heo struct ata_port *ap = qc->ap;
645669a5db4SJeff Garzik struct ata_device *adev = qc->dev;
646669a5db4SJeff Garzik
647669a5db4SJeff Garzik /* If timings are set and for the wrong channel (2nd test is
648669a5db4SJeff Garzik due to a libata shortcoming and will eventually go I hope) */
649669a5db4SJeff Garzik if (ap->host->private_data != ap->host
650669a5db4SJeff Garzik && ap->host->private_data != NULL)
651669a5db4SJeff Garzik opti82c46x_set_piomode(ap, adev);
652669a5db4SJeff Garzik
653669a5db4SJeff Garzik return ata_sff_qc_issue(qc);
654669a5db4SJeff Garzik }
6559363c382STejun Heo
656669a5db4SJeff Garzik static struct ata_port_operations opti82c46x_port_ops = {
657669a5db4SJeff Garzik .inherits = &legacy_base_port_ops,
658669a5db4SJeff Garzik .set_piomode = opti82c46x_set_piomode,
659029cfd6bSTejun Heo .qc_issue = opti82c46x_qc_issue,
660669a5db4SJeff Garzik };
6619363c382STejun Heo
662669a5db4SJeff Garzik /**
663669a5db4SJeff Garzik * qdi65x0_set_piomode - PIO setup for QDI65x0
664669a5db4SJeff Garzik * @ap: Port
6658c7e8f94SBartlomiej Zolnierkiewicz * @adev: Device
666defc9cd8SAlan Cox *
667defc9cd8SAlan Cox * In single channel mode the 6580 has one clock per device and we can
668defc9cd8SAlan Cox * avoid the requirement to clock switch. We also have to load the timing
669defc9cd8SAlan Cox * into the right clock according to whether we are master or slave.
670defc9cd8SAlan Cox *
671defc9cd8SAlan Cox * In dual channel mode the 6580 has one clock per channel and we have
6728c7e8f94SBartlomiej Zolnierkiewicz * to software clockswitch in qc_issue.
6738c7e8f94SBartlomiej Zolnierkiewicz */
6748c7e8f94SBartlomiej Zolnierkiewicz
qdi65x0_set_piomode(struct ata_port * ap,struct ata_device * adev)675defc9cd8SAlan Cox static void qdi65x0_set_piomode(struct ata_port *ap, struct ata_device *adev)
676669a5db4SJeff Garzik {
6778c7e8f94SBartlomiej Zolnierkiewicz struct ata_timing t;
678defc9cd8SAlan Cox struct legacy_data *ld_qdi = ap->host->private_data;
679defc9cd8SAlan Cox int active, recovery;
680cb616dd5SHarvey Harrison u8 timing;
681defc9cd8SAlan Cox
682defc9cd8SAlan Cox /* Get the timing data in cycles */
683defc9cd8SAlan Cox ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
684defc9cd8SAlan Cox
685defc9cd8SAlan Cox if (ld_qdi->fast) {
686defc9cd8SAlan Cox active = 8 - clamp_val(t.active, 1, 8);
687cb616dd5SHarvey Harrison recovery = 18 - clamp_val(t.recover, 3, 18);
68807633b5dSHarvey Harrison } else {
68907633b5dSHarvey Harrison active = 9 - clamp_val(t.active, 2, 9);
690defc9cd8SAlan Cox recovery = 15 - clamp_val(t.recover, 0, 15);
69107633b5dSHarvey Harrison }
69207633b5dSHarvey Harrison timing = (recovery << 4) | active | 0x08;
693defc9cd8SAlan Cox ld_qdi->clock[adev->devno] = timing;
694defc9cd8SAlan Cox
695cb616dd5SHarvey Harrison if (ld_qdi->type == QDI6580)
6968c7e8f94SBartlomiej Zolnierkiewicz outb(timing, ld_qdi->timing + 2 * adev->devno);
6978c7e8f94SBartlomiej Zolnierkiewicz else
698cb616dd5SHarvey Harrison outb(timing, ld_qdi->timing + 2 * ap->port_no);
6998c7e8f94SBartlomiej Zolnierkiewicz
7008c7e8f94SBartlomiej Zolnierkiewicz /* Clear the FIFO */
7018c7e8f94SBartlomiej Zolnierkiewicz if (ld_qdi->type != QDI6500 && adev->class != ATA_DEV_ATA)
702defc9cd8SAlan Cox outb(0x5F, (ld_qdi->timing & 0xFFF0) + 3);
7038c7e8f94SBartlomiej Zolnierkiewicz }
7046809e730SBartlomiej Zolnierkiewicz
705defc9cd8SAlan Cox /**
706defc9cd8SAlan Cox * qdi_qc_issue - command issue
707defc9cd8SAlan Cox * @qc: command pending
7089363c382STejun Heo *
709defc9cd8SAlan Cox * Called when the libata layer is about to issue a command. We wrap
710defc9cd8SAlan Cox * this interface so that we can load the correct ATA timings.
711defc9cd8SAlan Cox */
712defc9cd8SAlan Cox
qdi_qc_issue(struct ata_queued_cmd * qc)713defc9cd8SAlan Cox static unsigned int qdi_qc_issue(struct ata_queued_cmd *qc)
714defc9cd8SAlan Cox {
7159363c382STejun Heo struct ata_port *ap = qc->ap;
716defc9cd8SAlan Cox struct ata_device *adev = qc->dev;
717defc9cd8SAlan Cox struct legacy_data *ld_qdi = ap->host->private_data;
718defc9cd8SAlan Cox
719cb616dd5SHarvey Harrison if (ld_qdi->clock[adev->devno] != ld_qdi->last) {
720defc9cd8SAlan Cox if (adev->pio_mode) {
721cb616dd5SHarvey Harrison ld_qdi->last = ld_qdi->clock[adev->devno];
722defc9cd8SAlan Cox outb(ld_qdi->clock[adev->devno], ld_qdi->timing +
723cb616dd5SHarvey Harrison 2 * ap->port_no);
724cb616dd5SHarvey Harrison }
725defc9cd8SAlan Cox }
726defc9cd8SAlan Cox return ata_sff_qc_issue(qc);
727defc9cd8SAlan Cox }
7289363c382STejun Heo
vlb32_data_xfer(struct ata_queued_cmd * qc,unsigned char * buf,unsigned int buflen,int rw)729defc9cd8SAlan Cox static unsigned int vlb32_data_xfer(struct ata_queued_cmd *qc,
730defc9cd8SAlan Cox unsigned char *buf,
731989e0aacSBartlomiej Zolnierkiewicz unsigned int buflen, int rw)
732989e0aacSBartlomiej Zolnierkiewicz {
733defc9cd8SAlan Cox struct ata_device *adev = qc->dev;
734defc9cd8SAlan Cox struct ata_port *ap = adev->link->ap;
735989e0aacSBartlomiej Zolnierkiewicz int slop = buflen & 3;
736defc9cd8SAlan Cox
737defc9cd8SAlan Cox if (ata_id_has_dword_io(adev->id) && (slop == 0 || slop == 3)
738defc9cd8SAlan Cox && (ap->pflags & ATA_PFLAG_PIO32)) {
739e3cf95ddSAlan Cox if (rw == WRITE)
740e3cf95ddSAlan Cox iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
741defc9cd8SAlan Cox else
742defc9cd8SAlan Cox ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
743defc9cd8SAlan Cox
744defc9cd8SAlan Cox if (unlikely(slop)) {
745defc9cd8SAlan Cox __le32 pad = 0;
746defc9cd8SAlan Cox
74701392347SDan Carpenter if (rw == WRITE) {
74801392347SDan Carpenter memcpy(&pad, buf + buflen - slop, slop);
749defc9cd8SAlan Cox iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
750defc9cd8SAlan Cox } else {
7516ad67403SHarvey Harrison pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
752defc9cd8SAlan Cox memcpy(buf + buflen - slop, &pad, slop);
7536ad67403SHarvey Harrison }
754defc9cd8SAlan Cox }
755defc9cd8SAlan Cox return (buflen + 3) & ~3;
756defc9cd8SAlan Cox } else
757defc9cd8SAlan Cox return ata_sff_data_xfer(qc, buf, buflen, rw);
758defc9cd8SAlan Cox }
759989e0aacSBartlomiej Zolnierkiewicz
qdi_port(struct platform_device * dev,struct legacy_probe * lp,struct legacy_data * ld)760defc9cd8SAlan Cox static int qdi_port(struct platform_device *dev,
761defc9cd8SAlan Cox struct legacy_probe *lp, struct legacy_data *ld)
762b8325487SAlan Cox {
763b8325487SAlan Cox if (devm_request_region(&dev->dev, lp->private, 4, "qdi") == NULL)
764b8325487SAlan Cox return -EBUSY;
765b8325487SAlan Cox ld->timing = lp->private;
766b8325487SAlan Cox return 0;
767b8325487SAlan Cox }
768b8325487SAlan Cox
769b8325487SAlan Cox static struct ata_port_operations qdi6500_port_ops = {
770b8325487SAlan Cox .inherits = &legacy_base_port_ops,
771defc9cd8SAlan Cox .set_piomode = qdi65x0_set_piomode,
772029cfd6bSTejun Heo .qc_issue = qdi_qc_issue,
7738c7e8f94SBartlomiej Zolnierkiewicz .sff_data_xfer = vlb32_data_xfer,
7749363c382STejun Heo };
7755682ed33STejun Heo
776defc9cd8SAlan Cox static struct ata_port_operations qdi6580_port_ops = {
777defc9cd8SAlan Cox .inherits = &legacy_base_port_ops,
778defc9cd8SAlan Cox .set_piomode = qdi65x0_set_piomode,
779029cfd6bSTejun Heo .sff_data_xfer = vlb32_data_xfer,
7808c7e8f94SBartlomiej Zolnierkiewicz };
7815682ed33STejun Heo
782defc9cd8SAlan Cox static struct ata_port_operations qdi6580dp_port_ops = {
783defc9cd8SAlan Cox .inherits = &legacy_base_port_ops,
784defc9cd8SAlan Cox .set_piomode = qdi65x0_set_piomode,
785029cfd6bSTejun Heo .qc_issue = qdi_qc_issue,
7868c7e8f94SBartlomiej Zolnierkiewicz .sff_data_xfer = vlb32_data_xfer,
78743c7d17eSBartlomiej Zolnierkiewicz };
7885682ed33STejun Heo
789defc9cd8SAlan Cox static DEFINE_SPINLOCK(winbond_lock);
790defc9cd8SAlan Cox
winbond_writecfg(unsigned long port,u8 reg,u8 val)791b8325487SAlan Cox static void winbond_writecfg(unsigned long port, u8 reg, u8 val)
792b8325487SAlan Cox {
793b8325487SAlan Cox unsigned long flags;
794b8325487SAlan Cox spin_lock_irqsave(&winbond_lock, flags);
795b8325487SAlan Cox outb(reg, port + 0x01);
796b8325487SAlan Cox outb(val, port + 0x02);
797b8325487SAlan Cox spin_unlock_irqrestore(&winbond_lock, flags);
798b8325487SAlan Cox }
799b8325487SAlan Cox
winbond_readcfg(unsigned long port,u8 reg)800b8325487SAlan Cox static u8 winbond_readcfg(unsigned long port, u8 reg)
801b8325487SAlan Cox {
802b8325487SAlan Cox u8 val;
803b8325487SAlan Cox
804b8325487SAlan Cox unsigned long flags;
805b8325487SAlan Cox spin_lock_irqsave(&winbond_lock, flags);
806b8325487SAlan Cox outb(reg, port + 0x01);
807b8325487SAlan Cox val = inb(port + 0x02);
808b8325487SAlan Cox spin_unlock_irqrestore(&winbond_lock, flags);
809b8325487SAlan Cox
810b8325487SAlan Cox return val;
811b8325487SAlan Cox }
812b8325487SAlan Cox
winbond_set_piomode(struct ata_port * ap,struct ata_device * adev)813b8325487SAlan Cox static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
814b8325487SAlan Cox {
815b8325487SAlan Cox struct ata_timing t;
816b8325487SAlan Cox struct legacy_data *ld_winbond = ap->host->private_data;
817b8325487SAlan Cox int active, recovery;
818cb616dd5SHarvey Harrison u8 reg;
819b8325487SAlan Cox int timing = 0x88 + (ap->port_no * 4) + (adev->devno * 2);
820b8325487SAlan Cox
821b8325487SAlan Cox reg = winbond_readcfg(ld_winbond->timing, 0x81);
822b8325487SAlan Cox
823cb616dd5SHarvey Harrison /* Get the timing data in cycles */
824b8325487SAlan Cox if (reg & 0x40) /* Fast VLB bus, assume 50MHz */
825b8325487SAlan Cox ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000);
826b8325487SAlan Cox else
827b8325487SAlan Cox ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
828b8325487SAlan Cox
829b8325487SAlan Cox active = (clamp_val(t.active, 3, 17) - 1) & 0x0F;
830b8325487SAlan Cox recovery = (clamp_val(t.recover, 1, 15) + 1) & 0x0F;
83107633b5dSHarvey Harrison timing = (active << 4) | recovery;
83207633b5dSHarvey Harrison winbond_writecfg(ld_winbond->timing, timing, reg);
833b8325487SAlan Cox
834cb616dd5SHarvey Harrison /* Load the setup timing */
835b8325487SAlan Cox
836b8325487SAlan Cox reg = 0x35;
837b8325487SAlan Cox if (adev->class != ATA_DEV_ATA)
838b8325487SAlan Cox reg |= 0x08; /* FIFO off */
839b8325487SAlan Cox if (!ata_pio_need_iordy(adev))
840b8325487SAlan Cox reg |= 0x02; /* IORDY off */
841b8325487SAlan Cox reg |= (clamp_val(t.setup, 0, 3) << 6);
842b8325487SAlan Cox winbond_writecfg(ld_winbond->timing, timing + 1, reg);
84307633b5dSHarvey Harrison }
844cb616dd5SHarvey Harrison
winbond_port(struct platform_device * dev,struct legacy_probe * lp,struct legacy_data * ld)845b8325487SAlan Cox static int winbond_port(struct platform_device *dev,
846b8325487SAlan Cox struct legacy_probe *lp, struct legacy_data *ld)
847b8325487SAlan Cox {
848b8325487SAlan Cox if (devm_request_region(&dev->dev, lp->private, 4, "winbond") == NULL)
849b8325487SAlan Cox return -EBUSY;
850b8325487SAlan Cox ld->timing = lp->private;
851b8325487SAlan Cox return 0;
852b8325487SAlan Cox }
853b8325487SAlan Cox
854b8325487SAlan Cox static struct ata_port_operations winbond_port_ops = {
855b8325487SAlan Cox .inherits = &legacy_base_port_ops,
856b8325487SAlan Cox .set_piomode = winbond_set_piomode,
857029cfd6bSTejun Heo .sff_data_xfer = vlb32_data_xfer,
858b8325487SAlan Cox };
8595682ed33STejun Heo
860b8325487SAlan Cox static struct legacy_controller controllers[] = {
861b8325487SAlan Cox {"BIOS", &legacy_port_ops, ATA_PIO4,
862defc9cd8SAlan Cox ATA_FLAG_NO_IORDY, 0, NULL },
863b2f104bbSBartlomiej Zolnierkiewicz {"Snooping", &simple_port_ops, ATA_PIO4,
864e3cf95ddSAlan Cox 0, 0, NULL },
865b2f104bbSBartlomiej Zolnierkiewicz {"PDC20230", &pdc20230_port_ops, ATA_PIO2,
866e3cf95ddSAlan Cox ATA_FLAG_NO_IORDY,
867b2f104bbSBartlomiej Zolnierkiewicz ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, NULL },
868e3cf95ddSAlan Cox {"HT6560A", &ht6560a_port_ops, ATA_PIO2,
86916e6aecaSZhenwen Xu ATA_FLAG_NO_IORDY, 0, NULL },
870b2f104bbSBartlomiej Zolnierkiewicz {"HT6560B", &ht6560b_port_ops, ATA_PIO4,
871e3cf95ddSAlan Cox ATA_FLAG_NO_IORDY, 0, NULL },
872b2f104bbSBartlomiej Zolnierkiewicz {"OPTI82C611A", &opti82c611a_port_ops, ATA_PIO3,
873e3cf95ddSAlan Cox 0, 0, NULL },
874b2f104bbSBartlomiej Zolnierkiewicz {"OPTI82C46X", &opti82c46x_port_ops, ATA_PIO3,
875e3cf95ddSAlan Cox 0, 0, NULL },
876b2f104bbSBartlomiej Zolnierkiewicz {"QDI6500", &qdi6500_port_ops, ATA_PIO2,
877e3cf95ddSAlan Cox ATA_FLAG_NO_IORDY,
878b2f104bbSBartlomiej Zolnierkiewicz ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port },
879e3cf95ddSAlan Cox {"QDI6580", &qdi6580_port_ops, ATA_PIO4,
88016e6aecaSZhenwen Xu 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port },
881b2f104bbSBartlomiej Zolnierkiewicz {"QDI6580DP", &qdi6580dp_port_ops, ATA_PIO4,
88216e6aecaSZhenwen Xu 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port },
883b2f104bbSBartlomiej Zolnierkiewicz {"W83759A", &winbond_port_ops, ATA_PIO4,
88416e6aecaSZhenwen Xu 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE,
885b2f104bbSBartlomiej Zolnierkiewicz winbond_port }
88616e6aecaSZhenwen Xu };
887e3cf95ddSAlan Cox
888defc9cd8SAlan Cox /**
889defc9cd8SAlan Cox * probe_chip_type - Discover controller
890defc9cd8SAlan Cox * @probe: Probe entry to check
891defc9cd8SAlan Cox *
892defc9cd8SAlan Cox * Probe an ATA port and identify the type of controller. We don't
893defc9cd8SAlan Cox * check if the controller appears to be driveless at this point.
894defc9cd8SAlan Cox */
895defc9cd8SAlan Cox
probe_chip_type(struct legacy_probe * probe)896defc9cd8SAlan Cox static __init int probe_chip_type(struct legacy_probe *probe)
897defc9cd8SAlan Cox {
898b8325487SAlan Cox int mask = 1 << probe->slot;
899defc9cd8SAlan Cox
900defc9cd8SAlan Cox if (winbond && (probe->port == 0x1F0 || probe->port == 0x170)) {
901defc9cd8SAlan Cox u8 reg = winbond_readcfg(winbond, 0x81);
902b8325487SAlan Cox reg |= 0x80; /* jumpered mode off */
903b8325487SAlan Cox winbond_writecfg(winbond, 0x81, reg);
904b8325487SAlan Cox reg = winbond_readcfg(winbond, 0x83);
905b8325487SAlan Cox reg |= 0xF0; /* local control */
906b8325487SAlan Cox winbond_writecfg(winbond, 0x83, reg);
907b8325487SAlan Cox reg = winbond_readcfg(winbond, 0x85);
908b8325487SAlan Cox reg |= 0xF0; /* programmable timing */
909b8325487SAlan Cox winbond_writecfg(winbond, 0x85, reg);
910b8325487SAlan Cox
911b8325487SAlan Cox reg = winbond_readcfg(winbond, 0x81);
912b8325487SAlan Cox
913b8325487SAlan Cox if (reg & mask)
914b8325487SAlan Cox return W83759A;
915b8325487SAlan Cox }
916b8325487SAlan Cox if (probe->port == 0x1F0) {
917b8325487SAlan Cox unsigned long flags;
918defc9cd8SAlan Cox local_irq_save(flags);
919669a5db4SJeff Garzik /* Probes */
920669a5db4SJeff Garzik outb(inb(0x1F2) | 0x80, 0x1F2);
921669a5db4SJeff Garzik inb(0x1F5);
922669a5db4SJeff Garzik inb(0x1F2);
923defc9cd8SAlan Cox inb(0x3F6);
924669a5db4SJeff Garzik inb(0x3F6);
925669a5db4SJeff Garzik inb(0x1F2);
926669a5db4SJeff Garzik inb(0x1F2);
927669a5db4SJeff Garzik
928669a5db4SJeff Garzik if ((inb(0x1F2) & 0x80) == 0) {
929669a5db4SJeff Garzik /* PDC20230c or 20630 ? */
930669a5db4SJeff Garzik printk(KERN_INFO "PDC20230-C/20630 VLB ATA controller"
931669a5db4SJeff Garzik " detected.\n");
932defc9cd8SAlan Cox udelay(100);
933defc9cd8SAlan Cox inb(0x1F5);
934669a5db4SJeff Garzik local_irq_restore(flags);
935669a5db4SJeff Garzik return PDC20230;
936defc9cd8SAlan Cox } else {
937defc9cd8SAlan Cox outb(0x55, 0x1F2);
938669a5db4SJeff Garzik inb(0x1F2);
939669a5db4SJeff Garzik inb(0x1F2);
940669a5db4SJeff Garzik if (inb(0x1F2) == 0x00)
941669a5db4SJeff Garzik printk(KERN_INFO "PDC20230-B VLB ATA "
942defc9cd8SAlan Cox "controller detected.\n");
943defc9cd8SAlan Cox local_irq_restore(flags);
944defc9cd8SAlan Cox return BIOS;
945defc9cd8SAlan Cox }
946defc9cd8SAlan Cox }
947669a5db4SJeff Garzik
948669a5db4SJeff Garzik if (ht6560a & mask)
949669a5db4SJeff Garzik return HT6560A;
950defc9cd8SAlan Cox if (ht6560b & mask)
951defc9cd8SAlan Cox return HT6560B;
952defc9cd8SAlan Cox if (opti82c611a & mask)
953defc9cd8SAlan Cox return OPTI611A;
954defc9cd8SAlan Cox if (opti82c46x & mask)
955defc9cd8SAlan Cox return OPTI46X;
956defc9cd8SAlan Cox if (autospeed & mask)
957defc9cd8SAlan Cox return SNOOP;
958defc9cd8SAlan Cox return BIOS;
959defc9cd8SAlan Cox }
960defc9cd8SAlan Cox
961defc9cd8SAlan Cox
962669a5db4SJeff Garzik /**
963defc9cd8SAlan Cox * legacy_init_one - attach a legacy interface
964defc9cd8SAlan Cox * @probe: probe record
965defc9cd8SAlan Cox *
966145f74faSLee Jones * Register an ISA bus IDE interface. Such interfaces are PIO and we
967defc9cd8SAlan Cox * assume do not support IRQ sharing.
968defc9cd8SAlan Cox */
969defc9cd8SAlan Cox
legacy_init_one(struct legacy_probe * probe)970defc9cd8SAlan Cox static __init int legacy_init_one(struct legacy_probe *probe)
971defc9cd8SAlan Cox {
972defc9cd8SAlan Cox struct legacy_controller *controller = &controllers[probe->type];
973defc9cd8SAlan Cox int pio_modes = controller->pio_mask;
974defc9cd8SAlan Cox unsigned long io = probe->port;
975defc9cd8SAlan Cox u32 mask = (1 << probe->slot);
976defc9cd8SAlan Cox struct ata_port_operations *ops = controller->ops;
977defc9cd8SAlan Cox struct legacy_data *ld = &legacy_data[probe->slot];
978defc9cd8SAlan Cox struct ata_host *host = NULL;
979defc9cd8SAlan Cox struct ata_port *ap;
980defc9cd8SAlan Cox struct platform_device *pdev;
981defc9cd8SAlan Cox struct ata_device *dev;
982defc9cd8SAlan Cox void __iomem *io_addr, *ctrl_addr;
983defc9cd8SAlan Cox u32 iordy = (iordy_mask & mask) ? 0: ATA_FLAG_NO_IORDY;
984defc9cd8SAlan Cox int ret;
985defc9cd8SAlan Cox
986defc9cd8SAlan Cox iordy |= controller->flags;
987defc9cd8SAlan Cox
988defc9cd8SAlan Cox pdev = platform_device_register_simple(DRV_NAME, probe->slot, NULL, 0);
989defc9cd8SAlan Cox if (IS_ERR(pdev))
990defc9cd8SAlan Cox return PTR_ERR(pdev);
991defc9cd8SAlan Cox
992defc9cd8SAlan Cox ret = -EBUSY;
993defc9cd8SAlan Cox if (devm_request_region(&pdev->dev, io, 8, "pata_legacy") == NULL ||
994defc9cd8SAlan Cox devm_request_region(&pdev->dev, io + 0x0206, 1,
995defc9cd8SAlan Cox "pata_legacy") == NULL)
996defc9cd8SAlan Cox goto fail;
997defc9cd8SAlan Cox
998defc9cd8SAlan Cox ret = -ENOMEM;
999f834e49fSAlan Cox io_addr = devm_ioport_map(&pdev->dev, io, 8);
10005d728824STejun Heo ctrl_addr = devm_ioport_map(&pdev->dev, io + 0x0206, 1);
1001defc9cd8SAlan Cox if (!io_addr || !ctrl_addr)
1002defc9cd8SAlan Cox goto fail;
1003defc9cd8SAlan Cox ld->type = probe->type;
1004defc9cd8SAlan Cox if (controller->setup)
10058c7e8f94SBartlomiej Zolnierkiewicz if (controller->setup(pdev, probe, ld) < 0)
1006defc9cd8SAlan Cox goto fail;
1007b8325487SAlan Cox host = ata_host_alloc(&pdev->dev, 1);
1008defc9cd8SAlan Cox if (!host)
10095d728824STejun Heo goto fail;
10105d728824STejun Heo ap = host->ports[0];
10115d728824STejun Heo
10125d728824STejun Heo ap->ops = ops;
1013669a5db4SJeff Garzik ap->pio_mask = pio_modes;
10145d728824STejun Heo ap->flags |= ATA_FLAG_SLAVE_POSS | iordy;
10155d728824STejun Heo ap->pflags |= controller->pflags;
10165d728824STejun Heo ap->ioaddr.cmd_addr = io_addr;
1017e3cf95ddSAlan Cox ap->ioaddr.altstatus_addr = ctrl_addr;
10185d728824STejun Heo ap->ioaddr.ctl_addr = ctrl_addr;
10195d728824STejun Heo ata_sff_std_ports(&ap->ioaddr);
10205d728824STejun Heo ap->host->private_data = ld;
10219363c382STejun Heo
1022b8325487SAlan Cox ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", io, io + 0x0206);
10235d728824STejun Heo
1024defc9cd8SAlan Cox ret = ata_host_activate(host, probe->irq, ata_sff_interrupt, 0,
1025cbcdd875STejun Heo &legacy_sht);
10269363c382STejun Heo if (ret)
1027defc9cd8SAlan Cox goto fail;
10285d728824STejun Heo async_synchronize_full();
1029669a5db4SJeff Garzik ld->platform_dev = pdev;
103045bc955bSJames Bottomley
1031defc9cd8SAlan Cox /* Nothing found means we drop the port as its probably not there */
103224dc5f33STejun Heo
1033defc9cd8SAlan Cox ret = -ENODEV;
1034defc9cd8SAlan Cox ata_for_each_dev(dev, &ap->link, ALL) {
1035defc9cd8SAlan Cox if (!ata_dev_absent(dev)) {
10361eca4365STejun Heo legacy_host[probe->slot] = host;
1037defc9cd8SAlan Cox ld->platform_dev = pdev;
1038defc9cd8SAlan Cox return 0;
1039669a5db4SJeff Garzik }
1040669a5db4SJeff Garzik }
1041defc9cd8SAlan Cox ata_host_detach(host);
1042defc9cd8SAlan Cox fail:
104320cbf5f8STejun Heo platform_device_unregister(pdev);
1044669a5db4SJeff Garzik return ret;
1045669a5db4SJeff Garzik }
1046669a5db4SJeff Garzik
1047669a5db4SJeff Garzik /**
1048669a5db4SJeff Garzik * legacy_check_special_cases - ATA special cases
1049669a5db4SJeff Garzik * @p: PCI device to check
1050669a5db4SJeff Garzik * @primary: set this if we find an ATA master
1051669a5db4SJeff Garzik * @secondary: set this if we find an ATA secondary
1052145f74faSLee Jones *
1053145f74faSLee Jones * A small number of vendors implemented early PCI ATA interfaces
1054669a5db4SJeff Garzik * on bridge logic without the ATA interface being PCI visible.
1055defc9cd8SAlan Cox * Where we have a matching PCI driver we must skip the relevant
1056defc9cd8SAlan Cox * device here. If we don't know about it then the legacy driver
1057defc9cd8SAlan Cox * is the right driver anyway.
1058defc9cd8SAlan Cox */
1059defc9cd8SAlan Cox
legacy_check_special_cases(struct pci_dev * p,int * primary,int * secondary)1060669a5db4SJeff Garzik static void __init legacy_check_special_cases(struct pci_dev *p, int *primary,
1061669a5db4SJeff Garzik int *secondary)
1062b8325487SAlan Cox {
1063defc9cd8SAlan Cox /* Cyrix CS5510 pre SFF MWDMA ATA on the bridge */
1064669a5db4SJeff Garzik if (p->vendor == 0x1078 && p->device == 0x0000) {
1065669a5db4SJeff Garzik *primary = *secondary = 1;
1066669a5db4SJeff Garzik return;
1067669a5db4SJeff Garzik }
1068669a5db4SJeff Garzik /* Cyrix CS5520 pre SFF MWDMA ATA on the bridge */
1069669a5db4SJeff Garzik if (p->vendor == 0x1078 && p->device == 0x0002) {
1070669a5db4SJeff Garzik *primary = *secondary = 1;
1071669a5db4SJeff Garzik return;
1072669a5db4SJeff Garzik }
1073669a5db4SJeff Garzik /* Intel MPIIX - PIO ATA on non PCI side of bridge */
1074669a5db4SJeff Garzik if (p->vendor == 0x8086 && p->device == 0x1234) {
1075669a5db4SJeff Garzik u16 r;
1076669a5db4SJeff Garzik pci_read_config_word(p, 0x6C, &r);
1077669a5db4SJeff Garzik if (r & 0x8000) {
1078669a5db4SJeff Garzik /* ATA port enabled */
1079defc9cd8SAlan Cox if (r & 0x4000)
1080defc9cd8SAlan Cox *secondary = 1;
1081669a5db4SJeff Garzik else
1082669a5db4SJeff Garzik *primary = 1;
1083669a5db4SJeff Garzik }
1084669a5db4SJeff Garzik return;
1085669a5db4SJeff Garzik }
1086669a5db4SJeff Garzik }
1087669a5db4SJeff Garzik
probe_opti_vlb(void)1088669a5db4SJeff Garzik static __init void probe_opti_vlb(void)
1089669a5db4SJeff Garzik {
1090defc9cd8SAlan Cox /* If an OPTI 82C46X is present find out where the channels are */
1091defc9cd8SAlan Cox static const char *optis[4] = {
1092defc9cd8SAlan Cox "3/463MV", "5MV",
1093defc9cd8SAlan Cox "5MVA", "5MVB"
1094defc9cd8SAlan Cox };
1095defc9cd8SAlan Cox u8 chans = 1;
1096defc9cd8SAlan Cox u8 ctrl = (opti_syscfg(0x30) & 0xC0) >> 6;
1097defc9cd8SAlan Cox
1098defc9cd8SAlan Cox opti82c46x = 3; /* Assume master and slave first */
1099defc9cd8SAlan Cox printk(KERN_INFO DRV_NAME ": Opti 82C46%s chipset support.\n",
1100defc9cd8SAlan Cox optis[ctrl]);
1101defc9cd8SAlan Cox if (ctrl == 3)
1102defc9cd8SAlan Cox chans = (opti_syscfg(0x3F) & 0x20) ? 2 : 1;
1103defc9cd8SAlan Cox ctrl = opti_syscfg(0xAC);
1104defc9cd8SAlan Cox /* Check enabled and this port is the 465MV port. On the
1105defc9cd8SAlan Cox MVB we may have two channels */
1106defc9cd8SAlan Cox if (ctrl & 8) {
1107defc9cd8SAlan Cox if (chans == 2) {
1108defc9cd8SAlan Cox legacy_probe_add(0x1F0, 14, OPTI46X, 0);
1109defc9cd8SAlan Cox legacy_probe_add(0x170, 15, OPTI46X, 0);
1110defc9cd8SAlan Cox }
1111defc9cd8SAlan Cox if (ctrl & 4)
1112defc9cd8SAlan Cox legacy_probe_add(0x170, 15, OPTI46X, 0);
1113defc9cd8SAlan Cox else
1114defc9cd8SAlan Cox legacy_probe_add(0x1F0, 14, OPTI46X, 0);
1115defc9cd8SAlan Cox } else
1116defc9cd8SAlan Cox legacy_probe_add(0x1F0, 14, OPTI46X, 0);
1117defc9cd8SAlan Cox }
1118defc9cd8SAlan Cox
qdi65_identify_port(u8 r,u8 res,unsigned long port)1119defc9cd8SAlan Cox static __init void qdi65_identify_port(u8 r, u8 res, unsigned long port)
1120defc9cd8SAlan Cox {
1121defc9cd8SAlan Cox static const unsigned long ide_port[2] = { 0x170, 0x1F0 };
1122defc9cd8SAlan Cox /* Check card type */
1123defc9cd8SAlan Cox if ((r & 0xF0) == 0xC0) {
1124defc9cd8SAlan Cox /* QD6500: single channel */
1125defc9cd8SAlan Cox if (r & 8)
1126defc9cd8SAlan Cox /* Disabled ? */
1127b8325487SAlan Cox return;
1128defc9cd8SAlan Cox legacy_probe_add(ide_port[r & 0x01], 14 + (r & 0x01),
1129defc9cd8SAlan Cox QDI6500, port);
1130defc9cd8SAlan Cox }
1131defc9cd8SAlan Cox if (((r & 0xF0) == 0xA0) || (r & 0xF0) == 0x50) {
1132defc9cd8SAlan Cox /* QD6580: dual channel */
1133defc9cd8SAlan Cox if (!request_region(port + 2 , 2, "pata_qdi")) {
1134defc9cd8SAlan Cox release_region(port, 2);
1135defc9cd8SAlan Cox return;
1136defc9cd8SAlan Cox }
1137defc9cd8SAlan Cox res = inb(port + 3);
1138defc9cd8SAlan Cox /* Single channel mode ? */
1139defc9cd8SAlan Cox if (res & 1)
1140defc9cd8SAlan Cox legacy_probe_add(ide_port[r & 0x01], 14 + (r & 0x01),
1141defc9cd8SAlan Cox QDI6580, port);
1142defc9cd8SAlan Cox else { /* Dual channel mode */
1143defc9cd8SAlan Cox legacy_probe_add(0x1F0, 14, QDI6580DP, port);
1144defc9cd8SAlan Cox /* port + 0x02, r & 0x04 */
1145defc9cd8SAlan Cox legacy_probe_add(0x170, 15, QDI6580DP, port + 2);
1146defc9cd8SAlan Cox }
1147defc9cd8SAlan Cox release_region(port + 2, 2);
1148defc9cd8SAlan Cox }
1149b8325487SAlan Cox }
1150defc9cd8SAlan Cox
probe_qdi_vlb(void)1151defc9cd8SAlan Cox static __init void probe_qdi_vlb(void)
1152defc9cd8SAlan Cox {
1153defc9cd8SAlan Cox unsigned long flags;
1154defc9cd8SAlan Cox static const unsigned long qd_port[2] = { 0x30, 0xB0 };
1155defc9cd8SAlan Cox int i;
1156defc9cd8SAlan Cox
1157defc9cd8SAlan Cox /*
1158defc9cd8SAlan Cox * Check each possible QD65xx base address
1159defc9cd8SAlan Cox */
1160defc9cd8SAlan Cox
1161defc9cd8SAlan Cox for (i = 0; i < 2; i++) {
1162defc9cd8SAlan Cox unsigned long port = qd_port[i];
1163defc9cd8SAlan Cox u8 r, res;
1164defc9cd8SAlan Cox
1165defc9cd8SAlan Cox
1166defc9cd8SAlan Cox if (request_region(port, 2, "pata_qdi")) {
1167defc9cd8SAlan Cox /* Check for a card */
1168defc9cd8SAlan Cox local_irq_save(flags);
1169defc9cd8SAlan Cox /* I have no h/w that needs this delay but it
1170defc9cd8SAlan Cox is present in the historic code */
1171defc9cd8SAlan Cox r = inb(port);
1172defc9cd8SAlan Cox udelay(1);
1173defc9cd8SAlan Cox outb(0x19, port);
1174defc9cd8SAlan Cox udelay(1);
1175defc9cd8SAlan Cox res = inb(port);
1176defc9cd8SAlan Cox udelay(1);
1177defc9cd8SAlan Cox outb(r, port);
1178defc9cd8SAlan Cox udelay(1);
1179defc9cd8SAlan Cox local_irq_restore(flags);
1180defc9cd8SAlan Cox
1181defc9cd8SAlan Cox /* Fail */
1182defc9cd8SAlan Cox if (res == 0x19) {
1183defc9cd8SAlan Cox release_region(port, 2);
1184defc9cd8SAlan Cox continue;
1185defc9cd8SAlan Cox }
1186defc9cd8SAlan Cox /* Passes the presence test */
1187defc9cd8SAlan Cox r = inb(port + 1);
1188defc9cd8SAlan Cox udelay(1);
1189defc9cd8SAlan Cox /* Check port agrees with port set */
1190defc9cd8SAlan Cox if ((r & 2) >> 1 == i)
1191defc9cd8SAlan Cox qdi65_identify_port(r, res, port);
1192b8325487SAlan Cox release_region(port, 2);
1193defc9cd8SAlan Cox }
1194b8325487SAlan Cox }
1195defc9cd8SAlan Cox }
1196defc9cd8SAlan Cox
1197defc9cd8SAlan Cox /**
1198669a5db4SJeff Garzik * legacy_init - attach legacy interfaces
1199669a5db4SJeff Garzik *
1200669a5db4SJeff Garzik * Attach legacy IDE interfaces by scanning the usual IRQ/port suspects.
1201669a5db4SJeff Garzik * Right now we do not scan the ide0 and ide1 address but should do so
1202669a5db4SJeff Garzik * for non PCI systems or systems with no PCI IDE legacy mode devices.
1203669a5db4SJeff Garzik * If you fix that note there are special cases to consider like VLB
1204669a5db4SJeff Garzik * drivers and CS5510/20.
1205669a5db4SJeff Garzik */
1206669a5db4SJeff Garzik
legacy_init(void)1207669a5db4SJeff Garzik static __init int legacy_init(void)
1208669a5db4SJeff Garzik {
1209669a5db4SJeff Garzik int i;
1210669a5db4SJeff Garzik int ct = 0;
1211669a5db4SJeff Garzik int primary = 0;
1212669a5db4SJeff Garzik int secondary = 0;
1213669a5db4SJeff Garzik int pci_present = 0;
1214669a5db4SJeff Garzik struct legacy_probe *pl = &probe_list[0];
1215defc9cd8SAlan Cox int slot = 0;
1216defc9cd8SAlan Cox
1217defc9cd8SAlan Cox struct pci_dev *p = NULL;
1218669a5db4SJeff Garzik
1219669a5db4SJeff Garzik for_each_pci_dev(p) {
1220669a5db4SJeff Garzik int r;
1221669a5db4SJeff Garzik /* Check for any overlap of the system ATA mappings. Native
1222669a5db4SJeff Garzik mode controllers stuck on these addresses or some devices
1223defc9cd8SAlan Cox in 'raid' mode won't be found by the storage class test */
1224defc9cd8SAlan Cox for (r = 0; r < 6; r++) {
1225defc9cd8SAlan Cox if (pci_resource_start(p, r) == 0x1f0)
1226669a5db4SJeff Garzik primary = 1;
1227669a5db4SJeff Garzik if (pci_resource_start(p, r) == 0x170)
1228669a5db4SJeff Garzik secondary = 1;
1229669a5db4SJeff Garzik }
1230669a5db4SJeff Garzik /* Check for special cases */
1231669a5db4SJeff Garzik legacy_check_special_cases(p, &primary, &secondary);
1232669a5db4SJeff Garzik
1233669a5db4SJeff Garzik /* If PCI bus is present then don't probe for tertiary
1234669a5db4SJeff Garzik legacy ports */
1235defc9cd8SAlan Cox pci_present = 1;
1236defc9cd8SAlan Cox }
1237defc9cd8SAlan Cox
1238669a5db4SJeff Garzik if (winbond == 1)
1239669a5db4SJeff Garzik winbond = 0x130; /* Default port, alt is 1B0 */
1240b8325487SAlan Cox
1241b8325487SAlan Cox if (primary == 0 || all)
1242b8325487SAlan Cox legacy_probe_add(0x1F0, 14, UNKNOWN, 0);
1243defc9cd8SAlan Cox if (secondary == 0 || all)
1244defc9cd8SAlan Cox legacy_probe_add(0x170, 15, UNKNOWN, 0);
1245defc9cd8SAlan Cox
1246defc9cd8SAlan Cox if (probe_all || !pci_present) {
1247669a5db4SJeff Garzik /* ISA/VLB extra ports */
1248defc9cd8SAlan Cox legacy_probe_add(0x1E8, 11, UNKNOWN, 0);
1249defc9cd8SAlan Cox legacy_probe_add(0x168, 10, UNKNOWN, 0);
1250defc9cd8SAlan Cox legacy_probe_add(0x1E0, 8, UNKNOWN, 0);
1251defc9cd8SAlan Cox legacy_probe_add(0x160, 12, UNKNOWN, 0);
1252defc9cd8SAlan Cox }
1253defc9cd8SAlan Cox
1254669a5db4SJeff Garzik if (opti82c46x)
1255669a5db4SJeff Garzik probe_opti_vlb();
1256defc9cd8SAlan Cox if (qdi)
1257defc9cd8SAlan Cox probe_qdi_vlb();
1258defc9cd8SAlan Cox
1259defc9cd8SAlan Cox for (i = 0; i < NR_HOST; i++, pl++) {
1260defc9cd8SAlan Cox if (pl->port == 0)
1261defc9cd8SAlan Cox continue;
1262defc9cd8SAlan Cox if (pl->type == UNKNOWN)
1263669a5db4SJeff Garzik pl->type = probe_chip_type(pl);
1264defc9cd8SAlan Cox pl->slot = slot++;
1265defc9cd8SAlan Cox if (legacy_init_one(pl) == 0)
1266defc9cd8SAlan Cox ct++;
1267defc9cd8SAlan Cox }
1268669a5db4SJeff Garzik if (ct != 0)
1269669a5db4SJeff Garzik return 0;
1270669a5db4SJeff Garzik return -ENODEV;
1271669a5db4SJeff Garzik }
1272669a5db4SJeff Garzik
legacy_exit(void)1273669a5db4SJeff Garzik static __exit void legacy_exit(void)
1274669a5db4SJeff Garzik {
1275669a5db4SJeff Garzik int i;
1276669a5db4SJeff Garzik
1277669a5db4SJeff Garzik for (i = 0; i < NR_HOST; i++) {
1278669a5db4SJeff Garzik struct legacy_data *ld = &legacy_data[i];
1279669a5db4SJeff Garzik
1280669a5db4SJeff Garzik if (legacy_host[i])
128124dc5f33STejun Heo ata_host_detach(legacy_host[i]);
1282669a5db4SJeff Garzik platform_device_unregister(ld->platform_dev);
1283669a5db4SJeff Garzik }
1284669a5db4SJeff Garzik }
1285669a5db4SJeff Garzik
1286669a5db4SJeff Garzik MODULE_AUTHOR("Alan Cox");
1287669a5db4SJeff Garzik MODULE_DESCRIPTION("low-level driver for legacy ATA");
1288669a5db4SJeff Garzik MODULE_LICENSE("GPL");
1289669a5db4SJeff Garzik MODULE_VERSION(DRV_VERSION);
12900dcd0a76SBartlomiej Zolnierkiewicz MODULE_ALIAS("pata_qdi");
12916d981b9aSBartlomiej Zolnierkiewicz MODULE_ALIAS("pata_winbond");
1292669a5db4SJeff Garzik
1293669a5db4SJeff Garzik module_init(legacy_init);
1294669a5db4SJeff Garzik module_exit(legacy_exit);
1295