diff options
author | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2011-09-02 11:05:48 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-09-09 15:52:53 -0700 |
commit | 9af5d71d8e1fc404ad2ac1b568dafa1a2f9b3be2 (patch) | |
tree | d3f3732ada05aaef7ffb76cfbc5d849b0fc421ac /drivers/usb/host/xhci-mem.c | |
parent | 839c817ce67178ca3c7c7ad534c571bba1e69ebe (diff) |
xhci: Store endpoint bandwidth information.
In the upcoming patches, we'll use some stored endpoint information to
make software keep track of the worst-case bandwidth schedule. We need to
store several variables associated with each periodic endpoint:
- the type of endpoint
- Max Packet Size
- Mult
- Max ESIT payload
- Max Burst Size (aka number of packets, stored in one-based form)
- the endpoint interval (normalized to powers of 2 microframes)
All this information is available to the hardware, and stored in its
device output context. However, we need to ensure that the new
information is stored before the xHCI driver drops the xhci->lock to wait
on the Configure Endpoint command, so that another driver requesting a
configuration or alt setting change will see the update. The Configure
Endpoint command will never fail on the hardware that needs this software
bandwidth checking (assuming the slot is enabled and the flags are set
properly), so updating the endpoint info before the command completes
should be fine.
Until we add in the bandwidth checking code, just update the endpoint
information after the Configure Endpoint command completes, and after a
Reset Device command completes. Don't bother to clear the endpoint
bandwidth info when a device is being freed, since the xhci_virt_ep is
just going to be freed anyway.
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-mem.c')
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 5efb0afff5f..9451d94b78d 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1410,6 +1410,69 @@ void xhci_endpoint_zero(struct xhci_hcd *xhci, */ } +void xhci_clear_endpoint_bw_info(struct xhci_bw_info *bw_info) +{ + bw_info->ep_interval = 0; + bw_info->mult = 0; + bw_info->num_packets = 0; + bw_info->max_packet_size = 0; + bw_info->type = 0; + bw_info->max_esit_payload = 0; +} + +void xhci_update_bw_info(struct xhci_hcd *xhci, + struct xhci_container_ctx *in_ctx, + struct xhci_input_control_ctx *ctrl_ctx, + struct xhci_virt_device *virt_dev) +{ + struct xhci_bw_info *bw_info; + struct xhci_ep_ctx *ep_ctx; + unsigned int ep_type; + int i; + + for (i = 1; i < 31; ++i) { + bw_info = &virt_dev->eps[i].bw_info; + + /* We can't tell what endpoint type is being dropped, but + * unconditionally clearing the bandwidth info for non-periodic + * endpoints should be harmless because the info will never be + * set in the first place. + */ + if (!EP_IS_ADDED(ctrl_ctx, i) && EP_IS_DROPPED(ctrl_ctx, i)) { + /* Dropped endpoint */ + xhci_clear_endpoint_bw_info(bw_info); + continue; + } + + if (EP_IS_ADDED(ctrl_ctx, i)) { + ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, i); + ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2)); + + /* Ignore non-periodic endpoints */ + if (ep_type != ISOC_OUT_EP && ep_type != INT_OUT_EP && + ep_type != ISOC_IN_EP && + ep_type != INT_IN_EP) + continue; + + /* Added or changed endpoint */ + bw_info->ep_interval = CTX_TO_EP_INTERVAL( + le32_to_cpu(ep_ctx->ep_info)); + bw_info->mult = CTX_TO_EP_MULT( + le32_to_cpu(ep_ctx->ep_info)); + /* Number of packets is zero-based in the input context, + * but we want one-based for the interval table. + */ + bw_info->num_packets = CTX_TO_MAX_BURST( + le32_to_cpu(ep_ctx->ep_info2)) + 1; + bw_info->max_packet_size = MAX_PACKET_DECODED( + le32_to_cpu(ep_ctx->ep_info2)); + bw_info->type = ep_type; + bw_info->max_esit_payload = CTX_TO_MAX_ESIT_PAYLOAD( + le32_to_cpu(ep_ctx->tx_info)); + } + } +} + /* Copy output xhci_ep_ctx to the input xhci_ep_ctx copy. * Useful when you want to change one particular aspect of the endpoint and then * issue a configure endpoint command. |