From 35931356734087678c7da6c639346c4e0b91dbaa Mon Sep 17 00:00:00 2001 From: Xiaoguang Wu Date: Thu, 14 Mar 2019 23:27:54 +0800 Subject: [PATCH] DM USB: xHCI: Fix CTS test failure This patch fixes the failure of CTS 'USB Device Test' itme. Tracked-On: #2800 Signed-off-by: Xiaoguang Wu Acked-by: Yu Wang --- devicemodel/hw/pci/xhci.c | 31 ++++++++++++++++++++++++--- devicemodel/hw/platform/usb_pmapper.c | 26 ++++++++++++++++++---- devicemodel/include/usb_core.h | 1 + 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/devicemodel/hw/pci/xhci.c b/devicemodel/hw/pci/xhci.c index b4b1f26e0..ce1c7f4c0 100644 --- a/devicemodel/hw/pci/xhci.c +++ b/devicemodel/hw/pci/xhci.c @@ -2280,11 +2280,16 @@ pci_xhci_cmd_reset_ep(struct pci_xhci_vdev *xdev, struct xhci_trb *trb) { struct pci_xhci_dev_emu *dev; - struct pci_xhci_dev_ep *devep; + struct pci_xhci_dev_ep *devep; struct xhci_dev_ctx *dev_ctx; struct xhci_endp_ctx *ep_ctx; + struct usb_data_xfer *xfer; + struct usb_dev *udev; + struct usb_dev_req *r; + struct usb_native_devinfo *info = NULL; uint32_t cmderr, epid; uint32_t type; + int i; epid = XHCI_TRB_3_EP_GET(trb->dwTrb3); @@ -2322,10 +2327,30 @@ pci_xhci_cmd_reset_ep(struct pci_xhci_vdev *xdev, /* 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; + if (type == XHCI_TRB_TYPE_STOP_EP) { + udev = dev->dev_instance; + if (!udev) + goto done; + + info = &udev->info; + if (!(info->vid == 0x18d1 && info->pid == 0x2d01)) + goto done; + } devep = &dev->eps[epid]; + xfer = devep->ep_xfer; + if (!xfer) + goto done; + + if (info && info->vid == 0x18d1 && info->pid == 0x2d01) { + for (i = 0; i < USB_MAX_XFER_BLOCKS; i++) { + r = xfer->requests[i]; + if (r && r->libusb_xfer) + /* let usb_dev_comp_req to free the memory */ + libusb_cancel_transfer(r->libusb_xfer); + } + } + 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 b4e361e5b..258cf8787 100755 --- a/devicemodel/hw/platform/usb_pmapper.c +++ b/devicemodel/hw/platform/usb_pmapper.c @@ -228,8 +228,7 @@ usb_dev_comp_req(struct libusb_transfer *libusb_xfer) xfer->status = USB_ERR_STALLED; goto stall_out; case LIBUSB_TRANSFER_CANCELLED: - xfer->status = USB_ERR_IOERROR; - goto out; + goto cancel_out; case LIBUSB_TRANSFER_TIMED_OUT: xfer->status = USB_ERR_TIMEOUT; goto out; @@ -322,12 +321,14 @@ out: if (do_intr && g_ctx.intr_cb) g_ctx.intr_cb(xfer->dev, NULL); +cancel_out: /* unlock and release memory */ USB_DATA_XFER_UNLOCK(xfer); libusb_free_transfer(libusb_xfer); if (req && req->buffer) free(req->buffer); + xfer->requests[req->blk_start] = NULL; free(req); } @@ -630,10 +631,19 @@ usb_dev_set_config(struct usb_dev *udev, struct usb_data_xfer *xfer, int config) { int rc = 0; struct libusb_config_descriptor *cfg; + struct usb_devpath *path; assert(udev); assert(udev->handle); + /* do not set config for accessory device */ + if (udev->info.vid == 0x18d1 && udev->info.pid == 0x2d01) { + path = &udev->info.path; + UPRINTF(LFTL, "skip to configure accessory device %d-%s\r\n", + path->bus, usb_dev_path(path)); + return; + } + /* * set configuration * according to the libusb doc, the detach and release work @@ -744,12 +754,19 @@ int usb_dev_reset(void *pdata) { struct usb_dev *udev; + struct usb_devpath *path; udev = pdata; assert(udev); + path = &udev->info.path; + + /* do not set config for accessory device */ + if (!(udev->info.vid == 0x18d1 && udev->info.pid == 0x2d01)) + libusb_reset_device(udev->handle); + else + UPRINTF(LFTL, "skip resetting accessory device %d-%s\r\n", + path->bus, usb_dev_path(path)); - UPRINTF(LDBG, "reset endpoints\n"); - libusb_reset_device(udev->handle); usb_dev_reset_ep(udev); usb_dev_update_ep(udev); return 0; @@ -810,6 +827,7 @@ usb_dev_data(void *pdata, struct usb_data_xfer *xfer, int dir, int epctx) req->buf_length = data_size; req->blk_start = blk_start; req->blk_count = blk_count; + xfer->requests[blk_start] = req; UPRINTF(LDBG, "%s: transfer_length %d ep%d-transfer (%d-%d %d) request" "-%d (%d-%d %d) direction %s type %s\r\n", __func__, data_size, epctx, xfer->head, (xfer->tail - 1) % diff --git a/devicemodel/include/usb_core.h b/devicemodel/include/usb_core.h index 3c01cfe94..c54754b30 100644 --- a/devicemodel/include/usb_core.h +++ b/devicemodel/include/usb_core.h @@ -162,6 +162,7 @@ struct usb_data_xfer_block { struct usb_data_xfer { uint64_t magic; struct usb_data_xfer_block data[USB_MAX_XFER_BLOCKS]; + struct usb_dev_req *requests[USB_MAX_XFER_BLOCKS]; struct usb_device_request *ureq; /* setup ctl request */ int ndata; /* # of data items */ int head;