This is a note to let you know that I've just added the patch titled

    usb: chipidea: cleanup dma_pool if udc_start() fails

to my usb git tree which can be found at
    git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git
in the usb-next branch.

The patch will show up in the next release of the linux-next tree
(usually sometime within the next 24 hours during the week.)

The patch will also be merged in the next major kernel release
during the merge window.

If you have any questions about this process, please let me know.


>From ad6b1b97fe8504957d017cd6e4168cac8903d3f3 Mon Sep 17 00:00:00 2001
From: Marc Kleine-Budde <[email protected]>
Date: Wed, 12 Sep 2012 14:58:03 +0300
Subject: usb: chipidea: cleanup dma_pool if udc_start() fails

If udc_start() fails the qh_pool dma-pool cannot be closed because
it's still in use. This patch factors out the dma_pool_free() loop
into destroy_eps() and calls it in the error path of udc_start(),
too.

Cc: stable <[email protected]>
Reviewed-by: Richard Zhao <[email protected]>
Signed-off-by: Marc Kleine-Budde <[email protected]>
Signed-off-by: Alexander Shishkin <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
 drivers/usb/chipidea/udc.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 3a755e5..2d8b609 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1503,6 +1503,17 @@ static int init_eps(struct ci13xxx *ci)
        return retval;
 }
 
+static void destroy_eps(struct ci13xxx *ci)
+{
+       int i;
+
+       for (i = 0; i < ci->hw_ep_max; i++) {
+               struct ci13xxx_ep *mEp = &ci->ci13xxx_ep[i];
+
+               dma_pool_free(ci->qh_pool, mEp->qh.ptr, mEp->qh.dma);
+       }
+}
+
 /**
  * ci13xxx_start: register a gadget driver
  * @gadget: our gadget
@@ -1710,7 +1721,7 @@ static int udc_start(struct ci13xxx *ci)
        if (ci->platdata->flags & CI13XXX_REQUIRE_TRANSCEIVER) {
                if (ci->transceiver == NULL) {
                        retval = -ENODEV;
-                       goto free_pools;
+                       goto destroy_eps;
                }
        }
 
@@ -1761,6 +1772,8 @@ unreg_device:
 put_transceiver:
        if (!IS_ERR_OR_NULL(ci->transceiver) && ci->global_phy)
                usb_put_phy(ci->transceiver);
+destroy_eps:
+       destroy_eps(ci);
 free_pools:
        dma_pool_destroy(ci->td_pool);
 free_qh_pool:
@@ -1775,18 +1788,12 @@ free_qh_pool:
  */
 static void udc_stop(struct ci13xxx *ci)
 {
-       int i;
-
        if (ci == NULL)
                return;
 
        usb_del_gadget_udc(&ci->gadget);
 
-       for (i = 0; i < ci->hw_ep_max; i++) {
-               struct ci13xxx_ep *mEp = &ci->ci13xxx_ep[i];
-
-               dma_pool_free(ci->qh_pool, mEp->qh.ptr, mEp->qh.dma);
-       }
+       destroy_eps(ci);
 
        dma_pool_destroy(ci->td_pool);
        dma_pool_destroy(ci->qh_pool);
-- 
1.7.12.176.g3fc0e4c


--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to