diff --git a/devicemodel/hw/pci/xhci.c b/devicemodel/hw/pci/xhci.c index 21adf2ba6..439a6a3b8 100644 --- a/devicemodel/hw/pci/xhci.c +++ b/devicemodel/hw/pci/xhci.c @@ -3321,9 +3321,44 @@ done: return error; } +static void +pci_xhci_deinit(struct vmctx *ctx, struct pci_vdev *dev, char *opts) +{ + int i; + struct pci_xhci_vdev *xdev; + struct pci_xhci_dev_emu *de; + + assert(dev); + xdev = dev->arg; + + UPRINTF(LINF, "de-initialization\r\n"); + assert(xdev); + assert(xdev->devices); + + for (i = 1; i <= XHCI_MAX_DEVS; ++i) { + de = xdev->devices[i]; + if (de) { + xdev->devices[i] = NULL; + pci_xhci_dev_destroy(de); + xdev->ndevices--; + } + } + + free(xdev->devices); + free(xdev->slots); + free(xdev->portregs); + + usb_dev_sys_deinit(); + + pthread_mutex_destroy(&xdev->mtx); + free(xdev); + xhci_in_use = 0; +} + struct pci_vdev_ops pci_ops_xhci = { .class_name = "xhci", .vdev_init = pci_xhci_init, + .vdev_deinit = pci_xhci_deinit, .vdev_barwrite = pci_xhci_write, .vdev_barread = pci_xhci_read }; diff --git a/devicemodel/hw/platform/usb_pmapper.c b/devicemodel/hw/platform/usb_pmapper.c index 08692640b..f878663b1 100644 --- a/devicemodel/hw/platform/usb_pmapper.c +++ b/devicemodel/hw/platform/usb_pmapper.c @@ -937,6 +937,11 @@ usb_dev_sys_init(usb_dev_sys_cb conn_cb, usb_dev_sys_cb disconn_cb, goto errout; } + /* this is for guest rebooting purpose */ + g_ctx.conn_handle = native_conn_handle; + g_ctx.disconn_handle = native_disconn_handle; + g_ctx.thread_exit = 0; + if (pthread_create(&g_ctx.thread, NULL, usb_dev_sys_thread, NULL)) { libusb_hotplug_deregister_callback(g_ctx.libusb_ctx, native_conn_handle); @@ -953,3 +958,21 @@ errout: g_ctx.libusb_ctx = NULL; return -1; } + +void +usb_dev_sys_deinit(void) +{ + if (!g_ctx.libusb_ctx) + return; + + UPRINTF(LINF, "port-mapper de-initialization\r\n"); + libusb_hotplug_deregister_callback(g_ctx.libusb_ctx, g_ctx.conn_handle); + libusb_hotplug_deregister_callback(g_ctx.libusb_ctx, + g_ctx.disconn_handle); + + g_ctx.thread_exit = 1; + pthread_join(g_ctx.thread, 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 4df8035c3..baf1d429a 100644 --- a/devicemodel/include/usb_pmapper.h +++ b/devicemodel/include/usb_pmapper.h @@ -118,6 +118,10 @@ struct usb_dev_sys_ctx_info { pthread_t thread; int thread_exit; + /* handles of callback */ + libusb_hotplug_callback_handle conn_handle; + libusb_hotplug_callback_handle disconn_handle; + /* * The following callback funtions will be registered by * the code from HCD(eg: XHCI, EHCI...) emulation layer. @@ -137,6 +141,7 @@ struct usb_dev_sys_ctx_info { int usb_dev_sys_init(usb_dev_sys_cb conn_cb, usb_dev_sys_cb disconn_cb, usb_dev_sys_cb notify_cb, usb_dev_sys_cb intr_cb, void *hci_data, int log_level); +void usb_dev_sys_deinit(void); void *usb_dev_init(void *pdata, char *opt); void usb_dev_deinit(void *pdata); int usb_dev_info(void *pdata, int type, void *value, int size);