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 --- Change from v3 - Rebased to the 4.0-rc1 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 c9c3b57..0d89344 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -981,7 +981,7 @@ int scsi_device_get(struct scsi_device *sdev) return -ENXIO; /* We can fail try_module_get if we're doing SCSI operations * from module exit (like cache flush) */ - __module_get(sdev->host->hostt->module); + __module_get(sdev->host->module); return 0; } @@ -997,7 +997,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-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html