aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci-mem.c')
-rw-r--r--drivers/usb/host/xhci-mem.c132
1 files changed, 131 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 1755c668ac05..5efb0afff5f6 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -687,7 +687,98 @@ static void xhci_init_endpoint_timer(struct xhci_hcd *xhci,
687 ep->xhci = xhci; 687 ep->xhci = xhci;
688} 688}
689 689
690/* All the xhci_tds in the ring's TD list should be freed at this point */ 690static void xhci_free_tt_info(struct xhci_hcd *xhci,
691 struct xhci_virt_device *virt_dev,
692 int slot_id)
693{
694 struct list_head *tt;
695 struct list_head *tt_list_head;
696 struct list_head *tt_next;
697 struct xhci_tt_bw_info *tt_info;
698
699 /* If the device never made it past the Set Address stage,
700 * it may not have the real_port set correctly.
701 */
702 if (virt_dev->real_port == 0 ||
703 virt_dev->real_port > HCS_MAX_PORTS(xhci->hcs_params1)) {
704 xhci_dbg(xhci, "Bad real port.\n");
705 return;
706 }
707
708 tt_list_head = &(xhci->rh_bw[virt_dev->real_port - 1].tts);
709 if (list_empty(tt_list_head))
710 return;
711
712 list_for_each(tt, tt_list_head) {
713 tt_info = list_entry(tt, struct xhci_tt_bw_info, tt_list);
714 if (tt_info->slot_id == slot_id)
715 break;
716 }
717 /* Cautionary measure in case the hub was disconnected before we
718 * stored the TT information.
719 */
720 if (tt_info->slot_id != slot_id)
721 return;
722
723 tt_next = tt->next;
724 tt_info = list_entry(tt, struct xhci_tt_bw_info,
725 tt_list);
726 /* Multi-TT hubs will have more than one entry */
727 do {
728 list_del(tt);
729 kfree(tt_info);
730 tt = tt_next;
731 if (list_empty(tt_list_head))
732 break;
733 tt_next = tt->next;
734 tt_info = list_entry(tt, struct xhci_tt_bw_info,
735 tt_list);
736 } while (tt_info->slot_id == slot_id);
737}
738
739int xhci_alloc_tt_info(struct xhci_hcd *xhci,
740 struct xhci_virt_device *virt_dev,
741 struct usb_device *hdev,
742 struct usb_tt *tt, gfp_t mem_flags)
743{
744 struct xhci_tt_bw_info *tt_info;
745 unsigned int num_ports;
746 int i, j;
747
748 if (!tt->multi)
749 num_ports = 1;
750 else
751 num_ports = hdev->maxchild;
752
753 for (i = 0; i < num_ports; i++, tt_info++) {
754 struct xhci_interval_bw_table *bw_table;
755
756 tt_info = kzalloc(sizeof(*tt_info), mem_flags);
757 if (!tt_info)
758 goto free_tts;
759 INIT_LIST_HEAD(&tt_info->tt_list);
760 list_add(&tt_info->tt_list,
761 &xhci->rh_bw[virt_dev->real_port - 1].tts);
762 tt_info->slot_id = virt_dev->udev->slot_id;
763 if (tt->multi)
764 tt_info->ttport = i+1;
765 bw_table = &tt_info->bw_table;
766 for (j = 0; j < XHCI_MAX_INTERVAL; j++)
767 INIT_LIST_HEAD(&bw_table->interval_bw[j].endpoints);
768 }
769 return 0;
770
771free_tts:
772 xhci_free_tt_info(xhci, virt_dev, virt_dev->udev->slot_id);
773 return -ENOMEM;
774}
775
776
777/* All the xhci_tds in the ring's TD list should be freed at this point.
778 * Should be called with xhci->lock held if there is any chance the TT lists
779 * will be manipulated by the configure endpoint, allocate device, or update
780 * hub functions while this function is removing the TT entries from the list.
781 */
691void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id) 782void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
692{ 783{
693 struct xhci_virt_device *dev; 784 struct xhci_virt_device *dev;
@@ -709,6 +800,8 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
709 xhci_free_stream_info(xhci, 800 xhci_free_stream_info(xhci,
710 dev->eps[i].stream_info); 801 dev->eps[i].stream_info);
711 } 802 }
803 /* If this is a hub, free the TT(s) from the TT list */
804 xhci_free_tt_info(xhci, dev, slot_id);
712 805
713 if (dev->ring_cache) { 806 if (dev->ring_cache) {
714 for (i = 0; i < dev->num_rings_cached; i++) 807 for (i = 0; i < dev->num_rings_cached; i++)
@@ -926,6 +1019,36 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
926 xhci_dbg(xhci, "Set root hub portnum to %d\n", port_num); 1019 xhci_dbg(xhci, "Set root hub portnum to %d\n", port_num);
927 xhci_dbg(xhci, "Set fake root hub portnum to %d\n", dev->fake_port); 1020 xhci_dbg(xhci, "Set fake root hub portnum to %d\n", dev->fake_port);
928 1021
1022 /* Find the right bandwidth table that this device will be a part of.
1023 * If this is a full speed device attached directly to a root port (or a
1024 * decendent of one), it counts as a primary bandwidth domain, not a
1025 * secondary bandwidth domain under a TT. An xhci_tt_info structure
1026 * will never be created for the HS root hub.
1027 */
1028 if (!udev->tt || !udev->tt->hub->parent) {
1029 dev->bw_table = &xhci->rh_bw[port_num - 1].bw_table;
1030 } else {
1031 struct xhci_root_port_bw_info *rh_bw;
1032 struct xhci_tt_bw_info *tt_bw;
1033
1034 rh_bw = &xhci->rh_bw[port_num - 1];
1035 /* Find the right TT. */
1036 list_for_each_entry(tt_bw, &rh_bw->tts, tt_list) {
1037 if (tt_bw->slot_id != udev->tt->hub->slot_id)
1038 continue;
1039
1040 if (!dev->udev->tt->multi ||
1041 (udev->tt->multi &&
1042 tt_bw->ttport == dev->udev->ttport)) {
1043 dev->bw_table = &tt_bw->bw_table;
1044 dev->tt_info = tt_bw;
1045 break;
1046 }
1047 }
1048 if (!dev->tt_info)
1049 xhci_warn(xhci, "WARN: Didn't find a matching TT\n");
1050 }
1051
929 /* Is this a LS/FS device under an external HS hub? */ 1052 /* Is this a LS/FS device under an external HS hub? */
930 if (udev->tt && udev->tt->hub->parent) { 1053 if (udev->tt && udev->tt->hub->parent) {
931 slot_ctx->tt_info = cpu_to_le32(udev->tt->hub->slot_id | 1054 slot_ctx->tt_info = cpu_to_le32(udev->tt->hub->slot_id |
@@ -1552,6 +1675,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
1552 kfree(xhci->usb2_ports); 1675 kfree(xhci->usb2_ports);
1553 kfree(xhci->usb3_ports); 1676 kfree(xhci->usb3_ports);
1554 kfree(xhci->port_array); 1677 kfree(xhci->port_array);
1678 kfree(xhci->rh_bw);
1555 1679
1556 xhci->page_size = 0; 1680 xhci->page_size = 0;
1557 xhci->page_shift = 0; 1681 xhci->page_shift = 0;
@@ -1822,6 +1946,12 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
1822 if (!xhci->port_array) 1946 if (!xhci->port_array)
1823 return -ENOMEM; 1947 return -ENOMEM;
1824 1948
1949 xhci->rh_bw = kzalloc(sizeof(*xhci->rh_bw)*num_ports, flags);
1950 if (!xhci->rh_bw)
1951 return -ENOMEM;
1952 for (i = 0; i < num_ports; i++)
1953 INIT_LIST_HEAD(&xhci->rh_bw[i].tts);
1954
1825 /* 1955 /*
1826 * For whatever reason, the first capability offset is from the 1956 * For whatever reason, the first capability offset is from the
1827 * capability register base, not from the HCCPARAMS register. 1957 * capability register base, not from the HCCPARAMS register.