scsi: balance out autopm get/put calls in scsi_sysfs_add_sdev()
authorSubhash Jadavani <subhashj@codeaurora.org>
Wed, 10 Sep 2014 11:54:09 +0000 (14:54 +0300)
committerChristoph Hellwig <hch@lst.de>
Mon, 15 Sep 2014 23:02:05 +0000 (16:02 -0700)
SCSI Well-known logical units generally don't have any scsi driver
associated with it which means no one will call scsi_autopm_put_device()
on these wlun scsi devices and this would result in keeping the
corresponding scsi device always active (hence LLD can't be suspended as
well). Same exact problem can be seen for other scsi device representing
normal logical unit whose driver is yet to be loaded. This patch fixes
the above problem with this approach:

- make the scsi_autopm_put_device call at the end of scsi_sysfs_add_sdev
  to make it balance out the get earlier in the function.
- let drivers do paired get/put calls in their probe methods.

Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
Signed-off-by: Dolev Raviv <draviv@codeaurora.org>
Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/scsi/scsi_sysfs.c
drivers/scsi/sd.c
drivers/scsi/sr.c
drivers/scsi/st.c

index 85e36f3a55857d32ed6fc9000680646d127bed9c..f4cb7b3e9e2350d8b12f28d366cf90ab6c552262 100644 (file)
@@ -1044,10 +1044,6 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
        pm_runtime_enable(&sdev->sdev_gendev);
        scsi_autopm_put_target(starget);
 
-       /* The following call will keep sdev active indefinitely, until
-        * its driver does a corresponding scsi_autopm_pm_device().  Only
-        * drivers supporting autosuspend will do this.
-        */
        scsi_autopm_get_device(sdev);
 
        error = device_add(&sdev->sdev_gendev);
@@ -1085,6 +1081,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
                }
        }
 
+       scsi_autopm_put_device(sdev);
        return error;
 }
 
index aa43496b7b936164fa91ea8841f20bdef79ce461..0cb5c9f0c7431550f633660df8142ddd890f9e7e 100644 (file)
@@ -2965,6 +2965,7 @@ static int sd_probe(struct device *dev)
        int index;
        int error;
 
+       scsi_autopm_get_device(sdp);
        error = -ENODEV;
        if (sdp->type != TYPE_DISK && sdp->type != TYPE_MOD && sdp->type != TYPE_RBC)
                goto out;
@@ -3041,6 +3042,7 @@ static int sd_probe(struct device *dev)
  out_free:
        kfree(sdkp);
  out:
+       scsi_autopm_put_device(sdp);
        return error;
 }
 
index 7eeb93627beb77f31d00eeb147fc4e44ef6331c5..2de44cc58b1acd5cf038fd1a40ace6f34810b276 100644 (file)
@@ -657,6 +657,7 @@ static int sr_probe(struct device *dev)
        struct scsi_cd *cd;
        int minor, error;
 
+       scsi_autopm_get_device(sdev);
        error = -ENODEV;
        if (sdev->type != TYPE_ROM && sdev->type != TYPE_WORM)
                goto fail;
@@ -744,6 +745,7 @@ fail_put:
 fail_free:
        kfree(cd);
 fail:
+       scsi_autopm_put_device(sdev);
        return error;
 }
 
index aff9689de0f7079690e0a81653138469fa01bb68..d3fd6e8fb37868acf76948c70c958a7817f7a506 100644 (file)
@@ -4105,6 +4105,7 @@ static int st_probe(struct device *dev)
                return -ENODEV;
        }
 
+       scsi_autopm_get_device(SDp);
        i = queue_max_segments(SDp->request_queue);
        if (st_max_sg_segs < i)
                i = st_max_sg_segs;
@@ -4244,6 +4245,7 @@ out_put_disk:
 out_buffer_free:
        kfree(buffer);
 out:
+       scsi_autopm_put_device(SDp);
        return -ENODEV;
 };