As well as updating some internal docs so they're current, this patch adds the physical path to the data available through hotplugging. This feature was requested at the LinuxKongress hotplug BOF, and was also on my 2.5 list.
This allows hotplugging to use logic based on the same kind of external connection labeling that's always been available for, say, serial or pallel ports: configure the device on port A in this way, differently from the device on port B. Without access to physical IDs, many devices can't really be distinguished from each other. Examples include multiple identical UPS devices, storage devices, keypads, and so on. Please merge to Linus' latest. This functionality can also be added to 2.4.20 (or later) kernels. - Dave
--- ./drivers/usb-dist/core/usb.c Wed Oct 30 15:52:12 2002 +++ ./drivers/usb/core/usb.c Wed Nov 6 11:36:36 2002 @@ -514,17 +514,10 @@ * 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. + * 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_hotplug (struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) @@ -562,6 +555,18 @@ scratch = buffer; + /* NOTE: add any new parameters using USB_* names. */ + + /* always pass "physical" path to the usb gadget */ + envp [i++] = scratch; + length += snprintf (scratch, buffer_size - length, + "USB_PATH=usb-%s-%s", + usb_dev->bus->bus_name, usb_dev->devpath); + if ((buffer_size - length <= 0) || (i >= num_envp)) + return -ENOMEM; + ++length; + scratch += length; + #ifdef CONFIG_USB_DEVICEFS /* If this is available, userspace programs can directly read * all the device descriptors we don't tell them about. Or @@ -579,7 +584,7 @@ scratch += length; #endif - /* per-device configuration hacks are common */ + /* per-device configurations are common */ envp [i++] = scratch; length += snprintf (scratch, buffer_size - length, "PRODUCT=%x/%x/%x", usb_dev->descriptor.idVendor, @@ -604,10 +609,9 @@ 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. - * everything needs a smart agent and usbfs; or can rely on - * device-specific binding policies. + /* 2.4 only exposed interface zero. in 2.5, hotplug + * agents are called for all interfaces, and can use + * $DEVPATH/bInterfaceNumber if necessary. */ envp [i++] = scratch; length += snprintf (scratch, buffer_size - length,