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

📄 dev.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
	return softnet_get_online(pos);}static void softnet_seq_stop(struct seq_file *seq, void *v){}static int softnet_seq_show(struct seq_file *seq, void *v){	struct netif_rx_stats *s = v;	seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x %08x\n",		   s->total, s->dropped, s->time_squeeze, s->throttled,		   s->fastroute_hit, s->fastroute_success, s->fastroute_defer,		   s->fastroute_deferred_out,#if 0		   s->fastroute_latency_reduction#else		   s->cpu_collision#endif		  );	return 0;}static struct seq_operations dev_seq_ops = {	.start = dev_seq_start,	.next  = dev_seq_next,	.stop  = dev_seq_stop,	.show  = dev_seq_show,};static int dev_seq_open(struct inode *inode, struct file *file){	return seq_open(file, &dev_seq_ops);}static struct file_operations dev_seq_fops = {	.owner	 = THIS_MODULE,	.open    = dev_seq_open,	.read    = seq_read,	.llseek  = seq_lseek,	.release = seq_release,};static struct seq_operations softnet_seq_ops = {	.start = softnet_seq_start,	.next  = softnet_seq_next,	.stop  = softnet_seq_stop,	.show  = softnet_seq_show,};static int softnet_seq_open(struct inode *inode, struct file *file){	return seq_open(file, &softnet_seq_ops);}static struct file_operations softnet_seq_fops = {	.owner	 = THIS_MODULE,	.open    = softnet_seq_open,	.read    = seq_read,	.llseek  = seq_lseek,	.release = seq_release,};#ifdef WIRELESS_EXTextern int wireless_proc_init(void);#else#define wireless_proc_init() 0#endifstatic int __init dev_proc_init(void){	int rc = -ENOMEM;	if (!proc_net_fops_create("dev", S_IRUGO, &dev_seq_fops))		goto out;	if (!proc_net_fops_create("softnet_stat", S_IRUGO, &softnet_seq_fops))		goto out_dev;	if (wireless_proc_init())		goto out_softnet;	rc = 0;out:	return rc;out_softnet:	proc_net_remove("softnet_stat");out_dev:	proc_net_remove("dev");	goto out;}#else#define dev_proc_init() 0#endif	/* CONFIG_PROC_FS *//** *	netdev_set_master	-	set up master/slave pair *	@slave: slave device *	@master: new master device * *	Changes the master device of the slave. Pass %NULL to break the *	bonding. The caller must hold the RTNL semaphore. On a failure *	a negative errno code is returned. On success the reference counts *	are adjusted, %RTM_NEWLINK is sent to the routing socket and the *	function returns zero. */int netdev_set_master(struct net_device *slave, struct net_device *master){	struct net_device *old = slave->master;	ASSERT_RTNL();	if (master) {		if (old)			return -EBUSY;		dev_hold(master);	}	slave->master = master;		synchronize_net();	if (old)		dev_put(old);	if (master)		slave->flags |= IFF_SLAVE;	else		slave->flags &= ~IFF_SLAVE;	rtmsg_ifinfo(RTM_NEWLINK, slave, IFF_SLAVE);	return 0;}/** *	dev_set_promiscuity	- update promiscuity count on a device *	@dev: device *	@inc: modifier * *	Add or remove promsicuity from a device. While the count in the device *	remains above zero the interface remains promiscuous. Once it hits zero *	the device reverts back to normal filtering operation. A negative inc *	value is used to drop promiscuity on the device. */void dev_set_promiscuity(struct net_device *dev, int inc){	unsigned short old_flags = dev->flags;	dev->flags |= IFF_PROMISC;	if ((dev->promiscuity += inc) == 0)		dev->flags &= ~IFF_PROMISC;	if (dev->flags ^ old_flags) {		dev_mc_upload(dev);		printk(KERN_INFO "device %s %s promiscuous mode\n",		       dev->name, (dev->flags & IFF_PROMISC) ? "entered" :		       					       "left");	}}/** *	dev_set_allmulti	- update allmulti count on a device *	@dev: device *	@inc: modifier * *	Add or remove reception of all multicast frames to a device. While the *	count in the device remains above zero the interface remains listening *	to all interfaces. Once it hits zero the device reverts back to normal *	filtering operation. A negative @inc value is used to drop the counter *	when releasing a resource needing all multicasts. */void dev_set_allmulti(struct net_device *dev, int inc){	unsigned short old_flags = dev->flags;	dev->flags |= IFF_ALLMULTI;	if ((dev->allmulti += inc) == 0)		dev->flags &= ~IFF_ALLMULTI;	if (dev->flags ^ old_flags)		dev_mc_upload(dev);}unsigned dev_get_flags(const struct net_device *dev){	unsigned flags;	flags = (dev->flags & ~(IFF_PROMISC |				IFF_ALLMULTI |				IFF_RUNNING)) | 		(dev->gflags & (IFF_PROMISC |				IFF_ALLMULTI));	if (netif_running(dev) && netif_carrier_ok(dev))		flags |= IFF_RUNNING;	return flags;}int dev_change_flags(struct net_device *dev, unsigned flags){	int ret;	int old_flags = dev->flags;	/*	 *	Set the flags on our device.	 */	dev->flags = (flags & (IFF_DEBUG | IFF_NOTRAILERS | IFF_NOARP |			       IFF_DYNAMIC | IFF_MULTICAST | IFF_PORTSEL |			       IFF_AUTOMEDIA)) |		     (dev->flags & (IFF_UP | IFF_VOLATILE | IFF_PROMISC |				    IFF_ALLMULTI));	/*	 *	Load in the correct multicast list now the flags have changed.	 */	dev_mc_upload(dev);	/*	 *	Have we downed the interface. We handle IFF_UP ourselves	 *	according to user attempts to set it, rather than blindly	 *	setting it.	 */	ret = 0;	if ((old_flags ^ flags) & IFF_UP) {	/* Bit is different  ? */		ret = ((old_flags & IFF_UP) ? dev_close : dev_open)(dev);		if (!ret)			dev_mc_upload(dev);	}	if (dev->flags & IFF_UP &&	    ((old_flags ^ dev->flags) &~ (IFF_UP | IFF_PROMISC | IFF_ALLMULTI |					  IFF_VOLATILE)))		notifier_call_chain(&netdev_chain, NETDEV_CHANGE, dev);	if ((flags ^ dev->gflags) & IFF_PROMISC) {		int inc = (flags & IFF_PROMISC) ? +1 : -1;		dev->gflags ^= IFF_PROMISC;		dev_set_promiscuity(dev, inc);	}	/* NOTE: order of synchronization of IFF_PROMISC and IFF_ALLMULTI	   is important. Some (broken) drivers set IFF_PROMISC, when	   IFF_ALLMULTI is requested not asking us and not reporting.	 */	if ((flags ^ dev->gflags) & IFF_ALLMULTI) {		int inc = (flags & IFF_ALLMULTI) ? +1 : -1;		dev->gflags ^= IFF_ALLMULTI;		dev_set_allmulti(dev, inc);	}	if (old_flags ^ dev->flags)		rtmsg_ifinfo(RTM_NEWLINK, dev, old_flags ^ dev->flags);	return ret;}int dev_set_mtu(struct net_device *dev, int new_mtu){	int err;	if (new_mtu == dev->mtu)		return 0;	/*	MTU must be positive.	 */	if (new_mtu < 0)		return -EINVAL;	if (!netif_device_present(dev))		return -ENODEV;	err = 0;	if (dev->change_mtu)		err = dev->change_mtu(dev, new_mtu);	else		dev->mtu = new_mtu;	if (!err && dev->flags & IFF_UP)		notifier_call_chain(&netdev_chain,				    NETDEV_CHANGEMTU, dev);	return err;}/* *	Perform the SIOCxIFxxx calls. */static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd){	int err;	struct net_device *dev = __dev_get_by_name(ifr->ifr_name);	if (!dev)		return -ENODEV;	switch (cmd) {		case SIOCGIFFLAGS:	/* Get interface flags */			ifr->ifr_flags = dev_get_flags(dev);			return 0;		case SIOCSIFFLAGS:	/* Set interface flags */			return dev_change_flags(dev, ifr->ifr_flags);		case SIOCGIFMETRIC:	/* Get the metric on the interface					   (currently unused) */			ifr->ifr_metric = 0;			return 0;		case SIOCSIFMETRIC:	/* Set the metric on the interface					   (currently unused) */			return -EOPNOTSUPP;		case SIOCGIFMTU:	/* Get the MTU of a device */			ifr->ifr_mtu = dev->mtu;			return 0;		case SIOCSIFMTU:	/* Set the MTU of a device */			return dev_set_mtu(dev, ifr->ifr_mtu);		case SIOCGIFHWADDR:			memcpy(ifr->ifr_hwaddr.sa_data, dev->dev_addr,			       min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));			ifr->ifr_hwaddr.sa_family = dev->type;			return 0;		case SIOCSIFHWADDR:			if (!dev->set_mac_address)				return -EOPNOTSUPP;			if (ifr->ifr_hwaddr.sa_family != dev->type)				return -EINVAL;			if (!netif_device_present(dev))				return -ENODEV;			err = dev->set_mac_address(dev, &ifr->ifr_hwaddr);			if (!err)				notifier_call_chain(&netdev_chain,						    NETDEV_CHANGEADDR, dev);			return err;		case SIOCSIFHWBROADCAST:			if (ifr->ifr_hwaddr.sa_family != dev->type)				return -EINVAL;			memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data,			       min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));			notifier_call_chain(&netdev_chain,					    NETDEV_CHANGEADDR, dev);			return 0;		case SIOCGIFMAP:			ifr->ifr_map.mem_start = dev->mem_start;			ifr->ifr_map.mem_end   = dev->mem_end;			ifr->ifr_map.base_addr = dev->base_addr;			ifr->ifr_map.irq       = dev->irq;			ifr->ifr_map.dma       = dev->dma;			ifr->ifr_map.port      = dev->if_port;			return 0;		case SIOCSIFMAP:			if (dev->set_config) {				if (!netif_device_present(dev))					return -ENODEV;				return dev->set_config(dev, &ifr->ifr_map);			}			return -EOPNOTSUPP;		case SIOCADDMULTI:			if (!dev->set_multicast_list ||			    ifr->ifr_hwaddr.sa_family != AF_UNSPEC)				return -EINVAL;			if (!netif_device_present(dev))				return -ENODEV;			return dev_mc_add(dev, ifr->ifr_hwaddr.sa_data,					  dev->addr_len, 1);		case SIOCDELMULTI:			if (!dev->set_multicast_list ||			    ifr->ifr_hwaddr.sa_family != AF_UNSPEC)				return -EINVAL;			if (!netif_device_present(dev))				return -ENODEV;			return dev_mc_delete(dev, ifr->ifr_hwaddr.sa_data,					     dev->addr_len, 1);		case SIOCGIFINDEX:			ifr->ifr_ifindex = dev->ifindex;			return 0;		case SIOCGIFTXQLEN:			ifr->ifr_qlen = dev->tx_queue_len;			return 0;		case SIOCSIFTXQLEN:			if (ifr->ifr_qlen < 0)				return -EINVAL;			dev->tx_queue_len = ifr->ifr_qlen;			return 0;		case SIOCSIFNAME:			ifr->ifr_newname[IFNAMSIZ-1] = '\0';			return dev_change_name(dev, ifr->ifr_newname);		/*		 *	Unknown or private ioctl		 */		default:			if ((cmd >= SIOCDEVPRIVATE &&			    cmd <= SIOCDEVPRIVATE + 15) ||			    cmd == SIOCBONDENSLAVE ||			    cmd == SIOCBONDRELEASE ||			    cmd == SIOCBONDSETHWADDR ||			    cmd == SIOCBONDSLAVEINFOQUERY ||			    cmd == SIOCBONDINFOQUERY ||			    cmd == SIOCBONDCHANGEACTIVE ||			    cmd == SIOCGMIIPHY ||			    cmd == SIOCGMIIREG ||			    cmd == SIOCSMIIREG ||			    cmd == SIOCBRADDIF ||			    cmd == SIOCBRDELIF ||			    cmd == SIOCWANDEV) {				err = -EOPNOTSUPP;				if (dev->do_ioctl) {					if (netif_device_present(dev))						err = dev->do_ioctl(dev, ifr,								    cmd);					else						err = -ENODEV;				}			} else				err = -EINVAL;	}	return err;}/* *	This function handles all "interface"-type I/O control requests. The actual *	'doing' part of this is dev_ifsioc above. *//** *	dev_ioctl	-	network device ioctl *	@cmd: command to issue *	@arg: pointer to a struct ifreq in user space * *	Issue ioctl functions to devices. This is normally called by the *	user space syscall interfaces but can sometimes be useful for *	other purposes. The return value is the return from the syscall if *	positive or a negative errno code on error. */int dev_ioctl(unsigned int cmd, void __user *arg){	struct ifreq ifr;	int ret;	char *colon;	/* One special case: SIOCGIFCONF takes ifconf argument	   and requires shared lock, because it sleeps writing	   to user space.	 */	if (cmd == SIOCGIFCONF) {		rtnl_shlock();		ret = dev_ifconf((char __user *) arg);		rtnl_shunlock();		return ret;	}	if (cmd == SIOCGIFNAME)		return dev_ifname((struct ifreq __user *)arg);	if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))		return -EFAULT;	ifr.ifr_name[IFNAMSIZ-1] = 0;	colon = strchr(ifr.ifr_name, ':');	if (colon)		*colon = 0;	/*	 *	See which interface the caller is talking about.	 */	switch (cmd) {		/*		 *	These ioctl calls:		 *	- can be done by all.		 *	- atomic and do not require locking.		 *	- return a value		 */		case SIOCGIFFLAGS:		case SIOCGIFMETRIC:		case SIOCGIFMTU:		case SIOCGIFHWADDR:		case SIOCGIFSLAVE:		case SIOCGIFMAP:		case SIOCGIFINDEX:		case SIOCGIFTXQLEN:			dev_load(ifr.ifr_name);			read_lock(&dev_base_lock);			ret = dev_ifsioc(&ifr, cmd);			read_unlock(&dev_base_lock);			if (!ret) {				if (colon)					*colon = ':';				if (copy_to_user(arg, &ifr,						 sizeof(struct ifreq)))					ret = -EFAULT;			}			return ret;		case SIOCETHTOOL:			dev_load(ifr.ifr_name);			rtnl_lock();			ret = dev_ethtool(&ifr);			rtnl_unlock();			if (!ret) {				if (colon)					*colon = ':';				if (copy_to_user(arg, &ifr,						 sizeof(struct ifreq)))					ret = -EFAULT;			}			return ret;		/*		

⌨️ 快捷键说明

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