aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libsas/sas_init.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2012-01-11 16:13:44 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-02-29 16:25:32 -0500
commitab5266335ba1a43461443f9823276a2b44dd1ba7 (patch)
tree5ab3c7e21f27e0ecacb01117764d911c349b51c9 /drivers/scsi/libsas/sas_init.c
parentd230ce691c7712c4f56ba3378d6d2f44628a49f1 (diff)
[SCSI] libsas: route local link resets through ata-eh
Similar to the conversion of the transport-class reset we want bsg initiated resets to be managed by libata. Reported-by: Jacek Danecki <jacek.danecki@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/libsas/sas_init.c')
-rw-r--r--drivers/scsi/libsas/sas_init.c45
1 files changed, 26 insertions, 19 deletions
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c
index cf1b532b0e76..dc93e1181469 100644
--- a/drivers/scsi/libsas/sas_init.c
+++ b/drivers/scsi/libsas/sas_init.c
@@ -196,6 +196,27 @@ static int sas_get_linkerrors(struct sas_phy *phy)
196 return sas_smp_get_phy_events(phy); 196 return sas_smp_get_phy_events(phy);
197} 197}
198 198
199int sas_try_ata_reset(struct asd_sas_phy *asd_phy)
200{
201 struct domain_device *dev = NULL;
202
203 /* try to route user requested link resets through libata */
204 if (asd_phy->port)
205 dev = asd_phy->port->port_dev;
206
207 /* validate that dev has been probed */
208 if (dev)
209 dev = sas_find_dev_by_rphy(dev->rphy);
210
211 if (dev && dev_is_sata(dev)) {
212 sas_ata_schedule_reset(dev);
213 sas_ata_wait_eh(dev);
214 return 0;
215 }
216
217 return -ENODEV;
218}
219
199/** 220/**
200 * transport_sas_phy_reset - reset a phy and permit libata to manage the link 221 * transport_sas_phy_reset - reset a phy and permit libata to manage the link
201 * 222 *
@@ -204,7 +225,6 @@ static int sas_get_linkerrors(struct sas_phy *phy)
204 */ 225 */
205static int transport_sas_phy_reset(struct sas_phy *phy, int hard_reset) 226static int transport_sas_phy_reset(struct sas_phy *phy, int hard_reset)
206{ 227{
207 int ret;
208 enum phy_func reset_type; 228 enum phy_func reset_type;
209 229
210 if (hard_reset) 230 if (hard_reset)
@@ -218,21 +238,10 @@ static int transport_sas_phy_reset(struct sas_phy *phy, int hard_reset)
218 struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number]; 238 struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number];
219 struct sas_internal *i = 239 struct sas_internal *i =
220 to_sas_internal(sas_ha->core.shost->transportt); 240 to_sas_internal(sas_ha->core.shost->transportt);
221 struct domain_device *dev = NULL;
222
223 if (asd_phy->port)
224 dev = asd_phy->port->port_dev;
225
226 /* validate that dev has been probed */
227 if (dev)
228 dev = sas_find_dev_by_rphy(dev->rphy);
229 241
230 if (dev && dev_is_sata(dev) && !hard_reset) { 242 if (!hard_reset && sas_try_ata_reset(asd_phy) == 0)
231 sas_ata_schedule_reset(dev); 243 return 0;
232 sas_ata_wait_eh(dev); 244 return i->dft->lldd_control_phy(asd_phy, reset_type, NULL);
233 ret = 0;
234 } else
235 ret = i->dft->lldd_control_phy(asd_phy, reset_type, NULL);
236 } else { 245 } else {
237 struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent); 246 struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
238 struct domain_device *ddev = sas_find_dev_by_rphy(rphy); 247 struct domain_device *ddev = sas_find_dev_by_rphy(rphy);
@@ -241,12 +250,10 @@ static int transport_sas_phy_reset(struct sas_phy *phy, int hard_reset)
241 if (ata_dev && !hard_reset) { 250 if (ata_dev && !hard_reset) {
242 sas_ata_schedule_reset(ata_dev); 251 sas_ata_schedule_reset(ata_dev);
243 sas_ata_wait_eh(ata_dev); 252 sas_ata_wait_eh(ata_dev);
244 ret = 0; 253 return 0;
245 } else 254 } else
246 ret = sas_smp_phy_control(ddev, phy->number, reset_type, NULL); 255 return sas_smp_phy_control(ddev, phy->number, reset_type, NULL);
247 } 256 }
248
249 return ret;
250} 257}
251 258
252static int sas_phy_enable(struct sas_phy *phy, int enable) 259static int sas_phy_enable(struct sas_phy *phy, int enable)