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