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

📄 proc_usb.c

📁 Usb1.1驱动c语言源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		if (obulk.ep & 0x80)			pipe = usb_rcvbulkpipe(dev, obulk.ep & 0x7f);		else			pipe = usb_sndbulkpipe(dev, obulk.ep & 0x7f);		if (!usb_maxpacket(dev, pipe, !(obulk.ep & 0x80)))			return -EINVAL;		len1 = obulk.len;		if (len1 > PAGE_SIZE)			len1 = PAGE_SIZE;		if (!(tbuf = (unsigned char *)__get_free_page(GFP_KERNEL)))			return -ENOMEM;		if (obulk.ep & 0x80) {			if (len1 && !access_ok(VERIFY_WRITE, obulk.data, len1)) {				free_page((unsigned long)tbuf);				return -EINVAL;			}			i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, HZ*5);			if ((i > 0) && len2) {				copy_to_user_ret(obulk.data, tbuf, len2, -EFAULT);			}		} else {			if (len1) {				copy_from_user_ret(tbuf, obulk.data, len1, -EFAULT);			}			i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, HZ*5);		}		free_page((unsigned long)tbuf);		if (i < 0) {			printk(KERN_WARNING "procusb: EZUSB_OLD_BULK failed ep 0x%x len %u ret %d\n", 			       obulk.ep, obulk.len, i);			return i;		}		return len2;	case EZUSB_RESETEP:		if (obsolete_warn < 20) {			printk(KERN_WARNING "/proc/bus/usb: process %d (%s) used obsolete EZUSB_RESETEP ioctl\n",			       current->pid, current->comm);			obsolete_warn++;		}		if (!capable(CAP_SYS_RAWIO))			return -EPERM;		get_user_ret(ep, (unsigned int *)arg, -EFAULT);		if ((ep & ~0x80) >= 16)			return -EINVAL;		usb_settoggle(dev, ep & 0xf, !(ep & 0x80), 0);		return 0;	case EZUSB_SETINTERFACE:		if (obsolete_warn < 20) {			printk(KERN_WARNING "/proc/bus/usb: process %d (%s) used obsolete EZUSB_SETINTERFACE ioctl\n",			       current->pid, current->comm);			obsolete_warn++;		}		if (!capable(CAP_SYS_RAWIO))			return -EPERM;		copy_from_user_ret(&setintf, (void *)arg, sizeof(setintf), -EFAULT);		if (usb_set_interface(dev, setintf.interface, setintf.altsetting))			return -EINVAL;		return 0;	case EZUSB_SETCONFIGURATION:		if (obsolete_warn < 20) {			printk(KERN_WARNING "/proc/bus/usb: process %d (%s) used obsolete EZUSB_SETCONFIGURATION ioctl\n",			       current->pid, current->comm);			obsolete_warn++;		}		if (!capable(CAP_SYS_RAWIO))			return -EPERM;		get_user_ret(cfg, (unsigned int *)arg, -EFAULT);		if (usb_set_configuration(dev, cfg) < 0)			return -EINVAL;		return 0;	}	return -ENOIOCTLCMD;}static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	struct proc_dir_entry *dp = (struct proc_dir_entry *)inode->u.generic_ip;	struct usb_device *dev = (struct usb_device *)dp->data;	struct usb_proc_ctrltransfer ctrl;	struct usb_proc_bulktransfer bulk;	struct usb_proc_old_ctrltransfer octrl;	struct usb_proc_old_bulktransfer obulk;	struct usb_proc_setinterface setintf;	unsigned int len1, ep, pipe, cfg;	int len2;	unsigned char *tbuf;	int i;	switch (cmd) {	case USB_PROC_CONTROL:		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 "/proc/bus/usb: USB_PROC_CONTROL failed rqt %u rq %u len %u ret %d\n", 			       ctrl.requesttype, ctrl.request, ctrl.length, i);			return i;		}		return 0;	case USB_PROC_BULK:		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, (bulk.timeout * HZ + 500) / 1000);			if (!i && 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, (bulk.timeout * HZ + 500) / 1000);		}		free_page((unsigned long)tbuf);		if (i) {			printk(KERN_WARNING "/proc/bus/usb: USB_PROC_BULK failed ep 0x%x len %u ret %d\n", 			       bulk.ep, bulk.len, i);			return -ENXIO;		}		return len2;	case USB_PROC_OLD_CONTROL:		if (!capable(CAP_SYS_RAWIO))			return -EPERM;		copy_from_user_ret(&octrl, (void *)arg, sizeof(octrl), -EFAULT);		if (octrl.length > PAGE_SIZE)			return -EINVAL;		if (!(tbuf = (unsigned char *)__get_free_page(GFP_KERNEL)))			return -ENOMEM;		if (octrl.requesttype & 0x80) {			if (octrl.length && !access_ok(VERIFY_WRITE, octrl.data, octrl.length)) {				free_page((unsigned long)tbuf);				return -EINVAL;			}			i = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), octrl.request, 					    octrl.requesttype, octrl.value, octrl.index, tbuf, 					    octrl.length, HZ);			if ((i > 0) && octrl.length) {				copy_to_user_ret(octrl.data, tbuf, octrl.length, -EFAULT);			}		} else {			if (octrl.length) {				copy_from_user_ret(tbuf, octrl.data, octrl.length, -EFAULT);			}			i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), octrl.request, 					    octrl.requesttype, octrl.value, octrl.index, tbuf, 					    octrl.length, HZ);		}		free_page((unsigned long)tbuf);		if (i < 0) {			printk(KERN_WARNING "/proc/bus/usb: USB_PROC_OLD_CONTROL failed rqt %u rq %u len %u ret %d\n", 			       octrl.requesttype, octrl.request, octrl.length, i);			return i;		}		return 0;	case USB_PROC_OLD_BULK:		if (!capable(CAP_SYS_RAWIO))			return -EPERM;		copy_from_user_ret(&obulk, (void *)arg, sizeof(obulk), -EFAULT);		if (obulk.ep & 0x80)			pipe = usb_rcvbulkpipe(dev, obulk.ep & 0x7f);		else			pipe = usb_sndbulkpipe(dev, obulk.ep & 0x7f);		if (!usb_maxpacket(dev, pipe, !(obulk.ep & 0x80)))			return -EINVAL;		len1 = obulk.len;		if (len1 > PAGE_SIZE)			len1 = PAGE_SIZE;		if (!(tbuf = (unsigned char *)__get_free_page(GFP_KERNEL)))			return -ENOMEM;		if (obulk.ep & 0x80) {			if (len1 && !access_ok(VERIFY_WRITE, obulk.data, len1)) {				free_page((unsigned long)tbuf);				return -EINVAL;			}			i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, HZ*5);			if ((i > 0) && len2) {				copy_to_user_ret(obulk.data, tbuf, len2, -EFAULT);			}		} else {			if (len1) {				copy_from_user_ret(tbuf, obulk.data, len1, -EFAULT);			}			i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, HZ*5);		}		free_page((unsigned long)tbuf);		if (i < 0) {			printk(KERN_WARNING "/proc/bus/usb: USB_PROC_OLD_BULK failed ep 0x%x len %u ret %d\n", 			       obulk.ep, obulk.len, i);			return i;		}		return len2;	case USB_PROC_RESETEP:		if (!capable(CAP_SYS_RAWIO))			return -EPERM;		get_user_ret(ep, (unsigned int *)arg, -EFAULT);		if ((ep & ~0x80) >= 16)			return -EINVAL;		usb_settoggle(dev, ep & 0xf, !(ep & 0x80), 0);		return 0;	case USB_PROC_SETINTERFACE:		if (!capable(CAP_SYS_RAWIO))			return -EPERM;		copy_from_user_ret(&setintf, (void *)arg, sizeof(setintf), -EFAULT);		if (usb_set_interface(dev, setintf.interface, setintf.altsetting))			return -EINVAL;		return 0;	case USB_PROC_SETCONFIGURATION:		if (!capable(CAP_SYS_RAWIO))			return -EPERM;		get_user_ret(cfg, (unsigned int *)arg, -EFAULT);		if (usb_set_configuration(dev, cfg) < 0)			return -EINVAL;		return 0;	case EZUSB_CONTROL:	case EZUSB_BULK:	case EZUSB_OLD_CONTROL:	case EZUSB_OLD_BULK:	case EZUSB_RESETEP:	case EZUSB_SETINTERFACE:	case EZUSB_SETCONFIGURATION:		return usbdev_ioctl_ezusbcompat(inode, file, cmd, arg);	}	return -ENOIOCTLCMD;}static struct file_operations proc_usb_device_file_operations = {	usbdev_lseek,    /* lseek   */	usbdev_read,     /* read    */	NULL,            /* write   */	NULL,            /* readdir */	NULL,            /* poll    */	usbdev_ioctl,    /* 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_device_inode_operations = {	&proc_usb_device_file_operations,  /* file-ops */};void proc_usb_add_bus(struct usb_bus *bus){	char buf[16];	bus->proc_entry = NULL;	if (!usbdir)		return;	sprintf(buf, "%03d", bus->busnum);#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,31)	if (!(bus->proc_entry = create_proc_entry(buf, S_IFDIR, usbdir)))#else	if (!(bus->proc_entry = proc_mkdir(buf, usbdir)))#endif		return;	bus->proc_entry->data = bus;	conndiscevent();}/* devices need already be removed! */void proc_usb_remove_bus(struct usb_bus *bus){	if (!bus->proc_entry)		return;	remove_proc_entry(bus->proc_entry->name, usbdir);	conndiscevent();}void proc_usb_add_device(struct usb_device *dev){	char buf[16];	dev->proc_entry = NULL;	if (!dev->bus->proc_entry)		return;	sprintf(buf, "%03d", dev->devnum);	if (!(dev->proc_entry = create_proc_entry(buf, 0, dev->bus->proc_entry)))		return;	dev->proc_entry->ops = &proc_usb_device_inode_operations;	dev->proc_entry->data = dev;	conndiscevent();}void proc_usb_remove_device(struct usb_device *dev){	if (dev->proc_entry)		remove_proc_entry(dev->proc_entry->name, dev->bus->proc_entry);	conndiscevent();}void proc_usb_cleanup (void){	if (driversdir)		remove_proc_entry("drivers", usbdir);	if (devicesdir)		remove_proc_entry("devices", usbdir);	if (usbdir)		remove_proc_entry("usb", proc_bus);}int proc_usb_init (void){#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,31)	usbdir = create_proc_entry("usb", S_IFDIR, proc_bus);#else	usbdir = proc_mkdir("usb", proc_bus);#endif		if (!usbdir) {		printk ("proc_usb: cannot create /proc/bus/usb entry\n");		return -1;	}	driversdir = create_proc_entry("drivers", 0, usbdir);	if (!driversdir) {		printk ("proc_usb: cannot create /proc/bus/usb/drivers entry\n");		proc_usb_cleanup();		return -1;	}	driversdir->ops = &proc_usb_drvlist_inode_operations;	devicesdir = create_proc_entry("devices", 0, usbdir);	if (!devicesdir) {		printk ("proc_usb: cannot create /proc/bus/usb/devices entry\n");		proc_usb_cleanup ();		return -1;	}	devicesdir->ops = &proc_usb_devlist_inode_operations;	return 0;}/* end proc_usb.c */

⌨️ 快捷键说明

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