diff --git a/devicemodel/hw/pci/xhci.c b/devicemodel/hw/pci/xhci.c index 4f9b67524..2a49a73fc 100644 --- a/devicemodel/hw/pci/xhci.c +++ b/devicemodel/hw/pci/xhci.c @@ -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; } diff --git a/devicemodel/hw/platform/usb_pmapper.c b/devicemodel/hw/platform/usb_pmapper.c index a00e9a070..5a4d58a50 100755 --- a/devicemodel/hw/platform/usb_pmapper.c +++ b/devicemodel/hw/platform/usb_pmapper.c @@ -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); diff --git a/devicemodel/include/usb_core.h b/devicemodel/include/usb_core.h index 78f13963d..5692bfa70 100644 --- a/devicemodel/include/usb_core.h +++ b/devicemodel/include/usb_core.h @@ -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; }