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

📄 usb.c

📁 是关于linux2.5.1的完全源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	unsigned char *begin;	int parsed = 0, len, numskipped;	header = (struct usb_descriptor_header *)buffer;	/* Everything should be fine being passed into here, but we sanity */	/*  check JIC */	if (header->bLength > size) {		err("ran out of descriptors parsing");		return -1;	}			if (header->bDescriptorType != USB_DT_ENDPOINT) {		warn("unexpected descriptor 0x%X, expecting endpoint descriptor, type 0x%X",			endpoint->bDescriptorType, USB_DT_ENDPOINT);		return parsed;	}	if (header->bLength == USB_DT_ENDPOINT_AUDIO_SIZE)		memcpy(endpoint, buffer, USB_DT_ENDPOINT_AUDIO_SIZE);	else		memcpy(endpoint, buffer, USB_DT_ENDPOINT_SIZE);		le16_to_cpus(&endpoint->wMaxPacketSize);	buffer += header->bLength;	size -= header->bLength;	parsed += header->bLength;	/* Skip over the rest of the Class Specific or Vendor Specific */	/*  descriptors */	begin = buffer;	numskipped = 0;	while (size >= sizeof(struct usb_descriptor_header)) {		header = (struct usb_descriptor_header *)buffer;		if (header->bLength < 2) {			err("invalid descriptor length of %d", header->bLength);			return -1;		}		/* If we find another "proper" descriptor then we're done  */		if ((header->bDescriptorType == USB_DT_ENDPOINT) ||		    (header->bDescriptorType == USB_DT_INTERFACE) ||		    (header->bDescriptorType == USB_DT_CONFIG) ||		    (header->bDescriptorType == USB_DT_DEVICE))			break;		dbg("skipping descriptor 0x%X",			header->bDescriptorType);		numskipped++;		buffer += header->bLength;		size -= header->bLength;		parsed += header->bLength;	}	if (numskipped)		dbg("skipped %d class/vendor specific endpoint descriptors", numskipped);	/* Copy any unknown descriptors into a storage area for drivers */	/*  to later parse */	len = (int)(buffer - begin);	if (!len) {		endpoint->extra = NULL;		endpoint->extralen = 0;		return parsed;	}	endpoint->extra = kmalloc(len, GFP_KERNEL);	if (!endpoint->extra) {		err("couldn't allocate memory for endpoint extra descriptors");		endpoint->extralen = 0;		return parsed;	}	memcpy(endpoint->extra, begin, len);	endpoint->extralen = len;	return parsed;}static int usb_parse_interface(struct usb_interface *interface, unsigned char *buffer, int size){	int i, len, numskipped, retval, parsed = 0;	struct usb_descriptor_header *header;	struct usb_interface_descriptor *ifp;	unsigned char *begin;	interface->act_altsetting = 0;	interface->num_altsetting = 0;	interface->max_altsetting = USB_ALTSETTINGALLOC;	interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * interface->max_altsetting, GFP_KERNEL);		if (!interface->altsetting) {		err("couldn't kmalloc interface->altsetting");		return -1;	}	while (size > 0) {		if (interface->num_altsetting >= interface->max_altsetting) {			void *ptr;			int oldmas;			oldmas = interface->max_altsetting;			interface->max_altsetting += USB_ALTSETTINGALLOC;			if (interface->max_altsetting > USB_MAXALTSETTING) {				warn("too many alternate settings (max %d)",					USB_MAXALTSETTING);				return -1;			}			ptr = interface->altsetting;			interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * interface->max_altsetting, GFP_KERNEL);			if (!interface->altsetting) {				err("couldn't kmalloc interface->altsetting");				interface->altsetting = ptr;				return -1;			}			memcpy(interface->altsetting, ptr, sizeof(struct usb_interface_descriptor) * oldmas);			kfree(ptr);		}		ifp = interface->altsetting + interface->num_altsetting;		ifp->endpoint = NULL;		ifp->extra = NULL;		ifp->extralen = 0;		interface->num_altsetting++;		memcpy(ifp, buffer, USB_DT_INTERFACE_SIZE);		/* Skip over the interface */		buffer += ifp->bLength;		parsed += ifp->bLength;		size -= ifp->bLength;		begin = buffer;		numskipped = 0;		/* Skip over any interface, class or vendor descriptors */		while (size >= sizeof(struct usb_descriptor_header)) {			header = (struct usb_descriptor_header *)buffer;			if (header->bLength < 2) {				err("invalid descriptor length of %d", header->bLength);				return -1;			}			/* If we find another "proper" descriptor then we're done  */			if ((header->bDescriptorType == USB_DT_INTERFACE) ||			    (header->bDescriptorType == USB_DT_ENDPOINT) ||			    (header->bDescriptorType == USB_DT_CONFIG) ||			    (header->bDescriptorType == USB_DT_DEVICE))				break;			numskipped++;			buffer += header->bLength;			parsed += header->bLength;			size -= header->bLength;		}		if (numskipped)			dbg("skipped %d class/vendor specific interface descriptors", numskipped);		/* Copy any unknown descriptors into a storage area for */		/*  drivers to later parse */		len = (int)(buffer - begin);		if (len) {			ifp->extra = kmalloc(len, GFP_KERNEL);			if (!ifp->extra) {				err("couldn't allocate memory for interface extra descriptors");				ifp->extralen = 0;				return -1;			}			memcpy(ifp->extra, begin, len);			ifp->extralen = len;		}		/* Did we hit an unexpected descriptor? */		header = (struct usb_descriptor_header *)buffer;		if ((size >= sizeof(struct usb_descriptor_header)) &&		    ((header->bDescriptorType == USB_DT_CONFIG) ||		     (header->bDescriptorType == USB_DT_DEVICE)))			return parsed;		if (ifp->bNumEndpoints > USB_MAXENDPOINTS) {			warn("too many endpoints");			return -1;		}		ifp->endpoint = (struct usb_endpoint_descriptor *)			kmalloc(ifp->bNumEndpoints *			sizeof(struct usb_endpoint_descriptor), GFP_KERNEL);		if (!ifp->endpoint) {			err("out of memory");			return -1;			}		memset(ifp->endpoint, 0, ifp->bNumEndpoints *			sizeof(struct usb_endpoint_descriptor));			for (i = 0; i < ifp->bNumEndpoints; i++) {			header = (struct usb_descriptor_header *)buffer;			if (header->bLength > size) {				err("ran out of descriptors parsing");				return -1;			}					retval = usb_parse_endpoint(ifp->endpoint + i, buffer, size);			if (retval < 0)				return retval;			buffer += retval;			parsed += retval;			size -= retval;		}		/* We check to see if it's an alternate to this one */		ifp = (struct usb_interface_descriptor *)buffer;		if (size < USB_DT_INTERFACE_SIZE ||		    ifp->bDescriptorType != USB_DT_INTERFACE ||		    !ifp->bAlternateSetting)			return parsed;	}	return parsed;}int usb_parse_configuration(struct usb_config_descriptor *config, char *buffer){	int i, retval, size;	struct usb_descriptor_header *header;	memcpy(config, buffer, USB_DT_CONFIG_SIZE);	le16_to_cpus(&config->wTotalLength);	size = config->wTotalLength;	if (config->bNumInterfaces > USB_MAXINTERFACES) {		warn("too many interfaces");		return -1;	}	config->interface = (struct usb_interface *)		kmalloc(config->bNumInterfaces *		sizeof(struct usb_interface), GFP_KERNEL);	dbg("kmalloc IF %p, numif %i", config->interface, config->bNumInterfaces);	if (!config->interface) {		err("out of memory");		return -1;		}	memset(config->interface, 0,	       config->bNumInterfaces * sizeof(struct usb_interface));	buffer += config->bLength;	size -= config->bLength;		config->extra = NULL;	config->extralen = 0;	for (i = 0; i < config->bNumInterfaces; i++) {		int numskipped, len;		char *begin;		/* Skip over the rest of the Class Specific or Vendor */		/*  Specific descriptors */		begin = buffer;		numskipped = 0;		while (size >= sizeof(struct usb_descriptor_header)) {			header = (struct usb_descriptor_header *)buffer;			if ((header->bLength > size) || (header->bLength < 2)) {				err("invalid descriptor length of %d", header->bLength);				return -1;			}			/* If we find another "proper" descriptor then we're done  */			if ((header->bDescriptorType == USB_DT_ENDPOINT) ||			    (header->bDescriptorType == USB_DT_INTERFACE) ||			    (header->bDescriptorType == USB_DT_CONFIG) ||			    (header->bDescriptorType == USB_DT_DEVICE))				break;			dbg("skipping descriptor 0x%X", header->bDescriptorType);			numskipped++;			buffer += header->bLength;			size -= header->bLength;		}		if (numskipped)			dbg("skipped %d class/vendor specific endpoint descriptors", numskipped);		/* Copy any unknown descriptors into a storage area for */		/*  drivers to later parse */		len = (int)(buffer - begin);		if (len) {			if (config->extralen) {				warn("extra config descriptor");			} else {				config->extra = kmalloc(len, GFP_KERNEL);				if (!config->extra) {					err("couldn't allocate memory for config extra descriptors");					config->extralen = 0;					return -1;				}				memcpy(config->extra, begin, len);				config->extralen = len;			}		}		retval = usb_parse_interface(config->interface + i, buffer, size);		if (retval < 0)			return retval;		buffer += retval;		size -= retval;	}	return size;}// hub-only!! ... and only exported for reset/reinit path.// otherwise used internally on disconnect/destroy pathvoid usb_destroy_configuration(struct usb_device *dev){	int c, i, j, k;		if (!dev->config)		return;	if (dev->rawdescriptors) {		for (i = 0; i < dev->descriptor.bNumConfigurations; i++)			kfree(dev->rawdescriptors[i]);		kfree(dev->rawdescriptors);	}	for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {		struct usb_config_descriptor *cf = &dev->config[c];		if (!cf->interface)			break;		for (i = 0; i < cf->bNumInterfaces; i++) {			struct usb_interface *ifp =				&cf->interface[i];							if (!ifp->altsetting)				break;			for (j = 0; j < ifp->num_altsetting; j++) {				struct usb_interface_descriptor *as =					&ifp->altsetting[j];									if(as->extra) {					kfree(as->extra);				}				if (!as->endpoint)					break;									for(k = 0; k < as->bNumEndpoints; k++) {					if(as->endpoint[k].extra) {						kfree(as->endpoint[k].extra);					}				}					kfree(as->endpoint);			}			kfree(ifp->altsetting);		}		kfree(cf->interface);	}	kfree(dev->config);}/* for returning string descriptors in UTF-16LE */static int ascii2utf (char *ascii, __u8 *utf, int utfmax){	int retval;	for (retval = 0; *ascii && utfmax > 1; utfmax -= 2, retval += 2) {		*utf++ = *ascii++ & 0x7f;		*utf++ = 0;	}	return retval;}/* * root_hub_string is used by each host controller's root hub code, * so that they're identified consistently throughout the system. */int usb_root_hub_string (int id, int serial, char *type, __u8 *data, int len){	char buf [30];	// assert (len > (2 * (sizeof (buf) + 1)));	// assert (strlen (type) <= 8);	// language ids	if (id == 0) {		*data++ = 4; *data++ = 3;	/* 4 bytes data */		*data++ = 0; *data++ = 0;	/* some language id */		return 4;	// serial number	} else if (id == 1) {		sprintf (buf, "%x", serial);	// product description	} else if (id == 2) {		sprintf (buf, "USB %s Root Hub", type);	// id 3 == vendor description	// unsupported IDs --> "stall"	} else	    return 0;	data [0] = 2 + ascii2utf (buf, data + 2, len - 2);

⌨️ 快捷键说明

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