This updates the doc and code to match what's been true since 2.4.0 (!) and keventd, removing some error checks that are now handled lower down as well as making a few messages less confusing ("kusbd" etc).
Please merge to Linus' latest. I think it should also work against the 2.4 tree (with different "-p") and if so, it's worth applying there too. - Dave
--- ./drivers/usb-dist/core/usb.c Mon Jun 3 10:18:29 2002 +++ ./drivers/usb/core/usb.c Thu Jun 27 10:08:21 2002 @@ -754,39 +754,24 @@ /* * USB hotplugging invokes what /proc/sys/kernel/hotplug says * (normally /sbin/hotplug) when USB devices get added or removed. + * May not be called in_interrupt(). * * This invokes a user mode policy agent, 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. * - * Some synchronization is important: removes can't start processing - * before the add-device processing completes, and vice versa. That keeps - * a stack of USB-related identifiers stable while they're in use. If we - * know that agents won't complete after they return (such as by forking - * a process that completes later), it's enough to just waitpid() for the - * agent -- as is currently done. - * - * The reason: we know we're called either from khubd (the typical case) - * or from root hub initialization (init, kapmd, modprobe, etc). In both - * cases, we know no other thread can recycle our address, since we must - * already have been serialized enough to prevent that. + * keventd task sequencing ensures that removes can't start processing + * before the add-device processing completes, and vice versa ... but only + * so far as user mode reporting goes. khubd can process disconnects + * for devices before the hotplug connect event gets reported, since there + * is no synchronization once keventd is given its job. This basically + * means usb hotplug agents need to verify any usbfs names they see. */ static void call_policy (char *verb, struct usb_device *dev) { char *argv [3], **envp, *buf, *scratch; - int i = 0, value; + int i = 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; @@ -854,7 +839,7 @@ /* a simple/common case: one config, one interface, one driver * with current altsetting being a reasonable setting. - * everything needs a smart agent and usbfs; or can rely on + * otherwise needs a smart agent and usbfs; or can rely on * device-specific binding policies. */ envp [i++] = scratch; @@ -870,12 +855,10 @@ /* 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); + dbg ("%s %s %d", argv [0], verb, dev->devnum); + (void) call_usermodehelper (argv [0], argv, envp); kfree (buf); kfree (envp); - if (value != 0) - dbg ("kusbd policy returned 0x%x", value); } #else