aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2007-03-13 10:59:31 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-04-27 16:28:37 -0400
commit9f8b17e643fe6aa505629658445849397bda4e4f (patch)
tree30c45914f7be9f355db30964323673c7d37080e8 /drivers/usb
parent87840289637e9ea95118ebd76e2e335fdcddd725 (diff)
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>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/Kconfig25
-rw-r--r--drivers/usb/core/devio.c94
-rw-r--r--drivers/usb/core/driver.c58
-rw-r--r--drivers/usb/core/hub.c10
-rw-r--r--drivers/usb/core/inode.c2
-rw-r--r--drivers/usb/core/message.c65
-rw-r--r--drivers/usb/core/usb.c20
-rw-r--r--drivers/usb/core/usb.h14
8 files changed, 176 insertions, 112 deletions
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig
index 2fc0f88a3d86..f493fb1eaa27 100644
--- a/drivers/usb/core/Kconfig
+++ b/drivers/usb/core/Kconfig
@@ -31,7 +31,30 @@ config USB_DEVICEFS
31 For the format of the various /proc/bus/usb/ files, please read 31 For the format of the various /proc/bus/usb/ files, please read
32 <file:Documentation/usb/proc_usb_info.txt>. 32 <file:Documentation/usb/proc_usb_info.txt>.
33 33
34 Most users want to say Y here. 34 Usbfs files can't handle Access Control Lists (ACL), which are the
35 default way to grant access to USB devices for untrusted users of a
36 desktop system. The usbfs functionality is replaced by real
37 device-nodes managed by udev. These nodes live in /dev/bus/usb and
38 are used by libusb.
39
40config USB_DEVICE_CLASS
41 bool "USB device class-devices (DEPRECATED)"
42 depends on USB
43 default n
44 ---help---
45 Userspace access to USB devices is granted by device-nodes exported
46 directly from the usbdev in sysfs. Old versions of the driver
47 core and udev needed additional class devices to export device nodes.
48
49 These additional devices are difficult to handle in userspace, if
50 information about USB interfaces must be available. One device contains
51 the device node, the other device contains the interface data. Both
52 devices are at the same level in sysfs (siblings) and one can't access
53 the other. The device node created directly by the usbdev is the parent
54 device of the interface and therefore easily accessible from the interface
55 event.
56
57 This option provides backward compatibility if needed.
35 58
36config USB_DYNAMIC_MINORS 59config USB_DYNAMIC_MINORS
37 bool "Dynamic USB minor allocation (EXPERIMENTAL)" 60 bool "Dynamic USB minor allocation (EXPERIMENTAL)"
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index fc3545ddb06e..e023f3d56248 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -57,7 +57,6 @@
57 57
58#define USB_MAXBUS 64 58#define USB_MAXBUS 64
59#define USB_DEVICE_MAX USB_MAXBUS * 128 59#define USB_DEVICE_MAX USB_MAXBUS * 128
60static struct class *usb_device_class;
61 60
62/* Mutual exclusion for removal, open, and release */ 61/* Mutual exclusion for removal, open, and release */
63DEFINE_MUTEX(usbfs_mutex); 62DEFINE_MUTEX(usbfs_mutex);
@@ -514,22 +513,25 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig
514 return ret; 513 return ret;
515} 514}
516 515
517static struct usb_device *usbdev_lookup_minor(int minor) 516static int __match_minor(struct device *dev, void *data)
518{ 517{
519 struct device *device; 518 int minor = *((int *)data);
520 struct usb_device *udev = NULL;
521 519
522 down(&usb_device_class->sem); 520 if (dev->devt == MKDEV(USB_DEVICE_MAJOR, minor))
523 list_for_each_entry(device, &usb_device_class->devices, node) { 521 return 1;
524 if (device->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { 522 return 0;
525 udev = device->platform_data; 523}
526 break;
527 }
528 }
529 up(&usb_device_class->sem);
530 524
531 return udev; 525static struct usb_device *usbdev_lookup_by_minor(int minor)
532}; 526{
527 struct device *dev;
528
529 dev = bus_find_device(&usb_bus_type, NULL, &minor, __match_minor);
530 if (!dev)
531 return NULL;
532 put_device(dev);
533 return container_of(dev, struct usb_device, dev);
534}
533 535
534/* 536/*
535 * file operations 537 * file operations
@@ -548,11 +550,14 @@ static int usbdev_open(struct inode *inode, struct file *file)
548 goto out; 550 goto out;
549 551
550 ret = -ENOENT; 552 ret = -ENOENT;
551 /* check if we are called from a real node or usbfs */ 553 /* usbdev device-node */
552 if (imajor(inode) == USB_DEVICE_MAJOR) 554 if (imajor(inode) == USB_DEVICE_MAJOR)
553 dev = usbdev_lookup_minor(iminor(inode)); 555 dev = usbdev_lookup_by_minor(iminor(inode));
556#ifdef CONFIG_USB_DEVICEFS
557 /* procfs file */
554 if (!dev) 558 if (!dev)
555 dev = inode->i_private; 559 dev = inode->i_private;
560#endif
556 if (!dev) 561 if (!dev)
557 goto out; 562 goto out;
558 ret = usb_autoresume_device(dev); 563 ret = usb_autoresume_device(dev);
@@ -1570,7 +1575,7 @@ static unsigned int usbdev_poll(struct file *file, struct poll_table_struct *wai
1570 return mask; 1575 return mask;
1571} 1576}
1572 1577
1573const struct file_operations usbfs_device_file_operations = { 1578const struct file_operations usbdev_file_operations = {
1574 .llseek = usbdev_lseek, 1579 .llseek = usbdev_lseek,
1575 .read = usbdev_read, 1580 .read = usbdev_read,
1576 .poll = usbdev_poll, 1581 .poll = usbdev_poll,
@@ -1579,50 +1584,53 @@ const struct file_operations usbfs_device_file_operations = {
1579 .release = usbdev_release, 1584 .release = usbdev_release,
1580}; 1585};
1581 1586
1582static int usbdev_add(struct usb_device *dev) 1587#ifdef CONFIG_USB_DEVICE_CLASS
1588static struct class *usb_classdev_class;
1589
1590static int usb_classdev_add(struct usb_device *dev)
1583{ 1591{
1584 int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); 1592 int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1);
1585 1593
1586 dev->usbfs_dev = device_create(usb_device_class, &dev->dev, 1594 dev->usb_classdev = device_create(usb_classdev_class, &dev->dev,
1587 MKDEV(USB_DEVICE_MAJOR, minor), 1595 MKDEV(USB_DEVICE_MAJOR, minor),
1588 "usbdev%d.%d", dev->bus->busnum, dev->devnum); 1596 "usbdev%d.%d", dev->bus->busnum, dev->devnum);
1589 if (IS_ERR(dev->usbfs_dev)) 1597 if (IS_ERR(dev->usb_classdev))
1590 return PTR_ERR(dev->usbfs_dev); 1598 return PTR_ERR(dev->usb_classdev);
1591 1599
1592 dev->usbfs_dev->platform_data = dev;
1593 return 0; 1600 return 0;
1594} 1601}
1595 1602
1596static void usbdev_remove(struct usb_device *dev) 1603static void usb_classdev_remove(struct usb_device *dev)
1597{ 1604{
1598 device_unregister(dev->usbfs_dev); 1605 device_unregister(dev->usb_classdev);
1599} 1606}
1600 1607
1601static int usbdev_notify(struct notifier_block *self, unsigned long action, 1608static int usb_classdev_notify(struct notifier_block *self,
1602 void *dev) 1609 unsigned long action, void *dev)
1603{ 1610{
1604 switch (action) { 1611 switch (action) {
1605 case USB_DEVICE_ADD: 1612 case USB_DEVICE_ADD:
1606 if (usbdev_add(dev)) 1613 if (usb_classdev_add(dev))
1607 return NOTIFY_BAD; 1614 return NOTIFY_BAD;
1608 break; 1615 break;
1609 case USB_DEVICE_REMOVE: 1616 case USB_DEVICE_REMOVE:
1610 usbdev_remove(dev); 1617 usb_classdev_remove(dev);
1611 break; 1618 break;
1612 } 1619 }
1613 return NOTIFY_OK; 1620 return NOTIFY_OK;
1614} 1621}
1615 1622
1616static struct notifier_block usbdev_nb = { 1623static struct notifier_block usbdev_nb = {
1617 .notifier_call = usbdev_notify, 1624 .notifier_call = usb_classdev_notify,
1618}; 1625};
1626#endif
1619 1627
1620static struct cdev usb_device_cdev = { 1628static struct cdev usb_device_cdev = {
1621 .kobj = {.name = "usb_device", }, 1629 .kobj = {.name = "usb_device", },
1622 .owner = THIS_MODULE, 1630 .owner = THIS_MODULE,
1623}; 1631};
1624 1632
1625int __init usbdev_init(void) 1633int __init usb_devio_init(void)
1626{ 1634{
1627 int retval; 1635 int retval;
1628 1636
@@ -1632,38 +1640,38 @@ int __init usbdev_init(void)
1632 err("unable to register minors for usb_device"); 1640 err("unable to register minors for usb_device");
1633 goto out; 1641 goto out;
1634 } 1642 }
1635 cdev_init(&usb_device_cdev, &usbfs_device_file_operations); 1643 cdev_init(&usb_device_cdev, &usbdev_file_operations);
1636 retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX); 1644 retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX);
1637 if (retval) { 1645 if (retval) {
1638 err("unable to get usb_device major %d", USB_DEVICE_MAJOR); 1646 err("unable to get usb_device major %d", USB_DEVICE_MAJOR);
1639 goto error_cdev; 1647 goto error_cdev;
1640 } 1648 }
1641 usb_device_class = class_create(THIS_MODULE, "usb_device"); 1649#ifdef CONFIG_USB_DEVICE_CLASS
1642 if (IS_ERR(usb_device_class)) { 1650 usb_classdev_class = class_create(THIS_MODULE, "usb_device");
1651 if (IS_ERR(usb_classdev_class)) {
1643 err("unable to register usb_device class"); 1652 err("unable to register usb_device class");
1644 retval = PTR_ERR(usb_device_class); 1653 retval = PTR_ERR(usb_classdev_class);
1645 goto error_class; 1654 cdev_del(&usb_device_cdev);
1655 usb_classdev_class = NULL;
1656 goto out;
1646 } 1657 }
1647 1658
1648 usb_register_notify(&usbdev_nb); 1659 usb_register_notify(&usbdev_nb);
1649 1660#endif
1650out: 1661out:
1651 return retval; 1662 return retval;
1652 1663
1653error_class:
1654 usb_device_class = NULL;
1655 cdev_del(&usb_device_cdev);
1656
1657error_cdev: 1664error_cdev:
1658 unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); 1665 unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
1659 goto out; 1666 goto out;
1660} 1667}
1661 1668
1662void usbdev_cleanup(void) 1669void usb_devio_cleanup(void)
1663{ 1670{
1671#ifdef CONFIG_USB_DEVICE_CLASS
1664 usb_unregister_notify(&usbdev_nb); 1672 usb_unregister_notify(&usbdev_nb);
1665 class_destroy(usb_device_class); 1673 class_destroy(usb_classdev_class);
1674#endif
1666 cdev_del(&usb_device_cdev); 1675 cdev_del(&usb_device_cdev);
1667 unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); 1676 unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
1668} 1677}
1669
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 9b6a60fafddb..593386eb974d 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -574,23 +574,10 @@ static int usb_device_match(struct device *dev, struct device_driver *drv)
574} 574}
575 575
576#ifdef CONFIG_HOTPLUG 576#ifdef CONFIG_HOTPLUG
577
578/*
579 * This sends an uevent to userspace, typically helping to load driver
580 * or other modules, configure the device, and more. Drivers can provide
581 * a MODULE_DEVICE_TABLE to help with module loading subtasks.
582 *
583 * We're called either from khubd (the typical case) or from root hub
584 * (init, kapmd, modprobe, rmmod, etc), but the agents need to handle
585 * delays in event delivery. Use sysfs (and DEVPATH) to make sure the
586 * device (and this configuration!) are still present.
587 */
588static int usb_uevent(struct device *dev, char **envp, int num_envp, 577static int usb_uevent(struct device *dev, char **envp, int num_envp,
589 char *buffer, int buffer_size) 578 char *buffer, int buffer_size)
590{ 579{
591 struct usb_interface *intf;
592 struct usb_device *usb_dev; 580 struct usb_device *usb_dev;
593 struct usb_host_interface *alt;
594 int i = 0; 581 int i = 0;
595 int length = 0; 582 int length = 0;
596 583
@@ -600,13 +587,11 @@ static int usb_uevent(struct device *dev, char **envp, int num_envp,
600 /* driver is often null here; dev_dbg() would oops */ 587 /* driver is often null here; dev_dbg() would oops */
601 pr_debug ("usb %s: uevent\n", dev->bus_id); 588 pr_debug ("usb %s: uevent\n", dev->bus_id);
602 589
603 if (is_usb_device(dev)) { 590 if (is_usb_device(dev))
604 usb_dev = to_usb_device(dev); 591 usb_dev = to_usb_device(dev);
605 alt = NULL; 592 else {
606 } else { 593 struct usb_interface *intf = to_usb_interface(dev);
607 intf = to_usb_interface(dev);
608 usb_dev = interface_to_usbdev(intf); 594 usb_dev = interface_to_usbdev(intf);
609 alt = intf->cur_altsetting;
610 } 595 }
611 596
612 if (usb_dev->devnum < 0) { 597 if (usb_dev->devnum < 0) {
@@ -621,9 +606,7 @@ static int usb_uevent(struct device *dev, char **envp, int num_envp,
621#ifdef CONFIG_USB_DEVICEFS 606#ifdef CONFIG_USB_DEVICEFS
622 /* If this is available, userspace programs can directly read 607 /* If this is available, userspace programs can directly read
623 * all the device descriptors we don't tell them about. Or 608 * all the device descriptors we don't tell them about. Or
624 * even act as usermode drivers. 609 * act as usermode drivers.
625 *
626 * FIXME reduce hardwired intelligence here
627 */ 610 */
628 if (add_uevent_var(envp, num_envp, &i, 611 if (add_uevent_var(envp, num_envp, &i,
629 buffer, buffer_size, &length, 612 buffer, buffer_size, &length,
@@ -650,44 +633,29 @@ static int usb_uevent(struct device *dev, char **envp, int num_envp,
650 usb_dev->descriptor.bDeviceProtocol)) 633 usb_dev->descriptor.bDeviceProtocol))
651 return -ENOMEM; 634 return -ENOMEM;
652 635
653 if (!is_usb_device(dev)) { 636 if (add_uevent_var(envp, num_envp, &i,
654
655 if (add_uevent_var(envp, num_envp, &i,
656 buffer, buffer_size, &length, 637 buffer, buffer_size, &length,
657 "INTERFACE=%d/%d/%d", 638 "BUSNUM=%03d",
658 alt->desc.bInterfaceClass, 639 usb_dev->bus->busnum))
659 alt->desc.bInterfaceSubClass, 640 return -ENOMEM;
660 alt->desc.bInterfaceProtocol))
661 return -ENOMEM;
662 641
663 if (add_uevent_var(envp, num_envp, &i, 642 if (add_uevent_var(envp, num_envp, &i,
664 buffer, buffer_size, &length, 643 buffer, buffer_size, &length,
665 "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", 644 "DEVNUM=%03d",
666 le16_to_cpu(usb_dev->descriptor.idVendor), 645 usb_dev->devnum))
667 le16_to_cpu(usb_dev->descriptor.idProduct), 646 return -ENOMEM;
668 le16_to_cpu(usb_dev->descriptor.bcdDevice),
669 usb_dev->descriptor.bDeviceClass,
670 usb_dev->descriptor.bDeviceSubClass,
671 usb_dev->descriptor.bDeviceProtocol,
672 alt->desc.bInterfaceClass,
673 alt->desc.bInterfaceSubClass,
674 alt->desc.bInterfaceProtocol))
675 return -ENOMEM;
676 }
677 647
678 envp[i] = NULL; 648 envp[i] = NULL;
679
680 return 0; 649 return 0;
681} 650}
682 651
683#else 652#else
684 653
685static int usb_uevent(struct device *dev, char **envp, 654static int usb_uevent(struct device *dev, char **envp,
686 int num_envp, char *buffer, int buffer_size) 655 int num_envp, char *buffer, int buffer_size)
687{ 656{
688 return -ENODEV; 657 return -ENODEV;
689} 658}
690
691#endif /* CONFIG_HOTPLUG */ 659#endif /* CONFIG_HOTPLUG */
692 660
693/** 661/**
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 19abe81babd5..2a0b15e42bc7 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1367,11 +1367,15 @@ int usb_new_device(struct usb_device *udev)
1367 } 1367 }
1368#endif 1368#endif
1369 1369
1370 /* export the usbdev device-node for libusb */
1371 udev->dev.devt = MKDEV(USB_DEVICE_MAJOR,
1372 (((udev->bus->busnum-1) * 128) + (udev->devnum-1)));
1373
1370 /* Register the device. The device driver is responsible 1374 /* Register the device. The device driver is responsible
1371 * for adding the device files to usbfs and sysfs and for 1375 * for adding the device files to sysfs and for configuring
1372 * configuring the device. 1376 * the device.
1373 */ 1377 */
1374 err = device_add (&udev->dev); 1378 err = device_add(&udev->dev);
1375 if (err) { 1379 if (err) {
1376 dev_err(&udev->dev, "can't device_add, error %d\n", err); 1380 dev_err(&udev->dev, "can't device_add, error %d\n", err);
1377 goto fail; 1381 goto fail;
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index 11dad22da41c..cddfc62c4611 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -662,7 +662,7 @@ static void usbfs_add_device(struct usb_device *dev)
662 sprintf (name, "%03d", dev->devnum); 662 sprintf (name, "%03d", dev->devnum);
663 dev->usbfs_dentry = fs_create_file (name, devmode | S_IFREG, 663 dev->usbfs_dentry = fs_create_file (name, devmode | S_IFREG,
664 dev->bus->usbfs_dentry, dev, 664 dev->bus->usbfs_dentry, dev,
665 &usbfs_device_file_operations, 665 &usbdev_file_operations,
666 devuid, devgid); 666 devuid, devgid);
667 if (dev->usbfs_dentry == NULL) { 667 if (dev->usbfs_dentry == NULL) {
668 err ("error creating usbfs device entry"); 668 err ("error creating usbfs device entry");
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index c359ccb32998..da4ee07e0094 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1305,7 +1305,7 @@ int usb_reset_configuration(struct usb_device *dev)
1305 return 0; 1305 return 0;
1306} 1306}
1307 1307
1308static void release_interface(struct device *dev) 1308void usb_release_interface(struct device *dev)
1309{ 1309{
1310 struct usb_interface *intf = to_usb_interface(dev); 1310 struct usb_interface *intf = to_usb_interface(dev);
1311 struct usb_interface_cache *intfc = 1311 struct usb_interface_cache *intfc =
@@ -1315,6 +1315,67 @@ static void release_interface(struct device *dev)
1315 kfree(intf); 1315 kfree(intf);
1316} 1316}
1317 1317
1318#ifdef CONFIG_HOTPLUG
1319static int usb_if_uevent(struct device *dev, char **envp, int num_envp,
1320 char *buffer, int buffer_size)
1321{
1322 struct usb_device *usb_dev;
1323 struct usb_interface *intf;
1324 struct usb_host_interface *alt;
1325 int i = 0;
1326 int length = 0;
1327
1328 if (!dev)
1329 return -ENODEV;
1330
1331 /* driver is often null here; dev_dbg() would oops */
1332 pr_debug ("usb %s: uevent\n", dev->bus_id);
1333
1334 intf = to_usb_interface(dev);
1335 usb_dev = interface_to_usbdev(intf);
1336 alt = intf->cur_altsetting;
1337
1338 if (add_uevent_var(envp, num_envp, &i,
1339 buffer, buffer_size, &length,
1340 "INTERFACE=%d/%d/%d",
1341 alt->desc.bInterfaceClass,
1342 alt->desc.bInterfaceSubClass,
1343 alt->desc.bInterfaceProtocol))
1344 return -ENOMEM;
1345
1346 if (add_uevent_var(envp, num_envp, &i,
1347 buffer, buffer_size, &length,
1348 "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
1349 le16_to_cpu(usb_dev->descriptor.idVendor),
1350 le16_to_cpu(usb_dev->descriptor.idProduct),
1351 le16_to_cpu(usb_dev->descriptor.bcdDevice),
1352 usb_dev->descriptor.bDeviceClass,
1353 usb_dev->descriptor.bDeviceSubClass,
1354 usb_dev->descriptor.bDeviceProtocol,
1355 alt->desc.bInterfaceClass,
1356 alt->desc.bInterfaceSubClass,
1357 alt->desc.bInterfaceProtocol))
1358 return -ENOMEM;
1359
1360 envp[i] = NULL;
1361 return 0;
1362}
1363
1364#else
1365
1366static int usb_if_uevent(struct device *dev, char **envp,
1367 int num_envp, char *buffer, int buffer_size)
1368{
1369 return -ENODEV;
1370}
1371#endif /* CONFIG_HOTPLUG */
1372
1373struct device_type usb_if_device_type = {
1374 .name = "usb_interface",
1375 .release = usb_release_interface,
1376 .uevent = usb_if_uevent,
1377};
1378
1318/* 1379/*
1319 * usb_set_configuration - Makes a particular device setting be current 1380 * usb_set_configuration - Makes a particular device setting be current
1320 * @dev: the device whose configuration is being updated 1381 * @dev: the device whose configuration is being updated
@@ -1478,8 +1539,8 @@ free_interfaces:
1478 intf->dev.parent = &dev->dev; 1539 intf->dev.parent = &dev->dev;
1479 intf->dev.driver = NULL; 1540 intf->dev.driver = NULL;
1480 intf->dev.bus = &usb_bus_type; 1541 intf->dev.bus = &usb_bus_type;
1542 intf->dev.type = &usb_if_device_type;
1481 intf->dev.dma_mask = dev->dev.dma_mask; 1543 intf->dev.dma_mask = dev->dev.dma_mask;
1482 intf->dev.release = release_interface;
1483 device_initialize (&intf->dev); 1544 device_initialize (&intf->dev);
1484 mark_quiesced(intf); 1545 mark_quiesced(intf);
1485 sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d", 1546 sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d",
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 6f35dce8a95d..dfd1b5c87ca3 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -197,6 +197,11 @@ static void usb_release_dev(struct device *dev)
197 kfree(udev); 197 kfree(udev);
198} 198}
199 199
200struct device_type usb_device_type = {
201 .name = "usb_device",
202 .release = usb_release_dev,
203};
204
200#ifdef CONFIG_PM 205#ifdef CONFIG_PM
201 206
202static int ksuspend_usb_init(void) 207static int ksuspend_usb_init(void)
@@ -247,13 +252,10 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1)
247 252
248 device_initialize(&dev->dev); 253 device_initialize(&dev->dev);
249 dev->dev.bus = &usb_bus_type; 254 dev->dev.bus = &usb_bus_type;
255 dev->dev.type = &usb_device_type;
250 dev->dev.dma_mask = bus->controller->dma_mask; 256 dev->dev.dma_mask = bus->controller->dma_mask;
251 dev->dev.release = usb_release_dev;
252 dev->state = USB_STATE_ATTACHED; 257 dev->state = USB_STATE_ATTACHED;
253 258
254 /* This magic assignment distinguishes devices from interfaces */
255 dev->dev.platform_data = &usb_generic_driver;
256
257 INIT_LIST_HEAD(&dev->ep0.urb_list); 259 INIT_LIST_HEAD(&dev->ep0.urb_list);
258 dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE; 260 dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE;
259 dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT; 261 dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT;
@@ -882,9 +884,9 @@ static int __init usb_init(void)
882 retval = usb_register(&usbfs_driver); 884 retval = usb_register(&usbfs_driver);
883 if (retval) 885 if (retval)
884 goto driver_register_failed; 886 goto driver_register_failed;
885 retval = usbdev_init(); 887 retval = usb_devio_init();
886 if (retval) 888 if (retval)
887 goto usbdevice_init_failed; 889 goto usb_devio_init_failed;
888 retval = usbfs_init(); 890 retval = usbfs_init();
889 if (retval) 891 if (retval)
890 goto fs_init_failed; 892 goto fs_init_failed;
@@ -899,8 +901,8 @@ static int __init usb_init(void)
899hub_init_failed: 901hub_init_failed:
900 usbfs_cleanup(); 902 usbfs_cleanup();
901fs_init_failed: 903fs_init_failed:
902 usbdev_cleanup(); 904 usb_devio_cleanup();
903usbdevice_init_failed: 905usb_devio_init_failed:
904 usb_deregister(&usbfs_driver); 906 usb_deregister(&usbfs_driver);
905driver_register_failed: 907driver_register_failed:
906 usb_major_cleanup(); 908 usb_major_cleanup();
@@ -927,7 +929,7 @@ static void __exit usb_exit(void)
927 usb_major_cleanup(); 929 usb_major_cleanup();
928 usbfs_cleanup(); 930 usbfs_cleanup();
929 usb_deregister(&usbfs_driver); 931 usb_deregister(&usbfs_driver);
930 usbdev_cleanup(); 932 usb_devio_cleanup();
931 usb_hub_cleanup(); 933 usb_hub_cleanup();
932 usb_host_cleanup(); 934 usb_host_cleanup();
933 bus_unregister(&usb_bus_type); 935 bus_unregister(&usb_bus_type);
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index c94379e55f2d..bf2eb0dae2ec 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -78,15 +78,13 @@ static inline int usb_autoresume_device(struct usb_device *udev)
78 78
79extern struct workqueue_struct *ksuspend_usb_wq; 79extern struct workqueue_struct *ksuspend_usb_wq;
80extern struct bus_type usb_bus_type; 80extern struct bus_type usb_bus_type;
81extern struct device_type usb_device_type;
82extern struct device_type usb_if_device_type;
81extern struct usb_device_driver usb_generic_driver; 83extern struct usb_device_driver usb_generic_driver;
82 84
83/* Here's how we tell apart devices and interfaces. Luckily there's
84 * no such thing as a platform USB device, so we can steal the use
85 * of the platform_data field. */
86
87static inline int is_usb_device(const struct device *dev) 85static inline int is_usb_device(const struct device *dev)
88{ 86{
89 return dev->platform_data == &usb_generic_driver; 87 return dev->type == &usb_device_type;
90} 88}
91 89
92/* Do the same for device drivers and interface drivers. */ 90/* Do the same for device drivers and interface drivers. */
@@ -122,11 +120,11 @@ extern const char *usbcore_name;
122extern struct mutex usbfs_mutex; 120extern struct mutex usbfs_mutex;
123extern struct usb_driver usbfs_driver; 121extern struct usb_driver usbfs_driver;
124extern const struct file_operations usbfs_devices_fops; 122extern const struct file_operations usbfs_devices_fops;
125extern const struct file_operations usbfs_device_file_operations; 123extern const struct file_operations usbdev_file_operations;
126extern void usbfs_conn_disc_event(void); 124extern void usbfs_conn_disc_event(void);
127 125
128extern int usbdev_init(void); 126extern int usb_devio_init(void);
129extern void usbdev_cleanup(void); 127extern void usb_devio_cleanup(void);
130 128
131struct dev_state { 129struct dev_state {
132 struct list_head list; /* state list */ 130 struct list_head list; /* state list */