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

📄 usb.c

📁 基于S3CEB2410平台LINUX操作系统下 USB驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
				if (ep[e].wMaxPacketSize > dev->epmaxpacketin [b])					dev->epmaxpacketin [b] = ep[e].wMaxPacketSize;			}		}	}}/* * endp: endpoint number in bits 0-3; *	direction flag in bit 7 (1 = IN, 0 = OUT) */int usb_clear_halt(struct usb_device *dev, int pipe){	int result;	__u16 status;#if !defined(CONFIG_USB_UHCI124) && !defined(CONFIG_USB_UHCI124_MODULE)	unsigned char *buffer;#endif	int endp=usb_pipeendpoint(pipe)|(usb_pipein(pipe)<<7);/*	if (!usb_endpoint_halted(dev, endp & 0x0f, usb_endpoint_out(endp)))		return 0;*/	result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),		USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, endp, NULL, 0, HZ * SET_TIMEOUT);	/* don't clear if failed */	if (result < 0)		return result;#if defined(CONFIG_USB_UHCI124) || defined(CONFIG_USB_UHCI124_MODULE)	result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),		USB_REQ_GET_STATUS, USB_DIR_IN | USB_RECIP_ENDPOINT, 0, endp,		&status, sizeof(status), HZ * SET_TIMEOUT);#else	buffer = kmalloc(sizeof(status), GFP_KERNEL);	if (!buffer) {		err("unable to allocate memory for configuration descriptors");		return -ENOMEM;	}	result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),		USB_REQ_GET_STATUS, USB_DIR_IN | USB_RECIP_ENDPOINT, 0, endp,		buffer, sizeof(status), HZ * SET_TIMEOUT);	memcpy(&status, buffer, sizeof(status));	kfree(buffer);#endif	if (result < 0)		return result;	if (le16_to_cpu(status) & 1)		return -EPIPE;		/* still halted */	usb_endpoint_running(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));	/* toggle is reset on clear */	usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0);	return 0;}int usb_set_interface(struct usb_device *dev, int interface, int alternate){	struct usb_interface *iface;	int ret;	iface = usb_ifnum_to_if(dev, interface);	if (!iface) {		warn("selecting invalid interface %d", interface);		return -EINVAL;	}#if !defined(CONFIG_USB_UHCI124) && !defined(CONFIG_USB_UHCI124_MODULE)	/* 9.4.10 says devices don't need this, if the interface	   only has one alternate setting */	if (iface->num_altsetting == 1) {		warn("ignoring set_interface for dev %d, iface %d, alt %d",			dev->devnum, interface, alternate);		return 0;	}#endif	if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),	    USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, alternate,	    interface, NULL, 0, HZ * 5)) < 0)		return ret;	iface->act_altsetting = alternate;	dev->toggle[0] = 0;	/* 9.1.1.5 says to do this */	dev->toggle[1] = 0;	usb_set_maxpacket(dev);	return 0;}int usb_set_configuration(struct usb_device *dev, int configuration){	int i, ret;	struct usb_config_descriptor *cp = NULL;		for (i=0; i<dev->descriptor.bNumConfigurations; i++) {		if (dev->config[i].bConfigurationValue == configuration) {			cp = &dev->config[i];			break;		}	}	if (!cp) {		warn("selecting invalid configuration %d", configuration);		return -EINVAL;	}	if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),	    USB_REQ_SET_CONFIGURATION, 0, configuration, 0, NULL, 0, HZ * SET_TIMEOUT)) < 0)		return ret;	dev->actconfig = cp;	dev->toggle[0] = 0;	dev->toggle[1] = 0;	usb_set_maxpacket(dev);	return 0;}int usb_get_report(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_REPORT, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,		(type << 8) + id, ifnum, buf, size, HZ * GET_TIMEOUT);}int usb_set_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size){	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),		USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,		(type << 8) + id, ifnum, buf, size, HZ);}int usb_get_configuration(struct usb_device *dev){#if defined(CONFIG_USB_UHCI124) || defined(CONFIG_USB_UHCI124_MODULE)#define CFG_LEN 59static __u8 msDevCfg[CFG_LEN] = {0x09,0x02,0x3B,0x00,0x02,0x01,0x01,0xA0,				 0x32,0x09,0x04,0x00,0x00,0x01,0x03,0x01,				 0x01,0x01,0x09,0x21,0x10,0x01,0x00,0x01,				 0x22,0x36,0x00,0x07,0x05,0x81,0x03,0x08,				 0x00,0x0A,0x09,0x04,0x01,0x00,0x01,0x03,				 0x00,0x00,0x01,0x09,0x21,0x10,0x01,0x00,				 0x01,0x22,0x32,0x00,0x07,0x05,0x82,0x03,				 0x03,0x00,0x0A};static __u8 justyDevCfg[CFG_LEN] = {0x09,0x02,0x3B,0x00,0x02,0x01,0x00,0xA0,				    0x32,0x09,0x04,0x00,0x00,0x01,0x03,0x01,				    0x01,0x04,0x09,0x21,0x00,0x01,0x21,0x01,				    0x22,0x40,0x00,0x07,0x05,0x81,0x03,0x08,				    0x00,0x0A,0x09,0x04,0x01,0x00,0x01,0x03,				    0x01,0x02,0x05,0x09,0x21,0x00,0x01,0x21,				    0x01,0x22,0x32,0x00,0x07,0x05,0x82,0x03,				    0x03,0x00,0x0A};#endif	int result;	unsigned int cfgno, length;	unsigned char *bigbuffer;#if !defined(CONFIG_USB_UHCI124) && !defined(CONFIG_USB_UHCI124_MODULE)	unsigned char *buffer; 	struct usb_config_descriptor *desc;#else	unsigned char buffer[8];	struct usb_config_descriptor *desc =		(struct usb_config_descriptor *)buffer;#endif	if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG) {		warn("too many configurations");		return -EINVAL;	}	if (dev->descriptor.bNumConfigurations < 1) {		warn("not enough configurations");		return -EINVAL;	}	dev->config = (struct usb_config_descriptor *)		kmalloc(dev->descriptor.bNumConfigurations *		sizeof(struct usb_config_descriptor), GFP_KERNEL);	if (!dev->config) {		err("out of memory");		return -ENOMEM;		}	memset(dev->config, 0, dev->descriptor.bNumConfigurations *		sizeof(struct usb_config_descriptor));	dev->rawdescriptors = (char **)kmalloc(sizeof(char *) *		dev->descriptor.bNumConfigurations, GFP_KERNEL);	if (!dev->rawdescriptors) {		err("out of memory");		return -ENOMEM;	}#if !defined(CONFIG_USB_UHCI124) && !defined(CONFIG_USB_UHCI124_MODULE)	buffer = kmalloc(8, GFP_KERNEL);	if (!buffer) {		err("unable to allocate memory for configuration descriptors");		return -ENOMEM;	}	desc = (struct usb_config_descriptor *)buffer;#endif	for (cfgno = 0; cfgno < dev->descriptor.bNumConfigurations; cfgno++) {		/* We grab the first 8 bytes so we know how long the whole */		/*  configuration is */		result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8);		if (result < 8) {			if (result < 0)				err("unable to get descriptor");			else {				err("config descriptor too short (expected %i, got %i)", 8, result);				result = -EINVAL;			}			goto err;		}  	  	/* Get the full buffer */		length = le16_to_cpu(desc->wTotalLength);		bigbuffer = kmalloc(length, GFP_KERNEL);		if (!bigbuffer) {			err("unable to allocate memory for configuration descriptors");			result = -ENOMEM;			goto err;		}		/* Now that we know the length, get the whole thing */		result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, length);		if (result < 0) {			err("couldn't get all of config descriptors");			kfree(bigbuffer);			goto err;		}				if (result < length) {#if !defined(CONFIG_USB_UHCI124) && !defined(CONFIG_USB_UHCI124_MODULE)			err("config descriptor too short (expected %i, got %i)", length, result);			result = -EINVAL;			kfree(bigbuffer);			goto err;#else			printk("INFO: new device strings:"			       " vendor=%d, product=%d, device=%d\n",			       dev->descriptor.idVendor,			       dev->descriptor.idProduct,			       dev->descriptor.bcdDevice);			if (dev->descriptor.idVendor == 1118 &&			    dev->descriptor.idProduct == 29) {/* MS */			  memcpy( bigbuffer, msDevCfg, length );			  result = length;			} else if (dev->descriptor.idVendor == 1266 &&				   dev->descriptor.idProduct == 1) {/* Justy */			  memcpy( bigbuffer, justyDevCfg, length );			  result = length;			} else {			  err("config descriptor too short"			      " (expected %i, got %i)", length, result);			  result = -EINVAL;			  kfree(bigbuffer);			  goto err;			}#endif		}		dev->rawdescriptors[cfgno] = bigbuffer;		result = usb_parse_configuration(&dev->config[cfgno], bigbuffer);		if (result > 0)			dbg("descriptor data left");		else if (result < 0) {			result = -EINVAL;			goto err;		}	}#if !defined(CONFIG_USB_UHCI124) && !defined(CONFIG_USB_UHCI124_MODULE)	kfree(buffer);#endif	return 0;err:#if !defined(CONFIG_USB_UHCI124) && !defined(CONFIG_USB_UHCI124_MODULE)	kfree(buffer);#endif	dev->descriptor.bNumConfigurations = cfgno;	return result;}/* * usb_string: *	returns string length (> 0) or error (< 0) */int usb_string(struct usb_device *dev, int index, char *buf, size_t size){	unsigned char *tbuf;	int err;	unsigned int u, idx;	if (size <= 0 || !buf || !index)		return -EINVAL;	buf[0] = 0;	tbuf = kmalloc(256, GFP_KERNEL);	if (!tbuf)		return -ENOMEM;	/* get langid for strings if it's not yet known */	if (!dev->have_langid) {		err = usb_get_string(dev, 0, 0, tbuf, 4);		if (err < 0) {			err("error getting string descriptor 0 (error=%d)", err);			goto errout;		} else if (tbuf[0] < 4) {			err("string descriptor 0 too short");			err = -EINVAL;			goto errout;		} else {			dev->have_langid = -1;			dev->string_langid = tbuf[2] | (tbuf[3]<< 8);				/* always use the first langid listed */			dbg("USB device number %d default language ID 0x%x",				dev->devnum, dev->string_langid);		}	}	/*	 * Just ask for a maximum length string and then take the length	 * that was returned.	 */	err = usb_get_string(dev, dev->string_langid, index, tbuf, 255);	if (err < 0)		goto errout;	size--;		/* leave room for trailing NULL char in output buffer */	for (idx = 0, u = 2; u < err; u += 2) {		if (idx >= size)			break;		if (tbuf[u+1])			/* high byte */			buf[idx++] = '?';  /* non-ASCII character */		else			buf[idx++] = tbuf[u];	}	buf[idx] = 0;	err = idx; errout:	kfree(tbuf);	return err;}/* * By the time we get here, the device has gotten a new device ID * and is in the default state. We need to identify the thing and * get the ball rolling.. * * Returns 0 for success, != 0 for error. */int usb_new_device(struct usb_device *dev){	int err;	/* USB v1.1 5.5.3 */	/* We read the first 8 bytes from the device descriptor to get to */	/*  the bMaxPacketSize0 field. Then we set the maximum packet size */	/*  for the control pipe, and retrieve the rest */	dev->epmaxpacketin [0] = 8;	dev->epmaxpacketout[0] = 8;	err = usb_set_address(dev);	if (err < 0) {		err("USB device not accepting new address=%d (error=%d)",			dev->devnum, err);		clear_bit(dev->devnum, &dev->bus->devmap.devicemap);		dev->devnum = -1;		return 1;	}	wait_ms(10);	/* Let the SET_ADDRESS settle */	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8);	if (err < 8) {		if (err < 0)			err("USB device not responding, giving up (error=%d)", err);		else			err("USB device descriptor short read (expected %i, got %i)", 8, err);		clear_bit(dev->devnum, &dev->bus->devmap.devicemap);		dev->devnum = -1;		return 1;	}	dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0;	dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;	err = usb_get_device_descriptor(dev);#if !defined(CONFIG_USB_UHCI124) && !defined(CONFIG_USB_UHCI124_MODULE)	if (err < (signed)sizeof(dev->descriptor)) {#else	if (err < 18) {#endif		if (err < 0)			err("unable to get device descriptor (error=%d)", err);		else			err("USB device descriptor short read (expected %Zi, got %i)",				sizeof(dev->descriptor), err);			clear_bit(dev->devnum, &dev->bus->devmap.devicemap);		dev->devnum = -1;		return 1;	}	err = usb_get_configuration(dev);	if (err < 0) {		err("unable to get device %d configuration (error=%d)",			dev->devnum, err);		clear_bit(dev->devnum, &dev->bus->devmap.devicemap);		dev->devnum = -1;		return 1;	}	/* we set the default configuration here */	err = usb_set_configuration(dev, dev->config[0].bConfigurationValue);	if (err) {		err("failed to set device %d default configuration (error=%d)",			dev->devnum, err);		clear_bit(dev->devnum, &dev->bus->devmap.devicemap);		dev->devnum = -1;		return 1;	}	dbg("new device strings: Mfr=%d, Product=%d, SerialNumber=%d",		dev->descriptor.iManufacturer, dev->descriptor.iProduct, dev->descriptor.iSerialNumber);#ifdef DEBUG	if (dev->descriptor.iManufacturer)		usb_show_string(dev, "Manufacturer", dev->descriptor.iManufacturer);	if (dev->descriptor.iProduct)		usb_show_string(dev, "Product", dev->descriptor.iProduct);	if (dev->descriptor.iSerialNumber)		usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber);#endif	/* now that the basic setup is over, add a /proc/bus/usb entry */	usbdevfs_add_device(dev);	/* find drivers willing to handle this device */	usb_find_drivers(dev);	/* userspace may load modules and/or configure further */	call_policy ("add", dev);	return 0;}static int usb_open(struct inode * inode, struct file * file){	int minor = MINOR(inode->i_rdev);	struct usb_driver *c = usb_minors[minor/16];	int err = -ENODEV;	struct file_operations *old_fops, *new_fops = NULL;	/*	 * No load-on-demand? Randy, could you ACK that it's really not	 * supposed to be done?					-- AV	 */	if (!c || !(new_fop

⌨️ 快捷键说明

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