From 6a9a46ac473555c12ba816461797d3399436a020 Mon Sep 17 00:00:00 2001 From: Xiaoguang Wu Date: Thu, 18 Oct 2018 23:09:50 +0800 Subject: [PATCH] DM USB: xHCI: workaround for Stop Endpoint Command handling This patch is one workaround to resolve a crash issue for certain brand touch screen (eGalaxTouch EXC7200-7368v1.01). The formal fix should follow the xHCI spec to stop xfer and generate transfer completed event trb prior to Stop Endpoint Command complete event trb. It should be a big change and for short term, do nothing for the stop endpoint command which is no other side effect be observed so far. Tracked-On: #1413 Signed-off-by: Xiaoguang Wu Reviewed-by: Liang Yang Acked-by: Yu Wang --- devicemodel/hw/pci/xhci.c | 9 ++++++++- devicemodel/hw/platform/usb_pmapper.c | 17 ----------------- devicemodel/include/usb_core.h | 2 -- 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/devicemodel/hw/pci/xhci.c b/devicemodel/hw/pci/xhci.c index d6405b213..fb680e88b 100755 --- a/devicemodel/hw/pci/xhci.c +++ b/devicemodel/hw/pci/xhci.c @@ -2053,7 +2053,8 @@ pci_xhci_cmd_reset_ep(struct pci_xhci_vdev *xdev, epid = XHCI_TRB_3_EP_GET(trb->dwTrb3); - UPRINTF(LDBG, "reset ep %u: slot %u\r\n", epid, slot); + UPRINTF(LDBG, "reset ep %u: slot %u cmd_type: %02X\r\n", epid, slot, + XHCI_TRB_3_TYPE_GET(trb->dwTrb3)); cmderr = XHCI_TRB_ERROR_SUCCESS; @@ -2083,6 +2084,12 @@ pci_xhci_cmd_reset_ep(struct pci_xhci_vdev *xdev, goto done; } + /* FIXME: Currently nothing to do when Stop Endpoint Command is + * received. Will refine it strictly according to xHCI spec. + */ + if (type == XHCI_TRB_TYPE_STOP_EP) + goto done; + devep = &dev->eps[epid]; if (devep->ep_xfer != NULL) USB_DATA_XFER_RESET(devep->ep_xfer); diff --git a/devicemodel/hw/platform/usb_pmapper.c b/devicemodel/hw/platform/usb_pmapper.c index a7a5f2742..840e6654b 100755 --- a/devicemodel/hw/platform/usb_pmapper.c +++ b/devicemodel/hw/platform/usb_pmapper.c @@ -244,22 +244,6 @@ usb_dev_comp_req(struct libusb_transfer *libusb_xfer) } } - /* in case the xfer is reset by the USB_DATA_XFER_RESET */ - if (xfer->reset == 1) { - UPRINTF(LDBG, "ep%d reset detected\r\n", xfer->epid); - xfer->reset = 0; - /* ONLY interrupt transfer needs this. - * The transfer here is an old one before endpoint reset, so it - * should be discarded. But for bulk transfer, the transfer here - * is a new one after reset, so it should be kept. - */ - if (usb_dev_get_ep_type(req->udev, xfer->pid & 1, - xfer->epid / 2) == USB_ENDPOINT_INT) { - UPRINTF(LDBG, "goto reset out\r\n"); - goto reset_out; - } - } - /* handle the blocks belong to this request */ buf_idx = 0; idx = req->blk_start; @@ -323,7 +307,6 @@ out: if (do_intr && g_ctx.intr_cb) g_ctx.intr_cb(xfer->dev, NULL); -reset_out: /* unlock and release memory */ USB_DATA_XFER_UNLOCK(xfer); libusb_free_transfer(libusb_xfer); diff --git a/devicemodel/include/usb_core.h b/devicemodel/include/usb_core.h index 554cfba4b..d779acb2a 100644 --- a/devicemodel/include/usb_core.h +++ b/devicemodel/include/usb_core.h @@ -168,7 +168,6 @@ struct usb_data_xfer { void *dev; /* struct pci_xhci_dev_emu *dev */ int epid; /* related endpoint id */ int pid; /* token id */ - int reset; /* detect ep reset */ int status; pthread_mutex_t mtx; }; @@ -219,7 +218,6 @@ enum USB_ERRCODE { memset((x)->data, 0, sizeof((x)->data)); \ (x)->ndata = 0; \ (x)->head = (x)->tail = 0; \ - (x)->reset = 1; \ pthread_mutex_unlock((&(x)->mtx)); \ } while (0)