aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libsas/sas_port.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libsas/sas_port.c')
-rw-r--r--drivers/scsi/libsas/sas_port.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c
index e884a8c58a0..1398b714c01 100644
--- a/drivers/scsi/libsas/sas_port.c
+++ b/drivers/scsi/libsas/sas_port.c
@@ -39,6 +39,49 @@ static bool phy_is_wideport_member(struct asd_sas_port *port, struct asd_sas_phy
39 return true; 39 return true;
40} 40}
41 41
42static void sas_resume_port(struct asd_sas_phy *phy)
43{
44 struct domain_device *dev;
45 struct asd_sas_port *port = phy->port;
46 struct sas_ha_struct *sas_ha = phy->ha;
47 struct sas_internal *si = to_sas_internal(sas_ha->core.shost->transportt);
48
49 if (si->dft->lldd_port_formed)
50 si->dft->lldd_port_formed(phy);
51
52 if (port->suspended)
53 port->suspended = 0;
54 else {
55 /* we only need to handle "link returned" actions once */
56 return;
57 }
58
59 /* if the port came back:
60 * 1/ presume every device came back
61 * 2/ force the next revalidation to check all expander phys
62 */
63 list_for_each_entry(dev, &port->dev_list, dev_list_node) {
64 int i, rc;
65
66 rc = sas_notify_lldd_dev_found(dev);
67 if (rc) {
68 sas_unregister_dev(port, dev);
69 continue;
70 }
71
72 if (dev->dev_type == EDGE_DEV || dev->dev_type == FANOUT_DEV) {
73 dev->ex_dev.ex_change_count = -1;
74 for (i = 0; i < dev->ex_dev.num_phys; i++) {
75 struct ex_phy *phy = &dev->ex_dev.ex_phy[i];
76
77 phy->phy_change_count = -1;
78 }
79 }
80 }
81
82 sas_discover_event(port, DISCE_RESUME);
83}
84
42/** 85/**
43 * sas_form_port -- add this phy to a port 86 * sas_form_port -- add this phy to a port
44 * @phy: the phy of interest 87 * @phy: the phy of interest
@@ -58,7 +101,14 @@ static void sas_form_port(struct asd_sas_phy *phy)
58 if (port) { 101 if (port) {
59 if (!phy_is_wideport_member(port, phy)) 102 if (!phy_is_wideport_member(port, phy))
60 sas_deform_port(phy, 0); 103 sas_deform_port(phy, 0);
61 else { 104 else if (phy->suspended) {
105 phy->suspended = 0;
106 sas_resume_port(phy);
107
108 /* phy came back, try to cancel the timeout */
109 wake_up(&sas_ha->eh_wait_q);
110 return;
111 } else {
62 SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n", 112 SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n",
63 __func__, phy->id, phy->port->id, 113 __func__, phy->id, phy->port->id,
64 phy->port->num_phys); 114 phy->port->num_phys);