[SCSI] scsi_transport_sas: add destructor for bsg

There's currently no destructor for the bsg components. If you insert
and remove the module, you see the bsg devices building up and up. This
patch adds the destructor in the correct place in the transport class so
that the bsg and request queue are removed just before the device
destruction.

Acked-by: FUJITA Tomonori <tomof@acm.org>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>

authored by James Bottomley and committed by James Bottomley b6aff669 e7cbff13

+37 -1
+35 -1
drivers/scsi/scsi_transport_sas.c
··· 42 struct sas_host_attrs { 43 struct list_head rphy_list; 44 struct mutex lock; 45 u32 next_target_id; 46 u32 next_expander_id; 47 int next_port_id; ··· 216 } 217 218 if (rphy) 219 q->queuedata = rphy; 220 else 221 q->queuedata = shost; ··· 228 set_bit(QUEUE_FLAG_BIDI, &q->queue_flags); 229 230 return 0; 231 } 232 233 /* ··· 271 return 0; 272 } 273 274 static DECLARE_TRANSPORT_CLASS(sas_host_class, 275 - "sas_host", sas_host_setup, NULL, NULL); 276 277 static int sas_host_match(struct attribute_container *cont, 278 struct device *dev) ··· 1445 mutex_lock(&sas_host->lock); 1446 list_del(&rphy->list); 1447 mutex_unlock(&sas_host->lock); 1448 1449 transport_destroy_device(dev); 1450
··· 42 struct sas_host_attrs { 43 struct list_head rphy_list; 44 struct mutex lock; 45 + struct request_queue *q; 46 u32 next_target_id; 47 u32 next_expander_id; 48 int next_port_id; ··· 215 } 216 217 if (rphy) 218 + rphy->q = q; 219 + else 220 + to_sas_host_attrs(shost)->q = q; 221 + 222 + if (rphy) 223 q->queuedata = rphy; 224 else 225 q->queuedata = shost; ··· 222 set_bit(QUEUE_FLAG_BIDI, &q->queue_flags); 223 224 return 0; 225 + } 226 + 227 + static void sas_bsg_remove(struct Scsi_Host *shost, struct sas_rphy *rphy) 228 + { 229 + struct request_queue *q; 230 + 231 + if (rphy) 232 + q = rphy->q; 233 + else 234 + q = to_sas_host_attrs(shost)->q; 235 + 236 + if (!q) 237 + return; 238 + 239 + bsg_unregister_queue(q); 240 + blk_cleanup_queue(q); 241 } 242 243 /* ··· 249 return 0; 250 } 251 252 + static int sas_host_remove(struct transport_container *tc, struct device *dev, 253 + struct class_device *cdev) 254 + { 255 + struct Scsi_Host *shost = dev_to_shost(dev); 256 + 257 + sas_bsg_remove(shost, NULL); 258 + 259 + return 0; 260 + } 261 + 262 static DECLARE_TRANSPORT_CLASS(sas_host_class, 263 + "sas_host", sas_host_setup, sas_host_remove, NULL); 264 265 static int sas_host_match(struct attribute_container *cont, 266 struct device *dev) ··· 1413 mutex_lock(&sas_host->lock); 1414 list_del(&rphy->list); 1415 mutex_unlock(&sas_host->lock); 1416 + 1417 + sas_bsg_remove(shost, rphy); 1418 1419 transport_destroy_device(dev); 1420
+2
include/scsi/scsi_transport_sas.h
··· 91 #define phy_to_shost(phy) \ 92 dev_to_shost((phy)->dev.parent) 93 94 struct sas_rphy { 95 struct device dev; 96 struct sas_identify identify; 97 struct list_head list; 98 u32 scsi_target_id; 99 }; 100
··· 91 #define phy_to_shost(phy) \ 92 dev_to_shost((phy)->dev.parent) 93 94 + struct request_queue; 95 struct sas_rphy { 96 struct device dev; 97 struct sas_identify identify; 98 struct list_head list; 99 + struct request_queue *q; 100 u32 scsi_target_id; 101 }; 102