From 5f318dad72d227438f4da4c57afb2dfbd9dacddb Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 4 Sep 2019 13:01:02 +0300 Subject: usb: cdns3: Fix use after free in probe error handling We can't use "wrap" after it has been freed. Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/20190904100102.GB7007@mwanda Signed-off-by: Greg Kroah-Hartman --- drivers/usb/cdns3/cdns3-pci-wrap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/usb/cdns3') diff --git a/drivers/usb/cdns3/cdns3-pci-wrap.c b/drivers/usb/cdns3/cdns3-pci-wrap.c index c41ddb61b857..b0a29efe7d31 100644 --- a/drivers/usb/cdns3/cdns3-pci-wrap.c +++ b/drivers/usb/cdns3/cdns3-pci-wrap.c @@ -159,8 +159,9 @@ static int cdns3_pci_probe(struct pci_dev *pdev, wrap->plat_dev = platform_device_register_full(&plat_info); if (IS_ERR(wrap->plat_dev)) { pci_disable_device(pdev); + err = PTR_ERR(wrap->plat_dev); kfree(wrap); - return PTR_ERR(wrap->plat_dev); + return err; } } -- cgit v1.2.3 From 9816144313d33974bbd4599d4e8e554c11cae27e Mon Sep 17 00:00:00 2001 From: Pawel Laszczak Date: Thu, 26 Sep 2019 08:58:41 +0100 Subject: usb: cdns3: Fix sheduling with locks held. Patch fix issue in cdns3_ep0_feature_handle_device function. The function usleep_range can't be used there because this function is called with locks held and IRQs disabled in cdns3_device_thread_irq_handler(). To resolve this issue patch replaces usleep_range with mdelay. Reported-by: Dan Carpenter Signed-off-by: Pawel Laszczak Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver") Reviewed-by: Peter Chen Link: https://lore.kernel.org/r/1569484721-4424-1-git-send-email-pawell@cadence.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/cdns3/ep0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb/cdns3') diff --git a/drivers/usb/cdns3/ep0.c b/drivers/usb/cdns3/ep0.c index 44f652e8b5a2..0445da0a5a0c 100644 --- a/drivers/usb/cdns3/ep0.c +++ b/drivers/usb/cdns3/ep0.c @@ -332,7 +332,7 @@ static int cdns3_ep0_feature_handle_device(struct cdns3_device *priv_dev, * for sending status stage. * This time should be less then 3ms. */ - usleep_range(1000, 2000); + mdelay(1); cdns3_set_register_bit(&priv_dev->regs->usb_cmd, USB_CMD_STMODE | USB_STS_TMODE_SEL(tmode - 1)); -- cgit v1.2.3 From 623170ff59710474d2db3dfb0ebb7577f44abd33 Mon Sep 17 00:00:00 2001 From: Pawel Laszczak Date: Mon, 7 Oct 2019 07:39:11 +0100 Subject: usb:cdns3: Fix for CV CH9 running with g_zero driver. Patch fixes issue with Halt Endnpoint Test observed during using g_zero driver as DUT. Bug occurred only on some testing board. Endpoint can defer transition to Halted state if endpoint has pending requests. Patch add additional condition that allows to return correct endpoint status during Get Endpoint Status request even if the halting endpoint is in progress. Reported-by: Rahul Kumar Signed-off-by: Rahul Kumar Signed-off-by: Pawel Laszczak Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver") Tested-by: Roger Quadros Link: https://lore.kernel.org/r/1570430355-26118-1-git-send-email-pawell@cadence.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/cdns3/ep0.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/usb/cdns3') diff --git a/drivers/usb/cdns3/ep0.c b/drivers/usb/cdns3/ep0.c index 0445da0a5a0c..e71240b386b4 100644 --- a/drivers/usb/cdns3/ep0.c +++ b/drivers/usb/cdns3/ep0.c @@ -234,9 +234,11 @@ static int cdns3_req_ep0_set_address(struct cdns3_device *priv_dev, static int cdns3_req_ep0_get_status(struct cdns3_device *priv_dev, struct usb_ctrlrequest *ctrl) { + struct cdns3_endpoint *priv_ep; __le16 *response_pkt; u16 usb_status = 0; u32 recip; + u8 index; recip = ctrl->bRequestType & USB_RECIP_MASK; @@ -262,9 +264,13 @@ static int cdns3_req_ep0_get_status(struct cdns3_device *priv_dev, case USB_RECIP_INTERFACE: return cdns3_ep0_delegate_req(priv_dev, ctrl); case USB_RECIP_ENDPOINT: - /* check if endpoint is stalled */ + index = cdns3_ep_addr_to_index(ctrl->wIndex); + priv_ep = priv_dev->eps[index]; + + /* check if endpoint is stalled or stall is pending */ cdns3_select_ep(priv_dev, ctrl->wIndex); - if (EP_STS_STALL(readl(&priv_dev->regs->ep_sts))) + if (EP_STS_STALL(readl(&priv_dev->regs->ep_sts)) || + (priv_ep->flags & EP_STALL_PENDING)) usb_status = BIT(USB_ENDPOINT_HALT); break; default: -- cgit v1.2.3 From ac9099e10a603f02f52f583fba78dd54c52b5542 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Mon, 7 Oct 2019 15:16:01 +0300 Subject: usb: cdns3: gadget: Fix full-speed mode We need to disable USB3 PHY for full-speed mode else gadget mode is broken. Signed-off-by: Roger Quadros Signed-off-by: Sekhar Nori Reviewed-by: Peter Chen Link: https://lore.kernel.org/r/20191007121601.25996-3-rogerq@ti.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/cdns3/gadget.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/usb/cdns3') diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c index 228cdc4ab886..157536753b8c 100644 --- a/drivers/usb/cdns3/gadget.c +++ b/drivers/usb/cdns3/gadget.c @@ -2571,6 +2571,7 @@ static int cdns3_gadget_start(struct cdns3 *cdns) switch (max_speed) { case USB_SPEED_FULL: writel(USB_CONF_SFORCE_FS, &priv_dev->regs->usb_conf); + writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf); break; case USB_SPEED_HIGH: writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf); -- cgit v1.2.3 From 02ffc26df96b487f476b8945eaef13c7f170e79a Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Mon, 7 Oct 2019 15:16:00 +0300 Subject: usb: cdns3: fix cdns3_core_init_role() At startup we should trigger the HW state machine only if it is OTG mode. Otherwise we should just start the respective role. Initialize idle role by default. If we don't do this then cdns3_idle_role_stop() is not called when switching to host/device role and so lane switch mechanism doesn't work. This results to super-speed device not working in one orientation if it was plugged before driver probe. Signed-off-by: Roger Quadros Signed-off-by: Sekhar Nori Link: https://lore.kernel.org/r/20191007121601.25996-2-rogerq@ti.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/cdns3/core.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'drivers/usb/cdns3') diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c index 06f1e105be4e..1109dc5a4c39 100644 --- a/drivers/usb/cdns3/core.c +++ b/drivers/usb/cdns3/core.c @@ -160,10 +160,28 @@ static int cdns3_core_init_role(struct cdns3 *cdns) if (ret) goto err; - if (cdns->dr_mode != USB_DR_MODE_OTG) { + /* Initialize idle role to start with */ + ret = cdns3_role_start(cdns, USB_ROLE_NONE); + if (ret) + goto err; + + switch (cdns->dr_mode) { + case USB_DR_MODE_UNKNOWN: + case USB_DR_MODE_OTG: ret = cdns3_hw_role_switch(cdns); if (ret) goto err; + break; + case USB_DR_MODE_PERIPHERAL: + ret = cdns3_role_start(cdns, USB_ROLE_DEVICE); + if (ret) + goto err; + break; + case USB_DR_MODE_HOST: + ret = cdns3_role_start(cdns, USB_ROLE_HOST); + if (ret) + goto err; + break; } return ret; -- cgit v1.2.3 From eb21a74adaa11846737f503dd618bd35337e2c37 Mon Sep 17 00:00:00 2001 From: Pawel Laszczak Date: Mon, 7 Oct 2019 13:03:23 +0100 Subject: usb: cdns3: Fix for incorrect DMA mask. This patch restores the correct DMA mask after switching back to device mode. The issue occurred because Device part of controller use 32 bits DMA and Host side use 64 bits DMA. During loading XHCI driver the DMA mask used by driver is overwritten by XHCI driver so it must be restored to 32 bits. Reported-by: Pawel Laszczak Signed-off-by: Roger Quadros Signed-off-by: Pawel Laszczak Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver") Reviewed-by: Peter Chen Tested-by: Roger Quadros Link: https://lore.kernel.org/r/1570449803-15299-1-git-send-email-pawell@cadence.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/cdns3/gadget.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/usb/cdns3') diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c index 157536753b8c..2ca280f4c054 100644 --- a/drivers/usb/cdns3/gadget.c +++ b/drivers/usb/cdns3/gadget.c @@ -2663,6 +2663,13 @@ static int __cdns3_gadget_init(struct cdns3 *cdns) { int ret = 0; + /* Ensure 32-bit DMA Mask in case we switched back from Host mode */ + ret = dma_set_mask_and_coherent(cdns->dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(cdns->dev, "Failed to set dma mask: %d\n", ret); + return ret; + } + cdns3_drd_switch_gadget(cdns, 1); pm_runtime_get_sync(cdns->dev); -- cgit v1.2.3