Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=55a61604cd1354e1783364e1c901034f2f474b7d
Commit:     55a61604cd1354e1783364e1c901034f2f474b7d
Parent:     d7d0dad62a641c156386288a747c1a2f6bb2e42d
Author:     Conke Hu <[EMAIL PROTECTED]>
AuthorDate: Tue Mar 27 18:33:05 2007 +0800
Committer:  Jeff Garzik <[EMAIL PROTECTED]>
CommitDate: Wed Mar 28 02:04:27 2007 -0400

    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 <[EMAIL PROTECTED]>
    Signed-off-by: Jeff Garzik <[EMAIL PROTECTED]>
---
 drivers/ata/ahci.c |   21 +++++++++++++++++++--
 1 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index dc7b562..fd27227 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -80,6 +80,7 @@ enum {
        board_ahci_pi           = 1,
        board_ahci_vt8251       = 2,
        board_ahci_ign_iferr    = 3,
+       board_ahci_sb600        = 4,
 
        /* global controller registers */
        HOST_CAP                = 0x00, /* host capabilities */
@@ -168,6 +169,7 @@ enum {
        AHCI_FLAG_NO_NCQ                = (1 << 24),
        AHCI_FLAG_IGN_IRQ_IF_ERR        = (1 << 25), /* ignore IRQ_IF_ERR */
        AHCI_FLAG_HONOR_PI              = (1 << 26), /* honor PORTS_IMPL */
+       AHCI_FLAG_IGN_SERR_INTERNAL     = (1 << 27), /* ignore SERR_INTERNAL */
 };
 
 struct ahci_cmd_hdr {
@@ -362,6 +364,18 @@ static const struct ata_port_info ahci_port_info[] = {
                .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
                .port_ops       = &ahci_ops,
        },
+       /* board_ahci_sb600 */
+       {
+               .sht            = &ahci_sht,
+               .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                                 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
+                                 ATA_FLAG_SKIP_D2H_BSY |
+                                 AHCI_FLAG_IGN_SERR_INTERNAL,
+               .pio_mask       = 0x1f, /* pio0-4 */
+               .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
+               .port_ops       = &ahci_ops,
+       },
+
 };
 
 static const struct pci_device_id ahci_pci_tbl[] = {
@@ -399,7 +413,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
          PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr },
 
        /* ATI */
-       { PCI_VDEVICE(ATI, 0x4380), board_ahci }, /* ATI SB600 non-raid */
+       { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 non-raid */
        { PCI_VDEVICE(ATI, 0x4381), board_ahci }, /* ATI SB600 raid */
 
        /* VIA */
@@ -1067,8 +1081,11 @@ static void ahci_error_intr(struct ata_port *ap, u32 
irq_stat)
        if (ap->flags & AHCI_FLAG_IGN_IRQ_IF_ERR)
                irq_stat &= ~PORT_IRQ_IF_ERR;
 
-       if (irq_stat & PORT_IRQ_TF_ERR)
+       if (irq_stat & PORT_IRQ_TF_ERR) {
                err_mask |= AC_ERR_DEV;
+               if (ap->flags & AHCI_FLAG_IGN_SERR_INTERNAL)
+                       serror &= ~SERR_INTERNAL;
+       }
 
        if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) {
                err_mask |= AC_ERR_HOST_BUS;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to