Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

usb: xhci: factor out roothub bandwidth cleanup

Introduce xhci_rh_bw_cleanup() to release all bandwidth tracking
structures associated with xHCI roothub ports.

The new helper clears:
* TT bandwidth entries
* Per-interval endpoint lists

This refactors and consolidates the existing per-port cleanup logic
previously embedded in xhci_mem_cleanup(), reducing duplication and
making the teardown sequence easier to follow.

The helper will also be reused for upcoming S4 resume handling.

Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://patch.msgid.link/20260402131342.2628648-7-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Niklas Neronin and committed by
Greg Kroah-Hartman
0837c87f ab915ec9

+29 -21
+29 -21
drivers/usb/host/xhci-mem.c
··· 1895 1895 } 1896 1896 EXPORT_SYMBOL_GPL(xhci_remove_secondary_interrupter); 1897 1897 1898 + /* Cleanup roothub bandwidth data */ 1899 + static void xhci_rh_bw_cleanup(struct xhci_hcd *xhci) 1900 + { 1901 + struct xhci_root_port_bw_info *rh_bw; 1902 + struct xhci_tt_bw_info *tt_info, *tt_next; 1903 + struct list_head *eps, *ep, *ep_next; 1904 + 1905 + for (int i = 0; i < xhci->max_ports; i++) { 1906 + rh_bw = &xhci->rh_bw[i]; 1907 + 1908 + /* Clear and free all TT bandwidth entries */ 1909 + list_for_each_entry_safe(tt_info, tt_next, &rh_bw->tts, tt_list) { 1910 + list_del(&tt_info->tt_list); 1911 + kfree(tt_info); 1912 + } 1913 + 1914 + /* Clear per-interval endpoint lists */ 1915 + for (int j = 0; j < XHCI_MAX_INTERVAL; j++) { 1916 + eps = &rh_bw->bw_table.interval_bw[j].endpoints; 1917 + 1918 + list_for_each_safe(ep, ep_next, eps) 1919 + list_del_init(ep); 1920 + } 1921 + } 1922 + } 1923 + 1898 1924 void xhci_mem_cleanup(struct xhci_hcd *xhci) 1899 1925 { 1900 1926 struct device *dev = xhci_to_hcd(xhci)->self.sysdev; 1901 - int i, j; 1927 + int i; 1902 1928 1903 1929 cancel_delayed_work_sync(&xhci->cmd_timer); 1904 1930 ··· 1942 1916 xhci->cmd_ring = NULL; 1943 1917 xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Freed command ring"); 1944 1918 xhci_cleanup_command_queue(xhci); 1945 - 1946 - for (i = 0; i < xhci->max_ports && xhci->rh_bw; i++) { 1947 - struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table; 1948 - for (j = 0; j < XHCI_MAX_INTERVAL; j++) { 1949 - struct list_head *ep = &bwt->interval_bw[j].endpoints; 1950 - while (!list_empty(ep)) 1951 - list_del_init(ep->next); 1952 - } 1953 - } 1954 1919 1955 1920 for (i = xhci->max_slots; i > 0; i--) 1956 1921 xhci_free_virt_devices_depth_first(xhci, i); ··· 1976 1959 1977 1960 scratchpad_free(xhci); 1978 1961 1979 - if (!xhci->rh_bw) 1980 - goto no_bw; 1962 + if (xhci->rh_bw) 1963 + xhci_rh_bw_cleanup(xhci); 1981 1964 1982 - for (i = 0; i < xhci->max_ports; i++) { 1983 - struct xhci_tt_bw_info *tt, *n; 1984 - list_for_each_entry_safe(tt, n, &xhci->rh_bw[i].tts, tt_list) { 1985 - list_del(&tt->tt_list); 1986 - kfree(tt); 1987 - } 1988 - } 1989 - 1990 - no_bw: 1991 1965 xhci->cmd_ring_reserved_trbs = 0; 1992 1966 xhci->usb2_rhub.num_ports = 0; 1993 1967 xhci->usb3_rhub.num_ports = 0;