aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorConke Hu <conke.hu@gmail.com>2007-03-27 06:33:05 -0400
committerJeff Garzik <jeff@garzik.org>2007-03-28 02:04:27 -0400
commit55a61604cd1354e1783364e1c901034f2f474b7d (patch)
tree28c9a083fa426403f8a6fe852543ce04a6482618 /drivers
parentd7d0dad62a641c156386288a747c1a2f6bb2e42d (diff)
ahci.c: walkaround for SB600 SATA internal error issue
There is a HW issue in ATI SB600 SATA that PxSERR.E should not be set on some conditions, for example, when there is no media in SATA CD/DVD drive or media is not ready, AHCI controller fails to execute ATAPI commands and reports PORT_IRQ_TF_ERR, but ATI SB600 SATA controller sets PxSERR.E at the same time, which is not necessary. This patch is just to ignore the INTERNAL ERROR in such case. Without this patch, ahci error handler will report many errors as below: ----------- cut from dmesg ----------- ata9: soft resetting port ata9: SATA link up 1.5 Gbps (SStatus 113 SControl 300) ata9.00: configured for UDMA/33 ata9: EH complete ata9.00: exception Emask 0x40 SAct 0x0 SErr 0x800 action 0x2 ata9.00: (irq_stat 0x40000001) ata9.00: cmd a0/00:00:00:00:20/00:00:00:00:00/a0 tag 0 cdb 0x0 data 0 res 51/24:03:00:00:20/00:00:00:00:00/a0 Emask 0x40 (internal error) ata9: soft resetting port ata9: SATA link up 1.5 Gbps (SStatus 113 SControl 300) ata9.00: configured for UDMA/33 ata9: EH complete ata9.00: exception Emask 0x40 SAct 0x0 SErr 0x800 action 0x2 ata9.00: (irq_stat 0x40000001) ata9.00: cmd a0/01:00:00:00:00/00:00:00:00:00/a0 tag 0 cdb 0x43 data 12 in res 51/24:03:00:00:00/00:00:00:00:00/a0 Emask 0x40 (internal error) -------- end cut --------- Signed-off-by: Conke Hu <conke.hu@amd.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/ahci.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index dc7b56225923..fd27227771b4 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -80,6 +80,7 @@ enum {
80 board_ahci_pi = 1, 80 board_ahci_pi = 1,
81 board_ahci_vt8251 = 2, 81 board_ahci_vt8251 = 2,
82 board_ahci_ign_iferr = 3, 82 board_ahci_ign_iferr = 3,
83 board_ahci_sb600 = 4,
83 84
84 /* global controller registers */ 85 /* global controller registers */
85 HOST_CAP = 0x00, /* host capabilities */ 86 HOST_CAP = 0x00, /* host capabilities */
@@ -168,6 +169,7 @@ enum {
168 AHCI_FLAG_NO_NCQ = (1 << 24), 169 AHCI_FLAG_NO_NCQ = (1 << 24),
169 AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 25), /* ignore IRQ_IF_ERR */ 170 AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 25), /* ignore IRQ_IF_ERR */
170 AHCI_FLAG_HONOR_PI = (1 << 26), /* honor PORTS_IMPL */ 171 AHCI_FLAG_HONOR_PI = (1 << 26), /* honor PORTS_IMPL */
172 AHCI_FLAG_IGN_SERR_INTERNAL = (1 << 27), /* ignore SERR_INTERNAL */
171}; 173};
172 174
173struct ahci_cmd_hdr { 175struct ahci_cmd_hdr {
@@ -362,6 +364,18 @@ static const struct ata_port_info ahci_port_info[] = {
362 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 364 .udma_mask = 0x7f, /* udma0-6 ; FIXME */
363 .port_ops = &ahci_ops, 365 .port_ops = &ahci_ops,
364 }, 366 },
367 /* board_ahci_sb600 */
368 {
369 .sht = &ahci_sht,
370 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
371 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
372 ATA_FLAG_SKIP_D2H_BSY |
373 AHCI_FLAG_IGN_SERR_INTERNAL,
374 .pio_mask = 0x1f, /* pio0-4 */
375 .udma_mask = 0x7f, /* udma0-6 ; FIXME */
376 .port_ops = &ahci_ops,
377 },
378
365}; 379};
366 380
367static const struct pci_device_id ahci_pci_tbl[] = { 381static const struct pci_device_id ahci_pci_tbl[] = {
@@ -399,7 +413,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
399 PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr }, 413 PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr },
400 414
401 /* ATI */ 415 /* ATI */
402 { PCI_VDEVICE(ATI, 0x4380), board_ahci }, /* ATI SB600 non-raid */ 416 { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 non-raid */
403 { PCI_VDEVICE(ATI, 0x4381), board_ahci }, /* ATI SB600 raid */ 417 { PCI_VDEVICE(ATI, 0x4381), board_ahci }, /* ATI SB600 raid */
404 418
405 /* VIA */ 419 /* VIA */
@@ -1067,8 +1081,11 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
1067 if (ap->flags & AHCI_FLAG_IGN_IRQ_IF_ERR) 1081 if (ap->flags & AHCI_FLAG_IGN_IRQ_IF_ERR)
1068 irq_stat &= ~PORT_IRQ_IF_ERR; 1082 irq_stat &= ~PORT_IRQ_IF_ERR;
1069 1083
1070 if (irq_stat & PORT_IRQ_TF_ERR) 1084 if (irq_stat & PORT_IRQ_TF_ERR) {
1071 err_mask |= AC_ERR_DEV; 1085 err_mask |= AC_ERR_DEV;
1086 if (ap->flags & AHCI_FLAG_IGN_SERR_INTERNAL)
1087 serror &= ~SERR_INTERNAL;
1088 }
1072 1089
1073 if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) { 1090 if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) {
1074 err_mask |= AC_ERR_HOST_BUS; 1091 err_mask |= AC_ERR_HOST_BUS;