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

📄 wanmain.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *	Setup WAN link device. *	o verify user address space *	o allocate kernel memory and copy configuration data to kernel space *	o if configuration data includes extension, copy it to kernel space too *	o call driver's setup() entry point */static int wanrouter_device_setup(struct wan_device *wandev,				  wandev_conf_t __user *u_conf){	void *data = NULL;	wandev_conf_t *conf;	int err = -EINVAL;	if (wandev->setup == NULL) {	/* Nothing to do ? */		printk(KERN_INFO "%s: ERROR, No setup script: wandev->setup()\n",				wandev->name);		return 0;	}	conf = kmalloc(sizeof(wandev_conf_t), GFP_KERNEL);	if (conf == NULL){		printk(KERN_INFO "%s: ERROR, Failed to allocate kernel memory !\n",				wandev->name);		return -ENOBUFS;	}	if (copy_from_user(conf, u_conf, sizeof(wandev_conf_t))) {		printk(KERN_INFO "%s: Failed to copy user config data to kernel space!\n",				wandev->name);		kfree(conf);		return -EFAULT;	}	if (conf->magic != ROUTER_MAGIC) {		kfree(conf);		printk(KERN_INFO "%s: ERROR, Invalid MAGIC Number\n",				wandev->name);		return -EINVAL;	}	if (conf->data_size && conf->data) {		if (conf->data_size > 128000) {			printk(KERN_INFO			    "%s: ERROR, Invalid firmware data size %i !\n",					wandev->name, conf->data_size);			kfree(conf);			return -EINVAL;		}		data = vmalloc(conf->data_size);		if (!data) {			printk(KERN_INFO				"%s: ERROR, Faild allocate kernel memory !\n",				wandev->name);			kfree(conf);			return -ENOBUFS;		}		if (!copy_from_user(data, conf->data, conf->data_size)) {			conf->data = data;			err = wandev->setup(wandev, conf);		} else {			printk(KERN_INFO			     "%s: ERROR, Faild to copy from user data !\n",			       wandev->name);			err = -EFAULT;		}		vfree(data);	} else {		printk(KERN_INFO		    "%s: ERROR, No firmware found ! Firmware size = %i !\n",				wandev->name, conf->data_size);	}	kfree(conf);	return err;}/* *	Shutdown WAN device. *	o delete all not opened logical channels for this device *	o call driver's shutdown() entry point */static int wanrouter_device_shutdown(struct wan_device *wandev){	struct net_device *dev;	int err=0;	if (wandev->state == WAN_UNCONFIGURED)		return 0;	printk(KERN_INFO "\n%s: Shutting Down!\n",wandev->name);	for (dev = wandev->dev; dev;) {		err = wanrouter_delete_interface(wandev, dev->name);		if (err)			return err;		/* The above function deallocates the current dev		 * structure. Therefore, we cannot use dev->priv		 * as the next element: wandev->dev points to the		 * next element */		dev = wandev->dev;	}	if (wandev->ndev)		return -EBUSY;	/* there are opened interfaces  */	if (wandev->shutdown)		err=wandev->shutdown(wandev);	return err;}/* *	Get WAN device status & statistics. */static int wanrouter_device_stat(struct wan_device *wandev,				 wandev_stat_t __user *u_stat){	wandev_stat_t stat;	memset(&stat, 0, sizeof(stat));	/* Ask device driver to update device statistics */	if ((wandev->state != WAN_UNCONFIGURED) && wandev->update)		wandev->update(wandev);	/* Fill out structure */	stat.ndev  = wandev->ndev;	stat.state = wandev->state;	if (copy_to_user(u_stat, &stat, sizeof(stat)))		return -EFAULT;	return 0;}/* *	Create new WAN interface. *	o verify user address space *	o copy configuration data to kernel address space *	o allocate network interface data space *	o call driver's new_if() entry point *	o make sure there is no interface name conflict *	o register network interface */static int wanrouter_device_new_if(struct wan_device *wandev,				   wanif_conf_t __user *u_conf){	wanif_conf_t *cnf;	struct net_device *dev = NULL;#ifdef CONFIG_WANPIPE_MULTPPP	struct ppp_device *pppdev=NULL;#endif	int err;	if ((wandev->state == WAN_UNCONFIGURED) || (wandev->new_if == NULL))		return -ENODEV;	cnf = kmalloc(sizeof(wanif_conf_t), GFP_KERNEL);	if (!cnf)		return -ENOBUFS;	err = -EFAULT;	if (copy_from_user(cnf, u_conf, sizeof(wanif_conf_t)))		goto out;	err = -EINVAL;	if (cnf->magic != ROUTER_MAGIC)		goto out;	if (cnf->config_id == WANCONFIG_MPPP) {#ifdef CONFIG_WANPIPE_MULTPPP		pppdev = kzalloc(sizeof(struct ppp_device), GFP_KERNEL);		err = -ENOBUFS;		if (pppdev == NULL)			goto out;		pppdev->dev = kzalloc(sizeof(struct net_device), GFP_KERNEL);		if (pppdev->dev == NULL) {			kfree(pppdev);			err = -ENOBUFS;			goto out;		}		err = wandev->new_if(wandev, (struct net_device *)pppdev, cnf);		dev = pppdev->dev;#else		printk(KERN_INFO "%s: Wanpipe Mulit-Port PPP support has not been compiled in!\n",				wandev->name);		err = -EPROTONOSUPPORT;		goto out;#endif	} else {		dev = kzalloc(sizeof(struct net_device), GFP_KERNEL);		err = -ENOBUFS;		if (dev == NULL)			goto out;		err = wandev->new_if(wandev, dev, cnf);	}	if (!err) {		/* Register network interface. This will invoke init()		 * function supplied by the driver.  If device registered		 * successfully, add it to the interface list.		 */		if (dev->name == NULL) {			err = -EINVAL;		} else {			#ifdef WANDEBUG			printk(KERN_INFO "%s: registering interface %s...\n",				wanrouter_modname, dev->name);			#endif			err = register_netdev(dev);			if (!err) {				struct net_device *slave = NULL;				unsigned long smp_flags=0;				lock_adapter_irq(&wandev->lock, &smp_flags);				if (wandev->dev == NULL) {					wandev->dev = dev;				} else {					for (slave=wandev->dev;					 *((struct net_device **)slave->priv);				 slave = *((struct net_device **)slave->priv));				     *((struct net_device **)slave->priv) = dev;				}				++wandev->ndev;				unlock_adapter_irq(&wandev->lock, &smp_flags);				err = 0;	/* done !!! */				goto out;			}		}		if (wandev->del_if)			wandev->del_if(wandev, dev);	}	/* This code has moved from del_if() function */	kfree(dev->priv);	dev->priv = NULL;#ifdef CONFIG_WANPIPE_MULTPPP	if (cnf->config_id == WANCONFIG_MPPP)		kfree(pppdev);	else		kfree(dev);#else	/* Sync PPP is disabled */	if (cnf->config_id != WANCONFIG_MPPP)		kfree(dev);#endifout:	kfree(cnf);	return err;}/* *	Delete WAN logical channel. *	 o verify user address space *	 o copy configuration data to kernel address space */static int wanrouter_device_del_if(struct wan_device *wandev, char __user *u_name){	char name[WAN_IFNAME_SZ + 1];	int err = 0;	if (wandev->state == WAN_UNCONFIGURED)		return -ENODEV;	memset(name, 0, sizeof(name));	if (copy_from_user(name, u_name, WAN_IFNAME_SZ))		return -EFAULT;	err = wanrouter_delete_interface(wandev, name);	if (err)		return err;	/* If last interface being deleted, shutdown card	 * This helps with administration at leaf nodes	 * (You can tell if the person at the other end of the phone	 * has an interface configured) and avoids DoS vulnerabilities	 * in binary driver files - this fixes a problem with the current	 * Sangoma driver going into strange states when all the network	 * interfaces are deleted and the link irrecoverably disconnected.	 */	if (!wandev->ndev && wandev->shutdown)		err = wandev->shutdown(wandev);	return err;}/* *	Miscellaneous Functions *//* *	Find WAN device by name. *	Return pointer to the WAN device data space or NULL if device not found. */static struct wan_device *wanrouter_find_device(char *name){	struct wan_device *wandev;	for (wandev = wanrouter_router_devlist;	     wandev && strcmp(wandev->name, name);		wandev = wandev->next);	return wandev;}/* *	Delete WAN logical channel identified by its name. *	o find logical channel by its name *	o call driver's del_if() entry point *	o unregister network interface *	o unlink channel data space from linked list of channels *	o release channel data space * *	Return:	0		success *		-ENODEV		channel not found. *		-EBUSY		interface is open * *	Note: If (force != 0), then device will be destroyed even if interface *	associated with it is open. It's caller's responsibility to make *	sure that opened interfaces are not removed! */static int wanrouter_delete_interface(struct wan_device *wandev, char *name){	struct net_device *dev = NULL, *prev = NULL;	unsigned long smp_flags=0;	lock_adapter_irq(&wandev->lock, &smp_flags);	dev = wandev->dev;	prev = NULL;	while (dev && strcmp(name, dev->name)) {		struct net_device **slave = dev->priv;		prev = dev;		dev = *slave;	}	unlock_adapter_irq(&wandev->lock, &smp_flags);	if (dev == NULL)		return -ENODEV;	/* interface not found */	if (netif_running(dev))		return -EBUSY;	/* interface in use */	if (wandev->del_if)		wandev->del_if(wandev, dev);	lock_adapter_irq(&wandev->lock, &smp_flags);	if (prev) {		struct net_device **prev_slave = prev->priv;		struct net_device **slave = dev->priv;		*prev_slave = *slave;	} else {		struct net_device **slave = dev->priv;		wandev->dev = *slave;	}	--wandev->ndev;	unlock_adapter_irq(&wandev->lock, &smp_flags);	printk(KERN_INFO "%s: unregistering '%s'\n", wandev->name, dev->name);	/* Due to new interface linking method using dev->priv,	 * this code has moved from del_if() function.*/	kfree(dev->priv);	dev->priv=NULL;	unregister_netdev(dev);	free_netdev(dev);	return 0;}static void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags){	spin_lock_irqsave(lock, *smp_flags);}static void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags){	spin_unlock_irqrestore(lock, *smp_flags);}EXPORT_SYMBOL(register_wan_device);EXPORT_SYMBOL(unregister_wan_device);MODULE_LICENSE("GPL");/* *	End */

⌨️ 快捷键说明

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