refactor(core/usbh_core): refactor lsusb

Signed-off-by: sakumisu <1203593632@qq.com>
This commit is contained in:
sakumisu
2025-11-11 22:45:49 +08:00
parent 6105d7a1d6
commit e0dc9c9890

View File

@@ -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;
}