xref: /linux/drivers/ata/pata_legacy.c (revision 621cde16e49b3ecf7d59a8106a20aaebfb4a59a9)
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 /**
178defc9cd8SAlan Cox  *	legacy_probe_add	-	Add interface to probe list
179defc9cd8SAlan Cox  *	@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) {
2047d33004dSMaciej W. Rozycki 			if (!(probe_mask & 1 << i))
2057d33004dSMaciej W. Rozycki 				return -1;
206defc9cd8SAlan Cox 			free = lp;
207defc9cd8SAlan Cox 			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 /**
225669a5db4SJeff Garzik  *	legacy_set_mode		-	mode setting
2260260731fSTejun Heo  *	@link: IDE link
227b229a7b0SAlan  *	@unused: Device that failed when error is returned
228669a5db4SJeff Garzik  *
229669a5db4SJeff Garzik  *	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)2370260731fSTejun Heo static int legacy_set_mode(struct ata_link *link, struct ata_device **unused)
238669a5db4SJeff Garzik {
239f58229f8STejun Heo 	struct ata_device *dev;
240669a5db4SJeff Garzik 
2411eca4365STejun Heo 	ata_for_each_dev(dev, link, ENABLED) {
242a9a79dfeSJoe Perches 		ata_dev_info(dev, "configured for PIO\n");
243669a5db4SJeff Garzik 		dev->pio_mode = XFER_PIO_0;
244669a5db4SJeff Garzik 		dev->xfer_mode = XFER_PIO_0;
245669a5db4SJeff Garzik 		dev->xfer_shift = ATA_SHIFT_PIO;
246669a5db4SJeff Garzik 		dev->flags |= ATA_DFLAG_PIO;
247669a5db4SJeff Garzik 	}
248b229a7b0SAlan 	return 0;
249669a5db4SJeff Garzik }
250669a5db4SJeff Garzik 
25125df73d9SBart Van Assche static const struct scsi_host_template legacy_sht = {
25268d1d07bSTejun Heo 	ATA_PIO_SHT(DRV_NAME),
253669a5db4SJeff Garzik };
254669a5db4SJeff Garzik 
255029cfd6bSTejun Heo static const struct ata_port_operations legacy_base_port_ops = {
256029cfd6bSTejun Heo 	.inherits	= &ata_sff_port_ops,
257029cfd6bSTejun Heo 	.cable_detect	= ata_cable_40wire,
258029cfd6bSTejun Heo };
259029cfd6bSTejun Heo 
260669a5db4SJeff Garzik /*
261669a5db4SJeff Garzik  *	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 = {
269029cfd6bSTejun Heo 	.inherits	= &legacy_base_port_ops,
27023ebda2fSSebastian Andrzej Siewior 	.sff_data_xfer	= ata_sff_data_xfer32,
271669a5db4SJeff Garzik };
272669a5db4SJeff Garzik 
273669a5db4SJeff Garzik static struct ata_port_operations legacy_port_ops = {
274029cfd6bSTejun Heo 	.inherits	= &legacy_base_port_ops,
27523ebda2fSSebastian Andrzej Siewior 	.sff_data_xfer	= ata_sff_data_xfer32,
276029cfd6bSTejun Heo 	.set_mode	= legacy_set_mode,
277669a5db4SJeff Garzik };
278669a5db4SJeff Garzik 
279669a5db4SJeff Garzik /*
280669a5db4SJeff Garzik  *	Promise 20230C and 20620 support
281669a5db4SJeff Garzik  *
282defc9cd8SAlan Cox  *	This controller supports PIO0 to PIO2. We set PIO timings
283defc9cd8SAlan Cox  *	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.
286669a5db4SJeff Garzik  */
287669a5db4SJeff Garzik 
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 */
300defc9cd8SAlan Cox 	do {
301669a5db4SJeff Garzik 		inb(0x1F5);
302669a5db4SJeff Garzik 		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);
316171a9318SSergey Shtylyov 	rt &= ~(0x07 << (3 * !adev->devno));
317669a5db4SJeff Garzik 	if (pio)
318171a9318SSergey Shtylyov 		rt |= (1 + 3 * pio) << (3 * !adev->devno);
319171a9318SSergey Shtylyov 	outb(rt, 0x1F3);
320669a5db4SJeff Garzik 
321669a5db4SJeff Garzik 	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)328989e0aacSBartlomiej Zolnierkiewicz static unsigned int pdc_data_xfer_vlb(struct ata_queued_cmd *qc,
32955dba312STejun Heo 			unsigned char *buf, unsigned int buflen, int rw)
330669a5db4SJeff Garzik {
331989e0aacSBartlomiej Zolnierkiewicz 	struct ata_device *dev = qc->dev;
33216e6aecaSZhenwen Xu 	struct ata_port *ap = dev->link->ap;
333989e0aacSBartlomiej Zolnierkiewicz 	int slop = buflen & 3;
33416e6aecaSZhenwen Xu 
335c55af1f5SAlan Cox 	/* 32bit I/O capable *and* we need to write a whole number of dwords */
336e3cf95ddSAlan Cox 	if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3)
337e3cf95ddSAlan Cox 					&& (ap->pflags & ATA_PFLAG_PIO32)) {
338669a5db4SJeff Garzik 		unsigned long flags;
339669a5db4SJeff Garzik 
340669a5db4SJeff Garzik 		local_irq_save(flags);
341669a5db4SJeff Garzik 
342669a5db4SJeff Garzik 		/* Perform the 32bit I/O synchronization sequence */
3430d5ff566STejun Heo 		ioread8(ap->ioaddr.nsect_addr);
3440d5ff566STejun Heo 		ioread8(ap->ioaddr.nsect_addr);
3450d5ff566STejun Heo 		ioread8(ap->ioaddr.nsect_addr);
346669a5db4SJeff Garzik 
347669a5db4SJeff Garzik 		/* Now the data */
34855dba312STejun Heo 		if (rw == READ)
3490d5ff566STejun Heo 			ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
35055dba312STejun Heo 		else
35155dba312STejun Heo 			iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
352669a5db4SJeff Garzik 
353669a5db4SJeff Garzik 		if (unlikely(slop)) {
35401392347SDan Carpenter 			__le32 pad = 0;
35501392347SDan Carpenter 
35655dba312STejun Heo 			if (rw == READ) {
357b50e56d8SAl Viro 				pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
358669a5db4SJeff Garzik 				memcpy(buf + buflen - slop, &pad, slop);
35955dba312STejun Heo 			} else {
36055dba312STejun Heo 				memcpy(&pad, buf + buflen - slop, slop);
36155dba312STejun Heo 				iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
362669a5db4SJeff Garzik 			}
36355dba312STejun Heo 			buflen += 4 - slop;
364669a5db4SJeff Garzik 		}
365669a5db4SJeff Garzik 		local_irq_restore(flags);
36655dba312STejun Heo 	} else
36723ebda2fSSebastian Andrzej Siewior 		buflen = ata_sff_data_xfer32(qc, buf, buflen, rw);
36855dba312STejun Heo 
36955dba312STejun Heo 	return buflen;
370669a5db4SJeff Garzik }
371669a5db4SJeff Garzik 
372669a5db4SJeff Garzik static struct ata_port_operations pdc20230_port_ops = {
373029cfd6bSTejun Heo 	.inherits	= &legacy_base_port_ops,
374669a5db4SJeff Garzik 	.set_piomode	= pdc20230_set_piomode,
3755682ed33STejun Heo 	.sff_data_xfer	= pdc_data_xfer_vlb,
376669a5db4SJeff Garzik };
377669a5db4SJeff Garzik 
378669a5db4SJeff Garzik /*
379669a5db4SJeff Garzik  *	Holtek 6560A support
380669a5db4SJeff Garzik  *
381defc9cd8SAlan Cox  *	This controller supports PIO0 to PIO2 (no IORDY even though higher
382defc9cd8SAlan Cox  *	timings can be loaded).
383669a5db4SJeff Garzik  */
384669a5db4SJeff Garzik 
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 
39307633b5dSHarvey Harrison 	active = clamp_val(t.active, 2, 15);
39407633b5dSHarvey Harrison 	recover = clamp_val(t.recover, 4, 15);
395669a5db4SJeff Garzik 
396669a5db4SJeff Garzik 	inb(0x3E6);
397669a5db4SJeff Garzik 	inb(0x3E6);
398669a5db4SJeff Garzik 	inb(0x3E6);
399669a5db4SJeff Garzik 	inb(0x3E6);
400669a5db4SJeff Garzik 
4010d5ff566STejun Heo 	iowrite8(recover << 4 | active, ap->ioaddr.device_addr);
4020d5ff566STejun Heo 	ioread8(ap->ioaddr.status_addr);
403669a5db4SJeff Garzik }
404669a5db4SJeff Garzik 
405669a5db4SJeff Garzik static struct ata_port_operations ht6560a_port_ops = {
406029cfd6bSTejun Heo 	.inherits	= &legacy_base_port_ops,
407669a5db4SJeff Garzik 	.set_piomode	= ht6560a_set_piomode,
408669a5db4SJeff Garzik };
409669a5db4SJeff Garzik 
410669a5db4SJeff Garzik /*
411669a5db4SJeff Garzik  *	Holtek 6560B support
412669a5db4SJeff Garzik  *
413defc9cd8SAlan Cox  *	This controller supports PIO0 to PIO4. We honour the BIOS/jumper FIFO
414defc9cd8SAlan Cox  *	setting unless we see an ATAPI device in which case we force it off.
415669a5db4SJeff Garzik  *
416669a5db4SJeff Garzik  *	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 
42707633b5dSHarvey Harrison 	active = clamp_val(t.active, 2, 15);
42897163873SSergei Shtylyov 	recover = clamp_val(t.recover, 2, 16) & 0x0F;
429669a5db4SJeff Garzik 
430669a5db4SJeff Garzik 	inb(0x3E6);
431669a5db4SJeff Garzik 	inb(0x3E6);
432669a5db4SJeff Garzik 	inb(0x3E6);
433669a5db4SJeff Garzik 	inb(0x3E6);
434669a5db4SJeff Garzik 
4350d5ff566STejun Heo 	iowrite8(recover << 4 | active, ap->ioaddr.device_addr);
436669a5db4SJeff Garzik 
437669a5db4SJeff Garzik 	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 	}
4440d5ff566STejun Heo 	ioread8(ap->ioaddr.status_addr);
445669a5db4SJeff Garzik }
446669a5db4SJeff Garzik 
447669a5db4SJeff Garzik static struct ata_port_operations ht6560b_port_ops = {
448029cfd6bSTejun Heo 	.inherits	= &legacy_base_port_ops,
449669a5db4SJeff Garzik 	.set_piomode	= ht6560b_set_piomode,
450669a5db4SJeff Garzik };
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)482defc9cd8SAlan Cox static void opti82c611a_set_piomode(struct ata_port *ap,
483defc9cd8SAlan Cox 						struct ata_device *adev)
484669a5db4SJeff Garzik {
485669a5db4SJeff Garzik 	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 */
4930d5ff566STejun Heo 	ioread16(ap->ioaddr.error_addr);
4940d5ff566STejun Heo 	ioread16(ap->ioaddr.error_addr);
4950d5ff566STejun Heo 	iowrite8(3, ap->ioaddr.nsect_addr);
496669a5db4SJeff Garzik 
497669a5db4SJeff Garzik 	/* Read VLB clock strapping */
4980d5ff566STejun Heo 	clock = 1000000000 / khz[ioread8(ap->ioaddr.lbah_addr) & 0x03];
499669a5db4SJeff Garzik 
500669a5db4SJeff Garzik 	/* 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 
51107633b5dSHarvey Harrison 	active = clamp_val(t.active, 2, 17) - 2;
51207633b5dSHarvey Harrison 	recover = clamp_val(t.recover, 1, 16) - 1;
51307633b5dSHarvey Harrison 	setup = clamp_val(t.setup, 1, 4) - 1;
514669a5db4SJeff Garzik 
515669a5db4SJeff Garzik 	/* Select the right timing bank for write timing */
5160d5ff566STejun Heo 	rc = ioread8(ap->ioaddr.lbal_addr);
517669a5db4SJeff Garzik 	rc &= 0x7F;
518669a5db4SJeff Garzik 	rc |= (adev->devno << 7);
5190d5ff566STejun Heo 	iowrite8(rc, ap->ioaddr.lbal_addr);
520669a5db4SJeff Garzik 
521669a5db4SJeff Garzik 	/* Write the timings */
5220d5ff566STejun Heo 	iowrite8(active << 4 | recover, ap->ioaddr.error_addr);
523669a5db4SJeff Garzik 
524669a5db4SJeff Garzik 	/* Select the right bank for read timings, also
525669a5db4SJeff Garzik 	   load the shared timings for address */
5260d5ff566STejun Heo 	rc = ioread8(ap->ioaddr.device_addr);
527669a5db4SJeff Garzik 	rc &= 0xC0;
528669a5db4SJeff Garzik 	rc |= adev->devno;	/* Index select */
529669a5db4SJeff Garzik 	rc |= (setup << 4) | 0x04;
5300d5ff566STejun Heo 	iowrite8(rc, ap->ioaddr.device_addr);
531669a5db4SJeff Garzik 
532669a5db4SJeff Garzik 	/* Load the read timings */
5330d5ff566STejun Heo 	iowrite8(active << 4 | recover, ap->ioaddr.data_addr);
534669a5db4SJeff Garzik 
535669a5db4SJeff Garzik 	/* Ensure the timing register mode is right */
5360d5ff566STejun Heo 	rc = ioread8(ap->ioaddr.lbal_addr);
537669a5db4SJeff Garzik 	rc &= 0x73;
538669a5db4SJeff Garzik 	rc |= 0x84;
5390d5ff566STejun Heo 	iowrite8(rc, ap->ioaddr.lbal_addr);
540669a5db4SJeff Garzik 
541669a5db4SJeff Garzik 	/* Exit command mode */
5420d5ff566STejun Heo 	iowrite8(0x83,  ap->ioaddr.nsect_addr);
543669a5db4SJeff Garzik }
544669a5db4SJeff Garzik 
545669a5db4SJeff Garzik 
546669a5db4SJeff Garzik static struct ata_port_operations opti82c611a_port_ops = {
547029cfd6bSTejun Heo 	.inherits	= &legacy_base_port_ops,
548669a5db4SJeff Garzik 	.set_piomode	= opti82c611a_set_piomode,
549669a5db4SJeff Garzik };
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 */
569e0044c98SDan Carpenter 	sysclk = (opti_syscfg(0xAC) & 0xC0) >> 6;	/* BIOS set */
570669a5db4SJeff Garzik 
571669a5db4SJeff Garzik 	/* Enter configuration mode */
5720d5ff566STejun Heo 	ioread16(ap->ioaddr.error_addr);
5730d5ff566STejun Heo 	ioread16(ap->ioaddr.error_addr);
5740d5ff566STejun Heo 	iowrite8(3, ap->ioaddr.nsect_addr);
575669a5db4SJeff Garzik 
576669a5db4SJeff Garzik 	/* 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 
59007633b5dSHarvey Harrison 	active = clamp_val(t.active, 2, 17) - 2;
59107633b5dSHarvey Harrison 	recover = clamp_val(t.recover, 1, 16) - 1;
59207633b5dSHarvey Harrison 	setup = clamp_val(t.setup, 1, 4) - 1;
593669a5db4SJeff Garzik 
594669a5db4SJeff Garzik 	/* Select the right timing bank for write timing */
5950d5ff566STejun Heo 	rc = ioread8(ap->ioaddr.lbal_addr);
596669a5db4SJeff Garzik 	rc &= 0x7F;
597669a5db4SJeff Garzik 	rc |= (adev->devno << 7);
5980d5ff566STejun Heo 	iowrite8(rc, ap->ioaddr.lbal_addr);
599669a5db4SJeff Garzik 
600669a5db4SJeff Garzik 	/* Write the timings */
6010d5ff566STejun Heo 	iowrite8(active << 4 | recover, ap->ioaddr.error_addr);
602669a5db4SJeff Garzik 
603669a5db4SJeff Garzik 	/* Select the right bank for read timings, also
604669a5db4SJeff Garzik 	   load the shared timings for address */
6050d5ff566STejun Heo 	rc = ioread8(ap->ioaddr.device_addr);
606669a5db4SJeff Garzik 	rc &= 0xC0;
607669a5db4SJeff Garzik 	rc |= adev->devno;	/* Index select */
608669a5db4SJeff Garzik 	rc |= (setup << 4) | 0x04;
6090d5ff566STejun Heo 	iowrite8(rc, ap->ioaddr.device_addr);
610669a5db4SJeff Garzik 
611669a5db4SJeff Garzik 	/* Load the read timings */
6120d5ff566STejun Heo 	iowrite8(active << 4 | recover, ap->ioaddr.data_addr);
613669a5db4SJeff Garzik 
614669a5db4SJeff Garzik 	/* Ensure the timing register mode is right */
6150d5ff566STejun Heo 	rc = ioread8(ap->ioaddr.lbal_addr);
616669a5db4SJeff Garzik 	rc &= 0x73;
617669a5db4SJeff Garzik 	rc |= 0x84;
6180d5ff566STejun Heo 	iowrite8(rc, ap->ioaddr.lbal_addr);
619669a5db4SJeff Garzik 
620669a5db4SJeff Garzik 	/* Exit command mode */
6210d5ff566STejun Heo 	iowrite8(0x83,  ap->ioaddr.nsect_addr);
622669a5db4SJeff Garzik 
623669a5db4SJeff Garzik 	/* We need to know this for quad device on the MVB */
624669a5db4SJeff Garzik 	ap->host->private_data = ap;
625669a5db4SJeff Garzik }
626669a5db4SJeff Garzik 
627669a5db4SJeff Garzik /**
628145f74faSLee Jones  *	opti82c46x_qc_issue		-	command issue
629669a5db4SJeff Garzik  *	@qc: command pending
630669a5db4SJeff Garzik  *
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)6429363c382STejun Heo static unsigned int opti82c46x_qc_issue(struct ata_queued_cmd *qc)
643669a5db4SJeff Garzik {
644669a5db4SJeff Garzik 	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 
6539363c382STejun Heo 	return ata_sff_qc_issue(qc);
654669a5db4SJeff Garzik }
655669a5db4SJeff Garzik 
656669a5db4SJeff Garzik static struct ata_port_operations opti82c46x_port_ops = {
657029cfd6bSTejun Heo 	.inherits	= &legacy_base_port_ops,
658669a5db4SJeff Garzik 	.set_piomode	= opti82c46x_set_piomode,
6599363c382STejun Heo 	.qc_issue	= opti82c46x_qc_issue,
660669a5db4SJeff Garzik };
661669a5db4SJeff Garzik 
662669a5db4SJeff Garzik /**
6638c7e8f94SBartlomiej Zolnierkiewicz  *	qdi65x0_set_piomode		-	PIO setup for QDI65x0
664defc9cd8SAlan Cox  *	@ap: Port
665defc9cd8SAlan Cox  *	@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.
6708c7e8f94SBartlomiej Zolnierkiewicz  *
6718c7e8f94SBartlomiej Zolnierkiewicz  *	In dual channel mode the 6580 has one clock per channel and we have
6728c7e8f94SBartlomiej Zolnierkiewicz  *	to software clockswitch in qc_issue.
673defc9cd8SAlan Cox  */
674669a5db4SJeff Garzik 
qdi65x0_set_piomode(struct ata_port * ap,struct ata_device * adev)6758c7e8f94SBartlomiej Zolnierkiewicz static void qdi65x0_set_piomode(struct ata_port *ap, struct ata_device *adev)
676defc9cd8SAlan Cox {
677defc9cd8SAlan Cox 	struct ata_timing t;
678cb616dd5SHarvey Harrison 	struct legacy_data *ld_qdi = ap->host->private_data;
679defc9cd8SAlan Cox 	int active, recovery;
680defc9cd8SAlan Cox 	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 
685cb616dd5SHarvey Harrison 	if (ld_qdi->fast) {
68607633b5dSHarvey Harrison 		active = 8 - clamp_val(t.active, 1, 8);
68707633b5dSHarvey Harrison 		recovery = 18 - clamp_val(t.recover, 3, 18);
688defc9cd8SAlan Cox 	} else {
68907633b5dSHarvey Harrison 		active = 9 - clamp_val(t.active, 2, 9);
69007633b5dSHarvey Harrison 		recovery = 15 - clamp_val(t.recover, 0, 15);
691defc9cd8SAlan Cox 	}
692defc9cd8SAlan Cox 	timing = (recovery << 4) | active | 0x08;
693cb616dd5SHarvey Harrison 	ld_qdi->clock[adev->devno] = timing;
6948c7e8f94SBartlomiej Zolnierkiewicz 
6958c7e8f94SBartlomiej Zolnierkiewicz 	if (ld_qdi->type == QDI6580)
696cb616dd5SHarvey Harrison 		outb(timing, ld_qdi->timing + 2 * adev->devno);
6978c7e8f94SBartlomiej Zolnierkiewicz 	else
6988c7e8f94SBartlomiej Zolnierkiewicz 		outb(timing, ld_qdi->timing + 2 * ap->port_no);
6998c7e8f94SBartlomiej Zolnierkiewicz 
700defc9cd8SAlan Cox 	/* Clear the FIFO */
7018c7e8f94SBartlomiej Zolnierkiewicz 	if (ld_qdi->type != QDI6500 && adev->class != ATA_DEV_ATA)
7026809e730SBartlomiej Zolnierkiewicz 		outb(0x5F, (ld_qdi->timing & 0xFFF0) + 3);
703defc9cd8SAlan Cox }
704defc9cd8SAlan Cox 
705defc9cd8SAlan Cox /**
7069363c382STejun Heo  *	qdi_qc_issue		-	command issue
707defc9cd8SAlan Cox  *	@qc: command pending
708defc9cd8SAlan Cox  *
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)7139363c382STejun Heo static unsigned int qdi_qc_issue(struct ata_queued_cmd *qc)
714defc9cd8SAlan Cox {
715defc9cd8SAlan Cox 	struct ata_port *ap = qc->ap;
716defc9cd8SAlan Cox 	struct ata_device *adev = qc->dev;
717cb616dd5SHarvey Harrison 	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];
722cb616dd5SHarvey Harrison 			outb(ld_qdi->clock[adev->devno], ld_qdi->timing +
723defc9cd8SAlan Cox 							2 * ap->port_no);
724defc9cd8SAlan Cox 		}
725defc9cd8SAlan Cox 	}
7269363c382STejun Heo 	return ata_sff_qc_issue(qc);
727defc9cd8SAlan Cox }
728defc9cd8SAlan Cox 
vlb32_data_xfer(struct ata_queued_cmd * qc,unsigned char * buf,unsigned int buflen,int rw)729989e0aacSBartlomiej Zolnierkiewicz static unsigned int vlb32_data_xfer(struct ata_queued_cmd *qc,
730989e0aacSBartlomiej Zolnierkiewicz 				    unsigned char *buf,
731defc9cd8SAlan Cox 				    unsigned int buflen, int rw)
732defc9cd8SAlan Cox {
733989e0aacSBartlomiej Zolnierkiewicz 	struct ata_device *adev = qc->dev;
734defc9cd8SAlan Cox 	struct ata_port *ap = adev->link->ap;
735defc9cd8SAlan Cox 	int slop = buflen & 3;
736defc9cd8SAlan Cox 
737e3cf95ddSAlan Cox 	if (ata_id_has_dword_io(adev->id) && (slop == 0 || slop == 3)
738e3cf95ddSAlan Cox 					&& (ap->pflags & ATA_PFLAG_PIO32)) {
739defc9cd8SAlan Cox 		if (rw == WRITE)
740defc9cd8SAlan 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)) {
74501392347SDan Carpenter 			__le32 pad = 0;
74601392347SDan Carpenter 
747defc9cd8SAlan Cox 			if (rw == WRITE) {
748defc9cd8SAlan Cox 				memcpy(&pad, buf + buflen - slop, slop);
7496ad67403SHarvey Harrison 				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);
753defc9cd8SAlan Cox 			}
754defc9cd8SAlan Cox 		}
755defc9cd8SAlan Cox 		return (buflen + 3) & ~3;
756defc9cd8SAlan Cox 	} else
757989e0aacSBartlomiej Zolnierkiewicz 		return ata_sff_data_xfer(qc, buf, buflen, rw);
758defc9cd8SAlan Cox }
759defc9cd8SAlan Cox 
qdi_port(struct platform_device * dev,struct legacy_probe * lp,struct legacy_data * ld)760b8325487SAlan Cox static int qdi_port(struct platform_device *dev,
761b8325487SAlan 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 
769defc9cd8SAlan Cox static struct ata_port_operations qdi6500_port_ops = {
770029cfd6bSTejun Heo 	.inherits	= &legacy_base_port_ops,
7718c7e8f94SBartlomiej Zolnierkiewicz 	.set_piomode	= qdi65x0_set_piomode,
7729363c382STejun Heo 	.qc_issue	= qdi_qc_issue,
7735682ed33STejun Heo 	.sff_data_xfer	= vlb32_data_xfer,
774defc9cd8SAlan Cox };
775defc9cd8SAlan Cox 
776defc9cd8SAlan Cox static struct ata_port_operations qdi6580_port_ops = {
777029cfd6bSTejun Heo 	.inherits	= &legacy_base_port_ops,
7788c7e8f94SBartlomiej Zolnierkiewicz 	.set_piomode	= qdi65x0_set_piomode,
7795682ed33STejun Heo 	.sff_data_xfer	= vlb32_data_xfer,
780defc9cd8SAlan Cox };
781defc9cd8SAlan Cox 
782defc9cd8SAlan Cox static struct ata_port_operations qdi6580dp_port_ops = {
783029cfd6bSTejun Heo 	.inherits	= &legacy_base_port_ops,
7848c7e8f94SBartlomiej Zolnierkiewicz 	.set_piomode	= qdi65x0_set_piomode,
78543c7d17eSBartlomiej Zolnierkiewicz 	.qc_issue	= qdi_qc_issue,
7865682ed33STejun Heo 	.sff_data_xfer	= vlb32_data_xfer,
787defc9cd8SAlan Cox };
788defc9cd8SAlan Cox 
789b8325487SAlan Cox static DEFINE_SPINLOCK(winbond_lock);
790b8325487SAlan 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;
816cb616dd5SHarvey Harrison 	struct legacy_data *ld_winbond = ap->host->private_data;
817b8325487SAlan Cox 	int active, recovery;
818b8325487SAlan Cox 	u8 reg;
819b8325487SAlan Cox 	int timing = 0x88 + (ap->port_no * 4) + (adev->devno * 2);
820b8325487SAlan Cox 
821cb616dd5SHarvey Harrison 	reg = winbond_readcfg(ld_winbond->timing, 0x81);
822b8325487SAlan Cox 
823b8325487SAlan Cox 	/* 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 
82907633b5dSHarvey Harrison 	active = (clamp_val(t.active, 3, 17) - 1) & 0x0F;
83007633b5dSHarvey Harrison 	recovery = (clamp_val(t.recover, 1, 15) + 1) & 0x0F;
831b8325487SAlan Cox 	timing = (active << 4) | recovery;
832cb616dd5SHarvey Harrison 	winbond_writecfg(ld_winbond->timing, timing, reg);
833b8325487SAlan Cox 
834b8325487SAlan Cox 	/* 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 */
84107633b5dSHarvey Harrison 	reg |= (clamp_val(t.setup, 0, 3) << 6);
842cb616dd5SHarvey Harrison 	winbond_writecfg(ld_winbond->timing, timing + 1, reg);
843b8325487SAlan Cox }
844b8325487SAlan Cox 
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 = {
855029cfd6bSTejun Heo 	.inherits	= &legacy_base_port_ops,
856b8325487SAlan Cox 	.set_piomode	= winbond_set_piomode,
8575682ed33STejun Heo 	.sff_data_xfer	= vlb32_data_xfer,
858b8325487SAlan Cox };
859b8325487SAlan Cox 
860defc9cd8SAlan Cox static struct legacy_controller controllers[] = {
861b2f104bbSBartlomiej Zolnierkiewicz 	{"BIOS",	&legacy_port_ops, 	ATA_PIO4,
862e3cf95ddSAlan 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,
86716e6aecaSZhenwen Xu 			ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE,	NULL },
868b2f104bbSBartlomiej Zolnierkiewicz 	{"HT6560A",	&ht6560a_port_ops,	ATA_PIO2,
869e3cf95ddSAlan Cox 			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,
87816e6aecaSZhenwen Xu 			ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE,    qdi_port },
879b2f104bbSBartlomiej Zolnierkiewicz 	{"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,
885e3cf95ddSAlan Cox 								winbond_port }
886defc9cd8SAlan Cox };
887defc9cd8SAlan 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)896b8325487SAlan Cox static __init int probe_chip_type(struct legacy_probe *probe)
897defc9cd8SAlan Cox {
898defc9cd8SAlan Cox 	int mask = 1 << probe->slot;
899defc9cd8SAlan Cox 
900b8325487SAlan Cox 	if (winbond && (probe->port == 0x1F0 || probe->port == 0x170)) {
901b8325487SAlan 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 	}
916defc9cd8SAlan Cox 	if (probe->port == 0x1F0) {
917669a5db4SJeff Garzik 		unsigned long flags;
918669a5db4SJeff Garzik 		local_irq_save(flags);
919669a5db4SJeff Garzik 		/* Probes */
920669a5db4SJeff Garzik 		outb(inb(0x1F2) | 0x80, 0x1F2);
921defc9cd8SAlan Cox 		inb(0x1F5);
922669a5db4SJeff Garzik 		inb(0x1F2);
923669a5db4SJeff Garzik 		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 ? */
930defc9cd8SAlan Cox 			printk(KERN_INFO  "PDC20230-C/20630 VLB ATA controller"
931defc9cd8SAlan Cox 							" detected.\n");
932669a5db4SJeff Garzik 			udelay(100);
933669a5db4SJeff Garzik 			inb(0x1F5);
934defc9cd8SAlan Cox 			local_irq_restore(flags);
935defc9cd8SAlan Cox 			return PDC20230;
936669a5db4SJeff Garzik 		} else {
937669a5db4SJeff Garzik 			outb(0x55, 0x1F2);
938669a5db4SJeff Garzik 			inb(0x1F2);
939669a5db4SJeff Garzik 			inb(0x1F2);
940defc9cd8SAlan Cox 			if (inb(0x1F2) == 0x00)
941defc9cd8SAlan Cox 				printk(KERN_INFO "PDC20230-B VLB ATA "
942defc9cd8SAlan Cox 						     "controller detected.\n");
943defc9cd8SAlan Cox 			local_irq_restore(flags);
944defc9cd8SAlan Cox 			return BIOS;
945669a5db4SJeff Garzik 		}
946669a5db4SJeff Garzik 	}
947669a5db4SJeff Garzik 
948defc9cd8SAlan Cox 	if (ht6560a & mask)
949defc9cd8SAlan Cox 		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 }
960669a5db4SJeff Garzik 
961defc9cd8SAlan Cox 
962defc9cd8SAlan Cox /**
963defc9cd8SAlan Cox  *	legacy_init_one		-	attach a legacy interface
964145f74faSLee Jones  *	@probe: probe record
965defc9cd8SAlan Cox  *
966defc9cd8SAlan Cox  *	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;
997f834e49fSAlan Cox 
9985d728824STejun Heo 	ret = -ENOMEM;
999defc9cd8SAlan Cox 	io_addr = devm_ioport_map(&pdev->dev, io, 8);
1000defc9cd8SAlan Cox 	ctrl_addr = devm_ioport_map(&pdev->dev, io + 0x0206, 1);
1001defc9cd8SAlan Cox 	if (!io_addr || !ctrl_addr)
1002defc9cd8SAlan Cox 		goto fail;
10038c7e8f94SBartlomiej Zolnierkiewicz 	ld->type = probe->type;
1004defc9cd8SAlan Cox 	if (controller->setup)
1005b8325487SAlan Cox 		if (controller->setup(pdev, probe, ld) < 0)
1006defc9cd8SAlan Cox 			goto fail;
10075d728824STejun Heo 	host = ata_host_alloc(&pdev->dev, 1);
10085d728824STejun Heo 	if (!host)
10095d728824STejun Heo 		goto fail;
10105d728824STejun Heo 	ap = host->ports[0];
1011669a5db4SJeff Garzik 
10125d728824STejun Heo 	ap->ops = ops;
10135d728824STejun Heo 	ap->pio_mask = pio_modes;
10145d728824STejun Heo 	ap->flags |= ATA_FLAG_SLAVE_POSS | iordy;
1015e3cf95ddSAlan Cox 	ap->pflags |= controller->pflags;
10165d728824STejun Heo 	ap->ioaddr.cmd_addr = io_addr;
10175d728824STejun Heo 	ap->ioaddr.altstatus_addr = ctrl_addr;
10185d728824STejun Heo 	ap->ioaddr.ctl_addr = ctrl_addr;
10199363c382STejun Heo 	ata_sff_std_ports(&ap->ioaddr);
1020b8325487SAlan Cox 	ap->host->private_data = ld;
10215d728824STejun Heo 
1022defc9cd8SAlan Cox 	ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", io, io + 0x0206);
1023cbcdd875STejun Heo 
10249363c382STejun Heo 	ret = ata_host_activate(host, probe->irq, ata_sff_interrupt, 0,
1025defc9cd8SAlan Cox 				&legacy_sht);
10265d728824STejun Heo 	if (ret)
1027669a5db4SJeff Garzik 		goto fail;
102845bc955bSJames Bottomley 	async_synchronize_full();
1029defc9cd8SAlan Cox 	ld->platform_dev = pdev;
103024dc5f33STejun Heo 
1031defc9cd8SAlan Cox 	/* Nothing found means we drop the port as its probably not there */
1032defc9cd8SAlan Cox 
1033defc9cd8SAlan Cox 	ret = -ENODEV;
10341eca4365STejun Heo 	ata_for_each_dev(dev, &ap->link, ALL) {
1035defc9cd8SAlan Cox 		if (!ata_dev_absent(dev)) {
1036defc9cd8SAlan Cox 			legacy_host[probe->slot] = host;
1037669a5db4SJeff Garzik 			ld->platform_dev = pdev;
1038669a5db4SJeff Garzik 			return 0;
1039defc9cd8SAlan Cox 		}
1040defc9cd8SAlan Cox 	}
104120cbf5f8STejun Heo 	ata_host_detach(host);
1042669a5db4SJeff Garzik fail:
1043669a5db4SJeff Garzik 	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
1050145f74faSLee Jones  *	@primary: set this if we find an ATA master
1051145f74faSLee Jones  *	@secondary: set this if we find an ATA secondary
1052669a5db4SJeff Garzik  *
1053defc9cd8SAlan Cox  *	A small number of vendors implemented early PCI ATA interfaces
1054defc9cd8SAlan Cox  *	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.
1058669a5db4SJeff Garzik  */
1059669a5db4SJeff Garzik 
legacy_check_special_cases(struct pci_dev * p,int * primary,int * secondary)1060b8325487SAlan Cox static void __init legacy_check_special_cases(struct pci_dev *p, int *primary,
1061defc9cd8SAlan Cox 								int *secondary)
1062669a5db4SJeff Garzik {
1063669a5db4SJeff Garzik 	/* 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);
1077defc9cd8SAlan Cox 		if (r & 0x8000) {
1078defc9cd8SAlan Cox 			/* ATA port enabled */
1079669a5db4SJeff Garzik 			if (r & 0x4000)
1080669a5db4SJeff Garzik 				*secondary = 1;
1081669a5db4SJeff Garzik 			else
1082669a5db4SJeff Garzik 				*primary = 1;
1083669a5db4SJeff Garzik 		}
1084669a5db4SJeff Garzik 		return;
1085669a5db4SJeff Garzik 	}
1086669a5db4SJeff Garzik }
1087669a5db4SJeff Garzik 
probe_opti_vlb(void)1088defc9cd8SAlan Cox static __init void probe_opti_vlb(void)
1089defc9cd8SAlan Cox {
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 */
1125b8325487SAlan Cox 		if (r & 8)
1126defc9cd8SAlan Cox 			/* Disabled ? */
1127defc9cd8SAlan 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 		}
1147b8325487SAlan Cox 		release_region(port + 2, 2);
1148defc9cd8SAlan Cox 	}
1149defc9cd8SAlan 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 */
1190b8325487SAlan Cox 			if ((r & 2) >> 1 == i)
1191defc9cd8SAlan Cox 				qdi65_identify_port(r, res, port);
1192b8325487SAlan Cox 			release_region(port, 2);
1193defc9cd8SAlan Cox 		}
1194defc9cd8SAlan Cox 	}
1195defc9cd8SAlan Cox }
1196669a5db4SJeff Garzik 
1197669a5db4SJeff Garzik /**
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;
1213defc9cd8SAlan Cox 	int pci_present = 0;
1214defc9cd8SAlan Cox 	struct legacy_probe *pl = &probe_list[0];
1215defc9cd8SAlan Cox 	int slot = 0;
1216669a5db4SJeff Garzik 
1217669a5db4SJeff Garzik 	struct pci_dev *p = NULL;
1218669a5db4SJeff Garzik 
1219669a5db4SJeff Garzik 	for_each_pci_dev(p) {
1220669a5db4SJeff Garzik 		int r;
1221defc9cd8SAlan Cox 		/* Check for any overlap of the system ATA mappings. Native
1222defc9cd8SAlan Cox 		   mode controllers stuck on these addresses or some devices
1223defc9cd8SAlan Cox 		   in 'raid' mode won't be found by the storage class test */
1224669a5db4SJeff Garzik 		for (r = 0; r < 6; r++) {
1225669a5db4SJeff Garzik 			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 
1233defc9cd8SAlan Cox 		/* If PCI bus is present then don't probe for tertiary
1234defc9cd8SAlan Cox 		   legacy ports */
1235defc9cd8SAlan Cox 		pci_present = 1;
1236669a5db4SJeff Garzik 	}
1237669a5db4SJeff Garzik 
1238b8325487SAlan Cox 	if (winbond == 1)
1239b8325487SAlan Cox 		winbond = 0x130;	/* Default port, alt is 1B0 */
1240b8325487SAlan Cox 
1241defc9cd8SAlan Cox 	if (primary == 0 || all)
1242defc9cd8SAlan Cox 		legacy_probe_add(0x1F0, 14, UNKNOWN, 0);
1243defc9cd8SAlan Cox 	if (secondary == 0 || all)
1244defc9cd8SAlan Cox 		legacy_probe_add(0x170, 15, UNKNOWN, 0);
1245669a5db4SJeff Garzik 
1246defc9cd8SAlan Cox 	if (probe_all || !pci_present) {
1247defc9cd8SAlan Cox 		/* 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);
1252669a5db4SJeff Garzik 	}
1253669a5db4SJeff Garzik 
1254defc9cd8SAlan Cox 	if (opti82c46x)
1255defc9cd8SAlan Cox 		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)
1261669a5db4SJeff Garzik 			continue;
1262defc9cd8SAlan Cox 		if (pl->type == UNKNOWN)
1263defc9cd8SAlan Cox 			pl->type = probe_chip_type(pl);
1264defc9cd8SAlan Cox 		pl->slot = slot++;
1265defc9cd8SAlan Cox 		if (legacy_init_one(pl) == 0)
1266669a5db4SJeff Garzik 			ct++;
1267669a5db4SJeff Garzik 	}
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 
1277*d4a89339SSergey Shtylyov 	for (i = 0; i < NR_HOST; i++) {
1278669a5db4SJeff Garzik 		struct legacy_data *ld = &legacy_data[i];
1279*d4a89339SSergey Shtylyov 
1280*d4a89339SSergey Shtylyov 		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