diff options
-rw-r--r-- | drivers/ata/pata_cmd64x.c | 73 |
1 files changed, 56 insertions, 17 deletions
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 028638c7c1d9..f0dcb7056b19 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * (C) 2005 Red Hat Inc | 3 | * (C) 2005 Red Hat Inc |
4 | * Alan Cox <alan@lxorguk.ukuu.org.uk> | 4 | * Alan Cox <alan@lxorguk.ukuu.org.uk> |
5 | * (C) 2009-2010 Bartlomiej Zolnierkiewicz | 5 | * (C) 2009-2010 Bartlomiej Zolnierkiewicz |
6 | * (C) 2012 MontaVista Software, LLC <source@mvista.com> | ||
6 | * | 7 | * |
7 | * Based upon | 8 | * Based upon |
8 | * linux/drivers/ide/pci/cmd64x.c Version 1.30 Sept 10, 2002 | 9 | * linux/drivers/ide/pci/cmd64x.c Version 1.30 Sept 10, 2002 |
@@ -32,7 +33,7 @@ | |||
32 | #include <linux/libata.h> | 33 | #include <linux/libata.h> |
33 | 34 | ||
34 | #define DRV_NAME "pata_cmd64x" | 35 | #define DRV_NAME "pata_cmd64x" |
35 | #define DRV_VERSION "0.2.15" | 36 | #define DRV_VERSION "0.2.16" |
36 | 37 | ||
37 | /* | 38 | /* |
38 | * CMD64x specific registers definition. | 39 | * CMD64x specific registers definition. |
@@ -229,7 +230,27 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
229 | } | 230 | } |
230 | 231 | ||
231 | /** | 232 | /** |
232 | * cmd648_dma_stop - DMA stop callback | 233 | * cmd64x_bmdma_stop - DMA stop callback |
234 | * @qc: Command in progress | ||
235 | * | ||
236 | * DMA has completed. | ||
237 | */ | ||
238 | |||
239 | static void cmd64x_bmdma_stop(struct ata_queued_cmd *qc) | ||
240 | { | ||
241 | struct ata_port *ap = qc->ap; | ||
242 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | ||
243 | int irq_reg = ap->port_no ? ARTTIM23 : CFR; | ||
244 | u8 irq_stat; | ||
245 | |||
246 | ata_bmdma_stop(qc); | ||
247 | |||
248 | /* Reading the register should be enough to clear the interrupt */ | ||
249 | pci_read_config_byte(pdev, irq_reg, &irq_stat); | ||
250 | } | ||
251 | |||
252 | /** | ||
253 | * cmd648_bmdma_stop - DMA stop callback | ||
233 | * @qc: Command in progress | 254 | * @qc: Command in progress |
234 | * | 255 | * |
235 | * DMA has completed. | 256 | * DMA has completed. |
@@ -239,18 +260,20 @@ static void cmd648_bmdma_stop(struct ata_queued_cmd *qc) | |||
239 | { | 260 | { |
240 | struct ata_port *ap = qc->ap; | 261 | struct ata_port *ap = qc->ap; |
241 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 262 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
242 | u8 dma_intr; | 263 | unsigned long base = pci_resource_start(pdev, 4); |
243 | int dma_mask = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; | 264 | int irq_mask = ap->port_no ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0; |
244 | int dma_reg = ap->port_no ? ARTTIM23 : CFR; | 265 | u8 mrdmode; |
245 | 266 | ||
246 | ata_bmdma_stop(qc); | 267 | ata_bmdma_stop(qc); |
247 | 268 | ||
248 | pci_read_config_byte(pdev, dma_reg, &dma_intr); | 269 | /* Clear this port's interrupt bit (leaving the other port alone) */ |
249 | pci_write_config_byte(pdev, dma_reg, dma_intr | dma_mask); | 270 | mrdmode = inb(base + 1); |
271 | mrdmode &= ~(MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1); | ||
272 | outb(mrdmode | irq_mask, base + 1); | ||
250 | } | 273 | } |
251 | 274 | ||
252 | /** | 275 | /** |
253 | * cmd646r1_dma_stop - DMA stop callback | 276 | * cmd646r1_bmdma_stop - DMA stop callback |
254 | * @qc: Command in progress | 277 | * @qc: Command in progress |
255 | * | 278 | * |
256 | * Stub for now while investigating the r1 quirk in the old driver. | 279 | * Stub for now while investigating the r1 quirk in the old driver. |
@@ -273,6 +296,7 @@ static const struct ata_port_operations cmd64x_base_ops = { | |||
273 | 296 | ||
274 | static struct ata_port_operations cmd64x_port_ops = { | 297 | static struct ata_port_operations cmd64x_port_ops = { |
275 | .inherits = &cmd64x_base_ops, | 298 | .inherits = &cmd64x_base_ops, |
299 | .bmdma_stop = cmd64x_bmdma_stop, | ||
276 | .cable_detect = ata_cable_40wire, | 300 | .cable_detect = ata_cable_40wire, |
277 | }; | 301 | }; |
278 | 302 | ||
@@ -282,6 +306,12 @@ static struct ata_port_operations cmd646r1_port_ops = { | |||
282 | .cable_detect = ata_cable_40wire, | 306 | .cable_detect = ata_cable_40wire, |
283 | }; | 307 | }; |
284 | 308 | ||
309 | static struct ata_port_operations cmd646r3_port_ops = { | ||
310 | .inherits = &cmd64x_base_ops, | ||
311 | .bmdma_stop = cmd648_bmdma_stop, | ||
312 | .cable_detect = ata_cable_40wire, | ||
313 | }; | ||
314 | |||
285 | static struct ata_port_operations cmd648_port_ops = { | 315 | static struct ata_port_operations cmd648_port_ops = { |
286 | .inherits = &cmd64x_base_ops, | 316 | .inherits = &cmd64x_base_ops, |
287 | .bmdma_stop = cmd648_bmdma_stop, | 317 | .bmdma_stop = cmd648_bmdma_stop, |
@@ -306,7 +336,7 @@ static void cmd64x_fixup(struct pci_dev *pdev) | |||
306 | 336 | ||
307 | static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | 337 | static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) |
308 | { | 338 | { |
309 | static const struct ata_port_info cmd_info[6] = { | 339 | static const struct ata_port_info cmd_info[7] = { |
310 | { /* CMD 643 - no UDMA */ | 340 | { /* CMD 643 - no UDMA */ |
311 | .flags = ATA_FLAG_SLAVE_POSS, | 341 | .flags = ATA_FLAG_SLAVE_POSS, |
312 | .pio_mask = ATA_PIO4, | 342 | .pio_mask = ATA_PIO4, |
@@ -319,12 +349,18 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
319 | .mwdma_mask = ATA_MWDMA2, | 349 | .mwdma_mask = ATA_MWDMA2, |
320 | .port_ops = &cmd64x_port_ops | 350 | .port_ops = &cmd64x_port_ops |
321 | }, | 351 | }, |
322 | { /* CMD 646 with working UDMA */ | 352 | { /* CMD 646U with broken UDMA */ |
353 | .flags = ATA_FLAG_SLAVE_POSS, | ||
354 | .pio_mask = ATA_PIO4, | ||
355 | .mwdma_mask = ATA_MWDMA2, | ||
356 | .port_ops = &cmd646r3_port_ops | ||
357 | }, | ||
358 | { /* CMD 646U2 with working UDMA */ | ||
323 | .flags = ATA_FLAG_SLAVE_POSS, | 359 | .flags = ATA_FLAG_SLAVE_POSS, |
324 | .pio_mask = ATA_PIO4, | 360 | .pio_mask = ATA_PIO4, |
325 | .mwdma_mask = ATA_MWDMA2, | 361 | .mwdma_mask = ATA_MWDMA2, |
326 | .udma_mask = ATA_UDMA2, | 362 | .udma_mask = ATA_UDMA2, |
327 | .port_ops = &cmd64x_port_ops | 363 | .port_ops = &cmd646r3_port_ops |
328 | }, | 364 | }, |
329 | { /* CMD 646 rev 1 */ | 365 | { /* CMD 646 rev 1 */ |
330 | .flags = ATA_FLAG_SLAVE_POSS, | 366 | .flags = ATA_FLAG_SLAVE_POSS, |
@@ -372,16 +408,19 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
372 | switch (pdev->revision) { | 408 | switch (pdev->revision) { |
373 | /* UDMA works since rev 5 */ | 409 | /* UDMA works since rev 5 */ |
374 | default: | 410 | default: |
375 | ppi[0] = &cmd_info[2]; | 411 | ppi[0] = &cmd_info[3]; |
376 | ppi[1] = &cmd_info[2]; | 412 | ppi[1] = &cmd_info[3]; |
377 | break; | 413 | break; |
414 | /* Interrupts in MRDMODE since rev 3 */ | ||
378 | case 3: | 415 | case 3: |
379 | case 4: | 416 | case 4: |
417 | ppi[0] = &cmd_info[2]; | ||
418 | ppi[1] = &cmd_info[2]; | ||
380 | break; | 419 | break; |
381 | /* Rev 1 with other problems? */ | 420 | /* Rev 1 with other problems? */ |
382 | case 1: | 421 | case 1: |
383 | ppi[0] = &cmd_info[3]; | 422 | ppi[0] = &cmd_info[4]; |
384 | ppi[1] = &cmd_info[3]; | 423 | ppi[1] = &cmd_info[4]; |
385 | /* FALL THRU */ | 424 | /* FALL THRU */ |
386 | /* Early revs have no CNTRL_CH0 */ | 425 | /* Early revs have no CNTRL_CH0 */ |
387 | case 2: | 426 | case 2: |
@@ -429,8 +468,8 @@ static int cmd64x_reinit_one(struct pci_dev *pdev) | |||
429 | static const struct pci_device_id cmd64x[] = { | 468 | static const struct pci_device_id cmd64x[] = { |
430 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_643), 0 }, | 469 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_643), 0 }, |
431 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_646), 1 }, | 470 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_646), 1 }, |
432 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_648), 4 }, | 471 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_648), 5 }, |
433 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_649), 5 }, | 472 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_649), 6 }, |
434 | 473 | ||
435 | { }, | 474 | { }, |
436 | }; | 475 | }; |