diff options
| author | James Bottomley <JBottomley@Parallels.com> | 2013-05-10 10:54:01 -0400 |
|---|---|---|
| committer | James Bottomley <JBottomley@Parallels.com> | 2013-05-10 10:54:01 -0400 |
| commit | 297b8a07347555f0d2fafa4a1ddfc332d2d4afa9 (patch) | |
| tree | 7c54ce22c1cd10118b5094441b8d7da2f4c58d6a | |
| parent | 832e77bc1106592c621fc42f2f6a4500e414a0a1 (diff) | |
| parent | 6df339a51e3bf18b868384bdeb31e49a4fbaa3d8 (diff) | |
Merge branch 'postmerge' into for-linus
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
| -rw-r--r-- | drivers/scsi/scsi_lib.c | 9 | ||||
| -rw-r--r-- | drivers/scsi/scsi_pm.c | 84 | ||||
| -rw-r--r-- | drivers/scsi/sd.c | 22 | ||||
| -rw-r--r-- | include/scsi/scsi_device.h | 16 |
4 files changed, 93 insertions, 38 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index c31187d79343..86d522004a20 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
| @@ -276,11 +276,10 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, | |||
| 276 | } | 276 | } |
| 277 | EXPORT_SYMBOL(scsi_execute); | 277 | EXPORT_SYMBOL(scsi_execute); |
| 278 | 278 | ||
| 279 | 279 | int scsi_execute_req_flags(struct scsi_device *sdev, const unsigned char *cmd, | |
| 280 | int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd, | ||
| 281 | int data_direction, void *buffer, unsigned bufflen, | 280 | int data_direction, void *buffer, unsigned bufflen, |
| 282 | struct scsi_sense_hdr *sshdr, int timeout, int retries, | 281 | struct scsi_sense_hdr *sshdr, int timeout, int retries, |
| 283 | int *resid) | 282 | int *resid, int flags) |
| 284 | { | 283 | { |
| 285 | char *sense = NULL; | 284 | char *sense = NULL; |
| 286 | int result; | 285 | int result; |
| @@ -291,14 +290,14 @@ int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd, | |||
| 291 | return DRIVER_ERROR << 24; | 290 | return DRIVER_ERROR << 24; |
| 292 | } | 291 | } |
| 293 | result = scsi_execute(sdev, cmd, data_direction, buffer, bufflen, | 292 | result = scsi_execute(sdev, cmd, data_direction, buffer, bufflen, |
| 294 | sense, timeout, retries, 0, resid); | 293 | sense, timeout, retries, flags, resid); |
| 295 | if (sshdr) | 294 | if (sshdr) |
| 296 | scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, sshdr); | 295 | scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, sshdr); |
| 297 | 296 | ||
| 298 | kfree(sense); | 297 | kfree(sense); |
| 299 | return result; | 298 | return result; |
| 300 | } | 299 | } |
| 301 | EXPORT_SYMBOL(scsi_execute_req); | 300 | EXPORT_SYMBOL(scsi_execute_req_flags); |
| 302 | 301 | ||
| 303 | /* | 302 | /* |
| 304 | * Function: scsi_init_cmd_errh() | 303 | * Function: scsi_init_cmd_errh() |
diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c index 8f6b12cbd224..42539ee2cb11 100644 --- a/drivers/scsi/scsi_pm.c +++ b/drivers/scsi/scsi_pm.c | |||
| @@ -144,33 +144,83 @@ static int scsi_bus_restore(struct device *dev) | |||
| 144 | 144 | ||
| 145 | #ifdef CONFIG_PM_RUNTIME | 145 | #ifdef CONFIG_PM_RUNTIME |
| 146 | 146 | ||
| 147 | static int sdev_blk_runtime_suspend(struct scsi_device *sdev, | ||
| 148 | int (*cb)(struct device *)) | ||
| 149 | { | ||
| 150 | int err; | ||
| 151 | |||
| 152 | err = blk_pre_runtime_suspend(sdev->request_queue); | ||
| 153 | if (err) | ||
| 154 | return err; | ||
| 155 | if (cb) | ||
| 156 | err = cb(&sdev->sdev_gendev); | ||
| 157 | blk_post_runtime_suspend(sdev->request_queue, err); | ||
| 158 | |||
| 159 | return err; | ||
| 160 | } | ||
| 161 | |||
| 162 | static int sdev_runtime_suspend(struct device *dev) | ||
| 163 | { | ||
| 164 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
| 165 | int (*cb)(struct device *) = pm ? pm->runtime_suspend : NULL; | ||
| 166 | struct scsi_device *sdev = to_scsi_device(dev); | ||
| 167 | int err; | ||
| 168 | |||
| 169 | if (sdev->request_queue->dev) | ||
| 170 | return sdev_blk_runtime_suspend(sdev, cb); | ||
| 171 | |||
| 172 | err = scsi_dev_type_suspend(dev, cb); | ||
| 173 | if (err == -EAGAIN) | ||
| 174 | pm_schedule_suspend(dev, jiffies_to_msecs( | ||
| 175 | round_jiffies_up_relative(HZ/10))); | ||
| 176 | return err; | ||
| 177 | } | ||
| 178 | |||
| 147 | static int scsi_runtime_suspend(struct device *dev) | 179 | static int scsi_runtime_suspend(struct device *dev) |
| 148 | { | 180 | { |
| 149 | int err = 0; | 181 | int err = 0; |
| 150 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
| 151 | 182 | ||
| 152 | dev_dbg(dev, "scsi_runtime_suspend\n"); | 183 | dev_dbg(dev, "scsi_runtime_suspend\n"); |
| 153 | if (scsi_is_sdev_device(dev)) { | 184 | if (scsi_is_sdev_device(dev)) |
| 154 | err = scsi_dev_type_suspend(dev, | 185 | err = sdev_runtime_suspend(dev); |
| 155 | pm ? pm->runtime_suspend : NULL); | ||
| 156 | if (err == -EAGAIN) | ||
| 157 | pm_schedule_suspend(dev, jiffies_to_msecs( | ||
| 158 | round_jiffies_up_relative(HZ/10))); | ||
| 159 | } | ||
| 160 | 186 | ||
| 161 | /* Insert hooks here for targets, hosts, and transport classes */ | 187 | /* Insert hooks here for targets, hosts, and transport classes */ |
| 162 | 188 | ||
| 163 | return err; | 189 | return err; |
| 164 | } | 190 | } |
| 165 | 191 | ||
| 166 | static int scsi_runtime_resume(struct device *dev) | 192 | static int sdev_blk_runtime_resume(struct scsi_device *sdev, |
| 193 | int (*cb)(struct device *)) | ||
| 167 | { | 194 | { |
| 168 | int err = 0; | 195 | int err = 0; |
| 196 | |||
| 197 | blk_pre_runtime_resume(sdev->request_queue); | ||
| 198 | if (cb) | ||
| 199 | err = cb(&sdev->sdev_gendev); | ||
| 200 | blk_post_runtime_resume(sdev->request_queue, err); | ||
| 201 | |||
| 202 | return err; | ||
| 203 | } | ||
| 204 | |||
| 205 | static int sdev_runtime_resume(struct device *dev) | ||
| 206 | { | ||
| 207 | struct scsi_device *sdev = to_scsi_device(dev); | ||
| 169 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | 208 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
| 209 | int (*cb)(struct device *) = pm ? pm->runtime_resume : NULL; | ||
| 210 | |||
| 211 | if (sdev->request_queue->dev) | ||
| 212 | return sdev_blk_runtime_resume(sdev, cb); | ||
| 213 | else | ||
| 214 | return scsi_dev_type_resume(dev, cb); | ||
| 215 | } | ||
| 216 | |||
| 217 | static int scsi_runtime_resume(struct device *dev) | ||
| 218 | { | ||
| 219 | int err = 0; | ||
| 170 | 220 | ||
| 171 | dev_dbg(dev, "scsi_runtime_resume\n"); | 221 | dev_dbg(dev, "scsi_runtime_resume\n"); |
| 172 | if (scsi_is_sdev_device(dev)) | 222 | if (scsi_is_sdev_device(dev)) |
| 173 | err = scsi_dev_type_resume(dev, pm ? pm->runtime_resume : NULL); | 223 | err = sdev_runtime_resume(dev); |
| 174 | 224 | ||
| 175 | /* Insert hooks here for targets, hosts, and transport classes */ | 225 | /* Insert hooks here for targets, hosts, and transport classes */ |
| 176 | 226 | ||
| @@ -185,10 +235,18 @@ static int scsi_runtime_idle(struct device *dev) | |||
| 185 | 235 | ||
| 186 | /* Insert hooks here for targets, hosts, and transport classes */ | 236 | /* Insert hooks here for targets, hosts, and transport classes */ |
| 187 | 237 | ||
| 188 | if (scsi_is_sdev_device(dev)) | 238 | if (scsi_is_sdev_device(dev)) { |
| 189 | err = pm_schedule_suspend(dev, 100); | 239 | struct scsi_device *sdev = to_scsi_device(dev); |
| 190 | else | 240 | |
| 241 | if (sdev->request_queue->dev) { | ||
| 242 | pm_runtime_mark_last_busy(dev); | ||
| 243 | err = pm_runtime_autosuspend(dev); | ||
| 244 | } else { | ||
| 245 | err = pm_runtime_suspend(dev); | ||
| 246 | } | ||
| 247 | } else { | ||
| 191 | err = pm_runtime_suspend(dev); | 248 | err = pm_runtime_suspend(dev); |
| 249 | } | ||
| 192 | return err; | 250 | return err; |
| 193 | } | 251 | } |
| 194 | 252 | ||
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 196240dcf26e..c1c555242d0d 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
| @@ -1136,10 +1136,6 @@ static int sd_open(struct block_device *bdev, fmode_t mode) | |||
| 1136 | 1136 | ||
| 1137 | sdev = sdkp->device; | 1137 | sdev = sdkp->device; |
| 1138 | 1138 | ||
| 1139 | retval = scsi_autopm_get_device(sdev); | ||
| 1140 | if (retval) | ||
| 1141 | goto error_autopm; | ||
| 1142 | |||
| 1143 | /* | 1139 | /* |
| 1144 | * If the device is in error recovery, wait until it is done. | 1140 | * If the device is in error recovery, wait until it is done. |
| 1145 | * If the device is offline, then disallow any access to it. | 1141 | * If the device is offline, then disallow any access to it. |
| @@ -1184,8 +1180,6 @@ static int sd_open(struct block_device *bdev, fmode_t mode) | |||
| 1184 | return 0; | 1180 | return 0; |
| 1185 | 1181 | ||
| 1186 | error_out: | 1182 | error_out: |
| 1187 | scsi_autopm_put_device(sdev); | ||
| 1188 | error_autopm: | ||
| 1189 | scsi_disk_put(sdkp); | 1183 | scsi_disk_put(sdkp); |
| 1190 | return retval; | ||
