diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-12-14 17:04:33 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-12-16 10:12:50 -0500 |
commit | c10340aca270abb141154cd93dcf1be0b92143fc (patch) | |
tree | d16a979ce840cd9cde1421a0ee98c14409d019e1 | |
parent | da02d2a16ef3accd625f9e6e7bf83bb0f946ff62 (diff) |
[libata] sata_svw: Disable ATAPI DMA on current boards (errata workaround)
Current Broadcom/Serverworks SATA boards (including Apple K2 SATA)
have problems with ATAPI DMA, so it is disabled. ATAPI PIO, ATA PIO,
and ATA DMA continue to work just fine.
Acked-by: Anantha Subramanyam <ananth@broadcom.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | drivers/ata/sata_svw.c | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index db32d15b7fa1..d89c9590b845 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c | |||
@@ -56,6 +56,8 @@ | |||
56 | #define DRV_VERSION "2.0" | 56 | #define DRV_VERSION "2.0" |
57 | 57 | ||
58 | enum { | 58 | enum { |
59 | K2_FLAG_NO_ATAPI_DMA = (1 << 29), | ||
60 | |||
59 | /* Taskfile registers offsets */ | 61 | /* Taskfile registers offsets */ |
60 | K2_SATA_TF_CMD_OFFSET = 0x00, | 62 | K2_SATA_TF_CMD_OFFSET = 0x00, |
61 | K2_SATA_TF_DATA_OFFSET = 0x00, | 63 | K2_SATA_TF_DATA_OFFSET = 0x00, |
@@ -83,11 +85,33 @@ enum { | |||
83 | 85 | ||
84 | /* Port stride */ | 86 | /* Port stride */ |
85 | K2_SATA_PORT_OFFSET = 0x100, | 87 | K2_SATA_PORT_OFFSET = 0x100, |
88 | |||
89 | board_svw4 = 0, | ||
90 | board_svw8 = 1, | ||
91 | }; | ||
92 | |||
93 | static const struct k2_board_info { | ||
94 | unsigned int n_ports; | ||
95 | unsigned long port_flags; | ||
96 | } k2_board_info[] = { | ||
97 | /* board_svw4 */ | ||
98 | { 4, K2_FLAG_NO_ATAPI_DMA }, | ||
99 | |||
100 | /* board_svw8 */ | ||
101 | { 8, K2_FLAG_NO_ATAPI_DMA }, | ||
86 | }; | 102 | }; |
87 | 103 | ||
88 | static u8 k2_stat_check_status(struct ata_port *ap); | 104 | static u8 k2_stat_check_status(struct ata_port *ap); |
89 | 105 | ||
90 | 106 | ||
107 | static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc) | ||
108 | { | ||
109 | if (qc->ap->flags & K2_FLAG_NO_ATAPI_DMA) | ||
110 | return -1; /* ATAPI DMA not supported */ | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | |||
91 | static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) | 115 | static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) |
92 | { | 116 | { |
93 | if (sc_reg > SCR_CONTROL) | 117 | if (sc_reg > SCR_CONTROL) |
@@ -313,6 +337,7 @@ static const struct ata_port_operations k2_sata_ops = { | |||
313 | .check_status = k2_stat_check_status, | 337 | .check_status = k2_stat_check_status, |
314 | .exec_command = ata_exec_command, | 338 | .exec_command = ata_exec_command, |
315 | .dev_select = ata_std_dev_select, | 339 | .dev_select = ata_std_dev_select, |
340 | .check_atapi_dma = k2_sata_check_atapi_dma, | ||
316 | .bmdma_setup = k2_bmdma_setup_mmio, | 341 | .bmdma_setup = k2_bmdma_setup_mmio, |
317 | .bmdma_start = k2_bmdma_start_mmio, | 342 | .bmdma_start = k2_bmdma_start_mmio, |
318 | .bmdma_stop = ata_bmdma_stop, | 343 | .bmdma_stop = ata_bmdma_stop, |
@@ -359,6 +384,8 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
359 | struct ata_probe_ent *probe_ent = NULL; | 384 | struct ata_probe_ent *probe_ent = NULL; |
360 | unsigned long base; | 385 | unsigned long base; |
361 | void __iomem *mmio_base; | 386 | void __iomem *mmio_base; |
387 | const struct k2_board_info *board_info = | ||
388 | &k2_board_info[ent->driver_data]; | ||
362 | int pci_dev_busy = 0; | 389 | int pci_dev_busy = 0; |
363 | int rc; | 390 | int rc; |
364 | int i; | 391 | int i; |
@@ -424,7 +451,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
424 | 451 | ||
425 | probe_ent->sht = &k2_sata_sht; | 452 | probe_ent->sht = &k2_sata_sht; |
426 | probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 453 | probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
427 | ATA_FLAG_MMIO; | 454 | ATA_FLAG_MMIO | board_info->port_flags; |
428 | probe_ent->port_ops = &k2_sata_ops; | 455 | probe_ent->port_ops = &k2_sata_ops; |
429 | probe_ent->n_ports = 4; | 456 | probe_ent->n_ports = 4; |
430 | probe_ent->irq = pdev->irq; | 457 | probe_ent->irq = pdev->irq; |
@@ -441,7 +468,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
441 | /* different controllers have different number of ports - currently 4 or 8 */ | 468 | /* different controllers have different number of ports - currently 4 or 8 */ |
442 | /* All ports are on the same function. Multi-function device is no | 469 | /* All ports are on the same function. Multi-function device is no |
443 | * longer available. This should not be seen in any system. */ | 470 | * longer available. This should not be seen in any system. */ |
444 | for (i = 0; i < ent->driver_data; i++) | 471 | for (i = 0; i < board_info->n_ports; i++) |
445 | k2_sata_setup_port(&probe_ent->port[i], base + i * K2_SATA_PORT_OFFSET); | 472 | k2_sata_setup_port(&probe_ent->port[i], base + i * K2_SATA_PORT_OFFSET); |
446 | 473 | ||
447 | pci_set_master(pdev); | 474 | pci_set_master(pdev); |
@@ -469,11 +496,11 @@ err_out: | |||
469 | * controller | 496 | * controller |
470 | * */ | 497 | * */ |
471 | static const struct pci_device_id k2_sata_pci_tbl[] = { | 498 | static const struct pci_device_id k2_sata_pci_tbl[] = { |
472 | { PCI_VDEVICE(SERVERWORKS, 0x0240), 4 }, | 499 | { PCI_VDEVICE(SERVERWORKS, 0x0240), board_svw4 }, |
473 | { PCI_VDEVICE(SERVERWORKS, 0x0241), 4 }, | 500 | { PCI_VDEVICE(SERVERWORKS, 0x0241), board_svw4 }, |
474 | { PCI_VDEVICE(SERVERWORKS, 0x0242), 8 }, | 501 | { PCI_VDEVICE(SERVERWORKS, 0x0242), board_svw8 }, |
475 | { PCI_VDEVICE(SERVERWORKS, 0x024a), 4 }, | 502 | { PCI_VDEVICE(SERVERWORKS, 0x024a), board_svw4 }, |
476 | { PCI_VDEVICE(SERVERWORKS, 0x024b), 4 }, | 503 | { PCI_VDEVICE(SERVERWORKS, 0x024b), board_svw4 }, |
477 | 504 | ||
478 | { } | 505 | { } |
479 | }; | 506 | }; |