diff --git a/devicemodel/hw/pci/xhci.c b/devicemodel/hw/pci/xhci.c index e4749152d..4f9b67524 100644 --- a/devicemodel/hw/pci/xhci.c +++ b/devicemodel/hw/pci/xhci.c @@ -892,7 +892,7 @@ pci_xhci_native_usb_dev_disconn_cb(void *hci_data, void *dev_data) } edev = xdev->devices[vport]; - for (slot = 1; slot < XHCI_MAX_SLOTS; ++slot) + for (slot = 1; slot <= XHCI_MAX_SLOTS; ++slot) if (xdev->slots[slot] == edev) break; @@ -1056,6 +1056,8 @@ pci_xhci_dev_destroy(struct pci_xhci_dev_emu *de) { struct usb_devemu *ue; struct usb_dev *ud; + struct pci_xhci_dev_ep *vdep; + int i; if (de) { ue = de->dev_ue; @@ -1072,6 +1074,18 @@ pci_xhci_dev_destroy(struct pci_xhci_dev_emu *de) if (ue->ue_devtype == USB_DEV_PORT_MAPPER) free(ue); + for (i = 1; i < XHCI_MAX_ENDPOINTS; i++) { + vdep = &de->eps[i]; + if (vdep->ep_xfer) { + if (vdep->ep_xfer->ureq) { + free(vdep->ep_xfer->ureq); + vdep->ep_xfer->ureq = NULL; + } + free(vdep->ep_xfer); + vdep->ep_xfer = NULL; + } + } + free(de); } } @@ -3962,7 +3976,7 @@ pci_xhci_parse_opts(struct pci_xhci_vdev *xdev, char *opts) /* allocate neccessary resources during parsing*/ xdev->devices = calloc(XHCI_MAX_DEVS + 1, sizeof(*xdev->devices)); - xdev->slots = calloc(XHCI_MAX_SLOTS, sizeof(*xdev->slots)); + xdev->slots = calloc(XHCI_MAX_SLOTS + 1, sizeof(*xdev->slots)); xdev->portregs = calloc(XHCI_MAX_DEVS + 1, sizeof(*xdev->portregs)); if (!xdev->devices || !xdev->slots || !xdev->portregs) { rc = -2; diff --git a/devicemodel/hw/platform/usb_pmapper.c b/devicemodel/hw/platform/usb_pmapper.c index f08e159b8..a00e9a070 100755 --- a/devicemodel/hw/platform/usb_pmapper.c +++ b/devicemodel/hw/platform/usb_pmapper.c @@ -125,21 +125,22 @@ internal_scan(struct libusb_device ***list, int list_sz, int depth, } static int -usb_dev_scan_dev() +usb_dev_scan_dev(struct libusb_device ***devlist) { int num_devs; - struct libusb_device **devlist; int8_t visit[USB_MAX_DEVICES]; if (!g_ctx.libusb_ctx) return -1; - num_devs = libusb_get_device_list(g_ctx.libusb_ctx, &devlist); - if (num_devs < 0) + num_devs = libusb_get_device_list(g_ctx.libusb_ctx, devlist); + if (num_devs < 0) { + *devlist = NULL; return -1; + } memset(visit, 0, sizeof(visit)); - internal_scan(&devlist, num_devs, 1, visit, USB_MAX_DEVICES); + internal_scan(devlist, num_devs, 1, visit, USB_MAX_DEVICES); return num_devs; } @@ -1215,7 +1216,7 @@ usb_dev_sys_init(usb_dev_sys_cb conn_cb, usb_dev_sys_cb disconn_cb, g_ctx.notify_cb = notify_cb; g_ctx.intr_cb = intr_cb; - num_devs = usb_dev_scan_dev(); + num_devs = usb_dev_scan_dev(&g_ctx.devlist); UPRINTF(LINF, "found %d devices before Guest OS booted\r\n", num_devs); native_conn_evt = LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED; @@ -1260,10 +1261,15 @@ usb_dev_sys_init(usb_dev_sys_cb conn_cb, usb_dev_sys_cb disconn_cb, return 0; errout: - if (g_ctx.libusb_ctx) - libusb_exit(g_ctx.libusb_ctx); + if (g_ctx.devlist) { + libusb_free_device_list(g_ctx.devlist, 1); + g_ctx.devlist = NULL; + } - g_ctx.libusb_ctx = NULL; + if (g_ctx.libusb_ctx) { + libusb_exit(g_ctx.libusb_ctx); + g_ctx.libusb_ctx = NULL; + } return -1; } @@ -1281,6 +1287,11 @@ usb_dev_sys_deinit(void) g_ctx.thread_exit = 1; pthread_join(g_ctx.thread, NULL); + if (g_ctx.devlist) { + libusb_free_device_list(g_ctx.devlist, 1); + g_ctx.devlist = NULL; + } + libusb_exit(g_ctx.libusb_ctx); g_ctx.libusb_ctx = NULL; } diff --git a/devicemodel/include/usb_pmapper.h b/devicemodel/include/usb_pmapper.h index 43cb09fd8..ae528070b 100644 --- a/devicemodel/include/usb_pmapper.h +++ b/devicemodel/include/usb_pmapper.h @@ -102,6 +102,8 @@ struct usb_dev_sys_ctx_info { usb_dev_sys_cb notify_cb; usb_dev_sys_cb intr_cb; + libusb_device **devlist; + /* * private data from HCD layer */