aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2013-11-07 02:47:05 -0500
committerSarah Sharp <sarah.a.sharp@linux.intel.com>2014-03-04 18:38:20 -0500
commit0df1f663f32e5dc28cba68375b09bba5eaad103f (patch)
treed4483dde195da1acc258fb1ff7fd26238368da02
parente36e64930cffd94e1c37fdb82f35989384aa946b (diff)
uas: Add suspend/resume support
Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
-rw-r--r--drivers/usb/storage/uas.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index 8023944f2501..7a16ed8e8aac 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -1091,6 +1091,45 @@ static int uas_post_reset(struct usb_interface *intf)
1091 return 0; 1091 return 0;
1092} 1092}
1093 1093
1094static int uas_suspend(struct usb_interface *intf, pm_message_t message)
1095{
1096 struct Scsi_Host *shost = usb_get_intfdata(intf);
1097 struct uas_dev_info *devinfo = (void *)shost->hostdata[0];
1098
1099 /* Wait for any pending requests to complete */
1100 flush_work(&devinfo->work);
1101 if (usb_wait_anchor_empty_timeout(&devinfo->sense_urbs, 5000) == 0) {
1102 shost_printk(KERN_ERR, shost, "%s: timed out\n", __func__);
1103 return -ETIME;
1104 }
1105
1106 return 0;
1107}
1108
1109static int uas_resume(struct usb_interface *intf)
1110{
1111 return 0;
1112}
1113
1114static int uas_reset_resume(struct usb_interface *intf)
1115{
1116 struct Scsi_Host *shost = usb_get_intfdata(intf);
1117 struct uas_dev_info *devinfo = (void *)shost->hostdata[0];
1118 unsigned long flags;
1119
1120 if (uas_configure_endpoints(devinfo) != 0) {
1121 shost_printk(KERN_ERR, shost,
1122 "%s: alloc streams error after reset", __func__);
1123 return -EIO;
1124 }
1125
1126 spin_lock_irqsave(shost->host_lock, flags);
1127 scsi_report_bus_reset(shost, 0);
1128 spin_unlock_irqrestore(shost->host_lock, flags);
1129
1130 return 0;
1131}
1132
1094static void uas_disconnect(struct usb_interface *intf) 1133static void uas_disconnect(struct usb_interface *intf)
1095{ 1134{
1096 struct Scsi_Host *shost = usb_get_intfdata(intf); 1135 struct Scsi_Host *shost = usb_get_intfdata(intf);
@@ -1114,6 +1153,9 @@ static struct usb_driver uas_driver = {
1114 .disconnect = uas_disconnect, 1153 .disconnect = uas_disconnect,
1115 .pre_reset = uas_pre_reset, 1154 .pre_reset = uas_pre_reset,
1116 .post_reset = uas_post_reset, 1155 .post_reset = uas_post_reset,
1156 .suspend = uas_suspend,
1157 .resume = uas_resume,
1158 .reset_resume = uas_reset_resume,
1117 .id_table = uas_usb_ids, 1159 .id_table = uas_usb_ids,
1118}; 1160};
1119 1161