📄 usbd.c
字号:
} 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. */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; */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. */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;}struct usb_otg_descriptor *usbd_device_otg_descriptor( struct usb_device_instance *device, int port, int configuration, int interface, int alternate){ struct usb_alternate_instance *alt_instance; if (!(alt_instance = usbd_device_alternate_instance(device, port, configuration, interface, alternate))) { return 0; } return (alt_instance->otg_descriptor);}/** * 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. */int usbd_alloc_urb_data(struct usbd_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. * */struct usbd_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&0x7f),endpoint_address); if ((endpoint->endpoint_address&0x7f) == endpoint_address) { struct usbd_urb *urb; dbg_urbmem(4,"[%d]: endpoint: %p %02x", i, endpoint, endpoint->endpoint_address); if (!(urb = ckmalloc(sizeof(struct usbd_urb), GFP_ATOMIC))) { dbg_urbmem(0,"ckmalloc(%u,GFP_ATOMIC) failed", sizeof(struct usbd_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; } return urb; } } printk ("can't find endpoint #%02x!\n",endpoint_address); 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&0x7f),endpoint_address); if ((endpoint->endpoint_address&0x7f) == endpoint_address) { dbg_urbmem(0,"found it, but too late"); break; } } return NULL;}/** * 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. */void usbd_device_event_irq(struct usb_device_instance *device, usb_device_event_t event, int data){ struct usbd_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,"-------------------------------------------------------------------------------------"); switch(event) { case DEVICE_UNKNOWN: dbg_usbe(1, "%s", usbd_device_events[DEVICE_UNKNOWN]); break; case DEVICE_INIT: dbg_usbe(3, "%s", usbd_device_events[DEVICE_INIT]); device->device_state = STATE_INIT; break; case DEVICE_CREATE: dbg_usbe(3, "%s", usbd_device_events[DEVICE_CREATE]); device->device_state = STATE_ATTACHED; break; case DEVICE_HUB_CONFIGURED: dbg_usbe(3, "%s", usbd_device_events[DEVICE_HUB_CONFIGURED]); device->device_state = STATE_POWERED; break; case DEVICE_RESET: dbg_usbe(1, "%s", usbd_device_events[DEVICE_RESET]); device->device_state = STATE_DEFAULT; device->address = 0; break; case DEVICE_ADDRESS_ASSIGNED: dbg_usbe(1, "%s", usbd_device_events[DEVICE_ADDRESS_ASSIGNED]); device->device_state = STATE_ADDRESSED; break; case DEVICE_CONFIGURED: dbg_usbe(1, "%s", usbd_device_events[DEVICE_CONFIGURED]); device->device_state = STATE_CONFIGURED; break; case DEVICE_DE_CONFIGURED: dbg_usbe(1, "%s", usbd_device_events[DEVICE_DE_CONFIGURED]); device->device_state = STATE_ADDRESSED; break; case DEVICE_BUS_INACTIVE: dbg_usbe(1, "%s", usbd_device_events[DEVICE_BUS_INACTIVE]); if (device->status != USBD_CLOSING) { device->status = USBD_SUSPENDED; } break; case DEVICE_BUS_ACTIVITY: dbg_usbe(1, "%s", usbd_device_events[DEVICE_BUS_ACTIVITY]); if (device->status != USBD_CLOSING) { device->status = USBD_OK; } break; case DEVICE_SET_INTERFACE: dbg_usbe(1, "%s", usbd_device_events[DEVICE_SET_INTERFACE]); break; case DEVICE_SET_FEATURE: dbg_usbe(1, "%s", usbd_device_events[DEVICE_SET_FEATURE]); break; case DEVICE_CLEAR_FEATURE: dbg_usbe(1, "%s", usbd_device_events[DEVICE_CLEAR_FEATURE]); break; case DEVICE_POWER_INTERRUPTION: dbg_usbe(1, "%s", usbd_device_events[DEVICE_POWER_INTERRUPTION]); device->device_state = STATE_POWERED; break; case DEVICE_HUB_RESET: dbg_usbe(1, "%s", usbd_device_events[DEVICE_HUB_RESET]); device->device_state = STATE_ATTACHED; break; case DEVICE_DESTROY: dbg_usbe(1, "%s", usbd_device_events[DEVICE_DESTROY]); device->device_state = STATE_UNKNOWN; break; case DEVICE_BUS_REQUEST: break; case DEVICE_BUS_RELEASE: break; case DEVICE_ACCEPT_HNP: break; case DEVICE_REQUEST_SRP: break; case DEVICE_FUNCTION_PRIVATE: dbg_usbe(1, "%s", usbd_device_events[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 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;}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. */int usbd_endpoint_halted(struct usb_device_instance *device, int endpoint){ if (!device->bus->driver->ops->endpoint_halted) { return 1; } 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. */int usbd_device_feature(struct usb_device_instance *device, int endpoint, int feature){ if (!device->bus->driver->ops->device_feature) { return 1; } 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 */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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -