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

📄 usb.c

📁 Usb1.1驱动c语言源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	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;		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 at 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 descriptor which is at or below */			/*  us in the descriptor heirarchy then return */			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 = NULL;			ifp->extralen = 0;		} else {			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(dev, 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_device *dev, struct usb_config_descriptor *config, char *buffer){	int i;	int retval;	int size;	struct usb_descriptor_header *header;	memcpy(config, buffer, USB_DT_INTERFACE_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;		for (i = 0; i < config->bNumInterfaces; i++) {		header = (struct usb_descriptor_header *)buffer;		if ((header->bLength > size) || (header->bLength <= 2)) {			err("ran out of descriptors parsing");			return -1;		}				if (header->bDescriptorType != USB_DT_INTERFACE) {			warn("unexpected descriptor 0x%X",				header->bDescriptorType);			buffer += header->bLength;			size -= header->bLength;			continue;		}		retval = usb_parse_interface(dev, config->interface + i, buffer, size);		if (retval < 0)			return retval;		buffer += retval;		size -= retval;	}	return size;}void usb_destroy_configuration(struct usb_device *dev){	int c, i, j, k;		if (!dev->config)		return;	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);}			void usb_init_root_hub(struct usb_device *dev){	dev->devnum = -1;	dev->slow = 0;	dev->actconfig = NULL;}/* * __usb_get_extra_descriptor() finds a descriptor of specific type in the * extra field of the interface and endpoint descriptor structs. */int __usb_get_extra_descriptor(char *buffer, unsigned size, unsigned char type, void **ptr){	struct usb_descriptor_header *header;	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 (header->bDescriptorType == type) {			*ptr = header;			return 0;		}		buffer += header->bLength;		size -= header->bLength;	}	return -1;}/* * Something got disconnected. Get rid of it, and all of its children. */void usb_disconnect(struct usb_device **pdev){	struct usb_device * dev = *pdev;	int i;	if (!dev)		return;	*pdev = NULL;	info("USB disconnect on device %d", dev->devnum);	if (dev->actconfig) {		for (i = 0; i < dev->actconfig->bNumInterfaces; i++) {			struct usb_interface *interface = &dev->actconfig->interface[i];			struct usb_driver *driver = interface->driver;			if (driver) {				driver->disconnect(dev, interface->private_data);				usb_driver_release_interface(driver, interface);			}		}	}	/* Free up all the children.. */	for (i = 0; i < USB_MAXCHILDREN; i++) {		struct usb_device **child = dev->children + i;		if (*child)			usb_disconnect(child);	}	/* remove /proc/bus/usb entry */        usbdevfs_remove_device(dev);	/* Free up the device itself, including its device number */	if (dev->devnum > 0)		clear_bit(dev->devnum, &dev->bus->devmap.devicemap);		usb_free_dev(dev);	}/* * Connect a new USB device. This basically just initializes * the USB device information and sets up the topology - it's * up to the low-level driver to reset the port and actually * do the setup (the upper levels don't know how to do that). */void usb_connect(struct usb_device *dev){	int devnum;	// FIXME needs locking for SMP!!	/* why? this is called only from the hub thread, 	 * which hopefully doesn't run on multiple CPU's simulatenously 8-)	 */	dev->descriptor.bMaxPacketSize0 = 8;  /* Start off at 8 bytes  */	devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, 1);	if (devnum < 128) {		set_bit(devnum, dev->bus->devmap.devicemap);		dev->devnum = devnum;	}}/* * These are the actual routines to send * and receive control messages. */#define GET_TIMEOUT 3#define SET_TIMEOUT 3int usb_set_address(struct usb_device *dev){	return usb_control_msg(dev, usb_snddefctrl(dev), USB_REQ_SET_ADDRESS,		0, dev->devnum, 0, NULL, 0, HZ * GET_TIMEOUT);}int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size){	int i = 5;	int result;		memset(buf,0,size);	// Make sure we parse really received data	while (i--) {		if ((result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),			USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,			(type << 8) + index, 0, buf, size, HZ * GET_TIMEOUT)) >= 0 ||		     result == -EPIPE)			break;	}	return result;}int usb_get_class_descriptor(struct usb_device *dev, int ifnum,		unsigned char type, unsigned char id, void *buf, int size){	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),		USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN,		(type << 8) + id, ifnum, buf, size, HZ * GET_TIMEOUT);}int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char index, void *buf, int size){	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),		USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,		(USB_DT_STRING << 8) + index, langid, buf, size, HZ * GET_TIMEOUT);}int usb_get_device_descriptor(struct usb_device *dev){	int ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor,				     sizeof(dev->descriptor));	if (ret >= 0) {		le16_to_cpus(&dev->descriptor.bcdUSB);		le16_to_cpus(&dev->descriptor.idVendor);		le16_to_cpus(&dev->descriptor.idProduct);		le16_to_cpus(&dev->descriptor.bcdDevice);	}	return ret;}int usb_get_status(struct usb_device *dev, int type, int target, void *data){	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),		USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, data, 2, HZ * GET_TIMEOUT);}int usb_get_protocol(struct usb_device *dev, int ifnum){	unsigned char type;	int ret;	if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),	    USB_REQ_GET_PROTOCOL, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,	    0, ifnum, &type, 1, HZ * GET_TIMEOUT)) < 0)		return ret;	return type;}int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol){	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),		USB_REQ_SET_PROTOCOL, USB_TYPE_CLASS | USB_RECIP_INTERFACE,		protocol, ifnum, NULL, 0, HZ * SET_TIMEOUT);}int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id){	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),		USB_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE,		(duration << 8) | report_id, ifnum, NULL, 0, HZ * SET_TIMEOUT);}static void usb_set_maxpacket(struct usb_device *dev){	int i, j, b;	struct usb_interface *ifp;	for (i=0; i<dev->actconfig->bNumInterfaces; i++) {		ifp = dev->actconfig->interface + i;		for (j = 0; j < ifp->num_altsetting; j++) {			struct usb_interface_descriptor *as = ifp->altsetting + j;			struct usb_endpoint_descriptor *ep = as->endpoint;			int e;			for (e=0; e<as->bNumEndpoints; e++) {				b = ep[e].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;				if ((ep[e].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==					USB_ENDPOINT_XFER_CONTROL) {	/* Control => bidirectional */					dev->epmaxpacketout[b] = ep[e].wMaxPacketSize;					dev->epmaxpacketin [b] = ep[e].wMaxPacketSize;					}				else if (usb_endpoint_out(ep[e].bEndpointAddress)) {					if (ep[e].wMaxPacketSize > dev->epmaxpacketout[b])						dev->epmaxpacketout[b] = ep[e].wMaxPacketSize;				}				else {					if (ep[e].wMaxPacketSize > dev->epmaxpacketin [b])						dev->epmaxpacketin [b] = ep[e].wMaxPacketSize;

⌨️ 快捷键说明

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