📄 usbd.c
字号:
static int dump_descriptor (char *buf, char *sp, int num){ int len = 0; while (sp && num--) { dohexval (buf, *sp++); buf += 2; *buf++ = ' '; len += 3; } len++; *buf = '\n'; return len;}/* * * usbd_device_proc_read - implement proc file system read. * @file * @buf * @count * @pos * * Standard proc file system read function. * * We let upper layers iterate for us, *pos will indicate which device to return * statistics for. */static ssize_t usbd_device_proc_read_functions (struct file *file, char *buf, size_t count, loff_t * pos){ unsigned long page; int len = 0; int index; struct list_head *lhd; struct usb_function_driver *function_driver; struct usb_device_instance *device; // get a page, max 4095 bytes of data... if (!(page = get_free_page (GFP_KERNEL))) { return -ENOMEM; } len = 0; index = (*pos)++; if (index == 0) { len += sprintf ((char *) page + len, "usb-device list\n"); } //read_lock(&usb_device_rwlock); if (index == 1) { list_for_each (lhd, &function_drivers) { function_driver = list_entry_func (lhd); if (function_driver->configuration_instance_array) {#if 0 { int configuration; // max 4095 bytes of data... len += sprintf ((char *) page + len, "Function: %s", function_driver->name); len += sprintf ((char *) page + len, "\tDescriptors: %d", function_driver->configurations); len += sprintf ((char *) page + len, "\n"); for (configuration = 0; configuration < function_driver->configurations; configuration++) { int interface; struct usb_configuration_description *configuration = &function_driver->configuration_description[configuration]; len += sprintf ((char *) page + len, "\tConfig: %d %s\n", configuration, configuration->iConfiguration); for (interface = 0; interface < configuration->interfaces; interface++) { int alternate; struct usb_interface_instance *interface = &configuration->interface_instance_array[interface]; int endpoint; struct usb_interface_description *interface = &configuration->interface_list[interface]; len += sprintf ((char *) page + len, "\t\tInterface: %d\n", interface); for (endpoint = 0; endpoint < interface->endpoints; endpoint++) { // XXX struct usb_endpoint_description *endpoint = &interface->endpoint_list[endpoint]; len += sprintf ((char *) page + len, "\t\t\tEndpoint: %d %d\n", endpoint, endpoint->bEndpointAddress); } } } break; }#endif len += sprintf ((char *) page + len, "\nDevice descriptor "); len += dump_descriptor ((char *) page + len, (char *) function_driver->device_descriptor, sizeof (struct usb_device_descriptor)); { int configuration; struct usb_configuration_instance *configuration_instance_array = function_driver->configuration_instance_array; for (configuration = 0; configuration < function_driver->configurations; configuration++) { int interface; struct usb_configuration_descriptor *configuration_descriptor = configuration_instance_array[configuration].configuration_descriptor; len += sprintf ((char *) page + len, "\nConfiguration descriptor [%d ] ", configuration); len += dump_descriptor ((char *) page + len, (char *) configuration_descriptor, sizeof (struct usb_configuration_descriptor)); for (interface = 0; interface < configuration_instance_array[configuration].interfaces; interface++) { int alternate; //int class; struct usb_interface_instance *interface_instance = configuration_instance_array[configuration].interface_instance_array + interface; dbg_init (1, "interface: %d:%d alternates: %d", configuration, interface, interface_instance->alternates); for (alternate = 0; alternate < interface_instance->alternates; alternate++) { int endpoint; int class; struct usb_alternate_instance *alternate_instance = interface_instance->alternates_instance_array + alternate; struct usb_interface_descriptor *interface_descriptor = alternate_instance->interface_descriptor; dbg_init (1, "alternate: %d:%d:%d classes: %d", configuration, interface, alternate, alternate_instance->classes); len += sprintf ((char *) page + len, "\nInterface descriptor [%d:%d:%d ] ", configuration, interface + 1, alternate); len += dump_descriptor ((char *) page + len, (char *) interface_descriptor, sizeof (struct usb_interface_descriptor)); for (class = 0; class < alternate_instance->classes; class++) { struct usb_class_descriptor *class_descriptor = alternate_instance->classes_descriptor_array[class]; len += sprintf ((char *) page + len, "Class descriptor [%d:%d:%d ] ", configuration, interface + 1, class); len += dump_descriptor ((char *) page + len, (char *) class_descriptor, *(char *) class_descriptor); } dbg_init (1, "alternate: %d:%d:%d endpoints: %d", configuration, interface, alternate, alternate_instance->endpoints); for (endpoint = 0; endpoint < alternate_instance->endpoints; endpoint++) { struct usb_endpoint_descriptor *endpoint_descriptor = alternate_instance->endpoints_descriptor_array[endpoint]; dbg_init (1, "endpoint: %d:%d:%d:%d", configuration, interface, alternate, endpoint); len += sprintf ((char *) page + len, "Endpoint descriptor [%d:%d:%d:%d] ", configuration, interface + 1, alternate, endpoint); len += dump_descriptor ((char *) page + len, (char *) endpoint_descriptor, sizeof (struct usb_endpoint_descriptor)); } } } } break; } } } } else if (index == 2) { int i; int k; struct usb_string_descriptor *string_descriptor; len += sprintf ((char *) page + len, "\n\n"); if ((string_descriptor = usbd_get_string (0)) != NULL) { len += sprintf ((char *) page + len, "String [%2d] ", 0); for (k = 0; k < (string_descriptor->bLength / 2) - 1; k++) { len += sprintf ((char *) page + len, "%02x %02x ", string_descriptor->wData[k] >> 8, string_descriptor->wData[k] & 0xff); len++; } len += sprintf ((char *) page + len, "\n"); } for (i = 1; i < maxstrings; i++) { if ((string_descriptor = usbd_get_string (i)) != NULL) { len += sprintf((char *)page+len, "String [%2d:%2d] ", i, string_descriptor->bLength); // bLength = sizeof(struct usb_string_descriptor) + 2*strlen(str)-2; for (k = 0; k < (string_descriptor->bLength / 2) - 1; k++) { *(char *) (page + len) = (char) string_descriptor->wData[k]; len++; } len += sprintf ((char *) page + len, "\n"); } } } else if (index == 3) { list_for_each (lhd, &devices) { device = list_entry_device (lhd); len += sprintf ((char *) page + len, "\n\nBus: %s", device->bus->driver->name); if (device->ep0) { len += sprintf ((char *) page + len, " ep0: %s", device->ep0->function_driver->name); } if (device->function_instance_array) { len += sprintf ((char *) page + len, " func: %s", device->function_instance_array->function_driver->name); } len += sprintf ((char *) page + len, " state: %s", usbd_device_states[device->device_state]); len += sprintf ((char *) page + len, " addr: %d", device->address); len += sprintf ((char *) page + len, " conf: %d", device->configuration); len += sprintf ((char *) page + len, " int: %d", device->interface); len += sprintf ((char *) page + len, " alt: %d", device->alternate); len += sprintf ((char *) page + len, "\n"); break; } len += sprintf ((char *) page + len, "\n"); } //read_unlock(&usb_device_rwlock); if (len > count) { len = -EINVAL; } else if (len > 0 && copy_to_user (buf, (char *) page, len)) { len = -EFAULT; } free_page (page); return len;}static struct file_operations usbd_device_proc_operations_functions = { read:usbd_device_proc_read_functions,};/* * * usbd_device_proc_read - implement proc file system read. * @file: xx * @buf: xx * @count: xx * @pos: xx * * Standard proc file system read function. * * We let upper layers iterate for us, *pos will indicate which device to return * statistics for. */static ssize_t usbd_device_proc_read_devices (struct file *file, char *buf, size_t count, loff_t * pos){ unsigned long page; int len = 0; int index; struct list_head *lhd; struct usb_device_instance *device; // get a page, max 4095 bytes of data... if (!(page = get_free_page (GFP_KERNEL))) { return -ENOMEM; } len = 0; index = (*pos)++; if (index == 0) { len += sprintf ((char *) page + len, "usb-device list\n"); } //read_lock(&usb_device_rwlock); if (index > 0) { list_for_each (lhd, &devices) { int configuration; device = list_entry_device (lhd); if (--index == 0) { // max 4095 bytes of data... len += sprintf ((char *) page + len, "Device: %s", device->bus->driver->name); len += sprintf ((char *) page + len, "\n"); len += sprintf ((char *) page + len, "%20s[ ] ", "Device:"); len += dump_descriptor ((char *) page + len, (char *) device->device_descriptor, sizeof (struct usb_device_descriptor)); break; } // iterate across configurations for this device for (configuration = 0; index > 0; configuration++) { int interface; struct usb_configuration_descriptor *configuration_descriptor; if (!(configuration_descriptor = usbd_device_configuration_descriptor (device, 0, configuration))) { break; } if (--index == 0) { // max 4095 bytes of data... len += sprintf ((char *) page + len, "%20s[%2d ] ", "Configuration:", configuration); len += dump_descriptor ((char *) page + len, (char *) configuration_descriptor, sizeof (struct usb_configuration_descriptor)); break; } // iterate across interfaces for this configurations for (interface = 0; index > 0; interface++) { int alternate; struct usb_interface_instance *interface_instance; if (!(interface_instance = usbd_device_interface_instance (device, 0, configuration, interface))) { break; } // itererate across alternates for this interafce for (alternate = 0; index > 0; alternate++) { int endpoint; struct usb_interface_descriptor *interface_descriptor; if (!(interface_descriptor = usbd_device_interface_descriptor (device, 0, configuration, interface, alternate))) { break; } if (--index == 0) { // max 4095 bytes of data... len += sprintf ((char *) page + len, "%20s[%2d:%2d ] ", "Interface", configuration, interface); len += dump_descriptor ((char *) page + len, (char *) interface_descriptor, sizeof (struct usb_interface_descriptor)); break; } // iterate across endpoints for this interface for (endpoint = 0; index > 0; endpoint++) { struct usb_endpoint_descriptor *endpoint_descriptor; if (!(endpoint_descriptor = usbd_device_endpoint_descriptor_index (device, 0, configuration, interface, alternate, endpoint))) { break; } if (--index == 0) { len += sprintf ((char *) page + len, "%20s[%2d:%2d:%2d] ", "Endpoint", configuration, interface, endpoint); len += dump_descriptor ((char *) page + len, (char *) endpoint_descriptor, sizeof (struct usb_endpoint_descriptor)); break; } } } } } } } if (index > 0) { int i; for (i = 1; i < maxstrings; i++) { struct usb_string_descriptor *string_descriptor; if ((string_descriptor = usbd_get_string (i)) != NULL) { if (--index == 0) { int k; len += sprintf ((char *) page + len, "%20s[%2d] ", "String", i); // bLength = sizeof(struct usb_string_descriptor) + 2*strlen(str)-2; for (k = 0; k < (string_descriptor->bLength / 2) - 1; k++) { *(char *) (page + len) = (char) string_descriptor->wData[k]; len++; } len += sprintf ((char *) page + len, "\n"); } } } } //read_unlock(&usb_device_rwlock); if (len > count) { len = -EINVAL; } else if (len > 0 && copy_to_user (buf, (char *) page, len)) { len = -EFAULT; } free_page (page); return len;}static struct file_operations usbd_device_proc_operations_devices = { read:usbd_device_proc_read_devices,};#endif/* Module init ******************************************************************************* */unsigned intset (unsigned int a, unsigned b){ return (a ? a : b);}char *strset (char *s, char *d){ return ((s && strlen (s) ? s : d));}static int __init usbd_device_init (void){#if 0 debug_option *op;#endif printk (KERN_INFO "usbdcore: %s (dbg=\"%s\")\n", __usbd_module_info, dbg ? dbg : "");#if 0 if (NULL != (op = find_debug_option (dbg_table, "hot"))) { op->sub_table = usbd_hotplug_get_dbg_table (); } if (NULL != (op = find_debug_option (dbg_table, "mon"))) { op->sub_table = usbd_monitor_get_dbg_table (); }#endif if (0 != scan_debug_options ("usb-device", dbg_table, dbg)) { return (-EINVAL); }#ifdef CONFIG_USBD_PROCFS { struct proc_dir_entry *p; // create proc filesystem entries if ((p = create_proc_entry ("usb-functions", 0, 0)) == NULL) return -ENOMEM; p->proc_fops = &usbd_device_proc_operations_functions; if ((p = create_proc_entry ("usb-devices", 0, 0)) == NULL) return -ENOMEM; p->proc_fops = &usbd_device_proc_operations_devices; }#endif return 0;}static void __exit usbd_device_exit (void){ printk (KERN_INFO "usbdcore: %s exiting\n", __usbd_module_info);#ifdef CONFIG_USBD_PROCFS // remove proc filesystem entry remove_proc_entry ("usb-functions", NULL); remove_proc_entry ("usb-devices", NULL);#endif}module_init (usbd_device_init);module_exit (usbd_device_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -