diff --git a/devicemodel/hw/pci/xhci.c b/devicemodel/hw/pci/xhci.c index 021fa16f6..0a426f36f 100755 --- a/devicemodel/hw/pci/xhci.c +++ b/devicemodel/hw/pci/xhci.c @@ -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; } diff --git a/devicemodel/hw/platform/usb_pmapper.c b/devicemodel/hw/platform/usb_pmapper.c index 13b67a057..899030186 100755 --- a/devicemodel/hw/platform/usb_pmapper.c +++ b/devicemodel/hw/platform/usb_pmapper.c @@ -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; diff --git a/devicemodel/hw/usb_core.c b/devicemodel/hw/usb_core.c index 4c3ea3f56..581267d66 100644 --- a/devicemodel/hw/usb_core.c +++ b/devicemodel/hw/usb_core.c @@ -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; +} diff --git a/devicemodel/include/usb_core.h b/devicemodel/include/usb_core.h index de7534d13..795073dc8 100644 --- a/devicemodel/include/usb_core.h +++ b/devicemodel/include/usb_core.h @@ -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_ */