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

📄 ezusb.c

📁 Usb1.1驱动c语言源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	struct async *as = NULL;	void *data = NULL;	unsigned int pipe;	int ret;	if (ab->len > PAGE_SIZE)		return -EINVAL;	if ((ab->ep & ~0x80) >= 16)		return -EINVAL;	if (ab->ep & 0x80) {		pipe = usb_rcvbulkpipe(ez->usbdev, ab->ep & 0x7f);		if (ab->len > 0 && !access_ok(VERIFY_WRITE, ab->data, ab->len))			return -EFAULT;	} else		pipe = usb_sndbulkpipe(ez->usbdev, ab->ep & 0x7f);	if (!usb_maxpacket(ez->usbdev, pipe, !(ab->ep & 0x80)))		return -EINVAL;	if (ab->len > 0 && !(data = kmalloc(ab->len, GFP_KERNEL)))		return -ENOMEM;	if (!(as = alloc_async(0))) {		if (data)			kfree(data);		return -ENOMEM;	}	INIT_LIST_HEAD(&as->asynclist);	as->ez = ez;	as->userdata = ab->data;	as->datalen = ab->len;	as->context = ab->context;	as->urb.dev = ez->usbdev;	as->urb.pipe = pipe;	as->urb.transfer_flags = 0;	as->urb.transfer_buffer = data;	as->urb.transfer_buffer_length = ab->len;	as->urb.context = as;	as->urb.complete = (usb_complete_t)async_completed;	if (ab->len > 0 && !(ab->ep & 0x80)) {		if (copy_from_user(data, ab->data, ab->len)) {			free_async(as);			return -EFAULT;		}		as->userdata = NULL; /* no need to copy back at completion */	}	async_newpending(as);	if ((ret = usb_submit_urb(&as->urb))) { printk(KERN_DEBUG "ezusb: bulk: usb_submit_urb returned %d\n", ret);		async_removepending(as);		free_async(as);		return -EINVAL; /* return ret; */	}	return 0;}static int ezusb_requestiso(struct ezusb *ez, struct ezusb_asynciso *ai, unsigned char *cmd){	struct async *as;	void *data = NULL;	unsigned int maxpkt, pipe, dsize, totsize, i, j;	int ret;	if ((ai->ep & ~0x80) >= 16 || ai->framecnt < 1 || ai->framecnt > 128)		return -EINVAL;	if (ai->ep & 0x80)		pipe = usb_rcvisocpipe(ez->usbdev, ai->ep & 0x7f);	else		pipe = usb_sndisocpipe(ez->usbdev, ai->ep & 0x7f);	if (!(maxpkt = usb_maxpacket(ez->usbdev, pipe, !(ai->ep & 0x80))))		return -EINVAL;	dsize = maxpkt * ai->framecnt;//printk(KERN_DEBUG "ezusb: iso: dsize %d\n", dsize);	if (dsize > 65536) 		return -EINVAL;	if (ai->ep & 0x80)		if (dsize > 0 && !access_ok(VERIFY_WRITE, ai->data, dsize))			return -EFAULT;	if (dsize > 0 && !(data = kmalloc(dsize, GFP_KERNEL)))	{		printk("dsize: %d failed\n",dsize);		return -ENOMEM;	}	if (!(as = alloc_async(ai->framecnt))) {		if (data)			kfree(data);		printk("alloc_async failed\n");					return -ENOMEM;	}	INIT_LIST_HEAD(&as->asynclist);		as->ez = ez;	as->userdata = ai->data;	as->datalen = dsize;	as->context = ai->context;		as->urb.dev = ez->usbdev;	as->urb.pipe = pipe;	as->urb.transfer_flags = USB_ISO_ASAP;	as->urb.transfer_buffer = data;	as->urb.transfer_buffer_length = dsize;	as->urb.context = as;	as->urb.complete = (usb_complete_t)async_completed;	for (i = totsize = 0; i < as->urb.number_of_packets; i++) {		as->urb.iso_frame_desc[i].offset = totsize;		if (get_user(j, (int *)(cmd + i * sizeof(struct ezusb_isoframestat)))) {			free_async(as);			return -EFAULT;		}		as->urb.iso_frame_desc[i].length = j;		totsize += j;	}	if (dsize > 0 && totsize > 0 && !(ai->ep & 0x80)) {		if (copy_from_user(data, ai->data, totsize)) {			free_async(as);			return -EFAULT;		}		as->userdata = NULL; /* no need to copy back at completion */	}	async_newpending(as);	if ((ret = usb_submit_urb(&as->urb))) { printk(KERN_DEBUG "ezusb: iso: usb_submit_urb returned %d\n", ret);		async_removepending(as);		free_async(as);		return -EINVAL; /* return ret; */	}	return 0;}static int ezusb_terminateasync(struct ezusb *ez, void *context){	struct async *as;	int ret = 0;	while ((as = async_getpending(ez, context))) {		usb_unlink_urb(&as->urb);		ret++;	}	return ret;}static int ezusb_asynccompl(struct async *as, void *arg){	struct ezusb_asynccompleted *cpl;	unsigned int numframes, cplsize, i;	if (as->userdata) {		if (copy_to_user(as->userdata, as->urb.transfer_buffer, as->datalen)) {			free_async(as);			return -EFAULT;		}	}	numframes = as->urb.number_of_packets;	cplsize = sizeof(struct ezusb_asynccompleted) + numframes * sizeof(struct ezusb_isoframestat);	if (!(cpl = kmalloc(cplsize, GFP_KERNEL))) {		free_async(as);		return -ENOMEM;	}	cpl->status = as->urb.status;	cpl->length = as->urb.actual_length;	cpl->context = as->context;	for (i = 0; i < numframes; i++) {		cpl->isostat[i].length = as->urb.iso_frame_desc[i].length;		cpl->isostat[i].status = as->urb.iso_frame_desc[i].status;	}	free_async(as);	if (copy_to_user(arg, cpl, cplsize)) {		kfree(cpl);		return -EFAULT;	}	kfree(cpl);	return 0;}static int ezusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	struct ezusb *ez = (struct ezusb *)file->private_data;	DECLARE_WAITQUEUE(wait, current);	struct usb_proc_ctrltransfer pctrl;	struct usb_proc_bulktransfer pbulk;	struct usb_proc_old_ctrltransfer opctrl;	struct usb_proc_old_bulktransfer opbulk;	struct usb_proc_setinterface psetintf;	struct ezusb_ctrltransfer ctrl;	struct ezusb_bulktransfer bulk;	struct ezusb_old_ctrltransfer octrl;	struct ezusb_old_bulktransfer obulk;	struct ezusb_setinterface setintf;	struct ezusb_asyncbulk abulk;	struct ezusb_asynciso aiso;	struct ezusb_interrupt ezint;	struct async *as;	void *context;	unsigned int ep, cfg;	int i, ret = 0;	down(&ez->mutex);	if (!ez->usbdev) {		up(&ez->mutex);		return -EIO;	}	switch (cmd) {	case USB_PROC_CONTROL:		if (copy_from_user(&pctrl, (void *)arg, sizeof(pctrl))) {			ret = -EFAULT;			break;		}		ret = ezusb_control(ez->usbdev, pctrl.requesttype, pctrl.request, 				    pctrl.value, pctrl.index, pctrl.length, 				    (pctrl.timeout * HZ + 500) / 1000, pctrl.data);		break;	case USB_PROC_BULK:		if (copy_from_user(&pbulk, (void *)arg, sizeof(pbulk))) {			ret = -EFAULT;			break;		}		ret = ezusb_bulk(ez->usbdev, pbulk.ep, pbulk.len, 				 (pbulk.timeout * HZ + 500) / 1000, pbulk.data);		break;	case USB_PROC_OLD_CONTROL:		if (copy_from_user(&opctrl, (void *)arg, sizeof(opctrl))) {			ret = -EFAULT;			break;		}		ret = ezusb_control(ez->usbdev, opctrl.requesttype, opctrl.request, 				    opctrl.value, opctrl.index, opctrl.length, HZ, opctrl.data);		break;	case USB_PROC_OLD_BULK:		if (copy_from_user(&opbulk, (void *)arg, sizeof(opbulk))) {			ret = -EFAULT;			break;		}		ret = ezusb_bulk(ez->usbdev, opbulk.ep, opbulk.len, 5*HZ, opbulk.data);		break;	case USB_PROC_RESETEP:		if (get_user(ep, (unsigned int *)arg)) {			ret = -EFAULT;			break;		}		ret = ezusb_resetep(ez->usbdev, ep);		break;		case USB_PROC_SETINTERFACE:		if (copy_from_user(&psetintf, (void *)arg, sizeof(psetintf))) {			ret = -EFAULT;			break;		}		ret = ezusb_setinterface(ez->usbdev, psetintf.interface, psetintf.altsetting);		break;	case USB_PROC_SETCONFIGURATION:		if (get_user(cfg, (unsigned int *)arg)) {			ret = -EFAULT;			break;		}		ret = ezusb_setconfiguration(ez->usbdev, cfg);		break;	case EZUSB_CONTROL:		if (copy_from_user(&ctrl, (void *)arg, sizeof(ctrl))) {			ret = -EFAULT;			break;		}		ret = ezusb_control(ez->usbdev, ctrl.requesttype, ctrl.request, 				    ctrl.value, ctrl.index, ctrl.length, 				    (ctrl.timeout * HZ + 500) / 1000, ctrl.data);		break;	case EZUSB_BULK:		if (copy_from_user(&bulk, (void *)arg, sizeof(bulk))) {			ret = -EFAULT;			break;		}		ret = ezusb_bulk(ez->usbdev, bulk.ep, bulk.len, 				 (bulk.timeout * HZ + 500) / 1000, bulk.data);		break;	case EZUSB_OLD_CONTROL:		if (copy_from_user(&octrl, (void *)arg, sizeof(octrl))) {			ret = -EFAULT;			break;		}		if (octrl.dlen != octrl.length) {			ret = -EINVAL;			break;		}		ret = ezusb_control(ez->usbdev, octrl.requesttype, octrl.request, 				    octrl.value, octrl.index, octrl.length, HZ, octrl.data);		break;	case EZUSB_OLD_BULK:		if (copy_from_user(&obulk, (void *)arg, sizeof(obulk))) {			ret = -EFAULT;			break;		}		ret = ezusb_bulk(ez->usbdev, obulk.ep, obulk.len, 5*HZ, obulk.data);		break;	case EZUSB_RESETEP:		if (get_user(ep, (unsigned int *)arg)) {			ret = -EFAULT;			break;		}		ret = ezusb_resetep(ez->usbdev, ep);		break;		case EZUSB_SETINTERFACE:		if (copy_from_user(&setintf, (void *)arg, sizeof(setintf))) {			ret = -EFAULT;			break;		}		ret = ezusb_setinterface(ez->usbdev, setintf.interface, setintf.altsetting);		break;	case EZUSB_SETCONFIGURATION:		if (get_user(cfg, (unsigned int *)arg)) {			ret = -EFAULT;			break;		}		ret = ezusb_setconfiguration(ez->usbdev, cfg);		break;	case EZUSB_ASYNCCOMPLETED:		as = NULL;		current->state = TASK_INTERRUPTIBLE;		add_wait_queue(&ez->wait, &wait);		for (;;) {			if (!ez->usbdev)				break;			if ((as = async_getcompleted(ez)))				break;			if (signal_pending(current))				break;			up(&ez->mutex);			schedule();			down(&ez->mutex);		}		remove_wait_queue(&ez->wait, &wait);		current->state = TASK_RUNNING;		if (as) {			ret = ezusb_asynccompl(as, (void *)arg);			break;		}		if (signal_pending(current)) {			ret = -EINTR;			break;		}		ret = -EIO;		break;	case EZUSB_ASYNCCOMPLETEDNB:		if ((as = async_getcompleted(ez))) {			ret = ezusb_asynccompl(as, (void *)arg);			break;		}		ret = -EAGAIN;		break;	case EZUSB_REQUESTBULK:		if (copy_from_user(&abulk, (void *)arg, sizeof(abulk))) {			ret = -EFAULT;			break;		}		ret = ezusb_requestbulk(ez, &abulk);		break;		case EZUSB_REQUESTISO:		if (copy_from_user(&aiso, (void *)arg, sizeof(aiso))) {			ret = -EFAULT;			break;		}		ret = ezusb_requestiso(ez, &aiso, ((unsigned char *)arg)+sizeof(aiso));		break;	case EZUSB_TERMINATEASYNC:		if (get_user(context, (void **)arg)) {			ret = -EFAULT;			break;		}		ret = ezusb_terminateasync(ez, context);		break;	case EZUSB_GETFRAMENUMBER:		i = usb_get_current_frame_number(ez->usbdev);		ret = put_user(i, (int *)arg);		break;	case EZUSB_INTERRUPT:	  printk("INT START\n");		if (copy_from_user(&ezint, (void *)arg, sizeof(ezint))) {			ret = -EFAULT;			break;		}		ret=ezusb_interrupt(ez,&ezint);		break;	default:		ret = -ENOIOCTLCMD;		break;	}	up(&ez->mutex);	return ret;}static struct file_operations ezusb_fops = {	ezusb_llseek,	ezusb_read,	ezusb_write,	NULL,  /* readdir */	NULL,  /* poll */	ezusb_ioctl,	NULL,  /* mmap */	ezusb_open,	NULL,  /* flush */	ezusb_release,	NULL,  /* fsync */	NULL,  /* fasync */	NULL   /* lock */};/* --------------------------------------------------------------------- */static void * ezusb_probe(struct usb_device *usbdev, unsigned int ifnum){	struct ezusb *ez = &ezusb[0];	struct usb_interface_descriptor *interface;	struct usb_endpoint_descriptor *endpoint;#undef KERN_DEBUG#define KERN_DEBUG ""	printk(KERN_DEBUG "ezusb: probe: vendor id 0x%x, device id 0x%x\n",	       usbdev->descriptor.idVendor, usbdev->descriptor.idProduct);	/* the 1234:5678 is just a self assigned test ID */	if ((usbdev->descriptor.idVendor != 0x0547 || usbdev->descriptor.idProduct != 0x2131) 	#if 1		&&	    (usbdev->descriptor.idVendor != 0x0547 || usbdev->descriptor.idProduct != 0x9999) &&	    (usbdev->descriptor.idVendor != 0x1234 || usbdev->descriptor.idProduct != 0x5678)	   #endif 	    )		return NULL;	/* We don't handle multiple configurations */	if (usbdev->descriptor.bNumConfigurations != 1)		return NULL;#if 0	/* We don't handle multiple interfaces */	if (usbdev->config[0].bNumInterfaces != 1)		return NULL;#endif	down(&ez->mutex);	if (ez->usbdev) {		up(&ez->mutex);		printk(KERN_INFO "ezusb: device already used\n");		return NULL;	}	ez->usbdev = usbdev;	if (usb_set_configuration(usbdev, usbdev->config[0].bConfigurationValue) < 0) {		printk(KERN_ERR "ezusb: set_configuration failed\n");		goto err;	}	interface = &usbdev->config[0].interface[0].altsetting[1];	if (usb_set_interface(usbdev, 0, 1) < 0) {		printk(KERN_ERR "ezusb: set_interface failed\n");		goto err;	}	up(&ez->mutex);	MOD_INC_USE_COUNT;	return ez; err:	up(&ez->mutex);	ez->usbdev = NULL;	return NULL;}static void ezusb_disconnect(struct usb_device *usbdev, void *ptr){	struct ezusb *ez = (struct ezusb *)ptr;	down(&ez->mutex);	destroy_all_async(ez);	ez->usbdev = NULL;	up(&ez->mutex);	wake_up(&ez->wait);	MOD_DEC_USE_COUNT;}static struct usb_driver ezusb_driver = {	"ezusb",	ezusb_probe,	ezusb_disconnect,	{ NULL, NULL },	&ezusb_fops,	192};/* --------------------------------------------------------------------- */int ezusb_init(void){	unsigned u;	/* initialize struct */	for (u = 0; u < NREZUSB; u++) {		init_MUTEX(&ezusb[u].mutex);		ezusb[u].usbdev = NULL;		INIT_LIST_HEAD(&ezusb[u].async_pending);		INIT_LIST_HEAD(&ezusb[u].async_completed);		init_waitqueue_head(&ezusb[u].wait);		spin_lock_init(&ezusb[u].lock);	}	/* register misc device */	usb_register(&ezusb_driver);	printk(KERN_INFO "ezusb: Anchorchip firmware download driver registered\n");	return 0;}void ezusb_cleanup(void){	usb_deregister(&ezusb_driver);}/* --------------------------------------------------------------------- */#ifdef MODULEint minor = 192;int init_module(void){	return ezusb_init();}void cleanup_module(void){	ezusb_cleanup();}#endif/* --------------------------------------------------------------------- */

⌨️ 快捷键说明

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