aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-12-14 17:04:33 -0500
committerJeff Garzik <jeff@garzik.org>2006-12-16 10:12:50 -0500
commitc10340aca270abb141154cd93dcf1be0b92143fc (patch)
treed16a979ce840cd9cde1421a0ee98c14409d019e1
parentda02d2a16ef3accd625f9e6e7bf83bb0f946ff62 (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.c41
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
58enum { 58enum {
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
93static 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
88static u8 k2_stat_check_status(struct ata_port *ap); 104static u8 k2_stat_check_status(struct ata_port *ap);
89 105
90 106
107static 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
91static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) 115static 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 * */
471static const struct pci_device_id k2_sata_pci_tbl[] = { 498static 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};