]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
usb: gadget: aspeed: fix dma map failure
authorTao Ren <rentao.bupt@gmail.com>
Wed, 31 Mar 2021 04:58:31 +0000 (21:58 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 22 May 2021 08:59:29 +0000 (10:59 +0200)
[ Upstream commit bd4d607044b961cecbf8c4c2f3bb5da4fb156993 ]

Currently the virtual port_dev device is passed to DMA API, and this is
wrong because the device passed to DMA API calls must be the actual
hardware device performing the DMA.

The patch replaces usb_gadget_map_request/usb_gadget_unmap_request APIs
with usb_gadget_map_request_by_dev/usb_gadget_unmap_request_by_dev APIs
so the DMA capable platform device can be passed to the DMA APIs.

The patch fixes below backtrace detected on Facebook AST2500 OpenBMC
platforms:

[<80106550>] show_stack+0x20/0x24
[<80106868>] dump_stack+0x28/0x30
[<80823540>] __warn+0xfc/0x110
[<8011ac30>] warn_slowpath_fmt+0xb0/0xc0
[<8011ad44>] dma_map_page_attrs+0x24c/0x314
[<8016a27c>] usb_gadget_map_request_by_dev+0x100/0x1e4
[<805cedd8>] usb_gadget_map_request+0x1c/0x20
[<805cefbc>] ast_vhub_epn_queue+0xa0/0x1d8
[<7f02f710>] usb_ep_queue+0x48/0xc4
[<805cd3e8>] ecm_do_notify+0xf8/0x248
[<7f145920>] ecm_set_alt+0xc8/0x1d0
[<7f145c34>] composite_setup+0x680/0x1d30
[<7f00deb8>] ast_vhub_ep0_handle_setup+0xa4/0x1bc
[<7f02ee94>] ast_vhub_dev_irq+0x58/0x84
[<7f0309e0>] ast_vhub_irq+0xb0/0x1c8
[<7f02e118>] __handle_irq_event_percpu+0x50/0x19c
[<8015e5bc>] handle_irq_event_percpu+0x38/0x8c
[<8015e758>] handle_irq_event+0x38/0x4c

Fixes: 7ecca2a4080c ("usb/gadget: Add driver for Aspeed SoC virtual hub")
Reviewed-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Tao Ren <rentao.bupt@gmail.com>
Link: https://lore.kernel.org/r/20210331045831.28700-1-rentao.bupt@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/usb/gadget/udc/aspeed-vhub/core.c
drivers/usb/gadget/udc/aspeed-vhub/epn.c

index db3628be38c07b270eda5b9afe9d3cba1cab47e1..902e61be4d6424fa23435d6de1c6be775564548d 100644 (file)
@@ -36,6 +36,7 @@ void ast_vhub_done(struct ast_vhub_ep *ep, struct ast_vhub_req *req,
                   int status)
 {
        bool internal = req->internal;
+       struct ast_vhub *vhub = ep->vhub;
 
        EPVDBG(ep, "completing request @%p, status %d\n", req, status);
 
@@ -46,7 +47,7 @@ void ast_vhub_done(struct ast_vhub_ep *ep, struct ast_vhub_req *req,
 
        if (req->req.dma) {
                if (!WARN_ON(!ep->dev))
-                       usb_gadget_unmap_request(&ep->dev->gadget,
+                       usb_gadget_unmap_request_by_dev(&vhub->pdev->dev,
                                                 &req->req, ep->epn.is_in);
                req->req.dma = 0;
        }
index ae853cf3696625ec853aace1a9232036724130ac..931f540a747e9f3b139a9f8541d34231f55ec8f6 100644 (file)
@@ -376,7 +376,7 @@ static int ast_vhub_epn_queue(struct usb_ep* u_ep, struct usb_request *u_req,
        if (ep->epn.desc_mode ||
            ((((unsigned long)u_req->buf & 7) == 0) &&
             (ep->epn.is_in || !(u_req->length & (u_ep->maxpacket - 1))))) {
-               rc = usb_gadget_map_request(&ep->dev->gadget, u_req,
+               rc = usb_gadget_map_request_by_dev(&vhub->pdev->dev, u_req,
                                            ep->epn.is_in);
                if (rc) {
                        dev_warn(&vhub->pdev->dev,