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 + -
显示快捷键?