aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-mem.c
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2011-09-02 14:05:48 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-09-09 18:52:53 -0400
commit9af5d71d8e1fc404ad2ac1b568dafa1a2f9b3be2 (patch)
treed3f3732ada05aaef7ffb76cfbc5d849b0fc421ac /drivers/usb/host/xhci-mem.c
parent839c817ce67178ca3c7c7ad534c571bba1e69ebe (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.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 5efb0afff5f6..9451d94b78d9 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,
1410 */ 1410 */
1411} 1411}
1412 1412
1413void xhci_clear_endpoint_bw_info(struct xhci_bw_info *bw_info)
1414{
1415 bw_info->ep_interval = 0;
1416 bw_info->mult = 0;
1417 bw_info->num_packets = 0;
1418 bw_info->max_packet_size = 0;
1419 bw_info->type = 0;
1420 bw_info->max_esit_payload = 0;
1421}
1422
1423void xhci_update_bw_info(struct xhci_hcd *xhci,
1424 struct xhci_container_ctx *in_ctx,
1425 struct xhci_input_control_ctx *ctrl_ctx,
1426 struct xhci_virt_device *virt_dev)
1427{
1428 struct xhci_bw_info *bw_info;
1429 struct xhci_ep_ctx *ep_ctx;
1430 unsigned int ep_type;
1431 int i;
1432
1433 for (i = 1; i < 31; ++i) {
1434 bw_info = &virt_dev->eps[i].bw_info;
1435
1436 /* We can't tell what endpoint type is being dropped, but
1437 * unconditionally clearing the bandwidth info for non-periodic
1438 * endpoints should be harmless because the info will never be
1439 * set in the first place.
1440 */
1441 if (!EP_IS_ADDED(ctrl_ctx, i) && EP_IS_DROPPED(ctrl_ctx, i)) {
1442 /* Dropped endpoint */
1443 xhci_clear_endpoint_bw_info(bw_info);
1444 continue;
1445 }
1446
1447 if (EP_IS_ADDED(ctrl_ctx, i)) {
1448 ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, i);
1449 ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2));
1450
1451 /* Ignore non-periodic endpoints */
1452 if (ep_type != ISOC_OUT_EP && ep_type != INT_OUT_EP &&
1453 ep_type != ISOC_IN_EP &&
1454 ep_type != INT_IN_EP)
1455 continue;
1456
1457 /* Added or changed endpoint */
1458 bw_info->ep_interval = CTX_TO_EP_INTERVAL(
1459 le32_to_cpu(ep_ctx->ep_info));
1460 bw_info->mult = CTX_TO_EP_MULT(
1461 le32_to_cpu(ep_ctx->ep_info));
1462 /* Number of packets is zero-based in the input context,
1463 * but we want one-based for the interval table.
1464 */
1465 bw_info->num_packets = CTX_TO_MAX_BURST(
1466 le32_to_cpu(ep_ctx->ep_info2)) + 1;
1467 bw_info->max_packet_size = MAX_PACKET_DECODED(
1468 le32_to_cpu(ep_ctx->ep_info2));
1469 bw_info->type = ep_type;
1470 bw_info->max_esit_payload = CTX_TO_MAX_ESIT_PAYLOAD(
1471 le32_to_cpu(ep_ctx->tx_info));
1472 }
1473 }
1474}
1475
1413/* Copy output xhci_ep_ctx to the input xhci_ep_ctx copy. 1476/* Copy output xhci_ep_ctx to the input xhci_ep_ctx copy.
1414 * Useful when you want to change one particular aspect of the endpoint and then 1477 * Useful when you want to change one particular aspect of the endpoint and then
1415 * issue a configure endpoint command. 1478 * issue a configure endpoint command.