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

📄 dvb_net.c

📁 linux_dvb的驱动程序:linuxtv-dvb-1.1.1.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
	dvb_net_feed_stop(dev);	priv->rx_mode = RX_MODE_UNI;		if(dev->flags & IFF_PROMISC) {		dprintk("%s: promiscuous mode\n", dev->name);		priv->rx_mode = RX_MODE_PROMISC;	} else if ((dev->flags & IFF_ALLMULTI)) {		dprintk("%s: allmulti mode\n", dev->name);		priv->rx_mode = RX_MODE_ALL_MULTI;	} else if (dev->mc_count) {		int mci;		struct dev_mc_list *mc;		dprintk("%s: set_mc_list, %d entries\n",			dev->name, dev->mc_count);		priv->rx_mode = RX_MODE_MULTI;		priv->multi_num = 0;		for (mci = 0, mc=dev->mc_list; 		     mci < dev->mc_count;		     mc = mc->next, mci++) {			dvb_set_mc_filter(dev, mc);		}	}		dvb_net_feed_start(dev);	}static void dvb_net_set_multicast_list (struct net_device *dev){	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;	schedule_work(&priv->set_multicast_list_wq);}static int dvb_net_set_config(struct net_device *dev, struct ifmap *map){	if (netif_running(dev))		return -EBUSY;	return 0;}static void wq_restart_net_feed (void *data){	struct net_device *dev = data;	if (netif_running(dev)) {		dvb_net_feed_stop(dev);		dvb_net_feed_start(dev);	}}static int dvb_net_set_mac (struct net_device *dev, void *p){	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;	struct sockaddr *addr=p;	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);	if (netif_running(dev))		schedule_work(&priv->restart_net_feed_wq);	return 0;}static int dvb_net_open(struct net_device *dev){	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;	priv->in_use++;	dvb_net_feed_start(dev);	return 0;}static int dvb_net_stop(struct net_device *dev){	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;	priv->in_use--;        dvb_net_feed_stop(dev);	return 0;}static struct net_device_stats * dvb_net_get_stats(struct net_device *dev){        return &((struct dvb_net_priv*) dev->priv)->stats;}#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)static int dvb_net_init_dev (struct net_device *dev)#elsestatic void dvb_net_setup(struct net_device *dev)#endif{	ether_setup(dev);	dev->open		= dvb_net_open;	dev->stop		= dvb_net_stop;	dev->hard_start_xmit	= dvb_net_tx;	dev->get_stats		= dvb_net_get_stats;	dev->set_multicast_list = dvb_net_set_multicast_list;	dev->set_config         = dvb_net_set_config;	dev->set_mac_address    = dvb_net_set_mac;	dev->mtu		= 4096;	dev->mc_count           = 0;	dev->hard_header_cache  = NULL;	dev->flags |= IFF_NOARP;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	return 0;#endif}static int get_if(struct dvb_net *dvbnet){	int i;	for (i=0; i<DVB_NET_DEVICES_MAX; i++)		if (!dvbnet->state[i])			break;	if (i == DVB_NET_DEVICES_MAX)		return -1;	dvbnet->state[i]=1;	return i;}#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid){        struct net_device *net;	struct dmx_demux *demux;	struct dvb_net_priv *priv;	int result;	int if_num; 	if ((if_num = get_if(dvbnet)) < 0)		return -EINVAL;	net = &dvbnet->device[if_num];	demux = dvbnet->demux;		memset(net, 0, sizeof(struct net_device));	memcpy(net->name, "dvb0_0", 7);	net->name[3]   = dvbnet->dvbdev->adapter->num + '0';	net->name[5]   = if_num + '0';	net->addr_len  		= 6;	memcpy(net->dev_addr, dvbnet->dvbdev->adapter->proposed_mac, 6);	net->next      = NULL;	net->init      = dvb_net_init_dev;	if (!(net->priv = kmalloc(sizeof(struct dvb_net_priv), GFP_KERNEL)))		return -ENOMEM;		priv = net->priv;	memset(priv, 0, sizeof(struct dvb_net_priv));	priv->demux = demux;        priv->pid = pid;	priv->rx_mode = RX_MODE_UNI;	INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list, net);	INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed, net);        net->base_addr = pid;                	if ((result = register_netdev(net)) < 0) {		return result;	}        return if_num;}#elsestatic int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid){        struct net_device *net;	struct dvb_net_priv *priv;	int result;	int if_num; 	if ((if_num = get_if(dvbnet)) < 0)		return -EINVAL;	net = alloc_netdev(sizeof(struct dvb_net_priv), "dvb",			   dvb_net_setup);	if (!net)		return -ENOMEM;		sprintf(net->name, "dvb%d_%d", dvbnet->dvbdev->adapter->num, if_num);	net->addr_len  		= 6;	memcpy(net->dev_addr, dvbnet->dvbdev->adapter->proposed_mac, 6);	dvbnet->device[if_num] = net;		priv = net->priv;        priv->demux = dvbnet->demux;        priv->pid = pid;	priv->rx_mode = RX_MODE_UNI;	INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list, net);	INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed, net);        net->base_addr = pid;                	if ((result = register_netdev(net)) < 0) {		dvbnet->device[if_num] = NULL;		free_netdev(net);		return result;	}        return if_num;}#endif#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)static int dvb_net_remove_if(struct dvb_net *dvbnet, int num){	struct dvb_net_priv *priv = dvbnet->device[num].priv;	if (!dvbnet->state[num])		return -EINVAL;	if (priv->in_use)		return -EBUSY;	dvb_net_stop(&dvbnet->device[num]);	flush_scheduled_work();	kfree(priv);	unregister_netdev(&dvbnet->device[num]);	dvbnet->state[num]=0;	return 0;}#elsestatic int dvb_net_remove_if(struct dvb_net *dvbnet, int num){	struct net_device *net = dvbnet->device[num];	struct dvb_net_priv *priv = net->priv;	if (!dvbnet->state[num])		return -EINVAL;	if (priv->in_use)		return -EBUSY;	dvb_net_stop(net);	flush_scheduled_work();        unregister_netdev(net);	dvbnet->state[num]=0;	dvbnet->device[num] = NULL;	free_netdev(net);	return 0;}#endifstatic int dvb_net_do_ioctl(struct inode *inode, struct file *file,		  unsigned int cmd, void *parg){	struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;	struct dvb_net *dvbnet = (struct dvb_net *) dvbdev->priv;	if (((file->f_flags&O_ACCMODE)==O_RDONLY))		return -EPERM;		switch (cmd) {	case NET_ADD_IF:	{		struct dvb_net_if *dvbnetif=(struct dvb_net_if *)parg;		int result;				if (!capable(CAP_SYS_ADMIN))			return -EPERM;		result=dvb_net_add_if(dvbnet, dvbnetif->pid);		if (result<0)			return result;		dvbnetif->if_num=result;		break;	}	case NET_GET_IF:	{		struct net_device *netdev;		struct dvb_net_priv *priv_data;		struct dvb_net_if *dvbnetif=(struct dvb_net_if *)parg;		if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||		    !dvbnet->state[dvbnetif->if_num])			return -EINVAL;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)		netdev = &dvbnet->device[dvbnetif->if_num];#else		netdev = dvbnet->device[dvbnetif->if_num];#endif		priv_data=(struct dvb_net_priv*)netdev->priv;		dvbnetif->pid=priv_data->pid;		break;	}	case NET_REMOVE_IF:		if (!capable(CAP_SYS_ADMIN))			return -EPERM;		return dvb_net_remove_if(dvbnet, (int) (long) parg);	default:		return -ENOTTY;	}	return 0;}static int dvb_net_ioctl(struct inode *inode, struct file *file,	      unsigned int cmd, unsigned long arg){	return dvb_usercopy(inode, file, cmd, arg, dvb_net_do_ioctl);}static struct file_operations dvb_net_fops = {	.owner = THIS_MODULE,        .read =	0,	.write = 0,	.ioctl = dvb_net_ioctl,	.open =	dvb_generic_open,	.release = dvb_generic_release,	.poll =	0,};static struct dvb_device dvbdev_net = {        .priv = 0,        .users = 1,        .writers = 1,        .fops = &dvb_net_fops,};void dvb_net_release (struct dvb_net *dvbnet){	int i;	dvb_unregister_device(dvbnet->dvbdev);	for (i=0; i<DVB_NET_DEVICES_MAX; i++) {		if (!dvbnet->state[i])			continue;		dvb_net_remove_if(dvbnet, i);	}}int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet,		  struct dmx_demux *dmx){	int i;			dvbnet->demux = dmx;	for (i=0; i<DVB_NET_DEVICES_MAX; i++)		dvbnet->state[i] = 0;	dvb_register_device (adap, &dvbnet->dvbdev, &dvbdev_net,			     dvbnet, DVB_DEVICE_NET);	return 0;}

⌨️ 快捷键说明

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