libata: apply behavioral quirks to sil3826 PMP
[pandora-kernel.git] / drivers / ata / libata-pmp.c
index 21b80c5..f5c35be 100644 (file)
@@ -289,24 +289,24 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info)
 
        /* Disable sending Early R_OK.
         * With "cached read" HDD testing and multiple ports busy on a SATA
-        * host controller, 3726 PMP will very rarely drop a deferred
+        * host controller, 3x26 PMP will very rarely drop a deferred
         * R_OK that was intended for the host. Symptom will be all
         * 5 drives under test will timeout, get reset, and recover.
         */
-       if (vendor == 0x1095 && devid == 0x3726) {
+       if (vendor == 0x1095 && (devid == 0x3726 || devid == 0x3826)) {
                u32 reg;
 
                err_mask = sata_pmp_read(&ap->link, PMP_GSCR_SII_POL, &reg);
                if (err_mask) {
                        rc = -EIO;
-                       reason = "failed to read Sil3726 Private Register";
+                       reason = "failed to read Sil3x26 Private Register";
                        goto fail;
                }
                reg &= ~0x1;
                err_mask = sata_pmp_write(&ap->link, PMP_GSCR_SII_POL, reg);
                if (err_mask) {
                        rc = -EIO;
-                       reason = "failed to write Sil3726 Private Register";
+                       reason = "failed to write Sil3x26 Private Register";
                        goto fail;
                }
        }
@@ -383,15 +383,19 @@ static void sata_pmp_quirks(struct ata_port *ap)
        u16 devid = sata_pmp_gscr_devid(gscr);
        struct ata_link *link;
 
-       if (vendor == 0x1095 && devid == 0x3726) {
-               /* sil3726 quirks */
+       if (vendor == 0x1095 && (devid == 0x3726 || devid == 0x3826)) {
+               /* sil3x26 quirks */
                ata_for_each_link(link, ap, EDGE) {
                        /* link reports offline after LPM */
                        link->flags |= ATA_LFLAG_NO_LPM;
 
-                       /* Class code report is unreliable. */
+                       /*
+                        * Class code report is unreliable and SRST times
+                        * out under certain configurations.
+                        */
                        if (link->pmp < 5)
-                               link->flags |= ATA_LFLAG_ASSUME_ATA;
+                               link->flags |= ATA_LFLAG_NO_SRST |
+                                              ATA_LFLAG_ASSUME_ATA;
 
                        /* port 5 is for SEMB device and it doesn't like SRST */
                        if (link->pmp == 5)
@@ -399,20 +403,17 @@ static void sata_pmp_quirks(struct ata_port *ap)
                                               ATA_LFLAG_ASSUME_SEMB;
                }
        } else if (vendor == 0x1095 && devid == 0x4723) {
-               /* sil4723 quirks */
-               ata_for_each_link(link, ap, EDGE) {
-                       /* link reports offline after LPM */
-                       link->flags |= ATA_LFLAG_NO_LPM;
-
-                       /* class code report is unreliable */
-                       if (link->pmp < 2)
-                               link->flags |= ATA_LFLAG_ASSUME_ATA;
-
-                       /* the config device at port 2 locks up on SRST */
-                       if (link->pmp == 2)
-                               link->flags |= ATA_LFLAG_NO_SRST |
-                                              ATA_LFLAG_ASSUME_ATA;
-               }
+               /*
+                * sil4723 quirks
+                *
+                * Link reports offline after LPM.  Class code report is
+                * unreliable.  SIMG PMPs never got SRST reliable and the
+                * config device at port 2 locks up on SRST.
+                */
+               ata_for_each_link(link, ap, EDGE)
+                       link->flags |= ATA_LFLAG_NO_LPM |
+                                      ATA_LFLAG_NO_SRST |
+                                      ATA_LFLAG_ASSUME_ATA;
        } else if (vendor == 0x1095 && devid == 0x4726) {
                /* sil4726 quirks */
                ata_for_each_link(link, ap, EDGE) {