mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-24 06:29:19 +00:00
DM USB: xHCI: refine the de-init logic of xHCI vdevice
Add 'full' and 'non-full' de-initialize support for xHCI virtual device. The non-full de-initialization mainly release usb_dev structure and unbind the usbfs with native device. And the full de-initialize will release all the resources allocated for xHCI virtual device including the unbinding operation mentioned above Tracked-On: #2576 Signed-off-by: Conghui Chen <conghui.chen@intel.com> Signed-off-by: Xiaoguang Wu <xiaoguang.wu@intel.com> Acked-by: Yu Wang <yu1.wang@intel.com>
This commit is contained in:
parent
76a5131b37
commit
b77755cd58
@ -489,7 +489,7 @@ static int pci_xhci_disconnect_port(struct pci_xhci_vdev *xdev, int port,
|
|||||||
int need_intr);
|
int need_intr);
|
||||||
static struct pci_xhci_dev_emu *pci_xhci_dev_create(struct pci_xhci_vdev *
|
static struct pci_xhci_dev_emu *pci_xhci_dev_create(struct pci_xhci_vdev *
|
||||||
xdev, void *dev_data);
|
xdev, void *dev_data);
|
||||||
static void pci_xhci_dev_destroy(struct pci_xhci_dev_emu *de);
|
static void pci_xhci_dev_destroy(struct pci_xhci_dev_emu *de, bool full);
|
||||||
static void pci_xhci_set_evtrb(struct xhci_trb *evtrb, uint64_t port,
|
static void pci_xhci_set_evtrb(struct xhci_trb *evtrb, uint64_t port,
|
||||||
uint32_t errcode, uint32_t evtype);
|
uint32_t errcode, uint32_t evtype);
|
||||||
static int pci_xhci_xfer_complete(struct pci_xhci_vdev *xdev,
|
static int pci_xhci_xfer_complete(struct pci_xhci_vdev *xdev,
|
||||||
@ -1072,7 +1072,7 @@ pci_xhci_dev_create(struct pci_xhci_vdev *xdev, void *dev_data)
|
|||||||
|
|
||||||
errout:
|
errout:
|
||||||
if (ud)
|
if (ud)
|
||||||
ue->ue_deinit(ud);
|
ue->ue_deinit(ud, true);
|
||||||
|
|
||||||
free(ue);
|
free(ue);
|
||||||
free(de);
|
free(de);
|
||||||
@ -1080,28 +1080,42 @@ errout:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pci_xhci_dev_destroy(struct pci_xhci_dev_emu *de)
|
pci_xhci_dev_destroy(struct pci_xhci_dev_emu *de, bool full)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* When full == false, it means the destroy operation is partial and
|
||||||
|
* the pci_xhci_dev_emu is not released. Except that, the partial
|
||||||
|
* destroy also unbind the usbfs with the native USB device.
|
||||||
|
* When full == true, this function will release all the resources
|
||||||
|
* and do the unbind operation mentioned above.
|
||||||
|
*/
|
||||||
struct usb_devemu *ue;
|
struct usb_devemu *ue;
|
||||||
struct usb_dev *ud;
|
struct usb_dev *ud;
|
||||||
|
|
||||||
if (de) {
|
if (!de)
|
||||||
ue = de->dev_ue;
|
return;
|
||||||
ud = de->dev_instance;
|
|
||||||
if (ue) {
|
|
||||||
if (ue->ue_devtype == USB_DEV_PORT_MAPPER) {
|
|
||||||
assert(ue->ue_deinit);
|
|
||||||
if (ue->ue_deinit)
|
|
||||||
ue->ue_deinit(ud);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ue->ue_devtype == USB_DEV_PORT_MAPPER)
|
/* FIXME: will merge usb_dev and usb_devemu into one data structure */
|
||||||
free(ue);
|
ue = de->dev_ue;
|
||||||
|
ud = de->dev_instance;
|
||||||
|
if (ue) {
|
||||||
|
if (ue->ue_devtype == USB_DEV_PORT_MAPPER) {
|
||||||
|
|
||||||
free(de);
|
assert(ue->ue_deinit);
|
||||||
|
ue->ue_deinit(ud, full);
|
||||||
|
|
||||||
|
if (full)
|
||||||
|
de->dev_instance = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ue && ue->ue_devtype == USB_DEV_PORT_MAPPER && full) {
|
||||||
|
free(ue);
|
||||||
|
de->dev_ue = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (full)
|
||||||
|
free(de);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
@ -1857,7 +1871,7 @@ pci_xhci_cmd_disable_slot(struct pci_xhci_vdev *xdev, uint32_t slot)
|
|||||||
slot, di->path.bus, usb_dev_path(&di->path));
|
slot, di->path.bus, usb_dev_path(&di->path));
|
||||||
|
|
||||||
/* release all the resource allocated for virtual device */
|
/* release all the resource allocated for virtual device */
|
||||||
pci_xhci_dev_destroy(dev);
|
pci_xhci_dev_destroy(dev, true);
|
||||||
} else
|
} else
|
||||||
UPRINTF(LWRN, "invalid slot %d\r\n", slot);
|
UPRINTF(LWRN, "invalid slot %d\r\n", slot);
|
||||||
|
|
||||||
@ -4233,7 +4247,7 @@ pci_xhci_deinit(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
|
|||||||
de = xdev->devices[i];
|
de = xdev->devices[i];
|
||||||
if (de) {
|
if (de) {
|
||||||
xdev->devices[i] = NULL;
|
xdev->devices[i] = NULL;
|
||||||
pci_xhci_dev_destroy(de);
|
pci_xhci_dev_destroy(de, true);
|
||||||
xdev->ndevices--;
|
xdev->ndevices--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1054,22 +1054,27 @@ errout:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
usb_dev_deinit(void *pdata)
|
usb_dev_deinit(void *pdata, bool full)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct usb_dev *udev;
|
struct usb_dev *udev;
|
||||||
|
|
||||||
udev = pdata;
|
udev = pdata;
|
||||||
if (udev) {
|
if (!udev)
|
||||||
if (udev->handle) {
|
return;
|
||||||
rc = usb_dev_native_toggle_if_drivers(udev, 1);
|
|
||||||
if (rc)
|
if (!udev->handle)
|
||||||
UPRINTF(LWRN, "fail to attach if drv rc:%d\r\n",
|
goto out;
|
||||||
rc);
|
|
||||||
libusb_close(udev->handle);
|
rc = usb_dev_native_toggle_if_drivers(udev, 1);
|
||||||
}
|
if (rc)
|
||||||
|
UPRINTF(LWRN, "fail to attach if drv rc:%d\r\n", rc);
|
||||||
|
|
||||||
|
libusb_close(udev->handle);
|
||||||
|
udev->handle = NULL;
|
||||||
|
out:
|
||||||
|
if (full)
|
||||||
free(udev);
|
free(udev);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -116,7 +116,7 @@ struct usb_devemu {
|
|||||||
int (*ue_reset)(void *sc);
|
int (*ue_reset)(void *sc);
|
||||||
int (*ue_remove)(void *sc);
|
int (*ue_remove)(void *sc);
|
||||||
int (*ue_stop)(void *sc);
|
int (*ue_stop)(void *sc);
|
||||||
void (*ue_deinit)(void *pdata);
|
void (*ue_deinit)(void *pdata, bool full);
|
||||||
};
|
};
|
||||||
#define USB_EMUL_SET(x) DATA_SET(usb_emu_set, x)
|
#define USB_EMUL_SET(x) DATA_SET(usb_emu_set, x)
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ int usb_dev_sys_init(usb_dev_sys_cb conn_cb, usb_dev_sys_cb disconn_cb,
|
|||||||
void *hci_data, int log_level);
|
void *hci_data, int log_level);
|
||||||
void usb_dev_sys_deinit(void);
|
void usb_dev_sys_deinit(void);
|
||||||
void *usb_dev_init(void *pdata, char *opt);
|
void *usb_dev_init(void *pdata, char *opt);
|
||||||
void usb_dev_deinit(void *pdata);
|
void usb_dev_deinit(void *pdata, bool full);
|
||||||
int usb_dev_info(void *pdata, int type, void *value, int size);
|
int usb_dev_info(void *pdata, int type, void *value, int size);
|
||||||
int usb_dev_request(void *pdata, struct usb_data_xfer *xfer);
|
int usb_dev_request(void *pdata, struct usb_data_xfer *xfer);
|
||||||
int usb_dev_reset(void *pdata);
|
int usb_dev_reset(void *pdata);
|
||||||
|
Loading…
Reference in New Issue
Block a user