OSDN Git Service

isci: Hard reset failure will link reset all phys in the port
authorJeff Skirvin <jeffrey.d.skirvin@intel.com>
Mon, 20 Jun 2011 21:09:26 +0000 (14:09 -0700)
committerDan Williams <dan.j.williams@intel.com>
Sun, 3 Jul 2011 11:04:50 +0000 (04:04 -0700)
In the case where the hard reset process fails, each link in
the port is put through a link reset sequence.

Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
drivers/scsi/isci/port.c

index 2946eee..e540281 100644 (file)
@@ -1916,7 +1916,7 @@ int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *ipor
 {
        unsigned long flags;
        enum sci_status status;
-       int ret = TMF_RESP_FUNC_COMPLETE;
+       int idx, ret = TMF_RESP_FUNC_COMPLETE;
 
        dev_dbg(&ihost->pdev->dev, "%s: iport = %p\n",
                __func__, iport);
@@ -1953,14 +1953,26 @@ int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *ipor
         * the same as link failures on all phys in the port.
         */
        if (ret != TMF_RESP_FUNC_COMPLETE) {
+
                dev_err(&ihost->pdev->dev,
                        "%s: iport = %p; hard reset failed "
-                       "(0x%x) - sending link down to libsas for phy %p\n",
-                       __func__, iport, iport->hard_reset_status, iphy);
+                       "(0x%x) - driving explicit link fail for all phys\n",
+                       __func__, iport, iport->hard_reset_status);
 
-               isci_port_link_down(ihost, iphy, iport);
-       }
+               /* Down all phys in the port. */
+               spin_lock_irqsave(&ihost->scic_lock, flags);
+               for (idx = 0; idx < SCI_MAX_PHYS; ++idx) {
+
+                       if (iport->sci.phy_table[idx] != NULL) {
 
+                               scic_sds_phy_stop(
+                                       iport->sci.phy_table[idx]);
+                               scic_sds_phy_start(
+                                       iport->sci.phy_table[idx]);
+                       }
+               }
+               spin_unlock_irqrestore(&ihost->scic_lock, flags);
+       }
        return ret;
 }