From 216fe64b617f4d145b02ea2df16b163610b5dd2b Mon Sep 17 00:00:00 2001 From: Howard Yen Date: Wed, 17 Mar 2021 22:31:54 +0800 Subject: [PATCH] ANDROID: usb: host: free the offload TR by vendor hook Free vendor specific transfer ring through vendor hook when the offload is enabled. Bug: 175850224 Test: boot pass and headset works Change-Id: I1ee112f41dae56bf6e0b8cc5575d8f4e893071f5 Signed-off-by: Howard Yen Signed-off-by: Puma Hsu --- drivers/usb/host/xhci-mem.c | 4 ++-- drivers/usb/host/xhci.c | 6 +++++- drivers/usb/host/xhci.h | 4 ++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 7d34f956ba6d..6eda84e51138 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -394,7 +394,7 @@ static struct xhci_ring *xhci_vendor_alloc_transfer_ring(struct xhci_hcd *xhci, return 0; } -static void xhci_vendor_free_transfer_ring(struct xhci_hcd *xhci, +void xhci_vendor_free_transfer_ring(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, unsigned int ep_index) { struct xhci_vendor_ops *ops = xhci_vendor_get_ops(xhci); @@ -403,7 +403,7 @@ static void xhci_vendor_free_transfer_ring(struct xhci_hcd *xhci, ops->free_transfer_ring(xhci, virt_dev, ep_index); } -static bool xhci_vendor_is_usb_offload_enabled(struct xhci_hcd *xhci, +bool xhci_vendor_is_usb_offload_enabled(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, unsigned int ep_index) { struct xhci_vendor_ops *ops = xhci_vendor_get_ops(xhci); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 5eea3220ff25..c64ffcb77607 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -2990,7 +2990,11 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) for (i = 0; i < 31; i++) { if (virt_dev->eps[i].new_ring) { xhci_debugfs_remove_endpoint(xhci, virt_dev, i); - xhci_ring_free(xhci, virt_dev->eps[i].new_ring); + if (xhci_vendor_is_usb_offload_enabled(xhci, virt_dev, i)) + xhci_vendor_free_transfer_ring(xhci, virt_dev, i); + else + xhci_ring_free(xhci, virt_dev->eps[i].new_ring); + virt_dev->eps[i].new_ring = NULL; } } diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 58f259e9eb9e..64a658aae707 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -2257,6 +2257,10 @@ struct xhci_vendor_ops *xhci_vendor_get_ops(struct xhci_hcd *xhci); int xhci_vendor_sync_dev_ctx(struct xhci_hcd *xhci, unsigned int slot_id); bool xhci_vendor_usb_offload_skip_urb(struct xhci_hcd *xhci, struct urb *urb); +void xhci_vendor_free_transfer_ring(struct xhci_hcd *xhci, + struct xhci_virt_device *virt_dev, unsigned int ep_index); +bool xhci_vendor_is_usb_offload_enabled(struct xhci_hcd *xhci, + struct xhci_virt_device *virt_dev, unsigned int ep_index); /* * TODO: As per spec Isochronous IDT transmissions are supported. We bypass