aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2006-07-01 22:09:35 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-09-27 14:58:50 -0400
commit782da727b0d59e93c84a627948b1535a3db90392 (patch)
tree155cfe2df2a57961234c44186890fdcce72a0eb6 /drivers
parent8bb54ab573ecd1b4fe2ed66416a8d99a86e65316 (diff)
usbcore: make usb_generic a usb_device_driver
This patch (as714b) makes usb_generic into a usb_device_driver capable of being probed and unbound, just like other drivers. A fair amount of the work that used to get done during discovery or removal of a USB device have been moved to the probe and disconnect methods of usb_generic: creating the sysfs attributes and selecting an initial configuration. However the normal behavior should continue to be the same as before. We will now have the possibility of creating other USB device drivers, They will assist with exporting devices to remote systems (USB-over-TCPIP) or to paravirtual guest operating systems. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/core/driver.c69
-rw-r--r--drivers/usb/core/generic.c184
-rw-r--r--drivers/usb/core/hub.c164
-rw-r--r--drivers/usb/core/usb.c1
4 files changed, 232 insertions, 186 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 0d4b5dcee3a..a62de0a8540 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -530,9 +530,10 @@ static int usb_uevent(struct device *dev, char **envp, int num_envp,
530 /* driver is often null here; dev_dbg() would oops */ 530 /* driver is often null here; dev_dbg() would oops */
531 pr_debug ("usb %s: uevent\n", dev->bus_id); 531 pr_debug ("usb %s: uevent\n", dev->bus_id);
532 532
533 if (is_usb_device(dev)) 533 if (is_usb_device(dev)) {
534 return 0; 534 usb_dev = to_usb_device(dev);
535 else { 535 alt = NULL;
536 } else {
536 intf = to_usb_interface(dev); 537 intf = to_usb_interface(dev);
537 usb_dev = interface_to_usbdev(intf); 538 usb_dev = interface_to_usbdev(intf);
538 alt = intf->cur_altsetting; 539 alt = intf->cur_altsetting;
@@ -579,15 +580,17 @@ static int usb_uevent(struct device *dev, char **envp, int num_envp,
579 usb_dev->descriptor.bDeviceProtocol)) 580 usb_dev->descriptor.bDeviceProtocol))
580 return -ENOMEM; 581 return -ENOMEM;
581 582
582 if (add_uevent_var(envp, num_envp, &i, 583 if (!is_usb_device(dev)) {
584
585 if (add_uevent_var(envp, num_envp, &i,
583 buffer, buffer_size, &length, 586 buffer, buffer_size, &length,
584 "INTERFACE=%d/%d/%d", 587 "INTERFACE=%d/%d/%d",
585 alt->desc.bInterfaceClass, 588 alt->desc.bInterfaceClass,
586 alt->desc.bInterfaceSubClass, 589 alt->desc.bInterfaceSubClass,
587 alt->desc.bInterfaceProtocol)) 590 alt->desc.bInterfaceProtocol))
588 return -ENOMEM; 591 return -ENOMEM;
589 592
590 if (add_uevent_var(envp, num_envp, &i, 593 if (add_uevent_var(envp, num_envp, &i,
591 buffer, buffer_size, &length, 594 buffer, buffer_size, &length,
592 "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", 595 "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
593 le16_to_cpu(usb_dev->descriptor.idVendor), 596 le16_to_cpu(usb_dev->descriptor.idVendor),
@@ -599,7 +602,8 @@ static int usb_uevent(struct device *dev, char **envp, int num_envp,
599 alt->desc.bInterfaceClass, 602 alt->desc.bInterfaceClass,
600 alt->desc.bInterfaceSubClass, 603 alt->desc.bInterfaceSubClass,
601 alt->desc.bInterfaceProtocol)) 604 alt->desc.bInterfaceProtocol))
602 return -ENOMEM; 605 return -ENOMEM;
606 }
603 607
604 envp[i] = NULL; 608 envp[i] = NULL;
605 609
@@ -747,31 +751,22 @@ EXPORT_SYMBOL_GPL_FUTURE(usb_deregister);
747 751
748#ifdef CONFIG_PM 752#ifdef CONFIG_PM
749 753
750static int verify_suspended(struct device *dev, void *unused) 754static int usb_suspend(struct device *dev, pm_message_t message)
751{ 755{
752 if (dev->driver == NULL) 756 struct usb_device *udev;
753 return 0; 757 struct usb_device_driver *udriver;
754 return (dev->power.power_state.event == PM_EVENT_ON) ? -EBUSY : 0; 758 struct usb_interface *intf;
755} 759 struct usb_driver *driver;
760 int status;
756 761
757static int usb_generic_suspend(struct device *dev, pm_message_t message)
758{
759 struct usb_interface *intf;
760 struct usb_driver *driver;
761 int status;
762
763 /* USB devices enter SUSPEND state through their hubs, but can be
764 * marked for FREEZE as soon as their children are already idled.
765 * But those semantics are useless, so we equate the two (sigh).
766 */
767 if (is_usb_device(dev)) { 762 if (is_usb_device(dev)) {
763 if (dev->driver == NULL)
764 return 0;
765 udev = to_usb_device(dev);
766 udriver = to_usb_device_driver(dev->driver);
768 if (dev->power.power_state.event == message.event) 767 if (dev->power.power_state.event == message.event)
769 return 0; 768 return 0;
770 /* we need to rule out bogus requests through sysfs */ 769 return udriver->suspend(udev, message);
771 status = device_for_each_child(dev, NULL, verify_suspended);
772 if (status)
773 return status;
774 return usb_port_suspend(to_usb_device(dev));
775 } 770 }
776 771
777 if (dev->driver == NULL) 772 if (dev->driver == NULL)
@@ -799,12 +794,13 @@ static int usb_generic_suspend(struct device *dev, pm_message_t message)
799 return status; 794 return status;
800} 795}
801 796
802static int usb_generic_resume(struct device *dev) 797static int usb_resume(struct device *dev)
803{ 798{
804 struct usb_interface *intf; 799 struct usb_device *udev;
805 struct usb_driver *driver; 800 struct usb_device_driver *udriver;
806 struct usb_device *udev; 801 struct usb_interface *intf;
807 int status; 802 struct usb_driver *driver;
803 int status;
808 804
809 if (dev->power.power_state.event == PM_EVENT_ON) 805 if (dev->power.power_state.event == PM_EVENT_ON)
810 return 0; 806 return 0;
@@ -814,10 +810,13 @@ static int usb_generic_resume(struct device *dev)
814 810
815 /* devices resume through their hubs */ 811 /* devices resume through their hubs */
816 if (is_usb_device(dev)) { 812 if (is_usb_device(dev)) {
813 if (dev->driver == NULL)
814 return 0;
817 udev = to_usb_device(dev); 815 udev = to_usb_device(dev);
816 udriver = to_usb_device_driver(dev->driver);
818 if (udev->state == USB_STATE_NOTATTACHED) 817 if (udev->state == USB_STATE_NOTATTACHED)
819 return 0; 818 return 0;
820 return usb_port_resume(udev); 819 return udriver->resume(udev);
821 } 820 }
822 821
823 if (dev->driver == NULL) { 822 if (dev->driver == NULL) {
@@ -854,7 +853,7 @@ struct bus_type usb_bus_type = {
854 .match = usb_device_match, 853 .match = usb_device_match,
855 .uevent = usb_uevent, 854 .uevent = usb_uevent,
856#ifdef CONFIG_PM 855#ifdef CONFIG_PM
857 .suspend = usb_generic_suspend, 856 .suspend = usb_suspend,
858 .resume = usb_generic_resume, 857 .resume = usb_resume,
859#endif 858#endif
860}; 859};
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index fa6f34a12b4..1522195de71 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -21,24 +21,208 @@
21#include <linux/usb.h> 21#include <linux/usb.h>
22#include "usb.h" 22#include "usb.h"
23 23
24static inline const char *plural(int n)
25{
26 return (n == 1 ? "" : "s");
27}
28
29static int choose_configuration(struct usb_device *udev)
30{
31 int i;
32 int num_configs;
33 int insufficient_power = 0;
34 struct usb_host_config *c, *best;
35
36 best = NULL;
37 c = udev->config;
38 num_configs = udev->descriptor.bNumConfigurations;
39 for (i = 0; i < num_configs; (i++, c++)) {
40 struct usb_interface_descriptor *desc = NULL;
41
42 /* It's possible that a config has no interfaces! */
43 if (c->desc.bNumInterfaces > 0)
44 desc = &c->intf_cache[0]->altsetting->desc;
45
46 /*
47 * HP's USB bus-powered keyboard has only one configuration
48 * and it claims to be self-powered; other devices may have
49 * similar errors in their descriptors. If the next test
50 * were allowed to execute, such configurations would always
51 * be rejected and the devices would not work as expected.
52 * In the meantime, we run the risk of selecting a config
53 * that requires external power at a time when that power
54 * isn't available. It seems to be the lesser of two evils.
55 *
56 * Bugzilla #6448 reports a device that appears to crash
57 * when it receives a GET_DEVICE_STATUS request! We don't
58 * have any other way to tell whether a device is self-powered,
59 * but since we don't use that information anywhere but here,
60 * the call has been removed.
61 *
62 * Maybe the GET_DEVICE_STATUS call and the test below can
63 * be reinstated when device firmwares become more reliable.
64 * Don't hold your breath.
65 */
66#if 0
67 /* Rule out self-powered configs for a bus-powered device */
68 if (bus_powered && (c->desc.bmAttributes &
69 USB_CONFIG_ATT_SELFPOWER))
70 continue;
71#endif
72
73 /*
74 * The next test may not be as effective as it should be.
75 * Some hubs have errors in their descriptor, claiming
76 * to be self-powered when they are really bus-powered.
77 * We will overestimate the amount of current such hubs
78 * make available for each port.
79 *
80 * This is a fairly benign sort of failure. It won't
81 * cause us to reject configurations that we should have
82 * accepted.
83 */
84
85 /* Rule out configs that draw too much bus current */
86 if (c->desc.bMaxPower * 2 > udev->bus_mA) {
87 insufficient_power++;
88 continue;
89 }
90
91 /* If the first config's first interface is COMM/2/0xff
92 * (MSFT RNDIS), rule it out unless Linux has host-side
93 * RNDIS support. */
94 if (i == 0 && desc
95 && desc->bInterfaceClass == USB_CLASS_COMM
96 && desc->bInterfaceSubClass == 2
97 && desc->bInterfaceProtocol == 0xff) {
98#ifndef CONFIG_USB_NET_RNDIS_HOST
99 continue;
100#else
101 best = c;
102#endif
103 }
104
105 /* From the remaining configs, choose the first one whose
106 * first interface is for a non-vendor-specific class.
107 * Reason: Linux is more likely to have a class driver
108 * than a vendor-specific driver. */
109 else if (udev->descriptor.bDeviceClass !=
110 USB_CLASS_VENDOR_SPEC &&
111 (!desc || desc->bInterfaceClass !=
112 USB_CLASS_VENDOR_SPEC)) {
113 best = c;
114 break;
115 }
116
117 /* If all the remaining configs are vendor-specific,
118 * choose the first one. */
119 else if (!best)
120 best = c;
121 }
122
123 if (insufficient_power > 0)
124 dev_info(&udev->dev, "rejected %d configuration%s "
125 "due to insufficient available bus power\n",
126 insufficient_power, plural(insufficient_power));
127
128 if (best) {
129 i = best->desc.bConfigurationValue;
130 dev_info(&udev->dev,
131 "configuration #%d chosen from %d choice%s\n",
132 i, num_configs, plural(num_configs));
133 } else {
134 i = -1;
135 dev_warn(&udev->dev,
136 "no configuration chosen from %d choice%s\n",
137 num_configs, plural(num_configs));
138 }
139 return i;
140}
141
24static int generic_probe(struct usb_device *udev) 142static int generic_probe(struct usb_device *udev)
25{ 143{
144 int err, c;
145
146 /* put device-specific files into sysfs */
147 usb_create_sysfs_dev_files(udev);
148
149 /* Choose and set the configuration. This registers the interfaces
150 * with the driver core and lets interface drivers bind to them.
151 */
152 c = choose_configuration(udev);
153 if (c >= 0) {
154 err = usb_set_configuration(udev, c);
155 if (err) {
156 dev_err(&udev->dev, "can't set config #%d, error %d\n",
157 c, err);
158 /* This need not be fatal. The user can try to
159 * set other configurations. */
160 }
161 }
162
163 /* USB device state == configured ... usable */
164 usb_notify_add_device(udev);
165
26 return 0; 166 return 0;
27} 167}
168
28static void generic_disconnect(struct usb_device *udev) 169static void generic_disconnect(struct usb_device *udev)
29{ 170{
171 usb_notify_remove_device(udev);
172
30 /* if this is only an unbind, not a physical disconnect, then 173 /* if this is only an unbind, not a physical disconnect, then
31 * unconfigure the device */ 174 * unconfigure the device */
32 if (udev->state == USB_STATE_CONFIGURED) 175 if (udev->state == USB_STATE_CONFIGURED)
33 usb_set_configuration(udev, 0); 176 usb_set_configuration(udev, 0);
34 177
178 usb_remove_sysfs_dev_files(udev);
179
35 /* in case the call failed or the device was suspended */ 180 /* in case the call failed or the device was suspended */
36 if (udev->state >= USB_STATE_CONFIGURED) 181 if (udev->state >= USB_STATE_CONFIGURED)
37 usb_disable_device(udev, 0); 182 usb_disable_device(udev, 0);
38} 183}
39 184
185#ifdef CONFIG_PM
186
187static int verify_suspended(struct device *dev, void *unused)
188{
189 if (dev->driver == NULL)
190 return 0;
191 return (dev->power.power_state.event == PM_EVENT_ON) ? -EBUSY : 0;
192}
193
194static int generic_suspend(struct usb_device *udev, pm_message_t msg)
195{
196 int status;
197
198 /* rule out bogus requests through sysfs */
199 status = device_for_each_child(&udev->dev, NULL, verify_suspended);
200 if (status)
201 return status;
202
203 /* USB devices enter SUSPEND state through their hubs, but can be
204 * marked for FREEZE as soon as their children are already idled.
205 * But those semantics are useless, so we equate the two (sigh).
206 */
207 return usb_port_suspend(udev);
208}
209
210static int generic_resume(struct usb_device *udev)
211{
212 if (udev->state == USB_STATE_NOTATTACHED)
213 return 0;
214
215 return usb_port_resume(udev);
216}
217
218#endif /* CONFIG_PM */
219
40struct usb_device_driver usb_generic_driver = { 220struct usb_device_driver usb_generic_driver = {
41 .name = "usb", 221 .name = "usb",
42 .probe = generic_probe, 222 .probe = generic_probe,
43 .disconnect = generic_disconnect, 223 .disconnect = generic_disconnect,
224#ifdef CONFIG_PM
225 .suspend = generic_suspend,
226 .resume = generic_resume,
227#endif
44}; 228};
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index b00514d9a60..a372332440b 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1148,144 +1148,28 @@ void usb_disconnect(struct usb_device **pdev)
1148 * cleaning up all state associated with the current configuration 1148 * cleaning up all state associated with the current configuration
1149 * so that the hardware is now fully quiesced. 1149 * so that the hardware is now fully quiesced.
1150 */ 1150 */
1151 dev_dbg (&udev->dev, "unregistering device\n");
1151 usb_disable_device(udev, 0); 1152 usb_disable_device(udev, 0);
1152 1153
1153 usb_notify_remove_device(udev); 1154 usb_unlock_device(udev);
1155
1156 /* Unregister the device. The device driver is responsible
1157 * for removing the device files from usbfs and sysfs and for
1158 * de-configuring the device.
1159 */
1160 device_del(&udev->dev);
1154 1161
1155 /* Free the device number, remove the /proc/bus/usb entry and 1162 /* Free the device number and delete the parent's children[]
1156 * the sysfs attributes, and delete the parent's children[]
1157 * (or root_hub) pointer. 1163 * (or root_hub) pointer.
1158 */ 1164 */
1159 dev_dbg (&udev->dev, "unregistering device\n");
1160 release_address(udev); 1165 release_address(udev);
1161 usb_remove_sysfs_dev_files(udev);
1162 1166
1163 /* Avoid races with recursively_mark_NOTATTACHED() */ 1167 /* Avoid races with recursively_mark_NOTATTACHED() */
1164 spin_lock_irq(&device_state_lock); 1168 spin_lock_irq(&device_state_lock);
1165 *pdev = NULL; 1169 *pdev = NULL;
1166 spin_unlock_irq(&device_state_lock); 1170 spin_unlock_irq(&device_state_lock);
1167 1171
1168 usb_unlock_device(udev); 1172 put_device(&udev->dev);
1169
1170 device_unregister(&udev->dev);
1171}
1172
1173static inline const char *plural(int n)
1174{
1175 return (n == 1 ? "" : "s");
1176}
1177
1178static int choose_configuration(struct usb_device *udev)
1179{
1180 int i;
1181 int num_configs;
1182 int insufficient_power = 0;
1183 struct usb_host_config *c, *best;
1184
1185 best = NULL;
1186 c = udev->config;
1187 num_configs = udev->descriptor.bNumConfigurations;
1188 for (i = 0; i < num_configs; (i++, c++)) {
1189 struct usb_interface_descriptor *desc = NULL;
1190
1191 /* It's possible that a config has no interfaces! */
1192 if (c->desc.bNumInterfaces > 0)
1193 desc = &c->intf_cache[0]->altsetting->desc;
1194
1195 /*
1196 * HP's USB bus-powered keyboard has only one configuration
1197 * and it claims to be self-powered; other devices may have
1198 * similar errors in their descriptors. If the next test
1199 * were allowed to execute, such configurations would always
1200 * be rejected and the devices would not work as expected.
1201 * In the meantime, we run the risk of selecting a config
1202 * that requires external power at a time when that power
1203 * isn't available. It seems to be the lesser of two evils.
1204 *
1205 * Bugzilla #6448 reports a device that appears to crash
1206 * when it receives a GET_DEVICE_STATUS request! We don't
1207 * have any other way to tell whether a device is self-powered,
1208 * but since we don't use that information anywhere but here,
1209 * the call has been removed.
1210 *
1211 * Maybe the GET_DEVICE_STATUS call and the test below can
1212 * be reinstated when device firmwares become more reliable.
1213 * Don't hold your breath.
1214 */
1215#if 0
1216 /* Rule out self-powered configs for a bus-powered device */
1217 if (bus_powered && (c->desc.bmAttributes &
1218 USB_CONFIG_ATT_SELFPOWER))
1219 continue;
1220#endif
1221
1222 /*
1223 * The next test may not be as effective as it should be.
1224 * Some hubs have errors in their descriptor, claiming
1225 * to be self-powered when they are really bus-powered.
1226 * We will overestimate the amount of current such hubs
1227 * make available for each port.
1228 *
1229 * This is a fairly benign sort of failure. It won't
1230 * cause us to reject configurations that we should have
1231 * accepted.
1232 */
1233
1234 /* Rule out configs that draw too much bus current */
1235 if (c->desc.bMaxPower * 2 > udev->bus_mA) {
1236 insufficient_power++;
1237 continue;
1238 }
1239
1240 /* If the first config's first interface is COMM/2/0xff
1241 * (MSFT RNDIS), rule it out unless Linux has host-side
1242 * RNDIS support. */
1243 if (i == 0 && desc
1244 && desc->bInterfaceClass == USB_CLASS_COMM
1245 && desc->bInterfaceSubClass == 2
1246 && desc->bInterfaceProtocol == 0xff) {
1247#ifndef CONFIG_USB_NET_RNDIS_HOST
1248 continue;
1249#else
1250 best = c;
1251#endif
1252 }
1253
1254 /* From the remaining configs, choose the first one whose
1255 * first interface is for a non-vendor-specific class.
1256 * Reason: Linux is more likely to have a class driver
1257 * than a vendor-specific driver. */
1258 else if (udev->descriptor.bDeviceClass !=
1259 USB_CLASS_VENDOR_SPEC &&
1260 (!desc || desc->bInterfaceClass !=
1261 USB_CLASS_VENDOR_SPEC)) {
1262 best = c;
1263 break;
1264 }
1265
1266 /* If all the remaining configs are vendor-specific,
1267 * choose the first one. */
1268 else if (!best)
1269 best = c;
1270 }
1271
1272 if (insufficient_power > 0)
1273 dev_info(&udev->dev, "rejected %d configuration%s "
1274 "due to insufficient available bus power\n",
1275 insufficient_power, plural(insufficient_power));
1276
1277 if (best) {
1278 i = best->desc.bConfigurationValue;
1279 dev_info(&udev->dev,
1280 "configuration #%d chosen from %d choice%s\n",
1281 i, num_configs, plural(num_configs));
1282 } else {
1283 i = -1;
1284 dev_warn(&udev->dev,
1285 "no configuration chosen from %d choice%s\n",
1286 num_configs, plural(num_configs));
1287 }
1288 return i;
1289} 1173}
1290 1174
1291#ifdef DEBUG 1175#ifdef DEBUG
@@ -1328,7 +1212,6 @@ static inline void show_string(struct usb_device *udev, char *id, char *string)
1328int usb_new_device(struct usb_device *udev) 1212int usb_new_device(struct usb_device *udev)
1329{ 1213{
1330 int err; 1214 int err;
1331 int c;
1332 1215
1333 err = usb_get_configuration(udev); 1216 err = usb_get_configuration(udev);
1334 if (err < 0) { 1217 if (err < 0) {
@@ -1418,34 +1301,15 @@ int usb_new_device(struct usb_device *udev)
1418 } 1301 }
1419#endif 1302#endif
1420 1303
1421 /* put device-specific files into sysfs */ 1304 /* Register the device. The device driver is responsible
1305 * for adding the device files to usbfs and sysfs and for
1306 * configuring the device.
1307 */
1422 err = device_add (&udev->dev); 1308 err = device_add (&udev->dev);
1423 if (err) { 1309 if (err) {
1424 dev_err(&udev->dev, "can't device_add, error %d\n", err); 1310 dev_err(&udev->dev, "can't device_add, error %d\n", err);
1425 goto fail; 1311 goto fail;
1426 } 1312 }
1427 usb_create_sysfs_dev_files (udev);
1428
1429 usb_lock_device(udev);
1430
1431 /* choose and set the configuration. that registers the interfaces
1432 * with the driver core, and lets usb device drivers bind to them.
1433 */
1434 c = choose_configuration(udev);
1435 if (c >= 0) {
1436 err = usb_set_configuration(udev, c);
1437 if (err) {
1438 dev_err(&udev->dev, "can't set config #%d, error %d\n",
1439 c, err);
1440 /* This need not be fatal. The user can try to
1441 * set other configurations. */
1442 }
1443 }
1444
1445 /* USB device state == configured ... usable */
1446 usb_notify_add_device(udev);
1447
1448 usb_unlock_device(udev);
1449 1313
1450 return 0; 1314 return 0;
1451 1315
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 6dfbc284369..9ebfc0fe819 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -205,7 +205,6 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1)
205 device_initialize(&dev->dev); 205 device_initialize(&dev->dev);
206 dev->dev.bus = &usb_bus_type; 206 dev->dev.bus = &usb_bus_type;
207 dev->dev.dma_mask = bus->controller->dma_mask; 207 dev->dev.dma_mask = bus->controller->dma_mask;
208 dev->dev.driver = &usb_generic_driver.drvwrap.driver;
209 dev->dev.release = usb_release_dev; 208 dev->dev.release = usb_release_dev;
210 dev->state = USB_STATE_ATTACHED; 209 dev->state = USB_STATE_ATTACHED;
211 210