]> Pileus Git - ~andy/linux/blobdiff - drivers/usb/storage/usb.c
USB: add reset_resume method
[~andy/linux] / drivers / usb / storage / usb.c
index b8d6031b09750245ce4bdece07ed7528e4a7e6c1..00521f1d6a6b9ce8fed0e567258bfdee22d161fe 100644 (file)
 
 #include <linux/sched.h>
 #include <linux/errno.h>
-#include <linux/suspend.h>
+#include <linux/freezer.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/kthread.h>
 #include <linux/mutex.h>
-#include <linux/utsrelease.h>
+#include <linux/utsname.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -197,7 +197,6 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message)
        US_DEBUGP("%s\n", __FUNCTION__);
        if (us->suspend_resume_hook)
                (us->suspend_resume_hook)(us, US_SUSPEND);
-       iface->dev.power.power_state.event = message.event;
 
        /* When runtime PM is working, we'll set a flag to indicate
         * whether we should autoresume when a SCSI request arrives. */
@@ -215,12 +214,25 @@ static int storage_resume(struct usb_interface *iface)
        US_DEBUGP("%s\n", __FUNCTION__);
        if (us->suspend_resume_hook)
                (us->suspend_resume_hook)(us, US_RESUME);
-       iface->dev.power.power_state.event = PM_EVENT_ON;
 
        mutex_unlock(&us->dev_mutex);
        return 0;
 }
 
+static int storage_reset_resume(struct usb_interface *iface)
+{
+       struct us_data *us = usb_get_intfdata(iface);
+
+       US_DEBUGP("%s\n", __FUNCTION__);
+
+       /* Report the reset to the SCSI core */
+       usb_stor_report_bus_reset(us);
+
+       /* FIXME: Notify the subdrivers that they need to reinitialize
+        * the device */
+       return 0;
+}
+
 #endif /* CONFIG_PM */
 
 /*
@@ -228,7 +240,7 @@ static int storage_resume(struct usb_interface *iface)
  * a USB port reset, whether from this driver or a different one.
  */
 
-static void storage_pre_reset(struct usb_interface *iface)
+static int storage_pre_reset(struct usb_interface *iface)
 {
        struct us_data *us = usb_get_intfdata(iface);
 
@@ -236,22 +248,23 @@ static void storage_pre_reset(struct usb_interface *iface)
 
        /* Make sure no command runs during the reset */
        mutex_lock(&us->dev_mutex);
+       return 0;
 }
 
-static void storage_post_reset(struct usb_interface *iface)
+static int storage_post_reset(struct usb_interface *iface)
 {
        struct us_data *us = usb_get_intfdata(iface);
 
        US_DEBUGP("%s\n", __FUNCTION__);
 
        /* Report the reset to the SCSI core */
-       scsi_lock(us_to_host(us));
        usb_stor_report_bus_reset(us);
-       scsi_unlock(us_to_host(us));
 
        /* FIXME: Notify the subdrivers that they need to reinitialize
         * the device */
+
        mutex_unlock(&us->dev_mutex);
+       return 0;
 }
 
 /*
@@ -547,7 +560,7 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id)
                                idesc->bInterfaceSubClass,
                                idesc->bInterfaceProtocol,
                                msgs[msg],
-                               UTS_RELEASE);
+                               utsname()->release);
        }
 
        return 0;
@@ -731,28 +744,27 @@ static int get_pipes(struct us_data *us)
        struct usb_endpoint_descriptor *ep_int = NULL;
 
        /*
-        * Find the endpoints we need.
+        * Find the first endpoint of each type we need.
         * We are expecting a minimum of 2 endpoints - in and out (bulk).
-        * An optional interrupt is OK (necessary for CBI protocol).
+        * An optional interrupt-in is OK (necessary for CBI protocol).
         * We will ignore any others.
         */
        for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
                ep = &altsetting->endpoint[i].desc;
 
-               /* Is it a BULK endpoint? */
-               if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-                               == USB_ENDPOINT_XFER_BULK) {
-                       /* BULK in or out? */
-                       if (ep->bEndpointAddress & USB_DIR_IN)
-                               ep_in = ep;
-                       else
-                               ep_out = ep;
+               if (usb_endpoint_xfer_bulk(ep)) {
+                       if (usb_endpoint_dir_in(ep)) {
+                               if (!ep_in)
+                                       ep_in = ep;
+                       } else {
+                               if (!ep_out)
+                                       ep_out = ep;
+                       }
                }
 
-               /* Is it an interrupt endpoint? */
-               else if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-                               == USB_ENDPOINT_XFER_INT) {
-                       ep_int = ep;
+               else if (usb_endpoint_is_int_in(ep)) {
+                       if (!ep_int)
+                               ep_int = ep;
                }
        }
 
@@ -1060,6 +1072,7 @@ static struct usb_driver usb_storage_driver = {
 #ifdef CONFIG_PM
        .suspend =      storage_suspend,
        .resume =       storage_resume,
+       .reset_resume = storage_reset_resume,
 #endif
        .pre_reset =    storage_pre_reset,
        .post_reset =   storage_post_reset,