libata: don't use ap->ioaddr in non-SFF drivers
[safe/jmp/linux-2.6] / drivers / ata / libata-eh.c
index 0d0a2c0..4ec1397 100644 (file)
@@ -1785,6 +1785,11 @@ static void ata_eh_link_autopsy(struct ata_link *link)
                if (qc->flags & ATA_QCFLAG_SENSE_VALID)
                        qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER);
 
+               /* determine whether the command is worth retrying */
+               if (!(qc->err_mask & AC_ERR_INVALID) &&
+                   ((qc->flags & ATA_QCFLAG_IO) || qc->err_mask != AC_ERR_DEV))
+                       qc->flags |= ATA_QCFLAG_RETRY;
+
                /* accumulate error info */
                ehc->i.dev = qc->dev;
                all_err_mask |= qc->err_mask;
@@ -2050,20 +2055,10 @@ static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset,
        if (rc)
                return rc;
 
-       /* If any class isn't ATA_DEV_UNKNOWN, consider classification
-        * is complete and convert all ATA_DEV_UNKNOWN to
-        * ATA_DEV_NONE.
-        */
+       /* convert all ATA_DEV_UNKNOWN to ATA_DEV_NONE */
        ata_link_for_each_dev(dev, link)
-               if (classes[dev->devno] != ATA_DEV_UNKNOWN)
-                       break;
-
-       if (dev) {
-               ata_link_for_each_dev(dev, link) {
-                       if (classes[dev->devno] == ATA_DEV_UNKNOWN)
-                               classes[dev->devno] = ATA_DEV_NONE;
-               }
-       }
+               if (classes[dev->devno] == ATA_DEV_UNKNOWN)
+                       classes[dev->devno] = ATA_DEV_NONE;
 
        return 0;
 }
@@ -2074,15 +2069,15 @@ static int ata_eh_followup_srst_needed(struct ata_link *link,
 {
        if (link->flags & ATA_LFLAG_NO_SRST)
                return 0;
-       if (rc == -EAGAIN)
-               return 1;
+       if (rc == -EAGAIN) {
+               if (classify)
+                       return 1;
+               rc = 0;
+       }
        if (rc != 0)
                return 0;
        if ((link->ap->flags & ATA_FLAG_PMP) && ata_is_host_link(link))
                return 1;
-       if (classify && !(link->flags & ATA_LFLAG_ASSUME_CLASS) &&
-           classes[0] == ATA_DEV_UNKNOWN)
-               return 1;
        return 0;
 }
 
@@ -2271,6 +2266,11 @@ int ata_eh_reset(struct ata_link *link, int classify,
        return rc;
 
  fail:
+       /* if SCR isn't accessible on a fan-out port, PMP needs to be reset */
+       if (!ata_is_host_link(link) &&
+           sata_scr_read(link, SCR_STATUS, &sstatus))
+               rc = -ERESTART;
+
        if (rc == -ERESTART || try >= max_tries)
                goto out;
 
@@ -2783,18 +2783,11 @@ void ata_eh_finish(struct ata_port *ap)
                        /* FIXME: Once EH migration is complete,
                         * generate sense data in this function,
                         * considering both err_mask and tf.
-                        *
-                        * There's no point in retrying invalid
-                        * (detected by libata) and non-IO device
-                        * errors (rejected by device).  Finish them
-                        * immediately.
                         */
-                       if ((qc->err_mask & AC_ERR_INVALID) ||
-                           (!(qc->flags & ATA_QCFLAG_IO) &&
-                            qc->err_mask == AC_ERR_DEV))
-                               ata_eh_qc_complete(qc);
-                       else
+                       if (qc->flags & ATA_QCFLAG_RETRY)
                                ata_eh_qc_retry(qc);
+                       else
+                               ata_eh_qc_complete(qc);
                } else {
                        if (qc->flags & ATA_QCFLAG_SENSE_VALID) {
                                ata_eh_qc_complete(qc);
@@ -2814,6 +2807,7 @@ void ata_eh_finish(struct ata_port *ap)
 /**
  *     ata_do_eh - do standard error handling
  *     @ap: host port to handle error for
+ *
  *     @prereset: prereset method (can be NULL)
  *     @softreset: softreset method (can be NULL)
  *     @hardreset: hardreset method (can be NULL)
@@ -2844,6 +2838,27 @@ void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
        ata_eh_finish(ap);
 }
 
+/**
+ *     ata_std_error_handler - standard error handler
+ *     @ap: host port to handle error for
+ *
+ *     Standard error handler
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep).
+ */
+void ata_std_error_handler(struct ata_port *ap)
+{
+       struct ata_port_operations *ops = ap->ops;
+       ata_reset_fn_t hardreset = ops->hardreset;
+
+       /* ignore built-in hardreset if SCR access is not available */
+       if (ata_is_builtin_hardreset(hardreset) && !sata_scr_valid(&ap->link))
+               hardreset = NULL;
+
+       ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset);
+}
+
 #ifdef CONFIG_PM
 /**
  *     ata_eh_handle_port_suspend - perform port suspend operation