diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/scsi_transport_sas.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index 2871fd05fcf7..573f588154d0 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c | |||
@@ -42,6 +42,7 @@ | |||
42 | struct sas_host_attrs { | 42 | struct sas_host_attrs { |
43 | struct list_head rphy_list; | 43 | struct list_head rphy_list; |
44 | struct mutex lock; | 44 | struct mutex lock; |
45 | struct request_queue *q; | ||
45 | u32 next_target_id; | 46 | u32 next_target_id; |
46 | u32 next_expander_id; | 47 | u32 next_expander_id; |
47 | int next_port_id; | 48 | int next_port_id; |
@@ -215,6 +216,11 @@ static int sas_bsg_initialize(struct Scsi_Host *shost, struct sas_rphy *rphy, | |||
215 | } | 216 | } |
216 | 217 | ||
217 | if (rphy) | 218 | if (rphy) |
219 | rphy->q = q; | ||
220 | else | ||
221 | to_sas_host_attrs(shost)->q = q; | ||
222 | |||
223 | if (rphy) | ||
218 | q->queuedata = rphy; | 224 | q->queuedata = rphy; |
219 | else | 225 | else |
220 | q->queuedata = shost; | 226 | q->queuedata = shost; |
@@ -224,6 +230,22 @@ static int sas_bsg_initialize(struct Scsi_Host *shost, struct sas_rphy *rphy, | |||
224 | return 0; | 230 | return 0; |
225 | } | 231 | } |
226 | 232 | ||
233 | static void sas_bsg_remove(struct Scsi_Host *shost, struct sas_rphy *rphy) | ||
234 | { | ||
235 | struct request_queue *q; | ||
236 | |||
237 | if (rphy) | ||
238 | q = rphy->q; | ||
239 | else | ||
240 | q = to_sas_host_attrs(shost)->q; | ||
241 | |||
242 | if (!q) | ||
243 | return; | ||
244 | |||
245 | bsg_unregister_queue(q); | ||
246 | blk_cleanup_queue(q); | ||
247 | } | ||
248 | |||
227 | /* | 249 | /* |
228 | * SAS host attributes | 250 | * SAS host attributes |
229 | */ | 251 | */ |
@@ -249,8 +271,18 @@ static int sas_host_setup(struct transport_container *tc, struct device *dev, | |||
249 | return 0; | 271 | return 0; |
250 | } | 272 | } |
251 | 273 | ||
274 | static int sas_host_remove(struct transport_container *tc, struct device *dev, | ||
275 | struct class_device *cdev) | ||
276 | { | ||
277 | struct Scsi_Host *shost = dev_to_shost(dev); | ||
278 | |||
279 | sas_bsg_remove(shost, NULL); | ||
280 | |||
281 | return 0; | ||
282 | } | ||
283 | |||
252 | static DECLARE_TRANSPORT_CLASS(sas_host_class, | 284 | static DECLARE_TRANSPORT_CLASS(sas_host_class, |
253 | "sas_host", sas_host_setup, NULL, NULL); | 285 | "sas_host", sas_host_setup, sas_host_remove, NULL); |
254 | 286 | ||
255 | static int sas_host_match(struct attribute_container *cont, | 287 | static int sas_host_match(struct attribute_container *cont, |
256 | struct device *dev) | 288 | struct device *dev) |
@@ -1414,6 +1446,8 @@ void sas_rphy_free(struct sas_rphy *rphy) | |||
1414 | list_del(&rphy->list); | 1446 | list_del(&rphy->list); |
1415 | mutex_unlock(&sas_host->lock); | 1447 | mutex_unlock(&sas_host->lock); |
1416 | 1448 | ||
1449 | sas_bsg_remove(shost, rphy); | ||
1450 | |||
1417 | transport_destroy_device(dev); | 1451 | transport_destroy_device(dev); |
1418 | 1452 | ||
1419 | put_device(dev); | 1453 | put_device(dev); |