From 1ffba9058737af2ddeebc813faa8ea9b16bc892a Mon Sep 17 00:00:00 2001 From: Minas Harutyunyan Date: Tue, 12 Jun 2018 12:37:29 +0400 Subject: usb: dwc2: gadget: Fix issue in dwc2_gadget_start_isoc() In case of requests queue is empty reset EP target_frame to initial value. This allow restarting ISOC traffic in case when function driver queued requests with interruptions. Tested-by: Zeng Tao Signed-off-by: Minas Harutyunyan Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/usb/dwc2/gadget.c') diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index f0d9ccf1d665..bb499fea6100 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -884,6 +884,7 @@ static void dwc2_gadget_start_isoc_ddma(struct dwc2_hsotg_ep *hs_ep) struct dwc2_dma_desc *desc; if (list_empty(&hs_ep->queue)) { + hs_ep->target_frame = TARGET_FRAME_INITIAL; dev_dbg(hsotg->dev, "%s: No requests in queue\n", __func__); return; } -- cgit v1.2.3 From 6e967d7e2c4822eba4847ec09037119a0418aaef Mon Sep 17 00:00:00 2001 From: Zeng Tao Date: Tue, 12 Jun 2018 22:49:06 +0800 Subject: usb: dwc2: gadget: fix packet drop issue in dwc2_gadget_handle_nak In ISOC transfer, when the NAK interrupt happens, we shouldn't complete a usb request, the current flow will complete one usb request with no hardware transfer, this will lead to a packet drop on the usb bus. Acked-by: Minas Harutyunyan Signed-off-by: Zeng Tao Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/usb/dwc2/gadget.c') diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index bb499fea6100..bb5eb3c8132d 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2818,9 +2818,6 @@ static void dwc2_gadget_handle_nak(struct dwc2_hsotg_ep *hs_ep) tmp = dwc2_hsotg_read_frameno(hsotg); if (using_desc_dma(hsotg)) { - dwc2_hsotg_complete_request(hsotg, hs_ep, - get_ep_head(hs_ep), 0); - hs_ep->target_frame = tmp; dwc2_gadget_incr_frame_num(hs_ep); dwc2_gadget_start_isoc_ddma(hs_ep); -- cgit v1.2.3 From 21cbbc6bb7b4ba6aee303a3b4aef1578253724d8 Mon Sep 17 00:00:00 2001 From: Minas Harutyunyan Date: Tue, 12 Jun 2018 12:27:36 +0400 Subject: usb: dwc2: gadget: fix packet drop issue for ISOC OUT transfers In ISOC OUT transfer, when the OUT token received while EP disabled, we shouldn't complete a usb request. The current flow completed one usb request, this will lead to a packet drop to function driver. Signed-off-by: Minas Harutyunyan Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/usb/dwc2/gadget.c') diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index bb5eb3c8132d..fa3b6f361074 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2756,8 +2756,6 @@ static void dwc2_gadget_handle_out_token_ep_disabled(struct dwc2_hsotg_ep *ep) */ tmp = dwc2_hsotg_read_frameno(hsotg); - dwc2_hsotg_complete_request(hsotg, ep, get_ep_head(ep), 0); - if (using_desc_dma(hsotg)) { if (ep->target_frame == TARGET_FRAME_INITIAL) { /* Start first ISO Out */ -- cgit v1.2.3 From 9bb073a053f0464ea74a4d4c331fdb7da58568d6 Mon Sep 17 00:00:00 2001 From: Grigor Tovmasyan Date: Thu, 24 May 2018 18:22:30 +0400 Subject: usb: gadget: dwc2: fix memory leak in gadget_init() Freed allocated request for ep0 to prevent memory leak in case when dwc2_driver_probe() failed. Cc: Stefan Wahren Cc: Marek Szyprowski Tested-by: Stefan Wahren Tested-by: Marek Szyprowski Acked-by: Minas Harutyunyan Signed-off-by: Grigor Tovmasyan Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/usb/dwc2/gadget.c') diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index fa3b6f361074..76e4f2e7d947 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -4735,9 +4735,11 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg) } ret = usb_add_gadget_udc(dev, &hsotg->gadget); - if (ret) + if (ret) { + dwc2_hsotg_ep_free_request(&hsotg->eps_out[0]->ep, + hsotg->ctrl_req); return ret; - + } dwc2_hsotg_dump(hsotg); return 0; @@ -4751,6 +4753,7 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg) int dwc2_hsotg_remove(struct dwc2_hsotg *hsotg) { usb_del_gadget_udc(&hsotg->gadget); + dwc2_hsotg_ep_free_request(&hsotg->eps_out[0]->ep, hsotg->ctrl_req); return 0; } -- cgit v1.2.3 From 1d8e5c00275825fc42aaa5597dab1d0b5b26bb64 Mon Sep 17 00:00:00 2001 From: Minas Harutyunyan Date: Wed, 23 May 2018 16:24:44 +0400 Subject: dwc2: gadget: Fix ISOC IN DDMA PID bitfield value calculation PID bitfield in descriptor should be set based on particular request length, not based on EP's mc value. PID value can't be set to 0 even request length is 0. Signed-off-by: Minas Harutyunyan Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/usb/dwc2/gadget.c') diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 76e4f2e7d947..a0f82cca2d9a 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -812,6 +812,7 @@ static int dwc2_gadget_fill_isoc_desc(struct dwc2_hsotg_ep *hs_ep, u32 index; u32 maxsize = 0; u32 mask = 0; + u8 pid = 0; maxsize = dwc2_gadget_get_desc_params(hs_ep, &mask); @@ -840,7 +841,11 @@ static int dwc2_gadget_fill_isoc_desc(struct dwc2_hsotg_ep *hs_ep, ((len << DEV_DMA_NBYTES_SHIFT) & mask)); if (hs_ep->dir_in) { - desc->status |= ((hs_ep->mc << DEV_DMA_ISOC_PID_SHIFT) & + if (len) + pid = DIV_ROUND_UP(len, hs_ep->ep.maxpacket); + else + pid = 1; + desc->status |= ((pid << DEV_DMA_ISOC_PID_SHIFT) & DEV_DMA_ISOC_PID_MASK) | ((len % hs_ep->ep.maxpacket) ? DEV_DMA_SHORT : 0) | -- cgit v1.2.3