diff --git a/core/usbh_core.c b/core/usbh_core.c index 4d4f47df..211636de 100644 --- a/core/usbh_core.c +++ b/core/usbh_core.c @@ -269,60 +269,6 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config return 0; } -static void usbh_print_hubport_info(struct usbh_hubport *hport) -{ - USB_LOG_RAW("Device Descriptor:\r\n"); - USB_LOG_RAW("bLength: 0x%02x \r\n", hport->device_desc.bLength); - USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", hport->device_desc.bDescriptorType); - USB_LOG_RAW("bcdUSB: 0x%04x \r\n", hport->device_desc.bcdUSB); - USB_LOG_RAW("bDeviceClass: 0x%02x \r\n", hport->device_desc.bDeviceClass); - USB_LOG_RAW("bDeviceSubClass: 0x%02x \r\n", hport->device_desc.bDeviceSubClass); - USB_LOG_RAW("bDeviceProtocol: 0x%02x \r\n", hport->device_desc.bDeviceProtocol); - USB_LOG_RAW("bMaxPacketSize0: 0x%02x \r\n", hport->device_desc.bMaxPacketSize0); - USB_LOG_RAW("idVendor: 0x%04x \r\n", hport->device_desc.idVendor); - USB_LOG_RAW("idProduct: 0x%04x \r\n", hport->device_desc.idProduct); - USB_LOG_RAW("bcdDevice: 0x%04x \r\n", hport->device_desc.bcdDevice); - USB_LOG_RAW("iManufacturer: 0x%02x \r\n", hport->device_desc.iManufacturer); - USB_LOG_RAW("iProduct: 0x%02x \r\n", hport->device_desc.iProduct); - USB_LOG_RAW("iSerialNumber: 0x%02x \r\n", hport->device_desc.iSerialNumber); - USB_LOG_RAW("bNumConfigurations: 0x%02x\r\n", hport->device_desc.bNumConfigurations); - - USB_LOG_RAW("Config Descriptor:\r\n"); - USB_LOG_RAW("bLength: 0x%02x \r\n", hport->config.config_desc.bLength); - USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", hport->config.config_desc.bDescriptorType); - USB_LOG_RAW("wTotalLength: 0x%04x \r\n", hport->config.config_desc.wTotalLength); - USB_LOG_RAW("bNumInterfaces: 0x%02x \r\n", hport->config.config_desc.bNumInterfaces); - USB_LOG_RAW("bConfigurationValue: 0x%02x \r\n", hport->config.config_desc.bConfigurationValue); - USB_LOG_RAW("iConfiguration: 0x%02x \r\n", hport->config.config_desc.iConfiguration); - USB_LOG_RAW("bmAttributes: 0x%02x \r\n", hport->config.config_desc.bmAttributes); - USB_LOG_RAW("bMaxPower: 0x%02x \r\n", hport->config.config_desc.bMaxPower); - - for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) { - for (uint8_t j = 0; j < hport->config.intf[i].altsetting_num; j++) { - USB_LOG_RAW("\tInterface Descriptor:\r\n"); - USB_LOG_RAW("\tbLength: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bLength); - USB_LOG_RAW("\tbDescriptorType: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bDescriptorType); - USB_LOG_RAW("\tbInterfaceNumber: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceNumber); - USB_LOG_RAW("\tbAlternateSetting: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bAlternateSetting); - USB_LOG_RAW("\tbNumEndpoints: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints); - USB_LOG_RAW("\tbInterfaceClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceClass); - USB_LOG_RAW("\tbInterfaceSubClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceSubClass); - USB_LOG_RAW("\tbInterfaceProtocol: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceProtocol); - USB_LOG_RAW("\tiInterface: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.iInterface); - - for (uint8_t k = 0; k < hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints; k++) { - USB_LOG_RAW("\t\tEndpoint Descriptor:\r\n"); - USB_LOG_RAW("\t\tbLength: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bLength); - USB_LOG_RAW("\t\tbDescriptorType: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bDescriptorType); - USB_LOG_RAW("\t\tbEndpointAddress: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bEndpointAddress); - USB_LOG_RAW("\t\tbmAttributes: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bmAttributes); - USB_LOG_RAW("\t\twMaxPacketSize: 0x%04x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.wMaxPacketSize); - USB_LOG_RAW("\t\tbInterval: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bInterval); - } - } - } -} - static void usbh_print_setup(struct usb_setup_packet *setup) { (void)setup; @@ -820,73 +766,6 @@ static void *usbh_list_all_interface_name(struct usbh_hub *hub, const char *devn return NULL; } -static void usbh_list_all_interface_driver(struct usbh_hub *hub) -{ - struct usbh_hubport *hport; - struct usbh_hub *hub_next; - const char *speed_table[] = { "error-speed", "low-speed", "full-speed", "high-speed", "wireless-speed", "super-speed", "superplus-speed" }; - - for (uint8_t port = 0; port < hub->nports; port++) { - hport = &hub->child[port]; - if (hport->connected) { - for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) { - if (hport->config.intf[itf].class_driver && hport->config.intf[itf].class_driver->driver_name) { - for (uint8_t j = 0; j < hub->index; j++) { - USB_LOG_RAW("\t"); - } - - USB_LOG_RAW("|__Port %u, dev addr:0x%02x, If %u, ClassDriver=%s, %s\r\n", - hport->port, - hport->dev_addr, - itf, - hport->config.intf[itf].class_driver->driver_name, - speed_table[hport->speed]); - - if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) { - hub_next = hport->config.intf[itf].priv; - - if (hub_next && hub_next->connected) { - usbh_list_all_interface_driver(hub_next); - } - } - } - } - } - } -} - -static void usbh_list_all_interface_desc(struct usbh_bus *bus, struct usbh_hub *hub) -{ - struct usbh_hubport *hport; - struct usbh_hub *hub_next; - - for (uint8_t port = 0; port < hub->nports; port++) { - hport = &hub->child[port]; - if (hport->connected) { - USB_LOG_RAW("\r\nBus %u, Hub %u, Port %u, dev addr:0x%02x, VID:PID 0x%04x:0x%04x\r\n", - bus->busid, - hub->index, - hport->port, - hport->dev_addr, - hport->device_desc.idVendor, - hport->device_desc.idProduct); - usbh_print_hubport_info(hport); - - for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) { - if (hport->config.intf[itf].class_driver && hport->config.intf[itf].class_driver->driver_name) { - if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) { - hub_next = hport->config.intf[itf].priv; - - if (hub_next && hub_next->connected) { - usbh_list_all_interface_desc(bus, hub_next); - } - } - } - } - } - } -} - static struct usbh_hubport *usbh_list_all_hubport(struct usbh_hub *hub, uint8_t hub_index, uint8_t hub_port) { struct usbh_hubport *hport; @@ -964,64 +843,341 @@ struct usbh_hubport *usbh_find_hubport(uint8_t busid, uint8_t hub_index, uint8_t return hport; } +static void usbh_print_hubport_info(struct usbh_hubport *hport) +{ + USB_LOG_RAW("Device Descriptor:\r\n"); + USB_LOG_RAW("bLength: 0x%02x \r\n", hport->device_desc.bLength); + USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", hport->device_desc.bDescriptorType); + USB_LOG_RAW("bcdUSB: 0x%04x \r\n", hport->device_desc.bcdUSB); + USB_LOG_RAW("bDeviceClass: 0x%02x \r\n", hport->device_desc.bDeviceClass); + USB_LOG_RAW("bDeviceSubClass: 0x%02x \r\n", hport->device_desc.bDeviceSubClass); + USB_LOG_RAW("bDeviceProtocol: 0x%02x \r\n", hport->device_desc.bDeviceProtocol); + USB_LOG_RAW("bMaxPacketSize0: 0x%02x \r\n", hport->device_desc.bMaxPacketSize0); + USB_LOG_RAW("idVendor: 0x%04x \r\n", hport->device_desc.idVendor); + USB_LOG_RAW("idProduct: 0x%04x \r\n", hport->device_desc.idProduct); + USB_LOG_RAW("bcdDevice: 0x%04x \r\n", hport->device_desc.bcdDevice); + USB_LOG_RAW("iManufacturer: 0x%02x \r\n", hport->device_desc.iManufacturer); + USB_LOG_RAW("iProduct: 0x%02x \r\n", hport->device_desc.iProduct); + USB_LOG_RAW("iSerialNumber: 0x%02x \r\n", hport->device_desc.iSerialNumber); + USB_LOG_RAW("bNumConfigurations: 0x%02x\r\n", hport->device_desc.bNumConfigurations); + + USB_LOG_RAW("Config Descriptor:\r\n"); + USB_LOG_RAW("bLength: 0x%02x \r\n", hport->config.config_desc.bLength); + USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", hport->config.config_desc.bDescriptorType); + USB_LOG_RAW("wTotalLength: 0x%04x \r\n", hport->config.config_desc.wTotalLength); + USB_LOG_RAW("bNumInterfaces: 0x%02x \r\n", hport->config.config_desc.bNumInterfaces); + USB_LOG_RAW("bConfigurationValue: 0x%02x \r\n", hport->config.config_desc.bConfigurationValue); + USB_LOG_RAW("iConfiguration: 0x%02x \r\n", hport->config.config_desc.iConfiguration); + USB_LOG_RAW("bmAttributes: 0x%02x \r\n", hport->config.config_desc.bmAttributes); + USB_LOG_RAW("bMaxPower: 0x%02x \r\n", hport->config.config_desc.bMaxPower); + + for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) { + for (uint8_t j = 0; j < hport->config.intf[i].altsetting_num; j++) { + USB_LOG_RAW("\tInterface Descriptor:\r\n"); + USB_LOG_RAW("\tbLength: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bLength); + USB_LOG_RAW("\tbDescriptorType: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bDescriptorType); + USB_LOG_RAW("\tbInterfaceNumber: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceNumber); + USB_LOG_RAW("\tbAlternateSetting: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bAlternateSetting); + USB_LOG_RAW("\tbNumEndpoints: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints); + USB_LOG_RAW("\tbInterfaceClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceClass); + USB_LOG_RAW("\tbInterfaceSubClass: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceSubClass); + USB_LOG_RAW("\tbInterfaceProtocol: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.bInterfaceProtocol); + USB_LOG_RAW("\tiInterface: 0x%02x \r\n", hport->config.intf[i].altsetting[j].intf_desc.iInterface); + + for (uint8_t k = 0; k < hport->config.intf[i].altsetting[j].intf_desc.bNumEndpoints; k++) { + USB_LOG_RAW("\t\tEndpoint Descriptor:\r\n"); + USB_LOG_RAW("\t\tbLength: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bLength); + USB_LOG_RAW("\t\tbDescriptorType: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bDescriptorType); + USB_LOG_RAW("\t\tbEndpointAddress: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bEndpointAddress); + USB_LOG_RAW("\t\tbmAttributes: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bmAttributes); + USB_LOG_RAW("\t\twMaxPacketSize: 0x%04x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.wMaxPacketSize); + USB_LOG_RAW("\t\tbInterval: 0x%02x \r\n", hport->config.intf[i].altsetting[j].ep[k].ep_desc.bInterval); + } + } + } +} + +static void usbh_list_device(struct usbh_hub *hub, bool astree, bool verbose, int dev_addr, int vid, int pid) +{ + static const char *speed_table[] = { + "UNKNOWN", + "low-speed", + "full-speed", + "high-speed", + "wireless", + "super-speed", + "super-speed-plus", + }; + + static const char *root_speed_table[] = { + "UNKNOWN", + "1.1", + "1.1", + "2.0", + "2.5", + "3.0", + "3.0", + }; + + static const uint16_t speed_baud[] = { + 0, + 12, + 12, + 480, + 480, + 5000, + 10000, + }; + + struct usbh_bus *bus; + struct usbh_hubport *hport; + struct usbh_hub *hub_next; + + uint8_t imbuf[64]; + uint8_t ipbuf[64]; + + const char *pimstr; + const char *pipstr; + + bool imvalid = false; + bool ipvalid = false; + + int ret; + + bus = hub->bus; + + (void)speed_table; + + if (hub->is_roothub) { + if (astree) { + USB_LOG_RAW("/: Bus %02u.Port 1: Dev %u, Class=root_hub, Driver=hcd, %uM\r\n", + bus->busid, hub->hub_addr, speed_baud[hub->speed]); + + } else { + if ((dev_addr < 0) || (hub->hub_addr == dev_addr)) { + if (((vid < 0) || (vid == 0xffff)) && ((pid < 0) || (pid == 0xffff))) { + USB_LOG_RAW("Bus %03u Device %03u: ID %04x:%04x %s %s root hub\r\n", + bus->busid, hub->hub_addr, 0xffff, 0xffff, + "Cherry-Embedded", root_speed_table[hub->speed]); + } + } + } + } + + for (uint8_t port = 0; port < hub->nports; port++) { + hport = &hub->child[port]; + if (hport->connected) { + ret = 0; + if (hport->device_desc.iManufacturer) { + memset(imbuf, 0, sizeof(imbuf)); + ret = usbh_get_string_desc(hport, hport->device_desc.iManufacturer, imbuf, sizeof(imbuf)); + if (ret == 0) { + imvalid = true; + } + } + + if (hport->device_desc.iProduct) { + memset(ipbuf, 0, sizeof(ipbuf)); + ret = usbh_get_string_desc(hport, hport->device_desc.iProduct, ipbuf, sizeof(ipbuf)); + if (ret == 0) { + ipvalid = true; + } + } + + if (imvalid) { + pimstr = (const char *)imbuf; + } else { + pimstr = "Not specified Manufacturer"; + } + + if (ipvalid) { + pipstr = (const char *)ipbuf; + } else { + pipstr = "Not specified Product"; + } + + if (!astree) { + if ((dev_addr < 0) || (hport->dev_addr == dev_addr)) { + if (((vid < 0) || (vid == hport->device_desc.idVendor)) && ((pid < 0) || (pid == hport->device_desc.idProduct))) { + USB_LOG_RAW("Bus %03u Device %03u: ID %04x:%04x %s %s\r\n", + bus->busid, hport->dev_addr, hport->device_desc.idVendor, hport->device_desc.idProduct, + pimstr, pipstr); + + if (verbose) { + usbh_print_hubport_info(hport); + } + } + } + } + + for (uint8_t intf = 0; intf < hport->config.config_desc.bNumInterfaces; intf++) { + if (hport->config.intf[intf].class_driver && hport->config.intf[intf].class_driver->driver_name) { + if (astree) { + for (uint8_t j = 0; j < hub->index; j++) { + USB_LOG_RAW(" "); + } + + USB_LOG_RAW("|__ Port %u: Dev %u, If %u, ClassDriver=%s, %uM\r\n", + hport->port, hport->dev_addr, intf, hport->config.intf[intf].class_driver->driver_name, speed_baud[hport->speed]); + } + + if (!strcmp(hport->config.intf[intf].class_driver->driver_name, "hub")) { + hub_next = hport->config.intf[intf].priv; + + if (hub_next && hub_next->connected) { + usbh_list_device(hub_next, astree, verbose, dev_addr, vid, pid); + } + } + } else if (astree) { + for (uint8_t j = 0; j < hub->index; j++) { + USB_LOG_RAW(" "); + } + + USB_LOG_RAW("|__ Port %u: Dev %u, If 0 ClassDriver=none, %uM\r\n", + hport->port, hport->dev_addr, speed_baud[hport->speed]); + } + } + } + } +} + +void lsusb_help(void) +{ + USB_LOG_RAW("List USB Devices\r\n" + "Usage: lsusb [options]...\r\n" + "\r\n" + "-v, --verbose\r\n" + " - increase verbosity (show descriptors)\r\n" + "-s [[bus]:][dev_addr]\r\n" + " - show only devices with specified device and/or\r\n" + " bus numbers (in decimal)\r\n" + "-d vendor:[product]\r\n" + " - show only devices with the specified vendor and\r\n" + " product ID numbers (in hexadecimal)\r\n" + "-t, --tree\r\n" + " - dump the physical USB device hierarchy as a tree\r\n" + "-V, --version\r\n" + " - show version of the cherryusb\r\n" + "-h, --help\r\n" + " - show usage and help information\r\n"); +} + int lsusb(int argc, char **argv) { usb_slist_t *bus_list; - struct usbh_hub *hub; struct usbh_bus *bus; - size_t flags; + + int busid = -1; + int dev_addr = -1; + int vid = -1; + int pid = -1; + bool astree = false; + bool verbose = false; if (argc < 2) { - USB_LOG_RAW("Usage: lsusb [options]...\r\n"); - USB_LOG_RAW("List USB devices\r\n"); - USB_LOG_RAW(" -v, --verbose\r\n"); - USB_LOG_RAW(" Increase verbosity (show descriptors)\r\n"); - // USB_LOG_RAW(" -s [[bus]:[devnum]]\r\n"); - // USB_LOG_RAW(" Show only devices with specified device and/or bus numbers (in decimal)\r\n"); - // USB_LOG_RAW(" -d vendor:[product]\r\n"); - // USB_LOG_RAW(" Show only devices with the specified vendor and product ID numbers (in hexadecimal)\r\n"); - USB_LOG_RAW(" -t, --tree\r\n"); - USB_LOG_RAW(" Dump the physical USB device hierachy as a tree\r\n"); - USB_LOG_RAW(" -V, --version\r\n"); - USB_LOG_RAW(" Show version of program\r\n"); - USB_LOG_RAW(" -h, --help\r\n"); - USB_LOG_RAW(" Show usage and help\r\n"); - return 0; - } - if (argc > 3) { + lsusb_help(); return 0; } - flags = usb_osal_enter_critical_section(); + while (argc > 1) { + argc--; + argv++; - if (strcmp(argv[1], "-V") == 0) { - USB_LOG_RAW("CherryUSB Version %s\r\n", CHERRYUSB_VERSION_STR); - } + if (!strcmp(*argv, "-V") || !strcmp(*argv, "--version")) { + USB_LOG_RAW("CherryUSB version %s\r\n", CHERRYUSB_VERSION_STR); + return 0; + } else if (!strcmp(*argv, "-h") || !strcmp(*argv, "--help")) { + lsusb_help(); + return 0; + } else if (!strcmp(*argv, "-v") || !strcmp(*argv, "--verbose")) { + verbose = true; + } else if (!strcmp(*argv, "-t") || !strcmp(*argv, "--tree")) { + astree = true; + } else if (!strcmp(*argv, "-s")) { + if (argc > 1) { + argc--; + argv++; - if (strcmp(argv[1], "-t") == 0) { - usb_slist_for_each(bus_list, &g_bus_head) - { - bus = usb_slist_entry(bus_list, struct usbh_bus, list); - hub = &bus->hcd.roothub; + if (*argv[0] == '-') { + continue; + } - USB_LOG_RAW("/: Bus %u, Hub %u, ports=%u, is roothub\r\n", - bus->busid, - hub->index, - hub->nports); - usbh_list_all_interface_driver(hub); + char *endptr; + const char *colon = strchr(*argv, ':'); + (void)endptr; + + if (colon != NULL) { + const char *str; + if (colon > *argv) { + busid = strtol(*argv, &endptr, 10); + } + str = colon + 1; + if (*str != '\0') { + dev_addr = strtol(str, &endptr, 10); + if (dev_addr <= 0 || dev_addr >= 128) { + dev_addr = -1; + } + } + } else { + dev_addr = strtol(*argv, &endptr, 10); + if (dev_addr <= 0 || dev_addr >= 128) { + dev_addr = -1; + } + } + } + } else if (!strcmp(*argv, "-d")) { + if (argc > 1) { + argc--; + argv++; + + if (*argv[0] == '-') { + continue; + } + + char *endptr; + const char *colon = strchr(*argv, ':'); + (void)endptr; + + if (colon == NULL) { + continue; + } + const char *str; + + vid = strtol(*argv, &endptr, 16); + if (vid < 0 || vid > 0xffff) { + vid = -1; + continue; + } + str = colon + 1; + if (*str != '\0') { + pid = strtol(str, &endptr, 16); + if (pid < 0 || pid > 0xffff) { + pid = -1; + } + } + } } } - if (strcmp(argv[1], "-v") == 0) { - usb_slist_for_each(bus_list, &g_bus_head) - { - bus = usb_slist_entry(bus_list, struct usbh_bus, list); - hub = &bus->hcd.roothub; - - usbh_list_all_interface_desc(bus, hub); - } + if (astree) { + busid = -1; + dev_addr = -1; + vid = -1; + pid = -1; + verbose = false; + } + + usb_slist_for_each(bus_list, &g_bus_head) + { + bus = usb_slist_entry(bus_list, struct usbh_bus, list); + if (busid >= 0) { + if (bus->busid != busid) { + continue; + } + } + + usbh_list_device(&bus->hcd.roothub, astree, verbose, dev_addr, vid, pid); } - usb_osal_leave_critical_section(flags); return 0; }