📄 dp8390.c
字号:
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 + -