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

📄 dabusb.c

📁 基于S3CEB2410平台LINUX操作系统下 USB驱动源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	dbg("pending_io: %d", s->pending_io.counter);	s->pending_io.counter = 0;	return 0;}static int dabusb_startrek (pdabusb_t s){	if (!s->got_mem && s->state != _started) {		dbg("dabusb_startrek");		if (dabusb_alloc_buffers (s) < 0)			return -ENOMEM;		dabusb_stop (s);		s->state = _started;		s->readptr = 0;	}	if (!list_empty (&s->free_buff_list)) {		pbuff_t end;		int ret;			while (!dabusb_add_buf_tail (s, &s->rec_buff_list, &s->free_buff_list)) {			dbg("submitting: end:%p s->rec_buff_list:%p", s->rec_buff_list.prev, &s->rec_buff_list);			end = list_entry (s->rec_buff_list.prev, buff_t, buff_list);			ret = usb_submit_urb (end->purb);			if (ret) {				err("usb_submit_urb returned:%d", ret);				if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))					err("startrek: dabusb_add_buf_tail failed");				break;			}			else				atomic_inc (&s->pending_io);		}		dbg("pending_io: %d",s->pending_io.counter);	}	return 0;}static ssize_t dabusb_read (struct file *file, char *buf, size_t count, loff_t * ppos){	pdabusb_t s = (pdabusb_t) file->private_data;	unsigned long flags;	unsigned ret = 0;	int rem;	int cnt;	pbuff_t b;	purb_t purb = NULL;	dbg("dabusb_read");	if (*ppos)		return -ESPIPE;	if (s->remove_pending)		return -EIO;	if (!s->usbdev)		return -EIO;	while (count > 0) {		dabusb_startrek (s);		spin_lock_irqsave (&s->lock, flags);		if (list_empty (&s->rec_buff_list)) {			spin_unlock_irqrestore(&s->lock, flags);			err("error: rec_buf_list is empty");			goto err;		}				b = list_entry (s->rec_buff_list.next, buff_t, buff_list);		purb = b->purb;		spin_unlock_irqrestore(&s->lock, flags);		if (purb->status == -EINPROGRESS) {			if (file->f_flags & O_NONBLOCK)		// return nonblocking			 {				if (!ret)					ret = -EAGAIN;				goto err;			}			interruptible_sleep_on (&s->wait);			if (signal_pending (current)) {				if (!ret)					ret = -ERESTARTSYS;				goto err;			}			spin_lock_irqsave (&s->lock, flags);			if (list_empty (&s->rec_buff_list)) {				spin_unlock_irqrestore(&s->lock, flags);				err("error: still no buffer available.");				goto err;			}			spin_unlock_irqrestore(&s->lock, flags);			s->readptr = 0;		}		if (s->remove_pending) {			ret = -EIO;			goto err;		}		rem = purb->actual_length - s->readptr;		// set remaining bytes to copy		if (count >= rem)			cnt = rem;		else			cnt = count;		dbg("copy_to_user:%p %p %d",buf, purb->transfer_buffer + s->readptr, cnt);		if (copy_to_user (buf, purb->transfer_buffer + s->readptr, cnt)) {			err("read: copy_to_user failed");			if (!ret)				ret = -EFAULT;			goto err;		}		s->readptr += cnt;		count -= cnt;		buf += cnt;		ret += cnt;		if (s->readptr == purb->actual_length) {			// finished, take next buffer			if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))				err("read: dabusb_add_buf_tail failed");			s->readptr = 0;		}	}      err:			//up(&s->mutex);	return ret;}static int dabusb_open (struct inode *inode, struct file *file){	int devnum = MINOR (inode->i_rdev);	pdabusb_t s;	if (devnum < DABUSB_MINOR || devnum >= (DABUSB_MINOR + NRDABUSB))		return -EIO;	s = &dabusb[devnum - DABUSB_MINOR];	dbg("dabusb_open");	down (&s->mutex);	while (!s->usbdev || s->opened) {		up (&s->mutex);		if (file->f_flags & O_NONBLOCK) {			return -EBUSY;		}		schedule_timeout (HZ / 2);		if (signal_pending (current)) {			return -EAGAIN;		}		down (&s->mutex);	}	if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {		err("set_interface failed");		return -EINVAL;	}	s->opened = 1;	up (&s->mutex);	file->f_pos = 0;	file->private_data = s;	return 0;}static int dabusb_release (struct inode *inode, struct file *file){	pdabusb_t s = (pdabusb_t) file->private_data;	dbg("dabusb_release");	lock_kernel();	down (&s->mutex);	dabusb_stop (s);	dabusb_free_buffers (s);	up (&s->mutex);	if (!s->remove_pending) {		if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0)			err("set_interface failed");	}	else		wake_up (&s->remove_ok);	s->opened = 0;	unlock_kernel();	return 0;}static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	pdabusb_t s = (pdabusb_t) file->private_data;	pbulk_transfer_t pbulk;	int ret = 0;	int version = DABUSB_VERSION;	dbg("dabusb_ioctl");	if (s->remove_pending)		return -EIO;	down (&s->mutex);	if (!s->usbdev) {		up (&s->mutex);		return -EIO;	}	switch (cmd) {	case IOCTL_DAB_BULK:		pbulk = (pbulk_transfer_t) kmalloc (sizeof (bulk_transfer_t), GFP_KERNEL);		if (!pbulk) {			ret = -ENOMEM;			break;		}		if (copy_from_user (pbulk, (void *) arg, sizeof (bulk_transfer_t))) {			ret = -EFAULT;			kfree (pbulk);			break;		}		ret=dabusb_bulk (s, pbulk);		if(ret==0)			ret = copy_to_user ((void *) arg, pbulk, sizeof (bulk_transfer_t));		kfree (pbulk);		break;	case IOCTL_DAB_OVERRUNS:		ret = put_user (s->overruns, (unsigned int *) arg);		break;	case IOCTL_DAB_VERSION:		ret = put_user (version, (unsigned int *) arg);		break;	default:		ret = -ENOIOCTLCMD;		break;	}	up (&s->mutex);	return ret;}static struct file_operations dabusb_fops ={	owner:		THIS_MODULE,	llseek:		no_llseek,	read:		dabusb_read,	ioctl:		dabusb_ioctl,	open:		dabusb_open,	release:	dabusb_release,};static int dabusb_find_struct (void){	int u;	for (u = 0; u < NRDABUSB; u++) {		pdabusb_t s = &dabusb[u];		if (!s->usbdev)			return u;	}	return -1;}/* --------------------------------------------------------------------- */static void *dabusb_probe (struct usb_device *usbdev, unsigned int ifnum,			   const struct usb_device_id *id){	int devnum;	pdabusb_t s;	dbg("dabusb: probe: vendor id 0x%x, device id 0x%x ifnum:%d",	  usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, ifnum);	/* We don't handle multiple configurations */	if (usbdev->descriptor.bNumConfigurations != 1)		return NULL;	if (ifnum != _DABUSB_IF && usbdev->descriptor.idProduct == 0x9999)		return NULL;	devnum = dabusb_find_struct ();	if (devnum == -1)		return NULL;	s = &dabusb[devnum];	down (&s->mutex);	s->remove_pending = 0;	s->usbdev = usbdev;	if (usb_set_configuration (usbdev, usbdev->config[0].bConfigurationValue) < 0) {		err("set_configuration failed");		goto reject;	}	if (usbdev->descriptor.idProduct == 0x2131) {		dabusb_loadmem (s, NULL);		goto reject;	}	else {		dabusb_fpga_download (s, NULL);		if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0) {			err("set_interface failed");			goto reject;		}	}	dbg("bound to interface: %d", ifnum);	up (&s->mutex);	MOD_INC_USE_COUNT;	return s;      reject:	up (&s->mutex);	s->usbdev = NULL;	return NULL;}static void dabusb_disconnect (struct usb_device *usbdev, void *ptr){	pdabusb_t s = (pdabusb_t) ptr;	dbg("dabusb_disconnect");	s->remove_pending = 1;	wake_up (&s->wait);	if (s->state == _started)		sleep_on (&s->remove_ok);	s->usbdev = NULL;	s->overruns = 0;	MOD_DEC_USE_COUNT;}static struct usb_device_id dabusb_ids [] = {	{ USB_DEVICE(0x0547, 0x2131) },	{ USB_DEVICE(0x0547, 0x9999) },	{ }						/* Terminating entry */};MODULE_DEVICE_TABLE (usb, dabusb_ids);static struct usb_driver dabusb_driver ={	name:		"dabusb",	probe:		dabusb_probe,	disconnect:	dabusb_disconnect,	fops:		&dabusb_fops,	minor:		DABUSB_MINOR,	id_table:	dabusb_ids,};/* --------------------------------------------------------------------- */static int __init dabusb_init (void){	unsigned u;	/* initialize struct */	for (u = 0; u < NRDABUSB; u++) {		pdabusb_t s = &dabusb[u];		memset (s, 0, sizeof (dabusb_t));		init_MUTEX (&s->mutex);		s->usbdev = NULL;		s->total_buffer_size = buffers;		init_waitqueue_head (&s->wait);		init_waitqueue_head (&s->remove_ok);		spin_lock_init (&s->lock);		INIT_LIST_HEAD (&s->free_buff_list);		INIT_LIST_HEAD (&s->rec_buff_list);	}	/* register misc device */	if (usb_register(&dabusb_driver))		return -1;	dbg("dabusb_init: driver registered");	info(DRIVER_VERSION ":" DRIVER_DESC);	return 0;}static void __exit dabusb_cleanup (void){	dbg("dabusb_cleanup");	usb_deregister (&dabusb_driver);}/* --------------------------------------------------------------------- */MODULE_AUTHOR( DRIVER_AUTHOR );MODULE_DESCRIPTION( DRIVER_DESC );MODULE_LICENSE("GPL");MODULE_PARM (buffers, "i");MODULE_PARM_DESC (buffers, "Number of buffers (default=256)");module_init (dabusb_init);module_exit (dabusb_cleanup);/* --------------------------------------------------------------------- */

⌨️ 快捷键说明

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