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

📄 fs2410-usbcon.1.1.c

📁 此压缩文件是linux的usb驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
				up(&dev->limit_sem);				if (buf)				{					kfree(buf);				}				return 0;L_SEND_BULKDATA_ERR:				up(&dev->limit_sem);				if (buf)				{					kfree(buf);				}				return -1;			}			return 0;			break;		case IOCTL_GET_ARM_OUTPUT:			{				if (copy_from_user(&ctlData, (const void *)arg, sizeof(struct IOCTL_DATA_IO)))				{					retval = -EFAULT;					return -1;				}				if (ctlData.length > 0)				{					iosize = min(ctlData.length, (size_t)MAX_TRANSFER);					/* limit the number of URBs in flight to stop a user from using up all RAM */					if (down_interruptible(&dev->limit_sem))					{						retval = -ERESTARTSYS;						goto L_GET_OUTPUT_ERR_1;					}					spin_lock_irq(&dev->err_lock);					if ((retval = dev->errors) < 0)					{						/* any error is reported once */						dev->errors = 0;						/* to preserve notifications about reset */						retval = (retval == -EPIPE) ? retval : -EIO;					}					spin_unlock_irq(&dev->err_lock);					if (retval < 0)						goto L_GET_OUTPUT_ERR_1;					/* allocate memory */					buf = kzalloc(iosize, GFP_KERNEL);					if (!buf) 					{						err("Out of memory");						retval = -ENOMEM;						goto L_GET_OUTPUT_ERR_1;					}					/* this lock makes sure we don't submit URBs to gone devices */					mutex_lock(&dev->io_mutex);					if (!dev->interface) 					{/* disconnect() was called */						mutex_unlock(&dev->io_mutex);						retval = -ENODEV;						goto L_GET_OUTPUT_ERR_1;					}					/* get the data buffer length */					retval = usb_control_msg(							dev->udev, 							usb_rcvctrlpipe(dev->udev, 0),							PIPO0_GET_ARM_OUTPUT_LENGTH,							USB_DIR_IN | USB_TYPE_VENDOR,							0, 0, 							ucLen, 4, 							10000);					if (retval < 0)					{						mutex_unlock(&dev->io_mutex);						err("%s - failed controling urb to get buffer lenth, error %d", __FUNCTION__, retval);						goto L_GET_OUTPUT_ERR_1;					}					len = ((int)ucLen[0] << 24) + ((int)ucLen[1] << 16) + ((int)ucLen[2] << 8) + (int)ucLen[3];					if (len < iosize)						iosize = len;					/* get the data buffer */					retval = usb_control_msg(							dev->udev, 							usb_rcvctrlpipe(dev->udev, 0),							PIPO0_GET_ARM_OUTPUT,							USB_DIR_IN | USB_TYPE_VENDOR,							0, 0, 							buf, iosize, 							10000);					mutex_unlock(&dev->io_mutex);					if (retval < 0)					{						err("%s - failed controling urb to get buffer, error %d", __FUNCTION__, retval);						goto L_GET_OUTPUT_ERR_1;					}					if (copy_to_user((void *)ctlData.data, buf, iosize)) 					{						retval = -EFAULT;						goto L_GET_OUTPUT_ERR_1;					}				}				ctlData.length = iosize;				if (copy_to_user((void *)arg, &ctlData, sizeof(struct IOCTL_DATA_IO)))				{					retval = -EFAULT;					goto L_GET_OUTPUT_ERR_1;				}				up(&dev->limit_sem);				if (buf)				{					kfree(buf);				}				return 0;L_GET_OUTPUT_ERR_1:				up(&dev->limit_sem);				if (buf)				{					kfree(buf);				}				return -1;			}			return 0;			break;	}	err("Unknown command");	return -EFAULT;}int fs2410usbcon_ioctl(struct inode * inode_, struct file * filp, unsigned int cmd, unsigned long arg){	struct usb_fs2410usbcon *dev = (struct usb_fs2410usbcon *)filp->private_data;	int retval = 0;	char *buf = NULL;	size_t iosize = 0;	unsigned char ucLen[4];	int len; /* how many bytes can be readed out in the device ? */	struct IOCTL_DATA_IO ctlData;	switch (cmd)	{		case IOCTL_SET_USER_INPUT:			{				if (copy_from_user(&ctlData, (const void *)arg, sizeof(struct IOCTL_DATA_IO)))				{					retval = -EFAULT;					return -1;				}				if (ctlData.length > 0)				{					iosize = min(ctlData.length, (size_t)MAX_TRANSFER);					/* limit the number of URBs in flight to stop a user from using up all RAM */					if (down_interruptible(&dev->limit_sem))					{						retval = -ERESTARTSYS;						goto L_SET_INPUT_ERR_1;					}					spin_lock_irq(&dev->err_lock);					if ((retval = dev->errors) < 0)					{						/* any error is reported once */						dev->errors = 0;						/* to preserve notifications about reset */						retval = (retval == -EPIPE) ? retval : -EIO;					}					spin_unlock_irq(&dev->err_lock);					if (retval < 0)						goto L_SET_INPUT_ERR_1;					/* allocate memory */					buf = kzalloc(iosize, GFP_KERNEL);					if (!buf) 					{						err("Out of memory");						retval = -ENOMEM;						goto L_SET_INPUT_ERR_1;					}					if (copy_from_user(buf, ctlData.data, iosize)) 					{						retval = -EFAULT;						goto L_SET_INPUT_ERR_1;					}					/* this lock makes sure we don't submit URBs to gone devices */					mutex_lock(&dev->io_mutex);					if (!dev->interface) 					{/* disconnect() was called */						mutex_unlock(&dev->io_mutex);						retval = -ENODEV;						goto L_SET_INPUT_ERR_1;					}					/* send the data out */					retval = usb_control_msg(							dev->udev, 							usb_sndctrlpipe(dev->udev, 0),							PIPO0_SET_USER_INPUT,							USB_DIR_OUT | USB_TYPE_VENDOR,							0, 0, 							buf, iosize, 							10000);					mutex_unlock(&dev->io_mutex);					if (retval < 0)					{						err("%s - failed controling urb, error %d", __FUNCTION__, retval);						goto L_SET_INPUT_ERR_1;					}				}				ctlData.length = iosize;				if (copy_to_user((void *)arg, &ctlData, sizeof(struct IOCTL_DATA_IO)))				{					retval = -EFAULT;					goto L_SET_INPUT_ERR_1;				}				up(&dev->limit_sem);				if (buf)				{					kfree(buf);				}				return 0;L_SET_INPUT_ERR_1:				up(&dev->limit_sem);				if (buf)				{					kfree(buf);				}				return -1;			}			return 0;			break;		case IOCTL_GET_ARM_OUTPUT:			{				if (copy_from_user(&ctlData, (const void *)arg, sizeof(struct IOCTL_DATA_IO)))				{					retval = -EFAULT;					return -1;				}				if (ctlData.length > 0)				{					iosize = min(ctlData.length, (size_t)MAX_TRANSFER);					/* limit the number of URBs in flight to stop a user from using up all RAM */					if (down_interruptible(&dev->limit_sem))					{						retval = -ERESTARTSYS;						goto L_GET_OUTPUT_ERR_1;					}					spin_lock_irq(&dev->err_lock);					if ((retval = dev->errors) < 0)					{						/* any error is reported once */						dev->errors = 0;						/* to preserve notifications about reset */						retval = (retval == -EPIPE) ? retval : -EIO;					}					spin_unlock_irq(&dev->err_lock);					if (retval < 0)						goto L_GET_OUTPUT_ERR_1;					/* allocate memory */					buf = kzalloc(iosize, GFP_KERNEL);					if (!buf) 					{						err("Out of memory");						retval = -ENOMEM;						goto L_GET_OUTPUT_ERR_1;					}					/* this lock makes sure we don't submit URBs to gone devices */					mutex_lock(&dev->io_mutex);					if (!dev->interface) 					{/* disconnect() was called */						mutex_unlock(&dev->io_mutex);						retval = -ENODEV;						goto L_GET_OUTPUT_ERR_1;					}					/* get the data buffer length */					retval = usb_control_msg(							dev->udev, 							usb_rcvctrlpipe(dev->udev, 0),							PIPO0_GET_ARM_OUTPUT_LENGTH,							USB_DIR_IN | USB_TYPE_VENDOR,							0, 0, 							ucLen, 4, 							10000);					if (retval < 0)					{						mutex_unlock(&dev->io_mutex);						err("%s - failed controling urb to get buffer lenth, error %d", __FUNCTION__, retval);						goto L_GET_OUTPUT_ERR_1;					}					len = ((int)ucLen[0] << 24) + ((int)ucLen[1] << 16) + ((int)ucLen[2] << 8) + (int)ucLen[3];					if (len < iosize)						iosize = len;					/* get the data buffer */					retval = usb_control_msg(							dev->udev, 							usb_rcvctrlpipe(dev->udev, 0),							PIPO0_GET_ARM_OUTPUT,							USB_DIR_IN | USB_TYPE_VENDOR,							0, 0, 							buf, iosize, 							10000);					mutex_unlock(&dev->io_mutex);					if (retval < 0)					{						err("%s - failed controling urb to get buffer, error %d", __FUNCTION__, retval);						goto L_GET_OUTPUT_ERR_1;					}					if (copy_to_user((void *)ctlData.data, buf, iosize)) 					{						retval = -EFAULT;						goto L_GET_OUTPUT_ERR_1;					}				}				ctlData.length = iosize;				if (copy_to_user((void *)arg, &ctlData, sizeof(struct IOCTL_DATA_IO)))				{					retval = -EFAULT;					goto L_GET_OUTPUT_ERR_1;				}				up(&dev->limit_sem);				if (buf)				{					kfree(buf);				}				return 0;L_GET_OUTPUT_ERR_1:				up(&dev->limit_sem);				if (buf)				{					kfree(buf);				}				return -1;			}			return 0;			break;	}	err("Unknown command");	return -EFAULT;}static const struct file_operations fs2410usbcon_fops = {	.owner =	THIS_MODULE,	.read =		fs2410usbcon_read2,	.write =	fs2410usbcon_write2,	.ioctl =	fs2410usbcon_ioctl,	.open =		fs2410usbcon_open,	.release =	fs2410usbcon_release,	.flush =	fs2410usbcon_flush,};/* * usb class driver info in order to get a minor number from the usb core, * and to have the device registered with the driver core */static struct usb_class_driver fs2410usbcon_class = {	.name =		"fs2410usbcon%d",	.fops =		&fs2410usbcon_fops,	.minor_base =	USB_FS2410USBCON_MINOR_BASE,};static int fs2410usbcon_probe(struct usb_interface *interface, const struct usb_device_id *id){	struct usb_fs2410usbcon *dev;	struct usb_host_interface *iface_desc;	struct usb_endpoint_descriptor *endpoint;	size_t buffer_size;	int i;	int retval = -ENOMEM;	/* allocate memory for our device state and initialize it */	dev = kzalloc(sizeof(*dev), GFP_KERNEL);	if (!dev) {		err("Out of memory");		goto error;	}	kref_init(&dev->kref);	sema_init(&dev->limit_sem, WRITES_IN_FLIGHT);	mutex_init(&dev->io_mutex);	spin_lock_init(&dev->err_lock);	init_usb_anchor(&dev->submitted);	dev->udev = usb_get_dev(interface_to_usbdev(interface));	dev->interface = interface;	/* set up the endpoint information */	/* use only the first bulk-in and bulk-out endpoints */	iface_desc = interface->cur_altsetting;	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {		endpoint = &iface_desc->endpoint[i].desc;		if (!dev->bulk_in_endpointAddr &&		    usb_endpoint_is_bulk_in(endpoint)) {			/* we found a bulk in endpoint */			buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);			dev->bulk_in_size = buffer_size;			dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;			dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);			if (!dev->bulk_in_buffer) {				err("Could not allocate bulk_in_buffer");				goto error;			}		}		if (!dev->bulk_out_endpointAddr &&		    usb_endpoint_is_bulk_out(endpoint)) {			/* we found a bulk out endpoint */			dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;		}	}	if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {		err("Could not find both bulk-in and bulk-out endpoints");		goto error;	}	/* save our data pointer in this interface device */	usb_set_intfdata(interface, dev);	/* we can register the device now, as it is ready */	retval = usb_register_dev(interface, &fs2410usbcon_class);	if (retval) {		/* something prevented us from registering this driver */		err("Not able to get a minor for this device.");		usb_set_intfdata(interface, NULL);		goto error;	}	/* let the user know what node this device is now attached to */	info("USB fs2410usbcon device now attached to USBFS2410usbcon-%d", interface->minor);	return 0;error:	if (dev)		/* this frees allocated memory */		kref_put(&dev->kref, fs2410usbcon_delete);	return retval;}static void fs2410usbcon_disconnnect(struct usb_interface *interface){	struct usb_fs2410usbcon *dev;	int minor = interface->minor;	dev = usb_get_intfdata(interface);	usb_set_intfdata(interface, NULL);	/* give back our minor */	usb_deregister_dev(interface, &fs2410usbcon_class);	/* prevent more I/O from starting */	mutex_lock(&dev->io_mutex);	dev->interface = NULL;	mutex_unlock(&dev->io_mutex);	usb_kill_anchored_urbs(&dev->submitted);	/* decrement our usage count */	kref_put(&dev->kref, fs2410usbcon_delete);	info("USB fs2410usbcon #%d now disconnected", minor);}static void fs2410usbcon_draw_down(struct usb_fs2410usbcon *dev){	int time;	time = usb_wait_anchor_empty_timeout(&dev->submitted, 1000);	if (!time)		usb_kill_anchored_urbs(&dev->submitted);}static int fs2410usbcon_suspend(struct usb_interface *intf, pm_message_t message){	struct usb_fs2410usbcon *dev = usb_get_intfdata(intf);	if (!dev)		return 0;	fs2410usbcon_draw_down(dev);	return 0;}static int fs2410usbcon_resume (struct usb_interface *intf){	return 0;}static int fs2410usbcon_pre_reset(struct usb_interface *intf){	struct usb_fs2410usbcon *dev = usb_get_intfdata(intf);	mutex_lock(&dev->io_mutex);	fs2410usbcon_draw_down(dev);	return 0;}static int fs2410usbcon_post_reset(struct usb_interface *intf){	struct usb_fs2410usbcon *dev = usb_get_intfdata(intf);	/* we are sure no URBs are active - no locking needed */	dev->errors = -EPIPE;	mutex_unlock(&dev->io_mutex);	return 0;}static struct usb_driver fs2410usbcon_driver = {	.name =		"fs2410usbcon",	.probe =	fs2410usbcon_probe,	.disconnect =	fs2410usbcon_disconnnect,	.suspend =	fs2410usbcon_suspend,	.resume =	fs2410usbcon_resume,	.pre_reset =	fs2410usbcon_pre_reset,	.post_reset =	fs2410usbcon_post_reset,	.id_table =	fs2410usbcon_table,	.supports_autosuspend = 1,};static int __init usb_fs2410usbcon_init(void){	int result;	/* register this driver with the USB subsystem */	result = usb_register(&fs2410usbcon_driver);	if (result)		err("usb_register failed. Error number %d", result);	return result;}static void __exit usb_fs2410usbcon_exit(void){	/* deregister this driver with the USB subsystem */	usb_deregister(&fs2410usbcon_driver);}module_init(usb_fs2410usbcon_init);module_exit(usb_fs2410usbcon_exit);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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