📄 usbd.c
字号:
/* * * 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_tusbd_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] ", 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"); } } } 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_tusbd_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));}int __init usbd_device_init(void){#if 0 debug_option *op;#endif#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) {#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 + -