diff options
-rw-r--r-- | drivers/usb/core/message.c | 151 |
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; |