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

📄 proc_usb.c

📁 Usb1.1驱动c语言源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	 * count = device count at this level	 */	/* If this is the root hub, display the bandwidth information */	if (level == 0)		start += sprintf(start, format_bandwidth, bus->bandwidth_allocated, 				FRAME_TIME_MAX_USECS_ALLOC,				(100 * bus->bandwidth_allocated + FRAME_TIME_MAX_USECS_ALLOC / 2) / FRAME_TIME_MAX_USECS_ALLOC,			         bus->bandwidth_int_reqs, bus->bandwidth_isoc_reqs);	/* show the descriptor information for this device */	start = usb_dump_desc(start, end, usbdev);	if (start > end)		return start + sprintf(start, "(truncated)\n");	/* Now look at all of this device's children. */	for (chix = 0; chix < usbdev->maxchild; chix++) {		if (start > end)			return start;		if (usbdev->children[chix])			start = usb_device_dump(start, end, usbdev->children[chix], bus, level + 1, chix, ++cnt);	}	return start;}static ssize_t usb_device_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos){	struct list_head *buslist;	struct usb_bus *bus;	char *page, *end;	ssize_t ret = 0;	unsigned int pos, len;	if (*ppos < 0)		return -EINVAL;	if (nbytes <= 0)		return 0;	if (!access_ok(VERIFY_WRITE, buf, nbytes))		return -EFAULT;	if (!(page = (char*) __get_free_page(GFP_KERNEL)))		return -ENOMEM;	pos = *ppos;	/* enumerate busses */	for (buslist = usb_bus_list.next; buslist != &usb_bus_list; buslist = buslist->next) {		bus = list_entry(buslist, struct usb_bus, bus_list);		end = usb_device_dump(page, page + (PAGE_SIZE - 100), bus->root_hub, bus, 0, 0, 0);		len = end - page;		if (len > pos) {			len -= pos;			if (len > nbytes)				len = nbytes;			if (copy_to_user(buf, page + pos, len)) {				if (!ret)					ret = -EFAULT;				break;			}			nbytes -= len;			buf += len;			ret += len;			pos = 0;			*ppos += len;		} else			pos -= len;	}	free_page((unsigned long)page);	return ret;}static unsigned int usb_device_poll(struct file *file, struct poll_table_struct *wait){	struct usb_device_status *st = (struct usb_device_status *)file->private_data;	unsigned int mask = 0;		if (!st) {		st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL);		if (!st)			return POLLIN;		/*		 * need to prevent the module from being unloaded, since		 * proc_unregister does not call the release method and		 * we would have a memory leak		 */		st->lastev = conndiscevcnt;		file->private_data = st;		MOD_INC_USE_COUNT;		mask = POLLIN;	}	if (file->f_mode & FMODE_READ)		poll_wait(file, &deviceconndiscwq, wait);	if (st->lastev != conndiscevcnt)		mask |= POLLIN;	st->lastev = conndiscevcnt;	return mask;}static int usb_device_open(struct inode *inode, struct file *file){	file->private_data = NULL;	MOD_INC_USE_COUNT;	return 0;}static int usb_device_release(struct inode *inode, struct file *file){	if (file->private_data) {		kfree(file->private_data);		file->private_data = NULL;	}	MOD_DEC_USE_COUNT;		return 0;}/* * Dump usb_driver_list. * * We now walk the list of registered USB drivers. */static ssize_t usb_driver_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos){	struct list_head *tmp = usb_driver_list.next;	char *page, *start, *end;	ssize_t ret = 0;	unsigned int pos, len;	if (*ppos < 0)		return -EINVAL;	if (nbytes <= 0)		return 0;	if (!access_ok(VERIFY_WRITE, buf, nbytes))		return -EFAULT;	if (!(page = (char*) __get_free_page(GFP_KERNEL)))		return -ENOMEM;	start = page;	end = page + (PAGE_SIZE - 100);	pos = *ppos;	for (; tmp != &usb_driver_list; tmp = tmp->next) {		struct usb_driver *driver = list_entry(tmp, struct usb_driver, driver_list);		start += sprintf (start, "%s\n", driver->name);		if (start > end) {			start += sprintf(start, "(truncated)\n");			break;		}	}	if (start == page)		start += sprintf(start, "(none)\n");	len = start - page;	if (len > pos) {		len -= pos;		if (len > nbytes)			len = nbytes;		ret = len;		if (copy_to_user(buf, page + pos, len))			ret = -EFAULT;		else			*ppos += len;	}	free_page((unsigned long)page);	return ret;}static long long usbdev_lseek(struct file * file, long long offset, int orig);static struct file_operations proc_usb_devlist_file_operations = {	usbdev_lseek,       /* lseek   */	usb_device_read,    /* read    */	NULL,               /* write   */	NULL,               /* readdir */	usb_device_poll,    /* poll    */	NULL,               /* ioctl   */	NULL,               /* mmap    */	usb_device_open,    /* open    */	NULL,               /* flush   */	usb_device_release, /* release */	NULL                /* fsync   */};static struct inode_operations proc_usb_devlist_inode_operations = {	&proc_usb_devlist_file_operations,  /* file-ops */};static struct file_operations proc_usb_drvlist_file_operations = {	usbdev_lseek,    /* lseek   */	usb_driver_read, /* read    */	NULL,            /* write   */	NULL,            /* readdir */	NULL,            /* poll    */	NULL,            /* ioctl   */	NULL,            /* mmap    */	NULL,            /* no special open code    */	NULL,            /* flush */	NULL,            /* no special release code */	NULL             /* can't fsync */};static struct inode_operations proc_usb_drvlist_inode_operations = {	&proc_usb_drvlist_file_operations,  /* file-ops */};/* * proc entry for every device */static long long usbdev_lseek(struct file * file, long long offset, int orig){	switch (orig) {	case 0:		file->f_pos = offset;		return file->f_pos;	case 1:		file->f_pos += offset;		return file->f_pos;	case 2:		return -EINVAL;	default:		return -EINVAL;	}}static ssize_t usbdev_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos){	struct inode *inode = file->f_dentry->d_inode;	struct proc_dir_entry *dp = (struct proc_dir_entry *)inode->u.generic_ip;	struct usb_device *dev = (struct usb_device *)dp->data;	ssize_t ret = 0;	unsigned len;	if (*ppos < 0)		return -EINVAL;	if (*ppos < sizeof(struct usb_device_descriptor)) {		len = sizeof(struct usb_device_descriptor);		if (len > nbytes)			len = nbytes;		copy_to_user_ret(buf, ((char *)&dev->descriptor) + *ppos, len, -EFAULT);		*ppos += len;		buf += len;		nbytes -= len;		ret += len;	}	return ret;}/* note: this is a compatibility kludge that will vanish soon. */#include "ezusb.h"static int usbdev_ioctl_ezusbcompat(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	static unsigned obsolete_warn = 0;	struct proc_dir_entry *dp = (struct proc_dir_entry *)inode->u.generic_ip;	struct usb_device *dev = (struct usb_device *)dp->data;	struct ezusb_ctrltransfer ctrl;	struct ezusb_bulktransfer bulk;	struct ezusb_old_ctrltransfer octrl;	struct ezusb_old_bulktransfer obulk;	struct ezusb_setinterface setintf;	unsigned int len1, ep, pipe, cfg;	int len2;	unsigned char *tbuf;	int i;	switch (cmd) {	case EZUSB_CONTROL:		if (obsolete_warn < 20) {			printk(KERN_WARNING "/proc/bus/usb: process %d (%s) used obsolete EZUSB_CONTROL ioctl\n",			       current->pid, current->comm);			obsolete_warn++;		}		if (!capable(CAP_SYS_RAWIO))			return -EPERM;		copy_from_user_ret(&ctrl, (void *)arg, sizeof(ctrl), -EFAULT);		if (ctrl.length > PAGE_SIZE)			return -EINVAL;		if (!(tbuf = (unsigned char *)__get_free_page(GFP_KERNEL)))			return -ENOMEM;		if (ctrl.requesttype & 0x80) {			if (ctrl.length && !access_ok(VERIFY_WRITE, ctrl.data, ctrl.length)) {				free_page((unsigned long)tbuf);				return -EINVAL;			}			i = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ctrl.request, ctrl.requesttype,					    ctrl.value, ctrl.index, tbuf, ctrl.length, 					    (ctrl.timeout * HZ + 500) / 1000);			if ((i > 0) && ctrl.length) {				copy_to_user_ret(ctrl.data, tbuf, ctrl.length, -EFAULT);			}		} else {			if (ctrl.length) {				copy_from_user_ret(tbuf, ctrl.data, ctrl.length, -EFAULT);			}			i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.request, ctrl.requesttype,					    ctrl.value, ctrl.index, tbuf, ctrl.length, 					    (ctrl.timeout * HZ + 500) / 1000);		}		free_page((unsigned long)tbuf);		if (i < 0) {			printk(KERN_WARNING "procusb: EZUSB_CONTROL failed rqt %u rq %u len %u ret %d\n", 			       ctrl.requesttype, ctrl.request, ctrl.length, i);			return i;		}		return i;	case EZUSB_BULK:		if (obsolete_warn < 20) {			printk(KERN_WARNING "/proc/bus/usb: process %d (%s) used obsolete EZUSB_BULK ioctl\n",			       current->pid, current->comm);			obsolete_warn++;		}		if (!capable(CAP_SYS_RAWIO))			return -EPERM;		copy_from_user_ret(&bulk, (void *)arg, sizeof(bulk), -EFAULT);		if (bulk.ep & 0x80)			pipe = usb_rcvbulkpipe(dev, bulk.ep & 0x7f);		else			pipe = usb_sndbulkpipe(dev, bulk.ep & 0x7f);		if (!usb_maxpacket(dev, pipe, !(bulk.ep & 0x80)))			return -EINVAL;		len1 = bulk.len;		if (len1 > PAGE_SIZE)			len1 = PAGE_SIZE;		if (!(tbuf = (unsigned char *)__get_free_page(GFP_KERNEL)))			return -ENOMEM;		if (bulk.ep & 0x80) {			if (len1 && !access_ok(VERIFY_WRITE, bulk.data, len1)) {				free_page((unsigned long)tbuf);				return -EINVAL;			}			i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, (ctrl.timeout * HZ + 500) / 1000);			if ((i > 0) && len2) {				copy_to_user_ret(bulk.data, tbuf, len2, -EFAULT);			}		} else {			if (len1) {				copy_from_user_ret(tbuf, bulk.data, len1, -EFAULT);			}			i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, (ctrl.timeout * HZ + 500) / 1000);		}		free_page((unsigned long)tbuf);		if (i < 0) {			printk(KERN_WARNING "procusb: EZUSB_BULK failed ep 0x%x len %u ret %d\n", 			       bulk.ep, bulk.len, i);			return i;		}		return len2;	case EZUSB_OLD_CONTROL:		if (obsolete_warn < 20) {			printk(KERN_WARNING "/proc/bus/usb: process %d (%s) used obsolete EZUSB_OLD_CONTROL ioctl\n",			       current->pid, current->comm);			obsolete_warn++;		}		if (!capable(CAP_SYS_RAWIO))			return -EPERM;		copy_from_user_ret(&octrl, (void *)arg, sizeof(octrl), -EFAULT);		if (octrl.dlen > PAGE_SIZE)			return -EINVAL;		if (!(tbuf = (unsigned char *)__get_free_page(GFP_KERNEL)))			return -ENOMEM;		if (octrl.requesttype & 0x80) {			if (octrl.dlen && !access_ok(VERIFY_WRITE, octrl.data, octrl.dlen)) {				free_page((unsigned long)tbuf);				return -EINVAL;			}			i = usb_internal_control_msg(dev, usb_rcvctrlpipe(dev, 0), (devrequest *)&octrl, tbuf, octrl.dlen, HZ);			if ((i > 0) && octrl.dlen) {				copy_to_user_ret(octrl.data, tbuf, octrl.dlen, -EFAULT);			}		} else {			if (octrl.dlen) {				copy_from_user_ret(tbuf, octrl.data, octrl.dlen, -EFAULT);			}			i = usb_internal_control_msg(dev, usb_sndctrlpipe(dev, 0), (devrequest *)&octrl, tbuf, octrl.dlen, HZ);					}		free_page((unsigned long)tbuf);		if (i < 0) {			printk(KERN_WARNING "procusb: EZUSB_OLD_CONTROL failed rqt %u rq %u len %u ret %d\n", 			       octrl.requesttype, octrl.request, octrl.length, i);			return i;		}		return i;	case EZUSB_OLD_BULK:		if (obsolete_warn < 20) {			printk(KERN_WARNING "/proc/bus/usb: process %d (%s) used obsolete EZUSB_OLD_BULK ioctl\n",			       current->pid, current->comm);			obsolete_warn++;		}		if (!capable(CAP_SYS_RAWIO))			return -EPERM;		copy_from_user_ret(&obulk, (void *)arg, sizeof(obulk), -EFAULT);

⌨️ 快捷键说明

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