From babd183915e91a64e976b9e8ab682bb56624df76 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Fri, 31 May 2019 13:04:12 -0700 Subject: usb: dwc2: host: Fix wMaxPacketSize handling (fix webcam regression) In commit abb621844f6a ("usb: ch9: make usb_endpoint_maxp() return only packet size") the API to usb_endpoint_maxp() changed. It used to just return wMaxPacketSize but after that commit it returned wMaxPacketSize with the high bits (the multiplier) masked off. If you wanted to get the multiplier it was now up to your code to call the new usb_endpoint_maxp_mult() which was introduced in commit 541b6fe63023 ("usb: add helper to extract bits 12:11 of wMaxPacketSize"). Prior to the API change most host drivers were updated, but no update was made to dwc2. Presumably it was assumed that dwc2 was too simplistic to use the multiplier and thus just didn't support a certain class of USB devices. However, it turns out that dwc2 did use the multiplier and many devices using it were working quite nicely. That means that many USB devices have been broken since the API change. One such device is a Logitech HD Pro Webcam C920. Specifically, though dwc2 didn't directly call usb_endpoint_maxp(), it did call usb_maxpacket() which in turn called usb_endpoint_maxp(). Let's update dwc2 to work properly with the new API. Fixes: abb621844f6a ("usb: ch9: make usb_endpoint_maxp() return only packet size") Cc: stable@vger.kernel.org Acked-by: Minas Harutyunyan Reviewed-by: Matthias Kaehlcke Signed-off-by: Douglas Anderson Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd.c | 29 +++++++++++++++++------------ drivers/usb/dwc2/hcd.h | 20 +++++++++++--------- drivers/usb/dwc2/hcd_intr.c | 5 +++-- drivers/usb/dwc2/hcd_queue.c | 10 ++++++---- 4 files changed, 37 insertions(+), 27 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index b50ec3714fd8..5c51bf5506d1 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -2608,7 +2608,7 @@ static int dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) chan->dev_addr = dwc2_hcd_get_dev_addr(&urb->pipe_info); chan->ep_num = dwc2_hcd_get_ep_num(&urb->pipe_info); chan->speed = qh->dev_speed; - chan->max_packet = dwc2_max_packet(qh->maxp); + chan->max_packet = qh->maxp; chan->xfer_started = 0; chan->halt_status = DWC2_HC_XFER_NO_HALT_STATUS; @@ -2686,7 +2686,7 @@ static int dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) * This value may be modified when the transfer is started * to reflect the actual transfer length */ - chan->multi_count = dwc2_hb_mult(qh->maxp); + chan->multi_count = qh->maxp_mult; if (hsotg->params.dma_desc_enable) { chan->desc_list_addr = qh->desc_list_dma; @@ -3806,19 +3806,21 @@ static struct dwc2_hcd_urb *dwc2_hcd_urb_alloc(struct dwc2_hsotg *hsotg, static void dwc2_hcd_urb_set_pipeinfo(struct dwc2_hsotg *hsotg, struct dwc2_hcd_urb *urb, u8 dev_addr, - u8 ep_num, u8 ep_type, u8 ep_dir, u16 mps) + u8 ep_num, u8 ep_type, u8 ep_dir, + u16 maxp, u16 maxp_mult) { if (dbg_perio() || ep_type == USB_ENDPOINT_XFER_BULK || ep_type == USB_ENDPOINT_XFER_CONTROL) dev_vdbg(hsotg->dev, - "addr=%d, ep_num=%d, ep_dir=%1x, ep_type=%1x, mps=%d\n", - dev_addr, ep_num, ep_dir, ep_type, mps); + "addr=%d, ep_num=%d, ep_dir=%1x, ep_type=%1x, maxp=%d (%d mult)\n", + dev_addr, ep_num, ep_dir, ep_type, maxp, maxp_mult); urb->pipe_info.dev_addr = dev_addr; urb->pipe_info.ep_num = ep_num; urb->pipe_info.pipe_type = ep_type; urb->pipe_info.pipe_dir = ep_dir; - urb->pipe_info.mps = mps; + urb->pipe_info.maxp = maxp; + urb->pipe_info.maxp_mult = maxp_mult; } /* @@ -3909,8 +3911,9 @@ void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg) dwc2_hcd_is_pipe_in(&urb->pipe_info) ? "IN" : "OUT"); dev_dbg(hsotg->dev, - " Max packet size: %d\n", - dwc2_hcd_get_mps(&urb->pipe_info)); + " Max packet size: %d (%d mult)\n", + dwc2_hcd_get_maxp(&urb->pipe_info), + dwc2_hcd_get_maxp_mult(&urb->pipe_info)); dev_dbg(hsotg->dev, " transfer_buffer: %p\n", urb->buf); @@ -4510,8 +4513,10 @@ static void dwc2_dump_urb_info(struct usb_hcd *hcd, struct urb *urb, } dev_vdbg(hsotg->dev, " Speed: %s\n", speed); - dev_vdbg(hsotg->dev, " Max packet size: %d\n", - usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe))); + dev_vdbg(hsotg->dev, " Max packet size: %d (%d mult)\n", + usb_endpoint_maxp(&urb->ep->desc), + usb_endpoint_maxp_mult(&urb->ep->desc)); + dev_vdbg(hsotg->dev, " Data buffer length: %d\n", urb->transfer_buffer_length); dev_vdbg(hsotg->dev, " Transfer buffer: %p, Transfer DMA: %08lx\n", @@ -4594,8 +4599,8 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, dwc2_hcd_urb_set_pipeinfo(hsotg, dwc2_urb, usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe), ep_type, usb_pipein(urb->pipe), - usb_maxpacket(urb->dev, urb->pipe, - !(usb_pipein(urb->pipe)))); + usb_endpoint_maxp(&ep->desc), + usb_endpoint_maxp_mult(&ep->desc)); buf = urb->transfer_buffer; diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h index c089ffa1f0a8..ce6445a06588 100644 --- a/drivers/usb/dwc2/hcd.h +++ b/drivers/usb/dwc2/hcd.h @@ -171,7 +171,8 @@ struct dwc2_hcd_pipe_info { u8 ep_num; u8 pipe_type; u8 pipe_dir; - u16 mps; + u16 maxp; + u16 maxp_mult; }; struct dwc2_hcd_iso_packet_desc { @@ -264,6 +265,7 @@ struct dwc2_hs_transfer_time { * - USB_ENDPOINT_XFER_ISOC * @ep_is_in: Endpoint direction * @maxp: Value from wMaxPacketSize field of Endpoint Descriptor + * @maxp_mult: Multiplier for maxp * @dev_speed: Device speed. One of the following values: * - USB_SPEED_LOW * - USB_SPEED_FULL @@ -340,6 +342,7 @@ struct dwc2_qh { u8 ep_type; u8 ep_is_in; u16 maxp; + u16 maxp_mult; u8 dev_speed; u8 data_toggle; u8 ping_state; @@ -503,9 +506,14 @@ static inline u8 dwc2_hcd_get_pipe_type(struct dwc2_hcd_pipe_info *pipe) return pipe->pipe_type; } -static inline u16 dwc2_hcd_get_mps(struct dwc2_hcd_pipe_info *pipe) +static inline u16 dwc2_hcd_get_maxp(struct dwc2_hcd_pipe_info *pipe) +{ + return pipe->maxp; +} + +static inline u16 dwc2_hcd_get_maxp_mult(struct dwc2_hcd_pipe_info *pipe) { - return pipe->mps; + return pipe->maxp_mult; } static inline u8 dwc2_hcd_get_dev_addr(struct dwc2_hcd_pipe_info *pipe) @@ -620,12 +628,6 @@ static inline bool dbg_urb(struct urb *urb) static inline bool dbg_perio(void) { return false; } #endif -/* High bandwidth multiplier as encoded in highspeed endpoint descriptors */ -#define dwc2_hb_mult(wmaxpacketsize) (1 + (((wmaxpacketsize) >> 11) & 0x03)) - -/* Packet size for any kind of endpoint descriptor */ -#define dwc2_max_packet(wmaxpacketsize) ((wmaxpacketsize) & 0x07ff) - /* * Returns true if frame1 index is greater than frame2 index. The comparison * is done modulo FRLISTEN_64_SIZE. This accounts for the rollover of the diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c index 88b5dcf3aefc..a052d39b4375 100644 --- a/drivers/usb/dwc2/hcd_intr.c +++ b/drivers/usb/dwc2/hcd_intr.c @@ -1617,8 +1617,9 @@ static void dwc2_hc_ahberr_intr(struct dwc2_hsotg *hsotg, dev_err(hsotg->dev, " Speed: %s\n", speed); - dev_err(hsotg->dev, " Max packet size: %d\n", - dwc2_hcd_get_mps(&urb->pipe_info)); + dev_err(hsotg->dev, " Max packet size: %d (mult %d)\n", + dwc2_hcd_get_maxp(&urb->pipe_info), + dwc2_hcd_get_maxp_mult(&urb->pipe_info)); dev_err(hsotg->dev, " Data buffer length: %d\n", urb->length); dev_err(hsotg->dev, " Transfer buffer: %p, Transfer DMA: %08lx\n", urb->buf, (unsigned long)urb->dma); diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c index ea3aa640c15c..68bbac64b753 100644 --- a/drivers/usb/dwc2/hcd_queue.c +++ b/drivers/usb/dwc2/hcd_queue.c @@ -708,7 +708,7 @@ static void dwc2_hs_pmap_unschedule(struct dwc2_hsotg *hsotg, static int dwc2_uframe_schedule_split(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { - int bytecount = dwc2_hb_mult(qh->maxp) * dwc2_max_packet(qh->maxp); + int bytecount = qh->maxp_mult * qh->maxp; int ls_search_slice; int err = 0; int host_interval_in_sched; @@ -1332,7 +1332,7 @@ static int dwc2_check_max_xfer_size(struct dwc2_hsotg *hsotg, u32 max_channel_xfer_size; int status = 0; - max_xfer_size = dwc2_max_packet(qh->maxp) * dwc2_hb_mult(qh->maxp); + max_xfer_size = qh->maxp * qh->maxp_mult; max_channel_xfer_size = hsotg->params.max_transfer_size; if (max_xfer_size > max_channel_xfer_size) { @@ -1517,8 +1517,9 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, u32 prtspd = (hprt & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT; bool do_split = (prtspd == HPRT0_SPD_HIGH_SPEED && dev_speed != USB_SPEED_HIGH); - int maxp = dwc2_hcd_get_mps(&urb->pipe_info); - int bytecount = dwc2_hb_mult(maxp) * dwc2_max_packet(maxp); + int maxp = dwc2_hcd_get_maxp(&urb->pipe_info); + int maxp_mult = dwc2_hcd_get_maxp_mult(&urb->pipe_info); + int bytecount = maxp_mult * maxp; char *speed, *type; /* Initialize QH */ @@ -1531,6 +1532,7 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, qh->data_toggle = DWC2_HC_PID_DATA0; qh->maxp = maxp; + qh->maxp_mult = maxp_mult; INIT_LIST_HEAD(&qh->qtd_list); INIT_LIST_HEAD(&qh->qh_list_entry); -- cgit v1.2.3-59-g8ed1b From 4a4863bf2e7932e584a3a462d3c6daf891142ddc Mon Sep 17 00:00:00 2001 From: Martin Schiller Date: Mon, 18 Feb 2019 07:37:30 +0100 Subject: usb: dwc2: Fix DMA cache alignment issues Insert a padding between data and the stored_xfer_buffer pointer to ensure they are not on the same cache line. Otherwise, the stored_xfer_buffer gets corrupted for IN URBs on non-cache-coherent systems. (In my case: Lantiq xRX200 MIPS) Fixes: 3bc04e28a030 ("usb: dwc2: host: Get aligned DMA in a more supported way") Fixes: 56406e017a88 ("usb: dwc2: Fix DMA alignment to start at allocated boundary") Cc: Tested-by: Douglas Anderson Reviewed-by: Douglas Anderson Acked-by: Minas Harutyunyan Signed-off-by: Martin Schiller Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 5c51bf5506d1..2192a2873c7c 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -2480,8 +2480,10 @@ static void dwc2_free_dma_aligned_buffer(struct urb *urb) return; /* Restore urb->transfer_buffer from the end of the allocated area */ - memcpy(&stored_xfer_buffer, urb->transfer_buffer + - urb->transfer_buffer_length, sizeof(urb->transfer_buffer)); + memcpy(&stored_xfer_buffer, + PTR_ALIGN(urb->transfer_buffer + urb->transfer_buffer_length, + dma_get_cache_alignment()), + sizeof(urb->transfer_buffer)); if (usb_urb_dir_in(urb)) { if (usb_pipeisoc(urb->pipe)) @@ -2513,6 +2515,7 @@ static int dwc2_alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags) * DMA */ kmalloc_size = urb->transfer_buffer_length + + (dma_get_cache_alignment() - 1) + sizeof(urb->transfer_buffer); kmalloc_ptr = kmalloc(kmalloc_size, mem_flags); @@ -2523,7 +2526,8 @@ static int dwc2_alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags) * Position value of original urb->transfer_buffer pointer to the end * of allocation for later referencing */ - memcpy(kmalloc_ptr + urb->transfer_buffer_length, + memcpy(PTR_ALIGN(kmalloc_ptr + urb->transfer_buffer_length, + dma_get_cache_alignment()), &urb->transfer_buffer, sizeof(urb->transfer_buffer)); if (usb_urb_dir_out(urb)) -- cgit v1.2.3-59-g8ed1b From b5bbe22353614d6a4d7a4b33f326e3009ec38052 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Tue, 28 May 2019 23:59:48 -0700 Subject: usb: phy: mxs: Disable external charger detect in mxs_phy_hw_init() Since this driver already handles changer detction state, copy the workaround code currently residing in arch/arm/mach-imx/anatop.c into this drier to consolidate the places modifying it. Signed-off-by: Andrey Smirnov Cc: Chris Healy Cc: Felipe Balbi Cc: Shawn Guo Cc: Fabio Estevam Cc: NXP Linux Team Cc: linux-usb@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Reviewed-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-mxs-usb.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index 1b1bb0ad40c3..6fa16ab31e2e 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c @@ -63,6 +63,7 @@ #define ANADIG_USB1_CHRG_DETECT_SET 0x1b4 #define ANADIG_USB1_CHRG_DETECT_CLR 0x1b8 +#define ANADIG_USB2_CHRG_DETECT_SET 0x214 #define ANADIG_USB1_CHRG_DETECT_EN_B BIT(20) #define ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B BIT(19) #define ANADIG_USB1_CHRG_DETECT_CHK_CONTACT BIT(18) @@ -250,6 +251,19 @@ static int mxs_phy_hw_init(struct mxs_phy *mxs_phy) if (mxs_phy->data->flags & MXS_PHY_NEED_IP_FIX) writel(BM_USBPHY_IP_FIX, base + HW_USBPHY_IP_SET); + if (mxs_phy->regmap_anatop) { + unsigned int reg = mxs_phy->port_id ? + ANADIG_USB1_CHRG_DETECT_SET : + ANADIG_USB2_CHRG_DETECT_SET; + /* + * The external charger detector needs to be disabled, + * or the signal at DP will be poor + */ + regmap_write(mxs_phy->regmap_anatop, reg, + ANADIG_USB1_CHRG_DETECT_EN_B | + ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B); + } + mxs_phy_tx_init(mxs_phy); return 0; -- cgit v1.2.3-59-g8ed1b From 62fd0e0a24abeebe2c19fce49dd5716d9b62042d Mon Sep 17 00:00:00 2001 From: Young Xiao <92siuyang@gmail.com> Date: Tue, 28 May 2019 20:17:54 +0800 Subject: usb: gadget: fusb300_udc: Fix memory leak of fusb300->ep[i] There is no deallocation of fusb300->ep[i] elements, allocated at fusb300_probe. The patch adds deallocation of fusb300->ep array elements. Signed-off-by: Young Xiao <92siuyang@gmail.com> Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/fusb300_udc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/udc/fusb300_udc.c b/drivers/usb/gadget/udc/fusb300_udc.c index 263804d154a7..00e3f66836a9 100644 --- a/drivers/usb/gadget/udc/fusb300_udc.c +++ b/drivers/usb/gadget/udc/fusb300_udc.c @@ -1342,12 +1342,15 @@ static const struct usb_gadget_ops fusb300_gadget_ops = { static int fusb300_remove(struct platform_device *pdev) { struct fusb300 *fusb300 = platform_get_drvdata(pdev); + int i; usb_del_gadget_udc(&fusb300->gadget); iounmap(fusb300->reg); free_irq(platform_get_irq(pdev, 0), fusb300); fusb300_free_request(&fusb300->ep[0]->ep, fusb300->ep0_req); + for (i = 0; i < FUSB300_MAX_NUM_EP; i++) + kfree(fusb300->ep[i]); kfree(fusb300); return 0; @@ -1491,6 +1494,8 @@ clean_up: if (fusb300->ep0_req) fusb300_free_request(&fusb300->ep[0]->ep, fusb300->ep0_req); + for (i = 0; i < FUSB300_MAX_NUM_EP; i++) + kfree(fusb300->ep[i]); kfree(fusb300); } if (reg) -- cgit v1.2.3-59-g8ed1b From fbc318afadd6e7ae2252d6158cf7d0c5a2132f7d Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 22 May 2019 14:07:36 +0200 Subject: usb: gadget: udc: lpc32xx: allocate descriptor with GFP_ATOMIC Gadget drivers may queue request in interrupt context. This would lead to a descriptor allocation in that context. In that case we would hit BUG_ON(in_interrupt()) in __get_vm_area_node. Also remove the unnecessary cast. Acked-by: Sylvain Lemieux Tested-by: James Grant Signed-off-by: Alexandre Belloni Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/lpc32xx_udc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index d8f1c60793ed..2719194ebf42 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -937,8 +937,7 @@ static struct lpc32xx_usbd_dd_gad *udc_dd_alloc(struct lpc32xx_udc *udc) dma_addr_t dma; struct lpc32xx_usbd_dd_gad *dd; - dd = (struct lpc32xx_usbd_dd_gad *) dma_pool_alloc( - udc->dd_cache, (GFP_KERNEL | GFP_DMA), &dma); + dd = dma_pool_alloc(udc->dd_cache, GFP_ATOMIC | GFP_DMA, &dma); if (dd) dd->this_dma = dma; -- cgit v1.2.3-59-g8ed1b From 4faf3b36553a0a5304f58ee3a620e659739a2e20 Mon Sep 17 00:00:00 2001 From: Minas Harutyunyan Date: Mon, 29 Apr 2019 15:23:43 +0400 Subject: usb: dwc2: Set actual frame number for completed ISOC transfer for none DDMA On ISOC OUT transfer completion, in none DDMA mode, set actual frame number returning to function driver in usb_request. Signed-off-by: Minas Harutyunyan Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 16ffd9fd9361..1d4aef8d4137 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2417,6 +2417,10 @@ static void dwc2_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum) dwc2_gadget_incr_frame_num(hs_ep); } + /* Set actual frame number for completed transfers */ + if (!using_desc_dma(hsotg) && hs_ep->isochronous) + req->frame_number = hsotg->frame_number; + dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, result); } -- cgit v1.2.3-59-g8ed1b From 066cfd0770aba8a9ac79b59d99530653885d919d Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Mon, 1 Apr 2019 12:50:45 +0200 Subject: usb: gadget: dwc2: fix zlp handling The patch 10209abe87f5ebfd482a00323f5236d6094d0865 usb: dwc2: gadget: Add scatter-gather mode avoided a NULL pointer dereference (hs_ep->req == NULL) by calling dwc2_gadget_fill_nonisoc_xfer_dma_one() directly instead of through the dwc2_gadget_config_nonisoc_xfer_ddma() wrapper, which unconditionally dereferenced the said pointer. However, this was based on an incorrect assumption that in the context of dwc2_hsotg_program_zlp() the pointer is always NULL, which is not the case. The result were SB CV MSC tests failing starting from Test Case 6. Instead, this patch reverts to calling the wrapper and adds a check for the pointer being NULL inside the wrapper. Fixes: 10209abe87f5 (usb: dwc2: gadget: Add scatter-gather mode) Acked-by: Minas Harutyunyan Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 1d4aef8d4137..bff48a8a1984 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -835,19 +835,22 @@ static void dwc2_gadget_fill_nonisoc_xfer_ddma_one(struct dwc2_hsotg_ep *hs_ep, * with corresponding information based on transfer data. */ static void dwc2_gadget_config_nonisoc_xfer_ddma(struct dwc2_hsotg_ep *hs_ep, - struct usb_request *ureq, - unsigned int offset, + dma_addr_t dma_buff, unsigned int len) { + struct usb_request *ureq = NULL; struct dwc2_dma_desc *desc = hs_ep->desc_list; struct scatterlist *sg; int i; u8 desc_count = 0; + if (hs_ep->req) + ureq = &hs_ep->req->req; + /* non-DMA sg buffer */ - if (!ureq->num_sgs) { + if (!ureq || !ureq->num_sgs) { dwc2_gadget_fill_nonisoc_xfer_ddma_one(hs_ep, &desc, - ureq->dma + offset, len, true); + dma_buff, len, true); return; } @@ -1135,7 +1138,7 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg, offset = ureq->actual; /* Fill DDMA chain entries */ - dwc2_gadget_config_nonisoc_xfer_ddma(hs_ep, ureq, offset, + dwc2_gadget_config_nonisoc_xfer_ddma(hs_ep, ureq->dma + offset, length); /* write descriptor chain address to control register */ @@ -2037,12 +2040,13 @@ static void dwc2_hsotg_program_zlp(struct dwc2_hsotg *hsotg, dev_dbg(hsotg->dev, "Receiving zero-length packet on ep%d\n", index); if (using_desc_dma(hsotg)) { + /* Not specific buffer needed for ep0 ZLP */ + dma_addr_t dma = hs_ep->desc_list_dma; + if (!index) dwc2_gadget_set_ep0_desc_chain(hsotg, hs_ep); - /* Not specific buffer needed for ep0 ZLP */ - dwc2_gadget_fill_nonisoc_xfer_ddma_one(hs_ep, &hs_ep->desc_list, - hs_ep->desc_list_dma, 0, true); + dwc2_gadget_config_nonisoc_xfer_ddma(hs_ep, dma, 0); } else { dwc2_writel(hsotg, DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) | DXEPTSIZ_XFERSIZE(0), -- cgit v1.2.3-59-g8ed1b From 42cc68868ce9d5f5277f561bb17b4746a332bb28 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sat, 4 May 2019 07:04:07 +0000 Subject: usb: gadget: udc: lpc32xx: fix return value check in lpc32xx_udc_probe() In case of error, the function devm_ioremap_resource() returns ERR_PTR() and never returns NULL. The NULL test in the return value check should be replaced with IS_ERR(). This issue was detected by using the Coccinelle software. Fixes: 408b56ca5c8e ("usb: gadget: udc: lpc32xx: simplify probe") Acked-by: Sylvain Lemieux Acked-by: Vladimir Zapolskiy Signed-off-by: Wei Yongjun Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/lpc32xx_udc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index 2719194ebf42..5f1b14f3e5a0 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -3069,9 +3069,9 @@ static int lpc32xx_udc_probe(struct platform_device *pdev) } udc->udp_baseaddr = devm_ioremap_resource(dev, res); - if (!udc->udp_baseaddr) { + if (IS_ERR(udc->udp_baseaddr)) { dev_err(udc->dev, "IO map failure\n"); - return -ENOMEM; + return PTR_ERR(udc->udp_baseaddr); } /* Get USB device clock */ -- cgit v1.2.3-59-g8ed1b