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

📄 wanproc.c

📁 《嵌入式系统设计与实例开发实验教材二源码》Linux内核移植与编译实验
💻 C
📖 第 1 页 / 共 2 页
字号:
		NULL,			/* lseek   */		router_proc_read,	/* read	   */		NULL,			/* write   */		NULL,			/* readdir */		NULL,			/* select  */		wanrouter_ioctl,	/* ioctl   */		NULL,			/* mmap	   */		NULL,			/* no special open code	   */		NULL,			/* flush */		NULL,			/* no special release code */		NULL			/* can't fsync */	};#else	static struct file_operations wandev_fops =	{		NULL,                   /* lseek   */		router_proc_read,       /* read    */		device_write,           /* write   */		NULL,                   /* readdir */		NULL,                   /* select  */		wanrouter_ioctl,        /* ioctl   */		NULL,                   /* mmap    */		NULL,                   /* no special open code    */		NULL,                   /* no special release code */		NULL                    /* can't fsync */	};#endif	static struct inode_operations wandev_inode =	{		&wandev_fops,		NULL,			/* create */		NULL,			/* lookup */		NULL,			/* link */		NULL,			/* unlink */		NULL,			/* symlink */		NULL,			/* mkdir */		NULL,			/* rmdir */		NULL,			/* mknod */		NULL,			/* rename */		NULL,			/* readlink */		NULL,			/* follow_link */		NULL,			/* readpage */		NULL,			/* writepage */		NULL,			/* bmap */		NULL,			/* truncate */		router_proc_perms	};	/*	 * Proc filesystem derectory entries.	 */	/*	 *	/proc/net/router 	 */	 	static struct proc_dir_entry proc_router =	{		0,			/* .low_ino */		sizeof(name_root) - 1,	/* .namelen */		name_root,		/* .name */		0555 | S_IFDIR,		/* .mode */		2,			/* .nlink */		0,			/* .uid */		0,			/* .gid */		0,			/* .size */		&proc_dir_inode_operations, /* .ops */		NULL,			/* .get_info */		NULL,			/* .fill_node */		NULL,			/* .next */		NULL,			/* .parent */		NULL,			/* .subdir */		NULL,			/* .data */	};	/*	 *	/proc/net/router/config 	 */	 	static struct proc_dir_entry proc_router_conf =	{		0,			/* .low_ino */		sizeof(name_conf) - 1,	/* .namelen */		name_conf,		/* .name */		0444 | S_IFREG,		/* .mode */		1,			/* .nlink */		0,			/* .uid */		0,			/* .gid */		0,			/* .size */		&router_inode,		/* .ops */		&config_get_info,	/* .get_info */		NULL,			/* .fill_node */		NULL,			/* .next */		NULL,			/* .parent */		NULL,			/* .subdir */		NULL,			/* .data */	};	/*	 *	/proc/net/router/status 	 */	 	static struct proc_dir_entry proc_router_stat =	{		0,			/* .low_ino */		sizeof(name_stat) - 1,	/* .namelen */		name_stat,		/* .name */		0444 | S_IFREG,		/* .mode */		1,			/* .nlink */		0,			/* .uid */		0,			/* .gid */		0,			/* .size */		&router_inode,		/* .ops */		status_get_info,	/* .get_info */		NULL,			/* .fill_node */		NULL,			/* .next */		NULL,			/* .parent */		NULL,			/* .subdir */		NULL,			/* .data */	};	/* Strings */	static char conf_hdr[] =		"Device name    | port |IRQ|DMA|  mem.addr  |mem.size|"		"option1|option2|option3|option4\n";			static char stat_hdr[] =		"Device name    |protocol|station|interface|clocking|baud rate| MTU |ndev"		"|link state\n";	/*	 *	Interface functions	 */	/*	 *	Initialize router proc interface.	 */#ifdef LINUX_2_1	__initfunc(int wanrouter_proc_init (void))	{		int err = proc_register(proc_net, &proc_router);		if (!err) {			proc_register(&proc_router, &proc_router_conf);			proc_register(&proc_router, &proc_router_stat);		}		return err;	}#else	int wanrouter_proc_init (void)	{		int err = proc_register_dynamic(&proc_net, &proc_router);		if (!err) {			proc_register_dynamic(&proc_router, &proc_router_conf);			proc_register_dynamic(&proc_router, &proc_router_stat);		}		return err;	}#endif	/*	 *	Clean up router proc interface.	 */	void wanrouter_proc_cleanup (void)	{		proc_unregister(&proc_router, proc_router_conf.low_ino);		proc_unregister(&proc_router, proc_router_stat.low_ino);#ifdef LINUX_2_1		proc_unregister(proc_net, proc_router.low_ino);#else		proc_unregister(&proc_net, proc_router.low_ino);#endif	}	/*	 *	Add directory entry for WAN device.	 */	int wanrouter_proc_add (wan_device_t* wandev)	{		if (wandev->magic != ROUTER_MAGIC)			return -EINVAL;				memset(&wandev->dent, 0, sizeof(wandev->dent));		wandev->dent.namelen	= strlen(wandev->name);		wandev->dent.name	= wandev->name;		wandev->dent.mode	= 0444 | S_IFREG;		wandev->dent.nlink	= 1;		wandev->dent.ops	= &wandev_inode;		wandev->dent.get_info	= &wandev_get_info;		wandev->dent.data	= wandev;#ifdef LINUX_2_1		return proc_register(&proc_router, &wandev->dent);#else		return proc_register_dynamic(&proc_router, &wandev->dent);#endif	}	/*	 *	Delete directory entry for WAN device.	 */	 	int wanrouter_proc_delete(wan_device_t* wandev)	{		if (wandev->magic != ROUTER_MAGIC)			return -EINVAL;		proc_unregister(&proc_router, wandev->dent.low_ino);		return 0;	}	/****** Proc filesystem entry points ****************************************/	/*	 *	Verify access rights.	 */	static int router_proc_perms (struct inode* inode, int op)	{		return 0;	}	/*	 *	Read router proc directory entry.	 *	This is universal routine for reading all entries in /proc/net/wanrouter	 *	directory.  Each directory entry contains a pointer to the 'method' for	 *	preparing data for that entry.	 *	o verify arguments	 *	o allocate kernel buffer	 *	o call get_info() to prepare data	 *	o copy data to user space	 *	o release kernel buffer	 *	 *	Return:	number of bytes copied to user space (0, if no data)	 *		<0	error	 */#ifdef LINUX_2_1	static ssize_t router_proc_read(struct file* file, char* buf, size_t count,					loff_t *ppos)	{		struct inode *inode = file->f_dentry->d_inode;		struct proc_dir_entry* dent;		char* page;		int pos, offs, len;		if (count <= 0)			return 0;					dent = inode->u.generic_ip;		if ((dent == NULL) || (dent->get_info == NULL))			return 0;					page = kmalloc(PROC_BUFSZ, GFP_KERNEL);		if (page == NULL)			return -ENOBUFS;					pos = dent->get_info(page, dent->data, 0, 0, 0);		offs = file->f_pos;		if (offs < pos) {			len = min_t(unsigned int, pos - offs, count);			if (copy_to_user(buf, (page + offs), len)) {				kfree(page);				return -EFAULT;			}			file->f_pos += len;		}		else			len = 0;		kfree(page);		return len;	}#else	static int router_proc_read(		struct inode* inode, struct file* file, char* buf, int count)	{		struct proc_dir_entry* dent;		char* page;		int err, pos, offs, len;		if (count <= 0)			return 0;		dent = inode->u.generic_ip;		if ((dent == NULL) || (dent->get_info == NULL))			return -ENODATA;		err = verify_area(VERIFY_WRITE, buf, count);		if (err) return err;		page = kmalloc(PROC_BUFSZ, GFP_KERNEL);		if (page == NULL)			return -ENOMEM;		pos = dent->get_info(page, dent->data, 0, 0, 0);		offs = file->f_pos;		if (offs < pos) {			len = min_t(unsigned int, pos - offs, count);			memcpy_tofs((void*)buf, (void*)(page + offs), len);			file->f_pos += len;		}		else len = 0;		kfree(page);		return len;	}#endif	/*	 *	Prepare data for reading 'Config' entry.	 *	Return length of data.	 */	static int config_get_info(char* buf, char** start, off_t offs, int len, 		int dummy)	{		int cnt = sizeof(conf_hdr) - 1;		wan_device_t* wandev;		strcpy(buf, conf_hdr);		for (wandev = router_devlist;		     wandev && (cnt < (PROC_BUFSZ - 120));		     wandev = wandev->next) {			if (wandev->state) cnt += sprintf(&buf[cnt],				"%-15s|0x%-4X|%3u|%3u| 0x%-8lX |0x%-6X|%7u|%7u|%7u|%7u\n",				wandev->name,				wandev->ioport,				wandev->irq,				wandev->dma,				wandev->maddr,				wandev->msize,				wandev->hw_opt[0],				wandev->hw_opt[1],				wandev->hw_opt[2],				wandev->hw_opt[3]);		}		return cnt;	}	/*	 *	Prepare data for reading 'Status' entry.	 *	Return length of data.	 */	static int status_get_info(char* buf, char** start, off_t offs, int len, 				int dummy)	{		int cnt = 0;		wan_device_t* wandev;		//cnt += sprintf(&buf[cnt], "\nSTATUS:\n\n");		strcpy(&buf[cnt], stat_hdr);		cnt += sizeof(stat_hdr) - 1;		for (wandev = router_devlist;		     wandev && (cnt < (PROC_BUFSZ - 80));		     wandev = wandev->next) {			if (!wandev->state) continue;			cnt += sprintf(&buf[cnt],				"%-15s|%-8s|%-7s|%-9s|%-8s|%9u|%5u|%3u |",				wandev->name,				PROT_DECODE(wandev->config_id),				wandev->config_id == WANCONFIG_FR ? 					(wandev->station ? " Node" : " CPE") :					(wandev->config_id == WANCONFIG_X25 ?					(wandev->station ? " DCE" : " DTE") :					(" N/A")),				wandev->interface ? " V.35" : " RS-232",				wandev->clocking ? "internal" : "external",				wandev->bps,				wandev->mtu,				wandev->ndev);			switch (wandev->state) {			case WAN_UNCONFIGURED:				cnt += sprintf(&buf[cnt], "%-12s\n", "unconfigured");				break;			case WAN_DISCONNECTED:				cnt += sprintf(&buf[cnt], "%-12s\n", "disconnected");				break;			case WAN_CONNECTING:				cnt += sprintf(&buf[cnt], "%-12s\n", "connecting");				break;			case WAN_CONNECTED:				cnt += sprintf(&buf[cnt], "%-12s\n", "connected");				break;			case WAN_FT1_READY:				cnt += sprintf(&buf[cnt], "%-12s\n", "ft1 ready");				break;			default:				cnt += sprintf(&buf[cnt], "%-12s\n", "invalid");				break;			}		}		return cnt;	}	/*	 *	Prepare data for reading <device> entry.	 *	Return length of data.	 *	 *	On entry, the 'start' argument will contain a pointer to WAN device	 *	data space.	 */	static int wandev_get_info(char* buf, char** start, off_t offs, int len, 				int dummy)	{		wan_device_t* wandev = (void*)start;		int cnt = 0;		int rslt = 0;		if ((wandev == NULL) || (wandev->magic != ROUTER_MAGIC))			return 0;		if (!wandev->state)			return sprintf(&buf[cnt], "Device is not configured!\n");		/* Update device statistics */		if (wandev->update) {			rslt = wandev->update(wandev);			if(rslt) {				switch (rslt) {				case -EAGAIN:					return sprintf(&buf[cnt], "Device is busy!\n");				default:					return sprintf(&buf[cnt],						"Device is not configured!\n");				}			}		}		cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,			"total packets received", wandev->stats.rx_packets);		cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,			"total packets transmitted", wandev->stats.tx_packets);#ifdef LINUX_2_1		cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,			"total bytes received", wandev->stats.rx_bytes);		cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,			"total bytes transmitted", wandev->stats.tx_bytes);#endif		cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,			"bad packets received", wandev->stats.rx_errors);		cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,			"packet transmit problems", wandev->stats.tx_errors);		cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,			"received frames dropped", wandev->stats.rx_dropped);		cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,			"transmit frames dropped", wandev->stats.tx_dropped);		cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,			"multicast packets received", wandev->stats.multicast);		cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,			"transmit collisions", wandev->stats.collisions);		cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,			"receive length errors", wandev->stats.rx_length_errors);		cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,			"receiver overrun errors", wandev->stats.rx_over_errors);		cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,			"CRC errors", wandev->stats.rx_crc_errors);		cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,			"frame format errors (aborts)", wandev->stats.rx_frame_errors);		cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,			"receiver fifo overrun", wandev->stats.rx_fifo_errors);		cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,			"receiver missed packet", wandev->stats.rx_missed_errors);		cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,			"aborted frames transmitted", wandev->stats.tx_aborted_errors);		return cnt;	}#endif /* End of ifdef LINUX_2_4 */#else/* *	No /proc - output stubs */int __init wanrouter_proc_init(void){	return 0;}void wanrouter_proc_cleanup(void){	return;}int wanrouter_proc_add(wan_device_t *wandev){	return 0;}int wanrouter_proc_delete(wan_device_t *wandev){	return 0;}#endif/*============================================================================ * Write WAN device ???. * o Find WAN device associated with this node */#ifdef LINUX_2_0static int device_write(        struct inode* inode, struct file* file, const char* buf, int count){        int err = verify_area(VERIFY_READ, buf, count);        struct proc_dir_entry* dent;        wan_device_t* wandev;        if (err) return err;        dent = inode->u.generic_ip;        if ((dent == NULL) || (dent->data == NULL))                return -ENODATA;        wandev = dent->data;        printk(KERN_ERR "%s: writing %d bytes to %s...\n",                name_root, count, dent->name);        	return 0;}#endif/* *	End */ 

⌨️ 快捷键说明

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