aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/pata_cmd64x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/pata_cmd64x.c')
-rw-r--r--drivers/ata/pata_cmd64x.c73
1 files changed, 56 insertions, 17 deletions
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index 028638c7c1d..f0dcb7056b1 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
239static 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
274static struct ata_port_operations cmd64x_port_ops = { 297static 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
309static 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
285static struct ata_port_operations cmd648_port_ops = { 315static 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
307static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) 337static 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)
429static const struct pci_device_id cmd64x[] = { 468static 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};