usbd-func.c

来自「linux嵌入式课程实践中的一个关于声卡驱动程序 。」· C语言 代码 · 共 1,288 行 · 第 1/4 页

C
1,288
字号
    case USB_DT_INTERFACE:    case USB_DT_ENDPOINT:    case USB_DT_OTG:        length = device_descriptor_sizes[bDescriptorType];        break;    case CS_INTERFACE:        switch (bDescriptorSubtype) {        case USB_ST_HEADER:        case USB_ST_CMF:        case USB_ST_ACMF:        case USB_ST_DLMF:        case USB_ST_TRF:        case USB_ST_TCLF:        case USB_ST_NCT:        case USB_ST_MCMF:        case USB_ST_CCMF:        case USB_ST_ENF:        case USB_ST_ATMNF:        case USB_ST_MDLM:        case USB_ST_HID:            length = class_descriptor_sizes[bDescriptorSubtype];            break;        case USB_ST_UF:        case USB_ST_CSF:        case USB_ST_TOMF:        case USB_ST_USBTF:        case USB_ST_PUF:        case USB_ST_EUF:        case USB_ST_MDLMD:            length = class_descriptor_sizes[bDescriptorSubtype] + elements; // XXX check me            break;        default:            return NULL;        }        break;    case USB_DT_STRING:    default:        return NULL;    }    if (!(descriptor = ckmalloc(length, GFP_KERNEL))) {        return NULL;    }    switch (bDescriptorType) {    case CS_INTERFACE:        descriptor->descriptor.generic.bDescriptorSubtype = bDescriptorSubtype;    case USB_DT_DEVICE:    case USB_DT_CONFIG:    case USB_DT_INTERFACE:    case USB_DT_ENDPOINT:    case USB_DT_OTG:        descriptor->descriptor.generic.bLength = length;        descriptor->descriptor.generic.bDescriptorType = bDescriptorType;        break;    case USB_DT_STRING:        break;    }    dbg_init(1,"descriptor: %p length: %d", descriptor, length);    return descriptor;}/* * * usbd_dealloc_descriptor - deallocate a usb descriptor * @descriptor: pointer to usb descriptor to deallocate * * Deallocate a descriptor, first deallocate the index string descriptors. */static __exit void usbd_dealloc_descriptor(struct usb_descriptor *descriptor){    dbg_init(2,"descriptor: %p type: %d", descriptor, descriptor->descriptor.generic.bDescriptorType);    if (descriptor) {        switch (descriptor->descriptor.generic.bDescriptorType) {        case USB_DT_DEVICE:            dbg_init(2,"USB_DT_DEVICE");            usbd_dealloc_string(descriptor->descriptor.device.iManufacturer);            usbd_dealloc_string(descriptor->descriptor.device.iProduct);            usbd_dealloc_string(descriptor->descriptor.device.iManufacturer);            break;        case USB_DT_CONFIG:            dbg_init(2,"USB_DT_CONFIG");            usbd_dealloc_string(descriptor->descriptor.configuration.iConfiguration);            break;        case USB_DT_INTERFACE:            dbg_init(2,"USB_DT_INTERFACE");            usbd_dealloc_string(descriptor->descriptor.interface.iInterface);            break;        case CS_INTERFACE:            dbg_init(2,"class descriptor: %p type: %d subtype: %d",                     descriptor, descriptor->descriptor.generic.bDescriptorType,                    descriptor->descriptor.generic.bDescriptorSubtype            );            dbg_init(2,"USB_CS_INTERFACE");            {                struct usb_class_descriptor *class_descriptor = (struct usb_class_descriptor *)descriptor;                switch(descriptor->descriptor.generic.bDescriptorSubtype) {                case USB_ST_HEADER:                case USB_ST_CMF:                case USB_ST_ACMF:                case USB_ST_DLMF:                case USB_ST_TRF:                case USB_ST_TCLF:                case USB_ST_UF:                case USB_ST_CSF:                case USB_ST_TOMF:                case USB_ST_USBTF:                case USB_ST_NCT:                case USB_ST_PUF:                case USB_ST_EUF:                case USB_ST_MCMF:                case USB_ST_CCMF:                    break;                case USB_ST_ENF:                    dbg_init(2,"USB_ST_ENF");                    usbd_dealloc_string(class_descriptor->descriptor.ethernet_networking.iMACAddress);                    break;                case USB_ST_ATMNF:                    break;                }            }        }        lkfree(descriptor);    }}/* usb-device USB FUNCTION generic functions ************************************************* *//* ** alloc_function_classes - allocate class descriptor array* @classes: number of classes* @class_description_array: pointer to an array of class descriptions* * Return a pointer to an array of pointers to class descriptors. The descriptors * will be filled in with information from the class description array. *  * Returning NULL will cause the caller to cleanup all previously allocated memory. */__init static struct usb_class_descriptor **alloc_function_classes(int classes, struct usb_class_description *class_description_array){    int class;    struct usb_class_descriptor **classes_descriptor_array;    dbg_init(1,"classes: %d", classes);    if (!classes || !class_description_array) {        return NULL;    }    // allocate the class descriptor array    if (!(classes_descriptor_array = ckmalloc(sizeof(struct usb_class_descriptor *)*classes, GFP_KERNEL))) {        return NULL;    }    for (class = 0; class < classes; class++) {        struct usb_class_description *class_description = class_description_array + class;        struct usb_class_descriptor *class_descriptor;        //int elements;        dbg_init(1,"class: %d Subtype: %d elements: %d",                 class, class_description->bDescriptorSubtype, class_description->elements);        // allocate an class descriptor to use        if (!(class_descriptor = usbd_alloc_descriptor(CS_INTERFACE,                         class_description->bDescriptorSubtype, class_description->elements)))         {            dbg_init(0, "usbd_alloc_descriptor failed");            return NULL;        }        switch(class_description->bDescriptorSubtype) {        case USB_ST_HEADER:            class_descriptor->descriptor.header_function.bcdCDC = cpu_to_le16(CLASS_BCD_VERSION);            break;        case USB_ST_CMF:        case USB_ST_ACMF:            class_descriptor->descriptor.abstract_control.bmCapabilities =                 class_description->description.abstract_control.bmCapabilities;            break;        case USB_ST_DLMF:        case USB_ST_TRF:        case USB_ST_TCLF:            // XXX generalize USB_ST_UF here            dbg_init(0, "NOT IMPLEMENTED");            break;        case USB_ST_UF:            dbg_init(1, "USB_ST_UF: bMasterInterface: %02x", class_description->description.union_function.bMasterInterface);            dbg_init(1, "USB_ST_UF: bSlaveInterface[0]: %02x", class_description->description.union_function.bSlaveInterface[0]);            class_descriptor->descriptor.union_function.bMasterInterface =                 class_description->description.union_function.bMasterInterface;            class_descriptor->descriptor.union_function.bSlaveInterface0[0] =                 class_description->description.union_function.bSlaveInterface[0];#if 0            for (elements = 0; elements < class_description->elements; elements++) {                dbg_init(1, "USB_ST_UF: copying bSlaveInterface[%d] %02x", elements,                     class_description->description.union_function.bSlaveInterface[elements]);                class_descriptor->descriptor.union_function.bSlaveInterface0[elements] =                     class_description->description.union_function.bSlaveInterface[elements];            }#endif            break;        case USB_ST_CSF:        case USB_ST_TOMF:        case USB_ST_USBTF:        case USB_ST_NCT:        case USB_ST_PUF:        case USB_ST_EUF:        case USB_ST_MCMF:        case USB_ST_CCMF:            break;        case USB_ST_ENF:            class_descriptor->descriptor.ethernet_networking.bmEthernetStatistics =                 class_description->description.ethernet_networking.bmEthernetStatistics;            class_descriptor->descriptor.ethernet_networking.iMACAddress =                 usbd_alloc_string(class_description->description.ethernet_networking.iMACAddress);            class_descriptor->descriptor.ethernet_networking.wMaxSegmentSize =                 cpu_to_le16(class_description->description.ethernet_networking.wMaxSegmentSize);            class_descriptor->descriptor.ethernet_networking.wNumberMCFilters =                 cpu_to_le16(class_description->description.ethernet_networking.wNumberMCFilters);            class_descriptor->descriptor.ethernet_networking.bNumberPowerFilters =                 class_description->description.ethernet_networking.bNumberPowerFilters;            break;        case USB_ST_ATMNF:            break;        case USB_ST_MDLM:            dbg_init(1,"USB_ST_MDLM:");            class_descriptor->descriptor.mobile_direct.bcdVersion =                 class_description->description.mobile_direct.bcdVersion;            memcpy(class_descriptor->descriptor.mobile_direct.bGUID,                     class_description->description.mobile_direct.bGUID,                    sizeof(class_descriptor->descriptor.mobile_direct.bGUID));            break;        case USB_ST_MDLMD:            dbg_init(1,"USB_ST_MDLMD: sizeof descriptor: %d %d length: %d elements: %d",                     sizeof(struct usb_class_mdlmd_descriptor),                    class_descriptor_sizes[USB_ST_MDLMD],                    class_descriptor->descriptor.mobile_direct_detail.bFunctionLength,                    class_description->elements                    );            {                unsigned char *cp;                cp = (unsigned char *)class_descriptor;                dbg_init(1, "descriptor: %02x %02x %02x %02x %02x %02x", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]);            }            class_descriptor->descriptor.mobile_direct_detail.bGuidDescriptorType =                 class_description->description.mobile_direct_detail.bGuidDescriptorType;            //memcpy(class_descriptor->descriptor.mobile_direct_detail.bDetailData,             //        class_description->description.mobile_direct_detail.bDetailData,            //        class_description->elements            //        );            class_descriptor->descriptor.mobile_direct_detail.bDetailData[0] =                 class_description->description.mobile_direct_detail.bDetailData[0];            class_descriptor->descriptor.mobile_direct_detail.bDetailData[1] =                 class_description->description.mobile_direct_detail.bDetailData[1];            dbg_init(1,"USB_ST_MDLMD: detaildata[0] %02x %02x",                 class_descriptor->descriptor.mobile_direct_detail.bDetailData[0],                    class_description->description.mobile_direct_detail.bDetailData[0]                    );            dbg_init(1,"USB_ST_MDLMD: detaildata[1] %02x %02x",                 class_descriptor->descriptor.mobile_direct_detail.bDetailData[1],                    class_description->description.mobile_direct_detail.bDetailData[1]                    );            {                unsigned char *cp;                cp = (unsigned char *)class_descriptor;                dbg_init(1, "descriptor: %02x %02x %02x %02x %02x %02x", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]);            }            break;        case USB_ST_HID:            class_descriptor->descriptor.hid.bDescriptorType = USB_ST_HID;            class_descriptor->descriptor.hid.bNumDescriptors = 1;            class_descriptor->descriptor.hid.bcdHID =                 class_description->description.hid.bcdHID;            class_descriptor->descriptor.hid.bCountryCode =                 class_description->description.hid.bCountryCode;            class_descriptor->descriptor.hid.bDescriptorType1 =                 class_description->description.hid.bDescriptorType1;            class_descriptor->descriptor.hid.wDescriptorLength1 =                 class_description->description.hid.wDescriptorLength1;            break;        }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?