aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/libsas/sas_internal.h2
-rw-r--r--drivers/scsi/libsas/sas_phy.c4
-rw-r--r--drivers/scsi/libsas/sas_port.c21
3 files changed, 15 insertions, 12 deletions
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h
index 8b538bd1ff2b..14e21b5fb8ba 100644
--- a/drivers/scsi/libsas/sas_internal.h
+++ b/drivers/scsi/libsas/sas_internal.h
@@ -57,7 +57,7 @@ int sas_init_queue(struct sas_ha_struct *sas_ha);
57int sas_init_events(struct sas_ha_struct *sas_ha); 57int sas_init_events(struct sas_ha_struct *sas_ha);
58void sas_shutdown_queue(struct sas_ha_struct *sas_ha); 58void sas_shutdown_queue(struct sas_ha_struct *sas_ha);
59 59
60void sas_deform_port(struct asd_sas_phy *phy); 60void sas_deform_port(struct asd_sas_phy *phy, int gone);
61 61
62void sas_porte_bytes_dmaed(struct work_struct *work); 62void sas_porte_bytes_dmaed(struct work_struct *work);
63void sas_porte_broadcast_rcvd(struct work_struct *work); 63void sas_porte_broadcast_rcvd(struct work_struct *work);
diff --git a/drivers/scsi/libsas/sas_phy.c b/drivers/scsi/libsas/sas_phy.c
index b459c4b635b1..e0f5018e9071 100644
--- a/drivers/scsi/libsas/sas_phy.c
+++ b/drivers/scsi/libsas/sas_phy.c
@@ -39,7 +39,7 @@ static void sas_phye_loss_of_signal(struct work_struct *work)
39 sas_begin_event(PHYE_LOSS_OF_SIGNAL, &phy->ha->event_lock, 39 sas_begin_event(PHYE_LOSS_OF_SIGNAL, &phy->ha->event_lock,
40 &phy->phy_events_pending); 40 &phy->phy_events_pending);
41 phy->error = 0; 41 phy->error = 0;
42 sas_deform_port(phy); 42 sas_deform_port(phy, 1);
43} 43}
44 44
45static void sas_phye_oob_done(struct work_struct *work) 45static void sas_phye_oob_done(struct work_struct *work)
@@ -66,7 +66,7 @@ static void sas_phye_oob_error(struct work_struct *work)
66 sas_begin_event(PHYE_OOB_ERROR, &phy->ha->event_lock, 66 sas_begin_event(PHYE_OOB_ERROR, &phy->ha->event_lock,
67 &phy->phy_events_pending); 67 &phy->phy_events_pending);
68 68
69 sas_deform_port(phy); 69 sas_deform_port(phy, 1);
70 70
71 if (!port && phy->enabled && i->dft->lldd_control_phy) { 71 if (!port && phy->enabled && i->dft->lldd_control_phy) {
72 phy->error++; 72 phy->error++;
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c
index 5257fdfe699a..42fd1f25b664 100644
--- a/drivers/scsi/libsas/sas_port.c
+++ b/drivers/scsi/libsas/sas_port.c
@@ -57,7 +57,7 @@ static void sas_form_port(struct asd_sas_phy *phy)
57 57
58 if (port) { 58 if (port) {
59 if (!phy_is_wideport_member(port, phy)) 59 if (!phy_is_wideport_member(port, phy))
60 sas_deform_port(phy); 60 sas_deform_port(phy, 0);
61 else { 61 else {
62 SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n", 62 SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n",
63 __func__, phy->id, phy->port->id, 63 __func__, phy->id, phy->port->id,
@@ -153,28 +153,31 @@ static void sas_form_port(struct asd_sas_phy *phy)
153 * This is called when the physical link to the other phy has been 153 * This is called when the physical link to the other phy has been
154 * lost (on this phy), in Event thread context. We cannot delay here. 154 * lost (on this phy), in Event thread context. We cannot delay here.
155 */ 155 */
156void sas_deform_port(struct asd_sas_phy *phy) 156void sas_deform_port(struct asd_sas_phy *phy, int gone)
157{ 157{
158 struct sas_ha_struct *sas_ha = phy->ha; 158 struct sas_ha_struct *sas_ha = phy->ha;
159 struct asd_sas_port *port = phy->port; 159 struct asd_sas_port *port = phy->port;
160 struct sas_internal *si = 160 struct sas_internal *si =
161 to_sas_internal(sas_ha->core.shost->transportt); 161 to_sas_internal(sas_ha->core.shost->transportt);
162 struct domain_device *dev;
162 unsigned long flags; 163 unsigned long flags;
163 164
164 if (!port) 165 if (!port)
165 return; /* done by a phy event */ 166 return; /* done by a phy event */
166 167
167 if (port->port_dev) 168 dev = port->port_dev;
168 port->port_dev->pathways--; 169 if (dev)
170 dev->pathways--;
169 171
170 if (port->num_phys == 1) { 172 if (port->num_phys == 1) {
173 if (dev && gone)
174 dev->gone = 1;
171 sas_unregister_domain_devices(port); 175 sas_unregister_domain_devices(port);
172 sas_port_delete(port->port); 176 sas_port_delete(port->port);
173 port->port = NULL; 177 port->port = NULL;
174 } else 178 } else
175 sas_port_delete_phy(port->port, phy->phy); 179 sas_port_delete_phy(port->port, phy->phy);
176 180
177
178 if (si->dft->lldd_port_deformed) 181 if (si->dft->lldd_port_deformed)
179 si->dft->lldd_port_deformed(phy); 182 si->dft->lldd_port_deformed(phy);
180 183
@@ -244,7 +247,7 @@ void sas_porte_link_reset_err(struct work_struct *work)
244 sas_begin_event(PORTE_LINK_RESET_ERR, &phy->ha->event_lock, 247 sas_begin_event(PORTE_LINK_RESET_ERR, &phy->ha->event_lock,
245 &phy->port_events_pending); 248 &phy->port_events_pending);
246 249
247 sas_deform_port(phy); 250 sas_deform_port(phy, 1);
248} 251}
249 252
250void sas_porte_timer_event(struct work_struct *work) 253void sas_porte_timer_event(struct work_struct *work)
@@ -256,7 +259,7 @@ void sas_porte_timer_event(struct work_struct *work)
256 sas_begin_event(PORTE_TIMER_EVENT, &phy->ha->event_lock, 259 sas_begin_event(PORTE_TIMER_EVENT, &phy->ha->event_lock,
257 &phy->port_events_pending); 260 &phy->port_events_pending);
258 261
259 sas_deform_port(phy); 262 sas_deform_port(phy, 1);
260} 263}
261 264
262void sas_porte_hard_reset(struct work_struct *work) 265void sas_porte_hard_reset(struct work_struct *work)
@@ -268,7 +271,7 @@ void sas_porte_hard_reset(struct work_struct *work)
268 sas_begin_event(PORTE_HARD_RESET, &phy->ha->event_lock, 271 sas_begin_event(PORTE_HARD_RESET, &phy->ha->event_lock,
269 &phy->port_events_pending); 272 &phy->port_events_pending);
270 273
271 sas_deform_port(phy); 274 sas_deform_port(phy, 1);
272} 275}
273 276
274/* ---------- SAS port registration ---------- */ 277/* ---------- SAS port registration ---------- */
@@ -306,6 +309,6 @@ void sas_unregister_ports(struct sas_ha_struct *sas_ha)
306 309
307 for (i = 0; i < sas_ha->num_phys; i++) 310 for (i = 0; i < sas_ha->num_phys; i++)
308 if (sas_ha->sas_phy[i]->port) 311 if (sas_ha->sas_phy[i]->port)
309 sas_deform_port(sas_ha->sas_phy[i]); 312 sas_deform_port(sas_ha->sas_phy[i], 0);
310 313
311} 314}