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

📄 mnx_eth.c

📁 Minix3.11的源码。[MINIX 3是一个为高可靠性应用而设计的自由且简洁的类UNIX系统。]
💻 C
📖 第 1 页 / 共 2 页
字号:
	for (;;)	{		r= sendrec(eth_port->etp_osdep.etp_task, &mess);		if (r != ELOCKED)			break;		r= receive(eth_port->etp_osdep.etp_task, &mlocked);		assert(r == OK);		compare(mlocked.m_type, ==, DL_TASK_REPLY);		eth_rec(&mlocked);	}	if (r != OK)	{		printf("eth_get_stat: sendrec to %d failed: %d\n",			eth_port->etp_osdep.etp_task, r);		return EIO;	}	assert(mess.m_type == DL_TASK_REPLY);	r= mess.DL_STAT >> 16;	assert (r == 0);	if (mess.DL_STAT)	{		eth_rec(&mess);	}	return OK;}PUBLIC void eth_set_rec_conf (eth_port, flags)eth_port_t *eth_port;u32_t flags;{	int r;	unsigned dl_flags;	message mess, repl_mess;	assert(!eth_port->etp_vlan);	eth_port->etp_osdep.etp_recvconf= flags;	dl_flags= DL_NOMODE;	if (flags & NWEO_EN_BROAD)		dl_flags |= DL_BROAD_REQ;	if (flags & NWEO_EN_MULTI)		dl_flags |= DL_MULTI_REQ;	if (flags & NWEO_EN_PROMISC)		dl_flags |= DL_PROMISC_REQ;	mess.m_type= DL_INIT;	mess.DL_PORT= eth_port->etp_osdep.etp_port;	mess.DL_PROC= this_proc;	mess.DL_MODE= dl_flags;	do	{		r= sendrec(eth_port->etp_osdep.etp_task, &mess);		if (r == ELOCKED)	/* etp_task is sending to this task,					   I hope */		{			if (receive (eth_port->etp_osdep.etp_task, 				&repl_mess)< 0)			{				ip_panic(("unable to receive"));			}			compare(repl_mess.m_type, ==, DL_TASK_REPLY);			eth_rec(&repl_mess);		}	} while (r == ELOCKED);		if (r < 0)	{		printf("eth_set_rec_conf: sendrec to %d failed: %d\n",			eth_port->etp_osdep.etp_task, r);		return;	}	assert (mess.m_type == DL_INIT_REPLY);	if (mess.m3_i1 != eth_port->etp_osdep.etp_port)	{		ip_panic(("got reply for wrong port"));	}}PRIVATE void write_int(eth_port)eth_port_t *eth_port;{	acc_t *pack;	int multicast;	u8_t *eth_dst_ptr;	pack= eth_port->etp_wr_pack;	eth_port->etp_wr_pack= NULL;	eth_dst_ptr= (u8_t *)ptr2acc_data(pack);	multicast= (*eth_dst_ptr & 1);	/* low order bit indicates multicast */	if (multicast || (eth_port->etp_osdep.etp_recvconf & NWEO_EN_PROMISC))	{		assert(!no_ethWritePort);		no_ethWritePort= 1;		eth_arrive(eth_port, pack, bf_bufsize(pack));		assert(no_ethWritePort);		no_ethWritePort= 0;	}	else		bf_afree(pack);	eth_restart_write(eth_port);}PRIVATE void read_int(eth_port, count)eth_port_t *eth_port;int count;{	acc_t *pack, *cut_pack;	pack= eth_port->etp_rd_pack;	eth_port->etp_rd_pack= NULL;	cut_pack= bf_cut(pack, 0, count);	bf_afree(pack);	assert(!no_ethWritePort);	no_ethWritePort= 1;	eth_arrive(eth_port, cut_pack, count);	assert(no_ethWritePort);	no_ethWritePort= 0;		eth_port->etp_flags &= ~(EPF_READ_IP|EPF_READ_SP);	setup_read(eth_port);}PRIVATE void setup_read(eth_port)eth_port_t *eth_port;{	eth_port_t *loc_port;	acc_t *pack, *pack_ptr;	message mess1, block_msg;	iovec_t *iovec;	ev_arg_t ev_arg;	int i, r;	assert(!eth_port->etp_vlan);	assert(!(eth_port->etp_flags & (EPF_READ_IP|EPF_READ_SP)));	do	{		assert (!eth_port->etp_rd_pack);		iovec= eth_port->etp_osdep.etp_rd_iovec;		pack= bf_memreq (ETH_MAX_PACK_SIZE_TAGGED);		for (i=0, pack_ptr= pack; i<RD_IOVEC && pack_ptr;			i++, pack_ptr= pack_ptr->acc_next)		{			iovec[i].iov_addr= (vir_bytes)ptr2acc_data(pack_ptr);			iovec[i].iov_size= (vir_bytes)pack_ptr->acc_length;		}		assert (!pack_ptr);		mess1.m_type= DL_READV;		mess1.DL_PORT= eth_port->etp_osdep.etp_port;		mess1.DL_PROC= this_proc;		mess1.DL_COUNT= i;		mess1.DL_ADDR= (char *)iovec;		for (;;)		{			if (recv_debug)			{				printf("eth%d: sending DL_READV\n",					mess1.DL_PORT);			}			r= sendrec(eth_port->etp_osdep.etp_task, &mess1);			if (r != ELOCKED)				break;			/* ethernet task is sending to this task, I hope */			r= receive(eth_port->etp_osdep.etp_task, &block_msg);			if (r < 0)				ip_panic(("unable to receive"));			loc_port= eth_port;			if (loc_port->etp_osdep.etp_port != block_msg.DL_PORT ||				loc_port->etp_osdep.etp_task !=				block_msg.m_source)			{				loc_port= find_port(&block_msg);			}			assert(block_msg.DL_STAT &				(DL_PACK_SEND|DL_PACK_RECV));			if (block_msg.DL_STAT & DL_PACK_SEND)			{				loc_port->etp_osdep.etp_sendrepl= block_msg;				ev_arg.ev_ptr= loc_port;				ev_enqueue(&loc_port->etp_sendev, eth_sendev,					ev_arg);			}			if (block_msg.DL_STAT & DL_PACK_RECV)			{				if (recv_debug)				{					printf(			"setup_read(block_msg): eth%d got DL_PACK_RECV\n",						block_msg.DL_PORT);				}				assert(loc_port != eth_port);				loc_port->etp_osdep.etp_recvrepl= block_msg;				ev_arg.ev_ptr= loc_port;				ev_enqueue(&loc_port->etp_osdep.etp_recvev,					eth_recvev, ev_arg);			}		}		if (r < 0)		{			printf("mnx_eth`setup_read: sendrec to %d failed: %d\n",				eth_port->etp_osdep.etp_task, r);			eth_port->etp_rd_pack= pack;			eth_port->etp_flags |= EPF_READ_IP;			continue;		}		assert (mess1.m_type == DL_TASK_REPLY &&			mess1.DL_PORT == mess1.DL_PORT &&			mess1.DL_PROC == this_proc);		compare((mess1.DL_STAT >> 16), ==, OK);		if (mess1.DL_STAT & DL_PACK_RECV)		{			if (recv_debug)			{				printf(			"setup_read(mess1): eth%d: got DL_PACK_RECV\n",					mess1.DL_PORT);			}			/* packet received */			pack_ptr= bf_cut(pack, 0, mess1.DL_COUNT);			bf_afree(pack);			assert(!no_ethWritePort);			no_ethWritePort= 1;			eth_arrive(eth_port, pack_ptr, mess1.DL_COUNT);			assert(no_ethWritePort);			no_ethWritePort= 0;		}		else		{			/* no packet received */			eth_port->etp_rd_pack= pack;			eth_port->etp_flags |= EPF_READ_IP;		}		if (mess1.DL_STAT & DL_PACK_SEND)		{			eth_port->etp_osdep.etp_sendrepl= mess1;			ev_arg.ev_ptr= eth_port;			ev_enqueue(&eth_port->etp_sendev, eth_sendev, ev_arg);		}	} while (!(eth_port->etp_flags & EPF_READ_IP));	eth_port->etp_flags |= EPF_READ_SP;}PRIVATE void eth_recvev(ev, ev_arg)event_t *ev;ev_arg_t ev_arg;{	eth_port_t *eth_port;	message *m_ptr;	eth_port= ev_arg.ev_ptr;	assert(ev == &eth_port->etp_osdep.etp_recvev);	m_ptr= &eth_port->etp_osdep.etp_recvrepl;	assert(m_ptr->m_type == DL_TASK_REPLY);	assert(eth_port->etp_osdep.etp_port == m_ptr->DL_PORT &&		eth_port->etp_osdep.etp_task == m_ptr->m_source);	assert(m_ptr->DL_STAT & DL_PACK_RECV);	m_ptr->DL_STAT &= ~DL_PACK_RECV;	if (recv_debug)	{		printf("eth_recvev: eth%d got DL_PACK_RECV\n", m_ptr->DL_PORT);	}	read_int(eth_port, m_ptr->DL_COUNT);}PRIVATE void eth_sendev(ev, ev_arg)event_t *ev;ev_arg_t ev_arg;{	eth_port_t *eth_port;	message *m_ptr;	eth_port= ev_arg.ev_ptr;	assert(ev == &eth_port->etp_sendev);	m_ptr= &eth_port->etp_osdep.etp_sendrepl;	assert (m_ptr->m_type == DL_TASK_REPLY);	assert(eth_port->etp_osdep.etp_port == m_ptr->DL_PORT &&		eth_port->etp_osdep.etp_task == m_ptr->m_source);	assert(m_ptr->DL_STAT & DL_PACK_SEND);	m_ptr->DL_STAT &= ~DL_PACK_SEND;	/* packet is sent */	write_int(eth_port);}PRIVATE eth_port_t *find_port(m)message *m;{	eth_port_t *loc_port;	int i;	for (i=0, loc_port= eth_port_table; i<eth_conf_nr; i++, loc_port++)	{		if (loc_port->etp_osdep.etp_port == m->DL_PORT &&			loc_port->etp_osdep.etp_task == m->m_source)			break;	}	assert (i<eth_conf_nr);	return loc_port;}static void eth_restart(eth_port, tasknr)eth_port_t *eth_port;int tasknr;{	int r;	unsigned flags, dl_flags;	message mess;#if 0	int i, r, rport;	struct eth_conf *ecp;	eth_port_t *rep;#endif	printf("eth_restart: restarting eth%d, task %d, port %d\n",		eth_port-eth_port_table, tasknr,		eth_port->etp_osdep.etp_port);	eth_port->etp_osdep.etp_task= tasknr;	flags= eth_port->etp_osdep.etp_recvconf;	dl_flags= DL_NOMODE;	if (flags & NWEO_EN_BROAD)		dl_flags |= DL_BROAD_REQ;	if (flags & NWEO_EN_MULTI)		dl_flags |= DL_MULTI_REQ;	if (flags & NWEO_EN_PROMISC)		dl_flags |= DL_PROMISC_REQ;	mess.m_type= DL_INIT;	mess.DL_PORT= eth_port->etp_osdep.etp_port;	mess.DL_PROC= this_proc;	mess.DL_MODE= dl_flags;	r= sendrec(eth_port->etp_osdep.etp_task, &mess);	/* YYY */	if (r<0)	{		printf(	"eth_restart: sendrec to ethernet task %d failed: %d\n",			eth_port->etp_osdep.etp_task, r);		return;	}	if (mess.m3_i1 == ENXIO)	{		printf(	"osdep_eth_init: no ethernet device at task=%d,port=%d\n",			eth_port->etp_osdep.etp_task, 			eth_port->etp_osdep.etp_port);		return;	}	if (mess.m3_i1 < 0)		ip_panic(("osdep_eth_init: DL_INIT returned error %d\n",			mess.m3_i1));			if (mess.m3_i1 != eth_port->etp_osdep.etp_port)	{		ip_panic(("osdep_eth_init: got reply for wrong port (got %d, expected %d)\n",			mess.m3_i1, eth_port->etp_osdep.etp_port));	}	eth_port->etp_ethaddr= *(ether_addr_t *)mess.m3_ca1;	eth_port->etp_flags |= EPF_ENABLED;	if (eth_port->etp_wr_pack)	{		bf_afree(eth_port->etp_wr_pack);		eth_port->etp_wr_pack= NULL;		eth_restart_write(eth_port);	}	if (eth_port->etp_rd_pack)	{		bf_afree(eth_port->etp_rd_pack);		eth_port->etp_rd_pack= NULL;		eth_port->etp_flags &= ~(EPF_READ_IP|EPF_READ_SP);	}	setup_read (eth_port);}/* * $PchId: mnx_eth.c,v 1.16 2005/06/28 14:24:37 philip Exp $ */

⌨️ 快捷键说明

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