While accessing a scsi_device, the use count of the underlying LLDD module is incremented. The module reference is retrieved through .module field of struct scsi_host_template. This mapping between scsi_device and underlying LLDD module works well except ufs, unusual usb storage drivers, and sub drivers for esp_scsi. These drivers consist with core driver and actual LLDDs, and scsi_host_template is defined in the core driver. So the actual LLDDs can be unloaded even if the scsi_device is being accessed. This adds .module field in struct Scsi_Host and let the module reference be retrieved though it instead of struct scsi_host_template. This allows the actual LLDDs adjust module reference. Signed-off-by: Akinobu Mita <akinobu.mita@xxxxxxxxx> Reviewed-by: Hannes Reinecke <hare@xxxxxxx> Cc: Vinayak Holikatti <vinholikatti@xxxxxxxxx> Cc: Dolev Raviv <draviv@xxxxxxxxxxxxxx> Cc: Sujit Reddy Thumma <sthumma@xxxxxxxxxxxxxx> Cc: Subhash Jadavani <subhashj@xxxxxxxxxxxxxx> Cc: Christoph Hellwig <hch@xxxxxx> Cc: "James E.J. Bottomley" <JBottomley@xxxxxxxxxxxxx> Cc: Matthew Dharm <mdharm-usb@xxxxxxxxxxxxxxxxxx> Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> Cc: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> Cc: "David S. Miller" <davem@xxxxxxxxxxxxx> Cc: Hannes Reinecke <hare@xxxxxxx> Cc: linux-usb@xxxxxxxxxxxxxxx Cc: usb-storage@xxxxxxxxxxxxxxxxxxxxxxxx Cc: linux-scsi@xxxxxxxxxxxxxxx --- * Changes from v5 - Rebased as v5 doesn't apply cleanly to the latest tree anymore. drivers/scsi/hosts.c | 1 + drivers/scsi/scsi.c | 4 ++-- include/scsi/scsi_host.h | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 8bb173e..21f1442 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -411,6 +411,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) */ shost->max_cmd_len = 12; shost->hostt = sht; + shost->module = sht->module; shost->this_id = sht->this_id; shost->can_queue = sht->can_queue; shost->sg_tablesize = sht->sg_tablesize; diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 3833bf5..f7534a9 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -982,7 +982,7 @@ int scsi_device_get(struct scsi_device *sdev) goto fail; if (!get_device(&sdev->sdev_gendev)) goto fail; - if (!try_module_get(sdev->host->hostt->module)) + if (!try_module_get(sdev->host->module)) goto fail_put_device; return 0; @@ -1003,7 +1003,7 @@ EXPORT_SYMBOL(scsi_device_get); */ void scsi_device_put(struct scsi_device *sdev) { - module_put(sdev->host->hostt->module); + module_put(sdev->host->module); put_device(&sdev->sdev_gendev); } EXPORT_SYMBOL(scsi_device_put); diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index e113c75..8742bfd 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -620,6 +620,7 @@ struct Scsi_Host { */ unsigned short max_cmd_len; + struct module *module; int this_id; int can_queue; short cmd_per_lun; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html