📄 usbd.c
字号:
* Return the specified interface descriptor for the specified device. */EXPORT_SYMBOL(usbd_device_interface_descriptor);struct usb_interface_descriptor *usbd_device_interface_descriptor (struct usb_device_instance *device, int port, int configuration, int interface, int alternate){ struct usb_interface_instance *interface_instance; if (!(interface_instance = usbd_device_interface_instance (device, port, configuration, interface))) { return NULL; } if ((alternate < 0) || (alternate >= interface_instance->alternates)) { return NULL; } return (interface_instance->alternates_instance_array[alternate].interface_descriptor);}EXPORT_SYMBOL(usbd_device_class_report_descriptor_index);struct usb_class_report_descriptor *usbd_device_class_report_descriptor_index( struct usb_device_instance *device, int port, int configuration, int interface, int alternate, int index){ struct usb_alternate_instance *alternate_instance; if (!(alternate_instance = usbd_device_alternate_instance(device, port, configuration, interface, alternate))) { return NULL; } if (index >= alternate_instance->classes) { return NULL; } return *(alternate_instance->reports_descriptor_array+index);}/** * usbd_device_class_descriptor_index * @device: which device * @port: which port * @configuration: index to configuration, 0 - N-1 * @interface: index to interface * @index: which index * * Return the specified class descriptor for the specified device. */EXPORT_SYMBOL(usbd_device_class_descriptor_index);struct usb_class_descriptor *usbd_device_class_descriptor_index (struct usb_device_instance *device, int port, int configuration, int interface, int alternate, int index){ struct usb_alternate_instance *alternate_instance; if (!(alternate_instance = usbd_device_alternate_instance (device, port, configuration, interface, alternate))) { return NULL; } if (index >= alternate_instance->classes) { return NULL; } return *(alternate_instance->classes_descriptor_array + index);}/** * usbd_device_endpoint_descriptor_index * @device: which device * @port: which port * @configuration: index to configuration, 0 - N-1 * @interface: index to interface * @alternate: index setting * @index: which index * * Return the specified endpoint descriptor for the specified device. */EXPORT_SYMBOL(usbd_device_endpoint_descriptor_index);struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor_index (struct usb_device_instance *device, int port, int configuration, int interface, int alternate, int index){ struct usb_alternate_instance *alternate_instance; if (!(alternate_instance = usbd_device_alternate_instance (device, port, configuration, interface, alternate))) { return NULL; } if (index >= alternate_instance->endpoints) { return NULL; } return *(alternate_instance->endpoints_descriptor_array + index);}/** * usbd_device_endpoint_transfersize * @device: which device * @port: which port * @configuration: index to configuration, 0 - N-1 * @interface: index to interface * @index: which index * * Return the specified endpoint transfer size; */EXPORT_SYMBOL(usbd_device_endpoint_transfersize);int usbd_device_endpoint_transfersize (struct usb_device_instance *device, int port, int configuration, int interface, int alternate, int index){ struct usb_alternate_instance *alternate_instance; if (!(alternate_instance = usbd_device_alternate_instance (device, port, configuration, interface, alternate))) { return 0; } if (index >= alternate_instance->endpoints) { return 0; } return *(alternate_instance->endpoint_transfersize_array + index);}/** * usbd_device_endpoint_descriptor * @device: which device * @port: which port * @configuration: index to configuration, 0 - N-1 * @interface: index to interface * @alternate: alternate setting * @endpoint: which endpoint * * Return the specified endpoint descriptor for the specified device. */EXPORT_SYMBOL(usbd_device_endpoint_descriptor);struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor (struct usb_device_instance *device, int port, int configuration, int interface, int alternate, int endpoint){ struct usb_endpoint_descriptor *endpoint_descriptor; int i; for (i = 0; !(endpoint_descriptor = usbd_device_endpoint_descriptor_index (device, port, configuration, interface, alternate, i)); i++) { if (endpoint_descriptor->bEndpointAddress == endpoint) { return endpoint_descriptor; } } return NULL;}/** * usbd_alloc_urb_data - allocate urb data buffer * @urb: pointer to urb * @len: size of buffer to allocate * * Allocate a data buffer for the specified urb structure. */EXPORT_SYMBOL(usbd_alloc_urb_data);int usbd_alloc_urb_data (struct urb *urb, int len){ len += 2; urb->buffer_length = len; urb->actual_length = 0; if (len == 0) { dbg_urbmem (0, "len == zero"); return 0; } if (urb->endpoint && urb->endpoint->endpoint_address && urb->function_instance && urb->function_instance->function_driver->ops->alloc_urb_data) { dbg_urbmem (0, "urb->function->ops used"); return urb->function_instance->function_driver->ops->alloc_urb_data (urb, len); } return !(urb->buffer = ckmalloc (len, GFP_ATOMIC));}/** * usbd_alloc_urb - allocate an URB appropriate for specified endpoint * @device: device instance * @function_instance: device instance * @endpoint: endpoint * @length: size of transfer buffer to allocate * * Allocate an urb structure. The usb device urb structure is used to * contain all data associated with a transfer, including a setup packet for * control transfers. * * NOTE: endpoint_address MUST contain a direction flag. */EXPORT_SYMBOL(usbd_alloc_urb);struct urb *usbd_alloc_urb (struct usb_device_instance *device, struct usb_function_instance *function_instance, __u8 endpoint_address, int length){ int i; for (i = 0; i < device->bus->driver->max_endpoints; i++) { struct usb_endpoint_instance *endpoint = device->bus->endpoint_array + i; dbg_urbmem (2, "i=%d epa=%d want %d", i, endpoint->endpoint_address, endpoint_address); if (endpoint->endpoint_address == endpoint_address) { struct urb *urb; dbg_urbmem (2, "[%d]: endpoint: %p %02x length: %d", i, endpoint, endpoint->endpoint_address, length); if (!(urb = ckmalloc (sizeof (struct urb), GFP_ATOMIC))) { dbg_urbmem (0, "ckmalloc(%u,GFP_ATOMIC) failed", sizeof (struct urb)); return NULL; } urb->endpoint = endpoint; urb->device = device; urb->function_instance = function_instance; urb_link_init (&urb->link); if (length) { if (usbd_alloc_urb_data (urb, length)) { dbg_urbmem (0, "usbd_alloc_urb_data(%u,GFP_ATOMIC) failed", length); kfree (urb); return NULL; } } else { urb->buffer_length = urb->actual_length = 0; } dbg_urbmem(1, "[%d] urb: %p len: %d", endpoint_address, urb, length); return urb; } } dbg_urbmem (0, "can't find endpoint #%02x!", endpoint_address); for (i = 0; i < device->bus->driver->max_endpoints; i++) { struct usb_endpoint_instance *endpoint = device->bus->endpoint_array + i; dbg_urbmem (0, "i=%d epa=%d want %d", i, endpoint->endpoint_address, endpoint_address); if (endpoint->endpoint_address == endpoint_address) { dbg_urbmem (0, "found it, but too late"); break; } } return NULL;}/** * usbd_dealloc_urb - deallocate an URB and associated buffer * @urb: pointer to an urb structure * * Deallocate an urb structure and associated data. */EXPORT_SYMBOL(usbd_dealloc_urb);void usbd_dealloc_urb (struct urb *urb){ dbg_urbmem(1, "[%d] urb: %p len: %d", urb->endpoint->endpoint_address, urb, urb->buffer_length); if (urb) { if (urb->buffer) { if (urb->function_instance && urb->function_instance->function_driver->ops->dealloc_urb_data) { urb->function_instance->function_driver->ops->dealloc_urb_data (urb); } else { kfree (urb->buffer); } } kfree (urb); }}/** * usbd_device_event - called to respond to various usb events * @device: pointer to struct device * @event: event to respond to * * Used by a Bus driver to indicate an event. */EXPORT_SYMBOL(usbd_device_event_irq);void usbd_device_event_irq (struct usb_device_instance *device, usb_device_event_t event, int data){ struct urb *urb; usb_device_state_t state; if (!device || !device->bus) { dbg_usbe (1, "(%p,%d) NULL device or device->bus", device, event); return; } state = device->device_state; dbg_usbe (3, "-------------------------------------------------------------------------------------"); dbg_usbe (1,"%s", USBD_DEVICE_EVENTS(event)); switch (event) { case DEVICE_UNKNOWN: break; case DEVICE_INIT: device->device_state = STATE_INIT; break; case DEVICE_CREATE: device->device_state = STATE_ATTACHED; break; case DEVICE_HUB_CONFIGURED: device->device_state = STATE_POWERED; break; case DEVICE_RESET: device->device_state = STATE_DEFAULT; device->address = 0; break; case DEVICE_ADDRESS_ASSIGNED: device->device_state = STATE_ADDRESSED; break; case DEVICE_CONFIGURED: device->device_state = STATE_CONFIGURED; break; case DEVICE_DE_CONFIGURED: device->device_state = STATE_ADDRESSED; break; case DEVICE_BUS_INACTIVE: if (device->status != USBD_CLOSING) { device->status = USBD_SUSPENDED; } break; case DEVICE_BUS_ACTIVITY: if (device->status != USBD_CLOSING) { device->status = USBD_OK; } break; case DEVICE_SET_INTERFACE: break; case DEVICE_SET_FEATURE: break; case DEVICE_CLEAR_FEATURE: break; case DEVICE_POWER_INTERRUPTION: device->device_state = STATE_POWERED; break; case DEVICE_HUB_RESET: device->device_state = STATE_ATTACHED; break; case DEVICE_DESTROY: device->device_state = STATE_UNKNOWN; break; case DEVICE_FUNCTION_PRIVATE: break; } dbg_usbe (3, "%s event: %d oldstate: %d newstate: %d status: %d address: %d", device->name, event, state, device->device_state, device->status, device->address);; // tell the bus interface driver if (device->bus && device->bus->driver->ops->device_event) { dbg_usbe (3, "calling bus->event"); device->bus->driver->ops->device_event (device, event, data); }#if 0 if (device->function_instance_array && (device->function_instance_array + port)->function_driver->ops->event) { dbg_usbe (3, "calling function->event"); (device->function_instance_array + port)->function_driver->ops->event (device, event); }#endif if (device->ep0 && device->ep0->function_driver->ops->event) { dbg_usbe (3, "calling ep0->event"); device->ep0->function_driver->ops->event (device, event, data); }#if 0 // tell the bus interface driver if (device->bus && device->bus->driver->ops->device_event) { dbg_usbe (3, "calling bus->event"); device->bus->driver->ops->device_event (device, event); }#endif // dbg_usbe(0, "FINISHED - NO FUNCTION BH"); // return; // XXX // queue an urb to endpoint zero dbg_usbe(1,"queueing event urb"); if ((urb = usbd_alloc_urb (device, device->function_instance_array, 0, 0))) { urb->event = event; urb->data = data; urb_append_irq (&(urb->endpoint->events), urb); usbd_schedule_function_bh (device); } dbg_usbe (5, "FINISHED"); return;}EXPORT_SYMBOL(usbd_device_event);void usbd_device_event (struct usb_device_instance *device, usb_device_event_t event, int data){ unsigned long flags; local_irq_save (flags); usbd_device_event_irq (device, event, data); local_irq_restore (flags);}/** * usbd_endpoint_halted * @device: point to struct usb_device_instance * @endpoint: endpoint to check * * Return non-zero if endpoint is halted. */EXPORT_SYMBOL(usbd_endpoint_halted);int usbd_endpoint_halted (struct usb_device_instance *device, int endpoint){ if (!device->bus->driver->ops->endpoint_halted) { return -EINVAL; } return device->bus->driver->ops->endpoint_halted (device, endpoint);}/** * usbd_device_feature - set usb device feature * @device: point to struct usb_device_instance * @endpoint: which endpoint * @feature: feature value * * Return non-zero if endpoint is halted. */EXPORT_SYMBOL(usbd_device_feature);int usbd_device_feature (struct usb_device_instance *device, int endpoint, int feature){ if (!device->bus->driver->ops->device_feature) { return -EINVAL; } return device->bus->driver->ops->device_feature (device, endpoint, feature);}#ifdef CONFIG_USBD_PROCFS/* Proc Filesystem *************************************************************************** *//* * * dohex * */static void dohexdigit (char *cp, unsigned char val){ if (val < 0xa) { *cp = val + '0'; } else if ((val >= 0x0a) && (val <= 0x0f)) { *cp = val - 0x0a + 'a'; }}/* * * dohex * */static void dohexval (char *cp, unsigned char val){ dohexdigit (cp++, val >> 4); dohexdigit (cp++, val & 0xf);}/* * * dump_descriptor */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -