usbcore: move code among source files
authorAlan Stern <stern@rowland.harvard.edu>
Sun, 2 Jul 2006 02:08:06 +0000 (22:08 -0400)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 27 Sep 2006 18:58:50 +0000 (11:58 -0700)
This revised patch (as713b) moves a few routines among source files in
usbcore.  Some driver-related code in usb.c (claiming interfaces and
matching IDs) is moved to driver.c, where it belongs.  Also the
usb_generic stuff in driver.c is moved to a new source file: generic.c.
(That's the reason for revising the patch.)  Although not very big now,
it will get bigger in a later patch.

None of the code has been changed; it has only been re-arranged.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/core/Makefile
drivers/usb/core/driver.c
drivers/usb/core/generic.c [new file with mode: 0644]
drivers/usb/core/usb.c
drivers/usb/core/usb.h

index ec510922af63a1fac195a022b1347ff4d2624c78..34e9bac319b4e5af731727e5da58907f28612a61 100644 (file)
@@ -4,7 +4,7 @@
 
 usbcore-objs   := usb.o hub.o hcd.o urb.o message.o driver.o \
                        config.o file.o buffer.o sysfs.o endpoint.o \
-                       devio.o notify.o
+                       devio.o notify.o generic.o
 
 ifeq ($(CONFIG_PCI),y)
        usbcore-objs    += hcd-pci.o
index ec8906501415b38cac0298e52194874ff58a1c2f..8dcf2cd0c569afb54c290516c2bd50016dd0b9f6 100644 (file)
@@ -17,7 +17,8 @@
  *
  * NOTE! This is not actually a driver at all, rather this is
  * just a collection of helper routines that implement the
- * generic USB things that the real drivers can use..
+ * matching, probing, releasing, suspending and resuming for
+ * real drivers.
  *
  */
 
@@ -34,38 +35,6 @@ struct usb_dynid {
        struct usb_device_id id;
 };
 
-
-static int generic_probe(struct device *dev)
-{
-       return 0;
-}
-static int generic_remove(struct device *dev)
-{
-       struct usb_device *udev = to_usb_device(dev);
-
-       /* if this is only an unbind, not a physical disconnect, then
-        * unconfigure the device */
-       if (udev->state == USB_STATE_CONFIGURED)
-               usb_set_configuration(udev, 0);
-
-       /* in case the call failed or the device was suspended */
-       if (udev->state >= USB_STATE_CONFIGURED)
-               usb_disable_device(udev, 0);
-       return 0;
-}
-
-struct device_driver usb_generic_driver = {
-       .owner = THIS_MODULE,
-       .name = "usb",
-       .bus = &usb_bus_type,
-       .probe = generic_probe,
-       .remove = generic_remove,
-};
-
-/* Fun hack to determine if the struct device is a
- * usb device or a usb interface. */
-int usb_generic_driver_data;
-
 #ifdef CONFIG_HOTPLUG
 
 /*
@@ -238,6 +207,89 @@ static int usb_unbind_interface(struct device *dev)
        return 0;
 }
 
+/**
+ * usb_driver_claim_interface - bind a driver to an interface
+ * @driver: the driver to be bound
+ * @iface: the interface to which it will be bound; must be in the
+ *     usb device's active configuration
+ * @priv: driver data associated with that interface
+ *
+ * This is used by usb device drivers that need to claim more than one
+ * interface on a device when probing (audio and acm are current examples).
+ * No device driver should directly modify internal usb_interface or
+ * usb_device structure members.
+ *
+ * Few drivers should need to use this routine, since the most natural
+ * way to bind to an interface is to return the private data from
+ * the driver's probe() method.
+ *
+ * Callers must own the device lock and the driver model's usb_bus_type.subsys
+ * writelock.  So driver probe() entries don't need extra locking,
+ * but other call contexts may need to explicitly claim those locks.
+ */
+int usb_driver_claim_interface(struct usb_driver *driver,
+                               struct usb_interface *iface, void* priv)
+{
+       struct device *dev = &iface->dev;
+
+       if (dev->driver)
+               return -EBUSY;
+
+       dev->driver = &driver->driver;
+       usb_set_intfdata(iface, priv);
+       iface->condition = USB_INTERFACE_BOUND;
+       mark_active(iface);
+
+       /* if interface was already added, bind now; else let
+        * the future device_add() bind it, bypassing probe()
+        */
+       if (device_is_registered(dev))
+               device_bind_driver(dev);
+
+       return 0;
+}
+EXPORT_SYMBOL(usb_driver_claim_interface);
+
+/**
+ * usb_driver_release_interface - unbind a driver from an interface
+ * @driver: the driver to be unbound
+ * @iface: the interface from which it will be unbound
+ *
+ * This can be used by drivers to release an interface without waiting
+ * for their disconnect() methods to be called.  In typical cases this
+ * also causes the driver disconnect() method to be called.
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
+ * Callers must own the device lock and the driver model's usb_bus_type.subsys
+ * writelock.  So driver disconnect() entries don't need extra locking,
+ * but other call contexts may need to explicitly claim those locks.
+ */
+void usb_driver_release_interface(struct usb_driver *driver,
+                                       struct usb_interface *iface)
+{
+       struct device *dev = &iface->dev;
+
+       /* this should never happen, don't release something that's not ours */
+       if (!dev->driver || dev->driver != &driver->driver)
+               return;
+
+       /* don't release from within disconnect() */
+       if (iface->condition != USB_INTERFACE_BOUND)
+               return;
+
+       /* don't release if the interface hasn't been added yet */
+       if (device_is_registered(dev)) {
+               iface->condition = USB_INTERFACE_UNBINDING;
+               device_release_driver(dev);
+       }
+
+       dev->driver = NULL;
+       usb_set_intfdata(iface, NULL);
+       iface->condition = USB_INTERFACE_UNBOUND;
+       mark_quiesced(iface);
+}
+EXPORT_SYMBOL(usb_driver_release_interface);
+
 /* returns 0 if no match, 1 if match */
 static int usb_match_one_id(struct usb_interface *interface,
                            const struct usb_device_id *id)
@@ -402,6 +454,120 @@ int usb_device_match(struct device *dev, struct device_driver *drv)
        return 0;
 }
 
+#ifdef CONFIG_HOTPLUG
+
+/*
+ * This sends an uevent to userspace, typically helping to load driver
+ * or other modules, configure the device, and more.  Drivers can provide
+ * a MODULE_DEVICE_TABLE to help with module loading subtasks.
+ *
+ * We're called either from khubd (the typical case) or from root hub
+ * (init, kapmd, modprobe, rmmod, etc), but the agents need to handle
+ * delays in event delivery.  Use sysfs (and DEVPATH) to make sure the
+ * device (and this configuration!) are still present.
+ */
+static int usb_uevent(struct device *dev, char **envp, int num_envp,
+                     char *buffer, int buffer_size)
+{
+       struct usb_interface *intf;
+       struct usb_device *usb_dev;
+       struct usb_host_interface *alt;
+       int i = 0;
+       int length = 0;
+
+       if (!dev)
+               return -ENODEV;
+
+       /* driver is often null here; dev_dbg() would oops */
+       pr_debug ("usb %s: uevent\n", dev->bus_id);
+
+       /* Must check driver_data here, as on remove driver is always NULL */
+       if ((dev->driver == &usb_generic_driver) ||
+           (dev->driver_data == &usb_generic_driver_data))
+               return 0;
+
+       intf = to_usb_interface(dev);
+       usb_dev = interface_to_usbdev (intf);
+       alt = intf->cur_altsetting;
+
+       if (usb_dev->devnum < 0) {
+               pr_debug ("usb %s: already deleted?\n", dev->bus_id);
+               return -ENODEV;
+       }
+       if (!usb_dev->bus) {
+               pr_debug ("usb %s: bus removed?\n", dev->bus_id);
+               return -ENODEV;
+       }
+
+#ifdef CONFIG_USB_DEVICEFS
+       /* If this is available, userspace programs can directly read
+        * all the device descriptors we don't tell them about.  Or
+        * even act as usermode drivers.
+        *
+        * FIXME reduce hardwired intelligence here
+        */
+       if (add_uevent_var(envp, num_envp, &i,
+                          buffer, buffer_size, &length,
+                          "DEVICE=/proc/bus/usb/%03d/%03d",
+                          usb_dev->bus->busnum, usb_dev->devnum))
+               return -ENOMEM;
+#endif
+
+       /* per-device configurations are common */
+       if (add_uevent_var(envp, num_envp, &i,
+                          buffer, buffer_size, &length,
+                          "PRODUCT=%x/%x/%x",
+                          le16_to_cpu(usb_dev->descriptor.idVendor),
+                          le16_to_cpu(usb_dev->descriptor.idProduct),
+                          le16_to_cpu(usb_dev->descriptor.bcdDevice)))
+               return -ENOMEM;
+
+       /* class-based driver binding models */
+       if (add_uevent_var(envp, num_envp, &i,
+                          buffer, buffer_size, &length,
+                          "TYPE=%d/%d/%d",
+                          usb_dev->descriptor.bDeviceClass,
+                          usb_dev->descriptor.bDeviceSubClass,
+                          usb_dev->descriptor.bDeviceProtocol))
+               return -ENOMEM;
+
+       if (add_uevent_var(envp, num_envp, &i,
+                          buffer, buffer_size, &length,
+                          "INTERFACE=%d/%d/%d",
+                          alt->desc.bInterfaceClass,
+                          alt->desc.bInterfaceSubClass,
+                          alt->desc.bInterfaceProtocol))
+               return -ENOMEM;
+
+       if (add_uevent_var(envp, num_envp, &i,
+                          buffer, buffer_size, &length,
+                          "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
+                          le16_to_cpu(usb_dev->descriptor.idVendor),
+                          le16_to_cpu(usb_dev->descriptor.idProduct),
+                          le16_to_cpu(usb_dev->descriptor.bcdDevice),
+                          usb_dev->descriptor.bDeviceClass,
+                          usb_dev->descriptor.bDeviceSubClass,
+                          usb_dev->descriptor.bDeviceProtocol,
+                          alt->desc.bInterfaceClass,
+                          alt->desc.bInterfaceSubClass,
+                          alt->desc.bInterfaceProtocol))
+               return -ENOMEM;
+
+       envp[i] = NULL;
+
+       return 0;
+}
+
+#else
+
+static int usb_uevent(struct device *dev, char **envp,
+                       int num_envp, char *buffer, int buffer_size)
+{
+       return -ENODEV;
+}
+
+#endif /* CONFIG_HOTPLUG */
+
 /**
  * usb_register_driver - register a USB driver
  * @new_driver: USB operations for the driver
@@ -469,3 +635,119 @@ void usb_deregister(struct usb_driver *driver)
        usbfs_update_special();
 }
 EXPORT_SYMBOL_GPL_FUTURE(usb_deregister);
+
+#ifdef CONFIG_PM
+
+static int verify_suspended(struct device *dev, void *unused)
+{
+       if (dev->driver == NULL)
+               return 0;
+       return (dev->power.power_state.event == PM_EVENT_ON) ? -EBUSY : 0;
+}
+
+static int usb_generic_suspend(struct device *dev, pm_message_t message)
+{
+       struct usb_interface    *intf;
+       struct usb_driver       *driver;
+       int                     status;
+
+       /* USB devices enter SUSPEND state through their hubs, but can be
+        * marked for FREEZE as soon as their children are already idled.
+        * But those semantics are useless, so we equate the two (sigh).
+        */
+       if (dev->driver == &usb_generic_driver) {
+               if (dev->power.power_state.event == message.event)
+                       return 0;
+               /* we need to rule out bogus requests through sysfs */
+               status = device_for_each_child(dev, NULL, verify_suspended);
+               if (status)
+                       return status;
+               return usb_port_suspend(to_usb_device(dev));
+       }
+
+       if ((dev->driver == NULL) ||
+           (dev->driver_data == &usb_generic_driver_data))
+               return 0;
+
+       intf = to_usb_interface(dev);
+       driver = to_usb_driver(dev->driver);
+
+       /* with no hardware, USB interfaces only use FREEZE and ON states */
+       if (!is_active(intf))
+               return 0;
+
+       if (driver->suspend && driver->resume) {
+               status = driver->suspend(intf, message);
+               if (status)
+                       dev_err(dev, "%s error %d\n", "suspend", status);
+               else
+                       mark_quiesced(intf);
+       } else {
+               // FIXME else if there's no suspend method, disconnect...
+               dev_warn(dev, "no suspend for driver %s?\n", driver->name);
+               mark_quiesced(intf);
+               status = 0;
+       }
+       return status;
+}
+
+static int usb_generic_resume(struct device *dev)
+{
+       struct usb_interface    *intf;
+       struct usb_driver       *driver;
+       struct usb_device       *udev;
+       int                     status;
+
+       if (dev->power.power_state.event == PM_EVENT_ON)
+               return 0;
+
+       /* mark things as "on" immediately, no matter what errors crop up */
+       dev->power.power_state.event = PM_EVENT_ON;
+
+       /* devices resume through their hubs */
+       if (dev->driver == &usb_generic_driver) {
+               udev = to_usb_device(dev);
+               if (udev->state == USB_STATE_NOTATTACHED)
+                       return 0;
+               return usb_port_resume(udev);
+       }
+
+       if ((dev->driver == NULL) ||
+           (dev->driver_data == &usb_generic_driver_data)) {
+               dev->power.power_state.event = PM_EVENT_FREEZE;
+               return 0;
+       }
+
+       intf = to_usb_interface(dev);
+       driver = to_usb_driver(dev->driver);
+
+       udev = interface_to_usbdev(intf);
+       if (udev->state == USB_STATE_NOTATTACHED)
+               return 0;
+
+       /* if driver was suspended, it has a resume method;
+        * however, sysfs can wrongly mark things as suspended
+        * (on the "no suspend method" FIXME path above)
+        */
+       if (driver->resume) {
+               status = driver->resume(intf);
+               if (status) {
+                       dev_err(dev, "%s error %d\n", "resume", status);
+                       mark_quiesced(intf);
+               }
+       } else
+               dev_warn(dev, "no resume for driver %s?\n", driver->name);
+       return 0;
+}
+
+#endif /* CONFIG_PM */
+
+struct bus_type usb_bus_type = {
+       .name =         "usb",
+       .match =        usb_device_match,
+       .uevent =       usb_uevent,
+#ifdef CONFIG_PM
+       .suspend =      usb_generic_suspend,
+       .resume =       usb_generic_resume,
+#endif
+};
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
new file mode 100644 (file)
index 0000000..7bab976
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * drivers/usb/generic.c - generic driver for USB devices (not interfaces)
+ *
+ * (C) Copyright 2005 Greg Kroah-Hartman <gregkh@suse.de>
+ *
+ * based on drivers/usb/usb.c which had the following copyrights:
+ *     (C) Copyright Linus Torvalds 1999
+ *     (C) Copyright Johannes Erdfelt 1999-2001
+ *     (C) Copyright Andreas Gal 1999
+ *     (C) Copyright Gregory P. Smith 1999
+ *     (C) Copyright Deti Fliegl 1999 (new USB architecture)
+ *     (C) Copyright Randy Dunlap 2000
+ *     (C) Copyright David Brownell 2000-2004
+ *     (C) Copyright Yggdrasil Computing, Inc. 2000
+ *             (usb_device_id matching changes by Adam J. Richter)
+ *     (C) Copyright Greg Kroah-Hartman 2002-2003
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/usb.h>
+#include "usb.h"
+
+static int generic_probe(struct device *dev)
+{
+       return 0;
+}
+static int generic_remove(struct device *dev)
+{
+       struct usb_device *udev = to_usb_device(dev);
+
+       /* if this is only an unbind, not a physical disconnect, then
+        * unconfigure the device */
+       if (udev->state == USB_STATE_CONFIGURED)
+               usb_set_configuration(udev, 0);
+
+       /* in case the call failed or the device was suspended */
+       if (udev->state >= USB_STATE_CONFIGURED)
+               usb_disable_device(udev, 0);
+       return 0;
+}
+
+struct device_driver usb_generic_driver = {
+       .owner = THIS_MODULE,
+       .name = "usb",
+       .bus = &usb_bus_type,
+       .probe = generic_probe,
+       .remove = generic_remove,
+};
+
+/* Fun hack to determine if the struct device is a
+ * usb device or a usb interface. */
+int usb_generic_driver_data;
index b28a31b2030830b4b2c7e9e24131feaa1f1b5a4e..0b8c67bcde6076f369452d37260d5349888a1e6e 100644 (file)
@@ -112,87 +112,6 @@ struct usb_host_interface *usb_altnum_to_altsetting(struct usb_interface *intf,
        return NULL;
 }
 
-/**
- * usb_driver_claim_interface - bind a driver to an interface
- * @driver: the driver to be bound
- * @iface: the interface to which it will be bound; must be in the
- *     usb device's active configuration
- * @priv: driver data associated with that interface
- *
- * This is used by usb device drivers that need to claim more than one
- * interface on a device when probing (audio and acm are current examples).
- * No device driver should directly modify internal usb_interface or
- * usb_device structure members.
- *
- * Few drivers should need to use this routine, since the most natural
- * way to bind to an interface is to return the private data from
- * the driver's probe() method.
- *
- * Callers must own the device lock and the driver model's usb_bus_type.subsys
- * writelock.  So driver probe() entries don't need extra locking,
- * but other call contexts may need to explicitly claim those locks.
- */
-int usb_driver_claim_interface(struct usb_driver *driver,
-                               struct usb_interface *iface, void* priv)
-{
-       struct device *dev = &iface->dev;
-
-       if (dev->driver)
-               return -EBUSY;
-
-       dev->driver = &driver->driver;
-       usb_set_intfdata(iface, priv);
-       iface->condition = USB_INTERFACE_BOUND;
-       mark_active(iface);
-
-       /* if interface was already added, bind now; else let
-        * the future device_add() bind it, bypassing probe()
-        */
-       if (device_is_registered(dev))
-               device_bind_driver(dev);
-
-       return 0;
-}
-
-/**
- * usb_driver_release_interface - unbind a driver from an interface
- * @driver: the driver to be unbound
- * @iface: the interface from which it will be unbound
- *
- * This can be used by drivers to release an interface without waiting
- * for their disconnect() methods to be called.  In typical cases this
- * also causes the driver disconnect() method to be called.
- *
- * This call is synchronous, and may not be used in an interrupt context.
- * Callers must own the device lock and the driver model's usb_bus_type.subsys
- * writelock.  So driver disconnect() entries don't need extra locking,
- * but other call contexts may need to explicitly claim those locks.
- */
-void usb_driver_release_interface(struct usb_driver *driver,
-                                       struct usb_interface *iface)
-{
-       struct device *dev = &iface->dev;
-
-       /* this should never happen, don't release something that's not ours */
-       if (!dev->driver || dev->driver != &driver->driver)
-               return;
-
-       /* don't release from within disconnect() */
-       if (iface->condition != USB_INTERFACE_BOUND)
-               return;
-
-       /* don't release if the interface hasn't been added yet */
-       if (device_is_registered(dev)) {
-               iface->condition = USB_INTERFACE_UNBINDING;
-               device_release_driver(dev);
-       }
-
-       dev->driver = NULL;
-       usb_set_intfdata(iface, NULL);
-       iface->condition = USB_INTERFACE_UNBOUND;
-       mark_quiesced(iface);
-}
-
 struct find_interface_arg {
        int minor;
        struct usb_interface *interface;
@@ -234,120 +153,6 @@ struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)
        return argb.interface;
 }
 
-#ifdef CONFIG_HOTPLUG
-
-/*
- * This sends an uevent to userspace, typically helping to load driver
- * or other modules, configure the device, and more.  Drivers can provide
- * a MODULE_DEVICE_TABLE to help with module loading subtasks.
- *
- * We're called either from khubd (the typical case) or from root hub
- * (init, kapmd, modprobe, rmmod, etc), but the agents need to handle
- * delays in event delivery.  Use sysfs (and DEVPATH) to make sure the
- * device (and this configuration!) are still present.
- */
-static int usb_uevent(struct device *dev, char **envp, int num_envp,
-                     char *buffer, int buffer_size)
-{
-       struct usb_interface *intf;
-       struct usb_device *usb_dev;
-       struct usb_host_interface *alt;
-       int i = 0;
-       int length = 0;
-
-       if (!dev)
-               return -ENODEV;
-
-       /* driver is often null here; dev_dbg() would oops */
-       pr_debug ("usb %s: uevent\n", dev->bus_id);
-
-       /* Must check driver_data here, as on remove driver is always NULL */
-       if ((dev->driver == &usb_generic_driver) || 
-           (dev->driver_data == &usb_generic_driver_data))
-               return 0;
-
-       intf = to_usb_interface(dev);
-       usb_dev = interface_to_usbdev (intf);
-       alt = intf->cur_altsetting;
-
-       if (usb_dev->devnum < 0) {
-               pr_debug ("usb %s: already deleted?\n", dev->bus_id);
-               return -ENODEV;
-       }
-       if (!usb_dev->bus) {
-               pr_debug ("usb %s: bus removed?\n", dev->bus_id);
-               return -ENODEV;
-       }
-
-#ifdef CONFIG_USB_DEVICEFS
-       /* If this is available, userspace programs can directly read
-        * all the device descriptors we don't tell them about.  Or
-        * even act as usermode drivers.
-        *
-        * FIXME reduce hardwired intelligence here
-        */
-       if (add_uevent_var(envp, num_envp, &i,
-                          buffer, buffer_size, &length,
-                          "DEVICE=/proc/bus/usb/%03d/%03d",
-                          usb_dev->bus->busnum, usb_dev->devnum))
-               return -ENOMEM;
-#endif
-
-       /* per-device configurations are common */
-       if (add_uevent_var(envp, num_envp, &i,
-                          buffer, buffer_size, &length,
-                          "PRODUCT=%x/%x/%x",
-                          le16_to_cpu(usb_dev->descriptor.idVendor),
-                          le16_to_cpu(usb_dev->descriptor.idProduct),
-                          le16_to_cpu(usb_dev->descriptor.bcdDevice)))
-               return -ENOMEM;
-
-       /* class-based driver binding models */
-       if (add_uevent_var(envp, num_envp, &i,
-                          buffer, buffer_size, &length,
-                          "TYPE=%d/%d/%d",
-                          usb_dev->descriptor.bDeviceClass,
-                          usb_dev->descriptor.bDeviceSubClass,
-                          usb_dev->descriptor.bDeviceProtocol))
-               return -ENOMEM;
-
-       if (add_uevent_var(envp, num_envp, &i,
-                          buffer, buffer_size, &length,
-                          "INTERFACE=%d/%d/%d",
-                          alt->desc.bInterfaceClass,
-                          alt->desc.bInterfaceSubClass,
-                          alt->desc.bInterfaceProtocol))
-               return -ENOMEM;
-
-       if (add_uevent_var(envp, num_envp, &i,
-                          buffer, buffer_size, &length,
-                          "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
-                          le16_to_cpu(usb_dev->descriptor.idVendor),
-                          le16_to_cpu(usb_dev->descriptor.idProduct),
-                          le16_to_cpu(usb_dev->descriptor.bcdDevice),
-                          usb_dev->descriptor.bDeviceClass,
-                          usb_dev->descriptor.bDeviceSubClass,
-                          usb_dev->descriptor.bDeviceProtocol,
-                          alt->desc.bInterfaceClass,
-                          alt->desc.bInterfaceSubClass,
-                          alt->desc.bInterfaceProtocol))
-               return -ENOMEM;
-
-       envp[i] = NULL;
-
-       return 0;
-}
-
-#else
-
-static int usb_uevent(struct device *dev, char **envp,
-                       int num_envp, char *buffer, int buffer_size)
-{
-       return -ENODEV;
-}
-
-#endif /* CONFIG_HOTPLUG */
-
 /**
  * usb_release_dev - free a usb device structure when all users of it are finished.
  * @dev: device that's been disconnected
@@ -990,116 +795,6 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe,
                        usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
 }
 
-static int verify_suspended(struct device *dev, void *unused)
-{
-       if (dev->driver == NULL)
-               return 0;
-       return (dev->power.power_state.event == PM_EVENT_ON) ? -EBUSY : 0;
-}
-
-static int usb_generic_suspend(struct device *dev, pm_message_t message)
-{
-       struct usb_interface    *intf;
-       struct usb_driver       *driver;
-       int                     status;
-
-       /* USB devices enter SUSPEND state through their hubs, but can be
-        * marked for FREEZE as soon as their children are already idled.
-        * But those semantics are useless, so we equate the two (sigh).
-        */
-       if (dev->driver == &usb_generic_driver) {
-               if (dev->power.power_state.event == message.event)
-                       return 0;
-               /* we need to rule out bogus requests through sysfs */
-               status = device_for_each_child(dev, NULL, verify_suspended);
-               if (status)
-                       return status;
-               return usb_port_suspend(to_usb_device(dev));
-       }
-
-       if ((dev->driver == NULL) ||
-           (dev->driver_data == &usb_generic_driver_data))
-               return 0;
-
-       intf = to_usb_interface(dev);
-       driver = to_usb_driver(dev->driver);
-
-       /* with no hardware, USB interfaces only use FREEZE and ON states */
-       if (!is_active(intf))
-               return 0;
-
-       if (driver->suspend && driver->resume) {
-               status = driver->suspend(intf, message);
-               if (status)
-                       dev_err(dev, "%s error %d\n", "suspend", status);
-               else
-                       mark_quiesced(intf);
-       } else {
-               // FIXME else if there's no suspend method, disconnect...
-               dev_warn(dev, "no suspend for driver %s?\n", driver->name);
-               mark_quiesced(intf);
-               status = 0;
-       }
-       return status;
-}
-
-static int usb_generic_resume(struct device *dev)
-{
-       struct usb_interface    *intf;
-       struct usb_driver       *driver;
-       struct usb_device       *udev;
-       int                     status;
-
-       if (dev->power.power_state.event == PM_EVENT_ON)
-               return 0;
-
-       /* mark things as "on" immediately, no matter what errors crop up */
-       dev->power.power_state.event = PM_EVENT_ON;
-
-       /* devices resume through their hubs */
-       if (dev->driver == &usb_generic_driver) {
-               udev = to_usb_device(dev);
-               if (udev->state == USB_STATE_NOTATTACHED)
-                       return 0;
-               return usb_port_resume(udev);
-       }
-
-       if ((dev->driver == NULL) ||
-           (dev->driver_data == &usb_generic_driver_data)) {
-               dev->power.power_state.event = PM_EVENT_FREEZE;
-               return 0;
-       }
-
-       intf = to_usb_interface(dev);
-       driver = to_usb_driver(dev->driver);
-
-       udev = interface_to_usbdev(intf);
-       if (udev->state == USB_STATE_NOTATTACHED)
-               return 0;
-
-       /* if driver was suspended, it has a resume method;
-        * however, sysfs can wrongly mark things as suspended
-        * (on the "no suspend method" FIXME path above)
-        */
-       if (driver->resume) {
-               status = driver->resume(intf);
-               if (status) {
-                       dev_err(dev, "%s error %d\n", "resume", status);
-                       mark_quiesced(intf);
-               }
-       } else
-               dev_warn(dev, "no resume for driver %s?\n", driver->name);
-       return 0;
-}
-
-struct bus_type usb_bus_type = {
-       .name =         "usb",
-       .match =        usb_device_match,
-       .uevent =       usb_uevent,
-       .suspend =      usb_generic_suspend,
-       .resume =       usb_generic_resume,
-};
-
 /* format to disable USB on kernel command line is: nousb */
 __module_param_call("", nousb, param_set_bool, param_get_bool, &nousb, 0444);
 
@@ -1203,8 +898,6 @@ EXPORT_SYMBOL(usb_hub_tt_clear_buffer);
 
 EXPORT_SYMBOL(usb_lock_device_for_reset);
 
-EXPORT_SYMBOL(usb_driver_claim_interface);
-EXPORT_SYMBOL(usb_driver_release_interface);
 EXPORT_SYMBOL(usb_find_interface);
 EXPORT_SYMBOL(usb_ifnum_to_if);
 EXPORT_SYMBOL(usb_altnum_to_altsetting);
index 5a4eff5eec860be918fc82a8ec1b911291ea804a..82d397a6f773c343dc10f5bfb0e457e757b322d5 100644 (file)
@@ -33,9 +33,9 @@ extern void usb_host_cleanup(void);
 extern int usb_port_suspend(struct usb_device *dev);
 extern int usb_port_resume(struct usb_device *dev);
 
+extern struct bus_type usb_bus_type;
 extern struct device_driver usb_generic_driver;
 extern int usb_generic_driver_data;
-extern int usb_device_match(struct device *dev, struct device_driver *drv);
 
 /* Interfaces and their "power state" are owned by usbcore */