diff options
author | Lin Ming <ming.m.lin@intel.com> | 2012-07-06 00:06:57 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-07-20 03:58:55 -0400 |
commit | 33a2285d96b5e7b9500612ec623bf4313397bb53 (patch) | |
tree | 08d9f292b021ebb3c447421534913e8221de41e5 /drivers/scsi | |
parent | 4bdd03e61b7a5c4c6bc2b25d46fcd491788fdfb3 (diff) |
[SCSI] scsi_pm: set device runtime state before parent suspended
There is a race in scsi_bus_resume_common when set device's runtime
state to active after pm_runtime_put_sync(dev->parent).
Parent device may have been suspended so pm_runtime_set_active(dev) will
fail with -EBUSY.
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/scsi_pm.c | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c index d4201ded3b22..dc0ad85853e2 100644 --- a/drivers/scsi/scsi_pm.c +++ b/drivers/scsi/scsi_pm.c | |||
@@ -76,23 +76,24 @@ static int scsi_bus_resume_common(struct device *dev) | |||
76 | { | 76 | { |
77 | int err = 0; | 77 | int err = 0; |
78 | 78 | ||
79 | if (scsi_is_sdev_device(dev)) { | 79 | /* |
80 | /* | 80 | * Parent device may have runtime suspended as soon as |
81 | * Parent device may have runtime suspended as soon as | 81 | * it is woken up during the system resume. |
82 | * it is woken up during the system resume. | 82 | * |
83 | * | 83 | * Resume it on behalf of child. |
84 | * Resume it on behalf of child. | 84 | */ |
85 | */ | 85 | pm_runtime_get_sync(dev->parent); |
86 | pm_runtime_get_sync(dev->parent); | ||
87 | err = scsi_dev_type_resume(dev); | ||
88 | pm_runtime_put_sync(dev->parent); | ||
89 | } | ||
90 | 86 | ||
87 | if (scsi_is_sdev_device(dev)) | ||
88 | err = scsi_dev_type_resume(dev); | ||
91 | if (err == 0) { | 89 | if (err == 0) { |
92 | pm_runtime_disable(dev); | 90 | pm_runtime_disable(dev); |
93 | pm_runtime_set_active(dev); | 91 | pm_runtime_set_active(dev); |
94 | pm_runtime_enable(dev); | 92 | pm_runtime_enable(dev); |
95 | } | 93 | } |
94 | |||
95 | pm_runtime_put_sync(dev->parent); | ||
96 | |||
96 | return err; | 97 | return err; |
97 | } | 98 | } |
98 | 99 | ||