From 37bea42fec575203c1b49d64322f717c29e82b90 Mon Sep 17 00:00:00 2001 From: John Keeping Date: Mon, 5 Aug 2019 17:01:21 +0100 Subject: usb: dwc2: gadget: Fix kill_all_requests race When a gadget is disabled, kill_all_requests() can be called simultaneously from both a user process via dwc2_hsotg_pullup() and from the interrupt handler if the hardware detects disconnection. Since we drop the lock in dwc2_hsotg_complete_request() in order to call the completion handler, this means that the list is modified concurrently and leads to an infinite loop in kill_all_requests(). Replace the foreach loop with a while-not-empty loop in order to remove the danger of this concurrent modification. Note: I observed this with threadirqs, I'm not sure if it can be triggered without threaded interrupts. Signed-off-by: John Keeping Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/usb/dwc2') diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index bff48a8a1984..6be10e496e10 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3224,14 +3224,15 @@ static void kill_all_requests(struct dwc2_hsotg *hsotg, struct dwc2_hsotg_ep *ep, int result) { - struct dwc2_hsotg_req *req, *treq; unsigned int size; ep->req = NULL; - list_for_each_entry_safe(req, treq, &ep->queue, queue) - dwc2_hsotg_complete_request(hsotg, ep, req, - result); + while (!list_empty(&ep->queue)) { + struct dwc2_hsotg_req *req = get_ep_head(ep); + + dwc2_hsotg_complete_request(hsotg, ep, req, result); + } if (!hsotg->dedicated_fifos) return; -- cgit v1.2.3-59-g8ed1b From 18425e5eb029eadbf82407d4fc224ced52fde986 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 23 Jul 2019 22:16:39 +0300 Subject: usb: dwc2: Switch to use device_property_count_u32() Use use device_property_count_u32() directly, that makes code neater. Acked-by: Minas Harutyunyan Signed-off-by: Andy Shevchenko Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/params.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/usb/dwc2') diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c index 55f841a54015..31e090ac9f1e 100644 --- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c @@ -404,10 +404,7 @@ static void dwc2_get_device_properties(struct dwc2_hsotg *hsotg) device_property_read_u32(hsotg->dev, "g-np-tx-fifo-size", &p->g_np_tx_fifo_size); - num = device_property_read_u32_array(hsotg->dev, - "g-tx-fifo-size", - NULL, 0); - + num = device_property_count_u32(hsotg->dev, "g-tx-fifo-size"); if (num > 0) { num = min(num, 15); memset(p->g_tx_fifo_size, 0, -- cgit v1.2.3-59-g8ed1b