]> git.hungrycats.org Git - linux/commitdiff
converted USB to use the driver core's hotplug call.
authorGreg Kroah-Hartman <greg@kroah.com>
Fri, 27 Sep 2002 04:29:36 +0000 (21:29 -0700)
committerGreg Kroah-Hartman <greg@kroah.com>
Fri, 27 Sep 2002 04:29:36 +0000 (21:29 -0700)
drivers/usb/core/usb.c

index 57e32af64aac6a3337a31879707dcef029b82918..57d6faaa621c99615fdff846201fe88053ae3bbd 100644 (file)
@@ -510,57 +510,42 @@ static int usb_device_match (struct device *dev, struct device_driver *drv)
  * cases, we know no other thread can recycle our address, since we must
  * already have been serialized enough to prevent that.
  */
-static void call_policy (char *verb, struct usb_device *dev)
+static int usb_hotplug (struct device *dev, char **envp, int num_envp,
+                       char *buffer, int buffer_size)
 {
-       char *argv [3], **envp, *buf, *scratch;
-       int i = 0, value;
+       struct usb_interface *intf;
+       struct usb_device *usb_dev;
+       char *scratch;
+       int i = 0;
+       int length = 0;
 
-       if (!hotplug_path [0])
-               return;
-       if (in_interrupt ()) {
-               dbg ("In_interrupt");
-               return;
-       }
-       if (!current->fs->root) {
-               /* statically linked USB is initted rather early */
-               dbg ("call_policy %s, num %d -- no FS yet", verb, dev->devnum);
-               return;
-       }
-       if (dev->devnum < 0) {
-               dbg ("device already deleted ??");
-               return;
-       }
-       if (!(envp = (char **) kmalloc (20 * sizeof (char *), GFP_KERNEL))) {
-               dbg ("enomem");
-               return;
-       }
-       if (!(buf = kmalloc (256, GFP_KERNEL))) {
-               kfree (envp);
-               dbg ("enomem2");
-               return;
-       }
+       dbg ("%s", __FUNCTION__);
 
-       /* only one standardized param to hotplug command: type */
-       argv [0] = hotplug_path;
-       argv [1] = "usb";
-       argv [2] = 0;
+       if (!dev)
+               return -ENODEV;
 
-       /* minimal command environment */
-       envp [i++] = "HOME=/";
-       envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+       /* check for generic driver, we do not call do hotplug calls for it */
+       if (dev->driver == &usb_generic_driver)
+               return -ENODEV;
 
-#ifdef DEBUG
-       /* hint that policy agent should enter no-stdout debug mode */
-       envp [i++] = "DEBUG=kernel";
-#endif
-       /* extensible set of named bus-specific parameters,
-        * supporting multiple driver selection algorithms.
-        */
-       scratch = buf;
+       intf = to_usb_interface(dev);
+       if (!intf)
+               return -ENODEV;
 
-       /* action:  add, remove */
-       envp [i++] = scratch;
-       scratch += sprintf (scratch, "ACTION=%s", verb) + 1;
+       usb_dev = interface_to_usbdev (intf);
+       if (!usb_dev)
+               return -ENODEV;
+       
+       if (usb_dev->devnum < 0) {
+               dbg ("device already deleted ??");
+               return -ENODEV;
+       }
+       if (!usb_dev->bus) {
+               dbg ("bus already removed?");
+               return -ENODEV;
+       }
+
+       scratch = buffer;
 
 #ifdef CONFIG_USB_DEVICEFS
        /* If this is available, userspace programs can directly read
@@ -569,27 +554,48 @@ static void call_policy (char *verb, struct usb_device *dev)
         *
         * FIXME reduce hardwired intelligence here
         */
-       envp [i++] = "DEVFS=/proc/bus/usb";
        envp [i++] = scratch;
-       scratch += sprintf (scratch, "DEVICE=/proc/bus/usb/%03d/%03d",
-               dev->bus->busnum, dev->devnum) + 1;
+       length += snprintf (scratch, buffer_size - length,
+                           "%s", "DEVFS=/proc/bus/usb");
+       if ((buffer_size - length <= 0) || (i >= num_envp))
+               return -ENOMEM;
+       ++length;
+       scratch += length;
+
+       envp [i++] = scratch;
+       length += snprintf (scratch, buffer_size - length,
+                           "DEVICE=/proc/bus/usb/%03d/%03d",
+                           usb_dev->bus->busnum, usb_dev->devnum);
+       if ((buffer_size - length <= 0) || (i >= num_envp))
+               return -ENOMEM;
+       ++length;
+       scratch += length;
 #endif
 
        /* per-device configuration hacks are common */
        envp [i++] = scratch;
-       scratch += sprintf (scratch, "PRODUCT=%x/%x/%x",
-               dev->descriptor.idVendor,
-               dev->descriptor.idProduct,
-               dev->descriptor.bcdDevice) + 1;
+       length += snprintf (scratch, buffer_size - length, "PRODUCT=%x/%x/%x",
+                           usb_dev->descriptor.idVendor,
+                           usb_dev->descriptor.idProduct,
+                           usb_dev->descriptor.bcdDevice);
+       if ((buffer_size - length <= 0) || (i >= num_envp))
+               return -ENOMEM;
+       ++length;
+       scratch += length;
 
        /* class-based driver binding models */
        envp [i++] = scratch;
-       scratch += sprintf (scratch, "TYPE=%d/%d/%d",
-                           dev->descriptor.bDeviceClass,
-                           dev->descriptor.bDeviceSubClass,
-                           dev->descriptor.bDeviceProtocol) + 1;
-       if (dev->descriptor.bDeviceClass == 0) {
-               int alt = dev->actconfig->interface [0].act_altsetting;
+       length += snprintf (scratch, buffer_size - length, "TYPE=%d/%d/%d",
+                           usb_dev->descriptor.bDeviceClass,
+                           usb_dev->descriptor.bDeviceSubClass,
+                           usb_dev->descriptor.bDeviceProtocol);
+       if ((buffer_size - length <= 0) || (i >= num_envp))
+               return -ENOMEM;
+       ++length;
+       scratch += length;
+
+       if (usb_dev->descriptor.bDeviceClass == 0) {
+               int alt = intf->act_altsetting;
 
                /* a simple/common case: one config, one interface, one driver
                 * with current altsetting being a reasonable setting.
@@ -597,31 +603,29 @@ static void call_policy (char *verb, struct usb_device *dev)
                 * device-specific binding policies.
                 */
                envp [i++] = scratch;
-               scratch += sprintf (scratch, "INTERFACE=%d/%d/%d",
-                       dev->actconfig->interface [0].altsetting [alt].bInterfaceClass,
-                       dev->actconfig->interface [0].altsetting [alt].bInterfaceSubClass,
-                       dev->actconfig->interface [0].altsetting [alt].bInterfaceProtocol)
-                       + 1;
-               /* INTERFACE-0, INTERFACE-1, ... ? */
+               length += snprintf (scratch, buffer_size - length,
+                                   "INTERFACE=%d/%d/%d",
+                                   intf->altsetting[alt].bInterfaceClass,
+                                   intf->altsetting[alt].bInterfaceSubClass,
+                                   intf->altsetting[alt].bInterfaceProtocol);
+               if ((buffer_size - length <= 0) || (i >= num_envp))
+                       return -ENOMEM;
+               ++length;
+               scratch += length;
+
        }
        envp [i++] = 0;
-       /* assert: (scratch - buf) < sizeof buf */
 
-       /* NOTE: user mode daemons can call the agents too */
-
-       dbg ("kusbd: %s %s %d", argv [0], verb, dev->devnum);
-       value = call_usermodehelper (argv [0], argv, envp);
-       kfree (buf);
-       kfree (envp);
-       if (value != 0)
-               dbg ("kusbd policy returned 0x%x", value);
+       return 0;
 }
 
 #else
 
-static inline void
-call_policy (char *verb, struct usb_device *dev)
-{ } 
+static int usb_hotplug (struct device *dev, char **envp,
+                       char *buffer, int buffer_size)
+{
+       return -ENODEV;
+}
 
 #endif /* CONFIG_HOTPLUG */
 
@@ -894,9 +898,6 @@ void usb_disconnect(struct usb_device **pdev)
                put_device(&dev->dev);
        }
 
-       /* Let policy agent unload modules etc */
-       call_policy ("remove", dev);
-
        /* Decrement the reference count, it'll auto free everything when */
        /* it hits 0 which could very well be now */
        usb_put_dev(dev);
@@ -1174,9 +1175,6 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
        /* add a /proc/bus/usb entry */
        usbfs_add_device(dev);
 
-       /* userspace may load modules and/or configure further */
-       call_policy ("add", dev);
-
        return 0;
 }
 
@@ -1439,6 +1437,7 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe,
 struct bus_type usb_bus_type = {
        .name =         "usb",
        .match =        usb_device_match,
+       .hotplug =      usb_hotplug,
 };
 
 /*