V4L/DVB (6453): wm8739: convert to bus-based I2C API
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / ata / pata_acpi.c
blobe4542ab9c7f840fcf59102c8e92bb6422f79ff48
1 /*
2 * ACPI PATA driver
4 * (c) 2007 Red Hat <alan@redhat.com>
5 */
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>
23 #include <linux/libata.h>
24 #include <linux/ata.h>
26 #define DRV_NAME "pata_acpi"
27 #define DRV_VERSION "0.2.3"
29 struct pata_acpi {
30 struct ata_acpi_gtm gtm;
31 void *last;
32 unsigned long mask[2];
35 /**
36 * pacpi_pre_reset - check for 40/80 pin
37 * @ap: Port
38 * @deadline: deadline jiffies for the operation
40 * Perform the PATA port setup we need.
43 static int pacpi_pre_reset(struct ata_link *link, unsigned long deadline)
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;
50 return ata_std_prereset(link, deadline);
53 /**
54 * pacpi_cable_detect - cable type detection
55 * @ap: port to detect
57 * Perform device specific cable detection
60 static int pacpi_cable_detect(struct ata_port *ap)
62 struct pata_acpi *acpi = ap->private_data;
64 if ((acpi->mask[0] | acpi->mask[1]) & (0xF8 << ATA_SHIFT_UDMA))
65 return ATA_CBL_PATA80;
66 else
67 return ATA_CBL_PATA40;
70 /**
71 * pacpi_error_handler - Setup and error handler
72 * @ap: Port to handle
74 * LOCKING:
75 * None (inherited from caller).
78 static void pacpi_error_handler(struct ata_port *ap)
80 return ata_bmdma_drive_eh(ap, pacpi_pre_reset, ata_std_softreset,
81 NULL, ata_std_postreset);
84 /* Welcome to ACPI, bring a bucket */
85 static const unsigned int pio_cycle[7] = {
86 600, 383, 240, 180, 120, 100, 80
88 static const unsigned int mwdma_cycle[5] = {
89 480, 150, 120, 100, 80
91 static const unsigned int udma_cycle[7] = {
92 120, 80, 60, 45, 30, 20, 15
95 /**
96 * pacpi_discover_modes - filter non ACPI modes
97 * @adev: ATA device
98 * @mask: proposed modes
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
104 static unsigned long pacpi_discover_modes(struct ata_port *ap, struct ata_device *adev)
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);
112 struct ata_acpi_gtm probe;
114 probe = acpi->gtm;
116 /* We always use the 0 slot for crap hardware */
117 if (!(probe.flags & 0x10))
118 unit = 0;
120 ata_acpi_gtm(ap, &probe);
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;
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;
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;
153 if (mask & (0xF8 << ATA_SHIFT_UDMA))
154 ap->cbl = ATA_CBL_PATA80;
155 return mask;
159 * pacpi_mode_filter - mode filter for ACPI
160 * @adev: device
161 * @mask: mask of valid modes
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
167 static unsigned long pacpi_mode_filter(struct ata_device *adev, unsigned long mask)
169 struct pata_acpi *acpi = adev->link->ap->private_data;
170 return ata_pci_default_filter(adev, mask & acpi->mask[adev->devno]);
174 * pacpi_set_piomode - set initial PIO mode data
175 * @ap: ATA interface
176 * @adev: ATA device
179 static void pacpi_set_piomode(struct ata_port *ap, struct ata_device *adev)
181 int unit = adev->devno;
182 struct pata_acpi *acpi = ap->private_data;
184 if (!(acpi->gtm.flags & 0x10))
185 unit = 0;
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);
195 * pacpi_set_dmamode - set initial DMA mode data
196 * @ap: ATA interface
197 * @adev: ATA device
200 static void pacpi_set_dmamode(struct ata_port *ap, struct ata_device *adev)
202 int unit = adev->devno;
203 struct pata_acpi *acpi = ap->private_data;
205 if (!(acpi->gtm.flags & 0x10))
206 unit = 0;
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));
216 ata_acpi_stm(ap, &acpi->gtm);
217 /* See what mode we actually got */
218 ata_acpi_gtm(ap, &acpi->gtm);
222 * pacpi_qc_issue_prot - command issue
223 * @qc: command pending
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.
230 static unsigned int pacpi_qc_issue_prot(struct ata_queued_cmd *qc)
232 struct ata_port *ap = qc->ap;
233 struct ata_device *adev = qc->dev;
234 struct pata_acpi *acpi = ap->private_data;
236 if (acpi->gtm.flags & 0x10)
237 return ata_qc_issue_prot(qc);
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;
245 return ata_qc_issue_prot(qc);
249 * pacpi_port_start - port setup
250 * @ap: ATA port being set up
252 * Use the port_start hook to maintain private control structures
255 static int pacpi_port_start(struct ata_port *ap)
257 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
258 struct pata_acpi *acpi;
260 int ret;
262 if (ap->acpi_handle == NULL)
263 return -ENODEV;
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;
274 return ret;
277 static 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,
296 static 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,
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,
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,
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,
323 /* Timeout handling */
324 .irq_handler = ata_interrupt,
325 .irq_clear = ata_bmdma_irq_clear,
326 .irq_on = ata_irq_on,
328 /* Generic PATA PCI ATA helpers */
329 .port_start = pacpi_port_start,
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
338 * Called from kernel PCI layer.
340 * LOCKING:
341 * Inherited from PCI layer (may sleep).
343 * RETURNS:
344 * Zero on success, or -ERRNO value.
347 static int pacpi_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
349 static const struct ata_port_info info = {
350 .sht = &pacpi_sht,
351 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
353 .pio_mask = 0x1f,
354 .mwdma_mask = 0x07,
355 .udma_mask = 0x7f,
357 .port_ops = &pacpi_ops,
359 const struct ata_port_info *ppi[] = { &info, NULL };
360 return ata_pci_init_one(pdev, ppi);
363 static 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 */
368 static 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 #ifdef CONFIG_PM
374 .suspend = ata_pci_device_suspend,
375 .resume = ata_pci_device_resume,
376 #endif
379 static int __init pacpi_init(void)
381 return pci_register_driver(&pacpi_pci_driver);
384 static void __exit pacpi_exit(void)
386 pci_unregister_driver(&pacpi_pci_driver);
389 module_init(pacpi_init);
390 module_exit(pacpi_exit);
392 MODULE_AUTHOR("Alan Cox");
393 MODULE_DESCRIPTION("SCSI low-level driver for ATA in ACPI mode");
394 MODULE_LICENSE("GPL");
395 MODULE_DEVICE_TABLE(pci, pacpi_pci_tbl);
396 MODULE_VERSION(DRV_VERSION);