aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2006-06-01 13:59:16 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-06-21 18:04:15 -0400
commit6ad07129a8ed2e13dcd7e6313c201c32bcf7cc32 (patch)
tree55a1e1a2bdb6bfc5e93f169e22be98598dfbf8c7 /drivers
parentdf9a1f482d1252045210f50048911e2efba61e62 (diff)
[PATCH] usbcore: recovery from Set-Configuration failure
This patch (as703) improves the error handling when a Set-Configuration request fails. The old interfaces are all unregistered before the request is sent, and if the request fails then we don't know what config the device is using. So it makes no sense to leave actconfig pointing to the old configuration with its invalid interfaces. 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/message.c151
1 files changed, 75 insertions, 76 deletions
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index b2f608b0538d..8569600f3130 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1411,15 +1411,7 @@ free_interfaces:
1411 return ret; 1411 return ret;
1412 } 1412 }
1413 } 1413 }
1414 }
1415 1414
1416 /* if it's already configured, clear out old state first.
1417 * getting rid of old interfaces means unbinding their drivers.
1418 */
1419 if (dev->state != USB_STATE_ADDRESS)
1420 usb_disable_device (dev, 1); // Skip ep0
1421
1422 if (cp) {
1423 i = dev->bus_mA - cp->desc.bMaxPower * 2; 1415 i = dev->bus_mA - cp->desc.bMaxPower * 2;
1424 if (i < 0) 1416 if (i < 0)
1425 dev_warn(&dev->dev, "new config #%d exceeds power " 1417 dev_warn(&dev->dev, "new config #%d exceeds power "
@@ -1427,84 +1419,91 @@ free_interfaces:
1427 configuration, -i); 1419 configuration, -i);
1428 } 1420 }
1429 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
1430 if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 1428 if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1431 USB_REQ_SET_CONFIGURATION, 0, configuration, 0, 1429 USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
1432 NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) 1430 NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) {
1433 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 }
1434 1437
1435 dev->actconfig = cp; 1438 dev->actconfig = cp;
1436 if (!cp) 1439 if (!cp) {
1437 usb_set_device_state(dev, USB_STATE_ADDRESS); 1440 usb_set_device_state(dev, USB_STATE_ADDRESS);
1438 else { 1441 goto free_interfaces;
1439 usb_set_device_state(dev, USB_STATE_CONFIGURED); 1442 }
1443 usb_set_device_state(dev, USB_STATE_CONFIGURED);
1440 1444
1441 /* Initialize the new interface structures and the 1445 /* Initialize the new interface structures and the
1442 * hc/hcd/usbcore interface/endpoint state. 1446 * hc/hcd/usbcore interface/endpoint state.
1443 */ 1447 */
1444 for (i = 0; i < nintf; ++i) { 1448 for (i = 0; i < nintf; ++i) {
1445 struct usb_interface_cache *intfc; 1449 struct usb_interface_cache *intfc;
1446 struct usb_interface *intf; 1450 struct usb_interface *intf;
1447 struct usb_host_interface *alt; 1451 struct usb_host_interface *alt;
1448
1449 cp->interface[i] = intf = new_interfaces[i];
1450 intfc = cp->intf_cache[i];
1451 intf->altsetting = intfc->altsetting;
1452 intf->num_altsetting = intfc->num_altsetting;
1453 kref_get(&intfc->ref);
1454
1455 alt = usb_altnum_to_altsetting(intf, 0);
1456
1457 /* No altsetting 0? We'll assume the first altsetting.
1458 * We could use a GetInterface call, but if a device is
1459 * so non-compliant that it doesn't have altsetting 0
1460 * then I wouldn't trust its reply anyway.
1461 */
1462 if (!alt)
1463 alt = &intf->altsetting[0];
1464
1465 intf->cur_altsetting = alt;
1466 usb_enable_interface(dev, intf);
1467 intf->dev.parent = &dev->dev;
1468 intf->dev.driver = NULL;
1469 intf->dev.bus = &usb_bus_type;
1470 intf->dev.dma_mask = dev->dev.dma_mask;
1471 intf->dev.release = release_interface;
1472 device_initialize (&intf->dev);
1473 mark_quiesced(intf);
1474 sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d",
1475 dev->bus->busnum, dev->devpath,
1476 configuration,
1477 alt->desc.bInterfaceNumber);
1478 }
1479 kfree(new_interfaces);
1480 1452
1481 if (cp->string == NULL) 1453 cp->interface[i] = intf = new_interfaces[i];
1482 cp->string = usb_cache_string(dev, 1454 intfc = cp->intf_cache[i];
1483 cp->desc.iConfiguration); 1455 intf->altsetting = intfc->altsetting;
1456 intf->num_altsetting = intfc->num_altsetting;
1457 kref_get(&intfc->ref);
1484 1458
1485 /* Now that all the interfaces are set up, register them 1459 alt = usb_altnum_to_altsetting(intf, 0);
1486 * to trigger binding of drivers to interfaces. probe() 1460
1487 * routines may install different altsettings and may 1461 /* No altsetting 0? We'll assume the first altsetting.
1488 * claim() any interfaces not yet bound. Many class drivers 1462 * We could use a GetInterface call, but if a device is
1489 * need that: CDC, audio, video, etc. 1463 * so non-compliant that it doesn't have altsetting 0
1464 * then I wouldn't trust its reply anyway.
1490 */ 1465 */
1491 for (i = 0; i < nintf; ++i) { 1466 if (!alt)
1492 struct usb_interface *intf = cp->interface[i]; 1467 alt = &intf->altsetting[0];
1493 1468
1494 dev_dbg (&dev->dev, 1469 intf->cur_altsetting = alt;
1495 "adding %s (config #%d, interface %d)\n", 1470 usb_enable_interface(dev, intf);
1496 intf->dev.bus_id, configuration, 1471 intf->dev.parent = &dev->dev;
1497 intf->cur_altsetting->desc.bInterfaceNumber); 1472 intf->dev.driver = NULL;
1498 ret = device_add (&intf->dev); 1473 intf->dev.bus = &usb_bus_type;
1499 if (ret != 0) { 1474 intf->dev.dma_mask = dev->dev.dma_mask;
1500 dev_err(&dev->dev, 1475 intf->dev.release = release_interface;
1501 "device_add(%s) --> %d\n", 1476 device_initialize (&intf->dev);
1502 intf->dev.bus_id, 1477 mark_quiesced(intf);
1503 ret); 1478 sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d",
1504 continue; 1479 dev->bus->busnum, dev->devpath,
1505 } 1480 configuration, alt->desc.bInterfaceNumber);
1506 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;
1507 } 1505 }
1506 usb_create_sysfs_intf_files (intf);
1508 } 1507 }
1509 1508
1510 return 0; 1509 return 0;