diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/core/hcd.c | 5 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 229 | ||||
-rw-r--r-- | drivers/usb/core/hub.h | 3 | ||||
-rw-r--r-- | drivers/usb/core/message.c | 6 |
4 files changed, 162 insertions, 81 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index d16a0e8a7d72..0018bbc4de34 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -1825,8 +1825,6 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
1825 | retval = -ENOMEM; | 1825 | retval = -ENOMEM; |
1826 | goto err_allocate_root_hub; | 1826 | goto err_allocate_root_hub; |
1827 | } | 1827 | } |
1828 | rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH : | ||
1829 | USB_SPEED_FULL; | ||
1830 | 1828 | ||
1831 | /* Although in principle hcd->driver->start() might need to use rhdev, | 1829 | /* Although in principle hcd->driver->start() might need to use rhdev, |
1832 | * none of the current drivers do. | 1830 | * none of the current drivers do. |
@@ -1844,6 +1842,9 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
1844 | dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); | 1842 | dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); |
1845 | hcd->remote_wakeup = hcd->can_wakeup; | 1843 | hcd->remote_wakeup = hcd->can_wakeup; |
1846 | 1844 | ||
1845 | rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH : | ||
1846 | USB_SPEED_FULL; | ||
1847 | rhdev->bus_mA = min(500u, hcd->power_budget); | ||
1847 | if ((retval = register_root_hub(rhdev, hcd)) != 0) | 1848 | if ((retval = register_root_hub(rhdev, hcd)) != 0) |
1848 | goto err_register_root_hub; | 1849 | goto err_register_root_hub; |
1849 | 1850 | ||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 895ac829b9cf..b311005ff1a6 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -702,26 +702,40 @@ static int hub_configure(struct usb_hub *hub, | |||
702 | * and battery-powered root hubs (may provide just 8 mA). | 702 | * and battery-powered root hubs (may provide just 8 mA). |
703 | */ | 703 | */ |
704 | ret = usb_get_status(hdev, USB_RECIP_DEVICE, 0, &hubstatus); | 704 | ret = usb_get_status(hdev, USB_RECIP_DEVICE, 0, &hubstatus); |
705 | if (ret < 0) { | 705 | if (ret < 2) { |
706 | message = "can't get hub status"; | 706 | message = "can't get hub status"; |
707 | goto fail; | 707 | goto fail; |
708 | } | 708 | } |
709 | le16_to_cpus(&hubstatus); | 709 | le16_to_cpus(&hubstatus); |
710 | if (hdev == hdev->bus->root_hub) { | 710 | if (hdev == hdev->bus->root_hub) { |
711 | struct usb_hcd *hcd = | 711 | if (hdev->bus_mA == 0 || hdev->bus_mA >= 500) |
712 | container_of(hdev->bus, struct usb_hcd, self); | 712 | hub->mA_per_port = 500; |
713 | 713 | else { | |
714 | hub->power_budget = min(500u, hcd->power_budget) / 2; | 714 | hub->mA_per_port = hdev->bus_mA; |
715 | hub->limited_power = 1; | ||
716 | } | ||
715 | } else if ((hubstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0) { | 717 | } else if ((hubstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0) { |
716 | dev_dbg(hub_dev, "hub controller current requirement: %dmA\n", | 718 | dev_dbg(hub_dev, "hub controller current requirement: %dmA\n", |
717 | hub->descriptor->bHubContrCurrent); | 719 | hub->descriptor->bHubContrCurrent); |
718 | hub->power_budget = (501 - hub->descriptor->bHubContrCurrent) | 720 | hub->limited_power = 1; |
719 | / 2; | 721 | if (hdev->maxchild > 0) { |
722 | int remaining = hdev->bus_mA - | ||
723 | hub->descriptor->bHubContrCurrent; | ||
724 | |||
725 | if (remaining < hdev->maxchild * 100) | ||
726 | dev_warn(hub_dev, | ||
727 | "insufficient power available " | ||
728 | "to use all downstream ports\n"); | ||
729 | hub->mA_per_port = 100; /* 7.2.1.1 */ | ||
730 | } | ||
731 | } else { /* Self-powered external hub */ | ||
732 | /* FIXME: What about battery-powered external hubs that | ||
733 | * provide less current per port? */ | ||
734 | hub->mA_per_port = 500; | ||
720 | } | 735 | } |
721 | if (hub->power_budget) | 736 | if (hub->mA_per_port < 500) |
722 | dev_dbg(hub_dev, "%dmA bus power budget for children\n", | 737 | dev_dbg(hub_dev, "%umA bus power budget for each child\n", |
723 | hub->power_budget * 2); | 738 | hub->mA_per_port); |
724 | |||
725 | 739 | ||
726 | ret = hub_hub_status(hub, &hubstatus, &hubchange); | 740 | ret = hub_hub_status(hub, &hubstatus, &hubchange); |
727 | if (ret < 0) { | 741 | if (ret < 0) { |
@@ -1136,45 +1150,107 @@ void usb_disconnect(struct usb_device **pdev) | |||
1136 | device_unregister(&udev->dev); | 1150 | device_unregister(&udev->dev); |
1137 | } | 1151 | } |
1138 | 1152 | ||
1153 | static inline const char *plural(int n) | ||
1154 | { | ||
1155 | return (n == 1 ? "" : "s"); | ||
1156 | } | ||
1157 | |||
1139 | static int choose_configuration(struct usb_device *udev) | 1158 | static int choose_configuration(struct usb_device *udev) |
1140 | { | 1159 | { |
1141 | int c, i; | 1160 | int i; |
1161 | u16 devstatus; | ||
1162 | int bus_powered; | ||
1163 | int num_configs; | ||
1164 | struct usb_host_config *c, *best; | ||
1165 | |||
1166 | /* If this fails, assume the device is bus-powered */ | ||
1167 | devstatus = 0; | ||
1168 | usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); | ||
1169 | le16_to_cpus(&devstatus); | ||
1170 | bus_powered = ((devstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0); | ||
1171 | dev_dbg(&udev->dev, "device is %s-powered\n", | ||
1172 | bus_powered ? "bus" : "self"); | ||
1173 | |||
1174 | best = NULL; | ||
1175 | c = udev->config; | ||
1176 | num_configs = udev->descriptor.bNumConfigurations; | ||
1177 | for (i = 0; i < num_configs; (i++, c++)) { | ||
1178 | struct usb_interface_descriptor *desc = | ||
1179 | &c->intf_cache[0]->altsetting->desc; | ||
1180 | |||
1181 | /* | ||
1182 | * HP's USB bus-powered keyboard has only one configuration | ||
1183 | * and it claims to be self-powered; other devices may have | ||
1184 | * similar errors in their descriptors. If the next test | ||
1185 | * were allowed to execute, such configurations would always | ||
1186 | * be rejected and the devices would not work as expected. | ||
1187 | */ | ||
1188 | #if 0 | ||
1189 | /* Rule out self-powered configs for a bus-powered device */ | ||
1190 | if (bus_powered && (c->desc.bmAttributes & | ||
1191 | USB_CONFIG_ATT_SELFPOWER)) | ||
1192 | continue; | ||
1193 | #endif | ||
1142 | 1194 | ||
1143 | /* NOTE: this should interact with hub power budgeting */ | 1195 | /* |
1196 | * The next test may not be as effective as it should be. | ||
1197 | * Some hubs have errors in their descriptor, claiming | ||
1198 | * to be self-powered when they are really bus-powered. | ||
1199 | * We will overestimate the amount of current such hubs | ||
1200 | * make available for each port. | ||
1201 | * | ||
1202 | * This is a fairly benign sort of failure. It won't | ||
1203 | * cause us to reject configurations that we should have | ||
1204 | * accepted. | ||
1205 | */ | ||
1144 | 1206 | ||
1145 | c = udev->config[0].desc.bConfigurationValue; | 1207 | /* Rule out configs that draw too much bus current */ |
1146 | if (udev->descriptor.bNumConfigurations != 1) { | 1208 | if (c->desc.bMaxPower * 2 > udev->bus_mA) |
1147 | for (i = 0; i < udev->descriptor.bNumConfigurations; i++) { | 1209 | continue; |
1148 | struct usb_interface_descriptor *desc; | ||
1149 | 1210 | ||
1150 | /* heuristic: Linux is more likely to have class | 1211 | /* If the first config's first interface is COMM/2/0xff |
1151 | * drivers, so avoid vendor-specific interfaces. | 1212 | * (MSFT RNDIS), rule it out unless Linux has host-side |
1152 | */ | 1213 | * RNDIS support. */ |
1153 | desc = &udev->config[i].intf_cache[0] | 1214 | if (i == 0 && desc->bInterfaceClass == USB_CLASS_COMM |
1154 | ->altsetting->desc; | 1215 | && desc->bInterfaceSubClass == 2 |
1155 | if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC) | 1216 | && desc->bInterfaceProtocol == 0xff) { |
1156 | continue; | 1217 | #ifndef CONFIG_USB_NET_RNDIS |
1157 | /* COMM/2/all is CDC ACM, except 0xff is MSFT RNDIS. | 1218 | continue; |
1158 | * MSFT needs this to be the first config; never use | 1219 | #else |
1159 | * it as the default unless Linux has host-side RNDIS. | 1220 | best = c; |
1160 | * A second config would ideally be CDC-Ethernet, but | 1221 | #endif |
1161 | * may instead be the "vendor specific" CDC subset | 1222 | } |
1162 | * long used by ARM Linux for sa1100 or pxa255. | 1223 | |
1163 | */ | 1224 | /* From the remaining configs, choose the first one whose |
1164 | if (desc->bInterfaceClass == USB_CLASS_COMM | 1225 | * first interface is for a non-vendor-specific class. |
1165 | && desc->bInterfaceSubClass == 2 | 1226 | * Reason: Linux is more likely to have a class driver |
1166 | && desc->bInterfaceProtocol == 0xff) { | 1227 | * than a vendor-specific driver. */ |
1167 | c = udev->config[1].desc.bConfigurationValue; | 1228 | else if (udev->descriptor.bDeviceClass != |
1168 | continue; | 1229 | USB_CLASS_VENDOR_SPEC && |
1169 | } | 1230 | desc->bInterfaceClass != |
1170 | c = udev->config[i].desc.bConfigurationValue; | 1231 | USB_CLASS_VENDOR_SPEC) { |
1232 | best = c; | ||
1171 | break; | 1233 | break; |
1172 | } | 1234 | } |
1235 | |||
1236 | /* If all the remaining configs are vendor-specific, | ||
1237 | * choose the first one. */ | ||
1238 | else if (!best) | ||
1239 | best = c; | ||
1240 | } | ||
1241 | |||
1242 | if (best) { | ||
1243 | i = best->desc.bConfigurationValue; | ||
1173 | dev_info(&udev->dev, | 1244 | dev_info(&udev->dev, |
1174 | "configuration #%d chosen from %d choices\n", | 1245 | "configuration #%d chosen from %d choice%s\n", |
1175 | c, udev->descriptor.bNumConfigurations); | 1246 | i, num_configs, plural(num_configs)); |
1247 | } else { | ||
1248 | i = -1; | ||
1249 | dev_warn(&udev->dev, | ||
1250 | "no configuration chosen from %d choice%s\n", | ||
1251 | num_configs, plural(num_configs)); | ||
1176 | } | 1252 | } |
1177 | return c; | 1253 | return i; |
1178 | } | 1254 | } |
1179 | 1255 | ||
1180 | #ifdef DEBUG | 1256 | #ifdef DEBUG |
@@ -1327,17 +1403,13 @@ int usb_new_device(struct usb_device *udev) | |||
1327 | * with the driver core, and lets usb device drivers bind to them. | 1403 | * with the driver core, and lets usb device drivers bind to them. |
1328 | */ | 1404 | */ |
1329 | c = choose_configuration(udev); | 1405 | c = choose_configuration(udev); |
1330 | if (c < 0) | 1406 | if (c >= 0) { |
1331 | dev_warn(&udev->dev, | ||
1332 | "can't choose an initial configuration\n"); | ||
1333 | else { | ||
1334 | err = usb_set_configuration(udev, c); | 1407 | err = usb_set_configuration(udev, c); |
1335 | if (err) { | 1408 | if (err) { |
1336 | dev_err(&udev->dev, "can't set config #%d, error %d\n", | 1409 | dev_err(&udev->dev, "can't set config #%d, error %d\n", |
1337 | c, err); | 1410 | c, err); |
1338 | usb_remove_sysfs_dev_files(udev); | 1411 | /* This need not be fatal. The user can try to |
1339 | device_del(&udev->dev); | 1412 | * set other configurations. */ |
1340 | goto fail; | ||
1341 | } | 1413 | } |
1342 | } | 1414 | } |
1343 | 1415 | ||
@@ -1702,7 +1774,7 @@ static int finish_device_resume(struct usb_device *udev) | |||
1702 | * and device drivers will know about any resume quirks. | 1774 | * and device drivers will know about any resume quirks. |
1703 | */ | 1775 | */ |
1704 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); | 1776 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); |
1705 | if (status < 0) | 1777 | if (status < 2) |
1706 | dev_dbg(&udev->dev, | 1778 | dev_dbg(&udev->dev, |
1707 | "gone after usb resume? status %d\n", | 1779 | "gone after usb resume? status %d\n", |
1708 | status); | 1780 | status); |
@@ -1711,7 +1783,7 @@ static int finish_device_resume(struct usb_device *udev) | |||
1711 | int (*resume)(struct device *); | 1783 | int (*resume)(struct device *); |
1712 | 1784 | ||
1713 | le16_to_cpus(&devstatus); | 1785 | le16_to_cpus(&devstatus); |
1714 | if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP) | 1786 | if ((devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) |
1715 | && udev->parent) { | 1787 | && udev->parent) { |
1716 | status = usb_control_msg(udev, | 1788 | status = usb_control_msg(udev, |
1717 | usb_sndctrlpipe(udev, 0), | 1789 | usb_sndctrlpipe(udev, 0), |
@@ -2374,39 +2446,36 @@ hub_power_remaining (struct usb_hub *hub) | |||
2374 | { | 2446 | { |
2375 | struct usb_device *hdev = hub->hdev; | 2447 | struct usb_device *hdev = hub->hdev; |
2376 | int remaining; | 2448 | int remaining; |
2377 | unsigned i; | 2449 | int port1; |
2378 | 2450 | ||
2379 | remaining = hub->power_budget; | 2451 | if (!hub->limited_power) |
2380 | if (!remaining) /* self-powered */ | ||
2381 | return 0; | 2452 | return 0; |
2382 | 2453 | ||
2383 | for (i = 0; i < hdev->maxchild; i++) { | 2454 | remaining = hdev->bus_mA - hub->descriptor->bHubContrCurrent; |
2384 | struct usb_device *udev = hdev->children[i]; | 2455 | for (port1 = 1; port1 <= hdev->maxchild; ++port1) { |
2385 | int delta, ceiling; | 2456 | struct usb_device *udev = hdev->children[port1 - 1]; |
2457 | int delta; | ||
2386 | 2458 | ||
2387 | if (!udev) | 2459 | if (!udev) |
2388 | continue; | 2460 | continue; |
2389 | 2461 | ||
2390 | /* 100mA per-port ceiling, or 8mA for OTG ports */ | 2462 | /* Unconfigured devices may not use more than 100mA, |
2391 | if (i != (udev->bus->otg_port - 1) || hdev->parent) | 2463 | * or 8mA for OTG ports */ |
2392 | ceiling = 50; | ||
2393 | else | ||
2394 | ceiling = 4; | ||
2395 | |||
2396 | if (udev->actconfig) | 2464 | if (udev->actconfig) |
2397 | delta = udev->actconfig->desc.bMaxPower; | 2465 | delta = udev->actconfig->desc.bMaxPower * 2; |
2466 | else if (port1 != udev->bus->otg_port || hdev->parent) | ||
2467 | delta = 100; | ||
2398 | else | 2468 | else |
2399 | delta = ceiling; | 2469 | delta = 8; |
2400 | // dev_dbg(&udev->dev, "budgeted %dmA\n", 2 * delta); | 2470 | if (delta > hub->mA_per_port) |
2401 | if (delta > ceiling) | 2471 | dev_warn(&udev->dev, "%dmA is over %umA budget " |
2402 | dev_warn(&udev->dev, "%dmA over %dmA budget!\n", | 2472 | "for port %d!\n", |
2403 | 2 * (delta - ceiling), 2 * ceiling); | 2473 | delta, hub->mA_per_port, port1); |
2404 | remaining -= delta; | 2474 | remaining -= delta; |
2405 | } | 2475 | } |
2406 | if (remaining < 0) { | 2476 | if (remaining < 0) { |
2407 | dev_warn(hub->intfdev, | 2477 | dev_warn(hub->intfdev, "%dmA over power budget!\n", |
2408 | "%dmA over power budget!\n", | 2478 | - remaining); |
2409 | -2 * remaining); | ||
2410 | remaining = 0; | 2479 | remaining = 0; |
2411 | } | 2480 | } |
2412 | return remaining; | 2481 | return remaining; |
@@ -2501,7 +2570,8 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2501 | 2570 | ||
2502 | usb_set_device_state(udev, USB_STATE_POWERED); | 2571 | usb_set_device_state(udev, USB_STATE_POWERED); |
2503 | udev->speed = USB_SPEED_UNKNOWN; | 2572 | udev->speed = USB_SPEED_UNKNOWN; |
2504 | 2573 | udev->bus_mA = hub->mA_per_port; | |
2574 | |||
2505 | /* set the address */ | 2575 | /* set the address */ |
2506 | choose_address(udev); | 2576 | choose_address(udev); |
2507 | if (udev->devnum <= 0) { | 2577 | if (udev->devnum <= 0) { |
@@ -2521,16 +2591,16 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2521 | * on the parent. | 2591 | * on the parent. |
2522 | */ | 2592 | */ |
2523 | if (udev->descriptor.bDeviceClass == USB_CLASS_HUB | 2593 | if (udev->descriptor.bDeviceClass == USB_CLASS_HUB |
2524 | && hub->power_budget) { | 2594 | && udev->bus_mA <= 100) { |
2525 | u16 devstat; | 2595 | u16 devstat; |
2526 | 2596 | ||
2527 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, | 2597 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, |
2528 | &devstat); | 2598 | &devstat); |
2529 | if (status < 0) { | 2599 | if (status < 2) { |
2530 | dev_dbg(&udev->dev, "get status %d ?\n", status); | 2600 | dev_dbg(&udev->dev, "get status %d ?\n", status); |
2531 | goto loop_disable; | 2601 | goto loop_disable; |
2532 | } | 2602 | } |
2533 | cpu_to_le16s(&devstat); | 2603 | le16_to_cpus(&devstat); |
2534 | if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) { | 2604 | if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) { |
2535 | dev_err(&udev->dev, | 2605 | dev_err(&udev->dev, |
2536 | "can't connect bus-powered hub " | 2606 | "can't connect bus-powered hub " |
@@ -2583,9 +2653,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2583 | 2653 | ||
2584 | status = hub_power_remaining(hub); | 2654 | status = hub_power_remaining(hub); |
2585 | if (status) | 2655 | if (status) |
2586 | dev_dbg(hub_dev, | 2656 | dev_dbg(hub_dev, "%dmA power budget left\n", status); |
2587 | "%dmA power budget left\n", | ||
2588 | 2 * status); | ||
2589 | 2657 | ||
2590 | return; | 2658 | return; |
2591 | 2659 | ||
@@ -2797,6 +2865,11 @@ static void hub_events(void) | |||
2797 | if (hubchange & HUB_CHANGE_LOCAL_POWER) { | 2865 | if (hubchange & HUB_CHANGE_LOCAL_POWER) { |
2798 | dev_dbg (hub_dev, "power change\n"); | 2866 | dev_dbg (hub_dev, "power change\n"); |
2799 | clear_hub_feature(hdev, C_HUB_LOCAL_POWER); | 2867 | clear_hub_feature(hdev, C_HUB_LOCAL_POWER); |
2868 | if (hubstatus & HUB_STATUS_LOCAL_POWER) | ||
2869 | /* FIXME: Is this always true? */ | ||
2870 | hub->limited_power = 0; | ||
2871 | else | ||
2872 | hub->limited_power = 1; | ||
2800 | } | 2873 | } |
2801 | if (hubchange & HUB_CHANGE_OVERCURRENT) { | 2874 | if (hubchange & HUB_CHANGE_OVERCURRENT) { |
2802 | dev_dbg (hub_dev, "overcurrent change\n"); | 2875 | dev_dbg (hub_dev, "overcurrent change\n"); |
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index bf23f8978024..29d5f45a8456 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h | |||
@@ -220,8 +220,9 @@ struct usb_hub { | |||
220 | struct usb_hub_descriptor *descriptor; /* class descriptor */ | 220 | struct usb_hub_descriptor *descriptor; /* class descriptor */ |
221 | struct usb_tt tt; /* Transaction Translator */ | 221 | struct usb_tt tt; /* Transaction Translator */ |
222 | 222 | ||
223 | u8 power_budget; /* in 2mA units; or zero */ | 223 | unsigned mA_per_port; /* current for each child */ |
224 | 224 | ||
225 | unsigned limited_power:1; | ||
225 | unsigned quiescing:1; | 226 | unsigned quiescing:1; |
226 | unsigned activating:1; | 227 | unsigned activating:1; |
227 | unsigned resume_root_hub:1; | 228 | unsigned resume_root_hub:1; |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index fe74f99ca5f4..99ab774d4fdb 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1387,6 +1387,12 @@ free_interfaces: | |||
1387 | if (dev->state != USB_STATE_ADDRESS) | 1387 | if (dev->state != USB_STATE_ADDRESS) |
1388 | usb_disable_device (dev, 1); // Skip ep0 | 1388 | usb_disable_device (dev, 1); // Skip ep0 |
1389 | 1389 | ||
1390 | n = dev->bus_mA - cp->desc.bMaxPower * 2; | ||
1391 | if (n < 0) | ||
1392 | dev_warn(&dev->dev, "new config #%d exceeds power " | ||
1393 | "limit by %dmA\n", | ||
1394 | configuration, -n); | ||
1395 | |||
1390 | if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 1396 | if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
1391 | USB_REQ_SET_CONFIGURATION, 0, configuration, 0, | 1397 | USB_REQ_SET_CONFIGURATION, 0, configuration, 0, |
1392 | NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) | 1398 | NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) |