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

📄 inode.c

📁 S3C2440ARM9开发板的USB驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
		filp->f_pos++;		i++;		/* fall through */	case 1:		if (filldir(dirent, "..", 2, i, IROOT, DT_DIR) < 0)			return 0;		filp->f_pos++;		i++;		/* fall through */	default:				while (i >= 2 && i < 2+NRSPECIAL) {			spec = &special[filp->f_pos-2];			if (filldir(dirent, spec->name, strlen(spec->name), i, ISPECIAL | (filp->f_pos-2+IROOT), DT_UNKNOWN) < 0)				return 0;			filp->f_pos++;			i++;		}		if (i < 2+NRSPECIAL)			return 0;		i -= 2+NRSPECIAL;		down (&usb_bus_list_lock);		for (list = usb_bus_list.next; list != &usb_bus_list; list = list->next) {			if (i > 0) {				i--;				continue;			}			bus = list_entry(list, struct usb_bus, bus_list);			sprintf(numbuf, "%03d", bus->busnum);			if (filldir(dirent, numbuf, 3, filp->f_pos, IBUS | ((bus->busnum & 0xff) << 8), DT_UNKNOWN) < 0)				break;			filp->f_pos++;		}		up (&usb_bus_list_lock);		return 0;	}}static int bus_readdir(struct usb_device *dev, unsigned long ino, int pos, struct file *filp, void *dirent, filldir_t filldir){	char numbuf[8];	unsigned int i;	if (!dev)		return pos;	sprintf(numbuf, "%03d", dev->devnum);	if (pos > 0)		pos--;	else {		if (filldir(dirent, numbuf, 3, filp->f_pos, ino | (dev->devnum & 0xff), DT_UNKNOWN) < 0)			return -1;		filp->f_pos++;	}	for (i = 0; i < dev->maxchild; i++) {		if (!dev->children[i])			continue;		pos = bus_readdir(dev->children[i], ino, pos, filp, dirent, filldir);		if (pos < 0)			return -1;	}	return pos;}static int usbdevfs_bus_readdir(struct file *filp, void *dirent, filldir_t filldir){	struct inode *inode = filp->f_dentry->d_inode;	unsigned long ino = inode->i_ino;	struct usb_bus *bus;	/* sanity check */	if (ITYPE(ino) != IBUS)		return -EINVAL;	switch ((unsigned int)filp->f_pos) {	case 0:		if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) < 0)			return 0;		filp->f_pos++;		/* fall through */	case 1:		if (filldir(dirent, "..", 2, filp->f_pos, IROOT, DT_DIR) < 0)			return 0;		filp->f_pos++;		/* fall through */	default:		lock_kernel();		bus = usbdevfs_findbus(IBUSNR(ino));		bus_readdir(bus->root_hub, IDEVICE | ((bus->busnum & 0xff) << 8), filp->f_pos-2, filp, dirent, filldir);		unlock_kernel();		return 0;	}}static struct file_operations usbdevfs_root_file_operations = {	readdir: usbdevfs_root_readdir,};static struct inode_operations usbdevfs_root_inode_operations = {	lookup: usbdevfs_root_lookup,};static struct file_operations usbdevfs_bus_file_operations = {	readdir: usbdevfs_bus_readdir,};static struct inode_operations usbdevfs_bus_inode_operations = {	lookup: usbdevfs_bus_lookup,};static void usbdevfs_read_inode(struct inode *inode){	struct special *spec;	inode->i_ctime = inode->i_mtime = inode->i_atime = CURRENT_TIME;	inode->i_mode = S_IFREG;	inode->i_gid = inode->i_uid = 0;	INIT_LIST_HEAD(&inode->u.usbdev_i.dlist);	INIT_LIST_HEAD(&inode->u.usbdev_i.slist);	inode->u.usbdev_i.p.dev = NULL;	inode->u.usbdev_i.p.bus = NULL;	switch (ITYPE(inode->i_ino)) {	case ISPECIAL:		if (inode->i_ino == IROOT) {			inode->i_op = &usbdevfs_root_inode_operations;			inode->i_fop = &usbdevfs_root_file_operations;			inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;			return;		}		if (inode->i_ino <= IROOT || inode->i_ino > IROOT+NRSPECIAL)			return;		spec = &special[inode->i_ino-(IROOT+1)];		inode->i_fop = spec->fops;		return;	case IDEVICE:		return;	case IBUS:		return;	default:		return;        }}static void usbdevfs_put_super(struct super_block *sb){	list_del(&sb->u.usbdevfs_sb.slist);	INIT_LIST_HEAD(&sb->u.usbdevfs_sb.slist);	while (!list_empty(&sb->u.usbdevfs_sb.ilist))		free_inode(list_entry(sb->u.usbdevfs_sb.ilist.next, struct inode, u.usbdev_i.slist));}static int usbdevfs_statfs(struct super_block *sb, struct statfs *buf){        buf->f_type = USBDEVICE_SUPER_MAGIC;        buf->f_bsize = PAGE_SIZE/sizeof(long);   /* ??? */        buf->f_bfree = 0;        buf->f_bavail = 0;        buf->f_ffree = 0;        buf->f_namelen = NAME_MAX;        return 0;}static int usbdevfs_remount(struct super_block *s, int *flags, char *data){	struct list_head *ilist = s->u.usbdevfs_sb.ilist.next;	struct inode *inode;	int ret;	if ((ret = parse_options(s, data))) {		printk(KERN_WARNING "usbdevfs: remount parameter error\n");		return ret;	}	for (; ilist != &s->u.usbdevfs_sb.ilist; ilist = ilist->next) {		inode = list_entry(ilist, struct inode, u.usbdev_i.slist);		switch (ITYPE(inode->i_ino)) {			case ISPECIAL :				inode->i_uid = s->u.usbdevfs_sb.listuid;				inode->i_gid = s->u.usbdevfs_sb.listgid;				inode->i_mode = s->u.usbdevfs_sb.listmode | S_IFREG;				break;			case IBUS :				inode->i_uid = s->u.usbdevfs_sb.busuid;				inode->i_gid = s->u.usbdevfs_sb.busgid;				inode->i_mode = s->u.usbdevfs_sb.busmode | S_IFDIR;				break;			case IDEVICE :				inode->i_uid = s->u.usbdevfs_sb.devuid;				inode->i_gid = s->u.usbdevfs_sb.devgid;				inode->i_mode = s->u.usbdevfs_sb.devmode | S_IFREG;				break;		}	}	return 0;}static struct super_operations usbdevfs_sops = { 	read_inode:	usbdevfs_read_inode,	put_super:	usbdevfs_put_super,	statfs:		usbdevfs_statfs,	remount_fs:	usbdevfs_remount,};struct super_block *usbdevfs_read_super(struct super_block *s, void *data, int silent){        struct inode *root_inode, *inode;	struct list_head *blist;	struct usb_bus *bus;	unsigned int i;	if (parse_options(s, data)) {		printk(KERN_WARNING "usbdevfs: mount parameter error\n");		return NULL;	}	/* fill superblock */        s->s_blocksize = 1024;        s->s_blocksize_bits = 10;        s->s_magic = USBDEVICE_SUPER_MAGIC;        s->s_op = &usbdevfs_sops;	INIT_LIST_HEAD(&s->u.usbdevfs_sb.slist);	INIT_LIST_HEAD(&s->u.usbdevfs_sb.ilist);	root_inode = iget(s, IROOT);        if (!root_inode)                goto out_no_root;        s->s_root = d_alloc_root(root_inode);        if (!s->s_root)                goto out_no_root;	lock_kernel();	list_add_tail(&s->u.usbdevfs_sb.slist, &superlist);	for (i = 0; i < NRSPECIAL; i++) {		if (!(inode = iget(s, IROOT+1+i)))			continue;		inode->i_uid = s->u.usbdevfs_sb.listuid;		inode->i_gid = s->u.usbdevfs_sb.listgid;		inode->i_mode = s->u.usbdevfs_sb.listmode | S_IFREG;		special[i].inode = inode;		list_add_tail(&inode->u.usbdev_i.slist, &s->u.usbdevfs_sb.ilist);		list_add_tail(&inode->u.usbdev_i.dlist, &special[i].inodes);	}	down (&usb_bus_list_lock);	for (blist = usb_bus_list.next; blist != &usb_bus_list; blist = blist->next) {		bus = list_entry(blist, struct usb_bus, bus_list);		new_bus_inode(bus, s);		recurse_new_dev_inode(bus->root_hub, s);	}	up (&usb_bus_list_lock);	unlock_kernel();        return s; out_no_root:        printk("usbdevfs_read_super: get root inode failed\n");        iput(root_inode);        return NULL;}/* * The usbdevfs name is now deprecated (as of 2.4.19). * It will be removed when the 2.7.x development cycle is started. * You have been warned :) */static DECLARE_FSTYPE(usbdevice_fs_type, "usbdevfs", usbdevfs_read_super, FS_SINGLE);static DECLARE_FSTYPE(usbfs_type, "usbfs", usbdevfs_read_super, FS_SINGLE);/* --------------------------------------------------------------------- */static void update_special_inodes (void){	int i;	for (i = 0; i < NRSPECIAL; i++) {		struct inode *inode = special[i].inode;		if (inode)			inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;	}}void usbdevfs_add_bus(struct usb_bus *bus){	struct list_head *slist;	lock_kernel();	for (slist = superlist.next; slist != &superlist; slist = slist->next)		new_bus_inode(bus, list_entry(slist, struct super_block, u.usbdevfs_sb.slist));	update_special_inodes();	unlock_kernel();	usbdevfs_conn_disc_event();}void usbdevfs_remove_bus(struct usb_bus *bus){	lock_kernel();	while (!list_empty(&bus->inodes))		free_inode(list_entry(bus->inodes.next, struct inode, u.usbdev_i.dlist));	update_special_inodes();	unlock_kernel();	usbdevfs_conn_disc_event();}void usbdevfs_add_device(struct usb_device *dev){	struct list_head *slist;	lock_kernel();	for (slist = superlist.next; slist != &superlist; slist = slist->next)		new_dev_inode(dev, list_entry(slist, struct super_block, u.usbdevfs_sb.slist));	update_special_inodes();	unlock_kernel();	usbdevfs_conn_disc_event();}void usbdevfs_remove_device(struct usb_device *dev){	struct dev_state *ds;	struct siginfo sinfo;	lock_kernel();	while (!list_empty(&dev->inodes))		free_inode(list_entry(dev->inodes.next, struct inode, u.usbdev_i.dlist));	while (!list_empty(&dev->filelist)) {		ds = list_entry(dev->filelist.next, struct dev_state, list);		list_del(&ds->list);		INIT_LIST_HEAD(&ds->list);		down_write(&ds->devsem);		ds->dev = NULL;		up_write(&ds->devsem);		if (ds->discsignr) {			sinfo.si_signo = SIGPIPE;			sinfo.si_errno = EPIPE;			sinfo.si_code = SI_ASYNCIO;			sinfo.si_addr = ds->disccontext;			send_sig_info(ds->discsignr, &sinfo, ds->disctask);		}	}	update_special_inodes();	unlock_kernel();	usbdevfs_conn_disc_event();}/* --------------------------------------------------------------------- */#ifdef CONFIG_PROC_FS		static struct proc_dir_entry *usbdir = NULL;#endif	int __init usbdevfs_init(void){	int ret;	for (ret = 0; ret < NRSPECIAL; ret++) {		INIT_LIST_HEAD(&special[ret].inodes);	}	if ((ret = usb_register(&usbdevfs_driver)))		return ret;	if ((ret = register_filesystem(&usbdevice_fs_type))) {		usb_deregister(&usbdevfs_driver);		return ret;	}	if ((ret = register_filesystem(&usbfs_type))) {		usb_deregister(&usbdevfs_driver);		unregister_filesystem(&usbdevice_fs_type);		return ret;	}#ifdef CONFIG_PROC_FS			/* create mount point for usbdevfs */	usbdir = proc_mkdir("usb", proc_bus);#endif		return ret;}void __exit usbdevfs_cleanup(void){	usb_deregister(&usbdevfs_driver);	unregister_filesystem(&usbdevice_fs_type);	unregister_filesystem(&usbfs_type);#ifdef CONFIG_PROC_FS	        if (usbdir)                remove_proc_entry("usb", proc_bus);#endif}#if 0module_init(usbdevfs_init);module_exit(usbdevfs_cleanup);#endif

⌨️ 快捷键说明

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