Skip to contentSkip to conversation

usb: ci_udc: call udc_disconnect() from ci_pullup()

PATCH New Stephen Warren 2 participants 5 messages Jun 10, 2014 – Jun 11, 2014 USB

lore
Share & tools
lore
#0 lore raw

PATCH 1/4 usb: ci_udc: call udc_disconnect() from ci_pullup()

From: Stephen Warren <[email protected]>

ci_pullup()'s !is_on path contains a cut/paste copy of udc_disconnect(). Remove the duplication by simply calling udc_disconnect() instead.

---
 drivers/usb/gadget/ci_udc.c | 28 ++++++++++++----------------
 1 file changed, 12 insertions(+), 16 deletions(-)
drivers/usb/gadget/ci_udc.c +12 -16
index 6dc20c6c954c..5f308563e246 100644
@@ -697,6 +697,17 @@ int usb_gadget_handle_interrupts(void)
 	return value;
 }
 
+void udc_disconnect(void)
+{
+	struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor;
+	/* disable pullup */
+	stop_activity();
+	writel(USBCMD_FS2, &udc->usbcmd);
+	udelay(800);
+	if (controller.driver)
+		controller.driver->disconnect(&controller.gadget);
+}
+
 static int ci_pullup(struct usb_gadget *gadget, int is_on)
 {
 	struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor;
@@ -715,27 +726,12 @@ static int ci_pullup(struct usb_gadget *gadget, int is_on)
 		/* Turn on the USB connection by enabling the pullup resistor */
 		writel(USBCMD_ITC(MICRO_8FRAME) | USBCMD_RUN, &udc->usbcmd);
 	} else {
-		stop_activity();
-		writel(USBCMD_FS2, &udc->usbcmd);
-		udelay(800);
-		if (controller.driver)
-			controller.driver->disconnect(gadget);
+		udc_disconnect();
 	}
 
 	return 0;
 }
 
-void udc_disconnect(void)
-{
-	struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor;
-	/* disable pullup */
-	stop_activity();
-	writel(USBCMD_FS2, &udc->usbcmd);
-	udelay(800);
-	if (controller.driver)
-		controller.driver->disconnect(&controller.gadget);
-}
-
 static int ci_udc_probe(void)
 {
 	struct ept_queue_head *head;
Signature · 1 line
1.8.1.5
#1 lore raw

PATCH 2/4 usb: ci_udc: fix freeing of ep0 req

From: Stephen Warren <[email protected]>

ci_ep_alloc_request() avoids allocating multiple request objects for ep0 by keeping a record of the first req allocated for ep0, and always returning that instead of allocating a new req. However, if this req is ever freed, the record of the previous allocation is not cleared, so ci_ep_alloc_request() will keep returning this stale pointer. Fix ci_ep_free_request() to clear the record of the previous allocation.

---
 drivers/usb/gadget/ci_udc.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/usb/gadget/ci_udc.c +7 -2
index 5f308563e246..7a6563f83fd1 100644
@@ -221,9 +221,14 @@ ci_ep_alloc_request(struct usb_ep *ep, unsigned int gfp_flags)
 
 static void ci_ep_free_request(struct usb_ep *ep, struct usb_request *req)
 {
-	struct ci_req *ci_req;
+	struct ci_ep *ci_ep = container_of(ep, struct ci_ep, ep);
+	struct ci_req *ci_req = container_of(req, struct ci_req, req);
+	int num;
+
+	num = ci_ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+	if (num == 0)
+		controller.ep0_req = 0;
 
-	ci_req = container_of(req, struct ci_req, req);
 	if (ci_req->b_buf)
 		free(ci_req->b_buf);
 	free(ci_req);
Signature · 1 line
1.8.1.5
#2 lore raw

PATCH 3/4 usb: ci_udc: fix probe error cleanup

In reply to Stephen Warren

From: Stephen Warren <[email protected]>

If allocation of the ep0 req fails, clean up all the allocations that were made in ci_udc_probe().

---
 drivers/usb/gadget/ci_udc.c | 1 +
 1 file changed, 1 insertion(+)
drivers/usb/gadget/ci_udc.c +1 -0
index 7a6563f83fd1..1428af85cffd 100644
@@ -826,6 +826,7 @@ static int ci_udc_probe(void)
 
 	ci_ep_alloc_request(&controller.ep[0].ep, 0);
 	if (!controller.ep0_req) {
+		free(controller.items_mem);
 		free(controller.epts);
 		return -ENOMEM;
 	}
Signature · 1 line
1.8.1.5
#3 lore raw

PATCH 4/4 usb: ci_udc: clean up all allocations in unregister

In reply to Stephen Warren

From: Stephen Warren <[email protected]>

usb_gadget_unregister_driver() is called to tear down the USB device mode stack. Fix the driver to stop the USB HW (which causes any attached host to notice the disappearance of the device), and free all allocations (which obviously prevents memory leaks).

---
 drivers/usb/gadget/ci_udc.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/usb/gadget/ci_udc.c +6 -0
index 1428af85cffd..435a2720e96f 100644
@@ -875,5 +875,11 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 
 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
+	udc_disconnect();
+
+	ci_ep_free_request(&controller.ep[0].ep, &controller.ep0_req->req);
+	free(controller.items_mem);
+	free(controller.epts);
+
 	return 0;
 }
Signature · 1 line
1.8.1.5