aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/core/hcd.c86
-rw-r--r--drivers/usb/core/hcd.h32
-rw-r--r--drivers/usb/core/message.c20
-rw-r--r--drivers/usb/core/urb.c6
4 files changed, 144 insertions, 0 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 823744d80cb9..b2da4753b12e 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1560,6 +1560,92 @@ rescan:
1560 } 1560 }
1561} 1561}
1562 1562
1563/* Check whether a new configuration or alt setting for an interface
1564 * will exceed the bandwidth for the bus (or the host controller resources).
1565 * Only pass in a non-NULL config or interface, not both!
1566 * Passing NULL for both new_config and new_intf means the device will be
1567 * de-configured by issuing a set configuration 0 command.
1568 */
1569int usb_hcd_check_bandwidth(struct usb_device *udev,
1570 struct usb_host_config *new_config,
1571 struct usb_interface *new_intf)
1572{
1573 int num_intfs, i, j;
1574 struct usb_interface_cache *intf_cache;
1575 struct usb_host_interface *alt = 0;
1576 int ret = 0;
1577 struct usb_hcd *hcd;
1578 struct usb_host_endpoint *ep;
1579
1580 hcd = bus_to_hcd(udev->bus);
1581 if (!hcd->driver->check_bandwidth)
1582 return 0;
1583
1584 /* Configuration is being removed - set configuration 0 */
1585 if (!new_config && !new_intf) {
1586 for (i = 1; i < 16; ++i) {
1587 ep = udev->ep_out[i];
1588 if (ep)
1589 hcd->driver->drop_endpoint(hcd, udev, ep);
1590 ep = udev->ep_in[i];
1591 if (ep)
1592 hcd->driver->drop_endpoint(hcd, udev, ep);
1593 }
1594 hcd->driver->check_bandwidth(hcd, udev);
1595 return 0;
1596 }
1597 /* Check if the HCD says there's enough bandwidth. Enable all endpoints
1598 * each interface's alt setting 0 and ask the HCD to check the bandwidth
1599 * of the bus. There will always be bandwidth for endpoint 0, so it's
1600 * ok to exclude it.
1601 */
1602 if (new_config) {
1603 num_intfs = new_config->desc.bNumInterfaces;
1604 /* Remove endpoints (except endpoint 0, which is always on the
1605 * schedule) from the old config from the schedule
1606 */
1607 for (i = 1; i < 16; ++i) {
1608 ep = udev->ep_out[i];
1609 if (ep) {
1610 ret = hcd->driver->drop_endpoint(hcd, udev, ep);
1611 if (ret < 0)
1612 goto reset;
1613 }
1614 ep = udev->ep_in[i];
1615 if (ep) {
1616 ret = hcd->driver->drop_endpoint(hcd, udev, ep);
1617 if (ret < 0)
1618 goto reset;
1619 }
1620 }
1621 for (i = 0; i < num_intfs; ++i) {
1622
1623 /* Dig the endpoints for alt setting 0 out of the
1624 * interface cache for this interface
1625 */
1626 intf_cache = new_config->intf_cache[i];
1627 for (j = 0; j < intf_cache->num_altsetting; j++) {
1628 if (intf_cache->altsetting[j].desc.bAlternateSetting == 0)
1629 alt = &intf_cache->altsetting[j];
1630 }
1631 if (!alt) {
1632 printk(KERN_DEBUG "Did not find alt setting 0 for intf %d\n", i);
1633 continue;
1634 }
1635 for (j = 0; j < alt->desc.bNumEndpoints; j++) {
1636 ret = hcd->driver->add_endpoint(hcd, udev, &alt->endpoint[j]);
1637 if (ret < 0)
1638 goto reset;
1639 }
1640 }
1641 }
1642 ret = hcd->driver->check_bandwidth(hcd, udev);
1643reset:
1644 if (ret < 0)
1645 hcd->driver->reset_bandwidth(hcd, udev);
1646 return ret;
1647}
1648
1563/* Disables the endpoint: synchronizes with the hcd to make sure all 1649/* Disables the endpoint: synchronizes with the hcd to make sure all
1564 * endpoint state is gone from hardware. usb_hcd_flush_endpoint() must 1650 * endpoint state is gone from hardware. usb_hcd_flush_endpoint() must
1565 * have been called previously. Use for set_configuration, set_interface, 1651 * have been called previously. Use for set_configuration, set_interface,
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index ae6d9db41ca9..d397ecfd5b17 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -232,6 +232,35 @@ struct hc_driver {
232 int (*alloc_dev)(struct usb_hcd *, struct usb_device *); 232 int (*alloc_dev)(struct usb_hcd *, struct usb_device *);
233 /* Called by usb_release_dev to free HC device structures */ 233 /* Called by usb_release_dev to free HC device structures */
234 void (*free_dev)(struct usb_hcd *, struct usb_device *); 234 void (*free_dev)(struct usb_hcd *, struct usb_device *);
235
236 /* Bandwidth computation functions */
237 /* Note that add_endpoint() can only be called once per endpoint before
238 * check_bandwidth() or reset_bandwidth() must be called.
239 * drop_endpoint() can only be called once per endpoint also.
240 * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will
241 * add the endpoint to the schedule with possibly new parameters denoted by a
242 * different endpoint descriptor in usb_host_endpoint.
243 * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is
244 * not allowed.
245 */
246 /* Allocate endpoint resources and add them to a new schedule */
247 int (*add_endpoint)(struct usb_hcd *, struct usb_device *, struct usb_host_endpoint *);
248 /* Drop an endpoint from a new schedule */
249 int (*drop_endpoint)(struct usb_hcd *, struct usb_device *, struct usb_host_endpoint *);
250 /* Check that a new hardware configuration, set using
251 * endpoint_enable and endpoint_disable, does not exceed bus
252 * bandwidth. This must be called before any set configuration
253 * or set interface requests are sent to the device.
254 */
255 int (*check_bandwidth)(struct usb_hcd *, struct usb_device *);
256 /* Reset the device schedule to the last known good schedule,
257 * which was set from a previous successful call to
258 * check_bandwidth(). This reverts any add_endpoint() and
259 * drop_endpoint() calls since that last successful call.
260 * Used for when a check_bandwidth() call fails due to resource
261 * or bandwidth constraints.
262 */
263 void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *);
235 /* Returns the hardware-chosen device address */ 264 /* Returns the hardware-chosen device address */
236 int (*address_device)(struct usb_hcd *, struct usb_device *udev); 265 int (*address_device)(struct usb_hcd *, struct usb_device *udev);
237}; 266};
@@ -252,6 +281,9 @@ extern void usb_hcd_disable_endpoint(struct usb_device *udev,
252extern void usb_hcd_reset_endpoint(struct usb_device *udev, 281extern void usb_hcd_reset_endpoint(struct usb_device *udev,
253 struct usb_host_endpoint *ep); 282 struct usb_host_endpoint *ep);
254extern void usb_hcd_synchronize_unlinks(struct usb_device *udev); 283extern void usb_hcd_synchronize_unlinks(struct usb_device *udev);
284extern int usb_hcd_check_bandwidth(struct usb_device *udev,
285 struct usb_host_config *new_config,
286 struct usb_interface *new_intf);
255extern int usb_hcd_get_frame_number(struct usb_device *udev); 287extern int usb_hcd_get_frame_number(struct usb_device *udev);
256 288
257extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver, 289extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 9bd26dec7599..3a2e69ec2f29 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -510,6 +510,10 @@ EXPORT_SYMBOL_GPL(usb_sg_init);
510 * could be transferred. That capability is less useful for low or full 510 * could be transferred. That capability is less useful for low or full
511 * speed interrupt endpoints, which allow at most one packet per millisecond, 511 * speed interrupt endpoints, which allow at most one packet per millisecond,
512 * of at most 8 or 64 bytes (respectively). 512 * of at most 8 or 64 bytes (respectively).
513 *
514 * It is not necessary to call this function to reserve bandwidth for devices
515 * under an xHCI host controller, as the bandwidth is reserved when the
516 * configuration or interface alt setting is selected.
513 */ 517 */
514void usb_sg_wait(struct usb_sg_request *io) 518void usb_sg_wait(struct usb_sg_request *io)
515{ 519{
@@ -1653,6 +1657,21 @@ free_interfaces:
1653 if (ret) 1657 if (ret)
1654 goto free_interfaces; 1658 goto free_interfaces;
1655 1659
1660 /* Make sure we have bandwidth (and available HCD resources) for this
1661 * configuration. Remove endpoints from the schedule if we're dropping
1662 * this configuration to set configuration 0. After this point, the
1663 * host controller will not allow submissions to dropped endpoints. If
1664 * this call fails, the device state is unchanged.
1665 */
1666 if (cp)
1667 ret = usb_hcd_check_bandwidth(dev, cp, NULL);
1668 else
1669 ret = usb_hcd_check_bandwidth(dev, NULL, NULL);
1670 if (ret < 0) {
1671 usb_autosuspend_device(dev);
1672 goto free_interfaces;
1673 }
1674
1656 /* if it's already configured, clear out old state first. 1675 /* if it's already configured, clear out old state first.
1657 * getting rid of old interfaces means unbinding their drivers. 1676 * getting rid of old interfaces means unbinding their drivers.
1658 */ 1677 */
@@ -1675,6 +1694,7 @@ free_interfaces:
1675 dev->actconfig = cp; 1694 dev->actconfig = cp;
1676 if (!cp) { 1695 if (!cp) {
1677 usb_set_device_state(dev, USB_STATE_ADDRESS); 1696 usb_set_device_state(dev, USB_STATE_ADDRESS);
1697 usb_hcd_check_bandwidth(dev, NULL, NULL);
1678 usb_autosuspend_device(dev); 1698 usb_autosuspend_device(dev);
1679 goto free_interfaces; 1699 goto free_interfaces;
1680 } 1700 }
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 02eb0ef7a4c3..0885d4abdc62 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -241,6 +241,12 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb);
241 * If the USB subsystem can't allocate sufficient bandwidth to perform 241 * If the USB subsystem can't allocate sufficient bandwidth to perform
242 * the periodic request, submitting such a periodic request should fail. 242 * the periodic request, submitting such a periodic request should fail.
243 * 243 *
244 * For devices under xHCI, the bandwidth is reserved at configuration time, or
245 * when the alt setting is selected. If there is not enough bus bandwidth, the
246 * configuration/alt setting request will fail. Therefore, submissions to
247 * periodic endpoints on devices under xHCI should never fail due to bandwidth
248 * constraints.
249 *
244 * Device drivers must explicitly request that repetition, by ensuring that 250 * Device drivers must explicitly request that repetition, by ensuring that
245 * some URB is always on the endpoint's queue (except possibly for short 251 * some URB is always on the endpoint's queue (except possibly for short
246 * periods during completion callacks). When there is no longer an urb 252 * periods during completion callacks). When there is no longer an urb