From 5d938924f9bc39b9b93039091dc63443c25f6bb3 Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Tue, 9 Jun 2020 22:54:48 -0700 Subject: [PATCH 1/2] usb: xhci: Don't check for USB_STATE_NOTATTACHED in xhci_stop_endpoint This API can be called by the QMI sound driver precisely when a device is disconnected in order to issue a stop endpoint command to properly halt the transfer ring. With this check the function silently bails, so the XHCI controller hardware may continue to be accessing the buffers on the transfer ring; meanwhile the QMI sound driver proceeds to unmap the buffers from DMA resulting in an SMMU fault. Remove the check to allow the endpoint to be properly stopped. Change-Id: I80315c31d9b1685ac4375c1da051a8e22cab07ca Signed-off-by: Jack Pham --- drivers/usb/host/xhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 1176b001e3dd..8b9a39eddf40 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -5390,7 +5390,7 @@ int xhci_stop_endpoint(struct usb_device *udev, struct usb_host_endpoint *ep) unsigned long flags; int ret = 0; - if (udev->state == USB_STATE_NOTATTACHED || !HCD_RH_RUNNING(hcd)) + if (!HCD_RH_RUNNING(hcd)) return 0; cmd = xhci_alloc_command(xhci, true, GFP_NOIO); From da53231c3f813072af79a0071c7b2394305ac696 Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Wed, 10 Jun 2020 11:52:26 -0700 Subject: [PATCH 2/2] usb: xhci: Don't check for USB_STATE_NOTATTACHED in sec_event_ring_cleanup Similar to xhci_stop_endpoint(), this API is called when a device is removed. The check for udev->state == USB_STATE_NOTATTACHED was added by mistake and should be removed. Change-Id: Ie0df67c3139bd585f098215d093169c961710349 Signed-off-by: Jack Pham --- drivers/usb/host/xhci-mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 3580afd72baa..522b209d86be 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1947,7 +1947,7 @@ int xhci_sec_event_ring_cleanup(struct usb_device *udev, unsigned int intr_num) { struct usb_hcd *hcd = bus_to_hcd(udev->bus); - if (udev->state == USB_STATE_NOTATTACHED || !HCD_RH_RUNNING(hcd)) + if (!HCD_RH_RUNNING(hcd)) return 0; return sec_event_ring_cleanup(hcd_to_xhci(hcd), intr_num);