aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi.c')
-rw-r--r--drivers/scsi/scsi.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 94df671d776a..37843927e47f 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -851,14 +851,14 @@ EXPORT_SYMBOL(scsi_track_queue_full);
851 */ 851 */
852int scsi_device_get(struct scsi_device *sdev) 852int scsi_device_get(struct scsi_device *sdev)
853{ 853{
854 if (sdev->sdev_state == SDEV_DEL || sdev->sdev_state == SDEV_CANCEL) 854 if (sdev->sdev_state == SDEV_DEL)
855 return -ENXIO; 855 return -ENXIO;
856 if (!get_device(&sdev->sdev_gendev)) 856 if (!get_device(&sdev->sdev_gendev))
857 return -ENXIO; 857 return -ENXIO;
858 if (!try_module_get(sdev->host->hostt->module)) { 858 /* We can fail this if we're doing SCSI operations
859 put_device(&sdev->sdev_gendev); 859 * from module exit (like cache flush) */
860 return -ENXIO; 860 try_module_get(sdev->host->hostt->module);
861 } 861
862 return 0; 862 return 0;
863} 863}
864EXPORT_SYMBOL(scsi_device_get); 864EXPORT_SYMBOL(scsi_device_get);
@@ -873,7 +873,10 @@ EXPORT_SYMBOL(scsi_device_get);
873 */ 873 */
874void scsi_device_put(struct scsi_device *sdev) 874void scsi_device_put(struct scsi_device *sdev)
875{ 875{
876 module_put(sdev->host->hostt->module); 876 /* The module refcount will be zero if scsi_device_get()
877 * was called from a module removal routine */
878 if (likely(module_refcount(sdev->host->hostt->module) != 0))
879 module_put(sdev->host->hostt->module);
877 put_device(&sdev->sdev_gendev); 880 put_device(&sdev->sdev_gendev);
878} 881}
879EXPORT_SYMBOL(scsi_device_put); 882EXPORT_SYMBOL(scsi_device_put);