aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/Kconfig1
-rw-r--r--drivers/ata/Makefile1
-rw-r--r--drivers/ata/pata_legacy.c9
-rw-r--r--drivers/ata/pata_qdi.c366
4 files changed, 9 insertions, 368 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index c6ef9d0cf370..6bdedd7cca2c 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -831,6 +831,7 @@ config PATA_OF_PLATFORM
831config PATA_QDI 831config PATA_QDI
832 tristate "QDI VLB PATA support" 832 tristate "QDI VLB PATA support"
833 depends on ISA 833 depends on ISA
834 select PATA_LEGACY
834 help 835 help
835 Support for QDI 6500 and 6580 PATA controllers on VESA local bus. 836 Support for QDI 6500 and 6580 PATA controllers on VESA local bus.
836 837
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 9550d691fd19..6ece5b7231a3 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -88,7 +88,6 @@ obj-$(CONFIG_PATA_PCMCIA) += pata_pcmcia.o
88obj-$(CONFIG_PATA_PALMLD) += pata_palmld.o 88obj-$(CONFIG_PATA_PALMLD) += pata_palmld.o
89obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o 89obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o
90obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o 90obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o
91obj-$(CONFIG_PATA_QDI) += pata_qdi.o
92obj-$(CONFIG_PATA_RB532) += pata_rb532_cf.o 91obj-$(CONFIG_PATA_RB532) += pata_rb532_cf.o
93obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o 92obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o
94obj-$(CONFIG_PATA_SAMSUNG_CF) += pata_samsung_cf.o 93obj-$(CONFIG_PATA_SAMSUNG_CF) += pata_samsung_cf.o
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index d960f8e9e8b1..e71fdfbf69b3 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -137,11 +137,17 @@ static int ht6560a; /* HT 6560A on primary 1, second 2, both 3 */
137static int ht6560b; /* HT 6560A on primary 1, second 2, both 3 */ 137static int ht6560b; /* HT 6560A on primary 1, second 2, both 3 */
138static int opti82c611a; /* Opti82c611A on primary 1, sec 2, both 3 */ 138static int opti82c611a; /* Opti82c611A on primary 1, sec 2, both 3 */
139static int opti82c46x; /* Opti 82c465MV present(pri/sec autodetect) */ 139static int opti82c46x; /* Opti 82c465MV present(pri/sec autodetect) */
140static int qdi; /* Set to probe QDI controllers */
141static int autospeed; /* Chip present which snoops speed changes */ 140static int autospeed; /* Chip present which snoops speed changes */
142static int pio_mask = ATA_PIO4; /* PIO range for autospeed devices */ 141static int pio_mask = ATA_PIO4; /* PIO range for autospeed devices */
143static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */ 142static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */
144 143
144/* Set to probe QDI controllers */
145#ifdef CONFIG_PATA_QDI_MODULE
146static int qdi = 1;
147#else
148static int qdi;
149#endif
150
145#ifdef CONFIG_PATA_WINBOND_VLB_MODULE 151#ifdef CONFIG_PATA_WINBOND_VLB_MODULE
146static int winbond = 1; /* Set to probe Winbond controllers, 152static int winbond = 1; /* Set to probe Winbond controllers,
147 give I/O port if non standard */ 153 give I/O port if non standard */
@@ -1306,6 +1312,7 @@ MODULE_AUTHOR("Alan Cox");
1306MODULE_DESCRIPTION("low-level driver for legacy ATA"); 1312MODULE_DESCRIPTION("low-level driver for legacy ATA");
1307MODULE_LICENSE("GPL"); 1313MODULE_LICENSE("GPL");
1308MODULE_VERSION(DRV_VERSION); 1314MODULE_VERSION(DRV_VERSION);
1315MODULE_ALIAS("pata_qdi");
1309MODULE_ALIAS("pata_winbond"); 1316MODULE_ALIAS("pata_winbond");
1310 1317
1311module_param(probe_all, int, 0); 1318module_param(probe_all, int, 0);
diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c
deleted file mode 100644
index 45879dc6fa41..000000000000
--- a/drivers/ata/pata_qdi.c
+++ /dev/null
@@ -1,366 +0,0 @@
1/*
2 * pata_qdi.c - QDI VLB ATA controllers
3 * (C) 2006 Red Hat
4 *
5 * This driver mostly exists as a proof of concept for non PCI devices under
6 * libata. While the QDI6580 was 'neat' in 1993 it is no longer terribly
7 * useful.
8 *
9 * Tuning code written from the documentation at
10 * http://www.ryston.cz/petr/vlb/qd6500.html
11 * http://www.ryston.cz/petr/vlb/qd6580.html
12 *
13 * Probe code based on drivers/ide/legacy/qd65xx.c
14 * Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by
15 * Samuel Thibault <samuel.thibault@ens-lyon.org>
16 */
17
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/pci.h>
21#include <linux/init.h>
22#include <linux/blkdev.h>
23#include <linux/delay.h>
24#include <scsi/scsi_host.h>
25#include <linux/libata.h>
26#include <linux/platform_device.h>
27
28#define DRV_NAME "pata_qdi"
29#define DRV_VERSION "0.3.1"
30
31#define NR_HOST 4 /* Two 6580s */
32
33struct qdi_data {
34 unsigned long timing;
35 u8 clock[2];
36 u8 last;
37 int fast;
38 struct platform_device *platform_dev;
39
40};
41
42static struct ata_host *qdi_host[NR_HOST];
43static struct qdi_data qdi_data[NR_HOST];
44static int nr_qdi_host;
45
46#ifdef MODULE
47static int probe_qdi = 1;
48#else
49static int probe_qdi;
50#endif
51
52static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev)
53{
54 struct ata_timing t;
55 struct qdi_data *qdi = ap->host->private_data;
56 int active, recovery;
57 u8 timing;
58
59 /* Get the timing data in cycles */
60 ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
61
62 if (qdi->fast) {
63 active = 8 - clamp_val(t.active, 1, 8);
64 recovery = 18 - clamp_val(t.recover, 3, 18);
65 } else {
66 active = 9 - clamp_val(t.active, 2, 9);
67 recovery = 15 - clamp_val(t.recover, 0, 15);
68 }
69 timing = (recovery << 4) | active | 0x08;
70
71 qdi->clock[adev->devno] = timing;
72
73 outb(timing, qdi->timing);
74}
75
76static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev)
77{
78 struct ata_timing t;
79 struct qdi_data *qdi = ap->host->private_data;
80 int active, recovery;
81 u8 timing;
82
83 /* Get the timing data in cycles */
84 ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
85
86 if (qdi->fast) {
87 active = 8 - clamp_val(t.active, 1, 8);
88 recovery = 18 - clamp_val(t.recover, 3, 18);
89 } else {
90 active = 9 - clamp_val(t.active, 2, 9);
91 recovery = 15 - clamp_val(t.recover, 0, 15);
92 }
93 timing = (recovery << 4) | active | 0x08;
94
95 qdi->clock[adev->devno] = timing;
96
97 outb(timing, qdi->timing);
98
99 /* Clear the FIFO */
100 if (adev->class != ATA_DEV_ATA)
101 outb(0x5F, (qdi->timing & 0xFFF0) + 3);
102}
103
104/**
105 * qdi_qc_issue - command issue
106 * @qc: command pending
107 *
108 * Called when the libata layer is about to issue a command. We wrap
109 * this interface so that we can load the correct ATA timings.
110 */
111
112static unsigned int qdi_qc_issue(struct ata_queued_cmd *qc)
113{
114 struct ata_port *ap = qc->ap;
115 struct ata_device *adev = qc->dev;
116 struct qdi_data *qdi = ap->host->private_data;
117
118 if (qdi->clock[adev->devno] != qdi->last) {
119 if (adev->pio_mode) {
120 qdi->last = qdi->clock[adev->devno];
121 outb(qdi->clock[adev->devno], qdi->timing);
122 }
123 }
124 return ata_sff_qc_issue(qc);
125}
126
127static unsigned int qdi_data_xfer(struct ata_device *dev, unsigned char *buf,
128 unsigned int buflen, int rw)
129{
130 if (ata_id_has_dword_io(dev->id)) {
131 struct ata_port *ap = dev->link->ap;
132 int slop = buflen & 3;
133
134 if (rw == READ)
135 ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
136 else
137 iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
138
139 if (unlikely(slop)) {
140 __le32 pad;
141 if (rw == READ) {
142 pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
143 memcpy(buf + buflen - slop, &pad, slop);
144 } else {
145 memcpy(&pad, buf + buflen - slop, slop);
146 iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
147 }
148 buflen += 4 - slop;
149 }
150 } else
151 buflen = ata_sff_data_xfer(dev, buf, buflen, rw);
152
153 return buflen;
154}
155
156static struct scsi_host_template qdi_sht = {
157 ATA_PIO_SHT(DRV_NAME),
158};
159
160static struct ata_port_operations qdi6500_port_ops = {
161 .inherits = &ata_sff_port_ops,
162 .qc_issue = qdi_qc_issue,
163 .sff_data_xfer = qdi_data_xfer,
164 .cable_detect = ata_cable_40wire,
165 .set_piomode = qdi6500_set_piomode,
166};
167
168static struct ata_port_operations qdi6580_port_ops = {
169 .inherits = &qdi6500_port_ops,
170 .set_piomode = qdi6580_set_piomode,
171};
172
173/**
174 * qdi_init_one - attach a qdi interface
175 * @type: Type to display
176 * @io: I/O port start
177 * @irq: interrupt line
178 * @fast: True if on a > 33Mhz VLB
179 *
180 * Register an ISA bus IDE interface. Such interfaces are PIO and we
181 * assume do not support IRQ sharing.
182 */
183
184static __init int qdi_init_one(unsigned long port, int type, unsigned long io, int irq, int fast)
185{
186 unsigned long ctl = io + 0x206;
187 struct platform_device *pdev;
188 struct ata_host *host;
189 struct ata_port *ap;
190 void __iomem *io_addr, *ctl_addr;
191 int ret;
192
193 /*
194 * Fill in a probe structure first of all
195 */
196
197 pdev = platform_device_register_simple(DRV_NAME, nr_qdi_host, NULL, 0);
198 if (IS_ERR(pdev))
199 return PTR_ERR(pdev);
200
201 ret = -ENOMEM;
202 io_addr = devm_ioport_map(&pdev->dev, io, 8);
203 ctl_addr = devm_ioport_map(&pdev->dev, ctl, 1);
204 if (!io_addr || !ctl_addr)
205 goto fail;
206
207 ret = -ENOMEM;
208 host = ata_host_alloc(&pdev->dev, 1);
209 if (!host)
210 goto fail;
211 ap = host->ports[0];
212
213 if (type == 6580) {
214 ap->ops = &qdi6580_port_ops;
215 ap->pio_mask = ATA_PIO4;
216 ap->flags |= ATA_FLAG_SLAVE_POSS;
217 } else {
218 ap->ops = &qdi6500_port_ops;
219 ap->pio_mask = ATA_PIO2; /* Actually PIO3 !IORDY is possible */
220 ap->flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_IORDY;
221 }
222
223 ap->ioaddr.cmd_addr = io_addr;
224 ap->ioaddr.altstatus_addr = ctl_addr;
225 ap->ioaddr.ctl_addr = ctl_addr;
226 ata_sff_std_ports(&ap->ioaddr);
227
228 ata_port_desc(ap, "cmd %lx ctl %lx", io, ctl);
229
230 /*
231 * Hook in a private data structure per channel
232 */
233 ap->private_data = &qdi_data[nr_qdi_host];
234
235 qdi_data[nr_qdi_host].timing = port;
236 qdi_data[nr_qdi_host].fast = fast;
237 qdi_data[nr_qdi_host].platform_dev = pdev;
238
239 printk(KERN_INFO DRV_NAME": qd%d at 0x%lx.\n", type, io);
240
241 /* activate */
242 ret = ata_host_activate(host, irq, ata_sff_interrupt, 0, &qdi_sht);
243 if (ret)
244 goto fail;
245
246 qdi_host[nr_qdi_host++] = dev_get_drvdata(&pdev->dev);
247 return 0;
248
249 fail:
250 platform_device_unregister(pdev);
251 return ret;
252}
253
254/**
255 * qdi_init - attach qdi interfaces
256 *
257 * Attach qdi IDE interfaces by scanning the ports it may occupy.
258 */
259
260static __init int qdi_init(void)
261{
262 unsigned long flags;
263 static const unsigned long qd_port[2] = { 0x30, 0xB0 };
264 static const unsigned long ide_port[2] = { 0x170, 0x1F0 };
265 static const int ide_irq[2] = { 14, 15 };
266
267 int ct = 0;
268 int i;
269
270 if (probe_qdi == 0)
271 return -ENODEV;
272
273 /*
274 * Check each possible QD65xx base address
275 */
276
277 for (i = 0; i < 2; i++) {
278 unsigned long port = qd_port[i];
279 u8 r, res;
280
281
282 if (request_region(port, 2, "pata_qdi")) {
283 /* Check for a card */
284 local_irq_save(flags);
285 r = inb_p(port);
286 outb_p(0x19, port);
287 res = inb_p(port);
288 outb_p(r, port);
289 local_irq_restore(flags);
290
291 /* Fail */
292 if (res == 0x19)
293 {
294 release_region(port, 2);
295 continue;
296 }
297
298 /* Passes the presence test */
299 r = inb_p(port + 1); /* Check port agrees with port set */
300 if ((r & 2) >> 1 != i) {
301 release_region(port, 2);
302 continue;
303 }
304
305 /* Check card type */
306 if ((r & 0xF0) == 0xC0) {
307 /* QD6500: single channel */
308 if (r & 8) {
309 /* Disabled ? */
310 release_region(port, 2);
311 continue;
312 }
313 if (qdi_init_one(port, 6500, ide_port[r & 0x01], ide_irq[r & 0x01], r & 0x04) == 0)
314 ct++;
315 }
316 if (((r & 0xF0) == 0xA0) || (r & 0xF0) == 0x50) {
317 /* QD6580: dual channel */
318 if (!request_region(port + 2 , 2, "pata_qdi"))
319 {
320 release_region(port, 2);
321 continue;
322 }
323 res = inb(port + 3);
324 if (res & 1) {
325 /* Single channel mode */
326 if (qdi_init_one(port, 6580, ide_port[r & 0x01], ide_irq[r & 0x01], r & 0x04) == 0)
327 ct++;
328 } else {
329 /* Dual channel mode */
330 if (qdi_init_one(port, 6580, 0x1F0, 14, r & 0x04) == 0)
331 ct++;
332 if (qdi_init_one(port + 2, 6580, 0x170, 15, r & 0x04) == 0)
333 ct++;
334 }
335 }
336 }
337 }
338 if (ct != 0)
339 return 0;
340 return -ENODEV;
341}
342
343static __exit void qdi_exit(void)
344{
345 int i;
346
347 for (i = 0; i < nr_qdi_host; i++) {
348 ata_host_detach(qdi_host[i]);
349 /* Free the control resource. The 6580 dual channel has the resources
350 * claimed as a pair of 2 byte resources so we need no special cases...
351 */
352 release_region(qdi_data[i].timing, 2);
353 platform_device_unregister(qdi_data[i].platform_dev);
354 }
355}
356
357MODULE_AUTHOR("Alan Cox");
358MODULE_DESCRIPTION("low-level driver for qdi ATA");
359MODULE_LICENSE("GPL");
360MODULE_VERSION(DRV_VERSION);
361
362module_init(qdi_init);
363module_exit(qdi_exit);
364
365module_param(probe_qdi, int, 0);
366