diff options
author | Dave Airlie <airlied@redhat.com> | 2015-04-20 11:32:26 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2015-04-20 13:05:20 +1000 |
commit | 2c33ce009ca2389dbf0535d0672214d09738e35e (patch) | |
tree | 6186a6458c3c160385d794a23eaf07c786a9e61b /drivers/scsi/scsi.c | |
parent | cec32a47010647e8b0603726ebb75b990a4057a4 (diff) | |
parent | 09d51602cf84a1264946711dd4ea0dddbac599a1 (diff) |
Merge Linus master into drm-next
The merge is clean, but the arm build fails afterwards,
due to API changes in the regulator tree.
I've included the patch into the merge to fix the build.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/scsi/scsi.c')
-rw-r--r-- | drivers/scsi/scsi.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index c9c3b579eece..3833bf59fb66 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -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); |