mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-07-07 04:19:10 +00:00
DM USB: introduce struct usb_devpath and releted functions
This patch introduce struct usb_devpath to indentify uniquely an USB device, which is basic element for multiple hub support. Tracked-On: #1434 Signed-off-by: Liang Yang <liang3.yang@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
14bc961f03
commit
e8f7b6fa74
@ -534,32 +534,32 @@ pci_xhci_native_usb_dev_conn_cb(void *hci_data, void *dev_data)
|
||||
di = dev_data;
|
||||
|
||||
/* print physical information about new device */
|
||||
UPRINTF(LDBG, "%04x:%04x %d-%d connecting.\r\n",
|
||||
di->vid, di->pid, di->bus, di->port);
|
||||
UPRINTF(LDBG, "%04x:%04x %d-%s connecting.\r\n", di->vid, di->pid,
|
||||
di->path.bus, usb_dev_path(&di->path));
|
||||
|
||||
if (VPORT_STATE(xdev->port_map_tbl[di->bus][di->port]) ==
|
||||
VPORT_FREE) {
|
||||
if (VPORT_STATE(xdev->port_map_tbl[di->path.bus]
|
||||
[ROOTHUB_PORT(di->path)]) == VPORT_FREE) {
|
||||
UPRINTF(LDBG, "%04x:%04x %d-%d doesn't belong to this"
|
||||
" vm, bye.\r\n", di->vid, di->pid,
|
||||
di->bus, di->port);
|
||||
di->path.bus, ROOTHUB_PORT(di->path));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
UPRINTF(LDBG, "%04x:%04x %d-%d belong to this vm.\r\n", di->vid,
|
||||
di->pid, di->bus, di->port);
|
||||
UPRINTF(LDBG, "%04x:%04x %d-%s belong to this vm.\r\n", di->vid,
|
||||
di->pid, di->path.bus, usb_dev_path(&di->path));
|
||||
|
||||
port = pci_xhci_get_free_rh_port(xdev, di);
|
||||
if (port < 0) {
|
||||
UPRINTF(LFTL, "no free virtual port for native device %d-%d"
|
||||
"\r\n", di->bus, di->port);
|
||||
UPRINTF(LFTL, "no free virtual port for native device %d-%s"
|
||||
"\r\n", di->path.bus, usb_dev_path(&di->path));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
UPRINTF(LDBG, "%04X:%04X %d-%d is attached to virtual port %d.\r\n",
|
||||
di->vid, di->pid, di->bus, di->port, port);
|
||||
UPRINTF(LDBG, "%04X:%04X %d-%s is attached to virtual port %d.\r\n",
|
||||
di->vid, di->pid, di->path.bus,
|
||||
usb_dev_path(&di->path), port);
|
||||
|
||||
xdev->native_dev_info[di->bus][di->port] = *di;
|
||||
xdev->port_map_tbl[di->bus][di->port] =
|
||||
xdev->native_dev_info[di->path.bus][ROOTHUB_PORT(di->path)] = *di;
|
||||
xdev->port_map_tbl[di->path.bus][ROOTHUB_PORT(di->path)] =
|
||||
VPORT_NUM_STATE(VPORT_CONNECTED, port);
|
||||
|
||||
/* TODO: should revisit in deeper level */
|
||||
@ -593,12 +593,13 @@ pci_xhci_native_usb_dev_disconn_cb(void *hci_data, void *dev_data)
|
||||
assert(xdev->devices);
|
||||
|
||||
di = *((struct usb_native_devinfo *)dev_data);
|
||||
if (!pci_xhci_is_valid_portnum(di.port)) {
|
||||
UPRINTF(LFTL, "invalid physical port %d\r\n", di.port);
|
||||
if (!pci_xhci_is_valid_portnum(ROOTHUB_PORT(di.path))) {
|
||||
UPRINTF(LFTL, "invalid physical port %d\r\n",
|
||||
ROOTHUB_PORT(di.path));
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = xdev->port_map_tbl[di.bus][di.port];
|
||||
status = xdev->port_map_tbl[di.path.bus][ROOTHUB_PORT(di.path)];
|
||||
|
||||
for (port = 1; port <= XHCI_MAX_DEVS; ++port) {
|
||||
edev = xdev->devices[port];
|
||||
@ -606,7 +607,7 @@ pci_xhci_native_usb_dev_disconn_cb(void *hci_data, void *dev_data)
|
||||
continue;
|
||||
|
||||
udev = edev->dev_instance;
|
||||
if (udev->info.port == di.port)
|
||||
if (ROOTHUB_PORT(udev->info.path) == ROOTHUB_PORT(di.path))
|
||||
break;
|
||||
}
|
||||
|
||||
@ -620,14 +621,17 @@ pci_xhci_native_usb_dev_disconn_cb(void *hci_data, void *dev_data)
|
||||
* cleared for future connecting.
|
||||
*/
|
||||
UPRINTF(LFTL, "disconnect VPORT_CONNECTED device: "
|
||||
"%d-%d vport %d\r\n", di.bus, di.port,
|
||||
"%d-%s vport %d\r\n", di.path.bus,
|
||||
usb_dev_path(&di.path),
|
||||
VPORT_NUM(status));
|
||||
|
||||
pci_xhci_disconnect_port(xdev, VPORT_NUM(status), 0);
|
||||
xdev->port_map_tbl[di.bus][di.port] = VPORT_NUM_STATE(
|
||||
VPORT_ASSIGNED, 0);
|
||||
xdev->port_map_tbl[di.path.bus][ROOTHUB_PORT(di.path)]
|
||||
= VPORT_NUM_STATE(VPORT_ASSIGNED, 0);
|
||||
}
|
||||
|
||||
UPRINTF(LFTL, "fail to find physical port %d\r\n", di.port);
|
||||
UPRINTF(LFTL, "fail to find physical port %d\r\n",
|
||||
ROOTHUB_PORT(di.path));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -638,8 +642,8 @@ pci_xhci_native_usb_dev_disconn_cb(void *hci_data, void *dev_data)
|
||||
assert(VPORT_STATE(status) == VPORT_EMULATED ||
|
||||
VPORT_STATE(status) == VPORT_CONNECTED);
|
||||
|
||||
xdev->port_map_tbl[di.bus][di.port] = VPORT_NUM_STATE(VPORT_ASSIGNED,
|
||||
0);
|
||||
xdev->port_map_tbl[di.path.bus][ROOTHUB_PORT(di.path)] =
|
||||
VPORT_NUM_STATE(VPORT_ASSIGNED, 0);
|
||||
|
||||
/* TODO: should revisit this in deeper level */
|
||||
if (vm_get_suspend_mode() != VM_SUSPEND_NONE) {
|
||||
@ -1539,11 +1543,12 @@ pci_xhci_cmd_disable_slot(struct pci_xhci_vdev *xdev, uint32_t slot)
|
||||
xdev->slot_allocated[slot] = false;
|
||||
|
||||
di = &udev->info;
|
||||
xdev->port_map_tbl[di->bus][di->port] =
|
||||
xdev->port_map_tbl[di->path.bus][ROOTHUB_PORT(di->path)] =
|
||||
VPORT_NUM_STATE(VPORT_ASSIGNED, 0);
|
||||
|
||||
UPRINTF(LINF, "disable slot %d for native device %d-%d"
|
||||
"\r\n", slot, di->bus, di->port);
|
||||
UPRINTF(LINF, "disable slot %d for native device %d-%s"
|
||||
"\r\n", slot, di->path.bus,
|
||||
usb_dev_path(&di->path));
|
||||
|
||||
pci_xhci_dev_destroy(dev);
|
||||
} else
|
||||
@ -1662,13 +1667,15 @@ pci_xhci_cmd_address_device(struct pci_xhci_vdev *xdev,
|
||||
goto done;
|
||||
}
|
||||
|
||||
UPRINTF(LDBG, "create virtual device for %d-%d on virtual "
|
||||
"port %d\r\n", di->bus, di->port, rh_port);
|
||||
UPRINTF(LDBG, "create virtual device for %d-%s on virtual "
|
||||
"port %d\r\n", di->path.bus,
|
||||
usb_dev_path(&di->path), rh_port);
|
||||
|
||||
dev = pci_xhci_dev_create(xdev, di);
|
||||
if (!dev) {
|
||||
UPRINTF(LFTL, "fail to create device for %d-%d\r\n",
|
||||
di->bus, di->port);
|
||||
UPRINTF(LFTL, "fail to create device for %d-%s\r\n",
|
||||
di->path.bus,
|
||||
usb_dev_path(&di->path));
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -42,14 +42,15 @@ usb_dev_scan_dev()
|
||||
ldev = devlist[i];
|
||||
|
||||
memset(&di, 0, sizeof(di));
|
||||
di.bus = libusb_get_bus_number(ldev);
|
||||
di.port = libusb_get_port_number(ldev);
|
||||
di.path.bus = libusb_get_bus_number(ldev);
|
||||
di.path.depth = libusb_get_port_numbers(ldev, di.path.path,
|
||||
USB_MAX_TIERS);
|
||||
di.speed = libusb_get_device_speed(ldev);
|
||||
|
||||
rc = libusb_get_device_descriptor(ldev, &d);
|
||||
if (rc) {
|
||||
UPRINTF(LWRN, "fail to get descriptor for %d-%d\r\n",
|
||||
di.bus, di.port);
|
||||
UPRINTF(LWRN, "fail to get descriptor for %d-%s\r\n",
|
||||
di.path.bus, usb_dev_path(&di.path));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -58,7 +59,7 @@ usb_dev_scan_dev()
|
||||
di.bcd = d.bcdUSB;
|
||||
di.priv_data = ldev;
|
||||
|
||||
if (di.port == 0)
|
||||
if (ROOTHUB_PORT(di.path) == 0)
|
||||
continue;
|
||||
if (d.bDeviceClass == LIBUSB_CLASS_HUB)
|
||||
continue;
|
||||
@ -453,19 +454,19 @@ static int
|
||||
usb_dev_native_toggle_if(struct usb_dev *udev, int claim)
|
||||
{
|
||||
struct libusb_config_descriptor *config;
|
||||
uint8_t b, p, c, i;
|
||||
struct usb_devpath *path;
|
||||
uint8_t c, i;
|
||||
int rc = 0, r;
|
||||
|
||||
assert(udev);
|
||||
assert(udev->handle);
|
||||
assert(claim == 1 || claim == 0);
|
||||
|
||||
b = udev->info.bus;
|
||||
p = udev->info.port;
|
||||
|
||||
path = &udev->info.path;
|
||||
r = libusb_get_active_config_descriptor(udev->info.priv_data, &config);
|
||||
if (r) {
|
||||
UPRINTF(LWRN, "%d-%d: can't get config\r\n", b, p);
|
||||
UPRINTF(LWRN, "%d-%s: can't get config\r\n", path->bus,
|
||||
usb_dev_path(path));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -485,14 +486,16 @@ usb_dev_native_toggle_if(struct usb_dev *udev, int claim)
|
||||
}
|
||||
if (r) {
|
||||
rc = -1;
|
||||
UPRINTF(LWRN, "%d-%d:%d.%d can't %s if, r %d\r\n", b,
|
||||
p, c, i, claim == 1 ? "claim" :
|
||||
"release", r);
|
||||
UPRINTF(LWRN, "%d-%s:%d.%d can't %s if, r %d\r\n",
|
||||
path->bus, usb_dev_path(path), c, i,
|
||||
claim == 1 ? "claim" : "release", r);
|
||||
}
|
||||
}
|
||||
if (rc)
|
||||
UPRINTF(LWRN, "%d-%d fail to %s rc %d\r\n", b, p,
|
||||
claim == 1 ? "claim" : "release", rc);
|
||||
UPRINTF(LWRN, "%d-%s fail to %s rc %d\r\n", path->bus,
|
||||
usb_dev_path(path), claim == 1 ? "claim" :
|
||||
"release", rc);
|
||||
|
||||
libusb_free_config_descriptor(config);
|
||||
return rc;
|
||||
}
|
||||
@ -501,19 +504,19 @@ 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;
|
||||
struct usb_devpath *path;
|
||||
uint8_t c, i;
|
||||
int rc = 0, r;
|
||||
|
||||
assert(udev);
|
||||
assert(udev->handle);
|
||||
assert(attach == 1 || attach == 0);
|
||||
|
||||
b = udev->info.bus;
|
||||
p = udev->info.port;
|
||||
|
||||
path = &udev->info.path;
|
||||
r = libusb_get_active_config_descriptor(udev->info.priv_data, &config);
|
||||
if (r) {
|
||||
UPRINTF(LWRN, "%d-%d: can't get config\r\n", b, p);
|
||||
UPRINTF(LWRN, "%d-%s: can't get config\r\n", path->bus,
|
||||
usb_dev_path(path));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -531,14 +534,16 @@ usb_dev_native_toggle_if_drivers(struct usb_dev *udev, int attach)
|
||||
|
||||
if (r) {
|
||||
rc = -1;
|
||||
UPRINTF(LWRN, "%d-%d:%d.%d can't %stach if driver, r %d"
|
||||
"\r\n", b, p, c, i, attach == 1 ? "at" :
|
||||
"de", r);
|
||||
UPRINTF(LWRN, "%d-%s:%d.%d can't %stach if driver, r %d"
|
||||
"\r\n", path->bus, usb_dev_path(path),
|
||||
c, i, attach == 1 ? "at" : "de", r);
|
||||
}
|
||||
}
|
||||
if (rc)
|
||||
UPRINTF(LWRN, "%d-%d fail to %s rc %d\r\n", b, p,
|
||||
attach == 1 ? "attach" : "detach", rc);
|
||||
UPRINTF(LWRN, "%d-%s fail to %s rc %d\r\n", path->bus,
|
||||
usb_dev_path(path), attach == 1 ? "attach" :
|
||||
"detach", rc);
|
||||
|
||||
libusb_free_config_descriptor(config);
|
||||
return rc;
|
||||
}
|
||||
@ -591,8 +596,8 @@ err1:
|
||||
usb_dev_native_toggle_if(udev, 0);
|
||||
libusb_free_config_descriptor(cfg);
|
||||
err2:
|
||||
UPRINTF(LWRN, "%d-%d: fail to set config\r\n", udev->info.bus,
|
||||
udev->info.port);
|
||||
UPRINTF(LWRN, "%d-%s: fail to set config\r\n", udev->info.path.bus,
|
||||
usb_dev_path(&udev->info.path));
|
||||
xfer->status = USB_ERR_STALLED;
|
||||
}
|
||||
|
||||
@ -607,8 +612,8 @@ usb_dev_set_if(struct usb_dev *udev, int iface, int alt, struct usb_data_xfer
|
||||
if (iface >= USB_NUM_INTERFACE)
|
||||
goto errout;
|
||||
|
||||
UPRINTF(LDBG, "%d-%d set if, iface %d alt %d\r\n", udev->info.bus,
|
||||
udev->info.port, iface, alt);
|
||||
UPRINTF(LDBG, "%d-%s set if, iface %d alt %d\r\n", udev->info.path.bus,
|
||||
usb_dev_path(&udev->info.path), iface, alt);
|
||||
|
||||
if (libusb_set_interface_alt_setting(udev->handle, iface, alt))
|
||||
goto errout;
|
||||
@ -624,8 +629,11 @@ usb_dev_set_if(struct usb_dev *udev, int iface, int alt, struct usb_data_xfer
|
||||
|
||||
errout:
|
||||
xfer->status = USB_ERR_STALLED;
|
||||
UPRINTF(LDBG, "%d-%d fail to set if, iface %d alt %d\r\n",
|
||||
udev->info.bus, udev->info.port, iface, alt);
|
||||
UPRINTF(LDBG, "%d-%s fail to set if, iface %d alt %d\r\n",
|
||||
udev->info.path.bus,
|
||||
usb_dev_path(&udev->info.path),
|
||||
iface,
|
||||
alt);
|
||||
}
|
||||
|
||||
static struct usb_data_xfer_block *
|
||||
@ -916,10 +924,11 @@ usb_dev_init(void *pdata, char *opt)
|
||||
|
||||
di = pdata;
|
||||
libusb_get_device_descriptor(di->priv_data, &desc);
|
||||
UPRINTF(LINF, "Found USB device: %d-%d\r\nPID(0x%X), VID(0x%X) CLASS"
|
||||
UPRINTF(LINF, "Found USB device: %d-%s\r\nPID(0x%X), VID(0x%X) CLASS"
|
||||
"(0x%X) SUBCLASS(0x%X) BCD(0x%X) SPEED(%d)\r\n",
|
||||
di->bus, di->port, di->pid, di->vid, desc.bDeviceClass,
|
||||
desc.bDeviceSubClass, di->bcd, di->speed);
|
||||
di->path.bus, usb_dev_path(&di->path), di->pid,
|
||||
di->vid, desc.bDeviceClass, desc.bDeviceSubClass,
|
||||
di->bcd, di->speed);
|
||||
|
||||
/* allocate and populate udev */
|
||||
udev = calloc(1, sizeof(struct usb_dev));
|
||||
@ -927,7 +936,7 @@ usb_dev_init(void *pdata, char *opt)
|
||||
goto errout;
|
||||
|
||||
/* this is a root hub */
|
||||
if (di->port == 0)
|
||||
if (ROOTHUB_PORT(di->path) == 0)
|
||||
goto errout;
|
||||
|
||||
switch (desc.bcdUSB) {
|
||||
@ -1016,12 +1025,12 @@ usb_dev_info(void *pdata, int type, void *value, int size)
|
||||
pv = &udev->info.speed;
|
||||
break;
|
||||
case USB_INFO_BUS:
|
||||
sz = sizeof(udev->info.bus);
|
||||
pv = &udev->info.bus;
|
||||
sz = sizeof(udev->info.path.bus);
|
||||
pv = &udev->info.path.bus;
|
||||
break;
|
||||
case USB_INFO_PORT:
|
||||
sz = sizeof(udev->info.port);
|
||||
pv = &udev->info.port;
|
||||
sz = sizeof(udev->info.path.path[0]);
|
||||
pv = &udev->info.path.path[0];
|
||||
break;
|
||||
case USB_INFO_VID:
|
||||
sz = sizeof(udev->info.vid);
|
||||
@ -1069,9 +1078,10 @@ usb_dev_native_sys_conn_cb(struct libusb_context *ctx, struct libusb_device
|
||||
}
|
||||
|
||||
libusb_get_device_descriptor(ldev, &d);
|
||||
di.bus = libusb_get_bus_number(ldev);
|
||||
di.path.bus = libusb_get_bus_number(ldev);
|
||||
di.path.depth = libusb_get_port_numbers(ldev, di.path.path,
|
||||
USB_MAX_TIERS);
|
||||
di.speed = libusb_get_device_speed(ldev);
|
||||
di.port = libusb_get_port_number(ldev);
|
||||
di.pid = d.idProduct;
|
||||
di.vid = d.idVendor;
|
||||
di.bcd = d.bcdUSB;
|
||||
@ -1101,11 +1111,11 @@ usb_dev_native_sys_disconn_cb(struct libusb_context *ctx, struct libusb_device
|
||||
}
|
||||
|
||||
libusb_get_device_descriptor(ldev, &d);
|
||||
di.bus = libusb_get_bus_number(ldev);
|
||||
di.path.bus = libusb_get_bus_number(ldev);
|
||||
di.speed = libusb_get_device_speed(ldev);
|
||||
di.path.depth = libusb_get_port_numbers(ldev, di.path.path,
|
||||
USB_MAX_TIERS);
|
||||
|
||||
/* FIXME: * should use libusb_get_port_numbers here */
|
||||
di.port = libusb_get_port_number(ldev);
|
||||
di.pid = d.idProduct;
|
||||
di.vid = d.idVendor;
|
||||
di.bcd = d.bcdUSB;
|
||||
|
@ -243,3 +243,24 @@ void usb_parse_log_level(char level)
|
||||
usb_set_log_level(LFTL);
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
usb_dev_path(struct usb_devpath *path)
|
||||
{
|
||||
static char output[sizeof("01.02.03.04.05.06.07")+1];
|
||||
int i, r, n;
|
||||
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
r = n = sizeof(output);
|
||||
r -= snprintf(output, n, "%d", path->path[0]);
|
||||
|
||||
for (i = 1; i < path->depth; i++) {
|
||||
r -= snprintf(output + n - r, r, ".%d", path->path[i]);
|
||||
if (r < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
@ -84,6 +84,8 @@ enum usb_xfer_blk_stat {
|
||||
USB_XFER_BLK_HANDLED
|
||||
};
|
||||
|
||||
#define USB_MAX_TIERS 7
|
||||
|
||||
struct usb_hci;
|
||||
struct usb_device_request;
|
||||
struct usb_data_xfer;
|
||||
@ -163,13 +165,19 @@ struct usb_data_xfer {
|
||||
pthread_mutex_t mtx;
|
||||
};
|
||||
|
||||
struct usb_devpath {
|
||||
uint8_t bus;
|
||||
uint8_t depth;
|
||||
uint8_t path[USB_MAX_TIERS];
|
||||
};
|
||||
#define ROOTHUB_PORT(x) ((x).path[0])
|
||||
|
||||
struct usb_native_devinfo {
|
||||
int speed;
|
||||
uint8_t bus;
|
||||
uint8_t port;
|
||||
uint16_t bcd;
|
||||
uint16_t pid;
|
||||
uint16_t vid;
|
||||
struct usb_devpath path;
|
||||
void *priv_data;
|
||||
};
|
||||
|
||||
@ -239,5 +247,5 @@ struct usb_data_xfer_block *usb_data_xfer_append(struct usb_data_xfer *xfer,
|
||||
int blen,
|
||||
void *hci_data,
|
||||
int ccs);
|
||||
|
||||
char *usb_dev_path(struct usb_devpath *path);
|
||||
#endif /* _USB_CORE_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user