diff options
| -rw-r--r-- | drivers/usb/storage/scsiglue.c | 13 | ||||
| -rw-r--r-- | drivers/usb/storage/usb.c | 27 |
2 files changed, 29 insertions, 11 deletions
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 1ba19eaa1970..47e56079925d 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c | |||
| @@ -285,10 +285,15 @@ static int device_reset(struct scsi_cmnd *srb) | |||
| 285 | 285 | ||
| 286 | US_DEBUGP("%s called\n", __FUNCTION__); | 286 | US_DEBUGP("%s called\n", __FUNCTION__); |
| 287 | 287 | ||
| 288 | /* lock the device pointers and do the reset */ | 288 | result = usb_autopm_get_interface(us->pusb_intf); |
| 289 | mutex_lock(&(us->dev_mutex)); | 289 | if (result == 0) { |
| 290 | result = us->transport_reset(us); | 290 | |
| 291 | mutex_unlock(&us->dev_mutex); | 291 | /* lock the device pointers and do the reset */ |
| 292 | mutex_lock(&(us->dev_mutex)); | ||
| 293 | result = us->transport_reset(us); | ||
| 294 | mutex_unlock(&us->dev_mutex); | ||
| 295 | usb_autopm_put_interface(us->pusb_intf); | ||
| 296 | } | ||
| 292 | 297 | ||
| 293 | return result < 0 ? FAILED : SUCCESS; | 298 | return result < 0 ? FAILED : SUCCESS; |
| 294 | } | 299 | } |
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index cf3fc91234e7..bef8bcd9bd98 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
| @@ -191,16 +191,14 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message) | |||
| 191 | { | 191 | { |
| 192 | struct us_data *us = usb_get_intfdata(iface); | 192 | struct us_data *us = usb_get_intfdata(iface); |
| 193 | 193 | ||
| 194 | US_DEBUGP("%s\n", __FUNCTION__); | ||
| 195 | |||
| 194 | /* Wait until no command is running */ | 196 | /* Wait until no command is running */ |
| 195 | mutex_lock(&us->dev_mutex); | 197 | mutex_lock(&us->dev_mutex); |
| 196 | 198 | ||
| 197 | US_DEBUGP("%s\n", __FUNCTION__); | ||
| 198 | if (us->suspend_resume_hook) | 199 | if (us->suspend_resume_hook) |
| 199 | (us->suspend_resume_hook)(us, US_SUSPEND); | 200 | (us->suspend_resume_hook)(us, US_SUSPEND); |
| 200 | 201 | ||
| 201 | /* When runtime PM is working, we'll set a flag to indicate | ||
| 202 | * whether we should autoresume when a SCSI request arrives. */ | ||
| 203 | |||
| 204 | mutex_unlock(&us->dev_mutex); | 202 | mutex_unlock(&us->dev_mutex); |
| 205 | return 0; | 203 | return 0; |
| 206 | } | 204 | } |
| @@ -209,13 +207,11 @@ static int storage_resume(struct usb_interface *iface) | |||
| 209 | { | 207 | { |
| 210 | struct us_data *us = usb_get_intfdata(iface); | 208 | struct us_data *us = usb_get_intfdata(iface); |
| 211 | 209 | ||
| 212 | mutex_lock(&us->dev_mutex); | ||
| 213 | |||
| 214 | US_DEBUGP("%s\n", __FUNCTION__); | 210 | US_DEBUGP("%s\n", __FUNCTION__); |
| 211 | |||
| 215 | if (us->suspend_resume_hook) | 212 | if (us->suspend_resume_hook) |
| 216 | (us->suspend_resume_hook)(us, US_RESUME); | 213 | (us->suspend_resume_hook)(us, US_RESUME); |
| 217 | 214 | ||
| 218 | mutex_unlock(&us->dev_mutex); | ||
| 219 | return 0; | 215 | return 0; |
| 220 | } | 216 | } |
| 221 | 217 | ||
| @@ -313,6 +309,7 @@ static int usb_stor_control_thread(void * __us) | |||
| 313 | { | 309 | { |
| 314 | struct us_data *us = (struct us_data *)__us; | 310 | struct us_data *us = (struct us_data *)__us; |
| 315 | struct Scsi_Host *host = us_to_host(us); | 311 | struct Scsi_Host *host = us_to_host(us); |
| 312 | int autopm_rc; | ||
| 316 | 313 | ||
| 317 | current->flags |= PF_NOFREEZE; | 314 | current->flags |= PF_NOFREEZE; |
| 318 | 315 | ||
| @@ -323,6 +320,9 @@ static int usb_stor_control_thread(void * __us) | |||
| 323 | 320 | ||
| 324 | US_DEBUGP("*** thread awakened.\n"); | 321 | US_DEBUGP("*** thread awakened.\n"); |
| 325 | 322 | ||
| 323 | /* Autoresume the device */ | ||
| 324 | autopm_rc = usb_autopm_get_interface(us->pusb_intf); | ||
| 325 | |||
| 326 | /* lock the device pointers */ | 326 | /* lock the device pointers */ |
| 327 | mutex_lock(&(us->dev_mutex)); | 327 | mutex_lock(&(us->dev_mutex)); |
| 328 | 328 | ||
| @@ -381,6 +381,12 @@ static int usb_stor_control_thread(void * __us) | |||
| 381 | us->srb->result = SAM_STAT_GOOD; | 381 | us->srb->result = SAM_STAT_GOOD; |
| 382 | } | 382 | } |
| 383 | 383 | ||
| 384 | /* Did the autoresume fail? */ | ||
| 385 | else if (autopm_rc < 0) { | ||
| 386 | US_DEBUGP("Could not wake device\n"); | ||
| 387 | us->srb->result = DID_ERROR << 16; | ||
| 388 | } | ||
| 389 | |||
| 384 | /* we've got a command, let's do it! */ | 390 | /* we've got a command, let's do it! */ |
| 385 | else { | 391 | else { |
| 386 | US_DEBUG(usb_stor_show_command(us->srb)); | 392 | US_DEBUG(usb_stor_show_command(us->srb)); |
| @@ -423,6 +429,10 @@ SkipForAbort: | |||
| 423 | 429 | ||
| 424 | /* unlock the device pointers */ | 430 | /* unlock the device pointers */ |
| 425 | mutex_unlock(&us->dev_mutex); | 431 | mutex_unlock(&us->dev_mutex); |
| 432 | |||
| 433 | /* Start an autosuspend */ | ||
| 434 | if (autopm_rc == 0) | ||
| 435 | usb_autopm_put_interface(us->pusb_intf); | ||
| 426 | } /* for (;;) */ | 436 | } /* for (;;) */ |
| 427 | 437 | ||
| 428 | /* Wait until we are told to stop */ | 438 | /* Wait until we are told to stop */ |
| @@ -939,6 +949,7 @@ retry: | |||
| 939 | } | 949 | } |
| 940 | 950 | ||
| 941 | scsi_host_put(us_to_host(us)); | 951 | scsi_host_put(us_to_host(us)); |
| 952 | usb_autopm_put_interface(us->pusb_intf); | ||
| 942 | complete_and_exit(&threads_gone, 0); | 953 | complete_and_exit(&threads_gone, 0); |
| 943 | } | 954 | } |
| 944 | 955 | ||
| @@ -1028,6 +1039,7 @@ static int storage_probe(struct usb_interface *intf, | |||
| 1028 | * start it up. */ | 1039 | * start it up. */ |
| 1029 | scsi_host_get(us_to_host(us)); | 1040 | scsi_host_get(us_to_host(us)); |
| 1030 | atomic_inc(&total_threads); | 1041 | atomic_inc(&total_threads); |
| 1042 | usb_autopm_get_interface(intf); /* dropped in the scanning thread */ | ||
| 1031 | wake_up_process(th); | 1043 | wake_up_process(th); |
| 1032 | 1044 | ||
| 1033 | return 0; | 1045 | return 0; |
| @@ -1065,6 +1077,7 @@ static struct usb_driver usb_storage_driver = { | |||
| 1065 | .pre_reset = storage_pre_reset, | 1077 | .pre_reset = storage_pre_reset, |
| 1066 | .post_reset = storage_post_reset, | 1078 | .post_reset = storage_post_reset, |
| 1067 | .id_table = storage_usb_ids, | 1079 | .id_table = storage_usb_ids, |
| 1080 | .supports_autosuspend = 1, | ||
| 1068 | }; | 1081 | }; |
| 1069 | 1082 | ||
| 1070 | static int __init usb_stor_init(void) | 1083 | static int __init usb_stor_init(void) |
