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

📄 dp8390.c

📁 minix3的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
static void dp_nic2user(dep, nic_addr, iovp, offset, count)dpeth_t *dep;int nic_addr;iovec_dat_t *iovp;vir_bytes offset;vir_bytes count;{	vir_bytes vir_hw, vir_user;	int bytes, i, r;	vir_hw = dep->de_linmem + nic_addr;	i= 0;	while (count > 0)	{		if (i >= IOVEC_NR)		{			dp_next_iovec(iovp);			i= 0;			continue;		}		assert(i < iovp->iod_iovec_s);		if (offset >= iovp->iod_iovec[i].iov_size)		{			offset -= iovp->iod_iovec[i].iov_size;			i++;			continue;		}		bytes = iovp->iod_iovec[i].iov_size - offset;		if (bytes > count)			bytes = count;		r= sys_vircopy(SELF, BIOS_SEG, vir_hw,			iovp->iod_proc_nr, D,			iovp->iod_iovec[i].iov_addr + offset, bytes);		if (r != OK)			panic("DP8390", "dp_nic2user: sys_vircopy failed", r);		count -= bytes;		vir_hw += bytes;		offset += bytes;	}	assert(count == 0);}/*===========================================================================* *				dp_pio8_nic2user			     * *===========================================================================*/static void dp_pio8_nic2user(dep, nic_addr, iovp, offset, count)dpeth_t *dep;int nic_addr;iovec_dat_t *iovp;vir_bytes offset;vir_bytes count;{	phys_bytes phys_user;	int bytes, i;	outb_reg0(dep, DP_RBCR0, count & 0xFF);	outb_reg0(dep, DP_RBCR1, count >> 8);	outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);	outb_reg0(dep, DP_RSAR1, nic_addr >> 8);	outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);	i= 0;	while (count > 0)	{		if (i >= IOVEC_NR)		{			dp_next_iovec(iovp);			i= 0;			continue;		}		assert(i < iovp->iod_iovec_s);		if (offset >= iovp->iod_iovec[i].iov_size)		{			offset -= iovp->iod_iovec[i].iov_size;			i++;			continue;		}		bytes = iovp->iod_iovec[i].iov_size - offset;		if (bytes > count)			bytes = count;		do_vir_insb(dep->de_data_port, iovp->iod_proc_nr,			iovp->iod_iovec[i].iov_addr + offset, bytes);		count -= bytes;		offset += bytes;	}	assert(count == 0);}/*===========================================================================* *				dp_pio16_nic2user			     * *===========================================================================*/static void dp_pio16_nic2user(dep, nic_addr, iovp, offset, count)dpeth_t *dep;int nic_addr;iovec_dat_t *iovp;vir_bytes offset;vir_bytes count;{	vir_bytes vir_user;	vir_bytes ecount;	int i, r, bytes, user_proc;	u8_t two_bytes[2];	int odd_byte;	ecount= (count+1) & ~1;	odd_byte= 0;	outb_reg0(dep, DP_RBCR0, ecount & 0xFF);	outb_reg0(dep, DP_RBCR1, ecount >> 8);	outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);	outb_reg0(dep, DP_RSAR1, nic_addr >> 8);	outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);	i= 0;	while (count > 0)	{		if (i >= IOVEC_NR)		{			dp_next_iovec(iovp);			i= 0;			continue;		}		assert(i < iovp->iod_iovec_s);		if (offset >= iovp->iod_iovec[i].iov_size)		{			offset -= iovp->iod_iovec[i].iov_size;			i++;			continue;		}		bytes = iovp->iod_iovec[i].iov_size - offset;		if (bytes > count)			bytes = count;		user_proc= iovp->iod_proc_nr;		vir_user= iovp->iod_iovec[i].iov_addr + offset;		if (odd_byte)		{			r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[1],				user_proc, D, vir_user,  1);			if (r != OK)			{				panic("DP8390",					"dp_pio16_nic2user: sys_vircopy failed",					r);			}			count--;			offset++;			bytes--;			vir_user++;			odd_byte= 0;			if (!bytes)				continue;		}		ecount= bytes & ~1;		if (ecount != 0)		{			do_vir_insw(dep->de_data_port, user_proc, vir_user,				ecount);			count -= ecount;			offset += ecount;			bytes -= ecount;			vir_user += ecount;		}		if (bytes)		{			assert(bytes == 1);			*(u16_t *)two_bytes= inw(dep->de_data_port);			r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[0],				user_proc, D, vir_user,  1);			if (r != OK)			{				panic("DP8390",					"dp_pio16_nic2user: sys_vircopy failed",					r);			}			count--;			offset++;			bytes--;			vir_user++;			odd_byte= 1;		}	}	assert(count == 0);}/*===========================================================================* *				dp_next_iovec					     * *===========================================================================*/static void dp_next_iovec(iovp)iovec_dat_t *iovp;{	assert(iovp->iod_iovec_s > IOVEC_NR);	iovp->iod_iovec_s -= IOVEC_NR;	iovp->iod_iovec_addr += IOVEC_NR * sizeof(iovec_t);	get_userdata(iovp->iod_proc_nr, iovp->iod_iovec_addr, 		(iovp->iod_iovec_s > IOVEC_NR ? IOVEC_NR : iovp->iod_iovec_s) *		sizeof(iovec_t), iovp->iod_iovec); }/*===========================================================================* *				conf_hw					     * *===========================================================================*/static void conf_hw(dep)dpeth_t *dep;{	static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0 	/* ,... */ };	int ifnr;	dp_conf_t *dcp;	dep->de_mode= DEM_DISABLED;	/* Superfluous */	ifnr= dep-de_table;	dcp= &dp_conf[ifnr];	update_conf(dep, dcp);	if (dep->de_mode != DEM_ENABLED)		return;	if (!wdeth_probe(dep) && !ne_probe(dep) && !el2_probe(dep))	{		printf("%s: No ethernet card found at 0x%x\n", 			dep->de_name, dep->de_base_port);		dep->de_mode= DEM_DISABLED;		return;	}/* XXX */ if (dep->de_linmem == 0) dep->de_linmem= 0xFFFF0000;	dep->de_flags = DEF_EMPTY;	dep->de_stat = empty_stat;}/*===========================================================================* *				update_conf				     * *===========================================================================*/static void update_conf(dep, dcp)dpeth_t *dep;dp_conf_t *dcp;{	long v;	static char dpc_fmt[] = "x:d:x:x";#if ENABLE_PCI	if (dep->de_pci)	{		if (dep->de_pci == 1)		{			/* PCI device is present */			dep->de_mode= DEM_ENABLED;		}		return;		/* Already configured */	}#endif	/* Get the default settings and modify them from the environment. */	dep->de_mode= DEM_SINK;	v= dcp->dpc_port;	switch (env_parse(dcp->dpc_envvar, dpc_fmt, 0, &v, 0x0000L, 0xFFFFL)) {	case EP_OFF:		dep->de_mode= DEM_DISABLED;		break;	case EP_ON:	case EP_SET:		dep->de_mode= DEM_ENABLED;	/* Might become disabled if 						 * all probes fail */		break;	}	dep->de_base_port= v;	v= dcp->dpc_irq | DEI_DEFAULT;	(void) env_parse(dcp->dpc_envvar, dpc_fmt, 1, &v, 0L,						(long) NR_IRQ_VECTORS - 1);	dep->de_irq= v;	v= dcp->dpc_mem;	(void) env_parse(dcp->dpc_envvar, dpc_fmt, 2, &v, 0L, 0xFFFFFL);	dep->de_linmem= v;	v= 0;	(void) env_parse(dcp->dpc_envvar, dpc_fmt, 3, &v, 0x2000L, 0x8000L);	dep->de_ramsize= v;}/*===========================================================================* *				calc_iovec_size				     * *===========================================================================*/static int calc_iovec_size(iovp)iovec_dat_t *iovp;{	/* Calculate the size of a request. Note that the iovec_dat	 * structure will be unusable after calc_iovec_size.	 */	int size;	int i;	size= 0;	i= 0;	while (i < iovp->iod_iovec_s)	{		if (i >= IOVEC_NR)		{			dp_next_iovec(iovp);			i= 0;			continue;		}		size += iovp->iod_iovec[i].iov_size;		i++;	}	return size;}/*===========================================================================* *				reply					     * *===========================================================================*/static void reply(dep, err, may_block)dpeth_t *dep;int err;int may_block;{	message reply;	int status;	int r;	status = 0;	if (dep->de_flags & DEF_PACK_SEND)		status |= DL_PACK_SEND;	if (dep->de_flags & DEF_PACK_RECV)		status |= DL_PACK_RECV;	reply.m_type = DL_TASK_REPLY;	reply.DL_PORT = dep - de_table;	reply.DL_PROC = dep->de_client;	reply.DL_STAT = status | ((u32_t) err << 16);	reply.DL_COUNT = dep->de_read_s;	reply.DL_CLCK = 0;	/* Don't know */	r= send(dep->de_client, &reply);	if (r == ELOCKED && may_block)	{#if 0		printf("send locked\n");#endif		return;	}	if (r < 0)		panic("", "dp8390: send failed:", r);		dep->de_read_s = 0;	dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);}/*===========================================================================* *				mess_reply				     * *===========================================================================*/static void mess_reply(req, reply_mess)message *req;message *reply_mess;{	if (send(req->m_source, reply_mess) != OK)		panic("", "dp8390: unable to mess_reply", NO_NUM);}/*===========================================================================* *				get_userdata				     * *===========================================================================*/static void get_userdata(user_proc, user_addr, count, loc_addr)int user_proc;vir_bytes user_addr;vir_bytes count;void *loc_addr;{	int r;	r= sys_vircopy(user_proc, D, user_addr,		SELF, D, (vir_bytes)loc_addr, count);	if (r != OK)		panic("DP8390", "get_userdata: sys_vircopy failed", r);}/*===========================================================================* *				put_userdata				     * *===========================================================================*/static void put_userdata(user_proc, user_addr, count, loc_addr)int user_proc;vir_bytes user_addr;vir_bytes count;void *loc_addr;{	int r;	r= sys_vircopy(SELF, D, (vir_bytes)loc_addr, 		user_proc, D, user_addr, count);	if (r != OK)		panic("DP8390", "put_userdata: sys_vircopy failed", r);}u8_t inb(port_t port){	int r;	u32_t value;	r= sys_inb(port, &value);	if (r != OK)		panic("DP8390","sys_inb failed", r);	return value;}u16_t inw(port_t port){	int r;	u16_t value;	r= sys_inw(port, &value);	if (r != OK)		panic("DP8390", "sys_inw failed", r);	return value;}void outb(port_t port, u8_t value){	int r;	r= sys_outb(port, value);	if (r != OK)		panic("DP8390", "sys_outb failed", r);}void outw(port_t port, u16_t value){	int r;	r= sys_outw(port, value);	if (r != OK)		panic("DP8390", "sys_outw failed", r);}static void insb(port_t port, void *buf, size_t size){	do_vir_insb(port, SELF, (vir_bytes)buf, size);}static void insw(port_t port, void *buf, size_t size){	do_vir_insw(port, SELF, (vir_bytes)buf, size);}static void do_vir_insb(port_t port, int proc, vir_bytes buf, size_t size){	int r;	r= sys_sdevio(DIO_INPUT, port, DIO_BYTE, proc, (void *)buf, size);	if (r != OK)		panic("DP8390", "sys_sdevio failed", r);}static void do_vir_insw(port_t port, int proc, vir_bytes buf, size_t size){	int r;	r= sys_sdevio(DIO_INPUT, port, DIO_WORD, proc, (void *)buf, size);	if (r != OK)		panic("DP8390", "sys_sdevio failed", r);}static void do_vir_outsb(port_t port, int proc, vir_bytes buf, size_t size){	int r;	r= sys_sdevio(DIO_OUTPUT, port, DIO_BYTE, proc, (void *)buf, size);	if (r != OK)		panic("DP8390", "sys_sdevio failed", r);}static void do_vir_outsw(port_t port, int proc, vir_bytes buf, size_t size){	int r;	r= sys_sdevio(DIO_OUTPUT, port, DIO_WORD, proc, (void *)buf, size);	if (r != OK)		panic("DP8390", "sys_sdevio failed", r);}/* * $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $ */

⌨️ 快捷键说明

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