diff options
author | Dmitry Torokhov <dtor_core@ameritech.net> | 2006-06-26 01:31:38 -0400 |
---|---|---|
committer | Dmitry Torokhov <dtor_core@ameritech.net> | 2006-06-26 01:31:38 -0400 |
commit | 4854c7b27f0975a2b629f35ea3996d2968eb7c4f (patch) | |
tree | 4102bdb70289764a2058aff0f907b13d7cf0e0d1 /drivers/usb/core | |
parent | 3cbd5b32cb625f5c0f1b1476d154fac873dd49ce (diff) | |
parent | fcc18e83e1f6fd9fa6b333735bf0fcd530655511 (diff) |
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/usb/core')
-rw-r--r-- | drivers/usb/core/Makefile | 3 | ||||
-rw-r--r-- | drivers/usb/core/devio.c | 30 | ||||
-rw-r--r-- | drivers/usb/core/endpoint.c | 275 | ||||
-rw-r--r-- | drivers/usb/core/file.c | 79 | ||||
-rw-r--r-- | drivers/usb/core/hcd.c | 12 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 153 | ||||
-rw-r--r-- | drivers/usb/core/inode.c | 8 | ||||
-rw-r--r-- | drivers/usb/core/message.c | 182 | ||||
-rw-r--r-- | drivers/usb/core/sysfs.c | 201 | ||||
-rw-r--r-- | drivers/usb/core/usb.c | 3 | ||||
-rw-r--r-- | drivers/usb/core/usb.h | 3 |
11 files changed, 591 insertions, 358 deletions
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile index 28329ddf187c..ec510922af63 100644 --- a/drivers/usb/core/Makefile +++ b/drivers/usb/core/Makefile | |||
@@ -3,7 +3,8 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | usbcore-objs := usb.o hub.o hcd.o urb.o message.o driver.o \ | 5 | usbcore-objs := usb.o hub.o hcd.o urb.o message.o driver.o \ |
6 | config.o file.o buffer.o sysfs.o devio.o notify.o | 6 | config.o file.o buffer.o sysfs.o endpoint.o \ |
7 | devio.o notify.o | ||
7 | 8 | ||
8 | ifeq ($(CONFIG_PCI),y) | 9 | ifeq ($(CONFIG_PCI),y) |
9 | usbcore-objs += hcd-pci.o | 10 | usbcore-objs += hcd-pci.o |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 545da37afca7..bcbeaf7101d1 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -515,19 +515,19 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig | |||
515 | 515 | ||
516 | static struct usb_device *usbdev_lookup_minor(int minor) | 516 | static struct usb_device *usbdev_lookup_minor(int minor) |
517 | { | 517 | { |
518 | struct class_device *class_dev; | 518 | struct device *device; |
519 | struct usb_device *dev = NULL; | 519 | struct usb_device *udev = NULL; |
520 | 520 | ||
521 | down(&usb_device_class->sem); | 521 | down(&usb_device_class->sem); |
522 | list_for_each_entry(class_dev, &usb_device_class->children, node) { | 522 | list_for_each_entry(device, &usb_device_class->devices, node) { |
523 | if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { | 523 | if (device->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { |
524 | dev = class_dev->class_data; | 524 | udev = device->platform_data; |
525 | break; | 525 | break; |
526 | } | 526 | } |
527 | } | 527 | } |
528 | up(&usb_device_class->sem); | 528 | up(&usb_device_class->sem); |
529 | 529 | ||
530 | return dev; | 530 | return udev; |
531 | }; | 531 | }; |
532 | 532 | ||
533 | /* | 533 | /* |
@@ -823,8 +823,7 @@ static int proc_connectinfo(struct dev_state *ps, void __user *arg) | |||
823 | 823 | ||
824 | static int proc_resetdevice(struct dev_state *ps) | 824 | static int proc_resetdevice(struct dev_state *ps) |
825 | { | 825 | { |
826 | return usb_reset_device(ps->dev); | 826 | return usb_reset_composite_device(ps->dev, NULL); |
827 | |||
828 | } | 827 | } |
829 | 828 | ||
830 | static int proc_setintf(struct dev_state *ps, void __user *arg) | 829 | static int proc_setintf(struct dev_state *ps, void __user *arg) |
@@ -923,8 +922,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
923 | if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 922 | if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) |
924 | != USB_ENDPOINT_XFER_CONTROL) | 923 | != USB_ENDPOINT_XFER_CONTROL) |
925 | return -EINVAL; | 924 | return -EINVAL; |
926 | /* min 8 byte setup packet, max arbitrary */ | 925 | /* min 8 byte setup packet, max 8 byte setup plus an arbitrary data stage */ |
927 | if (uurb->buffer_length < 8 || uurb->buffer_length > PAGE_SIZE) | 926 | if (uurb->buffer_length < 8 || uurb->buffer_length > (8 + MAX_USBFS_BUFFER_SIZE)) |
928 | return -EINVAL; | 927 | return -EINVAL; |
929 | if (!(dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL))) | 928 | if (!(dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL))) |
930 | return -ENOMEM; | 929 | return -ENOMEM; |
@@ -982,7 +981,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
982 | return -EFAULT; | 981 | return -EFAULT; |
983 | } | 982 | } |
984 | for (totlen = u = 0; u < uurb->number_of_packets; u++) { | 983 | for (totlen = u = 0; u < uurb->number_of_packets; u++) { |
985 | if (isopkt[u].length > 1023) { | 984 | /* arbitrary limit, sufficient for USB 2.0 high-bandwidth iso */ |
985 | if (isopkt[u].length > 8192) { | ||
986 | kfree(isopkt); | 986 | kfree(isopkt); |
987 | return -EINVAL; | 987 | return -EINVAL; |
988 | } | 988 | } |
@@ -1576,16 +1576,16 @@ static void usbdev_add(struct usb_device *dev) | |||
1576 | { | 1576 | { |
1577 | int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); | 1577 | int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); |
1578 | 1578 | ||
1579 | dev->class_dev = class_device_create(usb_device_class, NULL, | 1579 | dev->usbfs_dev = device_create(usb_device_class, &dev->dev, |
1580 | MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev, | 1580 | MKDEV(USB_DEVICE_MAJOR, minor), |
1581 | "usbdev%d.%d", dev->bus->busnum, dev->devnum); | 1581 | "usbdev%d.%d", dev->bus->busnum, dev->devnum); |
1582 | 1582 | ||
1583 | dev->class_dev->class_data = dev; | 1583 | dev->usbfs_dev->platform_data = dev; |
1584 | } | 1584 | } |
1585 | 1585 | ||
1586 | static void usbdev_remove(struct usb_device *dev) | 1586 | static void usbdev_remove(struct usb_device *dev) |
1587 | { | 1587 | { |
1588 | class_device_unregister(dev->class_dev); | 1588 | device_unregister(dev->usbfs_dev); |
1589 | } | 1589 | } |
1590 | 1590 | ||
1591 | static int usbdev_notify(struct notifier_block *self, unsigned long action, | 1591 | static int usbdev_notify(struct notifier_block *self, unsigned long action, |
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c new file mode 100644 index 000000000000..247b5a4913a8 --- /dev/null +++ b/drivers/usb/core/endpoint.c | |||
@@ -0,0 +1,275 @@ | |||
1 | /* | ||
2 | * drivers/usb/core/endpoint.c | ||
3 | * | ||
4 | * (C) Copyright 2002,2004,2006 Greg Kroah-Hartman | ||
5 | * (C) Copyright 2002,2004 IBM Corp. | ||
6 | * (C) Copyright 2006 Novell Inc. | ||
7 | * | ||
8 | * Endpoint sysfs stuff | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/usb.h> | ||
14 | #include "usb.h" | ||
15 | |||
16 | /* endpoint stuff */ | ||
17 | |||
18 | struct ep_device { | ||
19 | struct usb_endpoint_descriptor *desc; | ||
20 | struct usb_device *udev; | ||
21 | struct device dev; | ||
22 | }; | ||
23 | #define to_ep_device(_dev) \ | ||
24 | container_of(_dev, struct ep_device, dev) | ||
25 | |||
26 | struct ep_attribute { | ||
27 | struct attribute attr; | ||
28 | ssize_t (*show)(struct usb_device *, | ||
29 | struct usb_endpoint_descriptor *, char *); | ||
30 | }; | ||
31 | #define to_ep_attribute(_attr) \ | ||
32 | container_of(_attr, struct ep_attribute, attr) | ||
33 | |||
34 | #define usb_ep_attr(field, format_string) \ | ||
35 | static ssize_t show_ep_##field(struct device *dev, \ | ||
36 | struct device_attribute *attr, \ | ||
37 | char *buf) \ | ||
38 | { \ | ||
39 | struct ep_device *ep = to_ep_device(dev); \ | ||
40 | return sprintf(buf, format_string, ep->desc->field); \ | ||
41 | } \ | ||
42 | static DEVICE_ATTR(field, S_IRUGO, show_ep_##field, NULL); | ||
43 | |||
44 | usb_ep_attr(bLength, "%02x\n") | ||
45 | usb_ep_attr(bEndpointAddress, "%02x\n") | ||
46 | usb_ep_attr(bmAttributes, "%02x\n") | ||
47 | usb_ep_attr(bInterval, "%02x\n") | ||
48 | |||
49 | static ssize_t show_ep_wMaxPacketSize(struct device *dev, | ||
50 | struct device_attribute *attr, char *buf) | ||
51 | { | ||
52 | struct ep_device *ep = to_ep_device(dev); | ||
53 | return sprintf(buf, "%04x\n", | ||
54 | le16_to_cpu(ep->desc->wMaxPacketSize) & 0x07ff); | ||
55 | } | ||
56 | static DEVICE_ATTR(wMaxPacketSize, S_IRUGO, show_ep_wMaxPacketSize, NULL); | ||
57 | |||
58 | static ssize_t show_ep_type(struct device *dev, struct device_attribute *attr, | ||
59 | char *buf) | ||
60 | { | ||
61 | struct ep_device *ep = to_ep_device(dev); | ||
62 | char *type = "unknown"; | ||
63 | |||
64 | switch (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | ||
65 | case USB_ENDPOINT_XFER_CONTROL: | ||
66 | type = "Control"; | ||
67 | break; | ||
68 | case USB_ENDPOINT_XFER_ISOC: | ||
69 | type = "Isoc"; | ||
70 | break; | ||
71 | case USB_ENDPOINT_XFER_BULK: | ||
72 | type = "Bulk"; | ||
73 | break; | ||
74 | case USB_ENDPOINT_XFER_INT: | ||
75 | type = "Interrupt"; | ||
76 | break; | ||
77 | } | ||
78 | return sprintf(buf, "%s\n", type); | ||
79 | } | ||
80 | static DEVICE_ATTR(type, S_IRUGO, show_ep_type, NULL); | ||
81 | |||
82 | static ssize_t show_ep_interval(struct device *dev, | ||
83 | struct device_attribute *attr, char *buf) | ||
84 | { | ||
85 | struct ep_device *ep = to_ep_device(dev); | ||
86 | char unit; | ||
87 | unsigned interval = 0; | ||
88 | unsigned in; | ||
89 | |||
90 | in = (ep->desc->bEndpointAddress & USB_DIR_IN); | ||
91 | |||
92 | switch (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | ||
93 | case USB_ENDPOINT_XFER_CONTROL: | ||
94 | if (ep->udev->speed == USB_SPEED_HIGH) /* uframes per NAK */ | ||
95 | interval = ep->desc->bInterval; | ||
96 | break; | ||
97 | case USB_ENDPOINT_XFER_ISOC: | ||
98 | interval = 1 << (ep->desc->bInterval - 1); | ||
99 | break; | ||
100 | case USB_ENDPOINT_XFER_BULK: | ||
101 | if (ep->udev->speed == USB_SPEED_HIGH && !in) /* uframes per NAK */ | ||
102 | interval = ep->desc->bInterval; | ||
103 | break; | ||
104 | case USB_ENDPOINT_XFER_INT: | ||
105 | if (ep->udev->speed == USB_SPEED_HIGH) | ||
106 | interval = 1 << (ep->desc->bInterval - 1); | ||
107 | else | ||
108 | interval = ep->desc->bInterval; | ||
109 | break; | ||
110 | } | ||
111 | interval *= (ep->udev->speed == USB_SPEED_HIGH) ? 125 : 1000; | ||
112 | if (interval % 1000) | ||
113 | unit = 'u'; | ||
114 | else { | ||
115 | unit = 'm'; | ||
116 | interval /= 1000; | ||
117 | } | ||
118 | |||
119 | return sprintf(buf, "%d%cs\n", interval, unit); | ||
120 | } | ||
121 | static DEVICE_ATTR(interval, S_IRUGO, show_ep_interval, NULL); | ||
122 | |||
123 | static ssize_t show_ep_direction(struct device *dev, | ||
124 | struct device_attribute *attr, char *buf) | ||
125 | { | ||
126 | struct ep_device *ep = to_ep_device(dev); | ||
127 | char *direction; | ||
128 | |||
129 | if ((ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == | ||
130 | USB_ENDPOINT_XFER_CONTROL) | ||
131 | direction = "both"; | ||
132 | else if (ep->desc->bEndpointAddress & USB_DIR_IN) | ||
133 | direction = "in"; | ||
134 | else | ||
135 | direction = "out"; | ||
136 | return sprintf(buf, "%s\n", direction); | ||
137 | } | ||
138 | static DEVICE_ATTR(direction, S_IRUGO, show_ep_direction, NULL); | ||
139 | |||
140 | static struct attribute *ep_dev_attrs[] = { | ||
141 | &dev_attr_bLength.attr, | ||
142 | &dev_attr_bEndpointAddress.attr, | ||
143 | &dev_attr_bmAttributes.attr, | ||
144 | &dev_attr_bInterval.attr, | ||
145 | &dev_attr_wMaxPacketSize.attr, | ||
146 | &dev_attr_interval.attr, | ||
147 | &dev_attr_type.attr, | ||
148 | &dev_attr_direction.attr, | ||
149 | NULL, | ||
150 | }; | ||
151 | static struct attribute_group ep_dev_attr_grp = { | ||
152 | .attrs = ep_dev_attrs, | ||
153 | }; | ||
154 | |||
155 | static struct endpoint_class { | ||
156 | struct kref kref; | ||
157 | struct class *class; | ||
158 | } *ep_class; | ||
159 | |||
160 | static int init_endpoint_class(void) | ||
161 | { | ||
162 | int result = 0; | ||
163 | |||
164 | if (ep_class != NULL) { | ||
165 | kref_get(&ep_class->kref); | ||
166 | goto exit; | ||
167 | } | ||
168 | |||
169 | ep_class = kmalloc(sizeof(*ep_class), GFP_KERNEL); | ||
170 | if (!ep_class) { | ||
171 | result = -ENOMEM; | ||
172 | goto exit; | ||
173 | } | ||
174 | |||
175 | kref_init(&ep_class->kref); | ||
176 | ep_class->class = class_create(THIS_MODULE, "usb_endpoint"); | ||
177 | if (IS_ERR(ep_class->class)) { | ||
178 | result = IS_ERR(ep_class->class); | ||
179 | kfree(ep_class); | ||
180 | ep_class = NULL; | ||
181 | goto exit; | ||
182 | } | ||
183 | |||
184 | exit: | ||
185 | return result; | ||
186 | } | ||
187 | |||
188 | static void release_endpoint_class(struct kref *kref) | ||
189 | { | ||
190 | /* Ok, we cheat as we know we only have one ep_class */ | ||
191 | class_destroy(ep_class->class); | ||
192 | kfree(ep_class); | ||
193 | ep_class = NULL; | ||
194 | } | ||
195 | |||
196 | static void destroy_endpoint_class(void) | ||
197 | { | ||
198 | if (ep_class) | ||
199 | kref_put(&ep_class->kref, release_endpoint_class); | ||
200 | } | ||
201 | |||
202 | static void ep_device_release(struct device *dev) | ||
203 | { | ||
204 | struct ep_device *ep_dev = to_ep_device(dev); | ||
205 | |||
206 | dev_dbg(dev, "%s called for %s\n", __FUNCTION__, dev->bus_id); | ||
207 | kfree(ep_dev); | ||
208 | } | ||
209 | |||
210 | void usb_create_ep_files(struct device *parent, | ||
211 | struct usb_host_endpoint *endpoint, | ||
212 | struct usb_device *udev) | ||
213 | { | ||
214 | char name[8]; | ||
215 | struct ep_device *ep_dev; | ||
216 | int minor; | ||
217 | int retval; | ||
218 | |||
219 | retval = init_endpoint_class(); | ||
220 | if (retval) | ||
221 | goto exit; | ||
222 | |||
223 | ep_dev = kzalloc(sizeof(*ep_dev), GFP_KERNEL); | ||
224 | if (!ep_dev) { | ||
225 | retval = -ENOMEM; | ||
226 | goto exit; | ||
227 | } | ||
228 | |||
229 | /* fun calculation to determine the minor of this endpoint */ | ||
230 | minor = (((udev->bus->busnum - 1) * 128) * 16) + (udev->devnum - 1); | ||
231 | |||
232 | ep_dev->desc = &endpoint->desc; | ||
233 | ep_dev->udev = udev; | ||
234 | ep_dev->dev.devt = MKDEV(442, minor); // FIXME fake number... | ||
235 | ep_dev->dev.class = ep_class->class; | ||
236 | ep_dev->dev.parent = parent; | ||
237 | ep_dev->dev.release = ep_device_release; | ||
238 | snprintf(ep_dev->dev.bus_id, BUS_ID_SIZE, "usbdev%d.%d_ep%02x", | ||
239 | udev->bus->busnum, udev->devnum, | ||
240 | endpoint->desc.bEndpointAddress); | ||
241 | |||
242 | retval = device_register(&ep_dev->dev); | ||
243 | if (retval) | ||
244 | goto error; | ||
245 | sysfs_create_group(&ep_dev->dev.kobj, &ep_dev_attr_grp); | ||
246 | |||
247 | endpoint->ep_dev = ep_dev; | ||
248 | |||
249 | /* create the symlink to the old-style "ep_XX" directory */ | ||
250 | sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress); | ||
251 | sysfs_create_link(&parent->kobj, &endpoint->ep_dev->dev.kobj, name); | ||
252 | |||
253 | exit: | ||
254 | return; | ||
255 | error: | ||
256 | kfree(ep_dev); | ||
257 | return; | ||
258 | } | ||
259 | |||
260 | void usb_remove_ep_files(struct usb_host_endpoint *endpoint) | ||
261 | { | ||
262 | |||
263 | if (endpoint->ep_dev) { | ||
264 | char name[8]; | ||
265 | |||
266 | sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress); | ||
267 | sysfs_remove_link(&endpoint->ep_dev->dev.parent->kobj, name); | ||
268 | sysfs_remove_group(&endpoint->ep_dev->dev.kobj, &ep_dev_attr_grp); | ||
269 | device_unregister(&endpoint->ep_dev->dev); | ||
270 | endpoint->ep_dev = NULL; | ||
271 | } | ||
272 | destroy_endpoint_class(); | ||
273 | } | ||
274 | |||
275 | |||
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index b263a54a13c0..f65b193cde3d 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c | |||
@@ -61,33 +61,66 @@ static struct file_operations usb_fops = { | |||
61 | .open = usb_open, | 61 | .open = usb_open, |
62 | }; | 62 | }; |
63 | 63 | ||
64 | static struct class *usb_class; | 64 | static struct usb_class { |
65 | struct kref kref; | ||
66 | struct class *class; | ||
67 | } *usb_class; | ||
65 | 68 | ||
66 | int usb_major_init(void) | 69 | static int init_usb_class(void) |
67 | { | 70 | { |
68 | int error; | 71 | int result = 0; |
69 | 72 | ||
70 | error = register_chrdev(USB_MAJOR, "usb", &usb_fops); | 73 | if (usb_class != NULL) { |
71 | if (error) { | 74 | kref_get(&usb_class->kref); |
72 | err("unable to get major %d for usb devices", USB_MAJOR); | 75 | goto exit; |
73 | goto out; | 76 | } |
77 | |||
78 | usb_class = kmalloc(sizeof(*usb_class), GFP_KERNEL); | ||
79 | if (!usb_class) { | ||
80 | result = -ENOMEM; | ||
81 | goto exit; | ||
74 | } | 82 | } |
75 | 83 | ||
76 | usb_class = class_create(THIS_MODULE, "usb"); | 84 | kref_init(&usb_class->kref); |
77 | if (IS_ERR(usb_class)) { | 85 | usb_class->class = class_create(THIS_MODULE, "usb"); |
78 | error = PTR_ERR(usb_class); | 86 | if (IS_ERR(usb_class->class)) { |
87 | result = IS_ERR(usb_class->class); | ||
79 | err("class_create failed for usb devices"); | 88 | err("class_create failed for usb devices"); |
80 | unregister_chrdev(USB_MAJOR, "usb"); | 89 | kfree(usb_class); |
81 | goto out; | 90 | usb_class = NULL; |
82 | } | 91 | } |
83 | 92 | ||
84 | out: | 93 | exit: |
94 | return result; | ||
95 | } | ||
96 | |||
97 | static void release_usb_class(struct kref *kref) | ||
98 | { | ||
99 | /* Ok, we cheat as we know we only have one usb_class */ | ||
100 | class_destroy(usb_class->class); | ||
101 | kfree(usb_class); | ||
102 | usb_class = NULL; | ||
103 | } | ||
104 | |||
105 | static void destroy_usb_class(void) | ||
106 | { | ||
107 | if (usb_class) | ||
108 | kref_put(&usb_class->kref, release_usb_class); | ||
109 | } | ||
110 | |||
111 | int usb_major_init(void) | ||
112 | { | ||
113 | int error; | ||
114 | |||
115 | error = register_chrdev(USB_MAJOR, "usb", &usb_fops); | ||
116 | if (error) | ||
117 | err("unable to get major %d for usb devices", USB_MAJOR); | ||
118 | |||
85 | return error; | 119 | return error; |
86 | } | 120 | } |
87 | 121 | ||
88 | void usb_major_cleanup(void) | 122 | void usb_major_cleanup(void) |
89 | { | 123 | { |
90 | class_destroy(usb_class); | ||
91 | unregister_chrdev(USB_MAJOR, "usb"); | 124 | unregister_chrdev(USB_MAJOR, "usb"); |
92 | } | 125 | } |
93 | 126 | ||
@@ -149,6 +182,10 @@ int usb_register_dev(struct usb_interface *intf, | |||
149 | if (retval) | 182 | if (retval) |
150 | goto exit; | 183 | goto exit; |
151 | 184 | ||
185 | retval = init_usb_class(); | ||
186 | if (retval) | ||
187 | goto exit; | ||
188 | |||
152 | intf->minor = minor; | 189 | intf->minor = minor; |
153 | 190 | ||
154 | /* create a usb class device for this usb interface */ | 191 | /* create a usb class device for this usb interface */ |
@@ -158,14 +195,13 @@ int usb_register_dev(struct usb_interface *intf, | |||
158 | ++temp; | 195 | ++temp; |
159 | else | 196 | else |
160 | temp = name; | 197 | temp = name; |
161 | intf->class_dev = class_device_create(usb_class, NULL, | 198 | intf->usb_dev = device_create(usb_class->class, &intf->dev, |
162 | MKDEV(USB_MAJOR, minor), | 199 | MKDEV(USB_MAJOR, minor), "%s", temp); |
163 | &intf->dev, "%s", temp); | 200 | if (IS_ERR(intf->usb_dev)) { |
164 | if (IS_ERR(intf->class_dev)) { | ||
165 | spin_lock (&minor_lock); | 201 | spin_lock (&minor_lock); |
166 | usb_minors[intf->minor] = NULL; | 202 | usb_minors[intf->minor] = NULL; |
167 | spin_unlock (&minor_lock); | 203 | spin_unlock (&minor_lock); |
168 | retval = PTR_ERR(intf->class_dev); | 204 | retval = PTR_ERR(intf->usb_dev); |
169 | } | 205 | } |
170 | exit: | 206 | exit: |
171 | return retval; | 207 | return retval; |
@@ -206,9 +242,10 @@ void usb_deregister_dev(struct usb_interface *intf, | |||
206 | spin_unlock (&minor_lock); | 242 | spin_unlock (&minor_lock); |
207 | 243 | ||
208 | snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); | 244 | snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); |
209 | class_device_destroy(usb_class, MKDEV(USB_MAJOR, intf->minor)); | 245 | device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); |
210 | intf->class_dev = NULL; | 246 | intf->usb_dev = NULL; |
211 | intf->minor = -1; | 247 | intf->minor = -1; |
248 | destroy_usb_class(); | ||
212 | } | 249 | } |
213 | EXPORT_SYMBOL(usb_deregister_dev); | 250 | EXPORT_SYMBOL(usb_deregister_dev); |
214 | 251 | ||
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index e2e00ba4e1e6..4bf914d00a14 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -1826,24 +1826,16 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
1826 | 1826 | ||
1827 | /* enable irqs just before we start the controller */ | 1827 | /* enable irqs just before we start the controller */ |
1828 | if (hcd->driver->irq) { | 1828 | if (hcd->driver->irq) { |
1829 | char buf[8], *bufp = buf; | ||
1830 | |||
1831 | #ifdef __sparc__ | ||
1832 | bufp = __irq_itoa(irqnum); | ||
1833 | #else | ||
1834 | sprintf(buf, "%d", irqnum); | ||
1835 | #endif | ||
1836 | |||
1837 | snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", | 1829 | snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", |
1838 | hcd->driver->description, hcd->self.busnum); | 1830 | hcd->driver->description, hcd->self.busnum); |
1839 | if ((retval = request_irq(irqnum, &usb_hcd_irq, irqflags, | 1831 | if ((retval = request_irq(irqnum, &usb_hcd_irq, irqflags, |
1840 | hcd->irq_descr, hcd)) != 0) { | 1832 | hcd->irq_descr, hcd)) != 0) { |
1841 | dev_err(hcd->self.controller, | 1833 | dev_err(hcd->self.controller, |
1842 | "request interrupt %s failed\n", bufp); | 1834 | "request interrupt %d failed\n", irqnum); |
1843 | goto err_request_irq; | 1835 | goto err_request_irq; |
1844 | } | 1836 | } |
1845 | hcd->irq = irqnum; | 1837 | hcd->irq = irqnum; |
1846 | dev_info(hcd->self.controller, "irq %s, %s 0x%08llx\n", bufp, | 1838 | dev_info(hcd->self.controller, "irq %d, %s 0x%08llx\n", irqnum, |
1847 | (hcd->driver->flags & HCD_MEMORY) ? | 1839 | (hcd->driver->flags & HCD_MEMORY) ? |
1848 | "io mem" : "io base", | 1840 | "io mem" : "io base", |
1849 | (unsigned long long)hcd->rsrc_start); | 1841 | (unsigned long long)hcd->rsrc_start); |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 90b8d43c6b33..e1731ff8af4d 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -432,15 +432,22 @@ static void hub_power_on(struct usb_hub *hub) | |||
432 | { | 432 | { |
433 | int port1; | 433 | int port1; |
434 | unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2; | 434 | unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2; |
435 | u16 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); | 435 | u16 wHubCharacteristics = |
436 | 436 | le16_to_cpu(hub->descriptor->wHubCharacteristics); | |
437 | /* if hub supports power switching, enable power on each port */ | 437 | |
438 | if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2) { | 438 | /* Enable power on each port. Some hubs have reserved values |
439 | * of LPSM (> 2) in their descriptors, even though they are | ||
440 | * USB 2.0 hubs. Some hubs do not implement port-power switching | ||
441 | * but only emulate it. In all cases, the ports won't work | ||
442 | * unless we send these messages to the hub. | ||
443 | */ | ||
444 | if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2) | ||
439 | dev_dbg(hub->intfdev, "enabling power on all ports\n"); | 445 | dev_dbg(hub->intfdev, "enabling power on all ports\n"); |
440 | for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++) | 446 | else |
441 | set_port_feature(hub->hdev, port1, | 447 | dev_dbg(hub->intfdev, "trying to enable port power on " |
442 | USB_PORT_FEAT_POWER); | 448 | "non-switchable hub\n"); |
443 | } | 449 | for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++) |
450 | set_port_feature(hub->hdev, port1, USB_PORT_FEAT_POWER); | ||
444 | 451 | ||
445 | /* Wait at least 100 msec for power to become stable */ | 452 | /* Wait at least 100 msec for power to become stable */ |
446 | msleep(max(pgood_delay, (unsigned) 100)); | 453 | msleep(max(pgood_delay, (unsigned) 100)); |
@@ -518,15 +525,16 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state) | |||
518 | 525 | ||
519 | 526 | ||
520 | /* caller has locked the hub device */ | 527 | /* caller has locked the hub device */ |
521 | static void hub_pre_reset(struct usb_hub *hub, int disable_ports) | 528 | static void hub_pre_reset(struct usb_interface *intf) |
522 | { | 529 | { |
530 | struct usb_hub *hub = usb_get_intfdata(intf); | ||
523 | struct usb_device *hdev = hub->hdev; | 531 | struct usb_device *hdev = hub->hdev; |
524 | int port1; | 532 | int port1; |
525 | 533 | ||
526 | for (port1 = 1; port1 <= hdev->maxchild; ++port1) { | 534 | for (port1 = 1; port1 <= hdev->maxchild; ++port1) { |
527 | if (hdev->children[port1 - 1]) { | 535 | if (hdev->children[port1 - 1]) { |
528 | usb_disconnect(&hdev->children[port1 - 1]); | 536 | usb_disconnect(&hdev->children[port1 - 1]); |
529 | if (disable_ports) | 537 | if (hub->error == 0) |
530 | hub_port_disable(hub, port1, 0); | 538 | hub_port_disable(hub, port1, 0); |
531 | } | 539 | } |
532 | } | 540 | } |
@@ -534,8 +542,10 @@ static void hub_pre_reset(struct usb_hub *hub, int disable_ports) | |||
534 | } | 542 | } |
535 | 543 | ||
536 | /* caller has locked the hub device */ | 544 | /* caller has locked the hub device */ |
537 | static void hub_post_reset(struct usb_hub *hub) | 545 | static void hub_post_reset(struct usb_interface *intf) |
538 | { | 546 | { |
547 | struct usb_hub *hub = usb_get_intfdata(intf); | ||
548 | |||
539 | hub_activate(hub); | 549 | hub_activate(hub); |
540 | hub_power_on(hub); | 550 | hub_power_on(hub); |
541 | } | 551 | } |
@@ -795,15 +805,16 @@ static void hub_disconnect(struct usb_interface *intf) | |||
795 | struct usb_hub *hub = usb_get_intfdata (intf); | 805 | struct usb_hub *hub = usb_get_intfdata (intf); |
796 | struct usb_device *hdev; | 806 | struct usb_device *hdev; |
797 | 807 | ||
808 | /* Disconnect all children and quiesce the hub */ | ||
809 | hub->error = 0; | ||
810 | hub_pre_reset(intf); | ||
811 | |||
798 | usb_set_intfdata (intf, NULL); | 812 | usb_set_intfdata (intf, NULL); |
799 | hdev = hub->hdev; | 813 | hdev = hub->hdev; |
800 | 814 | ||
801 | if (hdev->speed == USB_SPEED_HIGH) | 815 | if (hdev->speed == USB_SPEED_HIGH) |
802 | highspeed_hubs--; | 816 | highspeed_hubs--; |
803 | 817 | ||
804 | /* Disconnect all children and quiesce the hub */ | ||
805 | hub_pre_reset(hub, 1); | ||
806 | |||
807 | usb_free_urb(hub->urb); | 818 | usb_free_urb(hub->urb); |
808 | hub->urb = NULL; | 819 | hub->urb = NULL; |
809 | 820 | ||
@@ -1169,6 +1180,7 @@ static int choose_configuration(struct usb_device *udev) | |||
1169 | { | 1180 | { |
1170 | int i; | 1181 | int i; |
1171 | int num_configs; | 1182 | int num_configs; |
1183 | int insufficient_power = 0; | ||
1172 | struct usb_host_config *c, *best; | 1184 | struct usb_host_config *c, *best; |
1173 | 1185 | ||
1174 | best = NULL; | 1186 | best = NULL; |
@@ -1221,8 +1233,10 @@ static int choose_configuration(struct usb_device *udev) | |||
1221 | */ | 1233 | */ |
1222 | 1234 | ||
1223 | /* Rule out configs that draw too much bus current */ | 1235 | /* Rule out configs that draw too much bus current */ |
1224 | if (c->desc.bMaxPower * 2 > udev->bus_mA) | 1236 | if (c->desc.bMaxPower * 2 > udev->bus_mA) { |
1237 | insufficient_power++; | ||
1225 | continue; | 1238 | continue; |
1239 | } | ||
1226 | 1240 | ||
1227 | /* If the first config's first interface is COMM/2/0xff | 1241 | /* If the first config's first interface is COMM/2/0xff |
1228 | * (MSFT RNDIS), rule it out unless Linux has host-side | 1242 | * (MSFT RNDIS), rule it out unless Linux has host-side |
@@ -1231,7 +1245,7 @@ static int choose_configuration(struct usb_device *udev) | |||
1231 | && desc->bInterfaceClass == USB_CLASS_COMM | 1245 | && desc->bInterfaceClass == USB_CLASS_COMM |
1232 | && desc->bInterfaceSubClass == 2 | 1246 | && desc->bInterfaceSubClass == 2 |
1233 | && desc->bInterfaceProtocol == 0xff) { | 1247 | && desc->bInterfaceProtocol == 0xff) { |
1234 | #ifndef CONFIG_USB_NET_RNDIS | 1248 | #ifndef CONFIG_USB_NET_RNDIS_HOST |
1235 | continue; | 1249 | continue; |
1236 | #else | 1250 | #else |
1237 | best = c; | 1251 | best = c; |
@@ -1256,6 +1270,11 @@ static int choose_configuration(struct usb_device *udev) | |||
1256 | best = c; | 1270 | best = c; |
1257 | } | 1271 | } |
1258 | 1272 | ||
1273 | if (insufficient_power > 0) | ||
1274 | dev_info(&udev->dev, "rejected %d configuration%s " | ||
1275 | "due to insufficient available bus power\n", | ||
1276 | insufficient_power, plural(insufficient_power)); | ||
1277 | |||
1259 | if (best) { | 1278 | if (best) { |
1260 | i = best->desc.bConfigurationValue; | 1279 | i = best->desc.bConfigurationValue; |
1261 | dev_info(&udev->dev, | 1280 | dev_info(&udev->dev, |
@@ -2732,7 +2751,8 @@ static void hub_events(void) | |||
2732 | 2751 | ||
2733 | /* If the hub has died, clean up after it */ | 2752 | /* If the hub has died, clean up after it */ |
2734 | if (hdev->state == USB_STATE_NOTATTACHED) { | 2753 | if (hdev->state == USB_STATE_NOTATTACHED) { |
2735 | hub_pre_reset(hub, 0); | 2754 | hub->error = -ENODEV; |
2755 | hub_pre_reset(intf); | ||
2736 | goto loop; | 2756 | goto loop; |
2737 | } | 2757 | } |
2738 | 2758 | ||
@@ -2744,7 +2764,7 @@ static void hub_events(void) | |||
2744 | dev_dbg (hub_dev, "resetting for error %d\n", | 2764 | dev_dbg (hub_dev, "resetting for error %d\n", |
2745 | hub->error); | 2765 | hub->error); |
2746 | 2766 | ||
2747 | ret = usb_reset_device(hdev); | 2767 | ret = usb_reset_composite_device(hdev, intf); |
2748 | if (ret) { | 2768 | if (ret) { |
2749 | dev_dbg (hub_dev, | 2769 | dev_dbg (hub_dev, |
2750 | "error resetting hub: %d\n", ret); | 2770 | "error resetting hub: %d\n", ret); |
@@ -2913,6 +2933,8 @@ static struct usb_driver hub_driver = { | |||
2913 | .disconnect = hub_disconnect, | 2933 | .disconnect = hub_disconnect, |
2914 | .suspend = hub_suspend, | 2934 | .suspend = hub_suspend, |
2915 | .resume = hub_resume, | 2935 | .resume = hub_resume, |
2936 | .pre_reset = hub_pre_reset, | ||
2937 | .post_reset = hub_post_reset, | ||
2916 | .ioctl = hub_ioctl, | 2938 | .ioctl = hub_ioctl, |
2917 | .id_table = hub_id_table, | 2939 | .id_table = hub_id_table, |
2918 | }; | 2940 | }; |
@@ -2992,9 +3014,9 @@ static int config_descriptors_changed(struct usb_device *udev) | |||
2992 | * usb_reset_device - perform a USB port reset to reinitialize a device | 3014 | * usb_reset_device - perform a USB port reset to reinitialize a device |
2993 | * @udev: device to reset (not in SUSPENDED or NOTATTACHED state) | 3015 | * @udev: device to reset (not in SUSPENDED or NOTATTACHED state) |
2994 | * | 3016 | * |
2995 | * WARNING - don't reset any device unless drivers for all of its | 3017 | * WARNING - don't use this routine to reset a composite device |
2996 | * interfaces are expecting that reset! Maybe some driver->reset() | 3018 | * (one with multiple interfaces owned by separate drivers)! |
2997 | * method should eventually help ensure sufficient cooperation. | 3019 | * Use usb_reset_composite_device() instead. |
2998 | * | 3020 | * |
2999 | * Do a port reset, reassign the device's address, and establish its | 3021 | * Do a port reset, reassign the device's address, and establish its |
3000 | * former operating configuration. If the reset fails, or the device's | 3022 | * former operating configuration. If the reset fails, or the device's |
@@ -3018,7 +3040,6 @@ int usb_reset_device(struct usb_device *udev) | |||
3018 | struct usb_device *parent_hdev = udev->parent; | 3040 | struct usb_device *parent_hdev = udev->parent; |
3019 | struct usb_hub *parent_hub; | 3041 | struct usb_hub *parent_hub; |
3020 | struct usb_device_descriptor descriptor = udev->descriptor; | 3042 | struct usb_device_descriptor descriptor = udev->descriptor; |
3021 | struct usb_hub *hub = NULL; | ||
3022 | int i, ret = 0; | 3043 | int i, ret = 0; |
3023 | int port1 = udev->portnum; | 3044 | int port1 = udev->portnum; |
3024 | 3045 | ||
@@ -3036,14 +3057,6 @@ int usb_reset_device(struct usb_device *udev) | |||
3036 | } | 3057 | } |
3037 | parent_hub = hdev_to_hub(parent_hdev); | 3058 | parent_hub = hdev_to_hub(parent_hdev); |
3038 | 3059 | ||
3039 | /* If we're resetting an active hub, take some special actions */ | ||
3040 | if (udev->actconfig && udev->actconfig->desc.bNumInterfaces > 0 && | ||
3041 | udev->actconfig->interface[0]->dev.driver == | ||
3042 | &hub_driver.driver && | ||
3043 | (hub = hdev_to_hub(udev)) != NULL) { | ||
3044 | hub_pre_reset(hub, 0); | ||
3045 | } | ||
3046 | |||
3047 | set_bit(port1, parent_hub->busy_bits); | 3060 | set_bit(port1, parent_hub->busy_bits); |
3048 | for (i = 0; i < SET_CONFIG_TRIES; ++i) { | 3061 | for (i = 0; i < SET_CONFIG_TRIES; ++i) { |
3049 | 3062 | ||
@@ -3102,11 +3115,87 @@ int usb_reset_device(struct usb_device *udev) | |||
3102 | } | 3115 | } |
3103 | 3116 | ||
3104 | done: | 3117 | done: |
3105 | if (hub) | ||
3106 | hub_post_reset(hub); | ||
3107 | return 0; | 3118 | return 0; |
3108 | 3119 | ||
3109 | re_enumerate: | 3120 | re_enumerate: |
3110 | hub_port_logical_disconnect(parent_hub, port1); | 3121 | hub_port_logical_disconnect(parent_hub, port1); |
3111 | return -ENODEV; | 3122 | return -ENODEV; |
3112 | } | 3123 | } |
3124 | |||
3125 | /** | ||
3126 | * usb_reset_composite_device - warn interface drivers and perform a USB port reset | ||
3127 | * @udev: device to reset (not in SUSPENDED or NOTATTACHED state) | ||
3128 | * @iface: interface bound to the driver making the request (optional) | ||
3129 | * | ||
3130 | * Warns all drivers bound to registered interfaces (using their pre_reset | ||
3131 | * method), performs the port reset, and then lets the drivers know that | ||
3132 | * the reset is over (using their post_reset method). | ||
3133 | * | ||
3134 | * Return value is the same as for usb_reset_device(). | ||
3135 | * | ||
3136 | * The caller must own the device lock. For example, it's safe to use | ||
3137 | * this from a driver probe() routine after downloading new firmware. | ||
3138 | * For calls that might not occur during probe(), drivers should lock | ||
3139 | * the device using usb_lock_device_for_reset(). | ||
3140 | * | ||
3141 | * The interface locks are acquired during the pre_reset stage and released | ||
3142 | * during the post_reset stage. However if iface is not NULL and is | ||
3143 | * currently being probed, we assume that the caller already owns its | ||
3144 | * lock. | ||
3145 | */ | ||
3146 | int usb_reset_composite_device(struct usb_device *udev, | ||
3147 | struct usb_interface *iface) | ||
3148 | { | ||
3149 | int ret; | ||
3150 | struct usb_host_config *config = udev->actconfig; | ||
3151 | |||
3152 | if (udev->state == USB_STATE_NOTATTACHED || | ||
3153 | udev->state == USB_STATE_SUSPENDED) { | ||
3154 | dev_dbg(&udev->dev, "device reset not allowed in state %d\n", | ||
3155 | udev->state); | ||
3156 | return -EINVAL; | ||
3157 | } | ||
3158 | |||
3159 | if (iface && iface->condition != USB_INTERFACE_BINDING) | ||
3160 | iface = NULL; | ||
3161 | |||
3162 | if (config) { | ||
3163 | int i; | ||
3164 | struct usb_interface *cintf; | ||
3165 | struct usb_driver *drv; | ||
3166 | |||
3167 | for (i = 0; i < config->desc.bNumInterfaces; ++i) { | ||
3168 | cintf = config->interface[i]; | ||
3169 | if (cintf != iface) | ||
3170 | down(&cintf->dev.sem); | ||
3171 | if (device_is_registered(&cintf->dev) && | ||
3172 | cintf->dev.driver) { | ||
3173 | drv = to_usb_driver(cintf->dev.driver); | ||
3174 | if (drv->pre_reset) | ||
3175 | (drv->pre_reset)(cintf); | ||
3176 | } | ||
3177 | } | ||
3178 | } | ||
3179 | |||
3180 | ret = usb_reset_device(udev); | ||
3181 | |||
3182 | if (config) { | ||
3183 | int i; | ||
3184 | struct usb_interface *cintf; | ||
3185 | struct usb_driver *drv; | ||
3186 | |||
3187 | for (i = config->desc.bNumInterfaces - 1; i >= 0; --i) { | ||
3188 | cintf = config->interface[i]; | ||
3189 | if (device_is_registered(&cintf->dev) && | ||
3190 | cintf->dev.driver) { | ||
3191 | drv = to_usb_driver(cintf->dev.driver); | ||
3192 | if (drv->post_reset) | ||
3193 | (drv->post_reset)(cintf); | ||
3194 | } | ||
3195 | if (cintf != iface) | ||
3196 | up(&cintf->dev.sem); | ||
3197 | } | ||
3198 | } | ||
3199 | |||
3200 | return ret; | ||
3201 | } | ||
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index 3cf945cc5b9a..bfc9b28a7242 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c | |||
@@ -543,10 +543,10 @@ static void fs_remove_file (struct dentry *dentry) | |||
543 | 543 | ||
544 | /* --------------------------------------------------------------------- */ | 544 | /* --------------------------------------------------------------------- */ |
545 | 545 | ||
546 | static struct super_block *usb_get_sb(struct file_system_type *fs_type, | 546 | static int usb_get_sb(struct file_system_type *fs_type, |
547 | int flags, const char *dev_name, void *data) | 547 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) |
548 | { | 548 | { |
549 | return get_sb_single(fs_type, flags, data, usbfs_fill_super); | 549 | return get_sb_single(fs_type, flags, data, usbfs_fill_super, mnt); |
550 | } | 550 | } |
551 | 551 | ||
552 | static struct file_system_type usb_fs_type = { | 552 | static struct file_system_type usb_fs_type = { |
@@ -569,7 +569,7 @@ static int create_special_files (void) | |||
569 | ignore_mount = 1; | 569 | ignore_mount = 1; |
570 | 570 | ||
571 | /* create the devices special file */ | 571 | /* create the devices special file */ |
572 | retval = simple_pin_fs("usbfs", &usbfs_mount, &usbfs_mount_count); | 572 | retval = simple_pin_fs(&usb_fs_type, &usbfs_mount, &usbfs_mount_count); |
573 | if (retval) { | 573 | if (retval) { |
574 | err ("Unable to get usbfs mount"); | 574 | err ("Unable to get usbfs mount"); |
575 | goto exit; | 575 | goto exit; |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 08fb20f06f3e..8569600f3130 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -158,6 +158,37 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u | |||
158 | 158 | ||
159 | 159 | ||
160 | /** | 160 | /** |
161 | * usb_interrupt_msg - Builds an interrupt urb, sends it off and waits for completion | ||
162 | * @usb_dev: pointer to the usb device to send the message to | ||
163 | * @pipe: endpoint "pipe" to send the message to | ||
164 | * @data: pointer to the data to send | ||
165 | * @len: length in bytes of the data to send | ||
166 | * @actual_length: pointer to a location to put the actual length transferred in bytes | ||
167 | * @timeout: time in msecs to wait for the message to complete before | ||
168 | * timing out (if 0 the wait is forever) | ||
169 | * Context: !in_interrupt () | ||
170 | * | ||
171 | * This function sends a simple interrupt message to a specified endpoint and | ||
172 | * waits for the message to complete, or timeout. | ||
173 | * | ||
174 | * If successful, it returns 0, otherwise a negative error number. The number | ||
175 | * of actual bytes transferred will be stored in the actual_length paramater. | ||
176 | * | ||
177 | * Don't use this function from within an interrupt context, like a bottom half | ||
178 | * handler. If you need an asynchronous message, or need to send a message | ||
179 | * from within interrupt context, use usb_submit_urb() If a thread in your | ||
180 | * driver uses this call, make sure your disconnect() method can wait for it to | ||
181 | * complete. Since you don't have a handle on the URB used, you can't cancel | ||
182 | * the request. | ||
183 | */ | ||
184 | int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe, | ||
185 | void *data, int len, int *actual_length, int timeout) | ||
186 | { | ||
187 | return usb_bulk_msg(usb_dev, pipe, data, len, actual_length, timeout); | ||
188 | } | ||
189 | EXPORT_SYMBOL_GPL(usb_interrupt_msg); | ||
190 | |||
191 | /** | ||
161 | * usb_bulk_msg - Builds a bulk urb, sends it off and waits for completion | 192 | * usb_bulk_msg - Builds a bulk urb, sends it off and waits for completion |
162 | * @usb_dev: pointer to the usb device to send the message to | 193 | * @usb_dev: pointer to the usb device to send the message to |
163 | * @pipe: endpoint "pipe" to send the message to | 194 | * @pipe: endpoint "pipe" to send the message to |
@@ -1380,15 +1411,7 @@ free_interfaces: | |||
1380 | return ret; | 1411 | return ret; |
1381 | } | 1412 | } |
1382 | } | 1413 | } |
1383 | } | ||
1384 | |||
1385 | /* if it's already configured, clear out old state first. | ||
1386 | * getting rid of old interfaces means unbinding their drivers. | ||
1387 | */ | ||
1388 | if (dev->state != USB_STATE_ADDRESS) | ||
1389 | usb_disable_device (dev, 1); // Skip ep0 | ||
1390 | 1414 | ||
1391 | if (cp) { | ||
1392 | i = dev->bus_mA - cp->desc.bMaxPower * 2; | 1415 | i = dev->bus_mA - cp->desc.bMaxPower * 2; |
1393 | if (i < 0) | 1416 | if (i < 0) |
1394 | dev_warn(&dev->dev, "new config #%d exceeds power " | 1417 | dev_warn(&dev->dev, "new config #%d exceeds power " |
@@ -1396,84 +1419,91 @@ free_interfaces: | |||
1396 | configuration, -i); | 1419 | configuration, -i); |
1397 | } | 1420 | } |
1398 | 1421 | ||
1422 | /* if it's already configured, clear out old state first. | ||
1423 | * getting rid of old interfaces means unbinding their drivers. | ||
1424 | */ | ||
1425 | if (dev->state != USB_STATE_ADDRESS) | ||
1426 | usb_disable_device (dev, 1); // Skip ep0 | ||
1427 | |||
1399 | if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 1428 | if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
1400 | USB_REQ_SET_CONFIGURATION, 0, configuration, 0, | 1429 | USB_REQ_SET_CONFIGURATION, 0, configuration, 0, |
1401 | NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) | 1430 | NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) { |
1402 | goto free_interfaces; | 1431 | |
1432 | /* All the old state is gone, so what else can we do? | ||
1433 | * The device is probably useless now anyway. | ||
1434 | */ | ||
1435 | cp = NULL; | ||
1436 | } | ||
1403 | 1437 | ||
1404 | dev->actconfig = cp; | 1438 | dev->actconfig = cp; |
1405 | if (!cp) | 1439 | if (!cp) { |
1406 | usb_set_device_state(dev, USB_STATE_ADDRESS); | 1440 | usb_set_device_state(dev, USB_STATE_ADDRESS); |
1407 | else { | 1441 | goto free_interfaces; |
1408 | usb_set_device_state(dev, USB_STATE_CONFIGURED); | 1442 | } |
1443 | usb_set_device_state(dev, USB_STATE_CONFIGURED); | ||
1409 | 1444 | ||
1410 | /* Initialize the new interface structures and the | 1445 | /* Initialize the new interface structures and the |
1411 | * hc/hcd/usbcore interface/endpoint state. | 1446 | * hc/hcd/usbcore interface/endpoint state. |
1412 | */ | 1447 | */ |
1413 | for (i = 0; i < nintf; ++i) { | 1448 | for (i = 0; i < nintf; ++i) { |
1414 | struct usb_interface_cache *intfc; | 1449 | struct usb_interface_cache *intfc; |
1415 | struct usb_interface *intf; | 1450 | struct usb_interface *intf; |
1416 | struct usb_host_interface *alt; | 1451 | struct usb_host_interface *alt; |
1417 | 1452 | ||
1418 | cp->interface[i] = intf = new_interfaces[i]; | 1453 | cp->interface[i] = intf = new_interfaces[i]; |
1419 | intfc = cp->intf_cache[i]; | 1454 | intfc = cp->intf_cache[i]; |
1420 | intf->altsetting = intfc->altsetting; | 1455 | intf->altsetting = intfc->altsetting; |
1421 | intf->num_altsetting = intfc->num_altsetting; | 1456 | intf->num_altsetting = intfc->num_altsetting; |
1422 | kref_get(&intfc->ref); | 1457 | kref_get(&intfc->ref); |
1423 | |||
1424 | alt = usb_altnum_to_altsetting(intf, 0); | ||
1425 | |||
1426 | /* No altsetting 0? We'll assume the first altsetting. | ||
1427 | * We could use a GetInterface call, but if a device is | ||
1428 | * so non-compliant that it doesn't have altsetting 0 | ||
1429 | * then I wouldn't trust its reply anyway. | ||
1430 | */ | ||
1431 | if (!alt) | ||
1432 | alt = &intf->altsetting[0]; | ||
1433 | |||
1434 | intf->cur_altsetting = alt; | ||
1435 | usb_enable_interface(dev, intf); | ||
1436 | intf->dev.parent = &dev->dev; | ||
1437 | intf->dev.driver = NULL; | ||
1438 | intf->dev.bus = &usb_bus_type; | ||
1439 | intf->dev.dma_mask = dev->dev.dma_mask; | ||
1440 | intf->dev.release = release_interface; | ||
1441 | device_initialize (&intf->dev); | ||
1442 | mark_quiesced(intf); | ||
1443 | sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d", | ||
1444 | dev->bus->busnum, dev->devpath, | ||
1445 | configuration, | ||
1446 | alt->desc.bInterfaceNumber); | ||
1447 | } | ||
1448 | kfree(new_interfaces); | ||
1449 | 1458 | ||
1450 | if (cp->string == NULL) | 1459 | alt = usb_altnum_to_altsetting(intf, 0); |
1451 | cp->string = usb_cache_string(dev, | ||
1452 | cp->desc.iConfiguration); | ||
1453 | 1460 | ||
1454 | /* Now that all the interfaces are set up, register them | 1461 | /* No altsetting 0? We'll assume the first altsetting. |
1455 | * to trigger binding of drivers to interfaces. probe() | 1462 | * We could use a GetInterface call, but if a device is |
1456 | * routines may install different altsettings and may | 1463 | * so non-compliant that it doesn't have altsetting 0 |
1457 | * claim() any interfaces not yet bound. Many class drivers | 1464 | * then I wouldn't trust its reply anyway. |
1458 | * need that: CDC, audio, video, etc. | ||
1459 | */ | 1465 | */ |
1460 | for (i = 0; i < nintf; ++i) { | 1466 | if (!alt) |
1461 | struct usb_interface *intf = cp->interface[i]; | 1467 | alt = &intf->altsetting[0]; |
1462 | 1468 | ||
1463 | dev_dbg (&dev->dev, | 1469 | intf->cur_altsetting = alt; |
1464 | "adding %s (config #%d, interface %d)\n", | 1470 | usb_enable_interface(dev, intf); |
1465 | intf->dev.bus_id, configuration, | 1471 | intf->dev.parent = &dev->dev; |
1466 | intf->cur_altsetting->desc.bInterfaceNumber); | 1472 | intf->dev.driver = NULL; |
1467 | ret = device_add (&intf->dev); | 1473 | intf->dev.bus = &usb_bus_type; |
1468 | if (ret != 0) { | 1474 | intf->dev.dma_mask = dev->dev.dma_mask; |
1469 | dev_err(&dev->dev, | 1475 | intf->dev.release = release_interface; |
1470 | "device_add(%s) --> %d\n", | 1476 | device_initialize (&intf->dev); |
1471 | intf->dev.bus_id, | 1477 | mark_quiesced(intf); |
1472 | ret); | 1478 | sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d", |
1473 | continue; | 1479 | dev->bus->busnum, dev->devpath, |
1474 | } | 1480 | configuration, alt->desc.bInterfaceNumber); |
1475 | usb_create_sysfs_intf_files (intf); | 1481 | } |
1482 | kfree(new_interfaces); | ||
1483 | |||
1484 | if (cp->string == NULL) | ||
1485 | cp->string = usb_cache_string(dev, cp->desc.iConfiguration); | ||
1486 | |||
1487 | /* Now that all the interfaces are set up, register them | ||
1488 | * to trigger binding of drivers to interfaces. probe() | ||
1489 | * routines may install different altsettings and may | ||
1490 | * claim() any interfaces not yet bound. Many class drivers | ||
1491 | * need that: CDC, audio, video, etc. | ||
1492 | */ | ||
1493 | for (i = 0; i < nintf; ++i) { | ||
1494 | struct usb_interface *intf = cp->interface[i]; | ||
1495 | |||
1496 | dev_dbg (&dev->dev, | ||
1497 | "adding %s (config #%d, interface %d)\n", | ||
1498 | intf->dev.bus_id, configuration, | ||
1499 | intf->cur_altsetting->desc.bInterfaceNumber); | ||
1500 | ret = device_add (&intf->dev); | ||
1501 | if (ret != 0) { | ||
1502 | dev_err(&dev->dev, "device_add(%s) --> %d\n", | ||
1503 | intf->dev.bus_id, ret); | ||
1504 | continue; | ||
1476 | } | 1505 | } |
1506 | usb_create_sysfs_intf_files (intf); | ||
1477 | } | 1507 | } |
1478 | 1508 | ||
1479 | return 0; | 1509 | return 0; |
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 71d881327e88..3f49bf51cff7 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -15,203 +15,6 @@ | |||
15 | #include <linux/usb.h> | 15 | #include <linux/usb.h> |
16 | #include "usb.h" | 16 | #include "usb.h" |
17 | 17 | ||
18 | /* endpoint stuff */ | ||
19 | struct ep_object { | ||
20 | struct usb_endpoint_descriptor *desc; | ||
21 | struct usb_device *udev; | ||
22 | struct kobject kobj; | ||
23 | }; | ||
24 | #define to_ep_object(_kobj) \ | ||
25 | container_of(_kobj, struct ep_object, kobj) | ||
26 | |||
27 | struct ep_attribute { | ||
28 | struct attribute attr; | ||
29 | ssize_t (*show)(struct usb_device *, | ||
30 | struct usb_endpoint_descriptor *, char *); | ||
31 | }; | ||
32 | #define to_ep_attribute(_attr) \ | ||
33 | container_of(_attr, struct ep_attribute, attr) | ||
34 | |||
35 | #define EP_ATTR(_name) \ | ||
36 | struct ep_attribute ep_##_name = { \ | ||
37 | .attr = {.name = #_name, .owner = THIS_MODULE, \ | ||
38 | .mode = S_IRUGO}, \ | ||
39 | .show = show_ep_##_name} | ||
40 | |||
41 | #define usb_ep_attr(field, format_string) \ | ||
42 | static ssize_t show_ep_##field(struct usb_device *udev, \ | ||
43 | struct usb_endpoint_descriptor *desc, \ | ||
44 | char *buf) \ | ||
45 | { \ | ||
46 | return sprintf(buf, format_string, desc->field); \ | ||
47 | } \ | ||
48 | static EP_ATTR(field); | ||
49 | |||
50 | usb_ep_attr(bLength, "%02x\n") | ||
51 | usb_ep_attr(bEndpointAddress, "%02x\n") | ||
52 | usb_ep_attr(bmAttributes, "%02x\n") | ||
53 | usb_ep_attr(bInterval, "%02x\n") | ||
54 | |||
55 | static ssize_t show_ep_wMaxPacketSize(struct usb_device *udev, | ||
56 | struct usb_endpoint_descriptor *desc, char *buf) | ||
57 | { | ||
58 | return sprintf(buf, "%04x\n", | ||
59 | le16_to_cpu(desc->wMaxPacketSize) & 0x07ff); | ||
60 | } | ||
61 | static EP_ATTR(wMaxPacketSize); | ||
62 | |||
63 | static ssize_t show_ep_type(struct usb_device *udev, | ||
64 | struct usb_endpoint_descriptor *desc, char *buf) | ||
65 | { | ||
66 | char *type = "unknown"; | ||
67 | |||
68 | switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | ||
69 | case USB_ENDPOINT_XFER_CONTROL: | ||
70 | type = "Control"; | ||
71 | break; | ||
72 | case USB_ENDPOINT_XFER_ISOC: | ||
73 | type = "Isoc"; | ||
74 | break; | ||
75 | case USB_ENDPOINT_XFER_BULK: | ||
76 | type = "Bulk"; | ||
77 | break; | ||
78 | case USB_ENDPOINT_XFER_INT: | ||
79 | type = "Interrupt"; | ||
80 | break; | ||
81 | } | ||
82 | return sprintf(buf, "%s\n", type); | ||
83 | } | ||
84 | static EP_ATTR(type); | ||
85 | |||
86 | static ssize_t show_ep_interval(struct usb_device *udev, | ||
87 | struct usb_endpoint_descriptor *desc, char *buf) | ||
88 | { | ||
89 | char unit; | ||
90 | unsigned interval = 0; | ||
91 | unsigned in; | ||
92 | |||
93 | in = (desc->bEndpointAddress & USB_DIR_IN); | ||
94 | |||
95 | switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | ||
96 | case USB_ENDPOINT_XFER_CONTROL: | ||
97 | if (udev->speed == USB_SPEED_HIGH) /* uframes per NAK */ | ||
98 | interval = desc->bInterval; | ||
99 | break; | ||
100 | case USB_ENDPOINT_XFER_ISOC: | ||
101 | interval = 1 << (desc->bInterval - 1); | ||
102 | break; | ||
103 | case USB_ENDPOINT_XFER_BULK: | ||
104 | if (udev->speed == USB_SPEED_HIGH && !in) /* uframes per NAK */ | ||
105 | interval = desc->bInterval; | ||
106 | break; | ||
107 | case USB_ENDPOINT_XFER_INT: | ||
108 | if (udev->speed == USB_SPEED_HIGH) | ||
109 | interval = 1 << (desc->bInterval - 1); | ||
110 | else | ||
111 | interval = desc->bInterval; | ||
112 | break; | ||
113 | } | ||
114 | interval *= (udev->speed == USB_SPEED_HIGH) ? 125 : 1000; | ||
115 | if (interval % 1000) | ||
116 | unit = 'u'; | ||
117 | else { | ||
118 | unit = 'm'; | ||
119 | interval /= 1000; | ||
120 | } | ||
121 | |||
122 | return sprintf(buf, "%d%cs\n", interval, unit); | ||
123 | } | ||
124 | static EP_ATTR(interval); | ||
125 | |||
126 | static ssize_t show_ep_direction(struct usb_device *udev, | ||
127 | struct usb_endpoint_descriptor *desc, char *buf) | ||
128 | { | ||
129 | char *direction; | ||
130 | |||
131 | if ((desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == | ||
132 | USB_ENDPOINT_XFER_CONTROL) | ||
133 | direction = "both"; | ||
134 | else if (desc->bEndpointAddress & USB_DIR_IN) | ||
135 | direction = "in"; | ||
136 | else | ||
137 | direction = "out"; | ||
138 | return sprintf(buf, "%s\n", direction); | ||
139 | } | ||
140 | static EP_ATTR(direction); | ||
141 | |||
142 | static struct attribute *ep_attrs[] = { | ||
143 | &ep_bLength.attr, | ||
144 | &ep_bEndpointAddress.attr, | ||
145 | &ep_bmAttributes.attr, | ||
146 | &ep_bInterval.attr, | ||
147 | &ep_wMaxPacketSize.attr, | ||
148 | &ep_type.attr, | ||
149 | &ep_interval.attr, | ||
150 | &ep_direction.attr, | ||
151 | NULL, | ||
152 | }; | ||
153 | |||
154 | static void ep_object_release(struct kobject *kobj) | ||
155 | { | ||
156 | kfree(to_ep_object(kobj)); | ||
157 | } | ||
158 | |||
159 | static ssize_t ep_object_show(struct kobject *kobj, struct attribute *attr, | ||
160 | char *buf) | ||
161 | { | ||
162 | struct ep_object *ep_obj = to_ep_object(kobj); | ||
163 | struct ep_attribute *ep_attr = to_ep_attribute(attr); | ||
164 | |||
165 | return (ep_attr->show)(ep_obj->udev, ep_obj->desc, buf); | ||
166 | } | ||
167 | |||
168 | static struct sysfs_ops ep_object_sysfs_ops = { | ||
169 | .show = ep_object_show, | ||
170 | }; | ||
171 | |||
172 | static struct kobj_type ep_object_ktype = { | ||
173 | .release = ep_object_release, | ||
174 | .sysfs_ops = &ep_object_sysfs_ops, | ||
175 | .default_attrs = ep_attrs, | ||
176 | }; | ||
177 | |||
178 | static void usb_create_ep_files(struct kobject *parent, | ||
179 | struct usb_host_endpoint *endpoint, | ||
180 | struct usb_device *udev) | ||
181 | { | ||
182 | struct ep_object *ep_obj; | ||
183 | struct kobject *kobj; | ||
184 | |||
185 | ep_obj = kzalloc(sizeof(struct ep_object), GFP_KERNEL); | ||
186 | if (!ep_obj) | ||
187 | return; | ||
188 | |||
189 | ep_obj->desc = &endpoint->desc; | ||
190 | ep_obj->udev = udev; | ||
191 | |||
192 | kobj = &ep_obj->kobj; | ||
193 | kobject_set_name(kobj, "ep_%02x", endpoint->desc.bEndpointAddress); | ||
194 | kobj->parent = parent; | ||
195 | kobj->ktype = &ep_object_ktype; | ||
196 | |||
197 | /* Don't use kobject_register, because it generates a hotplug event */ | ||
198 | kobject_init(kobj); | ||
199 | if (kobject_add(kobj) == 0) | ||
200 | endpoint->kobj = kobj; | ||
201 | else | ||
202 | kobject_put(kobj); | ||
203 | } | ||
204 | |||
205 | static void usb_remove_ep_files(struct usb_host_endpoint *endpoint) | ||
206 | { | ||
207 | |||
208 | if (endpoint->kobj) { | ||
209 | kobject_del(endpoint->kobj); | ||
210 | kobject_put(endpoint->kobj); | ||
211 | endpoint->kobj = NULL; | ||
212 | } | ||
213 | } | ||
214 | |||
215 | /* Active configuration fields */ | 18 | /* Active configuration fields */ |
216 | #define usb_actconfig_show(field, multiplier, format_string) \ | 19 | #define usb_actconfig_show(field, multiplier, format_string) \ |
217 | static ssize_t show_##field (struct device *dev, \ | 20 | static ssize_t show_##field (struct device *dev, \ |
@@ -420,7 +223,7 @@ void usb_create_sysfs_dev_files (struct usb_device *udev) | |||
420 | if (udev->serial) | 223 | if (udev->serial) |
421 | device_create_file (dev, &dev_attr_serial); | 224 | device_create_file (dev, &dev_attr_serial); |
422 | device_create_file (dev, &dev_attr_configuration); | 225 | device_create_file (dev, &dev_attr_configuration); |
423 | usb_create_ep_files(&dev->kobj, &udev->ep0, udev); | 226 | usb_create_ep_files(dev, &udev->ep0, udev); |
424 | } | 227 | } |
425 | 228 | ||
426 | void usb_remove_sysfs_dev_files (struct usb_device *udev) | 229 | void usb_remove_sysfs_dev_files (struct usb_device *udev) |
@@ -524,7 +327,7 @@ static inline void usb_create_intf_ep_files(struct usb_interface *intf, | |||
524 | 327 | ||
525 | iface_desc = intf->cur_altsetting; | 328 | iface_desc = intf->cur_altsetting; |
526 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) | 329 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) |
527 | usb_create_ep_files(&intf->dev.kobj, &iface_desc->endpoint[i], | 330 | usb_create_ep_files(&intf->dev, &iface_desc->endpoint[i], |
528 | udev); | 331 | udev); |
529 | } | 332 | } |
530 | 333 | ||
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index b7fdc1cd134a..fb488c8a860c 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -991,6 +991,8 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe, | |||
991 | 991 | ||
992 | static int verify_suspended(struct device *dev, void *unused) | 992 | static int verify_suspended(struct device *dev, void *unused) |
993 | { | 993 | { |
994 | if (dev->driver == NULL) | ||
995 | return 0; | ||
994 | return (dev->power.power_state.event == PM_EVENT_ON) ? -EBUSY : 0; | 996 | return (dev->power.power_state.event == PM_EVENT_ON) ? -EBUSY : 0; |
995 | } | 997 | } |
996 | 998 | ||
@@ -1207,6 +1209,7 @@ EXPORT_SYMBOL(usb_ifnum_to_if); | |||
1207 | EXPORT_SYMBOL(usb_altnum_to_altsetting); | 1209 | EXPORT_SYMBOL(usb_altnum_to_altsetting); |
1208 | 1210 | ||
1209 | EXPORT_SYMBOL(usb_reset_device); | 1211 | EXPORT_SYMBOL(usb_reset_device); |
1212 | EXPORT_SYMBOL(usb_reset_composite_device); | ||
1210 | 1213 | ||
1211 | EXPORT_SYMBOL(__usb_get_extra_descriptor); | 1214 | EXPORT_SYMBOL(__usb_get_extra_descriptor); |
1212 | 1215 | ||
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 4647e1ebc68d..7a650c763a62 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -4,6 +4,9 @@ extern void usb_create_sysfs_dev_files (struct usb_device *dev); | |||
4 | extern void usb_remove_sysfs_dev_files (struct usb_device *dev); | 4 | extern void usb_remove_sysfs_dev_files (struct usb_device *dev); |
5 | extern void usb_create_sysfs_intf_files (struct usb_interface *intf); | 5 | extern void usb_create_sysfs_intf_files (struct usb_interface *intf); |
6 | extern void usb_remove_sysfs_intf_files (struct usb_interface *intf); | 6 | extern void usb_remove_sysfs_intf_files (struct usb_interface *intf); |
7 | extern void usb_create_ep_files(struct device *parent, struct usb_host_endpoint *endpoint, | ||
8 | struct usb_device *udev); | ||
9 | extern void usb_remove_ep_files(struct usb_host_endpoint *endpoint); | ||
7 | 10 | ||
8 | extern void usb_disable_endpoint (struct usb_device *dev, unsigned int epaddr); | 11 | extern void usb_disable_endpoint (struct usb_device *dev, unsigned int epaddr); |
9 | extern void usb_disable_interface (struct usb_device *dev, | 12 | extern void usb_disable_interface (struct usb_device *dev, |