mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-01 20:05:30 +00:00
DM USB: extend the API for struct usb_devemu
For the purpose of USB port mapper, change struct usb_devemu to common interface between HCD layer and USB device layer. Besides, implements ue_init/ue_deinit/ue_info for port mapper. Change-Id: Id4b7345c7b321b9bdab58139c61169d9229cb6f8 Signed-off-by: Wu, Xiaoguang <xiaoguang.wu@intel.com> Reviewed-by: Shuo Liu <shuo.a.liu@intel.com> Reviewed-by: Yu Wang <yu1.wang@intel.com> Reviewed-by: Zhao Yakui <yakui.zhao@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
1816d3e608
commit
aa0480f44e
@ -282,9 +282,16 @@ umouse_event(uint8_t button, int x, int y, void *arg)
|
||||
}
|
||||
|
||||
static void *
|
||||
umouse_init(struct usb_hci *hci, char *opt)
|
||||
umouse_init(void *pdata, char *opt)
|
||||
{
|
||||
struct umouse_vdev *dev;
|
||||
struct usb_hci *hci;
|
||||
|
||||
hci = pdata;
|
||||
if (!hci) {
|
||||
UPRINTF(LFTL, "umouse: invalid hci\r\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dev = calloc(1, sizeof(struct umouse_vdev));
|
||||
if (!dev) {
|
||||
|
@ -44,6 +44,181 @@
|
||||
|
||||
static struct usb_dev_sys_ctx_info g_ctx;
|
||||
|
||||
static int
|
||||
usb_dev_native_toggle_if_drivers(struct usb_dev *udev, int attach)
|
||||
{
|
||||
struct libusb_config_descriptor *config;
|
||||
uint8_t b, p, c, i;
|
||||
int rc = 0, r;
|
||||
|
||||
assert(udev);
|
||||
assert(udev->handle);
|
||||
assert(udev->ldev);
|
||||
assert(attach == 1 || attach == 0);
|
||||
|
||||
b = udev->bus;
|
||||
p = udev->port;
|
||||
|
||||
r = libusb_get_active_config_descriptor(udev->ldev, &config);
|
||||
if (r) {
|
||||
UPRINTF(LWRN, "%d-%d: can't get config\r\n", b, p);
|
||||
return -1;
|
||||
}
|
||||
|
||||
c = config->bConfigurationValue;
|
||||
for (i = 0; i < config->bNumInterfaces; i++) {
|
||||
if (attach == 1)
|
||||
r = libusb_attach_kernel_driver(udev->handle, i);
|
||||
else
|
||||
r = libusb_detach_kernel_driver(udev->handle, i);
|
||||
|
||||
if (r) {
|
||||
rc = -1;
|
||||
UPRINTF(LWRN, "%d-%d:%d.%d can't %stach if driver\r\n",
|
||||
b, p, c, i, attach == 1 ? "at" : "de");
|
||||
}
|
||||
}
|
||||
if (rc)
|
||||
UPRINTF(LWRN, "%d-%d fail to %s rc %d\r\n", b, p,
|
||||
attach == 1 ? "attach" : "detach", rc);
|
||||
libusb_free_config_descriptor(config);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void *
|
||||
usb_dev_init(void *pdata, char *opt)
|
||||
{
|
||||
struct usb_dev *udev = NULL;
|
||||
struct libusb_device *ldev;
|
||||
struct libusb_device_descriptor desc;
|
||||
uint8_t bus, port;
|
||||
int speed, ver;
|
||||
|
||||
assert(pdata);
|
||||
|
||||
ldev = pdata;
|
||||
speed = libusb_get_device_speed(ldev);
|
||||
port = libusb_get_port_number(ldev);
|
||||
bus = libusb_get_bus_number(ldev);
|
||||
libusb_get_device_descriptor(ldev, &desc);
|
||||
UPRINTF(LINF, "Found USB device: %d-%d\r\nPID(0x%X), VID(0x%X) "
|
||||
"CLASS(0x%X) SUBCLASS(0x%x) BCD(0x%x)\r\n", bus, port,
|
||||
desc.idProduct, desc.idVendor,
|
||||
desc.bDeviceClass, desc.bDeviceSubClass, desc.bcdUSB);
|
||||
|
||||
/* allocate and populate udev */
|
||||
udev = calloc(1, sizeof(struct usb_dev));
|
||||
if (!udev)
|
||||
goto errout;
|
||||
|
||||
/* this is a root hub */
|
||||
if (port == 0)
|
||||
goto errout;
|
||||
|
||||
switch (desc.bcdUSB) { /* TODO: implemnt USB3.0 */
|
||||
case 0x300:
|
||||
ver = 2; break;
|
||||
case 0x200:
|
||||
case 0x110:
|
||||
ver = 2; break;
|
||||
default:
|
||||
goto errout;
|
||||
}
|
||||
|
||||
udev->speed = speed;
|
||||
udev->ldev = ldev;
|
||||
udev->version = ver;
|
||||
udev->handle = NULL;
|
||||
udev->port = port;
|
||||
udev->bus = bus;
|
||||
udev->pid = desc.idProduct;
|
||||
udev->vid = desc.idVendor;
|
||||
|
||||
/* configure physical device through libusb library */
|
||||
if (libusb_open(udev->ldev, &udev->handle)) {
|
||||
UPRINTF(LWRN, "fail to open device.\r\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (usb_dev_native_toggle_if_drivers(udev, 0) < 0) {
|
||||
UPRINTF(LWRN, "fail to detach interface driver.\r\n");
|
||||
goto errout;
|
||||
}
|
||||
return udev;
|
||||
|
||||
errout:
|
||||
if (udev && udev->handle)
|
||||
libusb_close(udev->handle);
|
||||
|
||||
free(udev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
usb_dev_deinit(void *pdata)
|
||||
{
|
||||
int rc = 0;
|
||||
struct usb_dev *udev;
|
||||
|
||||
udev = pdata;
|
||||
if (udev) {
|
||||
if (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);
|
||||
}
|
||||
free(udev);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
usb_dev_info(void *pdata, int type, void *value, int size)
|
||||
{
|
||||
struct usb_dev *udev;
|
||||
int sz;
|
||||
void *pv;
|
||||
|
||||
udev = pdata;
|
||||
assert(udev);
|
||||
assert(value);
|
||||
|
||||
switch (type) {
|
||||
case USB_INFO_VERSION:
|
||||
sz = sizeof(udev->version);
|
||||
pv = &udev->version;
|
||||
break;
|
||||
case USB_INFO_SPEED:
|
||||
sz = sizeof(udev->speed);
|
||||
pv = &udev->speed;
|
||||
break;
|
||||
case USB_INFO_BUS:
|
||||
sz = sizeof(udev->bus);
|
||||
pv = &udev->bus;
|
||||
break;
|
||||
case USB_INFO_PORT:
|
||||
sz = sizeof(udev->port);
|
||||
pv = &udev->port;
|
||||
break;
|
||||
case USB_INFO_VID:
|
||||
sz = sizeof(udev->vid);
|
||||
pv = &udev->vid;
|
||||
break;
|
||||
case USB_INFO_PID:
|
||||
sz = sizeof(udev->pid);
|
||||
pv = &udev->pid;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (size == sz)
|
||||
memcpy(value, pv, sz);
|
||||
|
||||
return sz == size ? 0 : -1;
|
||||
}
|
||||
|
||||
static void *
|
||||
usb_dev_sys_thread(void *arg)
|
||||
{
|
||||
|
@ -49,15 +49,17 @@ struct usb_devemu {
|
||||
int ue_usbspeed; /* usb device speed */
|
||||
|
||||
/* instance creation */
|
||||
void *(*ue_init)(struct usb_hci *hci, char *opt);
|
||||
void *(*ue_init)(void *pdata, char *opt);
|
||||
|
||||
/* handlers */
|
||||
int (*ue_request)(void *sc, struct usb_data_xfer *xfer);
|
||||
int (*ue_data)(void *sc, struct usb_data_xfer *xfer, int dir,
|
||||
int epctx);
|
||||
int (*ue_info)(void *sc, int type, void *value, int size);
|
||||
int (*ue_reset)(void *sc);
|
||||
int (*ue_remove)(void *sc);
|
||||
int (*ue_stop)(void *sc);
|
||||
void (*ue_deinit)(void *pdata);
|
||||
};
|
||||
#define USB_EMUL_SET(x) DATA_SET(usb_emu_set, x)
|
||||
|
||||
|
@ -36,6 +36,15 @@
|
||||
#define USB_NUM_INTERFACE 16
|
||||
#define USB_NUM_ENDPOINT 15
|
||||
|
||||
enum {
|
||||
USB_INFO_VERSION,
|
||||
USB_INFO_SPEED,
|
||||
USB_INFO_BUS,
|
||||
USB_INFO_PORT,
|
||||
USB_INFO_VID,
|
||||
USB_INFO_PID
|
||||
};
|
||||
|
||||
struct usb_dev_ep {
|
||||
uint8_t pid;
|
||||
uint8_t type;
|
||||
@ -48,6 +57,9 @@ struct usb_dev {
|
||||
int speed;
|
||||
int configuration;
|
||||
uint8_t port;
|
||||
uint8_t bus;
|
||||
uint8_t pid;
|
||||
uint16_t vid;
|
||||
|
||||
/* interface info */
|
||||
int if_num;
|
||||
@ -91,5 +103,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_init(void *pdata, char *opt);
|
||||
void usb_dev_deinit(void *pdata);
|
||||
int usb_dev_info(void *pdata, int type, void *value, int size);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user