⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbd.c

📁 linux嵌入式课程实践中的一个关于声卡驱动程序 。
💻 C
📖 第 1 页 / 共 3 页
字号:
    }    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 + -