aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci.h
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2011-09-02 14:05:50 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-09-09 18:52:53 -0400
commit2e27980e6eb78114c4ecbaad1ba71836e3887d18 (patch)
treef87552d67d6a23090ceb97868f7857ccf2ce6f97 /drivers/usb/host/xhci.h
parent9af5d71d8e1fc404ad2ac1b568dafa1a2f9b3be2 (diff)
xhci: Track interval bandwidth tables per port/TT.
In order to update the root port or TT's bandwidth interval table, we will need to keep track of a list of endpoints, per interval. That way we can easily know the new largest max packet size when we have to remove an endpoint. Add an endpoint list for each root port or TT structure, sorted by endpoint max packet size. Insert new endpoints into the list such that the head of the list always has the endpoint with the greatest max packet size. Only insert endpoints and update the interval table with new information when those endpoints are periodic. Make sure to update the number of active TTs when we add or drop periodic endpoints. A TT is only considered active if it has one or more periodic endpoints attached (control and bulk are best effort, and counted in the 20% reserved on the high speed bus). If the number of active endpoints for a TT was zero, and it's now non-zero, increment the number of active TTs for the rootport. If the number of active endpoints was non-zero, and it's now zero, decrement the number of active TTs. We have to be careful when we're checking the bandwidth for a new configuration/alt setting. If we don't have enough bandwidth, we need to be able to "roll back" the bandwidth information stored in the endpoint and the root port/TT interval bandwidth table. We can't just create a copy of the interval bandwidth table, modify it, and check the bandwidth with the copy because we have lists of endpoints and entries can't be on more than one list. Instead, we copy the old endpoint bandwidth information, and use it to revert the interval table when the bandwidth check fails. We don't check the bandwidth after endpoints are dropped from the interval table when a device is reset or freed after a disconnect, because having endpoints use less bandwidth should not push the bandwidth usage over the limits. Besides which, we can't fail a device disconnect. 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.h')
-rw-r--r--drivers/usb/host/xhci.h15
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index af15b903e061..050f07b1e790 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -797,7 +797,9 @@ struct xhci_virt_ep {
797 * process the missed tds on the endpoint ring. 797 * process the missed tds on the endpoint ring.
798 */ 798 */
799 bool skip; 799 bool skip;
800 /* Bandwidth checking storage */
800 struct xhci_bw_info bw_info; 801 struct xhci_bw_info bw_info;
802 struct list_head bw_endpoint_list;
801}; 803};
802 804
803enum xhci_overhead_type { 805enum xhci_overhead_type {
@@ -808,6 +810,10 @@ enum xhci_overhead_type {
808 810
809struct xhci_interval_bw { 811struct xhci_interval_bw {
810 unsigned int num_packets; 812 unsigned int num_packets;
813 /* Sorted by max packet size.
814 * Head of the list is the greatest max packet size.
815 */
816 struct list_head endpoints;
811 /* How many endpoints of each speed are present. */ 817 /* How many endpoints of each speed are present. */
812 unsigned int overhead[3]; 818 unsigned int overhead[3];
813}; 819};
@@ -1511,6 +1517,15 @@ unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc);
1511unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index); 1517unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index);
1512unsigned int xhci_last_valid_endpoint(u32 added_ctxs); 1518unsigned int xhci_last_valid_endpoint(u32 added_ctxs);
1513void xhci_endpoint_zero(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, struct usb_host_endpoint *ep); 1519void xhci_endpoint_zero(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, struct usb_host_endpoint *ep);
1520void xhci_drop_ep_from_interval_table(struct xhci_hcd *xhci,
1521 struct xhci_bw_info *ep_bw,
1522 struct xhci_interval_bw_table *bw_table,
1523 struct usb_device *udev,
1524 struct xhci_virt_ep *virt_ep,
1525 struct xhci_tt_bw_info *tt_info);
1526void xhci_update_tt_active_eps(struct xhci_hcd *xhci,
1527 struct xhci_virt_device *virt_dev,
1528 int old_active_eps);
1514void xhci_clear_endpoint_bw_info(struct xhci_bw_info *bw_info); 1529void xhci_clear_endpoint_bw_info(struct xhci_bw_info *bw_info);
1515void xhci_update_bw_info(struct xhci_hcd *xhci, 1530void xhci_update_bw_info(struct xhci_hcd *xhci,
1516 struct xhci_container_ctx *in_ctx, 1531 struct xhci_container_ctx *in_ctx,