diff options
Diffstat (limited to 'drivers/usb/core/usb.c')
-rw-r--r-- | drivers/usb/core/usb.c | 76 |
1 files changed, 61 insertions, 15 deletions
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 927a27dd2f8..a26f73880c3 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/usb.h> | 34 | #include <linux/usb.h> |
35 | #include <linux/mutex.h> | 35 | #include <linux/mutex.h> |
36 | #include <linux/workqueue.h> | 36 | #include <linux/workqueue.h> |
37 | #include <linux/debugfs.h> | ||
37 | 38 | ||
38 | #include <asm/io.h> | 39 | #include <asm/io.h> |
39 | #include <linux/scatterlist.h> | 40 | #include <linux/scatterlist.h> |
@@ -139,8 +140,7 @@ static int __find_interface(struct device *dev, void *data) | |||
139 | struct find_interface_arg *arg = data; | 140 | struct find_interface_arg *arg = data; |
140 | struct usb_interface *intf; | 141 | struct usb_interface *intf; |
141 | 142 | ||
142 | /* can't look at usb devices, only interfaces */ | 143 | if (!is_usb_interface(dev)) |
143 | if (is_usb_device(dev)) | ||
144 | return 0; | 144 | return 0; |
145 | 145 | ||
146 | intf = to_usb_interface(dev); | 146 | intf = to_usb_interface(dev); |
@@ -184,11 +184,16 @@ EXPORT_SYMBOL_GPL(usb_find_interface); | |||
184 | static void usb_release_dev(struct device *dev) | 184 | static void usb_release_dev(struct device *dev) |
185 | { | 185 | { |
186 | struct usb_device *udev; | 186 | struct usb_device *udev; |
187 | struct usb_hcd *hcd; | ||
187 | 188 | ||
188 | udev = to_usb_device(dev); | 189 | udev = to_usb_device(dev); |
190 | hcd = bus_to_hcd(udev->bus); | ||
189 | 191 | ||
190 | usb_destroy_configuration(udev); | 192 | usb_destroy_configuration(udev); |
191 | usb_put_hcd(bus_to_hcd(udev->bus)); | 193 | /* Root hubs aren't real devices, so don't free HCD resources */ |
194 | if (hcd->driver->free_dev && udev->parent) | ||
195 | hcd->driver->free_dev(hcd, udev); | ||
196 | usb_put_hcd(hcd); | ||
192 | kfree(udev->product); | 197 | kfree(udev->product); |
193 | kfree(udev->manufacturer); | 198 | kfree(udev->manufacturer); |
194 | kfree(udev->serial); | 199 | kfree(udev->serial); |
@@ -359,6 +364,13 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, | |||
359 | kfree(dev); | 364 | kfree(dev); |
360 | return NULL; | 365 | return NULL; |
361 | } | 366 | } |
367 | /* Root hubs aren't true devices, so don't allocate HCD resources */ | ||
368 | if (usb_hcd->driver->alloc_dev && parent && | ||
369 | !usb_hcd->driver->alloc_dev(usb_hcd, dev)) { | ||
370 | usb_put_hcd(bus_to_hcd(bus)); | ||
371 | kfree(dev); | ||
372 | return NULL; | ||
373 | } | ||
362 | 374 | ||
363 | device_initialize(&dev->dev); | 375 | device_initialize(&dev->dev); |
364 | dev->dev.bus = &usb_bus_type; | 376 | dev->dev.bus = &usb_bus_type; |
@@ -386,18 +398,24 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, | |||
386 | */ | 398 | */ |
387 | if (unlikely(!parent)) { | 399 | if (unlikely(!parent)) { |
388 | dev->devpath[0] = '0'; | 400 | dev->devpath[0] = '0'; |
401 | dev->route = 0; | ||
389 | 402 | ||
390 | dev->dev.parent = bus->controller; | 403 | dev->dev.parent = bus->controller; |
391 | dev_set_name(&dev->dev, "usb%d", bus->busnum); | 404 | dev_set_name(&dev->dev, "usb%d", bus->busnum); |
392 | root_hub = 1; | 405 | root_hub = 1; |
393 | } else { | 406 | } else { |
394 | /* match any labeling on the hubs; it's one-based */ | 407 | /* match any labeling on the hubs; it's one-based */ |
395 | if (parent->devpath[0] == '0') | 408 | if (parent->devpath[0] == '0') { |
396 | snprintf(dev->devpath, sizeof dev->devpath, | 409 | snprintf(dev->devpath, sizeof dev->devpath, |
397 | "%d", port1); | 410 | "%d", port1); |
398 | else | 411 | /* Root ports are not counted in route string */ |
412 | dev->route = 0; | ||
413 | } else { | ||
399 | snprintf(dev->devpath, sizeof dev->devpath, | 414 | snprintf(dev->devpath, sizeof dev->devpath, |
400 | "%s.%d", parent->devpath, port1); | 415 | "%s.%d", parent->devpath, port1); |
416 | dev->route = parent->route + | ||
417 | (port1 << ((parent->level - 1)*4)); | ||
418 | } | ||
401 | 419 | ||
402 | dev->dev.parent = &parent->dev; | 420 | dev->dev.parent = &parent->dev; |
403 | dev_set_name(&dev->dev, "%d-%s", bus->busnum, dev->devpath); | 421 | dev_set_name(&dev->dev, "%d-%s", bus->busnum, dev->devpath); |
@@ -810,12 +828,12 @@ void usb_buffer_dmasync(struct urb *urb) | |||
810 | return; | 828 | return; |
811 | 829 | ||
812 | if (controller->dma_mask) { | 830 | if (controller->dma_mask) { |
813 | dma_sync_single(controller, | 831 | dma_sync_single_for_cpu(controller, |
814 | urb->transfer_dma, urb->transfer_buffer_length, | 832 | urb->transfer_dma, urb->transfer_buffer_length, |
815 | usb_pipein(urb->pipe) | 833 | usb_pipein(urb->pipe) |
816 | ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 834 | ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
817 | if (usb_pipecontrol(urb->pipe)) | 835 | if (usb_pipecontrol(urb->pipe)) |
818 | dma_sync_single(controller, | 836 | dma_sync_single_for_cpu(controller, |
819 | urb->setup_dma, | 837 | urb->setup_dma, |
820 | sizeof(struct usb_ctrlrequest), | 838 | sizeof(struct usb_ctrlrequest), |
821 | DMA_TO_DEVICE); | 839 | DMA_TO_DEVICE); |
@@ -933,8 +951,8 @@ void usb_buffer_dmasync_sg(const struct usb_device *dev, int is_in, | |||
933 | || !controller->dma_mask) | 951 | || !controller->dma_mask) |
934 | return; | 952 | return; |
935 | 953 | ||
936 | dma_sync_sg(controller, sg, n_hw_ents, | 954 | dma_sync_sg_for_cpu(controller, sg, n_hw_ents, |
937 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 955 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
938 | } | 956 | } |
939 | EXPORT_SYMBOL_GPL(usb_buffer_dmasync_sg); | 957 | EXPORT_SYMBOL_GPL(usb_buffer_dmasync_sg); |
940 | #endif | 958 | #endif |
@@ -1012,6 +1030,35 @@ static struct notifier_block usb_bus_nb = { | |||
1012 | .notifier_call = usb_bus_notify, | 1030 | .notifier_call = usb_bus_notify, |
1013 | }; | 1031 | }; |
1014 | 1032 | ||
1033 | struct dentry *usb_debug_root; | ||
1034 | EXPORT_SYMBOL_GPL(usb_debug_root); | ||
1035 | |||
1036 | struct dentry *usb_debug_devices; | ||
1037 | |||
1038 | static int usb_debugfs_init(void) | ||
1039 | { | ||
1040 | usb_debug_root = debugfs_create_dir("usb", NULL); | ||
1041 | if (!usb_debug_root) | ||
1042 | return -ENOENT; | ||
1043 | |||
1044 | usb_debug_devices = debugfs_create_file("devices", 0444, | ||
1045 | usb_debug_root, NULL, | ||
1046 | &usbfs_devices_fops); | ||
1047 | if (!usb_debug_devices) { | ||
1048 | debugfs_remove(usb_debug_root); | ||
1049 | usb_debug_root = NULL; | ||
1050 | return -ENOENT; | ||
1051 | } | ||
1052 | |||
1053 | return 0; | ||
1054 | } | ||
1055 | |||
1056 | static void usb_debugfs_cleanup(void) | ||
1057 | { | ||
1058 | debugfs_remove(usb_debug_devices); | ||
1059 | debugfs_remove(usb_debug_root); | ||
1060 | } | ||
1061 | |||
1015 | /* | 1062 | /* |
1016 | * Init | 1063 | * Init |
1017 | */ | 1064 | */ |
@@ -1023,6 +1070,10 @@ static int __init usb_init(void) | |||
1023 | return 0; | 1070 | return 0; |
1024 | } | 1071 | } |
1025 | 1072 | ||
1073 | retval = usb_debugfs_init(); | ||
1074 | if (retval) | ||
1075 | goto out; | ||
1076 | |||
1026 | retval = ksuspend_usb_init(); | 1077 | retval = ksuspend_usb_init(); |
1027 | if (retval) | 1078 | if (retval) |
1028 | goto out; | 1079 | goto out; |
@@ -1032,9 +1083,6 @@ static int __init usb_init(void) | |||
1032 | retval = bus_register_notifier(&usb_bus_type, &usb_bus_nb); | 1083 | retval = bus_register_notifier(&usb_bus_type, &usb_bus_nb); |
1033 | if (retval) | 1084 | if (retval) |
1034 | goto bus_notifier_failed; | 1085 | goto bus_notifier_failed; |
1035 | retval = usb_host_init(); | ||
1036 | if (retval) | ||
1037 | goto host_init_failed; | ||
1038 | retval = usb_major_init(); | 1086 | retval = usb_major_init(); |
1039 | if (retval) | 1087 | if (retval) |
1040 | goto major_init_failed; | 1088 | goto major_init_failed; |
@@ -1064,8 +1112,6 @@ usb_devio_init_failed: | |||
1064 | driver_register_failed: | 1112 | driver_register_failed: |
1065 | usb_major_cleanup(); | 1113 | usb_major_cleanup(); |
1066 | major_init_failed: | 1114 | major_init_failed: |
1067 | usb_host_cleanup(); | ||
1068 | host_init_failed: | ||
1069 | bus_unregister_notifier(&usb_bus_type, &usb_bus_nb); | 1115 | bus_unregister_notifier(&usb_bus_type, &usb_bus_nb); |
1070 | bus_notifier_failed: | 1116 | bus_notifier_failed: |
1071 | bus_unregister(&usb_bus_type); | 1117 | bus_unregister(&usb_bus_type); |
@@ -1090,10 +1136,10 @@ static void __exit usb_exit(void) | |||
1090 | usb_deregister(&usbfs_driver); | 1136 | usb_deregister(&usbfs_driver); |
1091 | usb_devio_cleanup(); | 1137 | usb_devio_cleanup(); |
1092 | usb_hub_cleanup(); | 1138 | usb_hub_cleanup(); |
1093 | usb_host_cleanup(); | ||
1094 | bus_unregister_notifier(&usb_bus_type, &usb_bus_nb); | 1139 | bus_unregister_notifier(&usb_bus_type, &usb_bus_nb); |
1095 | bus_unregister(&usb_bus_type); | 1140 | bus_unregister(&usb_bus_type); |
1096 | ksuspend_usb_cleanup(); | 1141 | ksuspend_usb_cleanup(); |
1142 | usb_debugfs_cleanup(); | ||
1097 | } | 1143 | } |
1098 | 1144 | ||
1099 | subsys_initcall(usb_init); | 1145 | subsys_initcall(usb_init); |