📄 dp.c
字号:
memset(dep->de_address.ea_addr, 0, sizeof(ether_addr_t)); dp_confaddr(dep); /* Station address from env. */ break; default: break; } *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address; } else /* Port number is out of range */ port = ENXIO; reply_mess.m_type = DL_INIT_REPLY; reply_mess.m3_i1 = port; reply_mess.m3_i2 = DE_PORT_NR; DEBUG(printf("\t reply %d\n", reply_mess.m_type)); if (send(mp->m_source, &reply_mess) != OK) /* Can't send */ panic(dep->de_name, SendErrMsg, mp->m_source); return;}/*** Name: void dp_next_iovec(iovec_dat_t *iovp)** Function: Retrieves data from next iovec element.*/PUBLIC void dp_next_iovec(iovec_dat_t * iovp){ 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, iovp->iod_iovec); return;}/*** Name: int calc_iovec_size(iovec_dat_t *iovp)** Function: Compute the size of a request.*/static int calc_iovec_size(iovec_dat_t * iovp){ int size, ix; size = ix = 0; do { size += iovp->iod_iovec[ix].iov_size; if (++ix >= IOVEC_NR) { dp_next_iovec(iovp); ix = 0; } /* Till all vectors added */ } while (ix < iovp->iod_iovec_s); return size;}/*** Name: void do_vwrite(message *mp, int vectored)** Function:*/static void do_vwrite(message * mp, int vectored){ int port, size; dpeth_t *dep; port = mp->DL_PORT; if (port < 0 || port >= DE_PORT_NR) /* Check for illegal port number */ panic(dep->de_name, PortErrMsg, port); dep = &de_table[port]; dep->de_client = mp->DL_PROC; if (dep->de_mode == DEM_ENABLED) { if (dep->de_flags & DEF_SENDING) /* Is sending in progress? */ panic(dep->de_name, "send already in progress ", NO_NUM); dep->de_write_iovec.iod_proc_nr = mp->DL_PROC; if (vectored) { get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR, mp->DL_COUNT, dep->de_write_iovec.iod_iovec); dep->de_write_iovec.iod_iovec_s = mp->DL_COUNT; dep->de_write_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR; size = calc_iovec_size(&dep->de_write_iovec); } else { dep->de_write_iovec.iod_iovec[0].iov_addr = (vir_bytes) mp->DL_ADDR; dep->de_write_iovec.iod_iovec[0].iov_size = size = mp->DL_COUNT; dep->de_write_iovec.iod_iovec_s = 1; dep->de_write_iovec.iod_iovec_addr = 0; } if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE) panic(dep->de_name, SizeErrMsg, size); dep->de_flags |= DEF_SENDING; (*dep->de_sendf) (dep, FALSE, size); } else if (dep->de_mode == DEM_SINK) dep->de_flags |= DEF_ACK_SEND; reply(dep, OK); return;}/*** Name: void do_vread(message *mp, int vectored)** Function:*/static void do_vread(message * mp, int vectored){ int port, size; dpeth_t *dep; port = mp->DL_PORT; if (port < 0 || port >= DE_PORT_NR) /* Check for illegal port number */ panic(dep->de_name, PortErrMsg, port); dep = &de_table[port]; dep->de_client = mp->DL_PROC; if (dep->de_mode == DEM_ENABLED) { if (dep->de_flags & DEF_READING) /* Reading in progress */ panic(dep->de_name, "read already in progress", NO_NUM); dep->de_read_iovec.iod_proc_nr = mp->DL_PROC; if (vectored) { get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR, mp->DL_COUNT, dep->de_read_iovec.iod_iovec); dep->de_read_iovec.iod_iovec_s = mp->DL_COUNT; dep->de_read_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR; size = calc_iovec_size(&dep->de_read_iovec); } else { dep->de_read_iovec.iod_iovec[0].iov_addr = (vir_bytes) mp->DL_ADDR; dep->de_read_iovec.iod_iovec[0].iov_size = size = mp->DL_COUNT; dep->de_read_iovec.iod_iovec_s = 1; dep->de_read_iovec.iod_iovec_addr = 0; } if (size < ETH_MAX_PACK_SIZE) panic(dep->de_name, SizeErrMsg, size); dep->de_flags |= DEF_READING; (*dep->de_recvf) (dep, FALSE, size);#if 0 if ((dep->de_flags & (DEF_READING | DEF_STOPPED)) == (DEF_READING | DEF_STOPPED)) /* The chip is stopped, and all arrived packets delivered */ (*dep->de_resetf) (dep); dep->de_flags &= NOT(DEF_STOPPED);#endif } reply(dep, OK); return;}/*** Name: void do_getstat(message *mp)** Function: Reports device statistics.*/static void do_getstat(message * mp){ int port, rc; dpeth_t *dep; port = mp->DL_PORT; if (port < 0 || port >= DE_PORT_NR) /* Check for illegal port number */ panic(dep->de_name, PortErrMsg, port); dep = &de_table[port]; dep->de_client = mp->DL_PROC; if (dep->de_mode == DEM_ENABLED) (*dep->de_getstatsf) (dep); if ((rc = sys_datacopy(SELF, (vir_bytes)&dep->de_stat, mp->DL_PROC, (vir_bytes)mp->DL_ADDR, (vir_bytes) sizeof(dep->de_stat))) != OK) panic(DevName, CopyErrMsg, rc); reply(dep, OK); return;}static void do_getname(mp)message *mp;{ int r; strncpy(mp->DL_NAME, progname, sizeof(mp->DL_NAME)); mp->DL_NAME[sizeof(mp->DL_NAME)-1]= '\0'; mp->m_type= DL_NAME_REPLY; r= send(mp->m_source, mp); if (r != OK) panic("dpeth", "do_getname: send failed: %d\n", r);}/*** Name: void do_stop(message *mp)** Function: Stops network interface.*/static void do_stop(message * mp){ int port; dpeth_t *dep; port = mp->DL_PORT; if (port < 0 || port >= DE_PORT_NR) /* Check for illegal port number */ panic(dep->de_name, PortErrMsg, port); dep = &de_table[port]; if (dep->de_mode == DEM_ENABLED && (dep->de_flags & DEF_ENABLED)) { /* Stop device */ (dep->de_stopf) (dep); dep->de_flags = DEF_EMPTY; dep->de_mode = DEM_DISABLED; } return;}static void do_watchdog(void *message){ DEBUG(printf("\t no reply")); return;}/*** Name: int dpeth_task(void)** Function: Main entry for dp task*/PUBLIC int main(int argc, char **argv){ message m; dpeth_t *dep; int rc, fkeys, sfkeys, tasknr; (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]); env_setargs(argc, argv); /* Request function key for debug dumps */ fkeys = sfkeys = 0; bit_set(sfkeys, 8); if ((fkey_map(&fkeys, &sfkeys)) != OK) printf("%s: couldn't program Shift+F8 key (%d)\n", DevName, errno);#ifdef ETH_IGN_PROTO { static u16_t eth_ign_proto = 0; long val; val = 0xFFFF; env_parse("ETH_IGN_PROTO", "x", 0, &val, 0x0000L, 0xFFFFL); eth_ign_proto = htons((u16_t) val); }#endif /* Try to notify inet that we are present (again) */ rc = findproc("inet", &tasknr); if (rc == OK) notify(tasknr); while (TRUE) { if ((rc = receive(ANY, &m)) != OK) panic(dep->de_name, RecvErrMsg, rc); DEBUG(printf("eth: got message %d, ", m.m_type)); switch (m.m_type) { case DEV_PING: /* Status request from RS */ notify(m.m_source); continue; case DL_WRITE: /* Write message to device */ do_vwrite(&m, FALSE); break; case DL_WRITEV: /* Write message to device */ do_vwrite(&m, TRUE); break; case DL_READ: /* Read message from device */ do_vread(&m, FALSE); break; case DL_READV: /* Read message from device */ do_vread(&m, TRUE); break; case DL_INIT: /* Initialize device */ do_init(&m); break; case DL_GETSTAT: /* Get device statistics */ do_getstat(&m); break; case DL_GETNAME: do_getname(&m); break; case SYN_ALARM: /* to be defined */ do_watchdog(&m); break; case DL_STOP: /* Stop device */ do_stop(&m); break; case SYS_SIG: { sigset_t sigset = m.NOTIFY_ARG; if (sigismember(&sigset, SIGKSTOP)) { /* Shut down */ for (rc = 0; rc < DE_PORT_NR; rc += 1) { if (de_table[rc].de_mode == DEM_ENABLED) { m.m_type = DL_STOP; m.DL_PORT = rc; do_stop(&m); } } } break; } case HARD_INT: /* Interrupt from device */ for (dep = de_table; dep < &de_table[DE_PORT_NR]; dep += 1) { /* If device is enabled and interrupt pending */ if (dep->de_mode == DEM_ENABLED) { dep->de_int_pending = TRUE; (*dep->de_interruptf) (dep); if (dep->de_flags & (DEF_ACK_SEND | DEF_ACK_RECV)) reply(dep, !OK); dep->de_int_pending = FALSE; sys_irqenable(&dep->de_hook); } } break; case FKEY_PRESSED: /* Function key pressed */ do_dump(&m); break; default: /* Invalid message type */ panic(DevName, TypeErrMsg, m.m_type); break; } } return OK; /* Never reached, but keeps compiler happy */}/** dp.c **/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -