diff options
Diffstat (limited to 'drivers/usb/core')
| -rw-r--r-- | drivers/usb/core/Makefile | 4 | ||||
| -rw-r--r-- | drivers/usb/core/devio.c | 102 | ||||
| -rw-r--r-- | drivers/usb/core/hcd-pci.c | 28 | ||||
| -rw-r--r-- | drivers/usb/core/hcd.c | 3 | ||||
| -rw-r--r-- | drivers/usb/core/hcd.h | 8 | ||||
| -rw-r--r-- | drivers/usb/core/hub.c | 126 | ||||
| -rw-r--r-- | drivers/usb/core/hub.h | 7 | ||||
| -rw-r--r-- | drivers/usb/core/inode.c | 9 | ||||
| -rw-r--r-- | drivers/usb/core/message.c | 8 | ||||
| -rw-r--r-- | drivers/usb/core/urb.c | 26 | ||||
| -rw-r--r-- | drivers/usb/core/usb.c | 35 | ||||
| -rw-r--r-- | drivers/usb/core/usb.h | 5 |
12 files changed, 258 insertions, 103 deletions
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile index 9e8c377b8161..d5503cf0bf74 100644 --- a/drivers/usb/core/Makefile +++ b/drivers/usb/core/Makefile | |||
| @@ -3,14 +3,14 @@ | |||
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | usbcore-objs := usb.o hub.o hcd.o urb.o message.o \ | 5 | usbcore-objs := usb.o hub.o hcd.o urb.o message.o \ |
| 6 | config.o file.o buffer.o sysfs.o | 6 | config.o file.o buffer.o sysfs.o devio.o |
| 7 | 7 | ||
| 8 | ifeq ($(CONFIG_PCI),y) | 8 | ifeq ($(CONFIG_PCI),y) |
| 9 | usbcore-objs += hcd-pci.o | 9 | usbcore-objs += hcd-pci.o |
| 10 | endif | 10 | endif |
| 11 | 11 | ||
| 12 | ifeq ($(CONFIG_USB_DEVICEFS),y) | 12 | ifeq ($(CONFIG_USB_DEVICEFS),y) |
| 13 | usbcore-objs += devio.o inode.o devices.o | 13 | usbcore-objs += inode.o devices.o |
| 14 | endif | 14 | endif |
| 15 | 15 | ||
| 16 | obj-$(CONFIG_USB) += usbcore.o | 16 | obj-$(CONFIG_USB) += usbcore.o |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index f86bf1454e21..b4265aa7d45e 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | #include <linux/module.h> | 43 | #include <linux/module.h> |
| 44 | #include <linux/usb.h> | 44 | #include <linux/usb.h> |
| 45 | #include <linux/usbdevice_fs.h> | 45 | #include <linux/usbdevice_fs.h> |
| 46 | #include <linux/cdev.h> | ||
| 46 | #include <asm/uaccess.h> | 47 | #include <asm/uaccess.h> |
| 47 | #include <asm/byteorder.h> | 48 | #include <asm/byteorder.h> |
| 48 | #include <linux/moduleparam.h> | 49 | #include <linux/moduleparam.h> |
| @@ -50,6 +51,10 @@ | |||
| 50 | #include "hcd.h" /* for usbcore internals */ | 51 | #include "hcd.h" /* for usbcore internals */ |
| 51 | #include "usb.h" | 52 | #include "usb.h" |
| 52 | 53 | ||
| 54 | #define USB_MAXBUS 64 | ||
| 55 | #define USB_DEVICE_MAX USB_MAXBUS * 128 | ||
| 56 | static struct class *usb_device_class; | ||
| 57 | |||
| 53 | struct async { | 58 | struct async { |
| 54 | struct list_head asynclist; | 59 | struct list_head asynclist; |
| 55 | struct dev_state *ps; | 60 | struct dev_state *ps; |
| @@ -71,6 +76,8 @@ MODULE_PARM_DESC (usbfs_snoop, "true to log all usbfs traffic"); | |||
| 71 | dev_info( dev , format , ## arg); \ | 76 | dev_info( dev , format , ## arg); \ |
| 72 | } while (0) | 77 | } while (0) |
| 73 | 78 | ||
| 79 | #define USB_DEVICE_DEV MKDEV(USB_DEVICE_MAJOR, 0) | ||
| 80 | |||
| 74 | 81 | ||
| 75 | #define MAX_USBFS_BUFFER_SIZE 16384 | 82 | #define MAX_USBFS_BUFFER_SIZE 16384 |
| 76 | 83 | ||
| @@ -487,7 +494,7 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig | |||
| 487 | */ | 494 | */ |
| 488 | static int usbdev_open(struct inode *inode, struct file *file) | 495 | static int usbdev_open(struct inode *inode, struct file *file) |
| 489 | { | 496 | { |
| 490 | struct usb_device *dev; | 497 | struct usb_device *dev = NULL; |
| 491 | struct dev_state *ps; | 498 | struct dev_state *ps; |
| 492 | int ret; | 499 | int ret; |
| 493 | 500 | ||
| @@ -501,11 +508,16 @@ static int usbdev_open(struct inode *inode, struct file *file) | |||
| 501 | 508 | ||
| 502 | lock_kernel(); | 509 | lock_kernel(); |
| 503 | ret = -ENOENT; | 510 | ret = -ENOENT; |
| 504 | dev = usb_get_dev(inode->u.generic_ip); | 511 | /* check if we are called from a real node or usbfs */ |
| 512 | if (imajor(inode) == USB_DEVICE_MAJOR) | ||
| 513 | dev = usbdev_lookup_minor(iminor(inode)); | ||
| 514 | if (!dev) | ||
| 515 | dev = inode->u.generic_ip; | ||
| 505 | if (!dev) { | 516 | if (!dev) { |
| 506 | kfree(ps); | 517 | kfree(ps); |
| 507 | goto out; | 518 | goto out; |
| 508 | } | 519 | } |
| 520 | usb_get_dev(dev); | ||
| 509 | ret = 0; | 521 | ret = 0; |
| 510 | ps->dev = dev; | 522 | ps->dev = dev; |
| 511 | ps->file = file; | 523 | ps->file = file; |
| @@ -1226,7 +1238,6 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg) | |||
| 1226 | int retval = 0; | 1238 | int retval = 0; |
| 1227 | struct usb_interface *intf = NULL; | 1239 | struct usb_interface *intf = NULL; |
| 1228 | struct usb_driver *driver = NULL; | 1240 | struct usb_driver *driver = NULL; |
| 1229 | int i; | ||
| 1230 | 1241 | ||
| 1231 | /* get input parameters and alloc buffer */ | 1242 | /* get input parameters and alloc buffer */ |
| 1232 | if (copy_from_user(&ctrl, arg, sizeof (ctrl))) | 1243 | if (copy_from_user(&ctrl, arg, sizeof (ctrl))) |
| @@ -1258,15 +1269,6 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg) | |||
| 1258 | /* disconnect kernel driver from interface */ | 1269 | /* disconnect kernel driver from interface */ |
| 1259 | case USBDEVFS_DISCONNECT: | 1270 | case USBDEVFS_DISCONNECT: |
| 1260 | 1271 | ||
| 1261 | /* don't allow the user to unbind the hub driver from | ||
| 1262 | * a hub with children to manage */ | ||
| 1263 | for (i = 0; i < ps->dev->maxchild; ++i) { | ||
| 1264 | if (ps->dev->children[i]) | ||
| 1265 | retval = -EBUSY; | ||
| 1266 | } | ||
| 1267 | if (retval) | ||
| 1268 | break; | ||
| 1269 | |||
| 1270 | down_write(&usb_bus_type.subsys.rwsem); | 1272 | down_write(&usb_bus_type.subsys.rwsem); |
| 1271 | if (intf->dev.driver) { | 1273 | if (intf->dev.driver) { |
| 1272 | driver = to_usb_driver(intf->dev.driver); | 1274 | driver = to_usb_driver(intf->dev.driver); |
| @@ -1477,3 +1479,79 @@ struct file_operations usbfs_device_file_operations = { | |||
| 1477 | .open = usbdev_open, | 1479 | .open = usbdev_open, |
| 1478 | .release = usbdev_release, | 1480 | .release = usbdev_release, |
| 1479 | }; | 1481 | }; |
| 1482 | |||
| 1483 | struct usb_device *usbdev_lookup_minor(int minor) | ||
| 1484 | { | ||
| 1485 | struct class_device *class_dev; | ||
| 1486 | struct usb_device *dev = NULL; | ||
| 1487 | |||
| 1488 | down(&usb_device_class->sem); | ||
| 1489 | list_for_each_entry(class_dev, &usb_device_class->children, node) { | ||
| 1490 | if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { | ||
| 1491 | dev = class_dev->class_data; | ||
| 1492 | break; | ||
| 1493 | } | ||
| 1494 | } | ||
| 1495 | up(&usb_device_class->sem); | ||
| 1496 | |||
| 1497 | return dev; | ||
| 1498 | }; | ||
| 1499 | |||
| 1500 | void usbdev_add(struct usb_device *dev) | ||
| 1501 | { | ||
| 1502 | int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); | ||
| 1503 | |||
| 1504 | dev->class_dev = class_device_create(usb_device_class, | ||
| 1505 | MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev, | ||
| 1506 | "usbdev%d.%d", dev->bus->busnum, dev->devnum); | ||
| 1507 | |||
| 1508 | dev->class_dev->class_data = dev; | ||
| 1509 | } | ||
| 1510 | |||
| 1511 | void usbdev_remove(struct usb_device *dev) | ||
| 1512 | { | ||
| 1513 | class_device_unregister(dev->class_dev); | ||
| 1514 | } | ||
| 1515 | |||
| 1516 | static struct cdev usb_device_cdev = { | ||
| 1517 | .kobj = {.name = "usb_device", }, | ||
| 1518 | .owner = THIS_MODULE, | ||
| 1519 | }; | ||
| 1520 | |||
| 1521 | int __init usbdev_init(void) | ||
| 1522 | { | ||
| 1523 | int retval; | ||
| 1524 | |||
| 1525 | retval = register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX, | ||
| 1526 | "usb_device"); | ||
| 1527 | if (retval) { | ||
| 1528 | err("unable to register minors for usb_device"); | ||
| 1529 | goto out; | ||
| 1530 | } | ||
| 1531 | cdev_init(&usb_device_cdev, &usbfs_device_file_operations); | ||
| 1532 | retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX); | ||
| 1533 | if (retval) { | ||
| 1534 | err("unable to get usb_device major %d", USB_DEVICE_MAJOR); | ||
| 1535 | unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); | ||
| 1536 | goto out; | ||
| 1537 | } | ||
| 1538 | usb_device_class = class_create(THIS_MODULE, "usb_device"); | ||
| 1539 | if (IS_ERR(usb_device_class)) { | ||
| 1540 | err("unable to register usb_device class"); | ||
| 1541 | retval = PTR_ERR(usb_device_class); | ||
| 1542 | usb_device_class = NULL; | ||
| 1543 | cdev_del(&usb_device_cdev); | ||
| 1544 | unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); | ||
| 1545 | } | ||
| 1546 | |||
| 1547 | out: | ||
| 1548 | return retval; | ||
| 1549 | } | ||
| 1550 | |||
| 1551 | void usbdev_cleanup(void) | ||
| 1552 | { | ||
| 1553 | class_destroy(usb_device_class); | ||
| 1554 | cdev_del(&usb_device_cdev); | ||
| 1555 | unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); | ||
| 1556 | } | ||
| 1557 | |||
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index fc056062c960..cbb451d227d2 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c | |||
| @@ -121,10 +121,6 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id) | |||
| 121 | } | 121 | } |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | #ifdef CONFIG_PCI_NAMES | ||
| 125 | hcd->product_desc = dev->pretty_name; | ||
| 126 | #endif | ||
| 127 | |||
| 128 | pci_set_master (dev); | 124 | pci_set_master (dev); |
| 129 | 125 | ||
| 130 | retval = usb_add_hcd (hcd, dev->irq, SA_SHIRQ); | 126 | retval = usb_add_hcd (hcd, dev->irq, SA_SHIRQ); |
| @@ -264,8 +260,10 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) | |||
| 264 | retval = pci_set_power_state (dev, PCI_D3hot); | 260 | retval = pci_set_power_state (dev, PCI_D3hot); |
| 265 | if (retval == 0) { | 261 | if (retval == 0) { |
| 266 | dev_dbg (hcd->self.controller, "--> PCI D3\n"); | 262 | dev_dbg (hcd->self.controller, "--> PCI D3\n"); |
| 267 | pci_enable_wake (dev, PCI_D3hot, hcd->remote_wakeup); | 263 | retval = pci_enable_wake (dev, PCI_D3hot, hcd->remote_wakeup); |
| 268 | pci_enable_wake (dev, PCI_D3cold, hcd->remote_wakeup); | 264 | if (retval) |
| 265 | break; | ||
| 266 | retval = pci_enable_wake (dev, PCI_D3cold, hcd->remote_wakeup); | ||
| 269 | } else if (retval < 0) { | 267 | } else if (retval < 0) { |
| 270 | dev_dbg (&dev->dev, "PCI D3 suspend fail, %d\n", | 268 | dev_dbg (&dev->dev, "PCI D3 suspend fail, %d\n", |
| 271 | retval); | 269 | retval); |
| @@ -339,8 +337,20 @@ int usb_hcd_pci_resume (struct pci_dev *dev) | |||
| 339 | dev->current_state); | 337 | dev->current_state); |
| 340 | } | 338 | } |
| 341 | #endif | 339 | #endif |
| 342 | pci_enable_wake (dev, dev->current_state, 0); | 340 | retval = pci_enable_wake (dev, dev->current_state, 0); |
| 343 | pci_enable_wake (dev, PCI_D3cold, 0); | 341 | if (retval) { |
| 342 | dev_err(hcd->self.controller, | ||
| 343 | "can't enable_wake to %d, %d!\n", | ||
| 344 | dev->current_state, retval); | ||
| 345 | return retval; | ||
| 346 | } | ||
| 347 | retval = pci_enable_wake (dev, PCI_D3cold, 0); | ||
| 348 | if (retval) { | ||
| 349 | dev_err(hcd->self.controller, | ||
| 350 | "can't enable_wake to %d, %d!\n", | ||
| 351 | PCI_D3cold, retval); | ||
| 352 | return retval; | ||
| 353 | } | ||
| 344 | } else { | 354 | } else { |
| 345 | /* Same basic cases: clean (powered/not), dirty */ | 355 | /* Same basic cases: clean (powered/not), dirty */ |
| 346 | dev_dbg(hcd->self.controller, "PCI legacy resume\n"); | 356 | dev_dbg(hcd->self.controller, "PCI legacy resume\n"); |
| @@ -380,7 +390,7 @@ int usb_hcd_pci_resume (struct pci_dev *dev) | |||
| 380 | usb_hc_died (hcd); | 390 | usb_hc_died (hcd); |
| 381 | } | 391 | } |
| 382 | 392 | ||
| 383 | pci_enable_device(dev); | 393 | retval = pci_enable_device(dev); |
| 384 | return retval; | 394 | return retval; |
| 385 | } | 395 | } |
| 386 | EXPORT_SYMBOL (usb_hcd_pci_resume); | 396 | EXPORT_SYMBOL (usb_hcd_pci_resume); |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 12ecdb03ee5f..1017a97a418b 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
| @@ -1606,7 +1606,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs * r) | |||
| 1606 | return IRQ_NONE; | 1606 | return IRQ_NONE; |
| 1607 | 1607 | ||
| 1608 | hcd->saw_irq = 1; | 1608 | hcd->saw_irq = 1; |
| 1609 | if (hcd->state != start && hcd->state == HC_STATE_HALT) | 1609 | if (hcd->state == HC_STATE_HALT) |
| 1610 | usb_hc_died (hcd); | 1610 | usb_hc_died (hcd); |
| 1611 | return IRQ_HANDLED; | 1611 | return IRQ_HANDLED; |
| 1612 | } | 1612 | } |
| @@ -1630,7 +1630,6 @@ void usb_hc_died (struct usb_hcd *hcd) | |||
| 1630 | spin_lock_irqsave (&hcd_root_hub_lock, flags); | 1630 | spin_lock_irqsave (&hcd_root_hub_lock, flags); |
| 1631 | if (hcd->rh_registered) { | 1631 | if (hcd->rh_registered) { |
| 1632 | hcd->poll_rh = 0; | 1632 | hcd->poll_rh = 0; |
| 1633 | del_timer(&hcd->rh_timer); | ||
| 1634 | 1633 | ||
| 1635 | /* make khubd clean up old urbs and devices */ | 1634 | /* make khubd clean up old urbs and devices */ |
| 1636 | usb_set_device_state (hcd->self.root_hub, | 1635 | usb_set_device_state (hcd->self.root_hub, |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 28055f95645b..ac451fa7e4d2 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
| @@ -339,11 +339,11 @@ extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb); | |||
| 339 | * to preallocate bandwidth) | 339 | * to preallocate bandwidth) |
| 340 | */ | 340 | */ |
| 341 | #define USB2_HOST_DELAY 5 /* nsec, guess */ | 341 | #define USB2_HOST_DELAY 5 /* nsec, guess */ |
| 342 | #define HS_NSECS(bytes) ( ((55 * 8 * 2083)/1000) \ | 342 | #define HS_NSECS(bytes) ( ((55 * 8 * 2083) \ |
| 343 | + ((2083UL * (3167 + BitTime (bytes)))/1000) \ | 343 | + (2083UL * (3 + BitTime(bytes))))/1000 \ |
| 344 | + USB2_HOST_DELAY) | 344 | + USB2_HOST_DELAY) |
| 345 | #define HS_NSECS_ISO(bytes) ( ((38 * 8 * 2083)/1000) \ | 345 | #define HS_NSECS_ISO(bytes) ( ((38 * 8 * 2083) \ |
| 346 | + ((2083UL * (3167 + BitTime (bytes)))/1000) \ | 346 | + (2083UL * (3 + BitTime(bytes))))/1000 \ |
| 347 | + USB2_HOST_DELAY) | 347 | + USB2_HOST_DELAY) |
| 348 | #define HS_USECS(bytes) NS_TO_US (HS_NSECS(bytes)) | 348 | #define HS_USECS(bytes) NS_TO_US (HS_NSECS(bytes)) |
| 349 | #define HS_USECS_ISO(bytes) NS_TO_US (HS_NSECS_ISO(bytes)) | 349 | #define HS_USECS_ISO(bytes) NS_TO_US (HS_NSECS_ISO(bytes)) |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index c9412daff682..a12cab5314e9 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
| @@ -435,6 +435,7 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe) | |||
| 435 | static void hub_power_on(struct usb_hub *hub) | 435 | static void hub_power_on(struct usb_hub *hub) |
| 436 | { | 436 | { |
| 437 | int port1; | 437 | int port1; |
| 438 | unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2; | ||
| 438 | 439 | ||
| 439 | /* if hub supports power switching, enable power on each port */ | 440 | /* if hub supports power switching, enable power on each port */ |
| 440 | if ((hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) < 2) { | 441 | if ((hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) < 2) { |
| @@ -444,8 +445,8 @@ static void hub_power_on(struct usb_hub *hub) | |||
| 444 | USB_PORT_FEAT_POWER); | 445 | USB_PORT_FEAT_POWER); |
| 445 | } | 446 | } |
| 446 | 447 | ||
| 447 | /* Wait for power to be enabled */ | 448 | /* Wait at least 100 msec for power to become stable */ |
| 448 | msleep(hub->descriptor->bPwrOn2PwrGood * 2); | 449 | msleep(max(pgood_delay, (unsigned) 100)); |
| 449 | } | 450 | } |
| 450 | 451 | ||
| 451 | static void hub_quiesce(struct usb_hub *hub) | 452 | static void hub_quiesce(struct usb_hub *hub) |
| @@ -492,6 +493,23 @@ static int hub_hub_status(struct usb_hub *hub, | |||
| 492 | return ret; | 493 | return ret; |
| 493 | } | 494 | } |
| 494 | 495 | ||
| 496 | static int hub_port_disable(struct usb_hub *hub, int port1, int set_state) | ||
| 497 | { | ||
| 498 | struct usb_device *hdev = hub->hdev; | ||
| 499 | int ret; | ||
| 500 | |||
| 501 | if (hdev->children[port1-1] && set_state) { | ||
| 502 | usb_set_device_state(hdev->children[port1-1], | ||
| 503 | USB_STATE_NOTATTACHED); | ||
| 504 | } | ||
| 505 | ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE); | ||
| 506 | if (ret) | ||
| 507 | dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n", | ||
| 508 | port1, ret); | ||
| 509 | |||
| 510 | return ret; | ||
| 511 | } | ||
| 512 | |||
| 495 | static int hub_configure(struct usb_hub *hub, | 513 | static int hub_configure(struct usb_hub *hub, |
| 496 | struct usb_endpoint_descriptor *endpoint) | 514 | struct usb_endpoint_descriptor *endpoint) |
| 497 | { | 515 | { |
| @@ -610,19 +628,33 @@ static int hub_configure(struct usb_hub *hub, | |||
| 610 | break; | 628 | break; |
| 611 | } | 629 | } |
| 612 | 630 | ||
| 631 | /* Note 8 FS bit times == (8 bits / 12000000 bps) ~= 666ns */ | ||
| 613 | switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_TTTT) { | 632 | switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_TTTT) { |
| 614 | case 0x00: | 633 | case HUB_TTTT_8_BITS: |
| 615 | if (hdev->descriptor.bDeviceProtocol != 0) | 634 | if (hdev->descriptor.bDeviceProtocol != 0) { |
| 616 | dev_dbg(hub_dev, "TT requires at most 8 FS bit times\n"); | 635 | hub->tt.think_time = 666; |
| 636 | dev_dbg(hub_dev, "TT requires at most %d " | ||
| 637 | "FS bit times (%d ns)\n", | ||
| 638 | 8, hub->tt.think_time); | ||
| 639 | } | ||
| 617 | break; | 640 | break; |
| 618 | case 0x20: | 641 | case HUB_TTTT_16_BITS: |
| 619 | dev_dbg(hub_dev, "TT requires at most 16 FS bit times\n"); | 642 | hub->tt.think_time = 666 * 2; |
| 643 | dev_dbg(hub_dev, "TT requires at most %d " | ||
| 644 | "FS bit times (%d ns)\n", | ||
| 645 | 16, hub->tt.think_time); | ||
| 620 | break; | 646 | break; |
| 621 | case 0x40: | 647 | case HUB_TTTT_24_BITS: |
| 622 | dev_dbg(hub_dev, "TT requires at most 24 FS bit times\n"); | 648 | hub->tt.think_time = 666 * 3; |
| 649 | dev_dbg(hub_dev, "TT requires at most %d " | ||
| 650 | "FS bit times (%d ns)\n", | ||
| 651 | 24, hub->tt.think_time); | ||
| 623 | break; | 652 | break; |
| 624 | case 0x60: | 653 | case HUB_TTTT_32_BITS: |
| 625 | dev_dbg(hub_dev, "TT requires at most 32 FS bit times\n"); | 654 | hub->tt.think_time = 666 * 4; |
| 655 | dev_dbg(hub_dev, "TT requires at most %d " | ||
| 656 | "FS bit times (%d ns)\n", | ||
| 657 | 32, hub->tt.think_time); | ||
| 626 | break; | 658 | break; |
| 627 | } | 659 | } |
| 628 | 660 | ||
| @@ -712,20 +744,36 @@ fail: | |||
| 712 | 744 | ||
| 713 | static unsigned highspeed_hubs; | 745 | static unsigned highspeed_hubs; |
| 714 | 746 | ||
| 747 | /* Called after the hub driver is unbound from a hub with children */ | ||
| 748 | static void hub_remove_children_work(void *__hub) | ||
| 749 | { | ||
| 750 | struct usb_hub *hub = __hub; | ||
| 751 | struct usb_device *hdev = hub->hdev; | ||
| 752 | int i; | ||
| 753 | |||
| 754 | kfree(hub); | ||
| 755 | |||
| 756 | usb_lock_device(hdev); | ||
| 757 | for (i = 0; i < hdev->maxchild; ++i) { | ||
| 758 | if (hdev->children[i]) | ||
| 759 | usb_disconnect(&hdev->children[i]); | ||
| 760 | } | ||
| 761 | usb_unlock_device(hdev); | ||
| 762 | usb_put_dev(hdev); | ||
| 763 | } | ||
| 764 | |||
| 715 | static void hub_disconnect(struct usb_interface *intf) | 765 | static void hub_disconnect(struct usb_interface *intf) |
| 716 | { | 766 | { |
| 717 | struct usb_hub *hub = usb_get_intfdata (intf); | 767 | struct usb_hub *hub = usb_get_intfdata (intf); |
| 718 | struct usb_device *hdev; | 768 | struct usb_device *hdev; |
| 769 | int n, port1; | ||
| 719 | 770 | ||
| 720 | if (!hub) | 771 | usb_set_intfdata (intf, NULL); |
| 721 | return; | ||
| 722 | hdev = hub->hdev; | 772 | hdev = hub->hdev; |
| 723 | 773 | ||
| 724 | if (hdev->speed == USB_SPEED_HIGH) | 774 | if (hdev->speed == USB_SPEED_HIGH) |
| 725 | highspeed_hubs--; | 775 | highspeed_hubs--; |
| 726 | 776 | ||
| 727 | usb_set_intfdata (intf, NULL); | ||
| 728 | |||
| 729 | hub_quiesce(hub); | 777 | hub_quiesce(hub); |
| 730 | usb_free_urb(hub->urb); | 778 | usb_free_urb(hub->urb); |
| 731 | hub->urb = NULL; | 779 | hub->urb = NULL; |
| @@ -746,8 +794,27 @@ static void hub_disconnect(struct usb_interface *intf) | |||
| 746 | hub->buffer = NULL; | 794 | hub->buffer = NULL; |
| 747 | } | 795 | } |
| 748 | 796 | ||
| 749 | /* Free the memory */ | 797 | /* If there are any children then this is an unbind only, not a |
| 750 | kfree(hub); | 798 | * physical disconnection. The active ports must be disabled |
| 799 | * and later on we must call usb_disconnect(). We can't call | ||
| 800 | * it now because we may not hold the hub's device lock. | ||
| 801 | */ | ||
| 802 | n = 0; | ||
| 803 | for (port1 = 1; port1 <= hdev->maxchild; ++port1) { | ||
| 804 | if (hdev->children[port1 - 1]) { | ||
| 805 | ++n; | ||
| 806 | hub_port_disable(hub, port1, 1); | ||
| 807 | } | ||
| 808 | } | ||
| 809 | |||
| 810 | if (n == 0) | ||
| 811 | kfree(hub); | ||
| 812 | else { | ||
| 813 | /* Reuse the hub->leds work_struct for our own purposes */ | ||
| 814 | INIT_WORK(&hub->leds, hub_remove_children_work, hub); | ||
| 815 | schedule_work(&hub->leds); | ||
| 816 | usb_get_dev(hdev); | ||
| 817 | } | ||
| 751 | } | 818 | } |
| 752 | 819 | ||
| 753 | static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) | 820 | static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) |
| @@ -1051,6 +1118,7 @@ void usb_disconnect(struct usb_device **pdev) | |||
| 1051 | dev_dbg (&udev->dev, "unregistering device\n"); | 1118 | dev_dbg (&udev->dev, "unregistering device\n"); |
| 1052 | release_address(udev); | 1119 | release_address(udev); |
| 1053 | usbfs_remove_device(udev); | 1120 | usbfs_remove_device(udev); |
| 1121 | usbdev_remove(udev); | ||
| 1054 | usb_remove_sysfs_dev_files(udev); | 1122 | usb_remove_sysfs_dev_files(udev); |
| 1055 | 1123 | ||
| 1056 | /* Avoid races with recursively_mark_NOTATTACHED() */ | 1124 | /* Avoid races with recursively_mark_NOTATTACHED() */ |
| @@ -1290,6 +1358,7 @@ int usb_new_device(struct usb_device *udev) | |||
| 1290 | /* USB device state == configured ... usable */ | 1358 | /* USB device state == configured ... usable */ |
| 1291 | 1359 | ||
| 1292 | /* add a /proc/bus/usb entry */ | 1360 | /* add a /proc/bus/usb entry */ |
| 1361 | usbdev_add(udev); | ||
| 1293 | usbfs_add_device(udev); | 1362 | usbfs_add_device(udev); |
| 1294 | return 0; | 1363 | return 0; |
| 1295 | 1364 | ||
| @@ -1392,7 +1461,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
| 1392 | port1, status); | 1461 | port1, status); |
| 1393 | else { | 1462 | else { |
| 1394 | status = hub_port_wait_reset(hub, port1, udev, delay); | 1463 | status = hub_port_wait_reset(hub, port1, udev, delay); |
| 1395 | if (status) | 1464 | if (status && status != -ENOTCONN) |
| 1396 | dev_dbg(hub->intfdev, | 1465 | dev_dbg(hub->intfdev, |
| 1397 | "port_wait_reset: err = %d\n", | 1466 | "port_wait_reset: err = %d\n", |
| 1398 | status); | 1467 | status); |
| @@ -1401,8 +1470,8 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
| 1401 | /* return on disconnect or reset */ | 1470 | /* return on disconnect or reset */ |
| 1402 | switch (status) { | 1471 | switch (status) { |
| 1403 | case 0: | 1472 | case 0: |
| 1404 | /* TRSTRCY = 10 ms */ | 1473 | /* TRSTRCY = 10 ms; plus some extra */ |
| 1405 | msleep(10); | 1474 | msleep(10 + 40); |
| 1406 | /* FALL THROUGH */ | 1475 | /* FALL THROUGH */ |
| 1407 | case -ENOTCONN: | 1476 | case -ENOTCONN: |
| 1408 | case -ENODEV: | 1477 | case -ENODEV: |
| @@ -1428,23 +1497,6 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
| 1428 | return status; | 1497 | return status; |
| 1429 | } | 1498 | } |
| 1430 | 1499 | ||
| 1431 | static int hub_port_disable(struct usb_hub *hub, int port1, int set_state) | ||
| 1432 | { | ||
| 1433 | struct usb_device *hdev = hub->hdev; | ||
| 1434 | int ret; | ||
| 1435 | |||
| 1436 | if (hdev->children[port1-1] && set_state) { | ||
| 1437 | usb_set_device_state(hdev->children[port1-1], | ||
| 1438 | USB_STATE_NOTATTACHED); | ||
| 1439 | } | ||
| 1440 | ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE); | ||
| 1441 | if (ret) | ||
| 1442 | dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n", | ||
| 1443 | port1, ret); | ||
| 1444 | |||
| 1445 | return ret; | ||
| 1446 | } | ||
| 1447 | |||
| 1448 | /* | 1500 | /* |
| 1449 | * Disable a port and mark a logical connnect-change event, so that some | 1501 | * Disable a port and mark a logical connnect-change event, so that some |
| 1450 | * time later khubd will disconnect() any existing usb_device on the port | 1502 | * time later khubd will disconnect() any existing usb_device on the port |
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index 53bf5649621e..e7fa9b5a521e 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h | |||
| @@ -157,6 +157,12 @@ enum hub_led_mode { | |||
| 157 | 157 | ||
| 158 | struct usb_device; | 158 | struct usb_device; |
| 159 | 159 | ||
| 160 | /* Transaction Translator Think Times, in bits */ | ||
| 161 | #define HUB_TTTT_8_BITS 0x00 | ||
| 162 | #define HUB_TTTT_16_BITS 0x20 | ||
| 163 | #define HUB_TTTT_24_BITS 0x40 | ||
| 164 | #define HUB_TTTT_32_BITS 0x60 | ||
| 165 | |||
| 160 | /* | 166 | /* |
| 161 | * As of USB 2.0, full/low speed devices are segregated into trees. | 167 | * As of USB 2.0, full/low speed devices are segregated into trees. |
| 162 | * One type grows from USB 1.1 host controllers (OHCI, UHCI etc). | 168 | * One type grows from USB 1.1 host controllers (OHCI, UHCI etc). |
| @@ -170,6 +176,7 @@ struct usb_device; | |||
| 170 | struct usb_tt { | 176 | struct usb_tt { |
| 171 | struct usb_device *hub; /* upstream highspeed hub */ | 177 | struct usb_device *hub; /* upstream highspeed hub */ |
| 172 | int multi; /* true means one TT per port */ | 178 | int multi; /* true means one TT per port */ |
| 179 | unsigned think_time; /* think time in ns */ | ||
| 173 | 180 | ||
| 174 | /* for control/bulk error recovery (CLEAR_TT_BUFFER) */ | 181 | /* for control/bulk error recovery (CLEAR_TT_BUFFER) */ |
| 175 | spinlock_t lock; | 182 | spinlock_t lock; |
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index c3e3a95d3804..640f41e47029 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c | |||
| @@ -728,15 +728,9 @@ int __init usbfs_init(void) | |||
| 728 | { | 728 | { |
| 729 | int retval; | 729 | int retval; |
| 730 | 730 | ||
| 731 | retval = usb_register(&usbfs_driver); | ||
| 732 | if (retval) | ||
| 733 | return retval; | ||
| 734 | |||
| 735 | retval = register_filesystem(&usb_fs_type); | 731 | retval = register_filesystem(&usb_fs_type); |
| 736 | if (retval) { | 732 | if (retval) |
| 737 | usb_deregister(&usbfs_driver); | ||
| 738 | return retval; | 733 | return retval; |
| 739 | } | ||
| 740 | 734 | ||
| 741 | /* create mount point for usbfs */ | 735 | /* create mount point for usbfs */ |
| 742 | usbdir = proc_mkdir("usb", proc_bus); | 736 | usbdir = proc_mkdir("usb", proc_bus); |
| @@ -746,7 +740,6 @@ int __init usbfs_init(void) | |||
| 746 | 740 | ||
| 747 | void usbfs_cleanup(void) | 741 | void usbfs_cleanup(void) |
| 748 | { | 742 | { |
| 749 | usb_deregister(&usbfs_driver); | ||
| 750 | unregister_filesystem(&usb_fs_type); | 743 | unregister_filesystem(&usb_fs_type); |
| 751 | if (usbdir) | 744 | if (usbdir) |
| 752 | remove_proc_entry("usb", proc_bus); | 745 | remove_proc_entry("usb", proc_bus); |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 88d1b376f67c..c47c8052b486 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
| @@ -48,7 +48,6 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length) | |||
| 48 | 48 | ||
| 49 | init_completion(&done); | 49 | init_completion(&done); |
| 50 | urb->context = &done; | 50 | urb->context = &done; |
| 51 | urb->transfer_flags |= URB_ASYNC_UNLINK; | ||
| 52 | urb->actual_length = 0; | 51 | urb->actual_length = 0; |
| 53 | status = usb_submit_urb(urb, GFP_NOIO); | 52 | status = usb_submit_urb(urb, GFP_NOIO); |
| 54 | 53 | ||
| @@ -266,7 +265,9 @@ static void sg_complete (struct urb *urb, struct pt_regs *regs) | |||
| 266 | continue; | 265 | continue; |
| 267 | if (found) { | 266 | if (found) { |
| 268 | status = usb_unlink_urb (io->urbs [i]); | 267 | status = usb_unlink_urb (io->urbs [i]); |
| 269 | if (status != -EINPROGRESS && status != -EBUSY) | 268 | if (status != -EINPROGRESS |
| 269 | && status != -ENODEV | ||
| 270 | && status != -EBUSY) | ||
| 270 | dev_err (&io->dev->dev, | 271 | dev_err (&io->dev->dev, |
| 271 | "%s, unlink --> %d\n", | 272 | "%s, unlink --> %d\n", |
| 272 | __FUNCTION__, status); | 273 | __FUNCTION__, status); |
| @@ -357,8 +358,7 @@ int usb_sg_init ( | |||
| 357 | if (!io->urbs) | 358 | if (!io->urbs) |
| 358 | goto nomem; | 359 | goto nomem; |
| 359 | 360 | ||
| 360 | urb_flags = URB_ASYNC_UNLINK | URB_NO_TRANSFER_DMA_MAP | 361 | urb_flags = URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT; |
| 361 | | URB_NO_INTERRUPT; | ||
| 362 | if (usb_pipein (pipe)) | 362 | if (usb_pipein (pipe)) |
| 363 | urb_flags |= URB_SHORT_NOT_OK; | 363 | urb_flags |= URB_SHORT_NOT_OK; |
| 364 | 364 | ||
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index c0feee25ff0a..c846fefb7386 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
| @@ -309,9 +309,8 @@ int usb_submit_urb(struct urb *urb, unsigned mem_flags) | |||
| 309 | unsigned int allowed; | 309 | unsigned int allowed; |
| 310 | 310 | ||
| 311 | /* enforce simple/standard policy */ | 311 | /* enforce simple/standard policy */ |
| 312 | allowed = URB_ASYNC_UNLINK; // affects later unlinks | 312 | allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | |
| 313 | allowed |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); | 313 | URB_NO_INTERRUPT); |
| 314 | allowed |= URB_NO_INTERRUPT; | ||
| 315 | switch (temp) { | 314 | switch (temp) { |
| 316 | case PIPE_BULK: | 315 | case PIPE_BULK: |
| 317 | if (is_out) | 316 | if (is_out) |
| @@ -400,14 +399,8 @@ int usb_submit_urb(struct urb *urb, unsigned mem_flags) | |||
| 400 | * canceled (rather than any other code) and will quickly be removed | 399 | * canceled (rather than any other code) and will quickly be removed |
| 401 | * from host controller data structures. | 400 | * from host controller data structures. |
| 402 | * | 401 | * |
| 403 | * In the past, clearing the URB_ASYNC_UNLINK transfer flag for the | 402 | * This request is always asynchronous. |
| 404 | * URB indicated that the request was synchronous. This usage is now | 403 | * Success is indicated by returning -EINPROGRESS, |
| 405 | * deprecated; if the flag is clear the call will be forwarded to | ||
| 406 | * usb_kill_urb() and the return value will be 0. In the future, drivers | ||
| 407 | * should call usb_kill_urb() directly for synchronous unlinking. | ||
| 408 | * | ||
| 409 | * When the URB_ASYNC_UNLINK transfer flag for the URB is set, this | ||
| 410 | * request is asynchronous. Success is indicated by returning -EINPROGRESS, | ||
| 411 | * at which time the URB will normally have been unlinked but not yet | 404 | * at which time the URB will normally have been unlinked but not yet |
| 412 | * given back to the device driver. When it is called, the completion | 405 | * given back to the device driver. When it is called, the completion |
| 413 | * function will see urb->status == -ECONNRESET. Failure is indicated | 406 | * function will see urb->status == -ECONNRESET. Failure is indicated |
| @@ -453,17 +446,6 @@ int usb_unlink_urb(struct urb *urb) | |||
| 453 | { | 446 | { |
| 454 | if (!urb) | 447 | if (!urb) |
| 455 | return -EINVAL; | 448 | return -EINVAL; |
| 456 | if (!(urb->transfer_flags & URB_ASYNC_UNLINK)) { | ||
| 457 | #ifdef CONFIG_DEBUG_KERNEL | ||
| 458 | if (printk_ratelimit()) { | ||
| 459 | printk(KERN_NOTICE "usb_unlink_urb() is deprecated for " | ||
| 460 | "synchronous unlinks. Use usb_kill_urb() instead.\n"); | ||
| 461 | WARN_ON(1); | ||
| 462 | } | ||
| 463 | #endif | ||
| 464 | usb_kill_urb(urb); | ||
| 465 | return 0; | ||
| 466 | } | ||
| 467 | if (!(urb->dev && urb->dev->bus && urb->dev->bus->op)) | 449 | if (!(urb->dev && urb->dev->bus && urb->dev->bus->op)) |
| 468 | return -ENODEV; | 450 | return -ENODEV; |
| 469 | return urb->dev->bus->op->unlink_urb(urb, -ECONNRESET); | 451 | return urb->dev->bus->op->unlink_urb(urb, -ECONNRESET); |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 2cddd8a00437..087af73a59dd 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
| @@ -65,6 +65,16 @@ static int generic_probe (struct device *dev) | |||
| 65 | } | 65 | } |
| 66 | static int generic_remove (struct device *dev) | 66 | static int generic_remove (struct device *dev) |
| 67 | { | 67 | { |
| 68 | struct usb_device *udev = to_usb_device(dev); | ||
| 69 | |||
| 70 | /* if this is only an unbind, not a physical disconnect, then | ||
| 71 | * unconfigure the device */ | ||
| 72 | if (udev->state == USB_STATE_CONFIGURED) | ||
| 73 | usb_set_configuration(udev, 0); | ||
| 74 | |||
| 75 | /* in case the call failed or the device was suspended */ | ||
| 76 | if (udev->state >= USB_STATE_CONFIGURED) | ||
| 77 | usb_disable_device(udev, 0); | ||
| 68 | return 0; | 78 | return 0; |
| 69 | } | 79 | } |
| 70 | 80 | ||
| @@ -912,7 +922,7 @@ int usb_trylock_device(struct usb_device *udev) | |||
| 912 | * is neither BINDING nor BOUND. Rather than sleeping to wait for the | 922 | * is neither BINDING nor BOUND. Rather than sleeping to wait for the |
| 913 | * lock, the routine polls repeatedly. This is to prevent deadlock with | 923 | * lock, the routine polls repeatedly. This is to prevent deadlock with |
| 914 | * disconnect; in some drivers (such as usb-storage) the disconnect() | 924 | * disconnect; in some drivers (such as usb-storage) the disconnect() |
| 915 | * callback will block waiting for a device reset to complete. | 925 | * or suspend() method will block waiting for a device reset to complete. |
| 916 | * | 926 | * |
| 917 | * Returns a negative error code for failure, otherwise 1 or 0 to indicate | 927 | * Returns a negative error code for failure, otherwise 1 or 0 to indicate |
| 918 | * that the device will or will not have to be unlocked. (0 can be | 928 | * that the device will or will not have to be unlocked. (0 can be |
| @@ -922,6 +932,8 @@ int usb_trylock_device(struct usb_device *udev) | |||
| 922 | int usb_lock_device_for_reset(struct usb_device *udev, | 932 | int usb_lock_device_for_reset(struct usb_device *udev, |
| 923 | struct usb_interface *iface) | 933 | struct usb_interface *iface) |
| 924 | { | 934 | { |
| 935 | unsigned long jiffies_expire = jiffies + HZ; | ||
| 936 | |||
| 925 | if (udev->state == USB_STATE_NOTATTACHED) | 937 | if (udev->state == USB_STATE_NOTATTACHED) |
| 926 | return -ENODEV; | 938 | return -ENODEV; |
| 927 | if (udev->state == USB_STATE_SUSPENDED) | 939 | if (udev->state == USB_STATE_SUSPENDED) |
| @@ -938,6 +950,12 @@ int usb_lock_device_for_reset(struct usb_device *udev, | |||
| 938 | } | 950 | } |
| 939 | 951 | ||
| 940 | while (!usb_trylock_device(udev)) { | 952 | while (!usb_trylock_device(udev)) { |
| 953 | |||
| 954 | /* If we can't acquire the lock after waiting one second, | ||
| 955 | * we're probably deadlocked */ | ||
| 956 | if (time_after(jiffies, jiffies_expire)) | ||
| 957 | return -EBUSY; | ||
| 958 | |||
| 941 | msleep(15); | 959 | msleep(15); |
| 942 | if (udev->state == USB_STATE_NOTATTACHED) | 960 | if (udev->state == USB_STATE_NOTATTACHED) |
| 943 | return -ENODEV; | 961 | return -ENODEV; |
| @@ -1478,13 +1496,18 @@ static int __init usb_init(void) | |||
| 1478 | retval = usb_major_init(); | 1496 | retval = usb_major_init(); |
| 1479 | if (retval) | 1497 | if (retval) |
| 1480 | goto major_init_failed; | 1498 | goto major_init_failed; |
| 1499 | retval = usb_register(&usbfs_driver); | ||
| 1500 | if (retval) | ||
| 1501 | goto driver_register_failed; | ||
| 1502 | retval = usbdev_init(); | ||
| 1503 | if (retval) | ||
| 1504 | goto usbdevice_init_failed; | ||
| 1481 | retval = usbfs_init(); | 1505 | retval = usbfs_init(); |
| 1482 | if (retval) | 1506 | if (retval) |
| 1483 | goto fs_init_failed; | 1507 | goto fs_init_failed; |
| 1484 | retval = usb_hub_init(); | 1508 | retval = usb_hub_init(); |
| 1485 | if (retval) | 1509 | if (retval) |
| 1486 | goto hub_init_failed; | 1510 | goto hub_init_failed; |
| 1487 | |||
| 1488 | retval = driver_register(&usb_generic_driver); | 1511 | retval = driver_register(&usb_generic_driver); |
| 1489 | if (!retval) | 1512 | if (!retval) |
| 1490 | goto out; | 1513 | goto out; |
| @@ -1493,7 +1516,11 @@ static int __init usb_init(void) | |||
| 1493 | hub_init_failed: | 1516 | hub_init_failed: |
| 1494 | usbfs_cleanup(); | 1517 | usbfs_cleanup(); |
| 1495 | fs_init_failed: | 1518 | fs_init_failed: |
| 1496 | usb_major_cleanup(); | 1519 | usbdev_cleanup(); |
| 1520 | usbdevice_init_failed: | ||
| 1521 | usb_deregister(&usbfs_driver); | ||
| 1522 | driver_register_failed: | ||
| 1523 | usb_major_cleanup(); | ||
| 1497 | major_init_failed: | 1524 | major_init_failed: |
| 1498 | usb_host_cleanup(); | 1525 | usb_host_cleanup(); |
| 1499 | host_init_failed: | 1526 | host_init_failed: |
| @@ -1514,6 +1541,8 @@ static void __exit usb_exit(void) | |||
| 1514 | driver_unregister(&usb_generic_driver); | 1541 | driver_unregister(&usb_generic_driver); |
| 1515 | usb_major_cleanup(); | 1542 | usb_major_cleanup(); |
| 1516 | usbfs_cleanup(); | 1543 | usbfs_cleanup(); |
| 1544 | usb_deregister(&usbfs_driver); | ||
| 1545 | usbdev_cleanup(); | ||
| 1517 | usb_hub_cleanup(); | 1546 | usb_hub_cleanup(); |
| 1518 | usb_host_cleanup(); | 1547 | usb_host_cleanup(); |
| 1519 | bus_unregister(&usb_bus_type); | 1548 | bus_unregister(&usb_bus_type); |
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 2c690f6d4c18..83d48c8133af 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
| @@ -37,6 +37,11 @@ extern struct file_operations usbfs_devices_fops; | |||
| 37 | extern struct file_operations usbfs_device_file_operations; | 37 | extern struct file_operations usbfs_device_file_operations; |
| 38 | extern void usbfs_conn_disc_event(void); | 38 | extern void usbfs_conn_disc_event(void); |
| 39 | 39 | ||
| 40 | extern int usbdev_init(void); | ||
| 41 | extern void usbdev_cleanup(void); | ||
| 42 | extern void usbdev_add(struct usb_device *dev); | ||
| 43 | extern void usbdev_remove(struct usb_device *dev); | ||
| 44 | extern struct usb_device *usbdev_lookup_minor(int minor); | ||
| 40 | 45 | ||
| 41 | struct dev_state { | 46 | struct dev_state { |
| 42 | struct list_head list; /* state list */ | 47 | struct list_head list; /* state list */ |
