aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/Kconfig9
-rw-r--r--drivers/ata/Makefile2
-rw-r--r--drivers/ata/pata_acpi.c395
3 files changed, 406 insertions, 0 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index cf960bd1c00a..4672066167e3 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -173,6 +173,15 @@ config SATA_INIC162X
173 help 173 help
174 This option enables support for Initio 162x Serial ATA. 174 This option enables support for Initio 162x Serial ATA.
175 175
176config PATA_ACPI
177 tristate "ACPI firmware driver for PATA"
178 depends on ATA_ACPI
179 help
180 This option enables an ACPI method driver which drives
181 motherboard PATA controller interfaces through the ACPI
182 firmware in the BIOS. This driver can sometimes handle
183 otherwise unsupported hardware.
184
176config PATA_ALI 185config PATA_ALI
177 tristate "ALi PATA support (Experimental)" 186 tristate "ALi PATA support (Experimental)"
178 depends on PCI && EXPERIMENTAL 187 depends on PCI && EXPERIMENTAL
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 7e937519a930..2a63645003eb 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -66,6 +66,8 @@ obj-$(CONFIG_PATA_SCC) += pata_scc.o
66obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o 66obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o
67obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o 67obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o
68obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o 68obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o
69# Should be last but two libata driver
70obj-$(CONFIG_PATA_ACPI) += pata_acpi.o
69# Should be last but one libata driver 71# Should be last but one libata driver
70obj-$(CONFIG_ATA_GENERIC) += ata_generic.o 72obj-$(CONFIG_ATA_GENERIC) += ata_generic.o
71# Should be last libata driver 73# Should be last libata driver
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c
new file mode 100644
index 000000000000..5d3920f6fd69
--- /dev/null
+++ b/drivers/ata/pata_acpi.c
@@ -0,0 +1,395 @@
1/*
2 * ACPI PATA driver
3 *
4 * (c) 2007 Red Hat <alan@redhat.com>
5 */
6
7#include <linux/kernel.h>
8#include <linux/module.h>
9#include <linux/pci.h>
10#include <linux/init.h>
11#include <linux/blkdev.h>
12#include <linux/delay.h>
13#include <linux/device.h>
14#include <scsi/scsi_host.h>
15#include <acpi/acpi_bus.h>
16#include <acpi/acnames.h>
17#include <acpi/acnamesp.h>
18#include <acpi/acparser.h>
19#include <acpi/acexcep.h>
20#include <acpi/acmacros.h>
21#include <acpi/actypes.h>
22
23#include <linux/libata.h>
24#include <linux/ata.h>
25
26#define DRV_NAME "pata_acpi"
27#define DRV_VERSION "0.2.3"
28
29struct pata_acpi {
30 struct ata_acpi_gtm gtm;
31 void *last;
32 unsigned long mask[2];
33};
34
35/**
36 * pacpi_pre_reset - check for 40/80 pin
37 * @ap: Port
38 * @deadline: deadline jiffies for the operation
39 *
40 * Perform the PATA port setup we need.
41 */
42
43static int pacpi_pre_reset(struct ata_link *link, unsigned long deadline)
44{
45 struct ata_port *ap = link->ap;
46 struct pata_acpi *acpi = ap->private_data;
47 if (ap->acpi_handle == NULL || ata_acpi_gtm(ap, &acpi->gtm) < 0)
48 return -ENODEV;
49
50 return ata_std_prereset(link, deadline);
51}
52
53/**
54 * pacpi_cable_detect - cable type detection
55 * @ap: port to detect
56 *
57 * Perform device specific cable detection
58 */
59
60static int pacpi_cable_detect(struct ata_port *ap)
61{
62 struct pata_acpi *acpi = ap->private_data;
63
64 if ((acpi->mask[0] | acpi->mask[1]) & (0xF8 << ATA_SHIFT_UDMA))
65 return ATA_CBL_PATA80;
66 else
67 return ATA_CBL_PATA40;
68}
69
70/**
71 * pacpi_error_handler - Setup and error handler
72 * @ap: Port to handle
73 *
74 * LOCKING:
75 * None (inherited from caller).
76 */
77
78static void pacpi_error_handler(struct ata_port *ap)
79{
80 return ata_bmdma_drive_eh(ap, pacpi_pre_reset, ata_std_softreset,
81 NULL, ata_std_postreset);
82}
83
84/* Welcome to ACPI, bring a bucket */
85static const unsigned int pio_cycle[7] = {
86 600, 383, 240, 180, 120, 100, 80
87};
88static const unsigned int mwdma_cycle[5] = {
89 480, 150, 120, 100, 80
90};
91static const unsigned int udma_cycle[7] = {
92 120, 80, 60, 45, 30, 20, 15
93};
94
95/**
96 * pacpi_discover_modes - filter non ACPI modes
97 * @adev: ATA device
98 * @mask: proposed modes
99 *
100 * Try the modes available and see which ones the ACPI method will
101 * set up sensibly. From this we get a mask of ACPI modes we can use
102 */
103
104static unsigned long pacpi_discover_modes(struct ata_port *ap, struct ata_device *adev)
105{
106 int unit = adev->devno;
107 struct pata_acpi *acpi = ap->private_data;
108 int i;
109 u32 t;
110 unsigned long mask = (0x7f << ATA_SHIFT_UDMA) | (0x7 << ATA_SHIFT_MWDMA) | (0x1F << ATA_SHIFT_PIO);
111
112 struct ata_acpi_gtm probe;
113
114 probe = acpi->gtm;
115
116 /* We always use the 0 slot for crap hardware */
117 if (!(probe.flags & 0x10))
118 unit = 0;
119
120 ata_acpi_gtm(ap, &probe);
121
122 /* Start by scanning for PIO modes */
123 for (i = 0; i < 7; i++) {
124 t = probe.drive[unit].pio;
125 if (t <= pio_cycle[i]) {
126 mask |= (2 << (ATA_SHIFT_PIO + i)) - 1;
127 break;
128 }
129 }
130
131 /* See if we have MWDMA or UDMA data. We don't bother with MWDMA
132 if UDMA is availabe as this means the BIOS set UDMA and our
133 error changedown if it works is UDMA to PIO anyway */
134 if (probe.flags & (1 << (2 * unit))) {
135 /* MWDMA */
136 for (i = 0; i < 5; i++) {
137 t = probe.drive[unit].dma;
138 if (t <= mwdma_cycle[i]) {
139 mask |= (2 << (ATA_SHIFT_MWDMA + i)) - 1;
140 break;
141 }
142 }
143 } else {
144 /* UDMA */
145 for (i = 0; i < 7; i++) {
146 t = probe.drive[unit].dma;
147 if (t <= udma_cycle[i]) {
148 mask |= (2 << (ATA_SHIFT_UDMA + i)) - 1;
149 break;
150 }
151 }
152 }
153 if (mask & (0xF8 << ATA_SHIFT_UDMA))
154 ap->cbl = ATA_CBL_PATA80;
155 return mask;
156}
157
158/**
159 * pacpi_mode_filter - mode filter for ACPI
160 * @adev: device
161 * @mask: mask of valid modes
162 *
163 * Filter the valid mode list according to our own specific rules, in
164 * this case the list of discovered valid modes obtained by ACPI probing
165 */
166
167static unsigned long pacpi_mode_filter(struct ata_device *adev, unsigned long mask)
168{
169 struct pata_acpi *acpi = adev->link->ap->private_data;
170 return ata_pci_default_filter(adev, mask & acpi->mask[adev->devno]);
171}
172
173/**
174 * pacpi_set_piomode - set initial PIO mode data
175 * @ap: ATA interface
176 * @adev: ATA device
177 */
178
179static void pacpi_set_piomode(struct ata_port *ap, struct ata_device *adev)
180{
181 int unit = adev->devno;
182 struct pata_acpi *acpi = ap->private_data;
183
184 if(!(acpi->gtm.flags & 0x10))
185 unit = 0;
186
187 /* Now stuff the nS values into the structure */
188 acpi->gtm.drive[unit].pio = pio_cycle[adev->pio_mode - XFER_PIO_0];
189 ata_acpi_stm(ap, &acpi->gtm);
190 /* See what mode we actually got */
191 ata_acpi_gtm(ap, &acpi->gtm);
192}
193
194/**
195 * pacpi_set_dmamode - set initial DMA mode data
196 * @ap: ATA interface
197 * @adev: ATA device
198 */
199
200static void pacpi_set_dmamode(struct ata_port *ap, struct ata_device *adev)
201{
202 int unit = adev->devno;
203 struct pata_acpi *acpi = ap->private_data;
204
205 if(!(acpi->gtm.flags & 0x10))
206 unit = 0;
207
208 /* Now stuff the nS values into the structure */
209 if (adev->dma_mode >= XFER_UDMA_0) {
210 acpi->gtm.drive[unit].dma = udma_cycle[adev->dma_mode - XFER_UDMA_0];
211 acpi->gtm.flags |= (1 << (2 * unit));
212 } else {
213 acpi->gtm.drive[unit].dma = mwdma_cycle[adev->dma_mode - XFER_MW_DMA_0];
214 acpi->gtm.flags &= ~(1 << (2 * unit));
215 }
216 ata_acpi_stm(ap, &acpi->gtm);
217 /* See what mode we actually got */
218 ata_acpi_gtm(ap, &acpi->gtm);
219}
220
221/**
222 * pacpi_qc_issue_prot - command issue
223 * @qc: command pending
224 *
225 * Called when the libata layer is about to issue a command. We wrap
226 * this interface so that we can load the correct ATA timings if
227 * neccessary.
228 */
229
230static unsigned int pacpi_qc_issue_prot(struct ata_queued_cmd *qc)
231{
232 struct ata_port *ap = qc->ap;
233 struct ata_device *adev = qc->dev;
234 struct pata_acpi *acpi = ap->private_data;
235
236 if (acpi->gtm.flags & 0x10)
237 return ata_qc_issue_prot(qc);
238
239 if (adev != acpi->last) {
240 pacpi_set_piomode(ap, adev);
241 if (adev->dma_mode)
242 pacpi_set_dmamode(ap, adev);
243 acpi->last = adev;
244 }
245 return ata_qc_issue_prot(qc);
246}
247
248/**
249 * pacpi_port_start - port setup
250 * @ap: ATA port being set up
251 *
252 * Use the port_start hook to maintain private control structures
253 */
254
255static int pacpi_port_start(struct ata_port *ap)
256{
257 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
258 struct pata_acpi *acpi;
259
260 int ret;
261
262 if (ap->acpi_handle == NULL)
263 return -ENODEV;
264
265 acpi = ap->private_data = devm_kzalloc(&pdev->dev, sizeof(struct pata_acpi), GFP_KERNEL);
266 if (ap->private_data == NULL)
267 return -ENOMEM;
268 acpi->mask[0] = pacpi_discover_modes(ap, &ap->link.device[0]);
269 acpi->mask[1] = pacpi_discover_modes(ap, &ap->link.device[1]);
270 ret = ata_sff_port_start(ap);
271 if (ret < 0)
272 return ret;
273
274 return ret;
275}
276
277static struct scsi_host_template pacpi_sht = {
278 .module = THIS_MODULE,
279 .name = DRV_NAME,
280 .ioctl = ata_scsi_ioctl,
281 .queuecommand = ata_scsi_queuecmd,
282 .can_queue = ATA_DEF_QUEUE,
283 .this_id = ATA_SHT_THIS_ID,
284 .sg_tablesize = LIBATA_MAX_PRD,
285 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
286 .emulated = ATA_SHT_EMULATED,
287 .use_clustering = ATA_SHT_USE_CLUSTERING,
288 .proc_name = DRV_NAME,
289 .dma_boundary = ATA_DMA_BOUNDARY,
290 .slave_configure = ata_scsi_slave_config,
291 .slave_destroy = ata_scsi_slave_destroy,
292 /* Use standard CHS mapping rules */
293 .bios_param = ata_std_bios_param,
294};
295
296static const struct ata_port_operations pacpi_ops = {
297 .set_piomode = pacpi_set_piomode,
298 .set_dmamode = pacpi_set_dmamode,
299 .mode_filter = pacpi_mode_filter,
300
301 /* Task file is PCI ATA format, use helpers */
302 .tf_load = ata_tf_load,
303 .tf_read = ata_tf_read,
304 .check_status = ata_check_status,
305 .exec_command = ata_exec_command,
306 .dev_select = ata_std_dev_select,
307
308 .freeze = ata_bmdma_freeze,
309 .thaw = ata_bmdma_thaw,
310 .error_handler = pacpi_error_handler,
311 .post_internal_cmd = ata_bmdma_post_internal_cmd,
312 .cable_detect = pacpi_cable_detect,
313
314 /* BMDMA handling is PCI ATA format, use helpers */
315 .bmdma_setup = ata_bmdma_setup,
316 .bmdma_start = ata_bmdma_start,
317 .bmdma_stop = ata_bmdma_stop,
318 .bmdma_status = ata_bmdma_status,
319 .qc_prep = ata_qc_prep,
320 .qc_issue = pacpi_qc_issue_prot,
321 .data_xfer = ata_data_xfer,
322
323 /* Timeout handling */
324 .irq_handler = ata_interrupt,
325 .irq_clear = ata_bmdma_irq_clear,
326 .irq_on = ata_irq_on,
327
328 /* Generic PATA PCI ATA helpers */
329 .port_start = pacpi_port_start,
330};
331
332
333/**
334 * pacpi_init_one - Register ACPI ATA PCI device with kernel services
335 * @pdev: PCI device to register
336 * @ent: Entry in pacpi_pci_tbl matching with @pdev
337 *
338 * Called from kernel PCI layer.
339 *
340 * LOCKING:
341 * Inherited from PCI layer (may sleep).
342 *
343 * RETURNS:
344 * Zero on success, or -ERRNO value.
345 */
346
347static int pacpi_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
348{
349 static const struct ata_port_info info = {
350 .sht = &pacpi_sht,
351 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
352
353 .pio_mask = 0x1f,
354 .mwdma_mask = 0x07,
355 .udma_mask = 0x7f,
356
357 .port_ops = &pacpi_ops,
358 };
359 const struct ata_port_info *ppi[] = { &info, NULL };
360 return ata_pci_init_one(pdev, ppi);
361}
362
363static const struct pci_device_id pacpi_pci_tbl[] = {
364 { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, 1},
365 { } /* terminate list */
366};
367
368static struct pci_driver pacpi_pci_driver = {
369 .name = DRV_NAME,
370 .id_table = pacpi_pci_tbl,
371 .probe = pacpi_init_one,
372 .remove = ata_pci_remove_one,
373 .suspend = ata_pci_device_suspend,
374 .resume = ata_pci_device_resume,
375};
376
377static int __init pacpi_init(void)
378{
379 return pci_register_driver(&pacpi_pci_driver);
380}
381
382static void __exit pacpi_exit(void)
383{
384 pci_unregister_driver(&pacpi_pci_driver);
385}
386
387module_init(pacpi_init);
388module_exit(pacpi_exit);
389
390MODULE_AUTHOR("Alan Cox");
391MODULE_DESCRIPTION("SCSI low-level driver for ATA in ACPI mode");
392MODULE_LICENSE("GPL");
393MODULE_DEVICE_TABLE(pci, pacpi_pci_tbl);
394MODULE_VERSION(DRV_VERSION);
395