Skip to content

Commit

Permalink
scsi: balance out autopm get/put calls in scsi_sysfs_add_sdev()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Subhash Jadavani authored and Christoph Hellwig committed Sep 15, 2014
1 parent 50c4e96 commit 6fe8c1d
Show file tree
Hide file tree
Showing 4 changed files with 7 additions and 4 deletions.
5 changes: 1 addition & 4 deletions drivers/scsi/scsi_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -1085,6 +1081,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
}
}

scsi_autopm_put_device(sdev);
return error;
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/scsi/sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -3041,6 +3042,7 @@ static int sd_probe(struct device *dev)
out_free:
kfree(sdkp);
out:
scsi_autopm_put_device(sdp);
return error;
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/scsi/sr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -744,6 +745,7 @@ static int sr_probe(struct device *dev)
fail_free:
kfree(cd);
fail:
scsi_autopm_put_device(sdev);
return error;
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/scsi/st.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -4244,6 +4245,7 @@ static int st_probe(struct device *dev)
out_buffer_free:
kfree(buffer);
out:
scsi_autopm_put_device(SDp);
return -ENODEV;
};

Expand Down

0 comments on commit 6fe8c1d

Please sign in to comment.