USB: make usbdevices export their device nodes instead of using a separate class
o The "real" usb-devices export now a device node which can populate /dev/bus/usb. o The usb_device class is optional now and can be disabled in the kernel config. Major/minor of the "real" devices and class devices are the same. o The environment of the usb-device event contains DEVNUM and BUSNUM to help udev and get rid of the ugly udev rule we need for the class devices. o The usb-devices and usb-interfaces share the same bus, so I used the new "struct device_type" to let these devices identify themselves. This also removes the current logic of using a magic platform-pointer. The name of the device_type is also added to the environment which makes it easier to distinguish the different kinds of devices on the same subsystem. It looks like this: add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1 ACTION=add DEVPATH=/devices/pci0000:00/0000:00:1d.1/usb2/2-1 SUBSYSTEM=usb SEQNUM=1533 MAJOR=189 MINOR=131 DEVTYPE=usb_device PRODUCT=46d/c03e/2000 TYPE=0/0/0 BUSNUM=002 DEVNUM=004 This udev rule works as a replacement for usb_device class devices: SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", \ NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0644" Updated patch, which needs the device_type patches in Greg's tree. I also got a bugzilla assigned for this. :) https://bugzilla.novell.com/show_bug.cgi?id=250659 Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
8784028963
commit
9f8b17e643
@@ -1305,7 +1305,7 @@ int usb_reset_configuration(struct usb_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void release_interface(struct device *dev)
|
||||
void usb_release_interface(struct device *dev)
|
||||
{
|
||||
struct usb_interface *intf = to_usb_interface(dev);
|
||||
struct usb_interface_cache *intfc =
|
||||
@@ -1315,6 +1315,67 @@ static void release_interface(struct device *dev)
|
||||
kfree(intf);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
static int usb_if_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
{
|
||||
struct usb_device *usb_dev;
|
||||
struct usb_interface *intf;
|
||||
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);
|
||||
|
||||
intf = to_usb_interface(dev);
|
||||
usb_dev = interface_to_usbdev(intf);
|
||||
alt = intf->cur_altsetting;
|
||||
|
||||
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_if_uevent(struct device *dev, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif /* CONFIG_HOTPLUG */
|
||||
|
||||
struct device_type usb_if_device_type = {
|
||||
.name = "usb_interface",
|
||||
.release = usb_release_interface,
|
||||
.uevent = usb_if_uevent,
|
||||
};
|
||||
|
||||
/*
|
||||
* usb_set_configuration - Makes a particular device setting be current
|
||||
* @dev: the device whose configuration is being updated
|
||||
@@ -1478,8 +1539,8 @@ free_interfaces:
|
||||
intf->dev.parent = &dev->dev;
|
||||
intf->dev.driver = NULL;
|
||||
intf->dev.bus = &usb_bus_type;
|
||||
intf->dev.type = &usb_if_device_type;
|
||||
intf->dev.dma_mask = dev->dev.dma_mask;
|
||||
intf->dev.release = release_interface;
|
||||
device_initialize (&intf->dev);
|
||||
mark_quiesced(intf);
|
||||
sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d",
|
||||
|
Reference in New Issue
Block a user