sata_mv errata workaround for sata25 part 1
[safe/jmp/linux-2.6] / drivers / ata / libata-eh.c
index 4ec1397..61dcd00 100644 (file)
@@ -873,9 +873,9 @@ int sata_async_notification(struct ata_port *ap)
        if (rc == 0)
                sata_scr_write(&ap->link, SCR_NOTIFICATION, sntf);
 
-       if (!ap->nr_pmp_links || rc) {
+       if (!sata_pmp_attached(ap) || rc) {
                /* PMP is not attached or SNTF is not available */
-               if (!ap->nr_pmp_links) {
+               if (!sata_pmp_attached(ap)) {
                        /* PMP is not attached.  Check whether ATAPI
                         * AN is configured.  If so, notify media
                         * change.
@@ -1402,6 +1402,7 @@ static void ata_eh_analyze_ncq_error(struct ata_link *link)
        /* we've got the perpetrator, condemn it */
        qc = __ata_qc_from_tag(ap, tag);
        memcpy(&qc->result_tf, &tf, sizeof(tf));
+       qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
        qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ;
        ehc->i.err_mask &= ~AC_ERR_DEV;
 }
@@ -1853,7 +1854,7 @@ void ata_eh_autopsy(struct ata_port *ap)
        /* Autopsy of fanout ports can affect host link autopsy.
         * Perform host link autopsy last.
         */
-       if (ap->nr_pmp_links)
+       if (sata_pmp_attached(ap))
                ata_eh_link_autopsy(&ap->link);
 }
 
@@ -2052,22 +2053,20 @@ static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset,
                classes[dev->devno] = ATA_DEV_UNKNOWN;
 
        rc = reset(link, classes, deadline);
-       if (rc)
-               return rc;
 
        /* convert all ATA_DEV_UNKNOWN to ATA_DEV_NONE */
        ata_link_for_each_dev(dev, link)
                if (classes[dev->devno] == ATA_DEV_UNKNOWN)
                        classes[dev->devno] = ATA_DEV_NONE;
 
-       return 0;
+       return rc;
 }
 
 static int ata_eh_followup_srst_needed(struct ata_link *link,
                                       int rc, int classify,
                                       const unsigned int *classes)
 {
-       if (link->flags & ATA_LFLAG_NO_SRST)
+       if ((link->flags & ATA_LFLAG_NO_SRST) || ata_link_offline(link))
                return 0;
        if (rc == -EAGAIN) {
                if (classify)
@@ -2076,7 +2075,7 @@ static int ata_eh_followup_srst_needed(struct ata_link *link,
        }
        if (rc != 0)
                return 0;
-       if ((link->ap->flags & ATA_FLAG_PMP) && ata_is_host_link(link))
+       if (sata_pmp_supported(link->ap) && ata_is_host_link(link))
                return 1;
        return 0;
 }
@@ -2139,9 +2138,14 @@ int ata_eh_reset(struct ata_link *link, int classify,
        if (hardreset) {
                reset = hardreset;
                ehc->i.action = ATA_EH_HARDRESET;
-       } else {
+       } else if (softreset) {
                reset = softreset;
                ehc->i.action = ATA_EH_SOFTRESET;
+       } else {
+               ata_link_printk(link, KERN_ERR, "BUG: no reset method, "
+                               "please report to linux-ide@vger.kernel.org\n");
+               dump_stack();
+               return -EINVAL;
        }
 
        if (prereset) {
@@ -2209,21 +2213,6 @@ int ata_eh_reset(struct ata_link *link, int classify,
        if (rc && rc != -EAGAIN)
                goto fail;
 
-       /* was classification successful? */
-       if (classify && classes[0] == ATA_DEV_UNKNOWN &&
-           !(lflags & ATA_LFLAG_ASSUME_CLASS)) {
-               if (try < max_tries) {
-                       ata_link_printk(link, KERN_WARNING,
-                                       "classification failed\n");
-                       rc = -EINVAL;
-                       goto fail;
-               }
-
-               ata_link_printk(link, KERN_WARNING,
-                               "classfication failed, assuming ATA\n");
-               lflags |= ATA_LFLAG_ASSUME_ATA;
-       }
-
  done:
        ata_link_for_each_dev(dev, link) {
                /* After the reset, the device state is PIO 0 and the
@@ -2668,7 +2657,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
                /* if PMP is attached, this function only deals with
                 * downstream links, port should stay thawed.
                 */
-               if (!ap->nr_pmp_links)
+               if (!sata_pmp_attached(ap))
                        ata_eh_freeze_port(ap);
 
                ata_port_for_each_link(link, ap) {
@@ -2687,7 +2676,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
                        }
                }
 
-               if (!ap->nr_pmp_links)
+               if (!sata_pmp_attached(ap))
                        ata_eh_thaw_port(ap);
        }
 
@@ -2731,7 +2720,7 @@ dev_fail:
                        /* PMP reset requires working host port.
                         * Can't retry if it's frozen.
                         */
-                       if (ap->nr_pmp_links)
+                       if (sata_pmp_attached(ap))
                                goto out;
                        break;
                }