aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/devio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core/devio.c')
-rw-r--r--drivers/usb/core/devio.c109
1 files changed, 52 insertions, 57 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 36e7a843bf91..927a181120a9 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);
@@ -421,14 +420,11 @@ static int claimintf(struct dev_state *ps, unsigned int ifnum)
421 if (test_bit(ifnum, &ps->ifclaimed)) 420 if (test_bit(ifnum, &ps->ifclaimed))
422 return 0; 421 return 0;
423 422
424 /* lock against other changes to driver bindings */
425 down_write(&usb_bus_type.subsys.rwsem);
426 intf = usb_ifnum_to_if(dev, ifnum); 423 intf = usb_ifnum_to_if(dev, ifnum);
427 if (!intf) 424 if (!intf)
428 err = -ENOENT; 425 err = -ENOENT;
429 else 426 else
430 err = usb_driver_claim_interface(&usbfs_driver, intf, ps); 427 err = usb_driver_claim_interface(&usbfs_driver, intf, ps);
431 up_write(&usb_bus_type.subsys.rwsem);
432 if (err == 0) 428 if (err == 0)
433 set_bit(ifnum, &ps->ifclaimed); 429 set_bit(ifnum, &ps->ifclaimed);
434 return err; 430 return err;
@@ -444,8 +440,6 @@ static int releaseintf(struct dev_state *ps, unsigned int ifnum)
444 if (ifnum >= 8*sizeof(ps->ifclaimed)) 440 if (ifnum >= 8*sizeof(ps->ifclaimed))
445 return err; 441 return err;
446 dev = ps->dev; 442 dev = ps->dev;
447 /* lock against other changes to driver bindings */
448 down_write(&usb_bus_type.subsys.rwsem);
449 intf = usb_ifnum_to_if(dev, ifnum); 443 intf = usb_ifnum_to_if(dev, ifnum);
450 if (!intf) 444 if (!intf)
451 err = -ENOENT; 445 err = -ENOENT;
@@ -453,7 +447,6 @@ static int releaseintf(struct dev_state *ps, unsigned int ifnum)
453 usb_driver_release_interface(&usbfs_driver, intf); 447 usb_driver_release_interface(&usbfs_driver, intf);
454 err = 0; 448 err = 0;
455 } 449 }
456 up_write(&usb_bus_type.subsys.rwsem);
457 return err; 450 return err;
458} 451}
459 452
@@ -520,22 +513,25 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig
520 return ret; 513 return ret;
521} 514}
522 515
523static struct usb_device *usbdev_lookup_minor(int minor) 516static int __match_minor(struct device *dev, void *data)
524{ 517{
525 struct device *device; 518 int minor = *((int *)data);
526 struct usb_device *udev = NULL;
527 519
528 down(&usb_device_class->sem); 520 if (dev->devt == MKDEV(USB_DEVICE_MAJOR, minor))
529 list_for_each_entry(device, &usb_device_class->devices, node) { 521 return 1;
530 if (device->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { 522 return 0;
531 udev = device->platform_data; 523}
532 break;
533 }
534 }
535 up(&usb_device_class->sem);
536 524
537 return udev; 525static struct usb_device *usbdev_lookup_by_minor(int minor)
538}; 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}
539 535
540/* 536/*
541 * file operations 537 * file operations
@@ -554,11 +550,14 @@ static int usbdev_open(struct inode *inode, struct file *file)
554 goto out; 550 goto out;
555 551
556 ret = -ENOENT; 552 ret = -ENOENT;
557 /* check if we are called from a real node or usbfs */ 553 /* usbdev device-node */
558 if (imajor(inode) == USB_DEVICE_MAJOR) 554 if (imajor(inode) == USB_DEVICE_MAJOR)
559 dev = usbdev_lookup_minor(iminor(inode)); 555 dev = usbdev_lookup_by_minor(iminor(inode));
556#ifdef CONFIG_USB_DEVICEFS
557 /* procfs file */
560 if (!dev) 558 if (!dev)
561 dev = inode->i_private; 559 dev = inode->i_private;
560#endif
562 if (!dev) 561 if (!dev)
563 goto out; 562 goto out;
564 ret = usb_autoresume_device(dev); 563 ret = usb_autoresume_device(dev);
@@ -581,7 +580,7 @@ static int usbdev_open(struct inode *inode, struct file *file)
581 ps->disccontext = NULL; 580 ps->disccontext = NULL;
582 ps->ifclaimed = 0; 581 ps->ifclaimed = 0;
583 security_task_getsecid(current, &ps->secid); 582 security_task_getsecid(current, &ps->secid);
584 wmb(); 583 smp_wmb();
585 list_add_tail(&ps->list, &dev->filelist); 584 list_add_tail(&ps->list, &dev->filelist);
586 file->private_data = ps; 585 file->private_data = ps;
587 out: 586 out:
@@ -813,7 +812,6 @@ static int proc_getdriver(struct dev_state *ps, void __user *arg)
813 812
814 if (copy_from_user(&gd, arg, sizeof(gd))) 813 if (copy_from_user(&gd, arg, sizeof(gd)))
815 return -EFAULT; 814 return -EFAULT;
816 down_read(&usb_bus_type.subsys.rwsem);
817 intf = usb_ifnum_to_if(ps->dev, gd.interface); 815 intf = usb_ifnum_to_if(ps->dev, gd.interface);
818 if (!intf || !intf->dev.driver) 816 if (!intf || !intf->dev.driver)
819 ret = -ENODATA; 817 ret = -ENODATA;
@@ -822,7 +820,6 @@ static int proc_getdriver(struct dev_state *ps, void __user *arg)
822 sizeof(gd.driver)); 820 sizeof(gd.driver));
823 ret = (copy_to_user(arg, &gd, sizeof(gd)) ? -EFAULT : 0); 821 ret = (copy_to_user(arg, &gd, sizeof(gd)) ? -EFAULT : 0);
824 } 822 }
825 up_read(&usb_bus_type.subsys.rwsem);
826 return ret; 823 return ret;
827} 824}
828 825
@@ -1351,15 +1348,12 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl)
1351 1348
1352 /* disconnect kernel driver from interface */ 1349 /* disconnect kernel driver from interface */
1353 case USBDEVFS_DISCONNECT: 1350 case USBDEVFS_DISCONNECT:
1354
1355 down_write(&usb_bus_type.subsys.rwsem);
1356 if (intf->dev.driver) { 1351 if (intf->dev.driver) {
1357 driver = to_usb_driver(intf->dev.driver); 1352 driver = to_usb_driver(intf->dev.driver);
1358 dev_dbg (&intf->dev, "disconnect by usbfs\n"); 1353 dev_dbg (&intf->dev, "disconnect by usbfs\n");
1359 usb_driver_release_interface(driver, intf); 1354 usb_driver_release_interface(driver, intf);
1360 } else 1355 } else
1361 retval = -ENODATA; 1356 retval = -ENODATA;
1362 up_write(&usb_bus_type.subsys.rwsem);
1363 break; 1357 break;
1364 1358
1365 /* let kernel drivers try to (re)bind to the interface */ 1359 /* let kernel drivers try to (re)bind to the interface */
@@ -1371,7 +1365,6 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl)
1371 1365
1372 /* talk directly to the interface's driver */ 1366 /* talk directly to the interface's driver */
1373 default: 1367 default:
1374 down_read(&usb_bus_type.subsys.rwsem);
1375 if (intf->dev.driver) 1368 if (intf->dev.driver)
1376 driver = to_usb_driver(intf->dev.driver); 1369 driver = to_usb_driver(intf->dev.driver);
1377 if (driver == NULL || driver->ioctl == NULL) { 1370 if (driver == NULL || driver->ioctl == NULL) {
@@ -1381,7 +1374,6 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl)
1381 if (retval == -ENOIOCTLCMD) 1374 if (retval == -ENOIOCTLCMD)
1382 retval = -ENOTTY; 1375 retval = -ENOTTY;
1383 } 1376 }
1384 up_read(&usb_bus_type.subsys.rwsem);
1385 } 1377 }
1386 1378
1387 /* cleanup and return */ 1379 /* cleanup and return */
@@ -1583,7 +1575,7 @@ static unsigned int usbdev_poll(struct file *file, struct poll_table_struct *wai
1583 return mask; 1575 return mask;
1584} 1576}
1585 1577
1586const struct file_operations usbfs_device_file_operations = { 1578const struct file_operations usbdev_file_operations = {
1587 .llseek = usbdev_lseek, 1579 .llseek = usbdev_lseek,
1588 .read = usbdev_read, 1580 .read = usbdev_read,
1589 .poll = usbdev_poll, 1581 .poll = usbdev_poll,
@@ -1592,50 +1584,53 @@ const struct file_operations usbfs_device_file_operations = {
1592 .release = usbdev_release, 1584 .release = usbdev_release,
1593}; 1585};
1594 1586
1595static 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)
1596{ 1591{
1597 int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); 1592 int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1);
1598 1593
1599 dev->usbfs_dev = device_create(usb_device_class, &dev->dev, 1594 dev->usb_classdev = device_create(usb_classdev_class, &dev->dev,
1600 MKDEV(USB_DEVICE_MAJOR, minor), 1595 MKDEV(USB_DEVICE_MAJOR, minor),
1601 "usbdev%d.%d", dev->bus->busnum, dev->devnum); 1596 "usbdev%d.%d", dev->bus->busnum, dev->devnum);
1602 if (IS_ERR(dev->usbfs_dev)) 1597 if (IS_ERR(dev->usb_classdev))
1603 return PTR_ERR(dev->usbfs_dev); 1598 return PTR_ERR(dev->usb_classdev);
1604 1599
1605 dev->usbfs_dev->platform_data = dev;
1606 return 0; 1600 return 0;
1607} 1601}
1608 1602
1609static void usbdev_remove(struct usb_device *dev) 1603static void usb_classdev_remove(struct usb_device *dev)
1610{ 1604{
1611 device_unregister(dev->usbfs_dev); 1605 device_unregister(dev->usb_classdev);
1612} 1606}
1613 1607
1614static int usbdev_notify(struct notifier_block *self, unsigned long action, 1608static int usb_classdev_notify(struct notifier_block *self,
1615 void *dev) 1609 unsigned long action, void *dev)
1616{ 1610{
1617 switch (action) { 1611 switch (action) {
1618 case USB_DEVICE_ADD: 1612 case USB_DEVICE_ADD:
1619 if (usbdev_add(dev)) 1613 if (usb_classdev_add(dev))
1620 return NOTIFY_BAD; 1614 return NOTIFY_BAD;
1621 break; 1615 break;
1622 case USB_DEVICE_REMOVE: 1616 case USB_DEVICE_REMOVE:
1623 usbdev_remove(dev); 1617 usb_classdev_remove(dev);
1624 break; 1618 break;
1625 } 1619 }
1626 return NOTIFY_OK; 1620 return NOTIFY_OK;
1627} 1621}
1628 1622
1629static struct notifier_block usbdev_nb = { 1623static struct notifier_block usbdev_nb = {
1630 .notifier_call = usbdev_notify, 1624 .notifier_call = usb_classdev_notify,
1631}; 1625};
1626#endif
1632 1627
1633static struct cdev usb_device_cdev = { 1628static struct cdev usb_device_cdev = {
1634 .kobj = {.name = "usb_device", }, 1629 .kobj = {.name = "usb_device", },
1635 .owner = THIS_MODULE, 1630 .owner = THIS_MODULE,
1636}; 1631};
1637 1632
1638int __init usbdev_init(void) 1633int __init usb_devio_init(void)
1639{ 1634{
1640 int retval; 1635 int retval;
1641 1636
@@ -1645,38 +1640,38 @@ int __init usbdev_init(void)
1645 err("unable to register minors for usb_device"); 1640 err("unable to register minors for usb_device");
1646 goto out; 1641 goto out;
1647 } 1642 }
1648 cdev_init(&usb_device_cdev, &usbfs_device_file_operations); 1643 cdev_init(&usb_device_cdev, &usbdev_file_operations);
1649 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);
1650 if (retval) { 1645 if (retval) {
1651 err("unable to get usb_device major %d", USB_DEVICE_MAJOR); 1646 err("unable to get usb_device major %d", USB_DEVICE_MAJOR);
1652 goto error_cdev; 1647 goto error_cdev;
1653 } 1648 }
1654 usb_device_class = class_create(THIS_MODULE, "usb_device"); 1649#ifdef CONFIG_USB_DEVICE_CLASS
1655 if (IS_ERR(usb_device_class)) { 1650 usb_classdev_class = class_create(THIS_MODULE, "usb_device");
1651 if (IS_ERR(usb_classdev_class)) {
1656 err("unable to register usb_device class"); 1652 err("unable to register usb_device class");
1657 retval = PTR_ERR(usb_device_class); 1653 retval = PTR_ERR(usb_classdev_class);
1658 goto error_class; 1654 cdev_del(&usb_device_cdev);
1655 usb_classdev_class = NULL;
1656 goto out;
1659 } 1657 }
1660 1658
1661 usb_register_notify(&usbdev_nb); 1659 usb_register_notify(&usbdev_nb);
1662 1660#endif
1663out: 1661out:
1664 return retval; 1662 return retval;
1665 1663
1666error_class:
1667 usb_device_class = NULL;
1668 cdev_del(&usb_device_cdev);
1669
1670error_cdev: 1664error_cdev:
1671 unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); 1665 unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
1672 goto out; 1666 goto out;
1673} 1667}
1674 1668
1675void usbdev_cleanup(void) 1669void usb_devio_cleanup(void)
1676{ 1670{
1671#ifdef CONFIG_USB_DEVICE_CLASS
1677 usb_unregister_notify(&usbdev_nb); 1672 usb_unregister_notify(&usbdev_nb);
1678 class_destroy(usb_device_class); 1673 class_destroy(usb_classdev_class);
1674#endif
1679 cdev_del(&usb_device_cdev); 1675 cdev_del(&usb_device_cdev);
1680 unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); 1676 unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
1681} 1677}
1682