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

📄 lec.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
                      &ioc_data, vcc, vcc->push);        vcc->proto_data = dev_lec[ioc_data.dev_num];        vcc->push = lec_push;        return 0;}int lec_mcast_attach(struct atm_vcc *vcc, int arg){        if (arg <0 || arg >= MAX_LEC_ITF || !dev_lec[arg])                return -EINVAL;        vcc->proto_data = dev_lec[arg];        return (lec_mcast_make((struct lec_priv*)dev_lec[arg]->priv, vcc));}/* Initialize device. */int lecd_attach(struct atm_vcc *vcc, int arg){          int i;        struct lec_priv *priv;        if (arg<0)                i = 0;        else                i = arg;#ifdef CONFIG_TR        if (arg >= MAX_LEC_ITF)                return -EINVAL;#else /* Reserve the top NUM_TR_DEVS for TR */        if (arg >= (MAX_LEC_ITF-NUM_TR_DEVS))                return -EINVAL;#endif        if (!dev_lec[i]) {                int is_trdev, size;                is_trdev = 0;                if (i >= (MAX_LEC_ITF - NUM_TR_DEVS))                        is_trdev = 1;                size = sizeof(struct lec_priv);#ifdef CONFIG_TR                if (is_trdev)                        dev_lec[i] = alloc_trdev(size);                else#endif                dev_lec[i] = alloc_etherdev(size);                if (!dev_lec[i])                        return -ENOMEM;                snprintf(dev_lec[i]->name, IFNAMSIZ, "lec%d", i);                if (register_netdev(dev_lec[i])) {                        free_netdev(dev_lec[i]);                        return -EINVAL;                }                priv = dev_lec[i]->priv;                priv->is_trdev = is_trdev;                lec_init(dev_lec[i]);        } else {                priv = dev_lec[i]->priv;                if (priv->lecd)                        return -EADDRINUSE;        }        lec_arp_init(priv);	priv->itfnum = i;  /* LANE2 addition */        priv->lecd = vcc;        vcc->dev = &lecatm_dev;        vcc_insert_socket(vcc->sk);                vcc->proto_data = dev_lec[i];	set_bit(ATM_VF_META,&vcc->flags);	set_bit(ATM_VF_READY,&vcc->flags);        /* Set default values to these variables */        priv->maximum_unknown_frame_count = 1;        priv->max_unknown_frame_time = (1*HZ);        priv->vcc_timeout_period = (1200*HZ);        priv->max_retry_count = 1;        priv->aging_time = (300*HZ);        priv->forward_delay_time = (15*HZ);        priv->topology_change = 0;        priv->arp_response_time = (1*HZ);        priv->flush_timeout = (4*HZ);        priv->path_switching_delay = (6*HZ);        if (dev_lec[i]->flags & IFF_UP) {                netif_start_queue(dev_lec[i]);        }        __module_get(THIS_MODULE);        return i;}#ifdef CONFIG_PROC_FSstatic char* lec_arp_get_status_string(unsigned char status){	static char *lec_arp_status_string[] = {		"ESI_UNKNOWN       ",		"ESI_ARP_PENDING   ",		"ESI_VC_PENDING    ",		"<Undefined>       ",		"ESI_FLUSH_PENDING ",		"ESI_FORWARD_DIRECT"	};	if (status > ESI_FORWARD_DIRECT)		status = 3;	/* ESI_UNDEFINED */	return lec_arp_status_string[status];}static void lec_info(struct seq_file *seq, struct lec_arp_table *entry){	int i;	for (i = 0; i < ETH_ALEN; i++)		seq_printf(seq, "%2.2x", entry->mac_addr[i] & 0xff);	seq_printf(seq, " ");	for (i = 0; i < ATM_ESA_LEN; i++)		seq_printf(seq, "%2.2x", entry->atm_addr[i] & 0xff);	seq_printf(seq, " %s %4.4x", lec_arp_get_status_string(entry->status),		   entry->flags & 0xffff);	if (entry->vcc)		seq_printf(seq, "%3d %3d ", entry->vcc->vpi, entry->vcc->vci);	else	        seq_printf(seq, "        ");	if (entry->recv_vcc) {		seq_printf(seq, "     %3d %3d", entry->recv_vcc->vpi,			   entry->recv_vcc->vci);        }        seq_putc(seq, '\n');}struct lec_state {	unsigned long flags;	struct lec_priv *locked;	struct lec_arp_table *entry;	struct net_device *dev;	int itf;	int arp_table;	int misc_table;};static void *lec_tbl_walk(struct lec_state *state, struct lec_arp_table *tbl,			  loff_t *l){	struct lec_arp_table *e = state->entry;	if (!e)		e = tbl;	if (e == (void *)1) {		e = tbl;		--*l;	}	for (; e; e = e->next) {		if (--*l < 0)			break;	}	state->entry = e;	return (*l < 0) ? state : NULL;}static void *lec_arp_walk(struct lec_state *state, loff_t *l,			      struct lec_priv *priv){	void *v = NULL;	int p;	for (p = state->arp_table; p < LEC_ARP_TABLE_SIZE; p++) {		v = lec_tbl_walk(state, priv->lec_arp_tables[p], l);		if (v)			break;	}	state->arp_table = p;	return v;}static void *lec_misc_walk(struct lec_state *state, loff_t *l,			   struct lec_priv *priv){	struct lec_arp_table *lec_misc_tables[] = {		priv->lec_arp_empty_ones,		priv->lec_no_forward,		priv->mcast_fwds	};	void *v = NULL;	int q;	for (q = state->misc_table; q < ARRAY_SIZE(lec_misc_tables); q++) {		v = lec_tbl_walk(state, lec_misc_tables[q], l);		if (v)			break;	}	state->misc_table = q;	return v;}static void *lec_priv_walk(struct lec_state *state, loff_t *l,			   struct lec_priv *priv){	if (!state->locked) {		state->locked = priv;		spin_lock_irqsave(&priv->lec_arp_lock, state->flags);	}	if (!lec_arp_walk(state, l, priv) &&	    !lec_misc_walk(state, l, priv)) {		spin_unlock_irqrestore(&priv->lec_arp_lock, state->flags);		state->locked = NULL;		/* Partial state reset for the next time we get called */		state->arp_table = state->misc_table = 0;	}	return state->locked;}static void *lec_itf_walk(struct lec_state *state, loff_t *l){	struct net_device *dev;	void *v;	dev = state->dev ? state->dev : dev_lec[state->itf];	v = (dev && dev->priv) ? lec_priv_walk(state, l, dev->priv) : NULL;	if (!v && dev) {		dev_put(dev);		/* Partial state reset for the next time we get called */		dev = NULL;	}	state->dev = dev;	return v;}static void *lec_get_idx(struct lec_state *state, loff_t l){	void *v = NULL;	for (; state->itf < MAX_LEC_ITF; state->itf++) {		v = lec_itf_walk(state, &l);		if (v)			break;	}	return v; }static void *lec_seq_start(struct seq_file *seq, loff_t *pos){	struct lec_state *state = seq->private;	state->itf = 0;	state->dev = NULL;	state->locked = NULL;	state->arp_table = 0;	state->misc_table = 0;	state->entry = (void *)1;	return *pos ? lec_get_idx(state, *pos) : (void*)1;}static void lec_seq_stop(struct seq_file *seq, void *v){	struct lec_state *state = seq->private;	if (state->dev) {		spin_unlock_irqrestore(&state->locked->lec_arp_lock,				       state->flags);		dev_put(state->dev);	}}static void *lec_seq_next(struct seq_file *seq, void *v, loff_t *pos){	struct lec_state *state = seq->private;	v = lec_get_idx(state, 1);	*pos += !!PTR_ERR(v);	return v;}static int lec_seq_show(struct seq_file *seq, void *v){	static char lec_banner[] = "Itf  MAC          ATM destination" 		"                          Status            Flags "		"VPI/VCI Recv VPI/VCI\n";	if (v == (void *)1)		seq_puts(seq, lec_banner);	else {		struct lec_state *state = seq->private;		struct net_device *dev = state->dev; 		seq_printf(seq, "%s ", dev->name);		lec_info(seq, state->entry);	}	return 0;}static struct seq_operations lec_seq_ops = {	.start	= lec_seq_start,	.next	= lec_seq_next,	.stop	= lec_seq_stop,	.show	= lec_seq_show,};static int lec_seq_open(struct inode *inode, struct file *file){	struct lec_state *state;	struct seq_file *seq;	int rc = -EAGAIN;	state = kmalloc(sizeof(*state), GFP_KERNEL);	if (!state) {		rc = -ENOMEM;		goto out;	}	rc = seq_open(file, &lec_seq_ops);	if (rc)		goto out_kfree;	seq = file->private_data;	seq->private = state;out:	return rc;out_kfree:	kfree(state);	goto out;}static int lec_seq_release(struct inode *inode, struct file *file){	return seq_release_private(inode, file);}static struct file_operations lec_seq_fops = {	.owner		= THIS_MODULE,	.open		= lec_seq_open,	.read		= seq_read,	.llseek		= seq_lseek,	.release	= lec_seq_release,};#endifstatic int lane_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg){	struct atm_vcc *vcc = ATM_SD(sock);	int err = 0;		switch (cmd) {		case ATMLEC_CTRL: 		case ATMLEC_MCAST:		case ATMLEC_DATA:			if (!capable(CAP_NET_ADMIN))				return -EPERM;			break;		default:			return -ENOIOCTLCMD;	}	switch (cmd) {		case ATMLEC_CTRL:			err = lecd_attach(vcc, (int) arg);			if (err >= 0)				sock->state = SS_CONNECTED;			break;		case ATMLEC_MCAST:			err = lec_mcast_attach(vcc, (int) arg);			break;		case ATMLEC_DATA:			err = lec_vcc_attach(vcc, (void __user *) arg);			break;	}	return err;}static struct atm_ioctl lane_ioctl_ops = {	.owner  = THIS_MODULE,	.ioctl  = lane_ioctl,};static int __init lane_module_init(void){#ifdef CONFIG_PROC_FS	struct proc_dir_entry *p;	p = create_proc_entry("lec", S_IRUGO, atm_proc_root);	if (p)		p->proc_fops = &lec_seq_fops;#endif	register_atm_ioctl(&lane_ioctl_ops);        printk("lec.c: " __DATE__ " " __TIME__ " initialized\n");        return 0;}static void __exit lane_module_cleanup(void){        int i;        struct lec_priv *priv;	remove_proc_entry("lec", atm_proc_root);

⌨️ 快捷键说明

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