git: 8685d7b5cb75 - main - xhci(4): Make sure allocated bandwidth is freed in hardware by unconfiguring endpoint.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 13 Jan 2023 10:19:31 UTC
The branch main has been updated by hselasky: URL: https://cgit.FreeBSD.org/src/commit/?id=8685d7b5cb759b4f688dea93dbe1c38f9e833e4e commit 8685d7b5cb759b4f688dea93dbe1c38f9e833e4e Author: Cheng, Huiming <Huiming.Cheng@dellteam.com> AuthorDate: 2022-12-15 22:30:11 +0000 Commit: Hans Petter Selasky <hselasky@FreeBSD.org> CommitDate: 2023-01-13 10:18:19 +0000 xhci(4): Make sure allocated bandwidth is freed in hardware by unconfiguring endpoint. MFC after: 1 week Sponsored by: NVIDIA Networking --- sys/dev/usb/controller/xhci.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/sys/dev/usb/controller/xhci.c b/sys/dev/usb/controller/xhci.c index ba8360e54152..161f443631b2 100644 --- a/sys/dev/usb/controller/xhci.c +++ b/sys/dev/usb/controller/xhci.c @@ -4030,7 +4030,47 @@ xhci_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc, static void xhci_ep_uninit(struct usb_device *udev, struct usb_endpoint *ep) { + struct xhci_softc *sc = XHCI_BUS2SC(udev->bus); + const struct usb_endpoint_descriptor *edesc = ep->edesc; + struct usb_page_search buf_inp; + struct usb_page_cache *pcinp; + uint32_t mask; + uint8_t index; + uint8_t epno; + usb_error_t err; + + if (udev->parent_hub == NULL) { + /* root HUB has special endpoint handling */ + return; + } + + if ((edesc->bEndpointAddress & UE_ADDR) == 0) { + /* control endpoint is never unconfigured */ + return; + } + XHCI_CMD_LOCK(sc); + index = udev->controller_slot_id; + epno = XHCI_EPNO2EPID(edesc->bEndpointAddress); + mask = 1U << epno; + + if (sc->sc_hw.devs[index].ep_configured & mask) { + USB_BUS_LOCK(udev->bus); + xhci_configure_mask(udev, mask, 1); + USB_BUS_UNLOCK(udev->bus); + + pcinp = &sc->sc_hw.devs[index].input_pc; + usbd_get_page(pcinp, 0, &buf_inp); + err = xhci_cmd_configure_ep(sc, buf_inp.physaddr, 0, index); + if (err) { + DPRINTF("Unconfiguring endpoint failed: %d\n", err); + } else { + USB_BUS_LOCK(udev->bus); + sc->sc_hw.devs[index].ep_configured &= ~mask; + USB_BUS_UNLOCK(udev->bus); + } + } + XHCI_CMD_UNLOCK(sc); } static void