[ 63/94] USB: fix resource leak in xhci power loss path

From: Greg KH
Date: Sat May 26 2012 - 21:41:47 EST


3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oliver Neukum <oneukum@xxxxxxx>

commit f8a9e72d125f4e00ec529ba67b674321a1f3bf31 upstream.

Some more data structures must be freed and counters
reset if an XHCI controller has lost power. The failure
to do so renders some chips inoperative after a certain number
of S4 cycles.

This patch should be backported to kernels as old as 3.2,
that contain the commits c29eea621900f18287d50519f72cb9113746d75a
"xhci: Implement HS/FS/LS bandwidth checking." and
commit 839c817ce67178ca3c7c7ad534c571bba1e69ebe
"xhci: Implement HS/FS/LS bandwidth checking."

Signed-off-by: Oliver Neukum <oneukum@xxxxxxx>
Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
drivers/usb/host/xhci-mem.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)

--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1685,6 +1685,14 @@ void xhci_mem_cleanup(struct xhci_hcd *x
{
struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
struct dev_info *dev_info, *next;
+ struct list_head *tt_list_head;
+ struct list_head *tt;
+ struct list_head *endpoints;
+ struct list_head *ep, *q;
+ struct xhci_tt_bw_info *tt_info;
+ struct xhci_interval_bw_table *bwt;
+ struct xhci_virt_ep *virt_ep;
+
unsigned long flags;
int size;
int i;
@@ -1744,8 +1752,26 @@ void xhci_mem_cleanup(struct xhci_hcd *x
}
spin_unlock_irqrestore(&xhci->lock, flags);

+ bwt = &xhci->rh_bw->bw_table;
+ for (i = 0; i < XHCI_MAX_INTERVAL; i++) {
+ endpoints = &bwt->interval_bw[i].endpoints;
+ list_for_each_safe(ep, q, endpoints) {
+ virt_ep = list_entry(ep, struct xhci_virt_ep, bw_endpoint_list);
+ list_del(&virt_ep->bw_endpoint_list);
+ kfree(virt_ep);
+ }
+ }
+
+ tt_list_head = &xhci->rh_bw->tts;
+ list_for_each_safe(tt, q, tt_list_head) {
+ tt_info = list_entry(tt, struct xhci_tt_bw_info, tt_list);
+ list_del(tt);
+ kfree(tt_info);
+ }
+
xhci->num_usb2_ports = 0;
xhci->num_usb3_ports = 0;
+ xhci->num_active_eps = 0;
kfree(xhci->usb2_ports);
kfree(xhci->usb3_ports);
kfree(xhci->port_array);


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/