|
@@ -972,18 +972,24 @@ EXPORT_SYMBOL(scsi_report_opcode);
|
|
|
* Description: Gets a reference to the scsi_device and increments the use count
|
|
|
* of the underlying LLDD module. You must hold host_lock of the
|
|
|
* parent Scsi_Host or already have a reference when calling this.
|
|
|
+ *
|
|
|
+ * This will fail if a device is deleted or cancelled, or when the LLD module
|
|
|
+ * is in the process of being unloaded.
|
|
|
*/
|
|
|
int scsi_device_get(struct scsi_device *sdev)
|
|
|
{
|
|
|
- if (sdev->sdev_state == SDEV_DEL)
|
|
|
- return -ENXIO;
|
|
|
+ if (sdev->sdev_state == SDEV_DEL || sdev->sdev_state == SDEV_CANCEL)
|
|
|
+ goto fail;
|
|
|
if (!get_device(&sdev->sdev_gendev))
|
|
|
- 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);
|
|
|
-
|
|
|
+ goto fail;
|
|
|
+ if (!try_module_get(sdev->host->hostt->module))
|
|
|
+ goto fail_put_device;
|
|
|
return 0;
|
|
|
+
|
|
|
+fail_put_device:
|
|
|
+ put_device(&sdev->sdev_gendev);
|
|
|
+fail:
|
|
|
+ return -ENXIO;
|
|
|
}
|
|
|
EXPORT_SYMBOL(scsi_device_get);
|
|
|
|