aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-ring.c
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2009-04-27 22:58:38 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-16 00:44:49 -0400
commitf94e0186312b0fc39f41eed4e21836ed74b7efe1 (patch)
treed445d846f62c23cfbefc4958168d9cf4bacea3a4 /drivers/usb/host/xhci-ring.c
parent79abb1ab13cee5ba488210798b6e7bbae0b391ac (diff)
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.c11
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,
281 if (xhci->devs[slot_id]) 281 if (xhci->devs[slot_id])
282 xhci_free_virt_device(xhci, slot_id); 282 xhci_free_virt_device(xhci, slot_id);
283 break; 283 break;
284 case TRB_TYPE(TRB_CONFIG_EP):
285 xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(event->status);
286 complete(&xhci->devs[slot_id]->cmd_completion);
287 break;
284 case TRB_TYPE(TRB_ADDR_DEV): 288 case TRB_TYPE(TRB_ADDR_DEV):
285 xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(event->status); 289 xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(event->status);
286 complete(&xhci->addr_dev); 290 complete(&xhci->addr_dev);
@@ -809,3 +813,10 @@ int queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, u32 slot_
809 return queue_command(xhci, in_ctx_ptr, 0, 0, 813 return queue_command(xhci, in_ctx_ptr, 0, 0,
810 TRB_TYPE(TRB_ADDR_DEV) | SLOT_ID_FOR_TRB(slot_id)); 814 TRB_TYPE(TRB_ADDR_DEV) | SLOT_ID_FOR_TRB(slot_id));
811} 815}
816
817/* Queue a configure endpoint command TRB */
818int queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, u32 slot_id)
819{
820 return queue_command(xhci, in_ctx_ptr, 0, 0,
821 TRB_TYPE(TRB_CONFIG_EP) | SLOT_ID_FOR_TRB(slot_id));
822}