DM USB: xHCI: WA for an isochronous crash issue

The current xHCI mediator doesn't well support disable endpoint command.
This patch is one workaround for disable endpoint command to avoid
xHCI mediator to continue handle already dropped data.

Tracked-On: #2927
Signed-off-by: Xiaoguang Wu <xiaoguang.wu@intel.com>
Acked-by: Yu Wang <yu1.wang@intel.com>
This commit is contained in:
Xiaoguang Wu 2018-12-28 20:06:52 +08:00 committed by Eddie Dong
parent f0e7ce6a8c
commit 63743d8b9b
3 changed files with 14 additions and 0 deletions

View File

@ -1606,6 +1606,7 @@ pci_xhci_init_ep(struct pci_xhci_dev_emu *dev, int epid)
USB_DATA_XFER_INIT(devep->ep_xfer);
devep->ep_xfer->dev = (void *)dev;
devep->ep_xfer->epid = epid;
devep->ep_xfer->magic = USB_DROPPED_XFER_MAGIC;
} else
return -1;
}
@ -1631,6 +1632,7 @@ pci_xhci_disable_ep(struct pci_xhci_dev_emu *dev, int epid)
free(devep->ep_sctx_trbs);
if (devep->ep_xfer != NULL) {
memset(devep->ep_xfer, 0, sizeof(*devep->ep_xfer));
free(devep->ep_xfer);
devep->ep_xfer = NULL;
}

View File

@ -190,6 +190,15 @@ usb_dev_comp_req(struct libusb_transfer *libusb_xfer)
/* async transfer */
xfer = req->xfer;
if (xfer->magic != USB_DROPPED_XFER_MAGIC)
/* FIXME: if magic is not what we expected, which means it is
* reset by Disable Endpoint command, hence this xfer from
* callback function should be discarded. This is a workaround
* and a formal implementation for Disable Endpoint command
* will replace this WA.
*/
goto out;
assert(xfer);
assert(xfer->dev);

View File

@ -160,6 +160,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_device_request *ureq; /* setup ctl request */
int ndata; /* # of data items */
@ -242,6 +243,8 @@ enum USB_ERRCODE {
#define USB_NATIVE_NUM_PORT 20
#define USB_NATIVE_NUM_BUS 4
#define USB_DROPPED_XFER_MAGIC 0xaaaaaaaa55555555
extern int usb_log_level;
static inline int usb_get_log_level(void) { return usb_log_level; }
static inline void usb_set_log_level(int level) { usb_log_level = level; }