diff options
author | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2009-04-27 19:58:38 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-06-15 21:44:49 -0700 |
commit | f94e0186312b0fc39f41eed4e21836ed74b7efe1 (patch) | |
tree | d445d846f62c23cfbefc4958168d9cf4bacea3a4 /drivers/usb/host/xhci-ring.c | |
parent | 79abb1ab13cee5ba488210798b6e7bbae0b391ac (diff) | |
download | lwn-f94e0186312b0fc39f41eed4e21836ed74b7efe1.tar.gz lwn-f94e0186312b0fc39f41eed4e21836ed74b7efe1.zip |
USB: xhci: Bandwidth allocation support
Since the xHCI host controller hardware (xHC) has an internal schedule, it
needs a better representation of what devices are consuming bandwidth on
the bus. Each device is represented by a device context, with data about
the device, endpoints, and pointers to each endpoint ring.
We need to update the endpoint information for a device context before a
new configuration or alternate interface setting is selected. We setup an
input device context with modified endpoint information and newly
allocated endpoint rings, and then submit a Configure Endpoint Command to
the hardware.
The host controller can reject the new configuration if it exceeds the bus
bandwidth, or the host controller doesn't have enough internal resources
for the configuration. If the command fails, we still have the older
device context with the previous configuration. If the command succeeds,
we free the old endpoint rings.
The root hub isn't a real device, so always say yes to any bandwidth
changes for it.
The USB core will enable, disable, and then enable endpoint 0 several
times during the initialization sequence. The device will always have an
endpoint ring for endpoint 0 and bandwidth allocated for that, unless the
device is disconnected or gets a SetAddress 0 request. So we don't pay
attention for when xhci_check_bandwidth() is called for a re-add of
endpoint 0.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index f04162ae4374..b4ccf0d72c17 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -281,6 +281,10 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, if (xhci->devs[slot_id]) xhci_free_virt_device(xhci, slot_id); break; + case TRB_TYPE(TRB_CONFIG_EP): + xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(event->status); + complete(&xhci->devs[slot_id]->cmd_completion); + break; case TRB_TYPE(TRB_ADDR_DEV): xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(event->status); complete(&xhci->addr_dev); @@ -809,3 +813,10 @@ int queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, u32 slot_ return queue_command(xhci, in_ctx_ptr, 0, 0, TRB_TYPE(TRB_ADDR_DEV) | SLOT_ID_FOR_TRB(slot_id)); } + +/* Queue a configure endpoint command TRB */ +int queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, u32 slot_id) +{ + return queue_command(xhci, in_ctx_ptr, 0, 0, + TRB_TYPE(TRB_CONFIG_EP) | SLOT_ID_FOR_TRB(slot_id)); +} |