|
@@ -57,7 +57,7 @@ static void sas_form_port(struct asd_sas_phy *phy)
|
|
|
|
|
|
if (port) {
|
|
|
if (!phy_is_wideport_member(port, phy))
|
|
|
- sas_deform_port(phy);
|
|
|
+ sas_deform_port(phy, 0);
|
|
|
else {
|
|
|
SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n",
|
|
|
__func__, phy->id, phy->port->id,
|
|
@@ -153,28 +153,31 @@ static void sas_form_port(struct asd_sas_phy *phy)
|
|
|
* This is called when the physical link to the other phy has been
|
|
|
* lost (on this phy), in Event thread context. We cannot delay here.
|
|
|
*/
|
|
|
-void sas_deform_port(struct asd_sas_phy *phy)
|
|
|
+void sas_deform_port(struct asd_sas_phy *phy, int gone)
|
|
|
{
|
|
|
struct sas_ha_struct *sas_ha = phy->ha;
|
|
|
struct asd_sas_port *port = phy->port;
|
|
|
struct sas_internal *si =
|
|
|
to_sas_internal(sas_ha->core.shost->transportt);
|
|
|
+ struct domain_device *dev;
|
|
|
unsigned long flags;
|
|
|
|
|
|
if (!port)
|
|
|
return; /* done by a phy event */
|
|
|
|
|
|
- if (port->port_dev)
|
|
|
- port->port_dev->pathways--;
|
|
|
+ dev = port->port_dev;
|
|
|
+ if (dev)
|
|
|
+ dev->pathways--;
|
|
|
|
|
|
if (port->num_phys == 1) {
|
|
|
+ if (dev && gone)
|
|
|
+ dev->gone = 1;
|
|
|
sas_unregister_domain_devices(port);
|
|
|
sas_port_delete(port->port);
|
|
|
port->port = NULL;
|
|
|
} else
|
|
|
sas_port_delete_phy(port->port, phy->phy);
|
|
|
|
|
|
-
|
|
|
if (si->dft->lldd_port_deformed)
|
|
|
si->dft->lldd_port_deformed(phy);
|
|
|
|
|
@@ -244,7 +247,7 @@ void sas_porte_link_reset_err(struct work_struct *work)
|
|
|
sas_begin_event(PORTE_LINK_RESET_ERR, &phy->ha->event_lock,
|
|
|
&phy->port_events_pending);
|
|
|
|
|
|
- sas_deform_port(phy);
|
|
|
+ sas_deform_port(phy, 1);
|
|
|
}
|
|
|
|
|
|
void sas_porte_timer_event(struct work_struct *work)
|
|
@@ -256,7 +259,7 @@ void sas_porte_timer_event(struct work_struct *work)
|
|
|
sas_begin_event(PORTE_TIMER_EVENT, &phy->ha->event_lock,
|
|
|
&phy->port_events_pending);
|
|
|
|
|
|
- sas_deform_port(phy);
|
|
|
+ sas_deform_port(phy, 1);
|
|
|
}
|
|
|
|
|
|
void sas_porte_hard_reset(struct work_struct *work)
|
|
@@ -268,7 +271,7 @@ void sas_porte_hard_reset(struct work_struct *work)
|
|
|
sas_begin_event(PORTE_HARD_RESET, &phy->ha->event_lock,
|
|
|
&phy->port_events_pending);
|
|
|
|
|
|
- sas_deform_port(phy);
|
|
|
+ sas_deform_port(phy, 1);
|
|
|
}
|
|
|
|
|
|
/* ---------- SAS port registration ---------- */
|
|
@@ -306,6 +309,6 @@ void sas_unregister_ports(struct sas_ha_struct *sas_ha)
|
|
|
|
|
|
for (i = 0; i < sas_ha->num_phys; i++)
|
|
|
if (sas_ha->sas_phy[i]->port)
|
|
|
- sas_deform_port(sas_ha->sas_phy[i]);
|
|
|
+ sas_deform_port(sas_ha->sas_phy[i], 0);
|
|
|
|
|
|
}
|