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

📄 wanmain.c

📁 《嵌入式系统设计与实例开发实验教材二源码》Linux内核移植与编译实验
💻 C
📖 第 1 页 / 共 2 页
字号:
}/* *	WAN Driver IOCTL Handlers *//* *	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 device_setup (wan_device_t *wandev, wandev_conf_t *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;	}      #ifdef LINUX_2_0 	err = verify_area (VERIFY_READ, u_conf, sizeof(wandev_conf_t));	if(err){		return err;	}      #endif		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 defined (LINUX_2_1) || defined (LINUX_2_4)			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;	}      #else	memcpy_fromfs ((void *)conf, (void *)u_conf, sizeof(wandev_conf_t));      #endif		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 || conf->data_size < 0) {			printk(KERN_INFO 			    "%s: ERROR, Invalid firmware data size %i !\n",					wandev->name, conf->data_size);			kfree(conf);		        return -EINVAL;;		}#if defined (LINUX_2_1) || defined (LINUX_2_4)		data = vmalloc(conf->data_size);		if (data) {			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;			}		}else{ 			printk(KERN_INFO 			 	"%s: ERROR, Faild allocate kernel memory !\n",				wandev->name);			err = -ENOBUFS;		}					if (data){			vfree(data);		}#else                err = verify_area(VERIFY_READ, conf->data, conf->data_size);                if (!err) {                        data = kmalloc(conf->data_size, GFP_KERNEL);                        if (data) {                                memcpy_fromfs(data, (void*)conf->data,                                        conf->data_size);                                conf->data = data;                        }else{				printk(KERN_INFO 				    "%s: ERROR, Faild allocate kernel memory !\n",wandev->name);				err = -ENOMEM;			}                }else{			printk(KERN_INFO 			 	"%s: ERROR, Faild to copy from user data !\n",wandev->name);		}		if (!err){			err = wandev->setup(wandev, conf);		}		        	if (data){			kfree(data);		}#endif	}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 device_shutdown (wan_device_t *wandev){	netdevice_t *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;) {		if ((err=delete_interface(wandev, dev->name)) != 0){			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 device_stat (wan_device_t *wandev, wandev_stat_t *u_stat){	wandev_stat_t stat;      #ifdef LINUX_2_0	int err;	err = verify_area(VERIFY_WRITE, u_stat, sizeof(wandev_stat_t));        if (err)                return err;      #endif	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 defined (LINUX_2_1) || defined (LINUX_2_4)	if(copy_to_user(u_stat, &stat, sizeof(stat)))		return -EFAULT;      #else        memcpy_tofs((void*)u_stat, (void*)&stat, sizeof(stat));      #endif	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 device_new_if (wan_device_t *wandev, wanif_conf_t *u_conf){	wanif_conf_t conf;	netdevice_t *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;	#if defined (LINUX_2_1) || defined (LINUX_2_4)		if(copy_from_user(&conf, u_conf, sizeof(wanif_conf_t)))		return -EFAULT;#else        err = verify_area(VERIFY_READ, u_conf, sizeof(wanif_conf_t));        if (err)                return err;        memcpy_fromfs((void*)&conf, (void*)u_conf, sizeof(wanif_conf_t));#endif			if (conf.magic != ROUTER_MAGIC)		return -EINVAL;	err = -EPROTONOSUPPORT;	#ifdef CONFIG_WANPIPE_MULTPPP	if (conf.config_id == WANCONFIG_MPPP){		pppdev = kmalloc(sizeof(struct ppp_device), GFP_KERNEL);		if (pppdev == NULL){			return -ENOBUFS;		}		memset(pppdev, 0, sizeof(struct ppp_device));#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,16)		pppdev->dev = kmalloc(sizeof(netdevice_t), GFP_KERNEL);		if (pppdev->dev == NULL){			kfree(pppdev);			return -ENOBUFS;		}		memset(pppdev->dev, 0, sizeof(netdevice_t));#endif				err = wandev->new_if(wandev, (netdevice_t *)pppdev, &conf);				      #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,16)			dev = pppdev->dev;		      #else			dev = &pppdev->dev;		      #endif				}else{		dev = kmalloc(sizeof(netdevice_t), GFP_KERNEL);		if (dev == NULL){			return -ENOBUFS;		}		memset(dev, 0, sizeof(netdevice_t));			err = wandev->new_if(wandev, dev, &conf);	}#else	/* Sync PPP is disabled */	if (conf.config_id != WANCONFIG_MPPP){		dev = kmalloc(sizeof(netdevice_t), GFP_KERNEL);		if (dev == NULL){			return -ENOBUFS;		}		memset(dev, 0, sizeof(netdevice_t));			err = wandev->new_if(wandev, dev, &conf);	}else{		printk(KERN_INFO "%s: Wanpipe Mulit-Port PPP support has not been compiled in!\n",				wandev->name);		return err;	}#endif		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 if (dev_get(dev->name)){			err = -EEXIST;	/* name already exists */		}else{							#ifdef WANDEBUG					printk(KERN_INFO "%s: registering interface %s...\n",				modname, dev->name);			#endif										err = register_netdev(dev);			if (!err) {				netdevice_t *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;					     *((netdevice_t**)slave->priv);					     slave=*((netdevice_t**)slave->priv));					*((netdevice_t**)slave->priv) = dev;				}				++wandev->ndev;								unlock_adapter_irq(&wandev->lock, &smp_flags);				return 0;	/* done !!! */			}		}		if (wandev->del_if)			wandev->del_if(wandev, dev);	}	/* This code has moved from del_if() function */	if (dev->priv){		kfree(dev->priv);		dev->priv=NULL;	}	      #ifdef CONFIG_WANPIPE_MULTPPP	if (conf.config_id == WANCONFIG_MPPP){		kfree(pppdev);	}else{		kfree(dev);	}      #else	/* Sync PPP is disabled */	if (conf.config_id != WANCONFIG_MPPP){		kfree(dev);	}      #endif		return err;}/* *	Delete WAN logical channel. *	 o verify user address space *	 o copy configuration data to kernel address space */static int device_del_if (wan_device_t *wandev, char *u_name){	char name[WAN_IFNAME_SZ + 1];        int err = 0;	if (wandev->state == WAN_UNCONFIGURED)		return -ENODEV;	      #ifdef LINUX_2_0        err = verify_area(VERIFY_READ, u_name, WAN_IFNAME_SZ);        if (err)		return err;      #endif		memset(name, 0, sizeof(name));      #if defined (LINUX_2_1) || defined (LINUX_2_4)	if(copy_from_user(name, u_name, WAN_IFNAME_SZ))		return -EFAULT;      #else        memcpy_fromfs((void*)name, (void*)u_name, WAN_IFNAME_SZ);      #endif	err = 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 wan_device_t *find_device(char *name){	wan_device_t *wandev;	for (wandev = 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 delete_interface (wan_device_t *wandev, char *name){	netdevice_t *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)) {		netdevice_t **slave = dev->priv;		prev = dev;		dev = *slave;	}	unlock_adapter_irq(&wandev->lock, &smp_flags);		if (dev == NULL){		return -ENODEV;	/* interface not found */	}		       #ifdef LINUX_2_4	if (netif_running(dev)){       #else	if (dev->start) {       #endif		return -EBUSY;	/* interface in use */	}	if (wandev->del_if)		wandev->del_if(wandev, dev);	lock_adapter_irq(&wandev->lock, &smp_flags);	if (prev) {		netdevice_t **prev_slave = prev->priv;		netdevice_t **slave = dev->priv;		*prev_slave = *slave;	} else {		netdevice_t **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.*/	if (dev->priv){		kfree(dev->priv);		dev->priv=NULL;	}	unregister_netdev(dev);      #ifdef LINUX_2_4	kfree(dev);      #else	if (dev->name){		kfree(dev->name);	}	kfree(dev);      #endif	return 0;}void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags){      #ifdef LINUX_2_0	save_flags(*smp_flags);	cli();      #else       	spin_lock_irqsave(lock, *smp_flags);      #endif}void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags){      #ifdef LINUX_2_0	restore_flags(*smp_flags);      #else	spin_unlock_irqrestore(lock, *smp_flags);      #endif}#if defined (LINUX_2_1) || defined (LINUX_2_4)EXPORT_SYMBOL(register_wan_device);EXPORT_SYMBOL(unregister_wan_device);EXPORT_SYMBOL(wanrouter_encapsulate);EXPORT_SYMBOL(wanrouter_type_trans);EXPORT_SYMBOL(lock_adapter_irq);EXPORT_SYMBOL(unlock_adapter_irq);#endif/* *	End */

⌨️ 快捷键说明

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