usbd-func.c
来自「Linux2.4.20针对三星公司的s3c2440内核基础上的一些设备驱动代码」· C语言 代码 · 共 1,206 行 · 第 1/3 页
C
1,206 行
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; } } break; case USB_DT_HID: dbg_init(2,"USB_DT_HID"); break; case USB_DT_REPORT: dbg_init(2,"USB_DT_REPORT"); 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. */__devinit 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 Type: %d Subtype: %d elements: %d", class, class_description->bDescriptorType, class_description->bDescriptorSubtype, class_description->elements); // allocate an class descriptor to use if (!(class_descriptor = usbd_alloc_descriptor( class_description->bDescriptorType, class_description->bDescriptorSubtype, class_description->elements))) { dbg_init (0, "usbd_alloc_descriptor failed"); return NULL; } if (class_description->bDescriptorType != CS_INTERFACE) { switch (class_description->bDescriptorType) { case USB_DT_HID: class_descriptor->descriptor.hid.bcdCDC = cpu_to_le16(CLASS_HID_BCD_VERSION); class_descriptor->descriptor.hid.bCountryCode = class_description->description.hid.bCountryCode; class_descriptor->descriptor.hid.bNumDescriptors = 1; class_descriptor->descriptor.hid.bDescriptorType0 = class_description->description.hid.bDescriptorType; class_descriptor->descriptor.hid.wDescriptorLength0 = cpu_to_le16(class_description->description.hid.wDescriptorLength); break; } // save in class descriptor array classes_descriptor_array[class] = class_descriptor; continue; } // CDC class 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; } // save in class descriptor array classes_descriptor_array[class] = class_descriptor; } return classes_descriptor_array;}/* * * alloc_function_endpoints - allocate endpoint descriptor array * @endpoints: number of endpoints * @endpoint_description_array: pointer to an array of endpoint descriptions * * Return a pointer to an array of pointers to endpoint descriptors. The descriptors * will be filled in with information from the endpoint description array. * * Returning NULL will cause the caller to cleanup all previously allocated memory. */__devinit static struct usb_endpoint_descriptor **alloc_function_endpoints (int endpoints, struct usb_endpoint_description *endpoint_description_array){ int i; struct usb_endpoint_descriptor **endpoint_descriptor_array; if (!endpoints || !endpoint_description_array) { return NULL; } // allocate the endpoint descriptor array if (!(endpoint_descriptor_array = ckmalloc (sizeof (struct usb_endpoint_descriptor *) * endpoints, GFP_KERNEL))) { return NULL; } for (i = 0; i < endpoints; i++) { struct usb_endpoint_description *endpoint_description = endpoint_description_array + i; struct usb_endpoint_descriptor *endpoint_descriptor; dbg_init (1, "endpoint: %d:%d", i, endpoints); // allocate an endpoint descriptor to use if (!(endpoint_descriptor = usbd_alloc_descriptor (USB_DT_ENDPOINT, 0, 0))) { return NULL; } endpoint_descriptor->bEndpointAddress = endpoint_description->bEndpointAddress | endpoint_description->direction; endpoint_descriptor->bmAttributes = endpoint_description->bmAttributes; // XXX cpu_to_le16()? endpoint_descriptor->wMaxPacketSize = cpu_to_le16(endpoint_description->wMaxPacketSize); endpoint_descriptor->bInterval = endpoint_description->bInterval; // save in endpoint descriptor array endpoint_descriptor_array[i] = endpoint_descriptor; } return endpoint_descriptor_array;}__devinit static struct usb_class_report_descriptor **alloc_function_reports(int classes, struct usb_class_description *class_description_array){ int class; struct usb_class_report_descriptor **reports_descriptor_array; dbg_init(1,"classes: %d", classes); if (!classes || !class_description_array) { return NULL; } // allocate the class descriptor array if (!(reports_descriptor_array = ckmalloc(sizeof(struct usb_class_report_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_report_descriptor *report_descriptor; //int elements; if (class_description->bDescriptorType != USB_DT_HID) continue; dbg_init(1,"class: %d Type: %d DescriptionType: %d length: %d", class, class_description->bDescriptorType, class_description->description.hid.bDescriptorType, class_description->description.hid.wDescriptorLength); // allocate an class descriptor to use if (!(report_descriptor = usbd_alloc_descriptor(class_description->description.hid.bDescriptorType, 0, class_description->description.hid.wDescriptorLength ))) { dbg_init(0, "usbd_alloc_descriptor failed"); return NULL; } memcpy(&report_descriptor->bData[0], class_description->description.hid.reportDescriptor, class_description->description.hid.wDescriptorLength); report_descriptor->wLength = cpu_to_le16(class_description->description.hid.wDescriptorLength); // save in class descriptor array reports_descriptor_array[class] = report_descriptor; } return reports_descriptor_array;}/* * * alloc_endpoint_transfer - allocate endpoint transfer array * @endpoints: number of endpoints * @endpoint_description_array: pointer to an array of endpoint descriptions * * Return a pointer to an array of transfers sizes for each endpointi. * * Returning NULL will cause the caller to cleanup all previously allocated memory. */__devinit static int *alloc_endpoint_transfer (int endpoints, struct usb_endpoint_description *endpoint_description_array){ int i; int *endpoint_transfersize; if (!endpoints || !endpoint_description_array) { return NULL; } // allocate the endpoint descriptor array if (!(endpoint_transfersize = ckmalloc (sizeof (int) * endpoints, GFP_KERNEL))) { return NULL; } for (i = 0; i < endpoints; i++) { struct usb_endpoint_description *endpoint_description = endpoint_description_array + i; dbg_init (1, "endpoint: %d:%d", i, endpoints); endpoint_transfersize[i] = endpoint_description->transferSize; } return endpoint_transfersize;}#if 0/* * * alloc_function_interface - allocate alternate instance array * * Return a pointer to an array of alternate instances. Each instance contains a pointer * to a filled in alternate descriptor and a pointer to the endpoint descriptor array. * * Returning NULL will cause the caller to cleanup all previously allocated memory. */__devinit static struct usb_alternate_instance *alloc_function_interface (int bInterfaceNumber, struct usb_interface_description *interface_description){ struct usb_alternate_instance *alternate_instance; struct usb_interface_descriptor *interface_descriptor; dbg_init (1, "interface: %d", bInterfaceNumber); // allocate array of alternate instances if (!(alternate_instance = ckmalloc (sizeof (struct usb_alternate_instance), GFP_KERNEL))) { dbg_init (0, "ckmalloc failed"); return NULL; } // allocate a descriptor for this interface if (!(interface_descriptor = usbd_alloc_descriptor (USB_DT_INTERFACE, 0, 0))) { dbg_init (0, "usbd_alloc_descriptor failed"); return NULL; } interface_descriptor->bInterfaceNumber = bInterfaceNumber + 1; // XXX interface_descriptor->bInterfaceClass = interface_description->bInterfaceClass; interface_descriptor->bInterfaceSubClass = interface_description->bInterfaceSubClass; interface_descriptor->bInterfaceProtocol = interface_description->bInterfaceProtocol; interface_descriptor->bAlternateSetting = 0; interface_descriptor->iInterface = usbd_alloc_string (interface_description->iInterface); // XXX it should be possible to collapse the next two functions into one. alternate_instance->endpoints_descriptor_array = NULL; alternate_instance->endpoint_transfersize_array = NULL; // save number of alternates, classes and endpoints for this alternate alternate_instance->endpoints = 0; alternate_instance->interface_descriptor = interface_descriptor; return alternate_instance;}#endif/* * * alloc_function_alternates - allocate alternate instance array * @alternates: number of alternates * @alternate_description_array: pointer to an array of alternate descriptions * * Return a pointer to an array of alternate instances. Each instance contains a pointer * to a filled in alternate descriptor and a pointer to the endpoint descriptor array. * * Returning NULL will cause the caller to cleanup all previously allocated memory. */__devinit static struct usb_alternate_instance *alloc_function_alternates (int bInterfaceNumber, struct usb_interface_description *interface_description, int alternates, struct usb_alternate_description *alternate_description_array){ int i; struct usb_alternate_instance *alternate_instance_array; dbg_init (1, "bInterfaceNumber: %d, alternates: %d", bInterfaceNumber, alternates); // allocate array of alternate instances if (!(alternate_instance_array = ckmalloc (sizeof (struct usb_alternate_instance) * alternates, GFP_KERNEL))) { return NULL; } // iterate across the alternate descriptions
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?