From: David van Moolenbroek Date: Mon, 17 May 2010 22:22:53 +0000 (+0000) Subject: This patch switches the MINIX3 ethernet driver stack from a port-based X-Git-Tag: v3.1.7~53 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/zlib_tech.html?a=commitdiff_plain;h=9ba65d2ea8afd64c6051d4d41212bab010f97d18;p=minix.git This patch switches the MINIX3 ethernet driver stack from a port-based model to an instance-based model. Each ethernet driver instance is now responsible for exactly one network interface card. The port field in /etc/inet.conf now acts as an instance field instead. This patch also updates the data link protocol. This update: - eliminates the concept of ports entirely; - eliminates DL_GETNAME entirely; - standardizes on using m_source for IPC and DL_ENDPT for safecopies; - removes error codes from TASK/STAT replies, as they were unused; - removes a number of other old or unused fields; - names and renames a few other fields. All ethernet drivers have been changed to: - conform to the new protocol, and exactly that; - take on an instance number based on a given "instance" argument; - skip that number of PCI devices in probe iterations; - use config tables and environment variables based on that number; - no longer be limited to a predefined maximum of cards in any way; - get rid of any leftover non-safecopy support and other ancient junk; - have a correct banner protocol figure, or none at all. Other changes: * Inet.conf is now taken to be line-based, and supports #-comments. No existing installations are expected to be affected by this. * A new, select-based asynchio library replaces the old one. Kindly contributed by Kees J. Bot. * Inet now supports use of select() on IP devices. Combined, the last two changes together speed up dhcpd considerably in the presence of multiple interfaces. * A small bug has been fixed in nonamed. --- diff --git a/commands/dhcpd/devices.c b/commands/dhcpd/devices.c index 3d12a1648..f29d2d314 100644 --- a/commands/dhcpd/devices.c +++ b/commands/dhcpd/devices.c @@ -61,11 +61,7 @@ void give_buf(buf_t **dbp, buf_t **sbp) *sbp= nil; } -#if __minix_vmd -#define N_FDS 16 /* Minix-vmd can go async on many fds. */ -#else -#define N_FDS 1 /* Minix doesn't have async I/O. */ -#endif +#define N_FDS 16 /* Minix can go async on many fds. */ static fd_t fds[N_FDS]; /* List of open descriptors. */ static struct network *fdwaitq; /* Queue of nets waiting for fds. */ diff --git a/commands/dhcpd/dhcpd.c b/commands/dhcpd/dhcpd.c index bd43077ae..8b82fac1a 100644 --- a/commands/dhcpd/dhcpd.c +++ b/commands/dhcpd/dhcpd.c @@ -156,10 +156,6 @@ static int readpool(int fd, pool_t *entry) return 1; } -#if !__minix_vmd /* No fsync() for Minix. */ -#define fsync(fd) sync() -#endif - static void writepool(int fd, pool_t *entry) { /* (Over)write a pool table entry. */ diff --git a/commands/nonamed/nonamed.c b/commands/nonamed/nonamed.c index 797e6c56a..7dd1d95f4 100644 --- a/commands/nonamed/nonamed.c +++ b/commands/nonamed/nonamed.c @@ -1318,7 +1318,8 @@ static void refresh_cache(void) static int job_read_udp(void *data, int expired) /* Read UDP queries and replies. */ { - size_t ulen, dlen; + ssize_t ulen; + size_t dlen; static udp_dns_t udp; u16_t id, port; ipaddr_t ip; diff --git a/docs/UPDATING b/docs/UPDATING index 75de762b2..979920641 100644 --- a/docs/UPDATING +++ b/docs/UPDATING @@ -1,3 +1,8 @@ +20100515: + /usr/src/etc/usr/rc updated: copy it (or merge it) to /usr/etc/rc. + /etc/inet.conf is now line-based; if you have hand-edited this file + before, then make sure that you do not have configurations in there + that span multiple lines. 20100512: yacc and lex updated # make includes diff --git a/drivers/atl2/atl2.c b/drivers/atl2/atl2.c index b462260ca..670949006 100644 --- a/drivers/atl2/atl2.c +++ b/drivers/atl2/atl2.c @@ -91,7 +91,7 @@ PRIVATE struct { { 0x0000, 0x0000 } }; -PRIVATE long instance; +PRIVATE int instance; /*===========================================================================* * atl2_read_vpd * @@ -728,21 +728,19 @@ PRIVATE void atl2_reply(void) /* Send a task reply to Inet. */ message m; - int r, stat; + int r, flags; - stat = 0; + flags = DL_NOFLAGS; if (state.flags & ATL2_FLAG_PACK_SENT) - stat |= DL_PACK_SEND; + flags |= DL_PACK_SEND; if (state.flags & ATL2_FLAG_PACK_RCVD) - stat |= DL_PACK_RECV; + flags |= DL_PACK_RECV; m.m_type = DL_TASK_REPLY; - m.DL_PORT = 0; - m.DL_PROC = state.task_endpt; - m.DL_STAT = stat; + m.DL_FLAGS = flags; m.DL_COUNT = state.recv_count; - ATL2_DEBUG(("ATL2: sending reply stat %x count %d\n", stat, + ATL2_DEBUG(("ATL2: sending reply, flags %x count %d\n", flags, m.DL_COUNT)); if ((r = send(state.task_endpt, &m)) != OK) @@ -765,20 +763,9 @@ PRIVATE void atl2_readv(const message *m, int from_int) u8_t *pos; int i, j, r, batch; - if (m->DL_PORT != 0) { - printf("ATL2: read from invalid port\n"); - - return; - } - /* We can deal with only one read request from Inet at a time. */ assert(from_int || !(state.flags & ATL2_FLAG_READ_PEND)); - /* The exact semantics of DL_PROC are not clear. This driver takes it - * to be only the grant owner; other drivers treat it as the reply - * destination as well. - */ - assert(m->m_source == m->DL_PROC); state.task_endpt = m->m_source; /* Are there any packets available at all? */ @@ -802,7 +789,7 @@ PRIVATE void atl2_readv(const message *m, int from_int) /* Copy in the next batch. */ batch = MIN(m->DL_COUNT - i, NR_IOREQS); - r = sys_safecopyfrom(m->DL_PROC, m->DL_GRANT, off, + r = sys_safecopyfrom(m->DL_ENDPT, m->DL_GRANT, off, (vir_bytes) iovec, batch * sizeof(iovec[0]), D); if (r != OK) panic("vector copy failed: %d", r); @@ -811,7 +798,7 @@ PRIVATE void atl2_readv(const message *m, int from_int) for (j = 0, iovp = iovec; j < batch && left > 0; j++, iovp++) { size = MIN(iovp->iov_size, left); - r = sys_safecopyto(m->DL_PROC, iovp->iov_grant, 0, + r = sys_safecopyto(m->DL_ENDPT, iovp->iov_grant, 0, (vir_bytes) pos, size, D); if (r != OK) panic("safe copy failed: %d", r); @@ -871,16 +858,9 @@ PRIVATE void atl2_writev(const message *m, int from_int) u8_t *sizep; int i, j, r, batch, maxnum; - if (m->DL_PORT != 0) { - printf("ATL2: write to invalid port\n"); - - return; - } - /* We can deal with only one write request from Inet at a time. */ assert(from_int || !(state.flags & ATL2_FLAG_WRITE_PEND)); - assert(m->m_source == m->DL_PROC); state.task_endpt = m->m_source; /* If we are already certain that the packet won't fit, bail out. @@ -906,7 +886,7 @@ PRIVATE void atl2_writev(const message *m, int from_int) /* Copy in the next batch. */ batch = MIN(m->DL_COUNT - i, NR_IOREQS); - r = sys_safecopyfrom(m->DL_PROC, m->DL_GRANT, off, + r = sys_safecopyfrom(m->DL_ENDPT, m->DL_GRANT, off, (vir_bytes) iovec, batch * sizeof(iovec[0]), D); if (r != OK) panic("vector copy failed: %d", r); @@ -920,7 +900,7 @@ PRIVATE void atl2_writev(const message *m, int from_int) skip = 0; if (size > ATL2_TXD_BUFSIZE - pos) { skip = ATL2_TXD_BUFSIZE - pos; - r = sys_safecopyfrom(m->DL_PROC, + r = sys_safecopyfrom(m->DL_ENDPT, iovp->iov_grant, 0, (vir_bytes) (state.txd_base + pos), skip, D); @@ -929,8 +909,8 @@ PRIVATE void atl2_writev(const message *m, int from_int) pos = 0; } - r = sys_safecopyfrom(m->DL_PROC, iovp->iov_grant, skip, - (vir_bytes) (state.txd_base + pos), + r = sys_safecopyfrom(m->DL_ENDPT, iovp->iov_grant, + skip, (vir_bytes) (state.txd_base + pos), size - skip, D); if (r != OK) panic("safe copy failed: %d", r); @@ -1051,27 +1031,21 @@ PRIVATE void atl2_conf(message *m) ether_addr_t *addr; int r; - if (m->DL_PORT != 0) { - m->m3_i1 = ENXIO; - } - else { - state.mode = m->DL_MODE; - - atl2_set_mode(); + state.mode = m->DL_MODE; - addr = (ether_addr_t *) m->m3_ca1; + atl2_set_mode(); - addr->ea_addr[0] = state.hwaddr[1] >> 8; - addr->ea_addr[1] = state.hwaddr[1] & 0xff; - addr->ea_addr[2] = state.hwaddr[0] >> 24; - addr->ea_addr[3] = (state.hwaddr[0] >> 16) & 0xff; - addr->ea_addr[4] = (state.hwaddr[0] >> 8) & 0xff; - addr->ea_addr[5] = state.hwaddr[0] & 0xff; + addr = (ether_addr_t *) m->DL_HWADDR; - m->m3_i1 = OK; - } + addr->ea_addr[0] = state.hwaddr[1] >> 8; + addr->ea_addr[1] = state.hwaddr[1] & 0xff; + addr->ea_addr[2] = state.hwaddr[0] >> 24; + addr->ea_addr[3] = (state.hwaddr[0] >> 16) & 0xff; + addr->ea_addr[4] = (state.hwaddr[0] >> 8) & 0xff; + addr->ea_addr[5] = state.hwaddr[0] & 0xff; m->m_type = DL_CONF_REPLY; + m->DL_STAT = OK; if ((r = send(m->m_source, m)) != OK) printf("ATL2: unable to send reply (%d)\n", r); @@ -1086,38 +1060,10 @@ PRIVATE void atl2_getstat(message *m) */ int r; - if (m->DL_PORT != 0) { - r = ENXIO; - } - else { - r = sys_safecopyto(m->DL_PROC, m->DL_GRANT, 0, - (vir_bytes) &state.stat, sizeof(state.stat), D); - } + sys_safecopyto(m->DL_ENDPT, m->DL_GRANT, 0, + (vir_bytes) &state.stat, sizeof(state.stat), D); m->m_type = DL_STAT_REPLY; - /* keep m->DL_PORT */ - m->DL_STAT = r; - - if ((r = send(m->m_source, m)) != OK) - printf("ATL2: unable to send reply (%d)\n", r); -} - -/*===========================================================================* - * atl2_getname * - *===========================================================================*/ -PRIVATE void atl2_getname(message *m, int instance) -{ - /* Tell Inet the name of this driver. - */ - int r; - - /* Each instance must have a unique name. */ - m->m_type = DL_NAME_REPLY; - if (instance > 0) - snprintf(m->DL_NAME, sizeof(m->DL_NAME), "atl2:%u", - instance - 1); - else - strcpy(m->DL_NAME, "atl2"); if ((r = send(m->m_source, m)) != OK) printf("ATL2: unable to send reply (%d)\n", r); @@ -1212,13 +1158,15 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) /* Initialize the atl2 driver. */ int r, devind; + long v; #if ATL2_FKEY int fkeys, sfkeys; #endif /* How many matching devices should we skip? */ - instance = 0; - env_parse("atl2_instance", "d", 0, &instance, 0, 32); + v = 0; + (void) env_parse("instance", "d", 0, &v, 0, 255); + instance = (int) v; /* Try to find a recognized device. */ devind = atl2_probe(instance); @@ -1335,7 +1283,6 @@ int main(int argc, char **argv) /* Process requests from Inet. */ switch (m.m_type) { - case DL_GETNAME: atl2_getname(&m, instance); break; case DL_CONF: atl2_conf(&m); break; case DL_GETSTAT_S: atl2_getstat(&m); break; case DL_WRITEV_S: atl2_writev(&m, FALSE); break; diff --git a/drivers/dec21140A/dec21140A.c b/drivers/dec21140A/dec21140A.c index 8943003a6..d16aa8b48 100644 --- a/drivers/dec21140A/dec21140A.c +++ b/drivers/dec21140A/dec21140A.c @@ -29,10 +29,9 @@ _PROTOTYPE( PRIVATE u32_t io_inl, (u16_t); ); _PROTOTYPE( PRIVATE void io_outl, (u16_t, u32_t); ); _PROTOTYPE( PRIVATE void do_conf, (const message *); ); -_PROTOTYPE( PRIVATE void do_get_name, (message *); ); _PROTOTYPE( PRIVATE void do_get_stat_s, (message *); ); _PROTOTYPE( PRIVATE void do_interrupt, (const dpeth_t *); ); -_PROTOTYPE( PRIVATE void do_reply, (dpeth_t *, int, int); ); +_PROTOTYPE( PRIVATE void do_reply, (dpeth_t *); ); _PROTOTYPE( PRIVATE void do_vread_s, (const message *, int); ); _PROTOTYPE( PRIVATE void do_watchdog, (void *); ); @@ -53,7 +52,6 @@ _PROTOTYPE( PRIVATE void de_get_userdata_s, (int, cp_grant_id_t, /* Error messages */ static char str_CopyErrMsg[] = "unable to read/write user data"; -static char str_PortErrMsg[] = "illegal port"; static char str_SendErrMsg[] = "send failed"; static char str_SizeErrMsg[] = "illegal packet size"; static char str_UmapErrMsg[] = "Unable to sys_umap"; @@ -62,8 +60,8 @@ static char str_StatErrMsg[] = "Unable to send stats"; static char str_AlignErrMsg[] = "Bad align of buffer/descriptor"; static char str_DevName[] = "dec21140A:eth#?"; -PRIVATE dpeth_t de_table[DE_PORT_NR]; -PRIVATE const char *progname; +PRIVATE dpeth_t de_state; +PRIVATE int de_instance; /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); @@ -96,13 +94,12 @@ int main(int argc, char *argv[]) break; case HARDWARE: - for (dep = de_table; dep < &de_table[DE_PORT_NR]; dep += 1) { - if (dep->de_mode == DEM_ENABLED) { - do_interrupt(dep); - if (dep->de_flags & (DEF_ACK_SEND | DEF_ACK_RECV)) - do_reply(dep, OK, TRUE); - sys_irqenable(&dep->de_hook); - } + dep = &de_state; + if (dep->de_mode == DEM_ENABLED) { + do_interrupt(dep); + if (dep->de_flags & (DEF_ACK_SEND | DEF_ACK_RECV)) + do_reply(dep); + sys_irqenable(&dep->de_hook); } break; default: @@ -118,8 +115,6 @@ int main(int argc, char *argv[]) case DL_READV_S: do_vread_s(&m, FALSE); break; case DL_CONF: do_conf(&m); break; case DL_GETSTAT_S: do_get_stat_s(&m); break; - case DL_GETNAME: do_get_name(&m); break; - case DL_STOP: /* nothing */ break; default: printf("message 0x%lx; %d from %d\n", @@ -157,8 +152,11 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) { /* Initialize the DEC 21140A driver. */ int fkeys, sfkeys; + long v; - (progname=strrchr(env_argv[0],'/')) ? progname++ : (progname=env_argv[0]); + v = 0; + (void) env_parse("instance", "d", 0, &v, 0, 255); + de_instance = (int) v; /* Request function key for debug dumps */ fkeys = sfkeys = 0; @@ -174,24 +172,17 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) PRIVATE void do_get_stat_s(message * mp) { - int port, rc; + int rc; dpeth_t *dep; - port = mp->DL_PORT; - if (port < 0 || port >= DE_PORT_NR) - panic(str_PortErrMsg, port); - - dep = &de_table[port]; - dep->de_client = mp->DL_PROC; + dep = &de_state; - if ((rc = sys_safecopyto(mp->DL_PROC, mp->DL_GRANT, 0UL, + if ((rc = sys_safecopyto(mp->DL_ENDPT, mp->DL_GRANT, 0UL, (vir_bytes)&dep->de_stat, sizeof(dep->de_stat), 0)) != OK) panic(str_CopyErrMsg, rc); mp->m_type = DL_STAT_REPLY; - mp->DL_PORT = port; - mp->DL_STAT = OK; rc = send(mp->m_source, mp); if( rc != OK ) panic(str_StatErrMsg, rc); @@ -200,70 +191,65 @@ PRIVATE void do_get_stat_s(message * mp) PRIVATE void do_conf(const message * mp) { - int port = mp->DL_PORT; + int r; dpeth_t *dep; message reply_mess; - if (port >= 0 && port < DE_PORT_NR) { + dep = &de_state; - dep = &de_table[port]; - strncpy(dep->de_name, str_DevName, strlen(str_DevName)); - dep->de_name[strlen(dep->de_name)-1] = '0' + port; + strncpy(dep->de_name, str_DevName, strlen(str_DevName)); + dep->de_name[strlen(dep->de_name)-1] = '0' + de_instance; - if (dep->de_mode == DEM_DISABLED) { - de_update_conf(dep); - pci_init(); - if (dep->de_mode == DEM_ENABLED && !de_probe(dep, port)) { + if (dep->de_mode == DEM_DISABLED) { + de_update_conf(dep); + pci_init(); + if (dep->de_mode == DEM_ENABLED && !de_probe(dep, de_instance)) { printf("%s: warning no ethernet card found at 0x%04X\n", dep->de_name, dep->de_base_port); dep->de_mode = DEM_DISABLED; - } } + } - /* 'de_mode' may change if probe routines fail, test again */ - switch (dep->de_mode) { + r = OK; - case DEM_DISABLED: - port = ENXIO; /* Device is OFF or hardware probe failed */ - break; + /* 'de_mode' may change if probe routines fail, test again */ + switch (dep->de_mode) { - case DEM_ENABLED: - if (dep->de_flags == DEF_EMPTY) { + case DEM_DISABLED: + r = ENXIO; /* Device is OFF or hardware probe failed */ + break; + + case DEM_ENABLED: + if (dep->de_flags == DEF_EMPTY) { de_first_init(dep); dep->de_flags |= DEF_ENABLED; de_reset(dep); de_hw_conf(dep); de_setup_frame(dep); de_start(dep); - } + } - /* TODO CHECK PROMISC AND MULTI */ - dep->de_flags &= NOT(DEF_PROMISC | DEF_MULTI | DEF_BROAD); - if (mp->DL_MODE & DL_PROMISC_REQ) + /* TODO CHECK PROMISC AND MULTI */ + dep->de_flags &= NOT(DEF_PROMISC | DEF_MULTI | DEF_BROAD); + if (mp->DL_MODE & DL_PROMISC_REQ) dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD; - if (mp->DL_MODE & DL_MULTI_REQ) dep->de_flags |= DEF_MULTI; - if (mp->DL_MODE & DL_BROAD_REQ) dep->de_flags |= DEF_BROAD; - dep->de_client = mp->m_source; - break; - - case DEM_SINK: - DEBUG(printf("%s running in sink mode\n", str_DevName)); - memset(dep->de_address.ea_addr, 0, sizeof(ether_addr_t)); - de_conf_addr(dep); - break; - - default: break; - } - } else { /* Port number is out of range */ - port = ENXIO; - dep = NULL; + if (mp->DL_MODE & DL_MULTI_REQ) dep->de_flags |= DEF_MULTI; + if (mp->DL_MODE & DL_BROAD_REQ) dep->de_flags |= DEF_BROAD; + break; + + case DEM_SINK: + DEBUG(printf("%s running in sink mode\n", str_DevName)); + memset(dep->de_address.ea_addr, 0, sizeof(ether_addr_t)); + de_conf_addr(dep); + break; + + default: break; } reply_mess.m_type = DL_CONF_REPLY; - reply_mess.m3_i1 = port; - reply_mess.m3_i2 = DE_PORT_NR; - if(dep != NULL){ - *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address; + reply_mess.DL_STAT = r; + if(r == OK){ + *(ether_addr_t *) reply_mess.DL_HWADDR = dep->de_address; } if (send(mp->m_source, &reply_mess) != OK) @@ -272,42 +258,22 @@ PRIVATE void do_conf(const message * mp) return; } - -PRIVATE void do_get_name(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("do_getname: send failed: %d", r); -} - -PRIVATE void do_reply(dpeth_t * dep, int err, int may_block) +PRIVATE void do_reply(dpeth_t * dep) { message reply; - int status = 0; + int r, flags = DL_NOFLAGS; - if (dep->de_flags & DEF_ACK_SEND) status |= DL_PACK_SEND; - if (dep->de_flags & DEF_ACK_RECV) status |= DL_PACK_RECV; + if (dep->de_flags & DEF_ACK_SEND) flags |= DL_PACK_SEND; + if (dep->de_flags & DEF_ACK_RECV) flags |= 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_STAT = flags; reply.DL_COUNT = dep->de_read_s; - reply.DL_CLCK = 0; - status = send(dep->de_client, &reply); + r = send(dep->de_client, &reply); - if(status == ELOCKED && may_block){ - /*printf("Warning: Dec21041 send lock prevented\n\n");*/ - return; - } - - if(status < 0) - panic(str_SendErrMsg, status); + if(r < 0) + panic(str_SendErrMsg, r); dep->de_read_s = 0; dep->de_flags &= NOT(DEF_ACK_SEND | DEF_ACK_RECV); @@ -447,10 +413,14 @@ PRIVATE u16_t de_read_rom(const dpeth_t *dep, u8_t addr, u8_t nbAddrBits){ static void de_update_conf(dpeth_t * dep) { static char dpc_fmt[] = "x:d:x"; + char ec_key[16]; long val; + strcpy(ec_key, "DEETH0"); + ec_key[5] += de_instance; + dep->de_mode = DEM_ENABLED; - switch (env_parse("DEETH0", dpc_fmt, 0, &val, 0x000L, 0x3FFL)) { + switch (env_parse(ec_key, dpc_fmt, 0, &val, 0x000L, 0x3FFL)) { case EP_OFF: dep->de_mode = DEM_DISABLED; break; case EP_ON: dep->de_mode = DEM_SINK; break; } @@ -469,11 +439,9 @@ PRIVATE void do_vread_s(const message * mp, int from_int) de_loc_descr_t *descr = NULL; iovec_dat_s_t *iovp = NULL; - if (mp->DL_PORT < 0 || mp->DL_PORT >= DE_PORT_NR) - panic(str_PortErrMsg, mp->DL_PORT); + dep = &de_state; - dep = &de_table[mp->DL_PORT]; - dep->de_client = mp->DL_PROC; + dep->de_client = mp->m_source; if (dep->de_mode == DEM_ENABLED) { @@ -507,8 +475,8 @@ PRIVATE void do_vread_s(const message * mp, int from_int) /* Setup the iovec entry to allow copying into client layer */ - dep->de_read_iovec.iod_proc_nr = mp->DL_PROC; - de_get_userdata_s(mp->DL_PROC, (cp_grant_id_t) mp->DL_GRANT, 0, + dep->de_read_iovec.iod_proc_nr = mp->DL_ENDPT; + de_get_userdata_s(mp->DL_ENDPT, (cp_grant_id_t) mp->DL_GRANT, 0, mp->DL_COUNT, dep->de_read_iovec.iod_iovec); dep->de_read_iovec.iod_iovec_s = mp->DL_COUNT; dep->de_read_iovec.iod_grant = (cp_grant_id_t) mp->DL_GRANT; @@ -575,7 +543,7 @@ PRIVATE void do_vread_s(const message * mp, int from_int) } if(!from_int){ - do_reply(dep, OK, FALSE); + do_reply(dep); } return; @@ -588,7 +556,7 @@ PRIVATE void do_vread_s(const message * mp, int from_int) assert(!(dep->de_flags & DEF_READING)); dep->rx_return_msg = *mp; dep->de_flags |= DEF_READING; - do_reply(dep, OK, FALSE); + do_reply(dep); return; } @@ -599,9 +567,8 @@ PRIVATE void de_conf_addr(dpeth_t * dep) int ix; long val; - /* TODO: should be configurable... */ - strcpy(ea_key, "DEETH0"); - strcat(ea_key, "_EA"); + strcpy(ea_key, "DEETH0_EA"); + ea_key[5] += de_instance; for (ix = 0; ix < SA_ADDR_LEN; ix++) { val = dep->de_address.ea_addr[ix]; @@ -840,11 +807,9 @@ PRIVATE void do_vwrite_s(const message * mp, int from_int){ de_loc_descr_t *descr = NULL; char *buffer = NULL; - if( mp->DL_PORT < 0 || mp->DL_PORT >= DE_PORT_NR) - panic(str_PortErrMsg, mp->DL_PORT); + dep = &de_state; - dep = &de_table[mp->DL_PORT]; - dep->de_client = mp->DL_PROC; + dep->de_client = mp->m_source; if (dep->de_mode == DEM_ENABLED) { @@ -863,8 +828,8 @@ PRIVATE void do_vwrite_s(const message * mp, int from_int){ buffer = descr->buf1; iovp = &dep->de_write_iovec; - iovp->iod_proc_nr = mp->DL_PROC; - de_get_userdata_s(mp->DL_PROC, mp->DL_GRANT, 0, + iovp->iod_proc_nr = mp->DL_ENDPT; + de_get_userdata_s(mp->DL_ENDPT, mp->DL_GRANT, 0, mp->DL_COUNT, iovp->iod_iovec); iovp->iod_iovec_s = mp->DL_COUNT; iovp->iod_grant = (cp_grant_id_t) mp->DL_GRANT; @@ -910,7 +875,7 @@ PRIVATE void do_vwrite_s(const message * mp, int from_int){ dep->de_flags &= NOT(DEF_SENDING); return; } - do_reply(dep, OK, FALSE); + do_reply(dep); return; suspend: @@ -921,7 +886,7 @@ PRIVATE void do_vwrite_s(const message * mp, int from_int){ dep->de_flags |= DEF_SENDING; dep->de_stat.ets_transDef++; dep->tx_return_msg = *mp; - do_reply(dep, OK, FALSE); + do_reply(dep); } PRIVATE void warning(const char *type, int err){ diff --git a/drivers/dec21140A/dec21140A.h b/drivers/dec21140A/dec21140A.h index 0a2202eea..cf7ff895f 100644 --- a/drivers/dec21140A/dec21140A.h +++ b/drivers/dec21140A/dec21140A.h @@ -10,8 +10,6 @@ Created: 09/01/2009 Nicolas Tittley (first.last @ gmail DOT com) */ -#define DE_PORT_NR 1 - #define DE_FKEY 8 /* Shitf+ this value will dump info on console */ #undef NULL diff --git a/drivers/dp8390/dp8390.c b/drivers/dp8390/dp8390.c index 2700b348c..78803c5d8 100644 --- a/drivers/dp8390/dp8390.c +++ b/drivers/dp8390/dp8390.c @@ -4,45 +4,6 @@ * This file contains a ethernet device driver for NS dp8390 based ethernet * cards. * - * The valid messages and their parameters are: - * - * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR DL_GRANT - * |------------+----------+---------+----------+---------+---------+---------| - * | HARDINT | | | | | | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_WRITE | port nr | proc nr | count | mode | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_WRITEV | port nr | proc nr | count | mode | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_WRITEV_S| port nr | proc nr | count | mode | | grant | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_READ | port nr | proc nr | count | | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_READV | port nr | proc nr | count | | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_READV_S | port nr | proc nr | count | | | grant | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_CONF | port nr | proc nr | | mode | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_GETSTAT | port nr | proc nr | | | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * |DL_GETSTAT_S| port nr | proc nr | | | | grant | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_STOP | port_nr | | | | | | - * |------------|----------|---------|----------|---------|---------|---------| - * - * The messages sent are: - * - * m-type DL_PORT DL_PROC DL_COUNT DL_STAT DL_CLCK - * |-------------+----------+---------+----------+---------+---------| - * |DL_TASK_REPLY| port nr | proc nr | rd-count | err|stat| clock | - * |-------------+----------+---------+----------+---------+---------| - * - * m_type m3_i1 m3_i2 m3_ca1 - * |-------------+---------+-----------+---------------| - * |DL_CONF_REPLY| port nr | last port | ethernet addr | - * |-------------+---------+-----------+---------------| - * * Created: before Dec 28, 1992 by Philip Homburg * * Modified Mar 10 1994 by Philip Homburg @@ -68,11 +29,8 @@ #include "local.h" #include "dp8390.h" -#define DE_PORT_NR 3 - -static dpeth_t de_table[DE_PORT_NR]; -static u16_t eth_ign_proto; -static const char *progname; +static dpeth_t de_state; +static int de_instance; u32_t system_hz; @@ -82,22 +40,18 @@ typedef struct dp_conf port_t dpc_port; int dpc_irq; phys_bytes dpc_mem; - char *dpc_envvar; } dp_conf_t; -PRIVATE dp_conf_t dp_conf[]= /* Card addresses */ +#define DP_CONF_NR 4 +PRIVATE dp_conf_t dp_conf[DP_CONF_NR]= /* Card addresses */ { - /* I/O port, IRQ, Buffer address, Env. var. */ - { 0x280, 3, 0xD0000, "DPETH0" }, - { 0x300, 5, 0xC8000, "DPETH1" }, - { 0x380, 10, 0xD8000, "DPETH2" }, + /* I/O port, IRQ, Buffer address. */ + { 0x280, 3, 0xD0000, }, + { 0x300, 5, 0xC8000, }, + { 0x380, 10, 0xD8000, }, + { 0x000, 0, 0x00000, }, }; -/* Test if dp_conf has exactly DE_PORT_NR entries. If not then you will see - * the error: "array size is negative". - */ -extern int ___dummy[DE_PORT_NR == sizeof(dp_conf)/sizeof(dp_conf[0]) ? 1 : -1]; - /* Card inits configured out? */ #if !ENABLE_WDETH #define wdeth_probe(dep) (0) @@ -118,17 +72,12 @@ extern int ___dummy[DE_PORT_NR == sizeof(dp_conf)/sizeof(dp_conf[0]) ? 1 : -1]; #if ENABLE_PCI _PROTOTYPE( static void pci_conf, (void) ); #endif -_PROTOTYPE( static void do_vwrite, (message *mp, int from_int, - int vectored) ); _PROTOTYPE( static void do_vwrite_s, (message *mp, int from_int) ); -_PROTOTYPE( static void do_vread, (message *mp, int vectored) ); _PROTOTYPE( static void do_vread_s, (message *mp) ); _PROTOTYPE( static void do_init, (message *mp) ); _PROTOTYPE( static void do_int, (dpeth_t *dep) ); -_PROTOTYPE( static void do_getstat, (message *mp) ); _PROTOTYPE( static void do_getstat_s, (message *mp) ); -_PROTOTYPE( static void do_getname, (message *mp) ); -_PROTOTYPE( static void do_stop, (message *mp) ); +_PROTOTYPE( static void dp_stop, (dpeth_t *dep) ); _PROTOTYPE( static void dp_init, (dpeth_t *dep) ); _PROTOTYPE( static void dp_confaddr, (dpeth_t *dep) ); _PROTOTYPE( static void dp_reinit, (dpeth_t *dep) ); @@ -142,54 +91,32 @@ _PROTOTYPE( static void dp_pio8_getblock, (dpeth_t *dep, int page, size_t offset, size_t size, void *dst) ); _PROTOTYPE( static void dp_pio16_getblock, (dpeth_t *dep, int page, size_t offset, size_t size, void *dst) ); -_PROTOTYPE( static int dp_pkt2user, (dpeth_t *dep, int page, - vir_bytes length) ); _PROTOTYPE( static int dp_pkt2user_s, (dpeth_t *dep, int page, vir_bytes length) ); -_PROTOTYPE( static void dp_user2nic, (dpeth_t *dep, iovec_dat_t *iovp, - vir_bytes offset, int nic_addr, vir_bytes count) ); _PROTOTYPE( static void dp_user2nic_s, (dpeth_t *dep, iovec_dat_s_t *iovp, vir_bytes offset, int nic_addr, vir_bytes count) ); -_PROTOTYPE( static void dp_pio8_user2nic, (dpeth_t *dep, - iovec_dat_t *iovp, vir_bytes offset, - int nic_addr, vir_bytes count) ); _PROTOTYPE( static void dp_pio8_user2nic_s, (dpeth_t *dep, iovec_dat_s_t *iovp, vir_bytes offset, int nic_addr, vir_bytes count) ); -_PROTOTYPE( static void dp_pio16_user2nic, (dpeth_t *dep, - iovec_dat_t *iovp, vir_bytes offset, - int nic_addr, vir_bytes count) ); _PROTOTYPE( static void dp_pio16_user2nic_s, (dpeth_t *dep, iovec_dat_s_t *iovp, vir_bytes offset, int nic_addr, vir_bytes count) ); -_PROTOTYPE( static void dp_nic2user, (dpeth_t *dep, int nic_addr, - iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) ); _PROTOTYPE( static void dp_nic2user_s, (dpeth_t *dep, int nic_addr, iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) ); -_PROTOTYPE( static void dp_pio8_nic2user, (dpeth_t *dep, int nic_addr, - iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) ); _PROTOTYPE( static void dp_pio8_nic2user_s, (dpeth_t *dep, int nic_addr, iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) ); -_PROTOTYPE( static void dp_pio16_nic2user, (dpeth_t *dep, int nic_addr, - iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) ); _PROTOTYPE( static void dp_pio16_nic2user_s, (dpeth_t *dep, int nic_addr, iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) ); -_PROTOTYPE( static void dp_next_iovec, (iovec_dat_t *iovp) ); _PROTOTYPE( static void dp_next_iovec_s, (iovec_dat_s_t *iovp) ); _PROTOTYPE( static void conf_hw, (dpeth_t *dep) ); _PROTOTYPE( static void update_conf, (dpeth_t *dep, dp_conf_t *dcp) ); _PROTOTYPE( static void map_hw_buffer, (dpeth_t *dep) ); -_PROTOTYPE( static int calc_iovec_size, (iovec_dat_t *iovp) ); _PROTOTYPE( static int calc_iovec_size_s, (iovec_dat_s_t *iovp) ); -_PROTOTYPE( static void reply, (dpeth_t *dep, int err, int may_block) ); +_PROTOTYPE( static void reply, (dpeth_t *dep) ); _PROTOTYPE( static void mess_reply, (message *req, message *reply) ); -_PROTOTYPE( static void get_userdata, (int user_proc, - vir_bytes user_addr, vir_bytes count, void *loc_addr) ); _PROTOTYPE( static void get_userdata_s, (int user_proc, cp_grant_id_t grant, vir_bytes offset, vir_bytes count, void *loc_addr) ); -_PROTOTYPE( static void put_userdata, (int user_proc, - vir_bytes user_addr, vir_bytes count, void *loc_addr) ); _PROTOTYPE( static void put_userdata_s, (int user_proc, cp_grant_id_t grant, size_t count, void *loc_addr) ); _PROTOTYPE( static void insb, (port_t port, void *buf, size_t size) ); @@ -210,31 +137,28 @@ FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) ); EXTERN int env_argc; EXTERN char **env_argv; -PRIVATE int handle_hw_intr(void) +PRIVATE void handle_hw_intr(void) { - int i, r, irq; + int r, irq; dpeth_t *dep; - for (i= 0, dep= &de_table[0]; ide_mode != DEM_ENABLED) - continue; - assert(dep->de_flags & DEF_ENABLED); - irq= dep->de_irq; - assert(irq >= 0 && irq < NR_IRQ_VECTORS); - if (dep->de_int_pending || 1) - { - dep->de_int_pending= 0; - dp_check_ints(dep); - do_int(dep); - r= sys_irqenable(&dep->de_hook); - if (r != OK) { - panic("unable enable interrupts: %d", r); - } + dep = &de_state; + + if (dep->de_mode != DEM_ENABLED) + return; + assert(dep->de_flags & DEF_ENABLED); + irq= dep->de_irq; + assert(irq >= 0 && irq < NR_IRQ_VECTORS); + if (dep->de_int_pending || 1) + { + dep->de_int_pending= 0; + dp_check_ints(dep); + do_int(dep); + r= sys_irqenable(&dep->de_hook); + if (r != OK) { + panic("unable enable interrupts: %d", r); } } - - return r; } /*===========================================================================* @@ -258,7 +182,7 @@ int main(int argc, char *argv[]) if (is_ipc_notify(ipc_status)) { switch (_ENDPOINT_P(m.m_source)) { case HARDWARE: - r = handle_hw_intr(); + handle_hw_intr(); break; case CLOCK: printf("dp8390: notify from CLOCK\n"); @@ -274,17 +198,10 @@ int main(int argc, char *argv[]) switch (m.m_type) { - case DL_WRITE: do_vwrite(&m, FALSE, FALSE); break; - case DL_WRITEV: do_vwrite(&m, FALSE, TRUE); break; case DL_WRITEV_S: do_vwrite_s(&m, FALSE); break; - case DL_READ: do_vread(&m, FALSE); break; - case DL_READV: do_vread(&m, TRUE); break; case DL_READV_S: do_vread_s(&m); break; case DL_CONF: do_init(&m); break; - case DL_GETSTAT: do_getstat(&m); break; case DL_GETSTAT_S: do_getstat_s(&m); break; - case DL_GETNAME: do_getname(&m); break; - case DL_STOP: do_stop(&m); break; default: panic("dp8390: illegal message: %d", m.m_type); } @@ -318,7 +235,6 @@ PRIVATE void sef_local_startup() PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) { /* Initialize the dp8390 driver. */ - int i; dpeth_t *dep; long v; @@ -327,18 +243,15 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) if (env_argc < 1) { panic("A head which at this time has no name"); } - (progname=strrchr(env_argv[0],'/')) ? progname++ - : (progname=env_argv[0]); - for (i= 0, dep= de_table; ide_name, "dp8390#0"); - dep->de_name[7] += i; - } + v = 0; + (void) env_parse("instance", "d", 0, &v, 0, 255); + de_instance = (int) v; - v= 0; - (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL); - eth_ign_proto= htons((u16_t) v); + dep = &de_state; + + strcpy(dep->de_name, "dp8390#0"); + dep->de_name[7] += de_instance; /* Announce we are up! */ netdriver_announce(); @@ -351,20 +264,11 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) *===========================================================================*/ PRIVATE void sef_cb_signal_handler(int signo) { - message mess; - int i; - /* Only check for termination signal, ignore anything else. */ if (signo != SIGTERM) return; - for (i= 0; ide_mode == DEM_DISABLED) - printf("dp8390 port %d is disabled\n", i); - else if (dep->de_mode == DEM_SINK) - printf("dp8390 port %d is in sink mode\n", i); + if (dep->de_mode == DEM_DISABLED) + printf("dp8390 instance %d is disabled\n", de_instance); + else if (dep->de_mode == DEM_SINK) + printf("dp8390 instance %d is in sink mode\n", de_instance); #endif - if (dep->de_mode != DEM_ENABLED) - continue; + if (dep->de_mode != DEM_ENABLED) + return; - printf("dp8390 statistics of port %d:\n", i); + printf("dp8390 statistics of instance %d:\n", de_instance); - printf("recvErr :%8ld\t", dep->de_stat.ets_recvErr); - printf("sendErr :%8ld\t", dep->de_stat.ets_sendErr); - printf("OVW :%8ld\n", dep->de_stat.ets_OVW); + printf("recvErr :%8ld\t", dep->de_stat.ets_recvErr); + printf("sendErr :%8ld\t", dep->de_stat.ets_sendErr); + printf("OVW :%8ld\n", dep->de_stat.ets_OVW); - printf("CRCerr :%8ld\t", dep->de_stat.ets_CRCerr); - printf("frameAll :%8ld\t", dep->de_stat.ets_frameAll); - printf("missedP :%8ld\n", dep->de_stat.ets_missedP); + printf("CRCerr :%8ld\t", dep->de_stat.ets_CRCerr); + printf("frameAll :%8ld\t", dep->de_stat.ets_frameAll); + printf("missedP :%8ld\n", dep->de_stat.ets_missedP); - printf("packetR :%8ld\t", dep->de_stat.ets_packetR); - printf("packetT :%8ld\t", dep->de_stat.ets_packetT); - printf("transDef :%8ld\n", dep->de_stat.ets_transDef); + printf("packetR :%8ld\t", dep->de_stat.ets_packetR); + printf("packetT :%8ld\t", dep->de_stat.ets_packetT); + printf("transDef :%8ld\n", dep->de_stat.ets_transDef); - printf("collision :%8ld\t", dep->de_stat.ets_collision); - printf("transAb :%8ld\t", dep->de_stat.ets_transAb); - printf("carrSense :%8ld\n", dep->de_stat.ets_carrSense); + printf("collision :%8ld\t", dep->de_stat.ets_collision); + printf("transAb :%8ld\t", dep->de_stat.ets_transAb); + printf("carrSense :%8ld\n", dep->de_stat.ets_carrSense); - printf("fifoUnder :%8ld\t", dep->de_stat.ets_fifoUnder); - printf("fifoOver :%8ld\t", dep->de_stat.ets_fifoOver); - printf("CDheartbeat:%8ld\n", dep->de_stat.ets_CDheartbeat); + printf("fifoUnder :%8ld\t", dep->de_stat.ets_fifoUnder); + printf("fifoOver :%8ld\t", dep->de_stat.ets_fifoOver); + printf("CDheartbeat:%8ld\n", dep->de_stat.ets_CDheartbeat); - printf("OWC :%8ld\t", dep->de_stat.ets_OWC); + printf("OWC :%8ld\t", dep->de_stat.ets_OWC); - isr= inb_reg0(dep, DP_ISR); - printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr, - inb_reg0(dep, DP_ISR), dep->de_flags); - } + isr= inb_reg0(dep, DP_ISR); + printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr, + inb_reg0(dep, DP_ISR), dep->de_flags); } #endif @@ -426,8 +329,8 @@ void dp8390_dump() *===========================================================================*/ static void pci_conf() { - int i, h; - char *envvar; + int confnr; + char envvar[16]; struct dpeth *dep; static char envfmt[] = "*:d.d.d"; long v; @@ -437,143 +340,35 @@ static void pci_conf() return; first_time= 0; - for (i= 0, dep= de_table; ide_pci= env_prefix(envvar, "pci"))) - continue; /* no PCI config */ - v= 0; - (void) env_parse(envvar, envfmt, 1, &v, 0, 255); - dep->de_pcibus= v; - v= 0; - (void) env_parse(envvar, envfmt, 2, &v, 0, 255); - dep->de_pcidev= v; - v= 0; - (void) env_parse(envvar, envfmt, 3, &v, 0, 255); - dep->de_pcifunc= v; - } - - for (h= 1; h >= 0; h--) { - for (i= 0, dep= de_table; ide_pci) - { - printf("pci: no pci for port %d\n", i); - continue; - } - if (((dep->de_pcibus | dep->de_pcidev | - dep->de_pcifunc) != 0) != h) - { - continue; - } - if (!rtl_probe(dep, i)) - dep->de_pci= -1; - } - } -} -#endif /* ENABLE_PCI */ - -/*===========================================================================* - * do_vwrite * - *===========================================================================*/ -static void do_vwrite(mp, from_int, vectored) -message *mp; -int from_int; -int vectored; -{ - int port, count, size; - int sendq_head; - dpeth_t *dep; + dep= &de_state; - port = mp->DL_PORT; - count = mp->DL_COUNT; - if (port < 0 || port >= DE_PORT_NR) - panic("dp8390: illegal port: %d", port); - dep= &de_table[port]; - dep->de_client= mp->DL_PROC; + /* Pick a default configuration for this instance. */ + confnr= MIN(de_instance, DP_CONF_NR-1); - if (dep->de_mode == DEM_SINK) - { - assert(!from_int); - dep->de_flags |= DEF_PACK_SEND; - reply(dep, OK, FALSE); - return; - } - assert(dep->de_mode == DEM_ENABLED); - assert(dep->de_flags & DEF_ENABLED); - if (dep->de_flags & DEF_SEND_AVAIL) - panic("dp8390: send already in progress"); + strcpy(envvar, "DPETH0"); + envvar[5] += de_instance; + if (!(dep->de_pci= env_prefix(envvar, "pci"))) + return; /* no PCI config */ + v= 0; + (void) env_parse(envvar, envfmt, 1, &v, 0, 255); + dep->de_pcibus= v; + v= 0; + (void) env_parse(envvar, envfmt, 2, &v, 0, 255); + dep->de_pcidev= v; + v= 0; + (void) env_parse(envvar, envfmt, 3, &v, 0, 255); + dep->de_pcifunc= v; - sendq_head= dep->de_sendq_head; - if (dep->de_sendq[sendq_head].sq_filled) - { - if (from_int) - panic("dp8390: should not be sending"); - dep->de_sendmsg= *mp; - dep->de_flags |= DEF_SEND_AVAIL; - reply(dep, OK, FALSE); + if (!dep->de_pci) { + printf("%s: no pci for instance %d\n", dep->de_name, + de_instance); return; } - assert(!(dep->de_flags & DEF_PACK_SEND)); - - if (vectored) - { - get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR, - (count > IOVEC_NR ? IOVEC_NR : count) * - sizeof(iovec_t), dep->de_write_iovec.iod_iovec); - dep->de_write_iovec.iod_iovec_s = count; - dep->de_write_iovec.iod_proc_nr = mp->DL_PROC; - dep->de_write_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR; - - dep->de_tmp_iovec = dep->de_write_iovec; - size = calc_iovec_size(&dep->de_tmp_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 = - mp->DL_COUNT; - dep->de_write_iovec.iod_iovec_s = 1; - dep->de_write_iovec.iod_proc_nr = mp->DL_PROC; - dep->de_write_iovec.iod_iovec_addr = 0; - size= mp->DL_COUNT; - } - if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED) - { - panic("dp8390: invalid packet size: %d", size); - } - (dep->de_user2nicf)(dep, &dep->de_write_iovec, 0, - dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE, - size); - dep->de_sendq[sendq_head].sq_filled= TRUE; - if (dep->de_sendq_tail == sendq_head) - { - outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage); - outb_reg0(dep, DP_TBCR1, size >> 8); - outb_reg0(dep, DP_TBCR0, size & 0xff); - outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);/* there it goes.. */ - } - else - dep->de_sendq[sendq_head].sq_size= size; - - if (++sendq_head == dep->de_sendq_nr) - sendq_head= 0; - assert(sendq_head < SENDQ_NR); - dep->de_sendq_head= sendq_head; - - dep->de_flags |= DEF_PACK_SEND; - - /* If the interrupt handler called, don't send a reply. The reply - * will be sent after all interrupts are handled. - */ - if (from_int) - return; - reply(dep, OK, FALSE); - assert(dep->de_mode == DEM_ENABLED); - assert(dep->de_flags & DEF_ENABLED); + if (!rtl_probe(dep, de_instance)) + dep->de_pci= -1; } +#endif /* ENABLE_PCI */ /*===========================================================================* * do_vwrite_s * @@ -582,22 +377,20 @@ static void do_vwrite_s(mp, from_int) message *mp; int from_int; { - int port, count, size; + int count, size; int sendq_head; dpeth_t *dep; - port = mp->DL_PORT; + dep= &de_state; + count = mp->DL_COUNT; - if (port < 0 || port >= DE_PORT_NR) - panic("dp8390: illegal port: %d", port); - dep= &de_table[port]; - dep->de_client= mp->DL_PROC; + dep->de_client= mp->m_source; if (dep->de_mode == DEM_SINK) { assert(!from_int); dep->de_flags |= DEF_PACK_SEND; - reply(dep, OK, FALSE); + reply(dep); return; } assert(dep->de_mode == DEM_ENABLED); @@ -612,17 +405,17 @@ int from_int; panic("dp8390: should not be sending"); dep->de_sendmsg= *mp; dep->de_flags |= DEF_SEND_AVAIL; - reply(dep, OK, FALSE); + reply(dep); return; } assert(!(dep->de_flags & DEF_PACK_SEND)); - get_userdata_s(mp->DL_PROC, mp->DL_GRANT, 0, + get_userdata_s(mp->DL_ENDPT, mp->DL_GRANT, 0, (count > IOVEC_NR ? IOVEC_NR : count) * sizeof(dep->de_write_iovec_s.iod_iovec[0]), dep->de_write_iovec_s.iod_iovec); dep->de_write_iovec_s.iod_iovec_s = count; - dep->de_write_iovec_s.iod_proc_nr = mp->DL_PROC; + dep->de_write_iovec_s.iod_proc_nr = mp->DL_ENDPT; dep->de_write_iovec_s.iod_grant = mp->DL_GRANT; dep->de_write_iovec_s.iod_iovec_offset = 0; @@ -659,80 +452,10 @@ int from_int; */ if (from_int) return; - reply(dep, OK, FALSE); - - assert(dep->de_mode == DEM_ENABLED); - assert(dep->de_flags & DEF_ENABLED); -} - -/*===========================================================================* - * do_vread * - *===========================================================================*/ -static void do_vread(mp, vectored) -message *mp; -int vectored; -{ - int port, count; - int size; - dpeth_t *dep; + reply(dep); - port = mp->DL_PORT; - count = mp->DL_COUNT; - if (port < 0 || port >= DE_PORT_NR) - panic("dp8390: illegal port: %d", port); - dep= &de_table[port]; - dep->de_client= mp->DL_PROC; - if (dep->de_mode == DEM_SINK) - { - reply(dep, OK, FALSE); - return; - } assert(dep->de_mode == DEM_ENABLED); assert(dep->de_flags & DEF_ENABLED); - - if(dep->de_flags & DEF_READING) - panic("dp8390: read already in progress"); - - dep->de_safecopy_read= 0; - - if (vectored) - { - get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR, - (count > IOVEC_NR ? IOVEC_NR : count) * - sizeof(iovec_t), dep->de_read_iovec.iod_iovec); - dep->de_read_iovec.iod_iovec_s = count; - dep->de_read_iovec.iod_proc_nr = mp->DL_PROC; - dep->de_read_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR; - - dep->de_tmp_iovec = dep->de_read_iovec; - size= calc_iovec_size(&dep->de_tmp_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 = - mp->DL_COUNT; - dep->de_read_iovec.iod_iovec_s = 1; - dep->de_read_iovec.iod_proc_nr = mp->DL_PROC; - dep->de_read_iovec.iod_iovec_addr = 0; - size= count; - } - if (size < ETH_MAX_PACK_SIZE_TAGGED) - panic("dp8390: wrong packet size: %d", size); - dep->de_flags |= DEF_READING; - - dp_recv(dep); - - if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) == - (DEF_READING|DEF_STOPPED)) - { - /* The chip is stopped, and all arrived packets are - * delivered. - */ - dp_reset(dep); - } - reply(dep, OK, FALSE); } /*===========================================================================* @@ -741,35 +464,31 @@ int vectored; static void do_vread_s(mp) message *mp; { - int port, count; + int count; int size; dpeth_t *dep; - port = mp->DL_PORT; + dep= &de_state; + count = mp->DL_COUNT; - if (port < 0 || port >= DE_PORT_NR) - panic("dp8390: illegal port: %d", port); - dep= &de_table[port]; - dep->de_client= mp->DL_PROC; + dep->de_client= mp->m_source; if (dep->de_mode == DEM_SINK) { - reply(dep, OK, FALSE); + reply(dep); return; } assert(dep->de_mode == DEM_ENABLED); assert(dep->de_flags & DEF_ENABLED); - dep->de_safecopy_read= 1; - if(dep->de_flags & DEF_READING) panic("dp8390: read already in progress"); - get_userdata_s(mp->DL_PROC, mp->DL_GRANT, 0, + get_userdata_s(mp->DL_ENDPT, mp->DL_GRANT, 0, (count > IOVEC_NR ? IOVEC_NR : count) * sizeof(dep->de_read_iovec_s.iod_iovec[0]), dep->de_read_iovec_s.iod_iovec); dep->de_read_iovec_s.iod_iovec_s = count; - dep->de_read_iovec_s.iod_proc_nr = mp->DL_PROC; + dep->de_read_iovec_s.iod_proc_nr = mp->DL_ENDPT; dep->de_read_iovec_s.iod_grant = mp->DL_GRANT; dep->de_read_iovec_s.iod_iovec_offset = 0; @@ -790,7 +509,7 @@ message *mp; */ dp_reset(dep); } - reply(dep, OK, FALSE); + reply(dep); } /*===========================================================================* @@ -798,7 +517,6 @@ message *mp; *===========================================================================*/ static void do_init(message *mp) { - int port; dpeth_t *dep; message reply_mess; @@ -806,15 +524,8 @@ static void do_init(message *mp) pci_conf(); /* Configure PCI devices. */ #endif - port = mp->DL_PORT; - if (port < 0 || port >= DE_PORT_NR) - { - reply_mess.m_type= DL_CONF_REPLY; - reply_mess.m3_i1= ENXIO; - mess_reply(mp, &reply_mess); - return; - } - dep= &de_table[port]; + dep= &de_state; + if (dep->de_mode == DEM_DISABLED) { /* This is the default, try to (re)locate the device. */ @@ -823,7 +534,7 @@ static void do_init(message *mp) { /* Probe failed, or the device is configured off. */ reply_mess.m_type= DL_CONF_REPLY; - reply_mess.m3_i1= ENXIO; + reply_mess.DL_STAT= ENXIO; mess_reply(mp, &reply_mess); return; } @@ -834,12 +545,11 @@ static void do_init(message *mp) if (dep->de_mode == DEM_SINK) { strncpy((char *) dep->de_address.ea_addr, "ZDP", 6); - dep->de_address.ea_addr[5] = port; + dep->de_address.ea_addr[5] = de_instance; dp_confaddr(dep); reply_mess.m_type = DL_CONF_REPLY; - reply_mess.m3_i1 = mp->DL_PORT; - reply_mess.m3_i2 = DE_PORT_NR; - *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address; + reply_mess.DL_STAT = OK; + *(ether_addr_t *) reply_mess.DL_HWADDR = dep->de_address; mess_reply(mp, &reply_mess); return; } @@ -855,13 +565,11 @@ static void do_init(message *mp) if (mp->DL_MODE & DL_BROAD_REQ) dep->de_flags |= DEF_BROAD; - dep->de_client = mp->m_source; dp_reinit(dep); reply_mess.m_type = DL_CONF_REPLY; - reply_mess.m3_i1 = mp->DL_PORT; - reply_mess.m3_i2 = DE_PORT_NR; - *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address; + reply_mess.DL_STAT = OK; + *(ether_addr_t *) reply_mess.DL_HWADDR = dep->de_address; mess_reply(mp, &reply_mess); } @@ -873,51 +581,7 @@ static void do_int(dep) dpeth_t *dep; { if (dep->de_flags & (DEF_PACK_SEND | DEF_PACK_RECV)) - reply(dep, OK, TRUE); -} - -/*===========================================================================* - * do_getstat * - *===========================================================================*/ -static void do_getstat(message *mp) -{ - int port, r; - dpeth_t *dep; - - port = mp->DL_PORT; - if (port < 0 || port >= DE_PORT_NR) - panic("dp8390: illegal port: %d", port); - dep= &de_table[port]; - dep->de_client= mp->DL_PROC; - if (dep->de_mode == DEM_SINK) - { - put_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR, - (vir_bytes) sizeof(dep->de_stat), &dep->de_stat); - - mp->m_type= DL_STAT_REPLY; - mp->DL_PORT= port; - mp->DL_STAT= OK; - r= send(mp->m_source, mp); - if (r != OK) - panic("do_getstat: send failed: %d", r); - return; - } - assert(dep->de_mode == DEM_ENABLED); - assert(dep->de_flags & DEF_ENABLED); - - dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0); - dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1); - dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2); - - put_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR, - (vir_bytes) sizeof(dep->de_stat), &dep->de_stat); - - mp->m_type= DL_STAT_REPLY; - mp->DL_PORT= port; - mp->DL_STAT= OK; - r= send(mp->m_source, mp); - if (r != OK) - panic("do_getstat: send failed: %d", r); + reply(dep); } /*===========================================================================* @@ -926,22 +590,17 @@ static void do_getstat(message *mp) static void do_getstat_s(mp) message *mp; { - int port, r; + int r; dpeth_t *dep; - port = mp->DL_PORT; - if (port < 0 || port >= DE_PORT_NR) - panic("dp8390: illegal port: %d", port); - dep= &de_table[port]; - dep->de_client= mp->DL_PROC; + dep= &de_state; + if (dep->de_mode == DEM_SINK) { - put_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR, + put_userdata_s(mp->DL_ENDPT, (vir_bytes) mp->DL_GRANT, (vir_bytes) sizeof(dep->de_stat), &dep->de_stat); mp->m_type= DL_STAT_REPLY; - mp->DL_PORT= port; - mp->DL_STAT= OK; r= send(mp->m_source, mp); if (r != OK) panic("do_getstat: send failed: %d", r); @@ -954,47 +613,22 @@ message *mp; dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1); dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2); - put_userdata_s(mp->DL_PROC, mp->DL_GRANT, + put_userdata_s(mp->DL_ENDPT, mp->DL_GRANT, sizeof(dep->de_stat), &dep->de_stat); mp->m_type= DL_STAT_REPLY; - mp->DL_PORT= port; - mp->DL_STAT= OK; r= send(mp->m_source, mp); if (r != OK) panic("do_getstat: send failed: %d", r); } /*===========================================================================* - * do_getname * - *===========================================================================*/ -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("do_getname: send failed: %d", r); -} - -/*===========================================================================* - * do_stop * + * dp_stop * *===========================================================================*/ -static void do_stop(mp) -message *mp; +static void dp_stop(dep) +dpeth_t *dep; { - int port; - dpeth_t *dep; - port = mp->DL_PORT; - - if (port < 0 || port >= DE_PORT_NR) - panic("dp8390: illegal port: %d", port); - dep= &de_table[port]; if (dep->de_mode == DEM_SINK) return; assert(dep->de_mode == DEM_ENABLED); @@ -1105,25 +739,19 @@ dpeth_t *dep; dep->de_sendq_tail= 0; if (!dep->de_prog_IO) { - dep->de_user2nicf= dp_user2nic; dep->de_user2nicf_s= dp_user2nic_s; - dep->de_nic2userf= dp_nic2user; dep->de_nic2userf_s= dp_nic2user_s; dep->de_getblockf= dp_getblock; } else if (dep->de_16bit) { - dep->de_user2nicf= dp_pio16_user2nic; dep->de_user2nicf_s= dp_pio16_user2nic_s; - dep->de_nic2userf= dp_pio16_nic2user; dep->de_nic2userf_s= dp_pio16_nic2user_s; dep->de_getblockf= dp_pio16_getblock; } else { - dep->de_user2nicf= dp_pio8_user2nic; dep->de_user2nicf_s= dp_pio8_user2nic_s; - dep->de_nic2userf= dp_pio8_nic2user; dep->de_nic2userf_s= dp_pio8_nic2user_s; dep->de_getblockf= dp_pio8_getblock; } @@ -1155,8 +783,8 @@ dpeth_t *dep; long v; /* User defined ethernet address? */ - strcpy(eakey, dp_conf[dep-de_table].dpc_envvar); - strcat(eakey, "_EA"); + strcpy(eakey, "DPETH0_EA"); + eakey[5] += de_instance; for (i= 0; i < 6; i++) { @@ -1415,22 +1043,6 @@ dpeth_t *dep; printf("%s: strange next page\n", dep->de_name); next= curr; } - else if (eth_type == eth_ign_proto) - { - /* Hack: ignore packets of a given protocol, useful - * if you share a net with 80 computers sending - * Amoeba FLIP broadcasts. (Protocol 0x8146.) - */ - static int first= 1; - if (first) - { - first= 0; - printf("%s: dropping proto 0x%04x packets\n", - dep->de_name, - ntohs(eth_ign_proto)); - } - dep->de_stat.ets_packetR++; - } else if (header.dr_status & RSR_FO) { /* This is very serious, so we issue a warning and @@ -1443,10 +1055,7 @@ dpeth_t *dep; else if ((header.dr_status & RSR_PRX) && (dep->de_flags & DEF_ENABLED)) { - if (dep->de_safecopy_read) - r = dp_pkt2user_s(dep, pageno, length); - else - r = dp_pkt2user(dep, pageno, length); + r = dp_pkt2user_s(dep, pageno, length); if (r != OK) return; @@ -1473,15 +1082,7 @@ dpeth_t *dep; return; dep->de_flags &= ~DEF_SEND_AVAIL; - switch(dep->de_sendmsg.m_type) - { - case DL_WRITE: do_vwrite(&dep->de_sendmsg, TRUE, FALSE); break; - case DL_WRITEV: do_vwrite(&dep->de_sendmsg, TRUE, TRUE); break; - case DL_WRITEV_S: do_vwrite_s(&dep->de_sendmsg, TRUE); break; - default: - panic("dp8390: wrong type: %d", dep->de_sendmsg.m_type); - break; - } + do_vwrite_s(&dep->de_sendmsg, TRUE); } /*===========================================================================* @@ -1540,42 +1141,6 @@ void *dst; insw(dep->de_data_port, dst, size); } -/*===========================================================================* - * dp_pkt2user * - *===========================================================================*/ -static int dp_pkt2user(dpeth_t *dep, int page, vir_bytes length) -{ - int last, count; - - if (!(dep->de_flags & DEF_READING)) - return EGENERIC; - - last = page + (length - 1) / DP_PAGESIZE; - if (last >= dep->de_stoppage) - { - count = (dep->de_stoppage - page) * DP_PAGESIZE - - sizeof(dp_rcvhdr_t); - - /* Save read_iovec since we need it twice. */ - dep->de_tmp_iovec = dep->de_read_iovec; - (dep->de_nic2userf)(dep, page * DP_PAGESIZE + - sizeof(dp_rcvhdr_t), &dep->de_tmp_iovec, 0, count); - (dep->de_nic2userf)(dep, dep->de_startpage * DP_PAGESIZE, - &dep->de_read_iovec, count, length - count); - } - else - { - (dep->de_nic2userf)(dep, page * DP_PAGESIZE + - sizeof(dp_rcvhdr_t), &dep->de_read_iovec, 0, length); - } - - dep->de_read_s = length; - dep->de_flags |= DEF_PACK_RECV; - dep->de_flags &= ~DEF_READING; - - return OK; -} - /*===========================================================================* * dp_pkt2user_s * *===========================================================================*/ @@ -1613,60 +1178,11 @@ static int dp_pkt2user_s(dpeth_t *dep, int page, vir_bytes length) } /*===========================================================================* - * dp_user2nic * + * dp_user2nic_s * *===========================================================================*/ -static void dp_user2nic(dep, iovp, offset, nic_addr, count) +static void dp_user2nic_s(dep, iovp, offset, nic_addr, count) dpeth_t *dep; -iovec_dat_t *iovp; -vir_bytes offset; -int nic_addr; -vir_bytes count; -{ - vir_bytes vir_hw; - int i, r; - vir_bytes bytes; - - vir_hw = (vir_bytes)dep->de_locmem + 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(iovp->iod_proc_nr, D, - iovp->iod_iovec[i].iov_addr + offset, - SELF, D, vir_hw, bytes); - if (r != OK) - panic("dp_user2nic: sys_vircopy failed: %d", r); - - count -= bytes; - vir_hw += bytes; - offset += bytes; - } - assert(count == 0); -} - -/*===========================================================================* - * dp_user2nic_s * - *===========================================================================*/ -static void dp_user2nic_s(dep, iovp, offset, nic_addr, count) -dpeth_t *dep; -iovec_dat_s_t *iovp; +iovec_dat_s_t *iovp; vir_bytes offset; int nic_addr; vir_bytes count; @@ -1710,64 +1226,6 @@ vir_bytes count; assert(count == 0); } -/*===========================================================================* - * dp_pio8_user2nic * - *===========================================================================*/ -static void dp_pio8_user2nic(dep, iovp, offset, nic_addr, count) -dpeth_t *dep; -iovec_dat_t *iovp; -vir_bytes offset; -int nic_addr; -vir_bytes count; -{ - int bytes, i; - - outb_reg0(dep, DP_ISR, ISR_RDC); - - 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_RW | 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_outsb(dep->de_data_port, iovp->iod_proc_nr, - iovp->iod_iovec[i].iov_addr + offset, bytes); - count -= bytes; - offset += bytes; - } - assert(count == 0); - - for (i= 0; i<100; i++) - { - if (inb_reg0(dep, DP_ISR) & ISR_RDC) - break; - } - if (i == 100) - { - panic("dp8390: remote dma failed to complete"); - } -} - /*===========================================================================* * dp_pio8_user2nic_s * *===========================================================================*/ @@ -1830,113 +1288,6 @@ vir_bytes count; } } -/*===========================================================================* - * dp_pio16_user2nic * - *===========================================================================*/ -static void dp_pio16_user2nic(dep, iovp, offset, nic_addr, count) -dpeth_t *dep; -iovec_dat_t *iovp; -vir_bytes offset; -int nic_addr; -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_ISR, ISR_RDC); - 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_RW | 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(user_proc, D, vir_user, - SELF, D, (vir_bytes)&two_bytes[1], 1); - if (r != OK) { - panic("dp_pio16_user2nic: sys_vircopy failed: %d", - r); - } - outw(dep->de_data_port, *(u16_t *)two_bytes); - count--; - offset++; - bytes--; - vir_user++; - odd_byte= 0; - if (!bytes) - continue; - } - ecount= bytes & ~1; - if (ecount != 0) - { - do_vir_outsw(dep->de_data_port, user_proc, vir_user, - ecount); - count -= ecount; - offset += ecount; - bytes -= ecount; - vir_user += ecount; - } - if (bytes) - { - assert(bytes == 1); - r= sys_vircopy(user_proc, D, vir_user, - SELF, D, (vir_bytes)&two_bytes[0], 1); - if (r != OK) { - panic("dp_pio16_user2nic: sys_vircopy failed: %d", - r); - } - count--; - offset++; - bytes--; - vir_user++; - odd_byte= 1; - } - } - assert(count == 0); - - if (odd_byte) - outw(dep->de_data_port, *(u16_t *)two_bytes); - - for (i= 0; i<100; i++) - { - if (inb_reg0(dep, DP_ISR) & ISR_RDC) - break; - } - if (i == 100) - { - panic("dp8390: remote dma failed to complete"); - } -} - /*===========================================================================* * dp_pio16_user2nic_s * *===========================================================================*/ @@ -2042,53 +1393,6 @@ vir_bytes count; } } -/*===========================================================================* - * dp_nic2user * - *===========================================================================*/ -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; -{ - int bytes, i, r; - - vir_bytes vir_hw = (vir_bytes) (dep->de_locmem + 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, D, vir_hw, - iovp->iod_proc_nr, D, - iovp->iod_iovec[i].iov_addr + offset, bytes); - if (r != OK) - panic("dp_nic2user: sys_vircopy failed: %d", r); - - count -= bytes; - vir_hw += bytes; - offset += bytes; - } - assert(count == 0); -} - /*===========================================================================* * dp_nic2user_s * *===========================================================================*/ @@ -2137,52 +1441,6 @@ vir_bytes count; 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; -{ - 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_pio8_nic2user_s * *===========================================================================*/ @@ -2232,98 +1490,6 @@ vir_bytes count; 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("dp_pio16_nic2user: sys_vircopy failed: %d", - 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("dp_pio16_nic2user: sys_vircopy failed: %d", r); - } - count--; - offset++; - bytes--; - vir_user++; - odd_byte= 1; - } - } - assert(count == 0); -} - /*===========================================================================* * dp_pio16_nic2user_s * *===========================================================================*/ @@ -2418,23 +1584,6 @@ vir_bytes count; 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); -} - /*===========================================================================* * dp_next_iovec_s * *===========================================================================*/ @@ -2461,13 +1610,15 @@ dpeth_t *dep; { static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0 /* ,... */ }; - int ifnr; + int confnr; dp_conf_t *dcp; dep->de_mode= DEM_DISABLED; /* Superfluous */ - ifnr= dep-de_table; - dcp= &dp_conf[ifnr]; + /* Pick a default configuration for this instance. */ + confnr= MIN(de_instance, DP_CONF_NR-1); + + dcp= &dp_conf[confnr]; update_conf(dep, dcp); if (dep->de_mode != DEM_ENABLED) return; @@ -2494,6 +1645,7 @@ dp_conf_t *dcp; { long v; static char dpc_fmt[] = "x:d:x:x"; + char eckey[16]; #if ENABLE_PCI if (dep->de_pci) @@ -2507,10 +1659,13 @@ dp_conf_t *dcp; } #endif + strcpy(eckey, "DPETH0"); + eckey[5] += de_instance; + /* 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)) { + switch (env_parse(eckey, dpc_fmt, 0, &v, 0x0000L, 0xFFFFL)) { case EP_OFF: dep->de_mode= DEM_DISABLED; break; @@ -2523,16 +1678,15 @@ dp_conf_t *dcp; 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); + (void) env_parse(eckey, 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); + (void) env_parse(eckey, dpc_fmt, 2, &v, 0L, 0xFFFFFL); dep->de_linmem= v; v= 0; - (void) env_parse(dcp->dpc_envvar, dpc_fmt, 3, &v, 0x2000L, 0x8000L); + (void) env_parse(eckey, dpc_fmt, 3, &v, 0x2000L, 0x8000L); dep->de_ramsize= v; } @@ -2564,7 +1718,7 @@ dpeth_t *dep; panic("map_hw_buffer: cannot malloc size: %d", size); o= I386_PAGE_SIZE - ((vir_bytes)buf % I386_PAGE_SIZE); abuf= buf + o; - printf("buf at 0x%x, abuf at 0x%x\n", buf, abuf); + printf("buf at %p, abuf at %p\n", buf, abuf); #if 0 r= sys_vm_map(SELF, 1 /* map */, (vir_bytes)abuf, @@ -2577,34 +1731,6 @@ dpeth_t *dep; dep->de_locmem = abuf; } -/*===========================================================================* - * 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; -} - /*===========================================================================* * calc_iovec_size_s * *===========================================================================*/ @@ -2636,37 +1762,24 @@ iovec_dat_s_t *iovp; /*===========================================================================* * reply * *===========================================================================*/ -static void reply(dep, err, may_block) +static void reply(dep) dpeth_t *dep; -int err; -int may_block; { message reply; - int status; + int flags; int r; - status = 0; + flags = DL_NOFLAGS; if (dep->de_flags & DEF_PACK_SEND) - status |= DL_PACK_SEND; + flags |= DL_PACK_SEND; if (dep->de_flags & DEF_PACK_RECV) - status |= DL_PACK_RECV; + flags |= 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_FLAGS = flags; 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: %d", r); @@ -2685,23 +1798,6 @@ message *reply_mess; panic("dp8390: unable to mess_reply"); } -/*===========================================================================* - * 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("get_userdata: sys_vircopy failed: %d", r); -} - /*===========================================================================* * get_userdata_s * *===========================================================================*/ @@ -2720,23 +1816,6 @@ void *loc_addr; panic("get_userdata: sys_safecopyfrom failed: %d", 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("put_userdata: sys_vircopy failed: %d", r); -} - /*===========================================================================* * put_userdata_s * *===========================================================================*/ diff --git a/drivers/dp8390/dp8390.h b/drivers/dp8390/dp8390.h index 901428b1a..102f32041 100644 --- a/drivers/dp8390/dp8390.h +++ b/drivers/dp8390/dp8390.h @@ -277,19 +277,13 @@ typedef struct dpeth int de_flags; int de_mode; eth_stat_t de_stat; - iovec_dat_t de_read_iovec; iovec_dat_s_t de_read_iovec_s; - int de_safecopy_read; - iovec_dat_t de_write_iovec; iovec_dat_s_t de_write_iovec_s; - iovec_dat_t de_tmp_iovec; iovec_dat_s_t de_tmp_iovec_s; vir_bytes de_read_s; endpoint_t de_client; message de_sendmsg; - dp_user2nicf_t de_user2nicf; dp_user2nicf_s_t de_user2nicf_s; - dp_nic2userf_t de_nic2userf; dp_nic2userf_s_t de_nic2userf_s; dp_getblock_t de_getblockf; } dpeth_t; diff --git a/drivers/dpeth/dp.c b/drivers/dpeth/dp.c index e536f9f5a..df7119634 100644 --- a/drivers/dpeth/dp.c +++ b/drivers/dpeth/dp.c @@ -1,4 +1,3 @@ -#include /* ** File: dp.c Version 1.01, Oct. 17, 2007 ** Original: eth.c Version 1.00, Jan. 14, 1997 @@ -11,47 +10,7 @@ ** to remove bord specific code. It should operate (I hope) ** with any board driver. ** -** The valid messages and their parameters are: -** -** m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR -** +------------+---------+---------+--------+-------+---------+ -** | NOTIFY from HARDWARE, CLOCK, TTY, RS, PM, SYSTEM | -** +------------+---------+---------+--------+-------+---------+ -** | HARD_STOP | | | | | | -** +------------+---------+---------+--------+-------+---------+ -** | DL_WRITE | port nr | proc nr | count | mode | address | (3) -** +------------+---------+---------+--------+-------+---------+ -** | DL_WRITEV | port nr | proc nr | count | mode | address | (4) -** +------------+---------+---------+--------+-------+---------+ -** | DL_READ | port nr | proc nr | count | | address | (5) -** +------------+---------+---------+--------+-------+---------+ -** | DL_READV | port nr | proc nr | count | | address | (6) -** +------------+---------+---------+--------+-------+---------+ -** | DL_CONF | port nr | proc nr | | mode | address | (7) -** +------------+---------+---------+--------+-------+---------+ -** | DL_STOP | port_nr | | | | | (8) -** +------------+---------+---------+--------+-------+---------+ -** | DL_GETSTAT | port nr | proc nr | | | address | (9) -** +------------+---------+---------+--------+-------+---------+ -** -** The messages sent are: -** -** m-type DL_PORT DL_PROC DL_COUNT DL_STAT DL_CLCK -** +------------+---------+---------+--------+---------+---------+ -** |DL_TASK_REPL| port nr | proc nr |rd-count| err|stat| clock | (21) -** +------------+---------+---------+--------+---------+---------+ -** -** m_type m3_i1 m3_i2 m3_ca1 -** +------------+---------+---------+---------------+ -** |DL_CONF_REPL| port nr |last port| ethernet addr | (20) -** +------------+---------+---------+---------------+ -** ** $Id$ -** -** 2007-10-17: modified by jfdsmit@gmail.com -** added a third argument to the reply() function because not -** every reply should be of DL_TASK_REPLY (one should be -** DL_STAT_REPLY) */ #include @@ -66,61 +25,55 @@ /* ** Local data */ -extern int errno; -static dpeth_t de_table[DE_PORT_NR]; -static const char *progname; +static dpeth_t de_state; +static int de_instance; typedef struct dp_conf { /* Configuration description structure */ port_t dpc_port; int dpc_irq; phys_bytes dpc_mem; - char *dpc_envvar; } dp_conf_t; /* Device default configuration */ -static dp_conf_t dp_conf[DE_PORT_NR] = { - /* I/O port, IRQ, Buff addr, Env. var, Buf. selector */ - { 0x300, 5, 0xC8000, "DPETH0", }, - { 0x280, 10, 0xCC000, "DPETH1", }, +#define DP_CONF_NR 3 +static dp_conf_t dp_conf[DP_CONF_NR] = { + /* I/O port, IRQ, Buff addr, Env. var */ + { 0x300, 5, 0xC8000, }, + { 0x280, 10, 0xCC000, }, + { 0x000, 0, 0x00000, }, }; static char CopyErrMsg[] = "unable to read/write user data"; -static char PortErrMsg[] = "illegal port"; static char RecvErrMsg[] = "netdriver_receive failed"; static char SendErrMsg[] = "send failed"; static char SizeErrMsg[] = "illegal packet size"; static char TypeErrMsg[] = "illegal message type"; static char DevName[] = "eth#?"; -static void do_getname(message *mp); - /* ** Name: void reply(dpeth_t *dep, int err, int m_type) ** Function: Fills a reply message and sends it. */ -static void reply(dpeth_t * dep, int err, int m_type) +static void reply(dpeth_t * dep) { message reply; - int status = FALSE; + int r, flags; - if (dep->de_flags & DEF_ACK_SEND) status |= DL_PACK_SEND; - if (dep->de_flags & DEF_ACK_RECV) status |= DL_PACK_RECV; + flags = DL_NOFLAGS; + if (dep->de_flags & DEF_ACK_SEND) flags |= DL_PACK_SEND; + if (dep->de_flags & DEF_ACK_RECV) flags |= DL_PACK_RECV; - reply.m_type = m_type; - reply.DL_PORT = dep - de_table; - reply.DL_PROC = dep->de_client; - reply.DL_STAT = status /* | ((u32_t) err << 16) */; + reply.m_type = DL_TASK_REPLY; + reply.DL_FLAGS = flags; reply.DL_COUNT = dep->de_read_s; - getuptime(&reply.DL_CLCK); - DEBUG(printf("\t reply %d (%ld)\n", reply.m_type, reply.DL_STAT)); + DEBUG(printf("\t reply %d (%lx)\n", reply.m_type, reply.DL_FLAGS)); - if ((status = send(dep->de_client, &reply)) == OK) { - dep->de_read_s = 0; - dep->de_flags &= NOT(DEF_ACK_SEND | DEF_ACK_RECV); + if ((r = send(dep->de_client, &reply)) != OK) + panic(SendErrMsg, r); - } else if (status != ELOCKED || err == OK) - panic(SendErrMsg, status); + dep->de_read_s = 0; + dep->de_flags &= NOT(DEF_ACK_SEND | DEF_ACK_RECV); return; } @@ -136,8 +89,8 @@ static void dp_confaddr(dpeth_t * dep) int ix; long val; - strcpy(ea_key, dp_conf[dep - de_table].dpc_envvar); - strcat(ea_key, "_EA"); + strcpy(ea_key, "DPETH0_EA"); + ea_key[5] += de_instance; for (ix = 0; ix < SA_ADDR_LEN; ix++) { val = dep->de_address.ea_addr[ix]; @@ -160,11 +113,15 @@ static void dp_confaddr(dpeth_t * dep) static void update_conf(dpeth_t * dep, const dp_conf_t * dcp) { static char dpc_fmt[] = "x:d:x"; + char ec_key[16]; long val; + strcpy(ec_key, "DPETH0"); + ec_key[5] += de_instance; + dep->de_mode = DEM_SINK; val = dcp->dpc_port; /* Get I/O port address */ - switch (env_parse(dcp->dpc_envvar, dpc_fmt, 0, &val, 0x000L, 0x3FFL)) { + switch (env_parse(ec_key, dpc_fmt, 0, &val, 0x000L, 0x3FFL)) { case EP_OFF: dep->de_mode = DEM_DISABLED; break; case EP_ON: case EP_SET: dep->de_mode = DEM_ENABLED; break; @@ -172,11 +129,11 @@ static void update_conf(dpeth_t * dep, const dp_conf_t * dcp) dep->de_base_port = val; val = dcp->dpc_irq | DEI_DEFAULT; /* Get Interrupt line (IRQ) */ - env_parse(dcp->dpc_envvar, dpc_fmt, 1, &val, 0L, (long) NR_IRQ_VECTORS - 1); + env_parse(ec_key, dpc_fmt, 1, &val, 0L, (long) NR_IRQ_VECTORS - 1); dep->de_irq = val; val = dcp->dpc_mem; /* Get shared memory address */ - env_parse(dcp->dpc_envvar, dpc_fmt, 2, &val, 0L, LONG_MAX); + env_parse(ec_key, dpc_fmt, 2, &val, 0L, LONG_MAX); dep->de_linmem = val; return; @@ -189,40 +146,40 @@ static void update_conf(dpeth_t * dep, const dp_conf_t * dcp) static void do_dump(const message *mp) { dpeth_t *dep; - int port; + + dep = &de_state; printf("\n\n"); - for (port = 0, dep = de_table; port < DE_PORT_NR; port += 1, dep += 1) { - if (dep->de_mode == DEM_DISABLED) continue; + if (dep->de_mode == DEM_DISABLED) return; - printf("%s statistics:\t\t", dep->de_name); + printf("%s statistics:\t\t", dep->de_name); - /* Network interface status */ - printf("Status: 0x%04x (%d)\n\n", dep->de_flags, dep->de_int_pending); + /* Network interface status */ + printf("Status: 0x%04x (%d)\n\n", dep->de_flags, dep->de_int_pending); - (*dep->de_dumpstatsf) (dep); + (*dep->de_dumpstatsf) (dep); - /* Transmitted/received bytes */ - printf("Tx bytes:%10ld\t", dep->bytes_Tx); - printf("Rx bytes:%10ld\n", dep->bytes_Rx); + /* Transmitted/received bytes */ + printf("Tx bytes:%10ld\t", dep->bytes_Tx); + printf("Rx bytes:%10ld\n", dep->bytes_Rx); - /* Transmitted/received packets */ - printf("Tx OK: %8ld\t", dep->de_stat.ets_packetT); - printf("Rx OK: %8ld\n", dep->de_stat.ets_packetR); + /* Transmitted/received packets */ + printf("Tx OK: %8ld\t", dep->de_stat.ets_packetT); + printf("Rx OK: %8ld\n", dep->de_stat.ets_packetR); - /* Transmit/receive errors */ - printf("Tx Err: %8ld\t", dep->de_stat.ets_sendErr); - printf("Rx Err: %8ld\n", dep->de_stat.ets_recvErr); + /* Transmit/receive errors */ + printf("Tx Err: %8ld\t", dep->de_stat.ets_sendErr); + printf("Rx Err: %8ld\n", dep->de_stat.ets_recvErr); - /* Transmit unnerruns/receive overrruns */ - printf("Tx Und: %8ld\t", dep->de_stat.ets_fifoUnder); - printf("Rx Ovr: %8ld\n", dep->de_stat.ets_fifoOver); + /* Transmit unnerruns/receive overrruns */ + printf("Tx Und: %8ld\t", dep->de_stat.ets_fifoUnder); + printf("Rx Ovr: %8ld\n", dep->de_stat.ets_fifoOver); + + /* Transmit collisions/receive CRC errors */ + printf("Tx Coll: %8ld\t", dep->de_stat.ets_collision); + printf("Rx CRC: %8ld\n", dep->de_stat.ets_CRCerr); - /* Transmit collisions/receive CRC errors */ - printf("Tx Coll: %8ld\t", dep->de_stat.ets_collision); - printf("Rx CRC: %8ld\n", dep->de_stat.ets_CRCerr); - } return; } @@ -279,75 +236,73 @@ static void do_first_init(dpeth_t *dep, const dp_conf_t *dcp) */ static void do_init(const message * mp) { - int port; dpeth_t *dep; dp_conf_t *dcp; message reply_mess; + int r, confnr; - port = mp->DL_PORT; - if (port >= 0 && port < DE_PORT_NR) { - - dep = &de_table[port]; - dcp = &dp_conf[port]; - strcpy(dep->de_name, DevName); - dep->de_name[4] = '0' + port; - - if (dep->de_mode == DEM_DISABLED) { - - update_conf(dep, dcp); /* First time thru */ - if (dep->de_mode == DEM_ENABLED && - !el1_probe(dep) && /* Probe for 3c501 */ - !wdeth_probe(dep) && /* Probe for WD80x3 */ - !ne_probe(dep) && /* Probe for NEx000 */ - !el2_probe(dep) && /* Probe for 3c503 */ - !el3_probe(dep)) { /* Probe for 3c509 */ - printf("%s: warning no ethernet card found at 0x%04X\n", - dep->de_name, dep->de_base_port); - dep->de_mode = DEM_DISABLED; - } - } + dep = &de_state; - /* 'de_mode' may change if probe routines fail, test again */ - switch (dep->de_mode) { + /* Pick a default configuration for this instance. */ + confnr = MIN(de_instance, DP_CONF_NR-1); - case DEM_DISABLED: - /* Device is configured OFF or hardware probe failed */ - port = ENXIO; - break; + dcp = &dp_conf[confnr]; + strcpy(dep->de_name, DevName); + dep->de_name[4] = '0' + de_instance; - case DEM_ENABLED: - /* Device is present and probed */ - if (dep->de_flags == DEF_EMPTY) { - /* These actions only the first time */ - do_first_init(dep, dcp); - dep->de_flags |= DEF_ENABLED; - } - dep->de_flags &= NOT(DEF_PROMISC | DEF_MULTI | DEF_BROAD); - if (mp->DL_MODE & DL_PROMISC_REQ) - dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD; - if (mp->DL_MODE & DL_MULTI_REQ) dep->de_flags |= DEF_MULTI; - if (mp->DL_MODE & DL_BROAD_REQ) dep->de_flags |= DEF_BROAD; - (*dep->de_flagsf) (dep); - dep->de_client = mp->m_source; - break; + if (dep->de_mode == DEM_DISABLED) { - case DEM_SINK: - /* Device not present (sink mode) */ - memset(dep->de_address.ea_addr, 0, sizeof(ether_addr_t)); - dp_confaddr(dep); /* Station address from env. */ - break; - - default: break; + update_conf(dep, dcp); /* First time thru */ + if (dep->de_mode == DEM_ENABLED && + !el1_probe(dep) && /* Probe for 3c501 */ + !wdeth_probe(dep) && /* Probe for WD80x3 */ + !ne_probe(dep) && /* Probe for NEx000 */ + !el2_probe(dep) && /* Probe for 3c503 */ + !el3_probe(dep)) { /* Probe for 3c509 */ + printf("%s: warning no ethernet card found at 0x%04X\n", + dep->de_name, dep->de_base_port); + dep->de_mode = DEM_DISABLED; } - *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address; + } + + r = OK; + + /* 'de_mode' may change if probe routines fail, test again */ + switch (dep->de_mode) { + + case DEM_DISABLED: + /* Device is configured OFF or hardware probe failed */ + r = ENXIO; + break; - } else { /* Port number is out of range */ - port = ENXIO; + case DEM_ENABLED: + /* Device is present and probed */ + if (dep->de_flags == DEF_EMPTY) { + /* These actions only the first time */ + do_first_init(dep, dcp); + dep->de_flags |= DEF_ENABLED; + } + dep->de_flags &= NOT(DEF_PROMISC | DEF_MULTI | DEF_BROAD); + if (mp->DL_MODE & DL_PROMISC_REQ) + dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD; + if (mp->DL_MODE & DL_MULTI_REQ) dep->de_flags |= DEF_MULTI; + if (mp->DL_MODE & DL_BROAD_REQ) dep->de_flags |= DEF_BROAD; + (*dep->de_flagsf) (dep); + break; + + case DEM_SINK: + /* Device not present (sink mode) */ + memset(dep->de_address.ea_addr, 0, sizeof(ether_addr_t)); + dp_confaddr(dep); /* Station address from env. */ + break; + + default: break; } reply_mess.m_type = DL_CONF_REPLY; - reply_mess.m3_i1 = port; - reply_mess.m3_i2 = DE_PORT_NR; + reply_mess.DL_STAT = r; + if (r == OK) + *(ether_addr_t *) reply_mess.DL_HWADDR = dep->de_address; DEBUG(printf("\t reply %d\n", reply_mess.m_type)); if (send(mp->m_source, &reply_mess) != OK) /* Can't send */ panic(SendErrMsg, mp->m_source); @@ -396,23 +351,20 @@ static int calc_iovec_size(iovec_dat_s_t * iovp) */ static void do_vwrite_s(const message * mp) { - int port, size; + int size; dpeth_t *dep; - port = mp->DL_PORT; - if (port < 0 || port >= DE_PORT_NR) /* Check for illegal port number */ - panic(PortErrMsg, EINVAL); + dep = &de_state; - dep = &de_table[port]; - dep->de_client = mp->DL_PROC; + dep->de_client = mp->m_source; if (dep->de_mode == DEM_ENABLED) { if (dep->de_flags & DEF_SENDING) /* Is sending in progress? */ panic("send already in progress "); - dep->de_write_iovec.iod_proc_nr = mp->DL_PROC; - get_userdata_s(mp->DL_PROC, mp->DL_GRANT, 0, + dep->de_write_iovec.iod_proc_nr = mp->DL_ENDPT; + get_userdata_s(mp->DL_ENDPT, mp->DL_GRANT, 0, mp->DL_COUNT, dep->de_write_iovec.iod_iovec); dep->de_write_iovec.iod_iovec_s = mp->DL_COUNT; dep->de_write_iovec.iod_grant = (cp_grant_id_t) mp->DL_GRANT; @@ -427,7 +379,7 @@ static void do_vwrite_s(const message * mp) } else if (dep->de_mode == DEM_SINK) dep->de_flags |= DEF_ACK_SEND; - reply(dep, OK, DL_TASK_REPLY); + reply(dep); return; } @@ -437,23 +389,20 @@ static void do_vwrite_s(const message * mp) */ static void do_vread_s(const message * mp) { - int port, size; + int size; dpeth_t *dep; - port = mp->DL_PORT; - if (port < 0 || port >= DE_PORT_NR) /* Check for illegal port number */ - panic(PortErrMsg, EINVAL); + dep = &de_state; - dep = &de_table[port]; - dep->de_client = mp->DL_PROC; + dep->de_client = mp->m_source; if (dep->de_mode == DEM_ENABLED) { if (dep->de_flags & DEF_READING) /* Reading in progress */ panic("read already in progress"); - dep->de_read_iovec.iod_proc_nr = mp->DL_PROC; - get_userdata_s(mp->DL_PROC, (cp_grant_id_t) mp->DL_GRANT, 0, + dep->de_read_iovec.iod_proc_nr = mp->DL_ENDPT; + get_userdata_s(mp->DL_ENDPT, (cp_grant_id_t) mp->DL_GRANT, 0, mp->DL_COUNT, dep->de_read_iovec.iod_iovec); dep->de_read_iovec.iod_iovec_s = mp->DL_COUNT; dep->de_read_iovec.iod_grant = (cp_grant_id_t) mp->DL_GRANT; @@ -470,7 +419,7 @@ static void do_vread_s(const message * mp) dep->de_flags &= NOT(DEF_STOPPED); #endif } - reply(dep, OK, DL_TASK_REPLY); + reply(dep); return; } @@ -480,52 +429,32 @@ static void do_vread_s(const message * mp) */ static void do_getstat_s(const message * mp) { - int port, rc; + int rc; dpeth_t *dep; + message reply_mess; - port = mp->DL_PORT; - if (port < 0 || port >= DE_PORT_NR) /* Check for illegal port number */ - panic(PortErrMsg, EINVAL); - - dep = &de_table[port]; - dep->de_client = mp->DL_PROC; + dep = &de_state; if (dep->de_mode == DEM_ENABLED) (*dep->de_getstatsf) (dep); - if ((rc = sys_safecopyto(mp->DL_PROC, mp->DL_GRANT, 0, + if ((rc = sys_safecopyto(mp->DL_ENDPT, mp->DL_GRANT, 0, (vir_bytes)&dep->de_stat, (vir_bytes) sizeof(dep->de_stat), 0)) != OK) panic(CopyErrMsg, rc); - reply(dep, OK, DL_STAT_REPLY); - 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("do_getname: send failed: %d", r); + reply_mess.m_type = DL_STAT_REPLY; + rc= send(mp->m_source, &reply_mess); + if (rc != OK) + panic("do_getname: send failed: %d", rc); + return; } /* -** Name: void do_stop(message *mp) +** Name: void dp_stop(dpeth_t *dep) ** Function: Stops network interface. */ -static void do_stop(const message * mp) +static void dp_stop(dpeth_t * dep) { - int port; - dpeth_t *dep; - port = mp->DL_PORT; - if (port < 0 || port >= DE_PORT_NR) /* Check for illegal port number */ - panic(PortErrMsg, EINVAL); - - dep = &de_table[port]; if (dep->de_mode == DEM_ENABLED && (dep->de_flags & DEF_ENABLED)) { /* Stop device */ @@ -547,16 +476,16 @@ PRIVATE void handle_hw_intr(void) { dpeth_t *dep; - 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, DL_TASK_REPLY); - dep->de_int_pending = FALSE; - sys_irqenable(&dep->de_hook); - } + dep = &de_state; + + /* 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); + dep->de_int_pending = FALSE; + sys_irqenable(&dep->de_hook); } } @@ -623,12 +552,6 @@ PUBLIC int main(int argc, char **argv) case DL_GETSTAT_S: /* Get device statistics */ do_getstat_s(&m); break; - case DL_GETNAME: - do_getname(&m); - break; - case DL_STOP: /* Stop device */ - do_stop(&m); - break; default: /* Invalid message type */ panic(TypeErrMsg, m.m_type); break; @@ -665,23 +588,16 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) { /* Initialize the dpeth driver. */ int fkeys, sfkeys; - - (progname=strrchr(env_argv[0],'/')) ? progname++ : (progname=env_argv[0]); + long v; /* 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 + v = 0; + (void) env_parse("instance", "d", 0, &v, 0, 255); + de_instance = (int) v; /* Announce we are up! */ netdriver_announce(); @@ -694,19 +610,13 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) *===========================================================================*/ PRIVATE void sef_cb_signal_handler(int signo) { - int port; - message m; - /* Only check for termination signal, ignore anything else. */ if (signo != SIGTERM) return; - for (port = 0; port < DE_PORT_NR; port += 1) { - if (de_table[port].de_mode == DEM_ENABLED) { - m.m_type = DL_STOP; - m.DL_PORT = port; - do_stop(&m); - } - } + if (de_state.de_mode == DEM_ENABLED) + dp_stop(&de_state); + + exit(0); } /** dp.c **/ diff --git a/drivers/dpeth/dp.h b/drivers/dpeth/dp.h index 836346b9d..50ab297e3 100644 --- a/drivers/dpeth/dp.h +++ b/drivers/dpeth/dp.h @@ -82,7 +82,6 @@ typedef void (*dp_nic2userf_t) (struct dpeth *, int, int); typedef void (*dp_getblock_t) (struct dpeth *, u16_t, int, void *); #endif -#define DE_PORT_NR 2 /* Number of devices supported */ #define SENDQ_NR 2 /* Size of the send queue */ #define IOVEC_NR 16 /* Number of IOVEC entries at a time */ diff --git a/drivers/e1000/e1000.c b/drivers/e1000/e1000.c index 4cec31d92..0e1caacd0 100644 --- a/drivers/e1000/e1000.c +++ b/drivers/e1000/e1000.c @@ -28,8 +28,8 @@ PRIVATE u16_t pcitab_e1000[] = 0, }; -PRIVATE const char *progname; -PRIVATE e1000_t e1000_table[E1000_PORT_NR]; +PRIVATE int e1000_instance; +PRIVATE e1000_t e1000_state; _PROTOTYPE( PRIVATE void e1000_init, (message *mp) ); _PROTOTYPE( PRIVATE void e1000_init_pci, (void) ); @@ -41,11 +41,9 @@ _PROTOTYPE( PRIVATE void e1000_reset_hw, (e1000_t *e) ); _PROTOTYPE( PRIVATE void e1000_writev_s, (message *mp, int from_int) ); _PROTOTYPE( PRIVATE void e1000_readv_s, (message *mp, int from_int) ); _PROTOTYPE( PRIVATE void e1000_getstat_s, (message *mp) ); -_PROTOTYPE( PRIVATE void e1000_getname, (message *mp) ); _PROTOTYPE( PRIVATE void e1000_interrupt, (message *mp) ); _PROTOTYPE( PRIVATE int e1000_link_changed, (e1000_t *e) ); _PROTOTYPE( PRIVATE void e1000_stop, (void) ); -_PROTOTYPE( PRIVATE e1000_t * e1000_port, (int port) ); _PROTOTYPE( PRIVATE uint32_t e1000_reg_read, (e1000_t *e, uint32_t reg) ); _PROTOTYPE( PRIVATE void e1000_reg_write, (e1000_t *e, uint32_t reg, uint32_t value) ); @@ -57,7 +55,7 @@ _PROTOTYPE( PRIVATE u16_t eeprom_eerd, (void *e, int reg) ); _PROTOTYPE( PRIVATE u16_t eeprom_ich, (void *e, int reg) ); _PROTOTYPE( PRIVATE int eeprom_ich_init, (e1000_t *e) ); _PROTOTYPE( PRIVATE int eeprom_ich_cycle, (const e1000_t *e, u32_t timeout) ); -_PROTOTYPE( PRIVATE void reply, (e1000_t *e, int err, int may_block) ); +_PROTOTYPE( PRIVATE void reply, (e1000_t *e) ); _PROTOTYPE( PRIVATE void mess_reply, (message *req, message *reply) ); /* SEF functions and variables. */ @@ -108,9 +106,7 @@ int main(int argc, char *argv[]) case DL_WRITEV_S: e1000_writev_s(&m, FALSE); break; case DL_READV_S: e1000_readv_s(&m, FALSE); break; case DL_CONF: e1000_init(&m); break; - case DL_STOP: e1000_stop(); break; case DL_GETSTAT_S: e1000_getstat_s(&m); break; - case DL_GETNAME: e1000_getname(&m); break; default: panic("illegal message: %d", m.m_type); } @@ -144,19 +140,15 @@ PRIVATE void sef_local_startup() PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) { /* Initialize the e1000 driver. */ + long v; int r; - /* Verify command-line arguments. */ - if (env_argc < 1) - { - panic("no program name given in argc/argv"); - } - else - (progname = strrchr(env_argv[0],'/')) ? progname++ - : (progname = env_argv[0]); + v = 0; + (void) env_parse("instance", "d", 0, &v, 0, 255); + e1000_instance = (int) v; /* Clear state. */ - memset(e1000_table, 0, sizeof(e1000_table)); + memset(&e1000_state, 0, sizeof(e1000_state)); /* Perform calibration. */ if((r = tsc_calibrate()) != OK) @@ -200,23 +192,20 @@ PRIVATE void e1000_init(message *mp) first_time = 0; e1000_init_pci(); } - /* Retrieve e1000 pointer. */ - e = e1000_port(mp->DL_PORT); - e->client = mp->DL_PROC; + e = &e1000_state; /* Initialize hardware, if needed. */ if (!(e->status & E1000_ENABLED) && !(e1000_init_hw(e))) { - reply_mess.m_type = DL_CONF_REPLY; - reply_mess.m3_i1 = ENXIO; + reply_mess.m_type = DL_CONF_REPLY; + reply_mess.DL_STAT = ENXIO; mess_reply(mp, &reply_mess); return; } /* Reply back to INET. */ - reply_mess.m_type = DL_CONF_REPLY; - reply_mess.m3_i1 = mp->DL_PORT; - reply_mess.m3_i2 = E1000_PORT_NR; - *(ether_addr_t *) reply_mess.m3_ca1 = e->address; + reply_mess.m_type = DL_CONF_REPLY; + reply_mess.DL_STAT = OK; + *(ether_addr_t *) reply_mess.DL_HWADDR = e->address; mess_reply(mp, &reply_mess); } @@ -226,18 +215,15 @@ PRIVATE void e1000_init(message *mp) PRIVATE void e1000_init_pci() { e1000_t *e; - int i; /* Initialize the PCI bus. */ pci_init(); /* Try to detect e1000's. */ - for (i = 0, e = &e1000_table[i]; i < E1000_PORT_NR; i++, e++) - { - strcpy(e->name, "e1000#0"); - e->name[6] += i; - e1000_probe(e, i); - } + e = &e1000_state; + strcpy(e->name, "e1000#0"); + e->name[6] += e1000_instance; + e1000_probe(e, e1000_instance); } /*===========================================================================* @@ -353,7 +339,7 @@ PRIVATE int e1000_probe(e1000_t *e, int skip) * Output debug information. */ status[0] = e1000_reg_read(e, E1000_REG_STATUS); - E1000_DEBUG(3, ("%s: MEM at 0x%lx, IRQ %d\n", + E1000_DEBUG(3, ("%s: MEM at %p, IRQ %d\n", e->name, e->regs, e->irq)); E1000_DEBUG(3, ("%s: link %s, %s duplex\n", e->name, status[0] & 3 ? "up" : "down", @@ -441,7 +427,7 @@ e1000_t *e; /* * Do we have a user defined ethernet address? */ - eakey[sizeof(E1000_ENVVAR)-1] = '0' + (e-e1000_table); + eakey[sizeof(E1000_ENVVAR)-1] = '0' + e1000_instance; for (i= 0; i < 6; i++) { @@ -453,7 +439,7 @@ e1000_t *e; /* * If that fails, read Ethernet Address from EEPROM. */ - if ((i != 0 && i != 6) || i == 0) + if (i != 6) { for (i = 0; i < 3; i++) { @@ -592,12 +578,12 @@ PRIVATE void e1000_writev_s(mp, from_int) message *mp; int from_int; { - e1000_t *e = e1000_port(mp->DL_PORT); + e1000_t *e = &e1000_state; e1000_tx_desc_t *desc; iovec_s_t iovec[E1000_IOVEC_NR]; int r, head, tail, i, bytes = 0, size; - E1000_DEBUG(3, ("e1000: writev_s(%x,%d)\n", mp, from_int)); + E1000_DEBUG(3, ("e1000: writev_s(%p,%d)\n", mp, from_int)); /* Are we called from the interrupt handler? */ if (!from_int) @@ -607,6 +593,7 @@ int from_int; /* Copy write message. */ e->tx_message = *mp; + e->client = mp->m_source; e->status |= E1000_WRITING; /* Must be a sane vector count. */ @@ -616,7 +603,8 @@ int from_int; /* * Copy the I/O vector table. */ - if ((r = sys_safecopyfrom(e->client, e->tx_message.DL_GRANT, 0, + if ((r = sys_safecopyfrom(e->tx_message.DL_ENDPT, + e->tx_message.DL_GRANT, 0, (vir_bytes) iovec, e->tx_message.DL_COUNT * sizeof(iovec_s_t), D)) != OK) { @@ -639,7 +627,8 @@ int from_int; E1000_DEBUG(4, ("iovec[%d] = %d\n", i, size)); /* Copy bytes to TX queue buffers. */ - if ((r = sys_safecopyfrom(e->client, iovec[i].iov_grant, 0, + if ((r = sys_safecopyfrom(e->tx_message.DL_ENDPT, + iovec[i].iov_grant, 0, (vir_bytes) e->tx_buffer + (tail * E1000_IOBUF_SIZE), size, D)) != OK) @@ -672,7 +661,7 @@ int from_int; { e->status |= E1000_TRANSMIT; } - reply(e, OK, FALSE); + reply(e); } /*===========================================================================* @@ -682,17 +671,18 @@ PRIVATE void e1000_readv_s(mp, from_int) message *mp; int from_int; { - e1000_t *e = e1000_port(mp->DL_PORT); + e1000_t *e = &e1000_state; e1000_rx_desc_t *desc; iovec_s_t iovec[E1000_IOVEC_NR]; int i, r, head, tail, cur, bytes = 0, size; - E1000_DEBUG(3, ("e1000: readv_s(%x,%d)\n", mp, from_int)); + E1000_DEBUG(3, ("e1000: readv_s(%p,%d)\n", mp, from_int)); /* Are we called from the interrupt handler? */ if (!from_int) { e->rx_message = *mp; + e->client = mp->m_source; e->status |= E1000_READING; e->rx_size = 0; @@ -704,7 +694,8 @@ int from_int; /* * Copy the I/O vector table first. */ - if ((r = sys_safecopyfrom(e->client, e->rx_message.DL_GRANT, 0, + if ((r = sys_safecopyfrom(e->rx_message.DL_ENDPT, + e->rx_message.DL_GRANT, 0, (vir_bytes) iovec, e->rx_message.DL_COUNT * sizeof(iovec_s_t), D)) != OK) { @@ -721,7 +712,7 @@ int from_int; */ if (!(desc->status & E1000_RX_STATUS_EOP)) { - reply(e, OK, FALSE); + reply(e); return; } E1000_DEBUG(4, ("%s: head=%x, tail=%d\n", @@ -735,11 +726,11 @@ int from_int; size = iovec[i].iov_size < (desc->length - bytes) ? iovec[i].iov_size : (desc->length - bytes); - E1000_DEBUG(4, ("iovec[%d] = %d[%d]\n", + E1000_DEBUG(4, ("iovec[%d] = %lu[%d]\n", i, iovec[i].iov_size, size)); - if ((r = sys_safecopyto(e->client, iovec[i].iov_grant, 0, - (vir_bytes) e->rx_buffer + bytes + + if ((r = sys_safecopyto(e->rx_message.DL_ENDPT, iovec[i].iov_grant, + 0, (vir_bytes) e->rx_buffer + bytes + (cur * E1000_IOBUF_SIZE), size, D)) != OK) { @@ -759,7 +750,7 @@ int from_int; /* Increment tail. */ e1000_reg_write(e, E1000_REG_RDT, (tail + 1) % e->rx_desc_count); } - reply(e, OK, FALSE); + reply(e); } /*===========================================================================* @@ -770,7 +761,7 @@ message *mp; { int r; eth_stat_t stats; - e1000_t *e = e1000_port(mp->DL_PORT); + e1000_t *e = &e1000_state; E1000_DEBUG(3, ("e1000: getstat_s()\n")); @@ -790,37 +781,13 @@ message *mp; stats.ets_CDheartbeat = 0; stats.ets_OWC = 0; - sys_safecopyto(mp->DL_PROC, mp->DL_GRANT, 0, (vir_bytes)&stats, + sys_safecopyto(mp->DL_ENDPT, mp->DL_GRANT, 0, (vir_bytes)&stats, sizeof(stats), D); mp->m_type = DL_STAT_REPLY; - mp->DL_PORT = mp->DL_PORT; - mp->DL_STAT = OK; if((r=send(mp->m_source, mp)) != OK) panic("e1000_getstat: send() failed: %d", r); } -/*===========================================================================* - * e1000_getname * - *===========================================================================*/ -PRIVATE void e1000_getname(mp) -message *mp; -{ - int r; - - E1000_DEBUG(3, ("e1000: getname()\n")); - - /* Copy our program name. */ - strncpy(mp->DL_NAME, progname, sizeof(mp->DL_NAME)); - mp->DL_NAME[ sizeof(mp->DL_NAME) - 1 ] = 0; - - /* Acknowledge the name request. */ - mp->m_type = DL_NAME_REPLY; - if ((r = send(mp->m_source, mp)) != OK) - { - panic("e1000_getname: send() failed: %d", r); - } -} - /*===========================================================================* * e1000_interrupt * *===========================================================================*/ @@ -829,37 +796,32 @@ message *mp; { e1000_t *e; u32_t cause; - unsigned int i; E1000_DEBUG(3, ("e1000: interrupt\n")); /* - * Loop all cards. Check for interrupt reason(s). + * Check the card for interrupt reason(s). */ - for (i = 0; i < E1000_PORT_NR; i++) - { - e = e1000_port(i); + e = &e1000_state; - /* Re-enable interrupts. */ - if (sys_irqenable(&e->irq_hook) != OK) - { - panic("failed to re-enable IRQ"); - } + /* Re-enable interrupts. */ + if (sys_irqenable(&e->irq_hook) != OK) + { + panic("failed to re-enable IRQ"); + } - /* Read the Interrupt Cause Read register. */ - if ((cause = e1000_reg_read(e, E1000_REG_ICR))) - { - if (cause & E1000_REG_ICR_LSC) - e1000_link_changed(e); + /* Read the Interrupt Cause Read register. */ + if ((cause = e1000_reg_read(e, E1000_REG_ICR))) + { + if (cause & E1000_REG_ICR_LSC) + e1000_link_changed(e); - if (cause & (E1000_REG_ICR_RXO | E1000_REG_ICR_RXT)) - e1000_readv_s(&e->rx_message, TRUE); + if (cause & (E1000_REG_ICR_RXO | E1000_REG_ICR_RXT)) + e1000_readv_s(&e->rx_message, TRUE); - if ((cause & E1000_REG_ICR_TXQE) || - (cause & E1000_REG_ICR_TXDW)) - e1000_writev_s(&e->tx_message, TRUE); - - } + if ((cause & E1000_REG_ICR_TXQE) || + (cause & E1000_REG_ICR_TXDW)) + e1000_writev_s(&e->tx_message, TRUE); } } @@ -882,31 +844,6 @@ PRIVATE void e1000_stop() exit(EXIT_SUCCESS); } -/*===========================================================================* - * e1000_port * - *===========================================================================*/ -PRIVATE e1000_t * e1000_port(num) -int num; -{ - /* - * Is the given port number within the allowed range? - */ - if (num < 0 || num >= E1000_PORT_NR) - { - panic("invalid port number given: %d", num); - } - - /* - * The card must be active. - */ - if (!(e1000_table[num].status & E1000_DETECTED)) - { - panic("inactive port number given: %d", num); - } - return &e1000_table[num]; -} - - /*===========================================================================* * e1000_reg_read * *===========================================================================*/ @@ -1127,7 +1064,7 @@ int reg; int ret_val = -1; u8_t count = 0; e1000_t *e = (e1000_t *) v; - u16_t data; + u16_t data = 0; E1000_DEBUG(3, ("e1000_read_flash_data_ich8lan")); @@ -1198,10 +1135,8 @@ out: /*===========================================================================* * reply * *===========================================================================*/ -PRIVATE void reply(e, err, may_block) +PRIVATE void reply(e) e1000_t *e; -int err; -int may_block; { message msg; int r; @@ -1214,17 +1149,14 @@ int may_block; } /* Construct reply message. */ msg.m_type = DL_TASK_REPLY; - msg.DL_PORT = e - e1000_table; - msg.DL_PROC = e->client; + msg.DL_FLAGS = DL_NOFLAGS; msg.DL_COUNT = 0; - msg.DL_STAT = 0; - msg.DL_CLCK = 0; /* Did we successfully receive packet(s)? */ if (e->status & E1000_READING && e->status & E1000_RECEIVED) { - msg.DL_STAT = DL_PACK_RECV; + msg.DL_FLAGS |= DL_PACK_RECV; msg.DL_COUNT = e->rx_size >= ETH_MIN_PACK_SIZE ? e->rx_size : ETH_MIN_PACK_SIZE; @@ -1235,8 +1167,7 @@ int may_block; if (e->status & E1000_TRANSMIT && e->status & E1000_WRITING) { - msg.DL_STAT = DL_PACK_SEND; - msg.DL_COUNT = 0; + msg.DL_FLAGS |= DL_PACK_SEND; /* Clear flags. */ e->status &= ~(E1000_WRITING | E1000_TRANSMIT); diff --git a/drivers/e1000/e1000.h b/drivers/e1000/e1000.h index 75f1017ab..0124c3353 100644 --- a/drivers/e1000/e1000.h +++ b/drivers/e1000/e1000.h @@ -32,9 +32,6 @@ * @{ */ -/** Maximum number of cards supported. */ -#define E1000_PORT_NR 1 - /** Number of receive descriptors per card. */ #define E1000_RXDESC_NR 256 diff --git a/drivers/fxp/fxp.c b/drivers/fxp/fxp.c index 3a61d3451..01156ba57 100644 --- a/drivers/fxp/fxp.c +++ b/drivers/fxp/fxp.c @@ -4,51 +4,6 @@ * This file contains an ethernet device driver for Intel 82557, 82558, * 82559, 82550, and 82562 fast ethernet controllers. * - * The valid messages and their parameters are: - * - * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR DL_GRANT - * |------------+----------+---------+----------+---------+---------+---------| - * | HARDINT | | | | | | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_WRITE | port nr | proc nr | count | mode | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_WRITEV | port nr | proc nr | count | mode | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_WRITEV_S| port nr | proc nr | count | mode | | grant | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_READ | port nr | proc nr | count | | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_READV | port nr | proc nr | count | | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_READV_S | port nr | proc nr | count | | | grant | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_CONF | port nr | proc nr | | mode | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_GETSTAT | port nr | proc nr | | | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * |DL_GETSTAT_S| port nr | proc nr | | | | grant | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_STOP | port_nr | | | | | | - * |------------+----------+---------+----------+---------+---------+---------| - * - * The messages sent are: - * - * m-type DL_PORT DL_PROC DL_COUNT DL_STAT DL_CLCK - * |-------------+----------+---------+----------+---------+---------| - * |DL_TASK_REPLY| port nr | proc nr | rd-count | err|stat| clock | - * |-------------+----------+---------+----------+---------+---------| - * - * m_type m3_i1 m3_i2 m3_ca1 - * |-------------+---------+-----------+---------------| - * |DL_CONF_REPLY| port nr | last port | ethernet addr | - * |-------------+---------+-----------+---------------| - * - * m_type DL_PORT DL_STAT - * |------------|---------|-----------| - * |DL_STAT_REPL| port nr | err | - * |------------|---------|-----------| - * - * * Created: Nov 2004 by Philip Homburg */ @@ -104,8 +59,6 @@ PRIVATE struct pcitab pcitab_fxp[]= { 0x0000, 0x0000, 0 } }; -#define FXP_PORT_NR 1 /* Minix */ - typedef int irq_hook_t; static timer_t *fxp_timers= NULL; @@ -208,12 +161,11 @@ fxp_t; #define FT_82559 0x4 #define FT_82801 0x8 -PRIVATE fxp_t *fxp_table; -PRIVATE phys_bytes fxp_table_phys; +PRIVATE int fxp_instance; + +PRIVATE fxp_t *fxp_state; -PRIVATE u16_t eth_ign_proto; PRIVATE tmra_ut fxp_watchdog; -PRIVATE const char *progname; PRIVATE u32_t system_hz; @@ -231,11 +183,7 @@ _PROTOTYPE( static void fxp_init_buf, (fxp_t *fp) ); _PROTOTYPE( static void fxp_reset_hw, (fxp_t *fp) ); _PROTOTYPE( static void fxp_confaddr, (fxp_t *fp) ); _PROTOTYPE( static void fxp_rec_mode, (fxp_t *fp) ); -_PROTOTYPE( static void fxp_writev, (message *mp, int from_int, - int vectored) ); _PROTOTYPE( static void fxp_writev_s, (const message *mp, int from_int) ); -_PROTOTYPE( static void fxp_readv, (message *mp, int from_int, - int vectored) ); _PROTOTYPE( static void fxp_readv_s, (message *mp, int from_int) ); _PROTOTYPE( static void fxp_do_conf, (fxp_t *fp) ); _PROTOTYPE( static void fxp_cu_ptr_cmd, (fxp_t *fp, int cmd, @@ -243,15 +191,13 @@ _PROTOTYPE( static void fxp_cu_ptr_cmd, (fxp_t *fp, int cmd, _PROTOTYPE( static void fxp_ru_ptr_cmd, (fxp_t *fp, int cmd, phys_bytes bus_addr, int check_idle) ); _PROTOTYPE( static void fxp_restart_ru, (fxp_t *fp) ); -_PROTOTYPE( static void fxp_getstat, (message *mp) ); _PROTOTYPE( static void fxp_getstat_s, (message *mp) ); -_PROTOTYPE( static void fxp_getname, (message *mp) ); _PROTOTYPE( static void fxp_handler, (fxp_t *fp) ); _PROTOTYPE( static void fxp_check_ints, (fxp_t *fp) ); _PROTOTYPE( static void fxp_watchdog_f, (timer_t *tp) ); _PROTOTYPE( static int fxp_link_changed, (fxp_t *fp) ); _PROTOTYPE( static void fxp_report_link, (fxp_t *fp) ); -_PROTOTYPE( static void reply, (fxp_t *fp, int err, int may_block) ); +_PROTOTYPE( static void reply, (fxp_t *fp) ); _PROTOTYPE( static void mess_reply, (message *req, message *reply) ); _PROTOTYPE( static u16_t eeprom_read, (fxp_t *fp, int reg) ); _PROTOTYPE( static void eeprom_addrsize, (fxp_t *fp) ); @@ -268,25 +214,25 @@ _PROTOTYPE( static void tell_dev, (vir_bytes start, size_t size, PRIVATE void handle_hw_intr(void) { - int i, r; + int r; fxp_t *fp; - for (i= 0, fp= &fxp_table[0]; ifxp_mode != FM_ENABLED) - return; - fxp_handler(fp); + fp= fxp_state; - r= sys_irqenable(&fp->fxp_hook); - if (r != OK) { - panic("unable enable interrupts: %d", r); - } + if (fp->fxp_mode != FM_ENABLED) + return; + fxp_handler(fp); - if (!fp->fxp_got_int) - return; - fp->fxp_got_int= 0; - assert(fp->fxp_flags & FF_ENABLED); - fxp_check_ints(fp); + r= sys_irqenable(&fp->fxp_hook); + if (r != OK) { + panic("unable enable interrupts: %d", r); } + + if (!fp->fxp_got_int) + return; + fp->fxp_got_int= 0; + assert(fp->fxp_flags & FF_ENABLED); + fxp_check_ints(fp); } /* SEF functions and variables. */ @@ -332,16 +278,10 @@ int main(int argc, char *argv[]) switch (m.m_type) { - case DL_WRITEV: fxp_writev(&m, FALSE, TRUE); break; - case DL_WRITE: fxp_writev(&m, FALSE, FALSE); break; case DL_WRITEV_S: fxp_writev_s(&m, FALSE); break; - case DL_READ: fxp_readv(&m, FALSE, FALSE); break; - case DL_READV: fxp_readv(&m, FALSE, TRUE); break; case DL_READV_S: fxp_readv_s(&m, FALSE); break; case DL_CONF: fxp_init(&m); break; - case DL_GETSTAT: fxp_getstat(&m); break; case DL_GETSTAT_S: fxp_getstat_s(&m); break; - case DL_GETNAME: fxp_getname(&m); break; default: panic(" illegal message: %d", m.m_type); } @@ -375,28 +315,22 @@ PRIVATE void sef_local_startup() PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) { /* Initialize the fxp driver. */ - int r; long v; + int r; vir_bytes ft; - ft = sizeof(*fxp_table)*FXP_PORT_NR; system_hz = sys_hz(); - if (env_argc < 1) - panic("A head which at this time has no name"); - (progname=strrchr(env_argv[0],'/')) ? progname++ - : (progname=env_argv[0]); + v = 0; + (void) env_parse("instance", "d", 0, &v, 0, 255); + fxp_instance = (int) v; - v= 0; -#if 0 - (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL); -#endif - eth_ign_proto= htons((u16_t) v); + ft = sizeof(*fxp_state); - if(!(fxp_table = alloc_contig(ft, 0, &fxp_table_phys))) + if(!(fxp_state = alloc_contig(ft, 0, NULL))) panic("couldn't allocate table: %d", ENOMEM); - memset(fxp_table, 0, ft); + memset(fxp_state, 0, ft); if((r=tsc_calibrate()) != OK) panic("tsc_calibrate failed: %d", r); @@ -412,19 +346,15 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) *===========================================================================*/ PRIVATE void sef_cb_signal_handler(int signo) { - int i; port_t port; fxp_t *fp; /* Only check for termination signal, ignore anything else. */ if (signo != SIGTERM) return; - for (i= 0, fp= &fxp_table[0]; ifxp_mode != FM_ENABLED) - continue; - if (!(fp->fxp_flags & FF_ENABLED)) - continue; + fp= fxp_state; + + if (fp->fxp_mode == FM_ENABLED && (fp->fxp_flags & FF_ENABLED)) { port= fp->fxp_base_port; /* Reset device */ @@ -432,6 +362,7 @@ PRIVATE void sef_cb_signal_handler(int signo) printf("%s: resetting device\n", fp->fxp_name); fxp_outl(port, CSR_PORT, CP_CMD_SOFT_RESET); } + exit(0); } @@ -443,7 +374,6 @@ message *mp; { static int first_time= 1; - int port; fxp_t *fp; message reply_mess; @@ -457,15 +387,7 @@ message *mp; fxp_set_timer(&fxp_watchdog, system_hz, fxp_watchdog_f); } - port = mp->DL_PORT; - if (port < 0 || port >= FXP_PORT_NR) - { - reply_mess.m_type= DL_CONF_REPLY; - reply_mess.m3_i1= ENXIO; - mess_reply(mp, &reply_mess); - return; - } - fp= &fxp_table[port]; + fp= fxp_state; if (fp->fxp_mode == FM_DISABLED) { /* This is the default, try to (re)locate the device. */ @@ -474,7 +396,7 @@ message *mp; { /* Probe failed, or the device is configured off. */ reply_mess.m_type= DL_CONF_REPLY; - reply_mess.m3_i1= ENXIO; + reply_mess.DL_STAT= ENXIO; mess_reply(mp, &reply_mess); return; } @@ -495,13 +417,11 @@ message *mp; if (mp->DL_MODE & DL_BROAD_REQ) fp->fxp_flags |= FF_BROAD; - fp->fxp_client = mp->m_source; fxp_rec_mode(fp); reply_mess.m_type = DL_CONF_REPLY; - reply_mess.m3_i1 = mp->DL_PORT; - reply_mess.m3_i2 = FXP_PORT_NR; - *(ether_addr_t *) reply_mess.m3_ca1 = fp->fxp_address; + reply_mess.DL_STAT = OK; + *(ether_addr_t *) reply_mess.DL_HWADDR = fp->fxp_address; mess_reply(mp, &reply_mess); } @@ -514,63 +434,51 @@ static void fxp_pci_conf() static char envvar[] = FXP_ENVVAR "#"; static char envfmt[] = "*:d.d.d"; - int i, h; fxp_t *fp; long v; - for (i= 0, fp= fxp_table; ifxp_name, "fxp#0"); - fp->fxp_name[4] += i; - fp->fxp_seen= FALSE; - fp->fxp_features= FFE_NONE; - envvar[sizeof(FXP_ENVVAR)-1]= '0'+i; + fp= fxp_state; + + strcpy(fp->fxp_name, "fxp#0"); + fp->fxp_name[4] += fxp_instance; + fp->fxp_seen= FALSE; + fp->fxp_features= FFE_NONE; + envvar[sizeof(FXP_ENVVAR)-1]= '0'+fxp_instance; #if 0 - if (getenv(envvar) != NULL) + if (getenv(envvar) != NULL) + { + if (strcmp(getenv(envvar), "off") == 0) { - if (strcmp(getenv(envvar), "off") == 0) - { - fp->fxp_pcibus= 255; - continue; - } - if (!env_prefix(envvar, "pci")) - env_panic(envvar); + fp->fxp_pcibus= 255; } + if (!env_prefix(envvar, "pci")) + env_panic(envvar); + } #endif - v= 0; + pci_init(); + + if (fp->fxp_pcibus == 255) + return; + + v= 0; #if 0 - (void) env_parse(envvar, envfmt, 1, &v, 0, 255); + (void) env_parse(envvar, envfmt, 1, &v, 0, 255); #endif - fp->fxp_pcibus= v; - v= 0; + fp->fxp_pcibus= v; + v= 0; #if 0 - (void) env_parse(envvar, envfmt, 2, &v, 0, 255); + (void) env_parse(envvar, envfmt, 2, &v, 0, 255); #endif - fp->fxp_pcidev= v; - v= 0; + fp->fxp_pcidev= v; + v= 0; #if 0 - (void) env_parse(envvar, envfmt, 3, &v, 0, 255); + (void) env_parse(envvar, envfmt, 3, &v, 0, 255); #endif - fp->fxp_pcifunc= v; - } - - pci_init(); + fp->fxp_pcifunc= v; - for (h= 1; h >= 0; h--) { - for (i= 0, fp= fxp_table; ifxp_pcibus == 255) - continue; - if (((fp->fxp_pcibus | fp->fxp_pcidev | - fp->fxp_pcifunc) != 0) != h) - { - continue; - } - if (fxp_probe(fp, i)) - fp->fxp_seen= TRUE; - } - } + if (fxp_probe(fp, fxp_instance)) + fp->fxp_seen= TRUE; } /*===========================================================================* @@ -1051,7 +959,7 @@ static void fxp_confaddr(fxp_t *fp) long v; /* User defined ethernet address? */ - eakey[sizeof(FXP_ENVVAR)-1]= '0' + (fp-fxp_table); + eakey[sizeof(FXP_ENVVAR)-1]= '0' + fxp_instance; for (i= 0; i < 6; i++) { @@ -1139,183 +1047,25 @@ fxp_t *fp; } } -/*===========================================================================* - * fxp_writev * - *===========================================================================*/ -static void fxp_writev(mp, from_int, vectored) -message *mp; -int from_int; -int vectored; -{ - vir_bytes iov_src; - int i, j, n, o, r, s, dl_port, count, size, prev_head; - int fxp_client, fxp_tx_nbuf, fxp_tx_head; - u16_t tx_command; - fxp_t *fp; - iovec_t *iovp; - struct tx *txp, *prev_txp; - - dl_port = mp->DL_PORT; - count = mp->DL_COUNT; - if (dl_port < 0 || dl_port >= FXP_PORT_NR) - panic("fxp_writev: illegal port: %d", dl_port); - fp= &fxp_table[dl_port]; - fxp_client= mp->DL_PROC; - fp->fxp_client= fxp_client; - - assert(fp->fxp_mode == FM_ENABLED); - assert(fp->fxp_flags & FF_ENABLED); - - if (from_int) - { - assert(fp->fxp_flags & FF_SEND_AVAIL); - fp->fxp_flags &= ~FF_SEND_AVAIL; - fp->fxp_tx_alive= TRUE; - } - - if (fp->fxp_tx_idle) - { - txp= fp->fxp_tx_buf; - fxp_tx_head= 0; /* lint */ - prev_txp= NULL; /* lint */ - } - else - { - fxp_tx_nbuf= fp->fxp_tx_nbuf; - prev_head= fp->fxp_tx_head; - fxp_tx_head= prev_head+1; - if (fxp_tx_head == fxp_tx_nbuf) - fxp_tx_head= 0; - assert(fxp_tx_head < fxp_tx_nbuf); - - if (fxp_tx_head == fp->fxp_tx_tail) - { - /* Send queue is full */ - assert(!(fp->fxp_flags & FF_SEND_AVAIL)); - fp->fxp_flags |= FF_SEND_AVAIL; - goto suspend; - } - - prev_txp= &fp->fxp_tx_buf[prev_head]; - txp= &fp->fxp_tx_buf[fxp_tx_head]; - } - - assert(!(fp->fxp_flags & FF_SEND_AVAIL)); - assert(!(fp->fxp_flags & FF_PACK_SENT)); - - if (vectored) - { - - iov_src = (vir_bytes)mp->DL_ADDR; - - size= 0; - o= 0; - for (i= 0; ifxp_iovec[0])) - { - n= IOVEC_NR; - if (i+n > count) - n= count-i; - r= sys_vircopy(fxp_client, D, iov_src, - SELF, D, (vir_bytes)fp->fxp_iovec, - n * sizeof(fp->fxp_iovec[0])); - if (r != OK) - panic("fxp_writev: sys_vircopy failed: %d", r); - - for (j= 0, iovp= fp->fxp_iovec; jiov_size; - if (size + s > ETH_MAX_PACK_SIZE_TAGGED) { - panic("fxp_writev: invalid packet size"); - } - - r= sys_vircopy(fxp_client, D, iovp->iov_addr, - SELF, D, (vir_bytes)(txp->tx_buf+o), - s); - if (r != OK) { - panic("fxp_writev: sys_vircopy failed: %d", r); - } - size += s; - o += s; - } - } - if (size < ETH_MIN_PACK_SIZE) - panic("fxp_writev: invalid packet size: %d", size); - } - else - { - size= mp->DL_COUNT; - if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED) - panic("fxp_writev: invalid packet size: %d", size); - - r= sys_vircopy(fxp_client, D, (vir_bytes)mp->DL_ADDR, - SELF, D, (vir_bytes)txp->tx_buf, size); - if (r != OK) - panic("fxp_writev: sys_vircopy failed: %d", r); - } - - txp->tx_status= 0; - txp->tx_command= TXC_EL | CBL_XMIT; - txp->tx_tbda= TX_TBDA_NIL; - txp->tx_size= TXSZ_EOF | size; - txp->tx_tthresh= fp->fxp_tx_threshold; - txp->tx_ntbd= 0; - if (fp->fxp_tx_idle) - { - fp->fxp_tx_idle= 0; - fp->fxp_tx_head= fp->fxp_tx_tail= 0; - - fxp_cu_ptr_cmd(fp, SC_CU_START, fp->fxp_tx_busaddr, - TRUE /* check idle */); - } - else - { - /* Link new request in transmit list */ - tx_command= prev_txp->tx_command; - assert(tx_command == (TXC_EL | CBL_XMIT)); - prev_txp->tx_command= CBL_XMIT; - fp->fxp_tx_head= fxp_tx_head; - } - - fp->fxp_flags |= FF_PACK_SENT; - - /* If the interrupt handler called, don't send a reply. The reply - * will be sent after all interrupts are handled. - */ - if (from_int) - return; - reply(fp, OK, FALSE); - return; - -suspend: - if (from_int) - panic("fxp: should not be sending"); - - fp->fxp_tx_mess= *mp; - reply(fp, OK, FALSE); -} - /*===========================================================================* * fxp_writev_s * *===========================================================================*/ static void fxp_writev_s(const message *mp, int from_int) { + endpoint_t iov_endpt; cp_grant_id_t iov_grant; vir_bytes iov_offset; - int i, j, n, o, r, s, dl_port, count, size, prev_head; - int fxp_client, fxp_tx_nbuf, fxp_tx_head; + int i, j, n, o, r, s, count, size, prev_head; + int fxp_tx_nbuf, fxp_tx_head; u16_t tx_command; fxp_t *fp; iovec_s_t *iovp; struct tx *txp, *prev_txp; - dl_port = mp->DL_PORT; + fp= fxp_state; + count = mp->DL_COUNT; - if (dl_port < 0 || dl_port >= FXP_PORT_NR) - panic("fxp_writev: illegal port: %d", dl_port); - fp= &fxp_table[dl_port]; - fxp_client= mp->DL_PROC; - fp->fxp_client= fxp_client; + fp->fxp_client= mp->m_source; assert(fp->fxp_mode == FM_ENABLED); assert(fp->fxp_flags & FF_ENABLED); @@ -1357,6 +1107,7 @@ static void fxp_writev_s(const message *mp, int from_int) assert(!(fp->fxp_flags & FF_SEND_AVAIL)); assert(!(fp->fxp_flags & FF_PACK_SENT)); + iov_endpt= mp->DL_ENDPT; iov_grant= mp->DL_GRANT; size= 0; @@ -1368,7 +1119,7 @@ static void fxp_writev_s(const message *mp, int from_int) n= IOVEC_NR; if (i+n > count) n= count-i; - r= sys_safecopyfrom(fxp_client, iov_grant, iov_offset, + r= sys_safecopyfrom(iov_endpt, iov_grant, iov_offset, (vir_bytes)fp->fxp_iovec_s, n * sizeof(fp->fxp_iovec_s[0]), D); if (r != OK) @@ -1381,7 +1132,7 @@ static void fxp_writev_s(const message *mp, int from_int) panic("fxp_writev: invalid packet size: %d", size + s); } - r= sys_safecopyfrom(fxp_client, iovp->iov_grant, + r= sys_safecopyfrom(iov_endpt, iovp->iov_grant, 0, (vir_bytes)(txp->tx_buf+o), s, D); if (r != OK) { panic("fxp_writev_s: sys_safecopyfrom failed: %d", r); @@ -1423,7 +1174,7 @@ static void fxp_writev_s(const message *mp, int from_int) */ if (from_int) return; - reply(fp, OK, FALSE); + reply(fp); return; suspend: @@ -1431,185 +1182,7 @@ suspend: panic("fxp: should not be sending"); fp->fxp_tx_mess= *mp; - reply(fp, OK, FALSE); -} - -/*===========================================================================* - * fxp_readv * - *===========================================================================*/ -static void fxp_readv(mp, from_int, vectored) -message *mp; -int from_int; -int vectored; -{ - int i, j, n, o, r, s, dl_port, fxp_client, count, size, - fxp_rx_head, fxp_rx_nbuf; - port_t port; - unsigned packlen; - vir_bytes iov_src; - u16_t rfd_status; - u16_t rfd_res; - u8_t scb_status; - fxp_t *fp; - iovec_t *iovp; - struct rfd *rfdp, *prev_rfdp; - - dl_port = mp->DL_PORT; - count = mp->DL_COUNT; - if (dl_port < 0 || dl_port >= FXP_PORT_NR) - panic("fxp_readv: illegal port: %d", dl_port); - fp= &fxp_table[dl_port]; - fxp_client= mp->DL_PROC; - fp->fxp_client= fxp_client; - - assert(fp->fxp_mode == FM_ENABLED); - assert(fp->fxp_flags & FF_ENABLED); - - port= fp->fxp_base_port; - - fxp_rx_head= fp->fxp_rx_head; - rfdp= &fp->fxp_rx_buf[fxp_rx_head]; - - rfd_status= rfdp->rfd_status; - if (!(rfd_status & RFDS_C)) - { - /* Receive buffer is empty, suspend */ - goto suspend; - } - - if (!(rfd_status & RFDS_OK)) - { - /* Not OK? What happened? */ - assert(0); - } - else - { - assert(!(rfd_status & (RFDS_CRCERR | RFDS_ALIGNERR | - RFDS_OUTOFBUF | RFDS_DMAOVR | RFDS_TOOSHORT | - RFDS_RXERR))); - } - rfd_res= rfdp->rfd_res; - assert(rfd_res & RFDR_EOF); - assert(rfd_res & RFDR_F); - - packlen= rfd_res & RFDSZ_SIZE; - - if (vectored) - { - iov_src = (vir_bytes)mp->DL_ADDR; - - size= 0; - o= 0; - for (i= 0; ifxp_iovec[0])) - { - n= IOVEC_NR; - if (i+n > count) - n= count-i; - r= sys_vircopy(fxp_client, D, iov_src, - SELF, D, (vir_bytes)fp->fxp_iovec, - n * sizeof(fp->fxp_iovec[0])); - if (r != OK) - panic("fxp_readv: sys_vircopy failed: %d", r); - - for (j= 0, iovp= fp->fxp_iovec; jiov_size; - if (size + s > packlen) - { - assert(packlen > size); - s= packlen-size; - } - - r= sys_vircopy(SELF, D, - (vir_bytes)(rfdp->rfd_buf+o), - fxp_client, D, iovp->iov_addr, s); - if (r != OK) { - panic("fxp_readv: sys_vircopy failed: %d", r); - } - - size += s; - if (size == packlen) - break; - o += s; - } - if (size == packlen) - break; - } - if (size < packlen) - { - assert(0); - } - } - else - { - assert(0); - } - - fp->fxp_read_s= packlen; - fp->fxp_flags= (fp->fxp_flags & ~FF_READING) | FF_PACK_RECV; - - /* Re-init the current buffer */ - rfdp->rfd_status= 0; - rfdp->rfd_command= RFDC_EL; - rfdp->rfd_reserved= 0; - rfdp->rfd_res= 0; - rfdp->rfd_size= sizeof(rfdp->rfd_buf); - - fxp_rx_nbuf= fp->fxp_rx_nbuf; - if (fxp_rx_head == 0) - { - prev_rfdp= &fp->fxp_rx_buf[fxp_rx_nbuf-1]; - } - else - prev_rfdp= &rfdp[-1]; - - assert(prev_rfdp->rfd_command & RFDC_EL); - prev_rfdp->rfd_command &= ~RFDC_EL; - - fxp_rx_head++; - if (fxp_rx_head == fxp_rx_nbuf) - fxp_rx_head= 0; - assert(fxp_rx_head < fxp_rx_nbuf); - fp->fxp_rx_head= fxp_rx_head; - - if (!from_int) - reply(fp, OK, FALSE); - - return; - -suspend: - if (fp->fxp_rx_need_restart) - { - fp->fxp_rx_need_restart= 0; - - /* Check the status of the RU */ - scb_status= fxp_inb(port, SCB_STATUS); - if ((scb_status & SS_RUS_MASK) != SS_RU_NORES) - { - /* Race condition? */ - printf("fxp_readv: restart race: 0x%x\n", - scb_status); - assert((scb_status & SS_RUS_MASK) == SS_RU_READY); - } - else - { - fxp_restart_ru(fp); - } - } - if (from_int) - { - assert(fp->fxp_flags & FF_READING); - - /* No need to store any state */ - return; - } - - fp->fxp_rx_mess= *mp; - assert(!(fp->fxp_flags & FF_READING)); - fp->fxp_flags |= FF_READING; - - reply(fp, OK, FALSE); + reply(fp); } /*===========================================================================* @@ -1619,8 +1192,8 @@ static void fxp_readv_s(mp, from_int) message *mp; int from_int; { - int i, j, n, o, r, s, dl_port, fxp_client, count, size, - fxp_rx_head, fxp_rx_nbuf; + int i, j, n, o, r, s, count, size, fxp_rx_head, fxp_rx_nbuf; + endpoint_t iov_endpt; cp_grant_id_t iov_grant; port_t port; unsigned packlen; @@ -1632,13 +1205,10 @@ int from_int; iovec_s_t *iovp; struct rfd *rfdp, *prev_rfdp; - dl_port = mp->DL_PORT; + fp= fxp_state; + count = mp->DL_COUNT; - if (dl_port < 0 || dl_port >= FXP_PORT_NR) - panic("fxp_readv: illegal port: %d", dl_port); - fp= &fxp_table[dl_port]; - fxp_client= mp->DL_PROC; - fp->fxp_client= fxp_client; + fp->fxp_client= mp->m_source; assert(fp->fxp_mode == FM_ENABLED); assert(fp->fxp_flags & FF_ENABLED); @@ -1672,6 +1242,7 @@ int from_int; packlen= rfd_res & RFDSZ_SIZE; + iov_endpt = mp->DL_ENDPT; iov_grant = mp->DL_GRANT; size= 0; @@ -1683,7 +1254,7 @@ int from_int; n= IOVEC_NR; if (i+n > count) n= count-i; - r= sys_safecopyfrom(fxp_client, iov_grant, iov_offset, + r= sys_safecopyfrom(iov_endpt, iov_grant, iov_offset, (vir_bytes)fp->fxp_iovec_s, n * sizeof(fp->fxp_iovec_s[0]), D); if (r != OK) @@ -1698,7 +1269,7 @@ int from_int; s= packlen-size; } - r= sys_safecopyto(fxp_client, iovp->iov_grant, + r= sys_safecopyto(iov_endpt, iovp->iov_grant, 0, (vir_bytes)(rfdp->rfd_buf+o), s, D); if (r != OK) { @@ -1746,7 +1317,7 @@ int from_int; fp->fxp_rx_head= fxp_rx_head; if (!from_int) - reply(fp, OK, FALSE); + reply(fp); return; @@ -1781,7 +1352,7 @@ suspend: assert(!(fp->fxp_flags & FF_READING)); fp->fxp_flags |= FF_READING; - reply(fp, OK, FALSE); + reply(fp); } /*===========================================================================* @@ -1932,103 +1503,18 @@ fxp_t *fp; FALSE /* do not check idle */); } -/*===========================================================================* - * fxp_getstat * - *===========================================================================*/ -static void fxp_getstat(mp) -message *mp; -{ - clock_t t0,t1; - int r, dl_port; - fxp_t *fp; - u32_t *p; - eth_stat_t stats; - - dl_port = mp->DL_PORT; - if (dl_port < 0 || dl_port >= FXP_PORT_NR) - panic("fxp_getstat: illegal port: %d", dl_port); - fp= &fxp_table[dl_port]; - fp->fxp_client= mp->DL_PROC; - - assert(fp->fxp_mode == FM_ENABLED); - assert(fp->fxp_flags & FF_ENABLED); - - p= &fp->fxp_stat.sc_tx_fcp; - *p= 0; - - /* The dump commmand doesn't take a pointer. Setting a pointer - * doesn't hard though. - */ - fxp_cu_ptr_cmd(fp, SC_CU_DUMP_SC, 0, FALSE /* do not check idle */); - - getuptime(&t0); - do { - /* Wait for CU command to complete */ - if (*p != 0) - break; - } while (getuptime(&t1)==OK && (t1-t0) < micros_to_ticks(1000)); - - if (*p == 0) - panic("fxp_getstat: CU command failed to complete"); - if (*p != SCM_DSC) - panic("fxp_getstat: bad magic"); - - stats.ets_recvErr= - fp->fxp_stat.sc_rx_crc + - fp->fxp_stat.sc_rx_align + - fp->fxp_stat.sc_rx_resource + - fp->fxp_stat.sc_rx_overrun + - fp->fxp_stat.sc_rx_cd + - fp->fxp_stat.sc_rx_short; - stats.ets_sendErr= - fp->fxp_stat.sc_tx_maxcol + - fp->fxp_stat.sc_tx_latecol + - fp->fxp_stat.sc_tx_crs; - stats.ets_OVW= fp->fxp_stat.sc_rx_overrun; - stats.ets_CRCerr= fp->fxp_stat.sc_rx_crc; - stats.ets_frameAll= fp->fxp_stat.sc_rx_align; - stats.ets_missedP= fp->fxp_stat.sc_rx_resource; - stats.ets_packetR= fp->fxp_stat.sc_rx_good; - stats.ets_packetT= fp->fxp_stat.sc_tx_good; - stats.ets_transDef= fp->fxp_stat.sc_tx_defered; - stats.ets_collision= fp->fxp_stat.sc_tx_totcol; - stats.ets_transAb= fp->fxp_stat.sc_tx_maxcol; - stats.ets_carrSense= fp->fxp_stat.sc_tx_crs; - stats.ets_fifoUnder= fp->fxp_stat.sc_tx_underrun; - stats.ets_fifoOver= fp->fxp_stat.sc_rx_overrun; - stats.ets_CDheartbeat= 0; - stats.ets_OWC= fp->fxp_stat.sc_tx_latecol; - - r= sys_vircopy(SELF, D, (vir_bytes)&stats, - mp->DL_PROC, D, (vir_bytes) mp->DL_ADDR, sizeof(stats)); - if (r != OK) - panic("fxp_getstat: sys_vircopy failed: %d", r); - - mp->m_type= DL_STAT_REPLY; - mp->DL_PORT= dl_port; - mp->DL_STAT= OK; - r= send(mp->m_source, mp); - if (r != OK) - panic("fxp_getstat: send failed: %d", r); -} - - /*===========================================================================* * fxp_getstat_s * *===========================================================================*/ static void fxp_getstat_s(message *mp) { clock_t t0,t1; - int r, dl_port; + int r; fxp_t *fp; u32_t *p; eth_stat_t stats; - dl_port = mp->DL_PORT; - if (dl_port < 0 || dl_port >= FXP_PORT_NR) - panic("fxp_getstat: illegal port: %d", dl_port); - fp= &fxp_table[dl_port]; - fp->fxp_client= mp->DL_PROC; + fp= fxp_state; assert(fp->fxp_mode == FM_ENABLED); assert(fp->fxp_flags & FF_ENABLED); @@ -2079,35 +1565,17 @@ static void fxp_getstat_s(message *mp) stats.ets_CDheartbeat= 0; stats.ets_OWC= fp->fxp_stat.sc_tx_latecol; - r= sys_safecopyto(mp->DL_PROC, mp->DL_GRANT, 0, (vir_bytes)&stats, + r= sys_safecopyto(mp->DL_ENDPT, mp->DL_GRANT, 0, (vir_bytes)&stats, sizeof(stats), D); if (r != OK) panic("fxp_getstat_s: sys_safecopyto failed: %d", r); mp->m_type= DL_STAT_REPLY; - mp->DL_PORT= dl_port; - mp->DL_STAT= OK; r= send(mp->m_source, mp); if (r != OK) panic("fxp_getstat_s: send failed: %d", r); } - -/*===========================================================================* - * fxp_getname * - *===========================================================================*/ -static void fxp_getname(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("fxp_getname: send failed: %d", r); -} - /*===========================================================================* * fxp_handler * *===========================================================================*/ @@ -2182,21 +1650,9 @@ static void fxp_check_ints(fxp_t *fp) { if (!(fp->fxp_rx_buf[fp->fxp_rx_head].rfd_status & RFDS_C)) ; /* Nothing */ - else if (fp->fxp_rx_mess.m_type == DL_READV) - { - fxp_readv(&fp->fxp_rx_mess, TRUE /* from int */, - TRUE /* vectored */); - } - else if (fp->fxp_rx_mess.m_type == DL_READV_S) - { - fxp_readv_s(&fp->fxp_rx_mess, TRUE /* from int */); - - } else { - assert(fp->fxp_rx_mess.m_type == DL_READ); - fxp_readv(&fp->fxp_rx_mess, TRUE /* from int */, - FALSE /* !vectored */); + fxp_readv_s(&fp->fxp_rx_mess, TRUE /* from int */); } } if (fp->fxp_tx_idle) @@ -2292,25 +1748,8 @@ static void fxp_check_ints(fxp_t *fp) if (fp->fxp_flags & FF_SEND_AVAIL) { - if (fp->fxp_tx_mess.m_type == DL_WRITEV) - { - fxp_writev(&fp->fxp_tx_mess, - TRUE /* from int */, - TRUE /* vectored */); - } - else if (fp->fxp_tx_mess.m_type == DL_WRITEV_S) - { - fxp_writev_s(&fp->fxp_tx_mess, - TRUE /* from int */); - } - else - { - assert(fp->fxp_tx_mess.m_type == - DL_WRITE); - fxp_writev(&fp->fxp_tx_mess, - TRUE /* from int */, - FALSE /* !vectored */); - } + fxp_writev_s(&fp->fxp_tx_mess, + TRUE /* from int */); } } @@ -2319,7 +1758,7 @@ static void fxp_check_ints(fxp_t *fp) fxp_report_link(fp); if (fp->fxp_flags & (FF_PACK_SENT | FF_PACK_RECV)) - reply(fp, OK, TRUE); + reply(fp); } /*===========================================================================* @@ -2328,48 +1767,45 @@ static void fxp_check_ints(fxp_t *fp) static void fxp_watchdog_f(tp) timer_t *tp; { - int i; fxp_t *fp; tmr_arg(&fxp_watchdog)->ta_int= 0; fxp_set_timer(&fxp_watchdog, system_hz, fxp_watchdog_f); - for (i= 0, fp = &fxp_table[0]; ifxp_mode != FM_ENABLED) - continue; + fp= fxp_state; + if (fp->fxp_mode != FM_ENABLED) + return; - /* Handle race condition, MII interface mgith be busy */ - if(!fp->fxp_mii_busy) + /* Handle race condition, MII interface might be busy */ + if(!fp->fxp_mii_busy) + { + /* Check the link status. */ + if (fxp_link_changed(fp)) { - /* Check the link status. */ - if (fxp_link_changed(fp)) - { #if VERBOSE - printf("fxp_watchdog_f: link changed\n"); + printf("fxp_watchdog_f: link changed\n"); #endif - fp->fxp_report_link= TRUE; - fp->fxp_got_int= TRUE; - interrupt(fxp_tasknr); - } + fp->fxp_report_link= TRUE; + fp->fxp_got_int= TRUE; + interrupt(fxp_tasknr); } + } - if (!(fp->fxp_flags & FF_SEND_AVAIL)) - { - /* Assume that an idle system is alive */ - fp->fxp_tx_alive= TRUE; - continue; - } - if (fp->fxp_tx_alive) - { - fp->fxp_tx_alive= FALSE; - continue; - } - - fp->fxp_need_reset= TRUE; - fp->fxp_got_int= TRUE; - interrupt(fxp_tasknr); + if (!(fp->fxp_flags & FF_SEND_AVAIL)) + { + /* Assume that an idle system is alive */ + fp->fxp_tx_alive= TRUE; + return; + } + if (fp->fxp_tx_alive) + { + fp->fxp_tx_alive= FALSE; + return; } + + fp->fxp_need_reset= TRUE; + fp->fxp_got_int= TRUE; + interrupt(fxp_tasknr); } /*===========================================================================* @@ -2410,7 +1846,7 @@ static void fxp_report_link(fxp_t *fp) fp->fxp_mii_scr= scr; mii_ctrl= mii_read(fp, MII_CTRL); - mii_read(fp, MII_STATUS); /* Read the status register twice, why? */ + mii_read(fp, MII_STATUS); /* The status reg is latched, read twice */ mii_status= mii_read(fp, MII_STATUS); mii_id1= mii_read(fp, MII_PHYID_H); mii_id2= mii_read(fp, MII_PHYID_L); @@ -2630,42 +2066,25 @@ resspeed: /*===========================================================================* * reply * *===========================================================================*/ -static void reply(fp, err, may_block) +static void reply(fp) fxp_t *fp; -int err; -int may_block; { message reply; - int status; + int flags; int r; - status = 0; + flags = DL_NOFLAGS; if (fp->fxp_flags & FF_PACK_SENT) - status |= DL_PACK_SEND; + flags |= DL_PACK_SEND; if (fp->fxp_flags & FF_PACK_RECV) - status |= DL_PACK_RECV; + flags |= DL_PACK_RECV; reply.m_type = DL_TASK_REPLY; - reply.DL_PORT = fp - fxp_table; - reply.DL_PROC = fp->fxp_client; - reply.DL_STAT = status | ((u32_t) err << 16); + reply.DL_FLAGS = flags; reply.DL_COUNT = fp->fxp_read_s; -#if 0 - reply.DL_CLCK = get_uptime(); -#else - reply.DL_CLCK = 0; -#endif r= send(fp->fxp_client, &reply); - if (r == ELOCKED && may_block) - { -#if 0 - printW(); printf("send locked\n"); -#endif - return; - } - if (r < 0) panic("fxp: send failed: %d", r); diff --git a/drivers/lance/lance.c b/drivers/lance/lance.c index 2ad63d23c..4af5a7c2e 100644 --- a/drivers/lance/lance.c +++ b/drivers/lance/lance.c @@ -6,32 +6,35 @@ * * The valid messages and their parameters are: * - * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR DL_GRANT - * |------------+----------+---------+----------+---------+---------+---------| - * | HARDINT | | | | | | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_WRITEV_S| port nr | proc nr | count | mode | | grant | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_READV_S | port nr | proc nr | count | | | grant | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_CONF | port nr | proc nr | | mode | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * |DL_GETSTAT_S| port nr | proc nr | | | | grant | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_STOP | port_nr | | | | | | - * |------------|----------|---------|----------|---------|---------|---------| + * m_type DL_ENDPT DL_COUNT DL_MODE DL_GRANT + * |--------------+---------+----------+---------+---------| + * | DL_WRITEV_S | endpt | count | | grant | + * |--------------|---------|----------|---------|---------| + * | DL_READV_S | endpt | count | | grant | + * |--------------|---------|----------|---------|---------| + * | DL_CONF | | | mode | | + * |--------------|---------|----------|---------|---------| + * | DL_GETSTAT_S | endpt | | | grant | + * |--------------|---------|----------|---------|---------| + * | hardware int | | | | | + * |--------------|---------|----------|---------|---------| * * The messages sent are: * - * m-type DL_POR T DL_PROC DL_COUNT DL_STAT DL_CLCK - * |------------|----------|---------|----------|---------|---------| - * |DL_TASK_REPL| port nr | proc nr | rd-count | err|stat| clock | - * |------------|----------|---------|----------|---------|---------| + * m_type DL_COUNT DL_FLAGS + * |---------------+----------+---------| + * | DL_TASK_REPLY | rd-count | flags | + * |---------------|----------|---------| * - * m_type m3_i1 m3_i2 m3_ca1 - * |------------+---------+-----------+---------------| - * |DL_CONF_REPL| port nr | last port | ethernet addr | - * |------------|---------|-----------|---------------| + * m_type + * |---------------| + * | DL_STAT_REPLY | + * |---------------| + * + * m_type DL_STAT DL_ADDR + * |---------------+---------+---------------| + * | DL_CONF_REPLY | code | ethernet addr | + * |---------------|---------|---------------| * * Created: Jul 27, 2002 by Kazuya Kodama * Adapted for Minix 3: Sep 05, 2005 by Joren l'Ami @@ -55,9 +58,8 @@ #include "lance.h" -static ether_card_t ec_table[EC_PORT_NR_MAX]; -static int eth_tasknr= ANY; -static u16_t eth_ign_proto; +static ether_card_t ec_state; +static int ec_instance; /* Configuration */ typedef struct ec_conf @@ -65,15 +67,16 @@ typedef struct ec_conf port_t ec_port; int ec_irq; phys_bytes ec_mem; - char *ec_envvar; } ec_conf_t; /* We hardly use these. Just "LANCE0=on/off" "LANCE1=on/off" mean. */ -ec_conf_t ec_conf[]= /* Card addresses */ +#define EC_CONF_NR 3 +ec_conf_t ec_conf[EC_CONF_NR]= /* Card addresses */ { - /* I/O port, IRQ, Buffer address, Env. var, Buf selector. */ - { 0x1000, 9, 0x00000, "LANCE0" }, - { 0xD000, 15, 0x00000, "LANCE1" }, + /* I/O port, IRQ, Buffer address. */ + { 0x1000, 9, 0x00000, }, + { 0xD000, 15, 0x00000, }, + { 0x0000, 0, 0x00000, }, }; /* Actually, we use PCI-BIOS info. */ @@ -99,14 +102,12 @@ _PROTOTYPE( static void conf_hw, (ether_card_t *ec) ); _PROTOTYPE( static void update_conf, (ether_card_t *ec, ec_conf_t *ecp) ); _PROTOTYPE( static void mess_reply, (message *req, message *reply) ); _PROTOTYPE( static void do_int, (ether_card_t *ec) ); -_PROTOTYPE( static void reply, - (ether_card_t *ec, int err, int may_block) ); +_PROTOTYPE( static void reply, (ether_card_t *ec) ); _PROTOTYPE( static void ec_reset, (ether_card_t *ec) ); _PROTOTYPE( static void ec_send, (ether_card_t *ec) ); _PROTOTYPE( static void ec_recv, (ether_card_t *ec) ); -_PROTOTYPE( static void do_vwrite_s, - (message *mp, int from_int) ); -_PROTOTYPE( static void do_vread_s, (const message *mp) ); +_PROTOTYPE( static void do_vwrite_s, (message *mp, int from_int) ); +_PROTOTYPE( static void do_vread_s, (const message *mp) ); _PROTOTYPE( static void ec_user2nic, (ether_card_t *dep, iovec_dat_t *iovp, vir_bytes offset, int nic_addr, @@ -118,10 +119,9 @@ _PROTOTYPE( static void ec_nic2user, _PROTOTYPE( static int calc_iovec_size, (iovec_dat_t *iovp) ); _PROTOTYPE( static void ec_next_iovec, (iovec_dat_t *iovp) ); _PROTOTYPE( static void do_getstat_s, (message *mp) ); -_PROTOTYPE( static void do_stop, (message *mp) ); -_PROTOTYPE( static void do_getname, (message *mp) ); +_PROTOTYPE( static void lance_stop, (ether_card_t *ec) ); -_PROTOTYPE( static void lance_dump, (void) ); +_PROTOTYPE( static void lance_dump, (void) ); _PROTOTYPE( static void getAddressing, (int devind, ether_card_t *ec) ); /* probe+init LANCE cards */ @@ -137,7 +137,7 @@ _PROTOTYPE( static void write_csr, (port_t ioaddr, u16_t csrno, u16_t value)); /* --- LANCE --- */ /* General */ -#define Address unsigned long +typedef unsigned long Address; #define virt_to_bus(x) (vir2phys((unsigned long)x)) unsigned long vir2phys( unsigned long x ) @@ -250,6 +250,7 @@ struct lance_interface }; /* =============== global variables =============== */ +/* AKA the stuff that really should have been in ether_card_t */ static struct lance_interface *lp; #define LANCE_BUF_SIZE (sizeof(struct lance_interface)) static char *lance_buf = NULL; @@ -257,7 +258,6 @@ static int rx_slot_nr = 0; /* Rx-slot number */ static int tx_slot_nr = 0; /* Tx-slot number */ static int cur_tx_slot_nr = 0; /* Tx-slot number */ static char isstored[TX_RING_SIZE]; /* Tx-slot in-use */ -static const char *progname; phys_bytes lance_buf_phys; @@ -270,35 +270,29 @@ EXTERN char **env_argv; /*===========================================================================* * main * *===========================================================================*/ -void main( int argc, char **argv ) +int main( int argc, char **argv ) { message m; int ipc_status; - int i,r; + int r; ether_card_t *ec; /* SEF local startup. */ env_setargs(argc, argv); sef_local_startup(); + ec= &ec_state; + while (TRUE) { - for (i=0;iec_irq != 0) - sys_irqenable(&ec->ec_hook); - } + if (ec->ec_irq != 0) + sys_irqenable(&ec->ec_hook); if ((r= netdriver_receive(ANY, &m, &ipc_status)) != OK) panic("netdriver_receive failed: %d", r); - for (i=0;iec_irq != 0) - sys_irqdisable(&ec->ec_hook); - } + if (ec->ec_irq != 0) + sys_irqdisable(&ec->ec_hook); if (is_ipc_notify(ipc_status)) { switch(_ENDPOINT_P(m.m_source)) { @@ -306,17 +300,11 @@ void main( int argc, char **argv ) lance_dump(); break; case HARDWARE: - for (i=0;imode == EC_ENABLED) { - ec= &ec_table[i]; - if (ec->mode != EC_ENABLED) - continue; - - { - ec->ec_int_pending = 0; - ec_check_ints(ec); - do_int(ec); - } + ec->ec_int_pending = 0; + ec_check_ints(ec); + do_int(ec); } break; default: @@ -341,16 +329,12 @@ void main( int argc, char **argv ) case DL_GETSTAT_S: do_getstat_s(&m); break; - case DL_STOP: - do_stop(&m); - break; - case DL_GETNAME: - do_getname(&m); - break; default: panic("illegal message: %d", m.m_type); } } + + return 0; } /*===========================================================================* @@ -380,14 +364,11 @@ PRIVATE void sef_local_startup() PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) { /* Initialize the lance driver. */ - int r; long v; #if LANCE_FKEY - int fkeys, sfkeys; + int r, fkeys, sfkeys; #endif - (progname=strrchr(env_argv[0],'/')) ? progname++ : (progname=env_argv[0]); - #if LANCE_FKEY fkeys = sfkeys = 0; bit_set( sfkeys, 7 ); @@ -395,12 +376,12 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) printf("Warning: lance couldn't observe Shift+F7 key: %d\n",r); #endif - v= 0; - (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL); - eth_ign_proto= htons((u16_t) v); + v = 0; + (void) env_parse("instance", "d", 0, &v, 0, 255); + ec_instance = (int) v; - /* Announce we are up! */ - netdriver_announce(); + /* Announce we are up! */ + netdriver_announce(); return OK; } @@ -410,20 +391,12 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) *===========================================================================*/ PRIVATE void sef_cb_signal_handler(int signo) { - message mess; - int i; /* Only check for termination signal, ignore anything else. */ if (signo != SIGTERM) return; - for (i= 0; imode == EC_DISABLED) - printf("lance port %d is disabled\n", i); - else if (ec->mode == EC_SINK) - printf("lance port %d is in sink mode\n", i); - - if (ec->mode != EC_ENABLED) - continue; + ec = &ec_state; + if (ec->mode == EC_DISABLED) + printf("lance instance %d is disabled\n", ec_instance); + else if (ec->mode == EC_SINK) + printf("lance instance %d is in sink mode\n", ec_instance); + + if (ec->mode != EC_ENABLED) + return; - printf("lance statistics of port %d:\n", i); + printf("lance statistics of instance %d:\n", ec_instance); - printf("recvErr :%8ld\t", ec->eth_stat.ets_recvErr); - printf("sendErr :%8ld\t", ec->eth_stat.ets_sendErr); - printf("OVW :%8ld\n", ec->eth_stat.ets_OVW); + printf("recvErr :%8ld\t", ec->eth_stat.ets_recvErr); + printf("sendErr :%8ld\t", ec->eth_stat.ets_sendErr); + printf("OVW :%8ld\n", ec->eth_stat.ets_OVW); - printf("CRCerr :%8ld\t", ec->eth_stat.ets_CRCerr); - printf("frameAll :%8ld\t", ec->eth_stat.ets_frameAll); - printf("missedP :%8ld\n", ec->eth_stat.ets_missedP); + printf("CRCerr :%8ld\t", ec->eth_stat.ets_CRCerr); + printf("frameAll :%8ld\t", ec->eth_stat.ets_frameAll); + printf("missedP :%8ld\n", ec->eth_stat.ets_missedP); - printf("packetR :%8ld\t", ec->eth_stat.ets_packetR); - printf("packetT :%8ld\t", ec->eth_stat.ets_packetT); - printf("transDef :%8ld\n", ec->eth_stat.ets_transDef); + printf("packetR :%8ld\t", ec->eth_stat.ets_packetR); + printf("packetT :%8ld\t", ec->eth_stat.ets_packetT); + printf("transDef :%8ld\n", ec->eth_stat.ets_transDef); - printf("collision :%8ld\t", ec->eth_stat.ets_collision); - printf("transAb :%8ld\t", ec->eth_stat.ets_transAb); - printf("carrSense :%8ld\n", ec->eth_stat.ets_carrSense); + printf("collision :%8ld\t", ec->eth_stat.ets_collision); + printf("transAb :%8ld\t", ec->eth_stat.ets_transAb); + printf("carrSense :%8ld\n", ec->eth_stat.ets_carrSense); - printf("fifoUnder :%8ld\t", ec->eth_stat.ets_fifoUnder); - printf("fifoOver :%8ld\t", ec->eth_stat.ets_fifoOver); - printf("CDheartbeat:%8ld\n", ec->eth_stat.ets_CDheartbeat); + printf("fifoUnder :%8ld\t", ec->eth_stat.ets_fifoUnder); + printf("fifoOver :%8ld\t", ec->eth_stat.ets_fifoOver); + printf("CDheartbeat:%8ld\n", ec->eth_stat.ets_CDheartbeat); - printf("OWC :%8ld\t", ec->eth_stat.ets_OWC); + printf("OWC :%8ld\t", ec->eth_stat.ets_OWC); - ioaddr = ec->ec_port; - isr = read_csr(ioaddr, LANCE_CSR0); - printf("isr = 0x%x, flags = 0x%x\n", isr, + ioaddr = ec->ec_port; + isr = read_csr(ioaddr, LANCE_CSR0); + printf("isr = 0x%x, flags = 0x%x\n", isr, ec->flags); - printf("irq = %d\tioadr = 0x%x\n", ec->ec_irq, ec->ec_port); - - csr = read_csr(ioaddr, LANCE_CSR0); - printf("CSR0: 0x%x\n", csr); - csr = read_csr(ioaddr, LANCE_CSR3); - printf("CSR3: 0x%x\n", csr); - csr = read_csr(ioaddr, LANCE_CSR4); - printf("CSR4: 0x%x\n", csr); - csr = read_csr(ioaddr, LANCE_CSR5); - printf("CSR5: 0x%x\n", csr); - csr = read_csr(ioaddr, LANCE_CSR15); - printf("CSR15: 0x%x\n", csr); - - } + printf("irq = %d\tioadr = 0x%x\n", ec->ec_irq, ec->ec_port); + + csr = read_csr(ioaddr, LANCE_CSR0); + printf("CSR0: 0x%x\n", csr); + csr = read_csr(ioaddr, LANCE_CSR3); + printf("CSR3: 0x%x\n", csr); + csr = read_csr(ioaddr, LANCE_CSR4); + printf("CSR4: 0x%x\n", csr); + csr = read_csr(ioaddr, LANCE_CSR5); + printf("CSR5: 0x%x\n", csr); + csr = read_csr(ioaddr, LANCE_CSR15); + printf("CSR15: 0x%x\n", csr); } /*===========================================================================* @@ -503,7 +473,6 @@ static void lance_dump() static void do_init(mp) message *mp; { - int port; ether_card_t *ec; message reply_mess; @@ -513,18 +482,9 @@ message *mp; panic("alloc_contig failed: %d", LANCE_BUF_SIZE); } - port = mp->DL_PORT; - if (port < 0 || port >= EC_PORT_NR_MAX) - { - reply_mess.m_type= DL_CONF_REPLY; - reply_mess.m3_i1= ENXIO; - mess_reply(mp, &reply_mess); - return; - } - - ec= &ec_table[port]; - strcpy(ec->port_name, "eth_card#0"); - ec->port_name[9] += port; + ec= &ec_state; + strcpy(ec->port_name, "lance#0"); + ec->port_name[6] += ec_instance; if (ec->mode == EC_DISABLED) { @@ -543,7 +503,7 @@ message *mp; { /* Probe failed, or the device is configured off. */ reply_mess.m_type= DL_CONF_REPLY; - reply_mess.m3_i1= ENXIO; + reply_mess.DL_STAT = ENXIO; mess_reply(mp, &reply_mess); return; } @@ -561,9 +521,8 @@ message *mp; ec->mac_address.ea_addr[5] = 0; ec_confaddr(ec); reply_mess.m_type = DL_CONF_REPLY; - reply_mess.m3_i1 = mp->DL_PORT; - reply_mess.m3_i2 = EC_PORT_NR_MAX; - *(ether_addr_t *) reply_mess.m3_ca1 = ec->mac_address; + reply_mess.DL_STAT = OK; + *(ether_addr_t *) reply_mess.DL_HWADDR = ec->mac_address; mess_reply(mp, &reply_mess); return; } @@ -579,14 +538,11 @@ message *mp; if (mp->DL_MODE & DL_BROAD_REQ) ec->flags |= ECF_BROAD; - ec->client = mp->m_source; - ec_reinit(ec); reply_mess.m_type = DL_CONF_REPLY; - reply_mess.m3_i1 = mp->DL_PORT; - reply_mess.m3_i2 = EC_PORT_NR_MAX; - *(ether_addr_t *) reply_mess.m3_ca1 = ec->mac_address; + reply_mess.DL_STAT = OK; + *(ether_addr_t *) reply_mess.DL_HWADDR = ec->mac_address; mess_reply(mp, &reply_mess); } @@ -599,7 +555,7 @@ static void do_int(ec) ether_card_t *ec; { if (ec->flags & (ECF_PACK_SEND | ECF_PACK_RECV)) - reply(ec, OK, TRUE); + reply(ec); } @@ -611,18 +567,20 @@ ether_card_t *ec; { static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0 /* ,... */ }; - int ifnr; + int confnr; ec_conf_t *ecp; ec->mode= EC_DISABLED; /* Superfluous */ - ifnr= ec-ec_table; - ecp= &ec_conf[ifnr]; + /* Pick a default configuration. This hardly matters anymore. */ + confnr= MIN(ec_instance, EC_CONF_NR-1); + + ecp= &ec_conf[confnr]; update_conf(ec, ecp); if (ec->mode != EC_ENABLED) return; - if (!lance_probe(ec, ifnr)) + if (!lance_probe(ec, ec_instance)) { printf("%s: No ethernet card found on PCI-BIOS info.\n", ec->port_name); @@ -645,12 +603,15 @@ ether_card_t *ec; ec_conf_t *ecp; { long v; + char eckey[16]; static char ec_fmt[] = "x:d:x:x"; /* Get the default settings and modify them from the environment. */ + strcpy(eckey, "LANCE0"); + eckey[5] += ec_instance; ec->mode= EC_SINK; v= ecp->ec_port; - switch (env_parse(ecp->ec_envvar, ec_fmt, 0, &v, 0x0000L, 0xFFFFL)) + switch (env_parse(eckey, ec_fmt, 0, &v, 0x0000L, 0xFFFFL)) { case EP_OFF: ec->mode= EC_DISABLED; @@ -666,16 +627,15 @@ ec_conf_t *ecp; ec->ec_port= v; v= ecp->ec_irq | DEI_DEFAULT; - (void) env_parse(ecp->ec_envvar, ec_fmt, 1, &v, 0L, - (long) NR_IRQ_VECTORS - 1); + (void) env_parse(eckey, ec_fmt, 1, &v, 0L, (long) NR_IRQ_VECTORS - 1); ec->ec_irq= v; v= ecp->ec_mem; - (void) env_parse(ecp->ec_envvar, ec_fmt, 2, &v, 0L, 0xFFFFFL); + (void) env_parse(eckey, ec_fmt, 2, &v, 0L, 0xFFFFFL); ec->ec_linmem= v; v= 0; - (void) env_parse(ecp->ec_envvar, ec_fmt, 3, &v, 0x2000L, 0x8000L); + (void) env_parse(eckey, ec_fmt, 3, &v, 0x2000L, 0x8000L); ec->ec_ramsize= v; } @@ -716,36 +676,23 @@ ether_card_t *ec; /*===========================================================================* * reply * *===========================================================================*/ -static void reply(ec, err, may_block) +static void reply(ec) ether_card_t *ec; -int err; -int may_block; { message reply; - int status,r; - clock_t now; + int flags,r; - status = 0; + flags = DL_NOFLAGS; if (ec->flags & ECF_PACK_SEND) - status |= DL_PACK_SEND; + flags |= DL_PACK_SEND; if (ec->flags & ECF_PACK_RECV) - status |= DL_PACK_RECV; + flags |= DL_PACK_RECV; reply.m_type = DL_TASK_REPLY; - reply.DL_PORT = ec - ec_table; - reply.DL_PROC = ec->client; - reply.DL_STAT = status | ((u32_t) err << 16); + reply.DL_FLAGS = flags; reply.DL_COUNT = ec->read_s; - if ((r=getuptime(&now)) != OK) - panic("getuptime() failed: %d", r); - reply.DL_CLCK = now; - r = send(ec->client, &reply); - if (r == ELOCKED && may_block) - { - return; - } if (r < 0) panic("send failed: %d", r); @@ -778,8 +725,8 @@ ether_card_t *ec; long v; /* User defined ethernet address? */ - strcpy(eakey, ec_conf[ec-ec_table].ec_envvar); - strcat(eakey, "_EA"); + strcpy(eakey, "LANCE0_EA"); + eakey[5] += ec_instance; for (i = 0; i < 6; i++) { @@ -1069,22 +1016,22 @@ ether_card_t *ec; *===========================================================================*/ static void do_vread_s(const message *mp) { - int port, count, r; + int count, r; ether_card_t *ec; - port = mp->DL_PORT; + ec= &ec_state; + + ec->client= mp->m_source; count = mp->DL_COUNT; - ec= &ec_table[port]; - ec->client= mp->DL_PROC; - r = sys_safecopyfrom(mp->DL_PROC, mp->DL_GRANT, 0, + r = sys_safecopyfrom(mp->DL_ENDPT, mp->DL_GRANT, 0, (vir_bytes)ec->read_iovec.iod_iovec, (count > IOVEC_NR ? IOVEC_NR : count) * sizeof(iovec_s_t), D); if (r != OK) panic("do_vread_s: sys_safecopyfrom failed: %d", r); ec->read_iovec.iod_iovec_s = count; - ec->read_iovec.iod_proc_nr = mp->DL_PROC; + ec->read_iovec.iod_proc_nr = mp->DL_ENDPT; ec->read_iovec.iod_grant = (cp_grant_id_t) mp->DL_GRANT; ec->read_iovec.iod_iovec_offset = 0; @@ -1096,7 +1043,7 @@ static void do_vread_s(const message *mp) if ((ec->flags & (ECF_READING|ECF_STOPPED)) == (ECF_READING|ECF_STOPPED)) ec_reset(ec); - reply(ec, OK, FALSE); + reply(ec); } /*===========================================================================* @@ -1176,33 +1123,33 @@ static void do_vwrite_s(mp, from_int) message *mp; int from_int; { - int port, count, check, r; + int count, check, r; ether_card_t *ec; unsigned short ioaddr; - port = mp->DL_PORT; + ec = &ec_state; + + ec->client= mp->m_source; count = mp->DL_COUNT; - ec = &ec_table[port]; - ec->client= mp->DL_PROC; if (isstored[tx_slot_nr]==1) { /* all slots are used, so this message is buffered */ ec->sendmsg= *mp; ec->flags |= ECF_SEND_AVAIL; - reply(ec, OK, FALSE); + reply(ec); return; } /* convert the message to write_iovec */ - r = sys_safecopyfrom(mp->DL_PROC, mp->DL_GRANT, 0, + r = sys_safecopyfrom(mp->DL_ENDPT, mp->DL_GRANT, 0, (vir_bytes)ec->write_iovec.iod_iovec, (count > IOVEC_NR ? IOVEC_NR : count) * sizeof(iovec_s_t), D); if (r != OK) panic("do_vwrite_s: sys_safecopyfrom failed: %d", r); ec->write_iovec.iod_iovec_s = count; - ec->write_iovec.iod_proc_nr = mp->DL_PROC; + ec->write_iovec.iod_proc_nr = mp->DL_ENDPT; ec->write_iovec.iod_grant = mp->DL_GRANT; ec->write_iovec.iod_iovec_offset = 0; @@ -1236,7 +1183,7 @@ int from_int; /* reply by calling do_int() if this function is called from interrupt. */ if (from_int) return; - reply(ec, OK, FALSE); + reply(ec); } @@ -1375,45 +1322,31 @@ iovec_dat_t *iovp; static void do_getstat_s(mp) message *mp; { - int r, port; + int r; ether_card_t *ec; - port = mp->DL_PORT; - if (port < 0 || port >= EC_PORT_NR_MAX) - panic("illegal port: %d", port); - - ec= &ec_table[port]; - ec->client= mp->DL_PROC; + ec= &ec_state; - r = sys_safecopyto(mp->DL_PROC, mp->DL_GRANT, 0, + r = sys_safecopyto(mp->DL_ENDPT, mp->DL_GRANT, 0, (vir_bytes)&ec->eth_stat, sizeof(ec->eth_stat), D); if (r != OK) panic("do_getstat_s: sys_safecopyto failed: %d", r); mp->m_type= DL_STAT_REPLY; - mp->DL_PORT= port; - mp->DL_STAT= OK; r= send(mp->m_source, mp); if (r != OK) panic("do_getstat_s: send failed: %d", r); } /*===========================================================================* - * do_stop * + * lance_stop * *===========================================================================*/ -static void do_stop(mp) -message *mp; +static void lance_stop(ec) +ether_card_t *ec; { - int port; - ether_card_t *ec; unsigned short ioaddr; - port = mp->DL_PORT; - if (port < 0 || port >= EC_PORT_NR_MAX) - panic("illegal port: %d", port); - ec = &ec_table[port]; - if (!(ec->flags & ECF_ENABLED)) return; @@ -1584,22 +1517,6 @@ int skip; return lance_version; } -/*===========================================================================* - * do_getname * - *===========================================================================*/ -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("do_getname: send failed: %d", r); -} - /*===========================================================================* * lance_init_card * *===========================================================================*/ diff --git a/drivers/lance/lance.h b/drivers/lance/lance.h index 67117656b..dc2996112 100644 --- a/drivers/lance/lance.h +++ b/drivers/lance/lance.h @@ -20,9 +20,6 @@ #define PCI_DEVICE_ID_AMD_LANCE 0x2000 -/* supported max number of ether cards */ -#define EC_PORT_NR_MAX 2 - /* macros for 'mode' */ #define EC_DISABLED 0x0 #define EC_SINK 0x1 @@ -59,14 +56,11 @@ typedef struct iovec_dat vir_bytes iod_iovec_offset; } iovec_dat_t; -#define ETH0_SELECTOR 0x61 -#define ETH1_SELECTOR 0x69 - /* ====== ethernet card info. ====== */ typedef struct ether_card { /* ####### MINIX style ####### */ - char port_name[sizeof("eth_card#n")]; + char port_name[sizeof("lance#n")]; int flags; int mode; int transfer_mode; diff --git a/drivers/orinoco/hermes.c b/drivers/orinoco/hermes.c index b9ff7141c..158cb2e37 100644 --- a/drivers/orinoco/hermes.c +++ b/drivers/orinoco/hermes.c @@ -235,7 +235,7 @@ int hermes_init (hermes_t * hw) } if (!(reg & HERMES_EV_CMD)) { - printf("hermes @ %x: Timeout waiting for card to reset\n", + printf("hermes @ %lx: Timeout waiting for card to reset\n", hw->iobase); return -ETIMEDOUT; } @@ -250,7 +250,7 @@ int hermes_init (hermes_t * hw) /* Was the status, the result of the issued command, ok? */ /* The expression below should be zero. Non-zero means an error */ if (status & HERMES_STATUS_RESULT) { - printf("Hermes:Result of INIT_CMD wrong.error value: 0x%x\n", + printf("Hermes:Result of INIT_CMD wrong.error value: 0x%lx\n", (status & HERMES_STATUS_RESULT) >> 8); err = -EIO; } @@ -272,7 +272,7 @@ int hermes_docmd_wait (hermes_t * hw, u16_t cmd, u16_t parm0, err = hermes_issue_cmd (hw, cmd, parm0); if (err) { - printf("hermes @ %x: Error %d issuing command.\n", + printf("hermes @ %lx: Error %d issuing command.\n", hw->iobase, err); return err; } @@ -290,7 +290,7 @@ int hermes_docmd_wait (hermes_t * hw, u16_t cmd, u16_t parm0, /* check for a timeout: has the command still not completed? */ if (!(reg & HERMES_EV_CMD)) { - printf("hermes @ %x: Timeout waiting for command \ + printf("hermes @ %lx: Timeout waiting for command \ completion.\n", hw->iobase); err = -ETIMEDOUT; return err; @@ -361,7 +361,7 @@ int hermes_allocate (hermes_t * hw, u16_t size, u16_t * fid) { /* tired of waiting to complete. Abort. */ if (!(reg & HERMES_EV_ALLOC)) { - printf("hermes @ %x:Timeout waiting for frame allocation\n", + printf("hermes @ %lx:Timeout waiting for frame allocation\n", hw->iobase); return -ETIMEDOUT; } diff --git a/drivers/orinoco/orinoco.c b/drivers/orinoco/orinoco.c index 768be268a..97409e943 100644 --- a/drivers/orinoco/orinoco.c +++ b/drivers/orinoco/orinoco.c @@ -7,50 +7,6 @@ * Created by Stevens Le Blond * and Michael Valkering * - * * The valid messages and their parameters are: - * - * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR DL_GRANT - * |------------+----------+---------+----------+---------+---------+---------| - * | HARDINT | | | | | | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_WRITE | port nr | proc nr | count | mode | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_WRITEV | port nr | proc nr | count | mode | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_WRITEV_S| port nr | proc nr | count | mode | | grant | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_READ | port nr | proc nr | count | | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_READV | port nr | proc nr | count | | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_READV_S | port nr | proc nr | count | | | grant | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_CONF | port nr | proc nr | | mode | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_GETSTAT | port nr | proc nr | | | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * |DL_GETSTAT_S| port nr | proc nr | | | | grant | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_STOP | port_nr | | | | | | - * |------------|----------|---------|----------|---------|---------|---------| - * - * The messages sent are: - * - * m_type DL_PORT DL_PROC DL_COUNT DL_STAT DL_CLCK - * |------------|----------|---------|----------|---------|---------| - * |DL_TASK_REPL| port nr | proc nr | rd-count | err|stat| clock | - * |------------|----------|---------|----------|---------|---------| - * - * m_type m3_i1 m3_i2 m3_ca1 - * |------------|---------|-----------|---------------| - * |DL_CONF_REPL| port nr | last port | ethernet addr | - * |------------|---------|-----------|---------------| - * - * m_type DL_PORT DL_STAT - * |------------|---------|-----------| - * |DL_STAT_REPL| port nr | err | - * |------------|---------|-----------| - * */ #include @@ -126,7 +82,8 @@ static timer_t or_watchdog; #define IRQ_BAP 1 #define ETH_HLEN 14 -PRIVATE t_or or_table[OR_PORT_NR]; +PRIVATE t_or or_state; +PRIVATE int or_instance; struct ethhdr { u8_t h_dest[ETH_ALEN]; @@ -185,11 +142,9 @@ struct { #define BITRATE_TABLE_SIZE (sizeof(bitrate_table) / sizeof(bitrate_table[0])) -_PROTOTYPE (static void or_writev, (message * mp, int from_int, int vectored)); -_PROTOTYPE (static void or_readv, (message * mp, int from_int, int vectored)); _PROTOTYPE (static void or_writev_s, (message * mp, int from_int)); _PROTOTYPE (static void or_readv_s, (message * mp, int from_int)); -_PROTOTYPE (static void reply, (t_or * orp, int err, int may_block)); +_PROTOTYPE (static void reply, (t_or * orp)); _PROTOTYPE (static int or_probe, (t_or *, int skip)); _PROTOTYPE (static void or_ev_info, (t_or *)); _PROTOTYPE (static void or_init, (message *)); @@ -203,7 +158,6 @@ _PROTOTYPE (static void or_readrids, (hermes_t *, t_or *)); _PROTOTYPE (static void or_rec_mode, (t_or *)); _PROTOTYPE (static void mess_reply, (message *, message *)); _PROTOTYPE (static u32_t or_get_bar, (int devind, t_or * orp)); -_PROTOTYPE (static void or_getstat, (message * mp)); _PROTOTYPE (static void or_getstat_s, (message * mp)); _PROTOTYPE (static void print_linkstatus, (t_or * orp, u16_t status)); _PROTOTYPE (static int or_get_recvd_packet, (t_or *orp, u16_t rxfid, @@ -211,10 +165,8 @@ _PROTOTYPE (static int or_get_recvd_packet, (t_or *orp, u16_t rxfid, _PROTOTYPE (static void or_reset, (void)); _PROTOTYPE (static void or_watchdog_f, (timer_t *tp) ); _PROTOTYPE (static void setup_wepkey, (t_or *orp, char *wepkey0) ); -_PROTOTYPE (static void or_getstat, (message *m)); _PROTOTYPE (static void do_hard_int, (void)); _PROTOTYPE (static void check_int_events, (void)); -_PROTOTYPE (static void or_getname, (message *m)); _PROTOTYPE (static void or_handler, (t_or *orp)); _PROTOTYPE (static void or_dump, (message *m)); @@ -226,8 +178,6 @@ PRIVATE int int_event_check; /* set to TRUE if events arrived */ PRIVATE u32_t system_hz; -PRIVATE const char *progname; - /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); @@ -275,36 +225,18 @@ int main(int argc, char *argv[]) { } switch (m.m_type) { - case DL_WRITEV: - or_writev (&m, FALSE, TRUE); - break; case DL_WRITEV_S: or_writev_s (&m, FALSE); break; - case DL_WRITE: - or_writev (&m, FALSE, FALSE); - break; - case DL_READ: - or_readv (&m, FALSE, FALSE); - break; - case DL_READV: - or_readv (&m, FALSE, TRUE); - break; case DL_READV_S: or_readv_s (&m, FALSE); break; case DL_CONF: or_init (&m); break; - case DL_GETSTAT: - or_getstat (&m); - break; case DL_GETSTAT_S: or_getstat_s (&m); break; - case DL_GETNAME: - or_getname(&m); - break; default: panic("orinoco: illegal message: %d", m.m_type); } @@ -338,12 +270,14 @@ PRIVATE void sef_local_startup() PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) { /* Initialize the orinoco driver. */ + long v; int fkeys, sfkeys, r; system_hz = sys_hz(); - (progname=strrchr(env_argv[0],'/')) ? progname++ - : (progname=env_argv[0]); + v = 0; + (void) env_parse("instance", "d", 0, &v, 0, 255); + or_instance = (int) v; /* Observe some function key for debug dumps. */ fkeys = sfkeys = 0; bit_set(sfkeys, 11); @@ -361,15 +295,14 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) *===========================================================================*/ PRIVATE void sef_cb_signal_handler(int signo) { - int i; t_or *orp; /* Only check for termination signal, ignore anything else. */ if (signo != SIGTERM) return; - for (i= 0, orp= &or_table[0]; ior_mode != OR_M_ENABLED) - continue; + orp = &or_state; + + if (orp->or_mode == OR_M_ENABLED) { /* TODO: send a signal to the card to shut it down */ } exit(0); @@ -386,35 +319,16 @@ static void check_int_events(void) { /* the interrupt message doesn't contain information about the port, try * to find it */ - for (orp = or_table; - orp < or_table + OR_PORT_NR; orp++) { - if (orp->or_mode != OR_M_ENABLED) - continue; - if (!orp->or_got_int) - continue; - orp->or_got_int = 0; - assert (orp->or_flags & OR_F_ENABLED); - or_check_ints (orp); - } + orp = &or_state; -} - -/**************************************************************************** - * or_getname * - * * - * Gets the drivers name, orinoco * - ****************************************************************************/ -static void or_getname(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; + if (orp->or_mode != OR_M_ENABLED) + return; + if (!orp->or_got_int) + return; + orp->or_got_int = 0; + assert (orp->or_flags & OR_F_ENABLED); + or_check_ints (orp); - r = send(mp->m_source, mp); - if(r != OK) { - panic("or_getname: send failed: %d", r); - } } /***************************************************************************** @@ -424,17 +338,15 @@ static void or_getname(message *mp) { *****************************************************************************/ static void do_hard_int(void) { - int i,s; + int s; - for (i=0; i < OR_PORT_NR; i ++) { - /* Run interrupt handler at driver level. */ - or_handler( &or_table[i]); + /* Run interrupt handler at driver level. */ + or_handler(&or_state); - /* Reenable interrupts for this hook. */ - if ((s=sys_irqenable(&or_table[i].or_hook_id)) != OK) { - printf("orinoco: error, couldn't enable"); - printf(" interrupts: %d\n", s); - } + /* Reenable interrupts for this hook. */ + if ((s=sys_irqenable(&or_state.or_hook_id)) != OK) { + printf("orinoco: error, couldn't enable"); + printf(" interrupts: %d\n", s); } } @@ -447,7 +359,7 @@ static void do_hard_int(void) static void or_reset() { static clock_t last_reset, now; t_or *orp; - int i, j, r; + int i, r; if (OK != (r = getuptime(&now))) panic("orinoco: getuptime() failed: %d", r); @@ -456,31 +368,30 @@ static void or_reset() { printf("Resetting card too often. Going to reset driver\n"); exit(1); } + + last_reset = now; - for (i = 0, orp = or_table; orp < or_table + OR_PORT_NR; i++, orp++) { - if(orp->or_mode == OR_M_DISABLED) - printf("orinoco port %d is disabled\n", i); - - if(orp->or_mode != OR_M_ENABLED) { - continue; - } + orp = &or_state; - orp->or_need_reset = 0; - or_init_hw(orp); + if(orp->or_mode == OR_M_DISABLED) + printf("orinoco instance %d is disabled\n", or_instance); + + if(orp->or_mode != OR_M_ENABLED) { + return; + } - orp->rx_last = orp->rx_first = 0; - for(j = 0; j < NR_RX_BUFS; j++) { - orp->rx_length[0] = 0; - } + orp->or_need_reset = 0; + or_init_hw(orp); - if(orp->or_flags & OR_F_SEND_AVAIL) { - orp->or_tx.ret_busy = FALSE; - orp->or_send_int = TRUE; - } + orp->rx_last = orp->rx_first = 0; + for(i = 0; i < NR_RX_BUFS; i++) { + orp->rx_length[0] = 0; } - last_reset = now; - + if(orp->or_flags & OR_F_SEND_AVAIL) { + orp->or_tx.ret_busy = FALSE; + orp->or_send_int = TRUE; + } } /***************************************************************************** @@ -492,23 +403,23 @@ static void or_reset() { static void or_dump (message *m) { t_or *orp; + + orp = &or_state; - for (orp = or_table; orp < or_table + OR_PORT_NR; orp++) { - if(orp->or_mode == OR_M_DISABLED) { - printf("%s is disabled\n", orp->or_name); - } + if(orp->or_mode == OR_M_DISABLED) { + printf("%s is disabled\n", orp->or_name); + } - if(orp->or_mode != OR_M_ENABLED) - continue; + if(orp->or_mode != OR_M_ENABLED) + return; - m->m_type = FKEY_CONTROL; - m->FKEY_REQUEST = FKEY_EVENTS; - if(OK!=(sendrec(TTY_PROC_NR,m)) ) - printf("Contacting the TTY failed\n"); + m->m_type = FKEY_CONTROL; + m->FKEY_REQUEST = FKEY_EVENTS; + if(OK!=(sendrec(TTY_PROC_NR,m)) ) + printf("Contacting the TTY failed\n"); - if(bit_isset(m->FKEY_SFKEYS, 11)) { - print_linkstatus(orp, orp->last_linkstatus); - } + if(bit_isset(m->FKEY_SFKEYS, 11)) { + print_linkstatus(orp, orp->last_linkstatus); } } @@ -518,7 +429,6 @@ static void or_dump (message *m) * The main initialization function, called when a DL_INIT message comes in. * *****************************************************************************/ static void or_init (message * mp) { - int port; t_or *orp; message reply; static int first_time = 1; @@ -532,25 +442,14 @@ static void or_init (message * mp) { sys_setalarm(system_hz, 0); } - port = mp->DL_PORT; - if (port < 0 || port >= OR_PORT_NR) { - /* illegal port in message */ - reply.m_type = DL_CONF_REPLY; - reply.m3_i1 = ENXIO; - mess_reply (mp, &reply); - return; - } - - /* the port resolves to the main orinoco structure */ - orp = &or_table[port]; - /* resolving to the main hardware structure */ + orp = &or_state; if (orp->or_mode == OR_M_DISABLED) { /* Initialize the orp structure */ or_init_struct (orp); if (orp->or_mode == OR_M_DISABLED) { reply.m_type = DL_CONF_REPLY; - reply.m3_i1 = ENXIO; + reply.DL_STAT = ENXIO; mess_reply (mp, &reply); return; } @@ -575,14 +474,12 @@ static void or_init (message * mp) { if (mp->DL_MODE & DL_BROAD_REQ) orp->or_flags |= OR_F_BROAD; - orp->or_client = mp->m_source; or_rec_mode (orp); /* reply the caller that the configuration succeeded */ reply.m_type = DL_CONF_REPLY; - reply.m3_i1 = mp->DL_PORT; - reply.m3_i2 = OR_PORT_NR; - *(ether_addr_t *) reply.m3_ca1 = orp->or_address; + reply.DL_STAT = OK; + *(ether_addr_t *) reply.DL_HWADDR = orp->or_address; mess_reply (mp, &reply); } @@ -597,48 +494,40 @@ static void or_init (message * mp) { static void or_pci_conf () { long v; t_or *orp; - int i, h; static char envfmt[] = "*:d.d.d"; static char envvar[] = OR_ENVVAR "#"; static char val[128]; /* extract information from the boot monitor about the pci * configuration if provided */ - for (i = 0, orp = or_table; i < OR_PORT_NR; i++, orp++) { - strncpy (orp->or_name, OR_NAME, sizeof(OR_NAME)); - orp->or_name[sizeof(OR_NAME) - 2] = i + '0'; - orp->or_seen = FALSE; - /* whats this envvar; whats the definition;*/ - /* i guess this whole loop could be removed*/ - envvar[sizeof (OR_ENVVAR) - 1] = '0' + i; - if (0 == env_get_param(envvar, val, sizeof(val)) && - ! env_prefix(envvar, "pci")) { - env_panic(envvar); - } - v = 0; - (void) env_parse (envvar, envfmt, 1, &v, 0, 255); - orp->or_pci_bus = v; - v = 0; - (void) env_parse (envvar, envfmt, 2, &v, 0, 255); - orp->or_pci_dev = v; - v = 0; - (void) env_parse (envvar, envfmt, 3, &v, 0, 255); - orp->or_pci_func = v; - } + orp = &or_state; + + strncpy (orp->or_name, OR_NAME, sizeof(OR_NAME)); + orp->or_name[sizeof(OR_NAME) - 2] = or_instance + '0'; + orp->or_seen = FALSE; + /* whats this envvar; whats the definition;*/ + /* i guess this whole loop could be removed*/ + envvar[sizeof (OR_ENVVAR) - 1] = '0' + or_instance; + if (0 == env_get_param(envvar, val, sizeof(val)) && + ! env_prefix(envvar, "pci")) { + env_panic(envvar); + } + v = 0; + (void) env_parse (envvar, envfmt, 1, &v, 0, 255); + orp->or_pci_bus = v; + v = 0; + (void) env_parse (envvar, envfmt, 2, &v, 0, 255); + orp->or_pci_dev = v; + v = 0; + (void) env_parse (envvar, envfmt, 3, &v, 0, 255); + orp->or_pci_func = v; /* Initialize the pci bus, bridges and cards, if not yet done */ pci_init (); - /* Try to find out where the card(s) are in the pci bus */ - for (h = 1; h >= 0; h--) - for (i = 0, orp = or_table; i < OR_PORT_NR; i++, orp++) { - if (((orp->or_pci_bus | orp->or_pci_dev | - orp->or_pci_func) != 0) != h) { - continue; - } - if (or_probe (orp, i)) - orp->or_seen = TRUE; - } + /* Try to find out where the card is in the pci bus */ + if (or_probe (orp, or_instance)) + orp->or_seen = TRUE; } /***************************************************************************** @@ -815,7 +704,7 @@ static u32_t or_get_bar (int devind, t_or * orp) orp->or_name, bar, orp->or_irq); } - panic("Not implemente yet"); + panic("Not implemented yet"); /* Although we are able to find the desired bar and irq for an * I/O spaced card, we haven't implemented the right register * accessing functions. This wouldn't be difficult, but we were @@ -913,7 +802,7 @@ static void or_init_hw (t_or * orp) } /* here begins the real things, yeah! ;) */ - if (err = hermes_init (hw)) { + if ((err = hermes_init (hw)) != 0) { printf ("error value of hermes_init(): %d\n", err); } @@ -1293,43 +1182,41 @@ next: *****************************************************************************/ static void or_watchdog_f(timer_t *tp) { - int i; t_or *orp; /* Use a synchronous alarm instead of a watchdog timer. */ sys_setalarm(system_hz, 0); - for (i= 0, orp = &or_table[0]; ior_mode != OR_M_ENABLED) - continue; + orp = &or_state; - if (!(orp->or_flags & OR_F_SEND_AVAIL)) { - /* Assume that an idle system is alive */ - orp->or_tx_alive= TRUE; - continue; - } + if (orp->or_mode != OR_M_ENABLED) + return; - if (orp->connected == 0) { - orp->or_tx_alive= TRUE; - continue; - } - if (orp->or_tx_alive) { - orp->or_tx_alive= FALSE; - continue; - } - - printf("or_watchdog_f: resetting port %d\n", i); - - orp->or_need_reset= TRUE; - orp->or_got_int= TRUE; - check_int_events(); + if (!(orp->or_flags & OR_F_SEND_AVAIL)) { + /* Assume that an idle system is alive */ + orp->or_tx_alive= TRUE; + return; } + + if (orp->connected == 0) { + orp->or_tx_alive= TRUE; + return; + } + if (orp->or_tx_alive) { + orp->or_tx_alive= FALSE; + return; + } + + printf("or_watchdog_f: resetting instance %d\n", or_instance); + + orp->or_need_reset= TRUE; + orp->or_got_int= TRUE; + check_int_events(); } /***************************************************************************** * mess_reply * *****************************************************************************/ - static void mess_reply (message * req, message * reply_mess) { if (send (req->m_source, reply_mess) != 0) @@ -1337,184 +1224,13 @@ static void mess_reply (message * req, message * reply_mess) } -/***************************************************************************** - * or_writev * - * * - * As far as we can see, this function is never called from 3.1.3. However, * - * it is still in rtl8139, so we'll keep it here as well. It's almost a copy * - * of or_writev_s. We left out the comments. For an explanation, see * - * or_writev_s * -******************************************************************************/ -static void or_writev (message * mp, int from_int, int vectored) -{ - int port, or_client, count, size, err, data_len, data_off; - int o, j, n, i, s, p, cps; - struct ethhdr *eh; - t_or *orp; - hermes_t *hw; - struct hermes_tx_descriptor desc; - struct header_struct hdr; - - iovec_t *iovp; - u16_t txfid; - static u8_t databuf[IEEE802_11_DATA_LEN + ETH_HLEN + 2 + 1]; - memset (databuf, 0, IEEE802_11_DATA_LEN + ETH_HLEN + 3); - - port = mp->DL_PORT; - count = mp->DL_COUNT; - if (port < 0 || port >= OR_PORT_NR) - panic("orinoco: illegal port"); - - or_client = mp->DL_PROC; - orp = &or_table[port]; - orp->or_client = or_client; - hw = &(orp->hw); - - if (from_int) { - assert (orp->or_flags & OR_F_SEND_AVAIL); - orp->or_flags &= ~OR_F_SEND_AVAIL; - orp->or_send_int = FALSE; - orp->or_tx_alive = TRUE; - } - - if (orp->or_tx.ret_busy) { - assert(!(orp->or_flags & OR_F_SEND_AVAIL)); - orp->or_flags |= OR_F_SEND_AVAIL; - goto suspend_write; - } - - assert (orp->or_mode == OR_M_ENABLED); - assert (orp->or_flags & OR_F_ENABLED); - - /* CvR: copied from or_writev_s(), since txfid was not initialized. */ - txfid = orp->or_tx.or_txfid; - - if (vectored) { - - int iov_offset = 0; - size = 0; - o = 0; - - for (i = 0; i < count; i += IOVEC_NR, - iov_offset += IOVEC_NR * sizeof (orp->or_iovec[0])) { - - n = IOVEC_NR; - if (i + n > count) - n = count - i; - cps = sys_vircopy(or_client, D, - ((vir_bytes) mp->DL_ADDR) + iov_offset, - SELF, D, (vir_bytes) orp->or_iovec, - n * sizeof(orp->or_iovec[0])); - if (cps != OK) printf("sys_vircopy failed: %d\n", cps); - - for (j = 0, iovp = orp->or_iovec; j < n; j++, iovp++) { - s = iovp->iov_size; - if (size + s > ETH_MAX_PACK_SIZE_TAGGED) { - printf("invalid packet size\n"); - } - cps = sys_vircopy(or_client, D, iovp->iov_addr, - SELF, D, (vir_bytes) databuf + o, s); - if (cps != OK) - printf("sys_vircopy failed: %d\n",cps); - - size += s; - o += s; - } - } - if (size < ETH_MIN_PACK_SIZE) - printf("invalid packet size %d\n", size); - } else { - size = mp->DL_COUNT; - if (size < ETH_MIN_PACK_SIZE - || size > ETH_MAX_PACK_SIZE_TAGGED) - printf("invalid packet size %d\n", size); - - cps = sys_vircopy(or_client, D, (vir_bytes)mp->DL_ADDR, - SELF, D, (vir_bytes) databuf, size); - if (cps != OK) printf("sys_abscopy failed: %d\n", cps); - } - - memset (&desc, 0, sizeof (desc)); - desc.tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX; - - err = hermes_bap_pwrite (hw, USER_BAP, &desc, sizeof (desc), txfid, - 0); - if (err) { - or_reset(); - goto fail; - } - - eh = (struct ethhdr *) databuf; - if (ntohs (eh->h_proto) > 1500) { - - data_len = size - ETH_HLEN; - data_off = HERMES_802_3_OFFSET + sizeof (hdr); - - memcpy (hdr.dest, eh->h_dest, ETH_ALEN); - memcpy (hdr.src, eh->h_src, ETH_ALEN); - hdr.len = htons (data_len + ENCAPS_OVERHEAD); - - memcpy (&hdr.dsap, &encaps_hdr, sizeof (encaps_hdr)); - hdr.ethertype = eh->h_proto; - - err = hermes_bap_pwrite (hw, USER_BAP, &hdr, sizeof (hdr), - txfid, HERMES_802_3_OFFSET); - if (err) { - printf ("%s: Error %d writing packet header to BAP\n", - orp->or_name, err); - goto fail; - } - - p = ETH_HLEN; - } else { - data_len = size + ETH_HLEN; - data_off = HERMES_802_3_OFFSET; - p = 0; - } - - err = hermes_bap_pwrite (hw, USER_BAP, - (void *) &(databuf[p]), RUP_EVEN (data_len), - txfid, data_off); - if (err) { - printf ("hermes_bap_pwrite(data): error %d\n", err); - goto fail; - } - - orp->or_tx.ret_busy = TRUE; - - err = hermes_docmd_wait (hw, HERMES_CMD_TX | HERMES_CMD_RECL, - txfid, NULL); - if (err) { - orp->or_tx.ret_busy = FALSE; - printf ("hermes_docmd_wait(TX|RECL): error %d\n", err); - goto fail; - } - -fail: - orp->or_flags |= OR_F_PACK_SENT; - - if (from_int) { - return; - } - - reply (orp, OK, FALSE); - return; - -suspend_write: - orp->or_tx_mess = *mp; - reply (orp, OK, FALSE); - return; -} - - - /***************************************************************************** * or_writev_s * * * * Write data which is denoted by the message to the card and send it. * *****************************************************************************/ static void or_writev_s (message * mp, int from_int) { - int port, or_client, count, size, err, data_len, data_off; + int count, size, err, data_len, data_off; int o, j, n, i, s, p, cps ; struct ethhdr *eh; t_or *orp; @@ -1533,14 +1249,11 @@ static void or_writev_s (message * mp, int from_int) { static u8_t databuf[IEEE802_11_DATA_LEN + ETH_HLEN + 2 + 1]; memset (databuf, 0, IEEE802_11_DATA_LEN + ETH_HLEN + 3); - port = mp->DL_PORT; + orp = &or_state; + count = mp->DL_COUNT; - if (port < 0 || port >= OR_PORT_NR) - panic("orinoco: illegal port"); - or_client = mp->DL_PROC; - orp = &or_table[port]; - orp->or_client = or_client; + orp->or_client = mp->m_source; hw = &(orp->hw); /* Switch off interrupts. The card is accessable via 2 BAPs, one for @@ -1583,7 +1296,7 @@ static void or_writev_s (message * mp, int from_int) { if (i + n > count) n = count - i; - cps = sys_safecopyfrom(or_client, mp->DL_GRANT, iov_offset, + cps = sys_safecopyfrom(mp->DL_ENDPT, mp->DL_GRANT, iov_offset, (vir_bytes) orp->or_iovec_s, n * sizeof(orp->or_iovec_s[0]), D); if (cps != OK) @@ -1595,8 +1308,8 @@ static void or_writev_s (message * mp, int from_int) { printf("Orinoco: invalid pkt size\n"); } - cps = sys_safecopyfrom(or_client, iovp->iov_grant, 0, - (vir_bytes) databuf + o, s, D); + cps = sys_safecopyfrom(mp->DL_ENDPT, iovp->iov_grant, + 0, (vir_bytes) databuf + o, s, D); if (cps != OK) printf("orinoco: sys_safecopyfrom failed:%d\n", cps); @@ -1691,13 +1404,13 @@ fail: return; } - reply (orp, OK, FALSE); + reply (orp); return; suspend_write_s: orp->or_tx_mess = *mp; - reply (orp, OK, FALSE); + reply (orp); return; } @@ -1708,33 +1421,21 @@ suspend_write_s: * Send a message back to the caller, informing it about the data received * * or sent * *****************************************************************************/ -static void reply (t_or * orp, int err, int may_block) { +static void reply (t_or * orp) { message reply; - int status = 0, r; - clock_t now; + int flags = DL_NOFLAGS, r; if (orp->or_flags & OR_F_PACK_SENT) - status |= DL_PACK_SEND; + flags |= DL_PACK_SEND; if (orp->or_flags & OR_F_PACK_RECV) - status |= DL_PACK_RECV; + flags |= DL_PACK_RECV; reply.m_type = DL_TASK_REPLY; - reply.DL_PORT = orp - or_table; - assert(reply.DL_PORT == 0); - reply.DL_PROC = orp->or_client; - reply.DL_STAT = status | ((u32_t) err << 16); + reply.DL_FLAGS = flags; reply.DL_COUNT = orp->or_read_s; - if (OK != (r = getuptime(&now))) - panic("orinoco: getuptime() failed: %d", r); - - reply.DL_CLCK = now; r = send (orp->or_client, &reply); - if (r == ELOCKED && may_block) { - return; - } - if (r < 0) panic("orinoco: send failed: %d", r); @@ -1743,7 +1444,6 @@ static void reply (t_or * orp, int err, int may_block) { } - /***************************************************************************** * or_ev_info * * * @@ -1885,7 +1585,7 @@ static void print_linkstatus (t_or * orp, u16_t status) { printf ("%s: Error %d \n", orp->or_name, err); return; } - printf("channel: %d, freq: %d MHz ", + printf("channel: %d, freq: %ld MHz ", d, (channel_frequency[d-1])); } @@ -1902,30 +1602,15 @@ static void or_check_ints (t_or * orp) or_reset(); if ((orp->rx_first!=orp->rx_last) && (orp->or_flags & OR_F_READING)) { orp->or_ev_rx = 0; - if (orp->or_rx_mess.m_type == DL_READV) { - or_readv (&orp->or_rx_mess, TRUE, TRUE); - } else if(orp->or_rx_mess.m_type == DL_READV_S) { - or_readv_s (&orp->or_rx_mess, TRUE); - } else { - assert(orp->or_rx_mess.m_type == DL_READ); - or_readv (&orp->or_rx_mess, TRUE, FALSE); - } + or_readv_s (&orp->or_rx_mess, TRUE); } if (orp->or_send_int) { - if (orp->or_tx_mess.m_type == DL_WRITEV) { - or_writev (&orp->or_tx_mess, TRUE, TRUE); - } - else if(orp->or_tx_mess.m_type == DL_WRITEV_S) { - or_writev_s (&orp->or_tx_mess, TRUE); - } else { - assert(orp->or_tx_mess.m_type == DL_WRITE); - or_writev (&orp->or_tx_mess, TRUE, FALSE); - } + or_writev_s (&orp->or_tx_mess, TRUE); } if (orp->or_flags & (OR_F_PACK_SENT | OR_F_PACK_RECV)) { - reply (orp, OK, TRUE); + reply (orp); } } @@ -1947,118 +1632,6 @@ static int is_ethersnap(struct header_struct *hdr) { && ( (hdr->oui[2] == 0x00) || (hdr->oui[2] == 0xf8) ); } -/***************************************************************************** - * or_readv * - * * - * As far as we can see, this function is never called from 3.1.3. However, * - * it is still in rtl8139, so we'll keep it here as well. It's almost a copy * - * of or_readv_s. We left out the comments. For an explanation, see * - * or_readv_s * - *****************************************************************************/ -static void or_readv (message * mp, int from_int, int vectored) { - int i, j, n, o, s, dl_port; - int or_client, count; - int size, cps; - int length; - t_or *orp; - iovec_t *iovp; - u8_t *databuf; - - dl_port = mp->DL_PORT; - count = mp->DL_COUNT; - if (dl_port < 0 || dl_port >= OR_PORT_NR) - panic("orinoco: illegal port: %d", dl_port); - - orp = &or_table[dl_port]; - or_client = mp->DL_PROC; - orp->or_client = or_client; - - assert (orp->or_mode == OR_M_ENABLED); - assert (orp->or_flags & OR_F_ENABLED); - - if (!from_int && (orp->rx_first==orp->rx_last)) { - goto suspend_readv; - } - - databuf = &(orp->rx_buf[orp->rx_first][0]); - length = orp->rx_length[orp->rx_first]; - - orp->rxfid[orp->rx_first] = NO_FID; - orp->rx_length[orp->rx_first] = 0; - - orp->rx_first++; - orp->rx_first %= NR_RX_BUFS; - - o = 0; - - if (vectored) { - int iov_offset = 0; - size = 0; - - for (i = 0; i < count; i += IOVEC_NR, - iov_offset += IOVEC_NR * sizeof(orp->or_iovec[0])) { - - n = IOVEC_NR; - if (i + n > count) - n = count - i; - - cps = sys_vircopy(or_client, D, - (vir_bytes) mp->DL_ADDR + iov_offset, - SELF, D, (vir_bytes) orp->or_iovec, - n * sizeof(orp->or_iovec[0])); - if (cps != OK) printf("sys_vircopy failed: %d (%d)\n", - cps, __LINE__); - - for (j = 0, iovp = orp->or_iovec; j < n; j++, iovp++) { - s = iovp->iov_size; - if (size + s > length) { - assert (length > size); - s = length - size; - } - - cps = sys_vircopy(SELF, D, - (vir_bytes) databuf + o, - or_client, D, - iovp->iov_addr, s); - if (cps != OK) - printf("sys_vircopy failed:%d (%d)\n", - cps, __LINE__); - - size += s; - if (size == length) - break; - o += s; - } - if (size == length) - break; - } - assert (size >= length); - } - - orp->or_stat.ets_packetR++; - orp->or_read_s = length; - orp->or_flags &= ~OR_F_READING; - orp->or_flags |= OR_F_PACK_RECV; - - if (!from_int) - reply (orp, OK, FALSE); - - return; - -suspend_readv : - if (from_int) { - assert (orp->or_flags & OR_F_READING); - return; - } - - orp->or_rx_mess = *mp; - assert (!(orp->or_flags & OR_F_READING)); - orp->or_flags |= OR_F_READING; - - reply (orp, OK, FALSE); -} - - /***************************************************************************** * or_readv_s * * * @@ -2067,20 +1640,16 @@ suspend_readv : *****************************************************************************/ static void or_readv_s (message * mp, int from_int) { - int i, j, n, o, s, dl_port, or_client, count, size, cps; + int i, j, n, o, s, count, size, cps; int iov_offset = 0, length; t_or *orp; iovec_s_t *iovp; u8_t *databuf; - dl_port = mp->DL_PORT; - count = mp->DL_COUNT; - if (dl_port < 0 || dl_port >= OR_PORT_NR) - panic("orinoco: illegal port: %d", dl_port); + orp = &or_state; - orp = &or_table[dl_port]; - or_client = mp->DL_PROC; - orp->or_client = or_client; + orp->or_client = mp->m_source; + count = mp->DL_COUNT; assert (orp->or_mode == OR_M_ENABLED); assert (orp->or_flags & OR_F_ENABLED); @@ -2118,7 +1687,7 @@ static void or_readv_s (message * mp, int from_int) if (i + n > count) n = count - i; - cps = sys_safecopyfrom(or_client, mp->DL_GRANT, iov_offset, + cps = sys_safecopyfrom(mp->DL_ENDPT, mp->DL_GRANT, iov_offset, (vir_bytes)orp->or_iovec_s, n * sizeof(orp->or_iovec_s[0]), D); if (cps != OK) @@ -2130,7 +1699,7 @@ static void or_readv_s (message * mp, int from_int) assert (length > size); s = length - size; } - cps = sys_safecopyto(or_client, iovp->iov_grant, 0, + cps = sys_safecopyto(mp->DL_ENDPT, iovp->iov_grant, 0, (vir_bytes) databuf + o, s, D); if (cps != OK) panic("orinoco: warning: sys_safecopy failed: %d", cps); @@ -2147,7 +1716,6 @@ static void or_readv_s (message * mp, int from_int) assert(size >= length); orp->or_stat.ets_packetR++; -drop: orp->or_read_s = length; orp->or_flags &= ~OR_F_READING; orp->or_flags |= OR_F_PACK_RECV; @@ -2155,7 +1723,7 @@ drop: if (!from_int) { /* There was data in the orp->rx_buf[x] which is now copied to * the inet sever. Tell the inet server */ - reply (orp, OK, FALSE); + reply (orp); } return; @@ -2172,7 +1740,7 @@ suspend_readv_s: assert (!(orp->or_flags & OR_F_READING)); orp->or_flags |= OR_F_READING; - reply (orp, OK, FALSE); + reply (orp); } @@ -2280,47 +1848,6 @@ static int or_get_recvd_packet(t_or *orp, u16_t rxfid, u8_t *databuf) { return length; } -/***************************************************************************** - * or_getstat * - * * - * Return the statistics structure. The statistics aren't updated until now, * - * so this won't return much interesting yet. * - *****************************************************************************/ -static void or_getstat (message * mp) -{ - int r, port; - eth_stat_t stats; - t_or *orp; - - port = mp->DL_PORT; - if (port < 0 || port >= OR_PORT_NR) - panic("orinoco: illegal port: %d", port); - orp = &or_table[port]; - orp->or_client = mp->DL_PROC; - - assert (orp->or_mode == OR_M_ENABLED); - assert (orp->or_flags & OR_F_ENABLED); - - stats = orp->or_stat; - - r = sys_datacopy(SELF, (vir_bytes)&stats, mp->DL_PROC, - (vir_bytes) mp->DL_ADDR, sizeof(stats)); - if(r != OK) { - panic("or_getstat: send failed: %d", r); - } - - mp->m_type = DL_STAT_REPLY; - mp->DL_PORT = port; - mp->DL_STAT = OK; - - r = send(mp->m_source, mp); - if(r != OK) - panic("orinoco: getstat failed: %d", r); - - /*reply (orp, OK, FALSE);*/ - -} - /***************************************************************************** * or_getstat_s * * * @@ -2328,31 +1855,24 @@ static void or_getstat (message * mp) * so this won't return much interesting yet. * *****************************************************************************/ static void or_getstat_s (message * mp) { - int r, port; + int r; eth_stat_t stats; t_or *orp; - port = mp->DL_PORT; - if (port < 0 || port >= OR_PORT_NR) - panic("orinoco: illegal port: %d", port); - assert(port==0); - orp = &or_table[port]; - orp->or_client = mp->DL_PROC; + orp = &or_state; assert (orp->or_mode == OR_M_ENABLED); assert (orp->or_flags & OR_F_ENABLED); stats = orp->or_stat; - r = sys_safecopyto(mp->DL_PROC, mp->DL_GRANT, 0, + r = sys_safecopyto(mp->DL_ENDPT, mp->DL_GRANT, 0, (vir_bytes) &stats, sizeof(stats), D); if(r != OK) { panic("or_getstat_s: sys_safecopyto failed: %d", r); } mp->m_type = DL_STAT_REPLY; - mp->DL_PORT = port; - mp->DL_STAT = OK; r = send(mp->m_source, mp); if(r != OK) diff --git a/drivers/orinoco/orinoco.h b/drivers/orinoco/orinoco.h index 45daee7e2..e48299fa7 100644 --- a/drivers/orinoco/orinoco.h +++ b/drivers/orinoco/orinoco.h @@ -15,7 +15,6 @@ #define LARGE_KEY_LENGTH 13 #define IW_ESSID_MAX_SIZE 32 -#define OR_PORT_NR 1 #define IOVEC_NR 16 #define OR_ENVVAR "ORETH" #define OR_NAME "orinoco#n" diff --git a/drivers/rtl8139/liveupdate.c b/drivers/rtl8139/liveupdate.c index d6af2684f..fc43d5bcf 100644 --- a/drivers/rtl8139/liveupdate.c +++ b/drivers/rtl8139/liveupdate.c @@ -1,7 +1,7 @@ #include "rtl8139.h" /* State management variables. */ -EXTERN re_t re_table[RE_PORT_NR]; +EXTERN re_t re_state; /* Custom states definition. */ #define RL_STATE_READ_PROTOCOL_FREE (SEF_LU_STATE_CUSTOM_BASE + 0) @@ -12,28 +12,16 @@ EXTERN re_t re_table[RE_PORT_NR]; /* State management helpers. */ PRIVATE int is_reading; PRIVATE int is_writing; + PRIVATE void load_state_info(void) { - int i, found_processing; re_t *rep; /* Check if we are reading or writing. */ - is_reading = FALSE; - is_writing = FALSE; - found_processing = FALSE; - for (i= 0; ire_flags & REF_READING) { - is_reading = TRUE; - } + rep = &re_state; - if (rep->re_flags & REF_SEND_AVAIL) { - is_writing = TRUE; - } - - found_processing = (is_reading && is_writing); - } + is_reading = !!(rep->re_flags & REF_READING); + is_writing = !!(rep->re_flags & REF_SEND_AVAIL); } /*===========================================================================* diff --git a/drivers/rtl8139/rtl8139.c b/drivers/rtl8139/rtl8139.c index 61c9619c1..3ba0c411f 100644 --- a/drivers/rtl8139/rtl8139.c +++ b/drivers/rtl8139/rtl8139.c @@ -4,50 +4,6 @@ * This file contains a ethernet device driver for Realtek rtl8139 based * ethernet cards. * - * The valid messages and their parameters are: - * - * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR DL_GRANT - * |------------+----------+---------+----------+---------+---------+---------| - * | HARDINT | | | | | | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_WRITE | port nr | proc nr | count | mode | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_WRITEV | port nr | proc nr | count | mode | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_WRITEV_S| port nr | proc nr | count | mode | | grant | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_READ | port nr | proc nr | count | | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_READV | port nr | proc nr | count | | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_READV_S | port nr | proc nr | count | | | grant | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_CONF | port nr | proc nr | | mode | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_GETSTAT | port nr | proc nr | | | address | | - * |------------|----------|---------|----------|---------|---------|---------| - * |DL_GETSTAT_S| port nr | proc nr | | | | grant | - * |------------|----------|---------|----------|---------|---------|---------| - * | DL_STOP | port_nr | | | | | | - * |------------|----------|---------|----------|---------|---------|---------| - * - * The messages sent are: - * - * m_type DL_PORT DL_PROC DL_COUNT DL_STAT DL_CLCK - * |------------|----------|---------|----------|---------|---------| - * |DL_TASK_REPL| port nr | proc nr | rd-count | err|stat| clock | - * |------------|----------|---------|----------|---------|---------| - * - * m_type m3_i1 m3_i2 m3_ca1 - * |------------|---------|-----------|---------------| - * |DL_CONF_REPL| port nr | last port | ethernet addr | - * |------------|---------|-----------|---------------| - * - * m_type DL_PORT DL_STAT - * |------------|---------|-----------| - * |DL_STAT_REPL| port nr | err | - * |------------|---------|-----------| - * * Created: Aug 2003 by Philip Homburg * Changes: * Aug 15, 2004 sync alarms replace watchdogs timers (Jorrit N. Herder) @@ -55,6 +11,7 @@ * */ +#define VERBOSE 0 /* Verbose debugging output */ #define RTL8139_FKEY 0 /* Use function key to dump RTL8139 status */ #include "rtl8139.h" @@ -89,9 +46,10 @@ PRIVATE struct pcitab { 0x0000, 0x0000, 0 } }; -PUBLIC re_t re_table[RE_PORT_NR]; +PUBLIC re_t re_state; + +static int re_instance; -static u16_t eth_ign_proto; static tmra_ut rl_watchdog; static unsigned my_inb(u16_t port) { @@ -142,16 +100,12 @@ _PROTOTYPE( static void rl_init, (message *mp) ); _PROTOTYPE( static void rl_pci_conf, (void) ); _PROTOTYPE( static int rl_probe, (re_t *rep, int skip) ); _PROTOTYPE( static void rl_conf_hw, (re_t *rep) ); -_PROTOTYPE( static void rl_init_buf, (re_t *rep) ); +_PROTOTYPE( static void rl_init_buf, (re_t *rep) ); _PROTOTYPE( static void rl_init_hw, (re_t *rep) ); _PROTOTYPE( static void rl_reset_hw, (re_t *rep) ); _PROTOTYPE( static void rl_confaddr, (re_t *rep) ); _PROTOTYPE( static void rl_rec_mode, (re_t *rep) ); -_PROTOTYPE( static void rl_readv, (const message *mp, int from_int, - int vectored) ); _PROTOTYPE( static void rl_readv_s, (const message *mp, int from_int) ); -_PROTOTYPE( static void rl_writev, (const message *mp, int from_int, - int vectored) ); _PROTOTYPE( static void rl_writev_s, (const message *mp, int from_int) ); _PROTOTYPE( static void rl_check_ints, (re_t *rep) ); _PROTOTYPE( static void rl_report_link, (re_t *rep) ); @@ -160,18 +114,16 @@ _PROTOTYPE( static void mii_print_stat_speed, (u16_t stat, u16_t extstat) ); _PROTOTYPE( static void rl_clear_rx, (re_t *rep) ); _PROTOTYPE( static void rl_do_reset, (re_t *rep) ); -_PROTOTYPE( static void rl_getstat, (message *mp) ); _PROTOTYPE( static void rl_getstat_s, (message *mp) ); -_PROTOTYPE( static void rl_getname, (message *mp) ); -_PROTOTYPE( static void reply, (re_t *rep, int err, int may_block) ); +_PROTOTYPE( static void reply, (re_t *rep) ); _PROTOTYPE( static void mess_reply, (message *req, message *reply) ); -_PROTOTYPE( static void check_int_events, (void) ); +_PROTOTYPE( static void check_int_events, (void) ); _PROTOTYPE( static void do_hard_int, (void) ); -_PROTOTYPE( static void rtl8139_dump, (message *m) ); +_PROTOTYPE( static void rtl8139_dump, (message *m) ); #if 0 _PROTOTYPE( static void dump_phy, (re_t *rep) ); #endif -_PROTOTYPE( static int rl_handler, (re_t *rep) ); +_PROTOTYPE( static int rl_handler, (re_t *rep) ); _PROTOTYPE( static void rl_watchdog_f, (timer_t *tp) ); _PROTOTYPE( static void tell_dev, (vir_bytes start, size_t size, int pci_bus, int pci_dev, int pci_func) ); @@ -182,7 +134,6 @@ _PROTOTYPE( static void tell_dev, (vir_bytes start, size_t size, PRIVATE message m; PRIVATE int int_event_check; /* set to TRUE if events arrived */ -static const char *progname; PRIVATE u32_t system_hz; /* SEF functions and variables. */ @@ -249,19 +200,10 @@ int main(int argc, char *argv[]) switch (m.m_type) { - case DL_WRITE: rl_writev(&m, FALSE, FALSE); break; - case DL_WRITEV: rl_writev(&m, FALSE, TRUE); break; case DL_WRITEV_S: rl_writev_s(&m, FALSE); break; - case DL_READ: rl_readv(&m, FALSE, FALSE); break; - case DL_READV: rl_readv(&m, FALSE, TRUE); break; case DL_READV_S: rl_readv_s(&m, FALSE); break; case DL_CONF: rl_init(&m); break; - case DL_GETSTAT: rl_getstat(&m); break; case DL_GETSTAT_S: rl_getstat_s(&m); break; - case DL_GETNAME: rl_getname(&m); break; -#if 0 - case DL_STOP: do_stop(&m); break; -#endif default: panic("illegal message: %d", m.m_type); } @@ -296,21 +238,16 @@ PRIVATE void sef_local_startup() PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) { /* Initialize the rtl8139 driver. */ + long v; #if RTL8139_FKEY - int fkeys, sfkeys; + int r, fkeys, sfkeys; #endif - int r; - re_t *rep; - long v; system_hz = sys_hz(); - (progname=strrchr(env_argv[0],'/')) ? progname++ - : (progname=env_argv[0]); - - v= 0; - (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL); - eth_ign_proto= htons((u16_t) v); + v = 0; + (void) env_parse("instance", "d", 0, &v, 0, 255); + re_instance = (int) v; #if RTL8139_FKEY /* Observe some function key for debug dumps. */ @@ -319,9 +256,8 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) printf("Warning: RTL8139 couldn't observe Shift+F9 key: %d\n",r); #endif - /* Claim buffer memory now under Minix, before MM takes it all. */ - for (rep= &re_table[0]; rep < re_table+RE_PORT_NR; rep++) - rl_init_buf(rep); + /* Claim buffer memory now. */ + rl_init_buf(&re_state); /* Announce we are up! */ netdriver_announce(); @@ -334,18 +270,15 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) *===========================================================================*/ PRIVATE void sef_cb_signal_handler(int signo) { - int i; re_t *rep; /* Only check for termination signal, ignore anything else. */ if (signo != SIGTERM) return; - for (i= 0, rep= &re_table[0]; ire_mode != REM_ENABLED) - continue; + rep = &re_state; + if (rep->re_mode == REM_ENABLED) rl_outb(rep->re_base_port, RL_CR, 0); - } + exit(0); } @@ -354,18 +287,17 @@ PRIVATE void sef_cb_signal_handler(int signo) *===========================================================================*/ static void check_int_events(void) { - int i; - re_t *rep; - for (i= 0, rep= &re_table[0]; ire_mode != REM_ENABLED) - continue; - if (!rep->re_got_int) - continue; - rep->re_got_int= 0; - assert(rep->re_flags & REF_ENABLED); - rl_check_ints(rep); - } + re_t *rep; + + rep= &re_state; + + if (rep->re_mode != REM_ENABLED) + return; + if (!rep->re_got_int) + return; + rep->re_got_int= 0; + assert(rep->re_flags & REF_ENABLED); + rl_check_ints(rep); } /*===========================================================================* @@ -375,66 +307,63 @@ static void rtl8139_dump(m) message *m; /* pointer to request message */ { re_t *rep; - int i; + + rep= &re_state; printf("\n"); - for (i= 0, rep = &re_table[0]; ire_mode == REM_DISABLED) - printf("Realtek RTL 8139 port %d is disabled\n", i); + if (rep->re_mode == REM_DISABLED) + printf("Realtek RTL 8139 instance %d is disabled\n", + re_instance); - if (rep->re_mode != REM_ENABLED) - continue; + if (rep->re_mode != REM_ENABLED) + return; - printf("Realtek RTL 8139 statistics of port %d:\n", i); + printf("Realtek RTL 8139 statistics of instance %d:\n", re_instance); - printf("recvErr :%8ld\t", rep->re_stat.ets_recvErr); - printf("sendErr :%8ld\t", rep->re_stat.ets_sendErr); - printf("OVW :%8ld\n", rep->re_stat.ets_OVW); + printf("recvErr :%8ld\t", rep->re_stat.ets_recvErr); + printf("sendErr :%8ld\t", rep->re_stat.ets_sendErr); + printf("OVW :%8ld\n", rep->re_stat.ets_OVW); - printf("CRCerr :%8ld\t", rep->re_stat.ets_CRCerr); - printf("frameAll :%8ld\t", rep->re_stat.ets_frameAll); - printf("missedP :%8ld\n", rep->re_stat.ets_missedP); + printf("CRCerr :%8ld\t", rep->re_stat.ets_CRCerr); + printf("frameAll :%8ld\t", rep->re_stat.ets_frameAll); + printf("missedP :%8ld\n", rep->re_stat.ets_missedP); - printf("packetR :%8ld\t", rep->re_stat.ets_packetR); - printf("packetT :%8ld\t", rep->re_stat.ets_packetT); - printf("transDef :%8ld\n", rep->re_stat.ets_transDef); + printf("packetR :%8ld\t", rep->re_stat.ets_packetR); + printf("packetT :%8ld\t", rep->re_stat.ets_packetT); + printf("transDef :%8ld\n", rep->re_stat.ets_transDef); - printf("collision :%8ld\t", rep->re_stat.ets_collision); - printf("transAb :%8ld\t", rep->re_stat.ets_transAb); - printf("carrSense :%8ld\n", rep->re_stat.ets_carrSense); + printf("collision :%8ld\t", rep->re_stat.ets_collision); + printf("transAb :%8ld\t", rep->re_stat.ets_transAb); + printf("carrSense :%8ld\n", rep->re_stat.ets_carrSense); - printf("fifoUnder :%8ld\t", rep->re_stat.ets_fifoUnder); - printf("fifoOver :%8ld\t", rep->re_stat.ets_fifoOver); - printf("CDheartbeat:%8ld\n", rep->re_stat.ets_CDheartbeat); + printf("fifoUnder :%8ld\t", rep->re_stat.ets_fifoUnder); + printf("fifoOver :%8ld\t", rep->re_stat.ets_fifoOver); + printf("CDheartbeat:%8ld\n", rep->re_stat.ets_CDheartbeat); - printf("OWC :%8ld\t", rep->re_stat.ets_OWC); + printf("OWC :%8ld\t", rep->re_stat.ets_OWC); - printf("re_flags = 0x%x\n", rep->re_flags); + printf("re_flags = 0x%x\n", rep->re_flags); - printf( - "TSAD: 0x%04x, TSD: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", - rl_inw(rep->re_base_port, RL_TSAD), - rl_inl(rep->re_base_port, RL_TSD0+0*4), - rl_inl(rep->re_base_port, RL_TSD0+1*4), - rl_inl(rep->re_base_port, RL_TSD0+2*4), - rl_inl(rep->re_base_port, RL_TSD0+3*4)); - printf("tx_head %d, tx_tail %d, busy: %d %d %d %d\n", - rep->re_tx_head, rep->re_tx_tail, - rep->re_tx[0].ret_busy, rep->re_tx[1].ret_busy, - rep->re_tx[2].ret_busy, rep->re_tx[3].ret_busy); - } + printf("TSAD: 0x%04x, TSD: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", + rl_inw(rep->re_base_port, RL_TSAD), + rl_inl(rep->re_base_port, RL_TSD0+0*4), + rl_inl(rep->re_base_port, RL_TSD0+1*4), + rl_inl(rep->re_base_port, RL_TSD0+2*4), + rl_inl(rep->re_base_port, RL_TSD0+3*4)); + printf("tx_head %d, tx_tail %d, busy: %d %d %d %d\n", + rep->re_tx_head, rep->re_tx_tail, + rep->re_tx[0].ret_busy, rep->re_tx[1].ret_busy, + rep->re_tx[2].ret_busy, rep->re_tx[3].ret_busy); } /*===========================================================================* - * do_init * + * rl_init * *===========================================================================*/ static void rl_init(mp) message *mp; { static int first_time= 1; - int port; re_t *rep; message reply_mess; @@ -448,15 +377,7 @@ message *mp; sys_setalarm(system_hz, 0); } - port = mp->DL_PORT; - if (port < 0 || port >= RE_PORT_NR) - { - reply_mess.m_type= DL_CONF_REPLY; - reply_mess.m3_i1= ENXIO; - mess_reply(mp, &reply_mess); - return; - } - rep= &re_table[port]; + rep= &re_state; if (rep->re_mode == REM_DISABLED) { /* This is the default, try to (re)locate the device. */ @@ -465,7 +386,7 @@ message *mp; { /* Probe failed, or the device is configured off. */ reply_mess.m_type= DL_CONF_REPLY; - reply_mess.m3_i1= ENXIO; + reply_mess.DL_STAT= ENXIO; mess_reply(mp, &reply_mess); return; } @@ -488,13 +409,11 @@ message *mp; if (mp->DL_MODE & DL_BROAD_REQ) rep->re_flags |= REF_BROAD; - rep->re_client = mp->m_source; rl_rec_mode(rep); reply_mess.m_type = DL_CONF_REPLY; - reply_mess.m3_i1 = mp->DL_PORT; - reply_mess.m3_i2 = RE_PORT_NR; - *(ether_addr_t *) reply_mess.m3_ca1 = rep->re_address; + reply_mess.DL_STAT = OK; + *(ether_addr_t *) reply_mess.DL_HWADDR = rep->re_address; mess_reply(mp, &reply_mess); } @@ -504,48 +423,36 @@ message *mp; *===========================================================================*/ static void rl_pci_conf() { - int i, h; re_t *rep; static char envvar[] = RL_ENVVAR "#"; static char envfmt[] = "*:d.d.d"; static char val[128]; long v; - for (i= 0, rep= re_table; ire_name, "rtl8139#0"); - rep->re_name[8] += i; - rep->re_seen= FALSE; - envvar[sizeof(RL_ENVVAR)-1]= '0'+i; - if (0 == env_get_param(envvar, val, sizeof(val)) && - ! env_prefix(envvar, "pci")) { - env_panic(envvar); - } - v= 0; - (void) env_parse(envvar, envfmt, 1, &v, 0, 255); - rep->re_pcibus= v; - v= 0; - (void) env_parse(envvar, envfmt, 2, &v, 0, 255); - rep->re_pcidev= v; - v= 0; - (void) env_parse(envvar, envfmt, 3, &v, 0, 255); - rep->re_pcifunc= v; + rep= &re_state; + + strcpy(rep->re_name, "rtl8139#0"); + rep->re_name[8] += re_instance; + rep->re_seen= FALSE; + envvar[sizeof(RL_ENVVAR)-1]= '0'+re_instance; + if (0 == env_get_param(envvar, val, sizeof(val)) && + ! env_prefix(envvar, "pci")) { + env_panic(envvar); } + v= 0; + (void) env_parse(envvar, envfmt, 1, &v, 0, 255); + rep->re_pcibus= v; + v= 0; + (void) env_parse(envvar, envfmt, 2, &v, 0, 255); + rep->re_pcidev= v; + v= 0; + (void) env_parse(envvar, envfmt, 3, &v, 0, 255); + rep->re_pcifunc= v; pci_init(); - for (h= 1; h >= 0; h--) { - for (i= 0, rep= re_table; ire_pcibus | rep->re_pcidev | - rep->re_pcifunc) != 0) != h) - { - continue; - } - if (rl_probe(rep, i)) - rep->re_seen= TRUE; - } - } + if (rl_probe(rep, re_instance)) + rep->re_seen= TRUE; } /*===========================================================================* @@ -802,16 +709,20 @@ re_t *rep; #endif /* Reset the device */ +#if VERBOSE printf("rl_reset_hw: (before reset) port = 0x%x, RL_CR = 0x%x\n", port, rl_inb(port, RL_CR)); +#endif rl_outb(port, RL_CR, RL_CR_RST); getuptime(&t0); do { if (!(rl_inb(port, RL_CR) & RL_CR_RST)) break; } while (getuptime(&t1)==OK && (t1-t0) < system_hz); +#if VERBOSE printf("rl_reset_hw: (after reset) port = 0x%x, RL_CR = 0x%x\n", port, rl_inb(port, RL_CR)); +#endif if (rl_inb(port, RL_CR) & RL_CR_RST) printf("rtl8139: reset failed to complete"); @@ -902,7 +813,7 @@ re_t *rep; long v; /* User defined ethernet address? */ - eakey[sizeof(RL_ENVVAR)-1]= '0' + (rep-re_table); + eakey[sizeof(RL_ENVVAR)-1]= '0' + re_instance; port= rep->re_base_port; @@ -959,258 +870,12 @@ re_t *rep; rl_outl(port, RL_RCR, rcr); } -/*===========================================================================* - * rl_readv * - *===========================================================================*/ -static void rl_readv(const message *mp, int from_int, int vectored) -{ - int i, j, n, o, s, s1, dl_port, re_client, count, size; - port_t port; - unsigned amount, totlen, packlen; - u16_t d_start, d_end; - u32_t l, rxstat = 0x12345678; - re_t *rep; - iovec_t *iovp; - int cps; - - dl_port = mp->DL_PORT; - count = mp->DL_COUNT; - if (dl_port < 0 || dl_port >= RE_PORT_NR) - panic(" illegal port: %d", dl_port); - rep= &re_table[dl_port]; - re_client= mp->DL_PROC; - rep->re_client= re_client; - - if (rep->re_clear_rx) - goto suspend; /* Buffer overflow */ - - assert(rep->re_mode == REM_ENABLED); - assert(rep->re_flags & REF_ENABLED); - - port= rep->re_base_port; - - /* Assume that the RL_CR_BUFE check was been done by rl_checks_ints - */ - if (!from_int && (rl_inb(port, RL_CR) & RL_CR_BUFE)) - { - /* Receive buffer is empty, suspend */ - goto suspend; - } - - d_start= rl_inw(port, RL_CAPR) + RL_CAPR_DATA_OFF; - d_end= rl_inw(port, RL_CBR) % RX_BUFSIZE; - - if (d_start >= RX_BUFSIZE) - { - printf("rl_readv: strange value in RL_CAPR: 0x%x\n", - rl_inw(port, RL_CAPR)); - d_start %= RX_BUFSIZE; - } - - if (d_end > d_start) - amount= d_end-d_start; - else - amount= d_end+RX_BUFSIZE - d_start; - - rxstat = *(u32_t *) (rep->v_re_rx_buf + d_start); - - if (rep->re_clear_rx) - { -#if 0 - printf("rl_readv: late buffer overflow\n"); -#endif - goto suspend; /* Buffer overflow */ - } - - /* Should convert from little endian to host byte order */ - - if (!(rxstat & RL_RXS_ROK)) - { - printf("rxstat = 0x%08lx\n", rxstat); - printf("d_start: 0x%x, d_end: 0x%x, rxstat: 0x%lx\n", - d_start, d_end, rxstat); - panic("received packet not OK"); - } - totlen= (rxstat >> RL_RXS_LEN_S); - if (totlen < 8 || totlen > 2*ETH_MAX_PACK_SIZE) - { - /* Someting went wrong */ - printf( - "rl_readv: bad length (%u) in status 0x%08lx at offset 0x%x\n", - totlen, rxstat, d_start); - printf( - "d_start: 0x%x, d_end: 0x%x, totlen: %d, rxstat: 0x%lx\n", - d_start, d_end, totlen, rxstat); - panic(NULL); - } - -#if 0 - printf("d_start: 0x%x, d_end: 0x%x, totlen: %d, rxstat: 0x%x\n", - d_start, d_end, totlen, rxstat); -#endif - - if (totlen+4 > amount) - { - printf("rl_readv: packet not yet ready\n"); - goto suspend; - } - - /* Should subtract the CRC */ - packlen= totlen - ETH_CRC_SIZE; - - if (vectored) - { - int iov_offset = 0; - - size= 0; - o= d_start+4; - for (i= 0; ire_iovec[0])) - { - n= IOVEC_NR; - if (i+n > count) - n= count-i; - - cps = sys_vircopy(re_client, D, - (vir_bytes) mp->DL_ADDR + iov_offset, - SELF, D, (vir_bytes) rep->re_iovec, - n * sizeof(rep->re_iovec[0])); - if (cps != OK) - printf( - "RTL8139: warning, sys_vircopy failed: %d (%d)\n", - cps, __LINE__); - - for (j= 0, iovp= rep->re_iovec; jiov_size; - if (size + s > packlen) - { - assert(packlen > size); - s= packlen-size; - } - - if (o >= RX_BUFSIZE) - { - o -= RX_BUFSIZE; - assert(o < RX_BUFSIZE); - } - - if (o+s > RX_BUFSIZE) - { - assert(ov_re_rx_buf+o, - re_client, D, iovp->iov_addr, - s1); - if (cps != OK) - printf( - "RTL8139: warning, sys_vircopy failed: %d (%d)\n", - cps, __LINE__); - cps = sys_vircopy(SELF, D, - (vir_bytes) rep->v_re_rx_buf, - re_client, D, - iovp->iov_addr+s1, s-s1); - if (cps != OK) - printf( - "RTL8139: warning, sys_vircopy failed: %d (%d)\n", - cps, __LINE__); - } - else - { - cps = sys_vircopy(SELF, D, - (vir_bytes) rep->v_re_rx_buf+o, - re_client, D, iovp->iov_addr, - s); - if (cps != OK) - printf( - "RTL8139: warning, sys_vircopy failed: %d (%d)\n", - cps, __LINE__); - } - - size += s; - if (size == packlen) - break; - o += s; - } - if (size == packlen) - break; - } - if (size < packlen) - { - assert(0); - } - } - else - { - assert(0); -#if 0 - size= mp->DL_COUNT; - if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED) - panic("invalid packet size: %d", size); - if (OK != sys_umap(re_client, D, (vir_bytes)mp->DL_ADDR, size, &phys_user)) - panic("umap_local failed"); - - p= rep->re_tx[tx_head].ret_buf; - cps = sys_abscopy(phys_user, p, size); - if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps); -#endif - } - - if (rep->re_clear_rx) - { - /* For some reason the receiver FIFO is not stopped when - * the buffer is full. - */ -#if 0 - printf("rl_readv: later buffer overflow\n"); -#endif - goto suspend; /* Buffer overflow */ - } - - rep->re_stat.ets_packetR++; - rep->re_read_s= packlen; - rep->re_flags= (rep->re_flags & ~REF_READING) | REF_PACK_RECV; - - /* Avoid overflow in 16-bit computations */ - l= d_start; - l += totlen+4; - l= (l+3) & ~3; /* align */ - if (l >= RX_BUFSIZE) - { - l -= RX_BUFSIZE; - assert(l < RX_BUFSIZE); - } - rl_outw(port, RL_CAPR, l-RL_CAPR_DATA_OFF); - - if (!from_int) - reply(rep, OK, FALSE); - - return; - -suspend: - if (from_int) - { - assert(rep->re_flags & REF_READING); - - /* No need to store any state */ - return; - } - - rep->re_rx_mess= *mp; - assert(!(rep->re_flags & REF_READING)); - rep->re_flags |= REF_READING; - - reply(rep, OK, FALSE); -} - /*===========================================================================* * rl_readv_s * *===========================================================================*/ static void rl_readv_s(const message *mp, int from_int) { - int i, j, n, o, s, s1, dl_port, re_client, count, size; + int i, j, n, o, s, s1, count, size; port_t port; unsigned amount, totlen, packlen; phys_bytes dst_phys; @@ -1221,13 +886,10 @@ static void rl_readv_s(const message *mp, int from_int) int cps; int iov_offset = 0; - dl_port = mp->DL_PORT; + rep= &re_state; + + rep->re_client= mp->m_source; count = mp->DL_COUNT; - if (dl_port < 0 || dl_port >= RE_PORT_NR) - panic(" illegal port: %d", dl_port); - rep= &re_table[dl_port]; - re_client= mp->DL_PROC; - rep->re_client= re_client; if (rep->re_clear_rx) goto suspend; /* Buffer overflow */ @@ -1315,7 +977,7 @@ static void rl_readv_s(const message *mp, int from_int) if (i+n > count) n= count-i; - cps = sys_safecopyfrom(re_client, mp->DL_GRANT, iov_offset, + cps = sys_safecopyfrom(mp->DL_ENDPT, mp->DL_GRANT, iov_offset, (vir_bytes) rep->re_iovec_s, n * sizeof(rep->re_iovec_s[0]), D); if (cps != OK) { @@ -1333,7 +995,7 @@ static void rl_readv_s(const message *mp, int from_int) } #if 0 - if (sys_umap(re_client, D, iovp->iov_addr, s, &dst_phys) != OK) + if (sys_umap(mp->DL_ENDPT, D, iovp->iov_addr, s, &dst_phys) != OK) panic("umap_local failed"); #endif @@ -1348,14 +1010,14 @@ static void rl_readv_s(const message *mp, int from_int) assert(oDL_ENDPT, iovp->iov_grant, 0, (vir_bytes) rep->v_re_rx_buf+o, s1, D); if (cps != OK) { panic("rl_readv_s: sys_safecopyto failed: %d", cps); } - cps = sys_safecopyto(re_client, + cps = sys_safecopyto(mp->DL_ENDPT, iovp->iov_grant, s1, (vir_bytes) rep->v_re_rx_buf, s-s1, S); if (cps != OK) { @@ -1364,7 +1026,7 @@ static void rl_readv_s(const message *mp, int from_int) } else { - cps = sys_safecopyto(re_client, + cps = sys_safecopyto(mp->DL_ENDPT, iovp->iov_grant, 0, (vir_bytes) rep->v_re_rx_buf+o, s, D); if (cps != OK) @@ -1411,7 +1073,7 @@ static void rl_readv_s(const message *mp, int from_int) rl_outw(port, RL_CAPR, l-RL_CAPR_DATA_OFF); if (!from_int) - reply(rep, OK, FALSE); + reply(rep); return; @@ -1428,148 +1090,7 @@ suspend: assert(!(rep->re_flags & REF_READING)); rep->re_flags |= REF_READING; - reply(rep, OK, FALSE); -} - -/*===========================================================================* - * rl_writev * - *===========================================================================*/ -static void rl_writev(const message *mp, int from_int, int vectored) -{ - phys_bytes phys_user; - int i, j, n, s, port, count, size; - int tx_head, re_client; - re_t *rep; - iovec_t *iovp; - char *ret; - int cps; - - port = mp->DL_PORT; - count = mp->DL_COUNT; - if (port < 0 || port >= RE_PORT_NR) - panic("illegal port: %d", port); - rep= &re_table[port]; - re_client= mp->DL_PROC; - rep->re_client= re_client; - - assert(rep->re_mode == REM_ENABLED); - assert(rep->re_flags & REF_ENABLED); - - if (from_int) - { - assert(rep->re_flags & REF_SEND_AVAIL); - rep->re_flags &= ~REF_SEND_AVAIL; - rep->re_send_int= FALSE; - rep->re_tx_alive= TRUE; - } - - tx_head= rep->re_tx_head; - if (rep->re_tx[tx_head].ret_busy) - { - assert(!(rep->re_flags & REF_SEND_AVAIL)); - rep->re_flags |= REF_SEND_AVAIL; - if (rep->re_tx[tx_head].ret_busy) - goto suspend; - - /* Race condition, the interrupt handler may clear re_busy - * before we got a chance to set REF_SEND_AVAIL. Checking - * ret_busy twice should be sufficient. - */ -#if 0 - printf("rl_writev: race detected\n"); -#endif - rep->re_flags &= ~REF_SEND_AVAIL; - rep->re_send_int= FALSE; - } - - assert(!(rep->re_flags & REF_SEND_AVAIL)); - assert(!(rep->re_flags & REF_PACK_SENT)); - - if (vectored) - { - int iov_offset = 0; - - size= 0; - ret = rep->re_tx[tx_head].v_ret_buf; - for (i= 0; ire_iovec[0])) - { - n= IOVEC_NR; - if (i+n > count) - n= count-i; - cps = sys_vircopy(re_client, D, ((vir_bytes) mp->DL_ADDR) + iov_offset, - SELF, D, (vir_bytes) rep->re_iovec, - n * sizeof(rep->re_iovec[0])); -if (cps != OK) printf("RTL8139: warning, sys_vircopy failed: %d\n", cps); - - for (j= 0, iovp= rep->re_iovec; jiov_size; - if (size + s > ETH_MAX_PACK_SIZE_TAGGED) { - panic("invalid packet size"); - } - - if (OK != sys_umap(re_client, D, iovp->iov_addr, s, &phys_user)) - panic("umap_local failed"); - - cps = sys_vircopy(re_client, D, iovp->iov_addr, - SELF, D, (vir_bytes) ret, s); - if (cps != OK) printf("RTL8139: warning, sys_vircopy failed: %d\n", cps); - size += s; - ret += s; - } - } - if (size < ETH_MIN_PACK_SIZE) - panic("invalid packet size: %d", size); - } - else - { - size= mp->DL_COUNT; - if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED) - panic("invalid packet size: %d", size); - ret = rep->re_tx[tx_head].v_ret_buf; - cps = sys_vircopy(re_client, D, (vir_bytes)mp->DL_ADDR, - SELF, D, (vir_bytes) ret, size); - if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps); - } - - rl_outl(rep->re_base_port, RL_TSD0+tx_head*4, - rep->re_ertxth | size); - rep->re_tx[tx_head].ret_busy= TRUE; - - if (++tx_head == N_TX_BUF) - tx_head= 0; - assert(tx_head < RL_N_TX); - rep->re_tx_head= tx_head; - - rep->re_flags |= REF_PACK_SENT; - - /* If the interrupt handler called, don't send a reply. The reply - * will be sent after all interrupts are handled. - */ - if (from_int) - return; - reply(rep, OK, FALSE); - return; - -suspend: -#if 0 - printf("rl_writev: head %d, tail %d, busy: %d %d %d %d\n", - tx_head, rep->re_tx_tail, - rep->re_tx[0].ret_busy, rep->re_tx[1].ret_busy, - rep->re_tx[2].ret_busy, rep->re_tx[3].ret_busy); - printf("rl_writev: TSD: 0x%x, 0x%x, 0x%x, 0x%x\n", - rl_inl(rep->re_base_port, RL_TSD0+0*4), - rl_inl(rep->re_base_port, RL_TSD0+1*4), - rl_inl(rep->re_base_port, RL_TSD0+2*4), - rl_inl(rep->re_base_port, RL_TSD0+3*4)); -#endif - - if (from_int) - panic("should not be sending"); - - rep->re_tx_mess= *mp; - reply(rep, OK, FALSE); + reply(rep); } /*===========================================================================* @@ -1577,21 +1098,18 @@ suspend: *===========================================================================*/ static void rl_writev_s(const message *mp, int from_int) { - int i, j, n, s, port, count, size; - int tx_head, re_client; + int i, j, n, s, count, size; + int tx_head; re_t *rep; iovec_s_t *iovp; char *ret; int cps; int iov_offset = 0; - port = mp->DL_PORT; + rep= &re_state; + + rep->re_client= mp->m_source; count = mp->DL_COUNT; - if (port < 0 || port >= RE_PORT_NR) - panic("illegal port: %d", port); - rep= &re_table[port]; - re_client= mp->DL_PROC; - rep->re_client= re_client; assert(rep->re_mode == REM_ENABLED); assert(rep->re_flags & REF_ENABLED); @@ -1609,18 +1127,7 @@ static void rl_writev_s(const message *mp, int from_int) { assert(!(rep->re_flags & REF_SEND_AVAIL)); rep->re_flags |= REF_SEND_AVAIL; - if (rep->re_tx[tx_head].ret_busy) - goto suspend; - - /* Race condition, the interrupt handler may clear re_busy - * before we got a chance to set REF_SEND_AVAIL. Checking - * ret_busy twice should be sufficient. - */ -#if 0 - printf("rl_writev: race detected\n"); -#endif - rep->re_flags &= ~REF_SEND_AVAIL; - rep->re_send_int= FALSE; + goto suspend; } assert(!(rep->re_flags & REF_SEND_AVAIL)); @@ -1634,7 +1141,7 @@ static void rl_writev_s(const message *mp, int from_int) n= IOVEC_NR; if (i+n > count) n= count-i; - cps = sys_safecopyfrom(re_client, mp->DL_GRANT, iov_offset, + cps = sys_safecopyfrom(mp->DL_ENDPT, mp->DL_GRANT, iov_offset, (vir_bytes) rep->re_iovec_s, n * sizeof(rep->re_iovec_s[0]), D); if (cps != OK) { @@ -1647,8 +1154,8 @@ static void rl_writev_s(const message *mp, int from_int) if (size + s > ETH_MAX_PACK_SIZE_TAGGED) { panic("invalid packet size"); } - cps = sys_safecopyfrom(re_client, iovp->iov_grant, 0, - (vir_bytes) ret, s, D); + cps = sys_safecopyfrom(mp->DL_ENDPT, iovp->iov_grant, + 0, (vir_bytes) ret, s, D); if (cps != OK) { panic("rl_writev_s: sys_safecopyfrom failed: %d", cps); } @@ -1675,7 +1182,7 @@ static void rl_writev_s(const message *mp, int from_int) */ if (from_int) return; - reply(rep, OK, FALSE); + reply(rep); return; suspend: @@ -1695,7 +1202,7 @@ suspend: panic("should not be sending"); rep->re_tx_mess= *mp; - reply(rep, OK, FALSE); + reply(rep); } /*===========================================================================* @@ -1750,21 +1257,7 @@ re_t *rep; if ((re_flags & REF_READING) && !(rl_inb(rep->re_base_port, RL_CR) & RL_CR_BUFE)) { - if (rep->re_rx_mess.m_type == DL_READV) - { - rl_readv(&rep->re_rx_mess, TRUE /* from int */, - TRUE /* vectored */); - } - else if (rep->re_rx_mess.m_type == DL_READV_S) - { - rl_readv_s(&rep->re_rx_mess, TRUE /* from int */); - } - else - { - assert(rep->re_rx_mess.m_type == DL_READ); - rl_readv(&rep->re_rx_mess, TRUE /* from int */, - FALSE /* !vectored */); - } + rl_readv_s(&rep->re_rx_mess, TRUE /* from int */); } if (rep->re_clear_rx) rl_clear_rx(rep); @@ -1774,28 +1267,14 @@ re_t *rep; if (rep->re_send_int) { - if (rep->re_tx_mess.m_type == DL_WRITEV) - { - rl_writev(&rep->re_tx_mess, TRUE /* from int */, - TRUE /* vectored */); - } - else if (rep->re_tx_mess.m_type == DL_WRITEV_S) - { - rl_writev_s(&rep->re_tx_mess, TRUE /* from int */); - } - else - { - assert(rep->re_tx_mess.m_type == DL_WRITE); - rl_writev(&rep->re_tx_mess, TRUE /* from int */, - FALSE /* !vectored */); - } + rl_writev_s(&rep->re_tx_mess, TRUE /* from int */); } if (rep->re_report_link) rl_report_link(rep); if (rep->re_flags & (REF_PACK_SENT | REF_PACK_RECV)) - reply(rep, OK, TRUE); + reply(rep); } /*===========================================================================* @@ -2147,132 +1626,59 @@ re_t *rep; } } -/*===========================================================================* - * rl_getstat * - *===========================================================================*/ -static void rl_getstat(mp) -message *mp; -{ - int r, port; - eth_stat_t stats; - re_t *rep; - - port = mp->DL_PORT; - if (port < 0 || port >= RE_PORT_NR) - panic("illegal port: %d", port); - rep= &re_table[port]; - rep->re_client= mp->DL_PROC; - - assert(rep->re_mode == REM_ENABLED); - assert(rep->re_flags & REF_ENABLED); - - stats= rep->re_stat; - - r = sys_datacopy(SELF, (vir_bytes) &stats, mp->DL_PROC, - (vir_bytes) mp->DL_ADDR, sizeof(stats)); - if (r != OK) - panic("rl_getstat: sys_datacopy failed: %d", r); - - mp->m_type= DL_STAT_REPLY; - mp->DL_PORT= port; - mp->DL_STAT= OK; - r= send(mp->m_source, mp); - if (r != OK) - panic("rl_getstat: send failed: %d", r); -} - /*===========================================================================* * rl_getstat_s * *===========================================================================*/ static void rl_getstat_s(mp) message *mp; { - int r, port; + int r; eth_stat_t stats; re_t *rep; - port = mp->DL_PORT; - if (port < 0 || port >= RE_PORT_NR) - panic("illegal port: %d", port); - rep= &re_table[port]; - rep->re_client= mp->DL_PROC; + rep= &re_state; assert(rep->re_mode == REM_ENABLED); assert(rep->re_flags & REF_ENABLED); stats= rep->re_stat; - r = sys_safecopyto(mp->DL_PROC, mp->DL_GRANT, 0, + r = sys_safecopyto(mp->DL_ENDPT, mp->DL_GRANT, 0, (vir_bytes) &stats, sizeof(stats), D); if (r != OK) panic("rl_getstat_s: sys_safecopyto failed: %d", r); mp->m_type= DL_STAT_REPLY; - mp->DL_PORT= port; - mp->DL_STAT= OK; r= send(mp->m_source, mp); if (r != OK) panic("rl_getstat_s: send failed: %d", r); } - -/*===========================================================================* - * rl_getname * - *===========================================================================*/ -static void rl_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("rl_getname: send failed: %d", r); -} - - /*===========================================================================* * reply * *===========================================================================*/ -static void reply(rep, err, may_block) +static void reply(rep) re_t *rep; -int err; -int may_block; { message reply; - int status; + int flags; int r; - clock_t now; - status = 0; + flags = DL_NOFLAGS; if (rep->re_flags & REF_PACK_SENT) - status |= DL_PACK_SEND; + flags |= DL_PACK_SEND; if (rep->re_flags & REF_PACK_RECV) - status |= DL_PACK_RECV; + flags |= DL_PACK_RECV; reply.m_type = DL_TASK_REPLY; - reply.DL_PORT = rep - re_table; - reply.DL_PROC = rep->re_client; - reply.DL_STAT = status | ((u32_t) err << 16); + reply.DL_FLAGS = flags; reply.DL_COUNT = rep->re_read_s; - if (OK != (r = getuptime(&now))) - panic("getuptime() failed: %d", r); - reply.DL_CLCK = now; r= send(rep->re_client, &reply); - if (r == ELOCKED && may_block) - { -#if 0 - printW(); printf("send locked\n"); -#endif - return; - } - if (r < 0) { - printf("RTL8139 tried sending to %d, type %d\n", rep->re_client, reply.m_type); + printf("RTL8139 tried sending to %d, type %d\n", + rep->re_client, reply.m_type); panic("send failed: %d", r); } @@ -2292,6 +1698,9 @@ message *reply_mess; } #if 0 +/*===========================================================================* + * dump_phy * + *===========================================================================*/ static void dump_phy(rep) re_t *rep; { @@ -2387,19 +1796,19 @@ re_t *rep; } #endif +/*===========================================================================* + * do_hard_int * + *===========================================================================*/ static void do_hard_int(void) { - int i,s; - - for (i=0; i < RE_PORT_NR; i ++) { + int s; - /* Run interrupt handler at driver level. */ - rl_handler( &re_table[i]); + /* Run interrupt handler at driver level. */ + rl_handler(&re_state); - /* Reenable interrupts for this hook. */ - if ((s=sys_irqenable(&re_table[i].re_hook_id)) != OK) + /* Reenable interrupts for this hook. */ + if ((s=sys_irqenable(&re_state.re_hook_id)) != OK) printf("RTL8139: error, couldn't enable interrupts: %d\n", s); - } } /*===========================================================================* @@ -2680,43 +2089,40 @@ static int rl_handler(re_t *rep) static void rl_watchdog_f(tp) timer_t *tp; { - int i; re_t *rep; /* Use a synchronous alarm instead of a watchdog timer. */ sys_setalarm(system_hz, 0); - for (i= 0, rep = &re_table[0]; ire_mode != REM_ENABLED) + return; + if (!(rep->re_flags & REF_SEND_AVAIL)) { - if (rep->re_mode != REM_ENABLED) - continue; - if (!(rep->re_flags & REF_SEND_AVAIL)) - { - /* Assume that an idle system is alive */ - rep->re_tx_alive= TRUE; - continue; - } - if (rep->re_tx_alive) - { - rep->re_tx_alive= FALSE; - continue; - } - printf("rl_watchdog_f: resetting port %d\n", i); - printf( - "TSAD: 0x%04x, TSD: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", - rl_inw(rep->re_base_port, RL_TSAD), - rl_inl(rep->re_base_port, RL_TSD0+0*4), - rl_inl(rep->re_base_port, RL_TSD0+1*4), - rl_inl(rep->re_base_port, RL_TSD0+2*4), - rl_inl(rep->re_base_port, RL_TSD0+3*4)); - printf("tx_head %d, tx_tail %d, busy: %d %d %d %d\n", - rep->re_tx_head, rep->re_tx_tail, - rep->re_tx[0].ret_busy, rep->re_tx[1].ret_busy, - rep->re_tx[2].ret_busy, rep->re_tx[3].ret_busy); - rep->re_need_reset= TRUE; - rep->re_got_int= TRUE; - - check_int_events(); + /* Assume that an idle system is alive */ + rep->re_tx_alive= TRUE; + return; + } + if (rep->re_tx_alive) + { + rep->re_tx_alive= FALSE; + return; } + printf("rl_watchdog_f: resetting instance %d\n", re_instance); + printf("TSAD: 0x%04x, TSD: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", + rl_inw(rep->re_base_port, RL_TSAD), + rl_inl(rep->re_base_port, RL_TSD0+0*4), + rl_inl(rep->re_base_port, RL_TSD0+1*4), + rl_inl(rep->re_base_port, RL_TSD0+2*4), + rl_inl(rep->re_base_port, RL_TSD0+3*4)); + printf("tx_head %d, tx_tail %d, busy: %d %d %d %d\n", + rep->re_tx_head, rep->re_tx_tail, + rep->re_tx[0].ret_busy, rep->re_tx[1].ret_busy, + rep->re_tx[2].ret_busy, rep->re_tx[3].ret_busy); + rep->re_need_reset= TRUE; + rep->re_got_int= TRUE; + + check_int_events(); } #if 0 diff --git a/drivers/rtl8139/rtl8139.h b/drivers/rtl8139/rtl8139.h index d0e6c2dd5..9ed63d914 100644 --- a/drivers/rtl8139/rtl8139.h +++ b/drivers/rtl8139/rtl8139.h @@ -460,14 +460,10 @@ d9-ff reserved #define printW() ((void)0) #define vm_1phys2bus(p) (p) -#define VERBOSE 1 /* display message during init */ - #define RX_BUFSIZE RL_RCR_RBLEN_64K_SIZE #define RX_BUFBITS RL_RCR_RBLEN_64K #define N_TX_BUF RL_N_TX -#define RE_PORT_NR 1 /* Minix */ - /* I/O vectors are handled IOVEC_NR entries at a time. */ #define IOVEC_NR 16 diff --git a/drivers/rtl8169/rtl8169.c b/drivers/rtl8169/rtl8169.c index b7b073f32..60c77b167 100644 --- a/drivers/rtl8169/rtl8169.c +++ b/drivers/rtl8169/rtl8169.c @@ -38,8 +38,6 @@ #include "rtl8169.h" -#define RE_PORT_NR 1 /* Minix */ - #define IOVEC_NR 16 /* I/O vectors are handled IOVEC_NR entries at a time. */ #define RE_DTCC_VALUE 600 /* DTCC Update after every 10 minutes */ @@ -177,9 +175,10 @@ re_t; #define REF_BROAD 0x100 #define REF_ENABLED 0x200 -static re_t re_table[RE_PORT_NR]; +static re_t re_state; + +static int re_instance; -static u16_t eth_ign_proto; static timer_t rl_watchdog; static unsigned my_inb(u16_t port) @@ -249,10 +248,8 @@ _PROTOTYPE( static void rl_writev_s, (const message *mp, int from_int) ); _PROTOTYPE( static void rl_check_ints, (re_t *rep) ); _PROTOTYPE( static void rl_report_link, (re_t *rep) ); _PROTOTYPE( static void rl_do_reset, (re_t *rep) ); -_PROTOTYPE( static void rl_getstat, (message *mp) ); _PROTOTYPE( static void rl_getstat_s, (message *mp) ); -_PROTOTYPE( static void rl_getname, (message *mp) ); -_PROTOTYPE( static void reply, (re_t *rep, int err, int may_block) ); +_PROTOTYPE( static void reply, (re_t *rep) ); _PROTOTYPE( static void mess_reply, (message *req, message *reply) ); _PROTOTYPE( static void check_int_events, (void) ); _PROTOTYPE( static void do_hard_int, (void) ); @@ -268,7 +265,6 @@ _PROTOTYPE( static void rl_watchdog_f, (timer_t *tp) ); PRIVATE message m; PRIVATE int int_event_check; /* set to TRUE if events arrived */ -static char *progname; u32_t system_hz; /* SEF functions and variables. */ @@ -329,9 +325,7 @@ int main(int argc, char *argv[]) case DL_WRITEV_S: rl_writev_s(&m, FALSE); break; case DL_READV_S: rl_readv_s(&m, FALSE); break; case DL_CONF: rl_init(&m); break; - case DL_GETSTAT: rl_getstat(&m); break; case DL_GETSTAT_S: rl_getstat_s(&m); break; - case DL_GETNAME: rl_getname(&m); break; default: panic("illegal message: %d", m.m_type); } @@ -365,21 +359,16 @@ PRIVATE void sef_local_startup() PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) { /* Initialize the rtl8169 driver. */ - re_t *rep; long v; system_hz = sys_hz(); - (progname = strrchr(env_argv[0], '/')) ? progname++ - : (progname = env_argv[0]); - v = 0; - (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL); - eth_ign_proto = htons((u16_t) v); + (void) env_parse("instance", "d", 0, &v, 0, 255); + re_instance = (int) v; - /* Claim buffer memory now under Minix, before MM takes it all. */ - for (rep = &re_table[0]; rep < re_table + RE_PORT_NR; rep++) - rl_init_buf(rep); + /* Claim buffer memory now. */ + rl_init_buf(&re_state); /* Announce we are up! */ netdriver_announce(); @@ -392,17 +381,14 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) *===========================================================================*/ PRIVATE void sef_cb_signal_handler(int signo) { - int i; re_t *rep; /* Only check for termination signal, ignore anything else. */ if (signo != SIGTERM) return; - for (i = 0, rep = &re_table[0]; i < RE_PORT_NR; i++, rep++) { - if (rep->re_mode != REM_ENABLED) - continue; + rep = &re_state; + if (rep->re_mode == REM_ENABLED) rl_outb(rep->re_base_port, RL_CR, 0); - } exit(0); } @@ -450,18 +436,17 @@ static int mdio_read(u16_t port, int regaddr) *===========================================================================*/ static void check_int_events(void) { - int i; re_t *rep; - for (i = 0, rep = &re_table[0]; i < RE_PORT_NR; i++, rep++) { - if (rep->re_mode != REM_ENABLED) - continue; - if (!rep->re_got_int) - continue; - rep->re_got_int = 0; - assert(rep->re_flags & REF_ENABLED); - rl_check_ints(rep); - } + rep = &re_state; + + if (rep->re_mode != REM_ENABLED) + return; + if (!rep->re_got_int) + return; + rep->re_got_int = 0; + assert(rep->re_flags & REF_ENABLED); + rl_check_ints(rep); } static void rtl8169_update_stat(re_t *rep) @@ -499,84 +484,84 @@ static void rtl8169_dump(void) { re_dtcc *dtcc; re_t *rep; - int i; + + rep = &re_state; printf("\n"); - for (i = 0, rep = &re_table[0]; i < RE_PORT_NR; i++, rep++) { - if (rep->re_mode == REM_DISABLED) - printf("Realtek RTL 8169 port %d is disabled\n", i); + if (rep->re_mode == REM_DISABLED) + printf("Realtek RTL 8169 instance %d is disabled\n", + re_instance); - if (rep->re_mode != REM_ENABLED) - continue; + if (rep->re_mode != REM_ENABLED) + return; - rtl8169_update_stat(rep); + rtl8169_update_stat(rep); - printf("Realtek RTL 8169 statistics of port %d:\n", i); + printf("Realtek RTL 8169 statistics of instance %d:\n", re_instance); - printf("recvErr :%8ld\t", rep->re_stat.ets_recvErr); - printf("sendErr :%8ld\t", rep->re_stat.ets_sendErr); - printf("OVW :%8ld\n", rep->re_stat.ets_OVW); + printf("recvErr :%8ld\t", rep->re_stat.ets_recvErr); + printf("sendErr :%8ld\t", rep->re_stat.ets_sendErr); + printf("OVW :%8ld\n", rep->re_stat.ets_OVW); - printf("CRCerr :%8ld\t", rep->re_stat.ets_CRCerr); - printf("frameAll :%8ld\t", rep->re_stat.ets_frameAll); - printf("missedP :%8ld\n", rep->re_stat.ets_missedP); + printf("CRCerr :%8ld\t", rep->re_stat.ets_CRCerr); + printf("frameAll :%8ld\t", rep->re_stat.ets_frameAll); + printf("missedP :%8ld\n", rep->re_stat.ets_missedP); - printf("packetR :%8ld\t", rep->re_stat.ets_packetR); - printf("packetT :%8ld\t", rep->re_stat.ets_packetT); - printf("transDef :%8ld\n", rep->re_stat.ets_transDef); + printf("packetR :%8ld\t", rep->re_stat.ets_packetR); + printf("packetT :%8ld\t", rep->re_stat.ets_packetT); + printf("transDef :%8ld\n", rep->re_stat.ets_transDef); - printf("collision :%8ld\t", rep->re_stat.ets_collision); - printf("transAb :%8ld\t", rep->re_stat.ets_transAb); - printf("carrSense :%8ld\n", rep->re_stat.ets_carrSense); + printf("collision :%8ld\t", rep->re_stat.ets_collision); + printf("transAb :%8ld\t", rep->re_stat.ets_transAb); + printf("carrSense :%8ld\n", rep->re_stat.ets_carrSense); - printf("fifoUnder :%8ld\t", rep->re_stat.ets_fifoUnder); - printf("fifoOver :%8ld\t", rep->re_stat.ets_fifoOver); - printf("OWC :%8ld\n", rep->re_stat.ets_OWC); - printf("interrupts :%8lu\n", rep->interrupts); + printf("fifoUnder :%8ld\t", rep->re_stat.ets_fifoUnder); + printf("fifoOver :%8ld\t", rep->re_stat.ets_fifoOver); + printf("OWC :%8ld\n", rep->re_stat.ets_OWC); + printf("interrupts :%8lu\n", rep->interrupts); - printf("\nRealtek RTL 8169 Tally Counters:\n"); + printf("\nRealtek RTL 8169 Tally Counters:\n"); - dtcc = rep->v_dtcc_buf; + dtcc = rep->v_dtcc_buf; - if (dtcc->TxOk_high) - printf("TxOk :%8ld%08ld\t", dtcc->TxOk_high, dtcc->TxOk_low); - else - printf("TxOk :%16lu\t", dtcc->TxOk_low); + if (dtcc->TxOk_high) + printf("TxOk :%8ld%08ld\t", dtcc->TxOk_high, dtcc->TxOk_low); + else + printf("TxOk :%16lu\t", dtcc->TxOk_low); - if (dtcc->RxOk_high) - printf("RxOk :%8ld%08ld\n", dtcc->RxOk_high, dtcc->RxOk_low); - else - printf("RxOk :%16lu\n", dtcc->RxOk_low); + if (dtcc->RxOk_high) + printf("RxOk :%8ld%08ld\n", dtcc->RxOk_high, dtcc->RxOk_low); + else + printf("RxOk :%16lu\n", dtcc->RxOk_low); - if (dtcc->TxEr_high) - printf("TxEr :%8ld%08ld\t", dtcc->TxEr_high, dtcc->TxEr_low); - else - printf("TxEr :%16ld\t", dtcc->TxEr_low); + if (dtcc->TxEr_high) + printf("TxEr :%8ld%08ld\t", dtcc->TxEr_high, dtcc->TxEr_low); + else + printf("TxEr :%16ld\t", dtcc->TxEr_low); - printf("RxEr :%16ld\n", dtcc->RxEr); + printf("RxEr :%16ld\n", dtcc->RxEr); - printf("Tx1Col :%16ld\t", dtcc->Tx1Col); - printf("TxMCol :%16ld\n", dtcc->TxMCol); + printf("Tx1Col :%16ld\t", dtcc->Tx1Col); + printf("TxMCol :%16ld\n", dtcc->TxMCol); - if (dtcc->RxOkPhy_high) - printf("RxOkPhy :%8ld%08ld\t", dtcc->RxOkPhy_high, dtcc->RxOkPhy_low); - else - printf("RxOkPhy :%16ld\t", dtcc->RxOkPhy_low); + if (dtcc->RxOkPhy_high) + printf("RxOkPhy :%8ld%08ld\t", dtcc->RxOkPhy_high, dtcc->RxOkPhy_low); + else + printf("RxOkPhy :%16ld\t", dtcc->RxOkPhy_low); - if (dtcc->RxOkBrd_high) - printf("RxOkBrd :%8ld%08ld\n", dtcc->RxOkBrd_high, dtcc->RxOkBrd_low); - else - printf("RxOkBrd :%16ld\n", dtcc->RxOkBrd_low); + if (dtcc->RxOkBrd_high) + printf("RxOkBrd :%8ld%08ld\n", dtcc->RxOkBrd_high, dtcc->RxOkBrd_low); + else + printf("RxOkBrd :%16ld\n", dtcc->RxOkBrd_low); - printf("RxOkMul :%16ld\t", dtcc->RxOkMul); - printf("MissPkt :%16d\n", dtcc->MissPkt); + printf("RxOkMul :%16ld\t", dtcc->RxOkMul); + printf("MissPkt :%16d\n", dtcc->MissPkt); - printf("\nRealtek RTL 8169 Miscellaneous Info:\n"); + printf("\nRealtek RTL 8169 Miscellaneous Info:\n"); - printf("re_flags : 0x%08x\n", rep->re_flags); - printf("tx_head :%8d busy %d\t", - rep->re_tx_head, rep->re_tx[rep->re_tx_head].ret_busy); - } + printf("re_flags : 0x%08x\n", rep->re_flags); + printf("tx_head :%8d busy %d\t", + rep->re_tx_head, rep->re_tx[rep->re_tx_head].ret_busy); } /*===========================================================================* @@ -587,7 +572,6 @@ message *mp; { static int first_time = 1; - int port; re_t *rep; message reply_mess; @@ -600,21 +584,14 @@ message *mp; sys_setalarm(system_hz, 0); } - port = mp->DL_PORT; - if (port < 0 || port >= RE_PORT_NR) { - reply_mess.m_type = DL_CONF_REPLY; - reply_mess.m3_i1 = ENXIO; - mess_reply(mp, &reply_mess); - return; - } - rep = &re_table[port]; + rep = &re_state; if (rep->re_mode == REM_DISABLED) { /* This is the default, try to (re)locate the device. */ rl_conf_hw(rep); if (rep->re_mode == REM_DISABLED) { /* Probe failed, or the device is configured off. */ reply_mess.m_type = DL_CONF_REPLY; - reply_mess.m3_i1 = ENXIO; + reply_mess.DL_STAT = ENXIO; mess_reply(mp, &reply_mess); return; } @@ -634,13 +611,11 @@ message *mp; if (mp->DL_MODE & DL_BROAD_REQ) rep->re_flags |= REF_BROAD; - rep->re_client = mp->m_source; rl_rec_mode(rep); reply_mess.m_type = DL_CONF_REPLY; - reply_mess.m3_i1 = mp->DL_PORT; - reply_mess.m3_i2 = RE_PORT_NR; - *(ether_addr_t *) reply_mess.m3_ca1 = rep->re_address; + reply_mess.DL_STAT = OK; + *(ether_addr_t *) reply_mess.DL_HWADDR = rep->re_address; mess_reply(mp, &reply_mess); } @@ -650,46 +625,37 @@ message *mp; *===========================================================================*/ static void rl_pci_conf() { - int i, h; re_t *rep; static char envvar[] = RL_ENVVAR "#"; static char envfmt[] = "*:d.d.d"; static char val[128]; long v; - for (i = 0, rep = re_table; i < RE_PORT_NR; i++, rep++) { - strcpy(rep->re_name, "rtl8169#0"); - rep->re_name[8] += i; - rep->re_seen = FALSE; - envvar[sizeof(RL_ENVVAR)-1] = '0' + i; - if (0 == env_get_param(envvar, val, sizeof(val)) && - !env_prefix(envvar, "pci")) - { - env_panic(envvar); - } - v = 0; - (void) env_parse(envvar, envfmt, 1, &v, 0, 255); - rep->re_pcibus = v; - v = 0; - (void) env_parse(envvar, envfmt, 2, &v, 0, 255); - rep->re_pcidev = v; - v = 0; - (void) env_parse(envvar, envfmt, 3, &v, 0, 255); - rep->re_pcifunc = v; + rep = &re_state; + + strcpy(rep->re_name, "rtl8169#0"); + rep->re_name[8] += re_instance; + rep->re_seen = FALSE; + envvar[sizeof(RL_ENVVAR)-1] = '0' + re_instance; + if (0 == env_get_param(envvar, val, sizeof(val)) && + !env_prefix(envvar, "pci")) + { + env_panic(envvar); } + v = 0; + (void) env_parse(envvar, envfmt, 1, &v, 0, 255); + rep->re_pcibus = v; + v = 0; + (void) env_parse(envvar, envfmt, 2, &v, 0, 255); + rep->re_pcidev = v; + v = 0; + (void) env_parse(envvar, envfmt, 3, &v, 0, 255); + rep->re_pcifunc = v; pci_init(); - for (h = 1; h >= 0; h--) { - for (i = 0, rep = re_table; i < RE_PORT_NR; i++, rep++) { - if (((rep->re_pcibus | rep->re_pcidev | - rep->re_pcifunc) != 0) != h) { - continue; - } - if (rl_probe(rep, i)) - rep->re_seen = TRUE; - } - } + if (rl_probe(rep, re_instance)) + rep->re_seen = TRUE; } /*===========================================================================* @@ -1189,7 +1155,7 @@ re_t *rep; long v; /* User defined ethernet address? */ - eakey[sizeof(RL_ENVVAR)-1] = '0' + (rep-re_table); + eakey[sizeof(RL_ENVVAR)-1] = '0' + re_instance; port = rep->re_base_port; @@ -1276,7 +1242,7 @@ void transmittest(re_t *rep) *===========================================================================*/ static void rl_readv_s(const message *mp, int from_int) { - int i, j, n, s, dl_port, re_client, count, size, index; + int i, j, n, s, count, size, index; port_t port; unsigned totlen, packlen; re_desc *desc; @@ -1286,13 +1252,10 @@ static void rl_readv_s(const message *mp, int from_int) int cps; int iov_offset = 0; - dl_port = mp->DL_PORT; + rep = &re_state; + + rep->re_client = mp->m_source; count = mp->DL_COUNT; - if (dl_port < 0 || dl_port >= RE_PORT_NR) - panic(" illegal port: %d", dl_port); - rep = &re_table[dl_port]; - re_client = mp->DL_PROC; - rep->re_client = re_client; assert(rep->re_mode == REM_ENABLED); assert(rep->re_flags & REF_ENABLED); @@ -1306,7 +1269,6 @@ static void rl_readv_s(const message *mp, int from_int) goto suspend; /* Receive buffer is empty, suspend */ index = rep->re_rx_head; -readvs_test_loop: desc = rep->re_rx_desc; desc += index; readvs_loop: @@ -1351,7 +1313,7 @@ readvs_loop: n = IOVEC_NR; if (i + n > count) n = count-i; - cps = sys_safecopyfrom(re_client, mp->DL_GRANT, iov_offset, + cps = sys_safecopyfrom(mp->DL_ENDPT, mp->DL_GRANT, iov_offset, (vir_bytes) rep->re_iovec_s, n * sizeof(rep->re_iovec_s[0]), D); if (cps != OK) { @@ -1365,7 +1327,7 @@ readvs_loop: s = packlen-size; } - cps = sys_safecopyto(re_client, iovp->iov_grant, 0, + cps = sys_safecopyto(mp->DL_ENDPT, iovp->iov_grant, 0, (vir_bytes) rep->re_rx[index].v_ret_buf + size, s, D); if (cps != OK) panic("rl_readv_s: sys_safecopyto failed: %d", cps); @@ -1394,7 +1356,7 @@ readvs_loop: rep->re_flags = (rep->re_flags & ~REF_READING) | REF_PACK_RECV; if (!from_int) - reply(rep, OK, FALSE); + reply(rep); return; @@ -1410,7 +1372,7 @@ suspend: assert(!(rep->re_flags & REF_READING)); rep->re_flags |= REF_READING; - reply(rep, OK, FALSE); + reply(rep); } /*===========================================================================* @@ -1418,8 +1380,8 @@ suspend: *===========================================================================*/ static void rl_writev_s(const message *mp, int from_int) { - int i, j, n, s, port, count, size; - int tx_head, re_client; + int i, j, n, s, count, size; + int tx_head; re_t *rep; iovec_s_t *iovp; re_desc *desc; @@ -1427,16 +1389,11 @@ static void rl_writev_s(const message *mp, int from_int) int cps; int iov_offset = 0; - port = mp->DL_PORT; + rep = &re_state; + + rep->re_client = mp->m_source; count = mp->DL_COUNT; - if (port < 0 || port >= RE_PORT_NR) - panic("illegal port: %d", port); - rep = &re_table[port]; - assert(mp); - assert(port >= 0 && port < RE_PORT_NR); assert(rep->setup); - re_client = mp->DL_PROC; - rep->re_client = re_client; assert(rep->re_mode == REM_ENABLED); assert(rep->re_flags & REF_ENABLED); @@ -1454,7 +1411,7 @@ static void rl_writev_s(const message *mp, int from_int) desc += tx_head; if(!desc || !rep->re_tx_desc) { - printf("desc 0x%lx, re_tx_desc 0x%lx, tx_head %d, setup %d\n", + printf("desc %p, re_tx_desc %p, tx_head %d, setup %d\n", desc, rep->re_tx_desc, tx_head, rep->setup); } @@ -1463,7 +1420,6 @@ static void rl_writev_s(const message *mp, int from_int) assert(desc); - if (rep->re_tx[tx_head].ret_busy) { assert(!(rep->re_flags & REF_SEND_AVAIL)); rep->re_flags |= REF_SEND_AVAIL; @@ -1493,7 +1449,7 @@ static void rl_writev_s(const message *mp, int from_int) n = IOVEC_NR; if (i + n > count) n = count - i; - cps = sys_safecopyfrom(re_client, mp->DL_GRANT, iov_offset, + cps = sys_safecopyfrom(mp->DL_ENDPT, mp->DL_GRANT, iov_offset, (vir_bytes) rep->re_iovec_s, n * sizeof(rep->re_iovec_s[0]), D); if (cps != OK) { @@ -1505,8 +1461,8 @@ static void rl_writev_s(const message *mp, int from_int) if (size + s > ETH_MAX_PACK_SIZE_TAGGED) panic("invalid packet size"); - cps = sys_safecopyfrom(re_client, iovp->iov_grant, 0, - (vir_bytes) ret, s, D); + cps = sys_safecopyfrom(mp->DL_ENDPT, iovp->iov_grant, + 0, (vir_bytes) ret, s, D); if (cps != OK) { panic("rl_writev_s: sys_safecopyfrom failed: %d", cps); } @@ -1540,7 +1496,7 @@ static void rl_writev_s(const message *mp, int from_int) */ if (from_int) return; - reply(rep, OK, FALSE); + reply(rep); return; suspend: @@ -1548,7 +1504,7 @@ suspend: panic("should not be sending"); rep->re_tx_mess = *mp; - reply(rep, OK, FALSE); + reply(rep); } /*===========================================================================* @@ -1580,7 +1536,7 @@ re_t *rep; rl_report_link(rep); if (rep->re_flags & (REF_PACK_SENT | REF_PACK_RECV)) - reply(rep, OK, TRUE); + reply(rep); } /*===========================================================================* @@ -1639,127 +1595,56 @@ re_t *rep; } } -/*===========================================================================* - * rl_getstat * - *===========================================================================*/ -static void rl_getstat(mp) -message *mp; -{ - int r, port; - eth_stat_t stats; - re_t *rep; - - port = mp->DL_PORT; - if (port < 0 || port >= RE_PORT_NR) - panic("illegal port: %d", port); - rep = &re_table[port]; - rep->re_client = mp->DL_PROC; - - assert(rep->re_mode == REM_ENABLED); - assert(rep->re_flags & REF_ENABLED); - - stats = rep->re_stat; - - r = sys_datacopy(SELF, (vir_bytes) &stats, mp->DL_PROC, - (vir_bytes) mp->DL_ADDR, sizeof(stats)); - if (r != OK) - panic("rl_getstat: sys_datacopy failed: %d", r); - - mp->m_type = DL_STAT_REPLY; - mp->DL_PORT = port; - mp->DL_STAT = OK; - r = send(mp->m_source, mp); - if (r != OK) - panic("rl_getstat: send failed: %d", r); -} - /*===========================================================================* * rl_getstat_s * *===========================================================================*/ static void rl_getstat_s(mp) message *mp; { - int r, port; + int r; eth_stat_t stats; re_t *rep; - port = mp->DL_PORT; - if (port < 0 || port >= RE_PORT_NR) - panic("illegal port: %d", port); - rep = &re_table[port]; - rep->re_client = mp->DL_PROC; + rep = &re_state; assert(rep->re_mode == REM_ENABLED); assert(rep->re_flags & REF_ENABLED); stats = rep->re_stat; - r = sys_safecopyto(mp->DL_PROC, mp->DL_GRANT, 0, + r = sys_safecopyto(mp->DL_ENDPT, mp->DL_GRANT, 0, (vir_bytes) &stats, sizeof(stats), D); if (r != OK) panic("rl_getstat_s: sys_safecopyto failed: %d", r); mp->m_type = DL_STAT_REPLY; - mp->DL_PORT = port; - mp->DL_STAT = OK; r = send(mp->m_source, mp); if (r != OK) panic("rl_getstat_s: send failed: %d", r); } - -/*===========================================================================* - * rl_getname * - *===========================================================================*/ -static void rl_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("rl_getname: send failed: %d", r); -} - - /*===========================================================================* * reply * *===========================================================================*/ -static void reply(rep, err, may_block) +static void reply(rep) re_t *rep; -int err; -int may_block; { message reply; - int status; + int flags; int r; - clock_t now; - status = 0; + flags = DL_NOFLAGS; if (rep->re_flags & REF_PACK_SENT) - status |= DL_PACK_SEND; + flags |= DL_PACK_SEND; if (rep->re_flags & REF_PACK_RECV) - status |= DL_PACK_RECV; + flags |= DL_PACK_RECV; reply.m_type = DL_TASK_REPLY; - reply.DL_PORT = rep - re_table; - reply.DL_PROC = rep->re_client; - reply.DL_STAT = status | ((u32_t) err << 16); + reply.DL_FLAGS = flags; reply.DL_COUNT = rep->re_read_s; - if (OK != (r = getuptime(&now))) - panic("getuptime() failed: %d", r); - reply.DL_CLCK = now; r = send(rep->re_client, &reply); - if (r == ELOCKED && may_block) { - printW(); printf("send locked\n"); - return; - } - if (r < 0) { printf("RTL8169 tried sending to %d, type %d\n", rep->re_client, reply.m_type); @@ -1964,17 +1849,14 @@ static void dump_phy(const re_t *rep) static void do_hard_int(void) { - int i, s; - - for (i = 0; i < RE_PORT_NR; i++) { + int s; - /* Run interrupt handler at driver level. */ - rl_handler(&re_table[i]); + /* Run interrupt handler at driver level. */ + rl_handler(&re_state); - /* Reenable interrupts for this hook. */ - if ((s = sys_irqenable(&re_table[i].re_hook_id)) != OK) - printf("RTL8169: error, couldn't enable interrupts: %d\n", s); - } + /* Reenable interrupts for this hook. */ + if ((s = sys_irqenable(&re_state.re_hook_id)) != OK) + printf("RTL8169: error, couldn't enable interrupts: %d\n", s); } /*===========================================================================* @@ -2091,36 +1973,35 @@ static void rl_handler(re_t *rep) static void rl_watchdog_f(tp) timer_t *tp; { - int i; re_t *rep; /* Use a synchronous alarm instead of a watchdog timer. */ sys_setalarm(system_hz, 0); - for (i = 0, rep = &re_table[0]; i < RE_PORT_NR; i++, rep++) { - if (rep->re_mode != REM_ENABLED) - continue; + rep = &re_state; - /* Should collect statistics */ - if (!(++rep->dtcc_counter % RE_DTCC_VALUE)) - rtl8169_update_stat(rep); + if (rep->re_mode != REM_ENABLED) + return; - if (!(rep->re_flags & REF_SEND_AVAIL)) { - /* Assume that an idle system is alive */ - rep->re_tx_alive = TRUE; - continue; - } - if (rep->re_tx_alive) { - rep->re_tx_alive = FALSE; - continue; - } - printf("rl_watchdog_f: resetting port %d mode 0x%x flags 0x%x\n", - i, rep->re_mode, rep->re_flags); - printf("tx_head :%8d busy %d\t", - rep->re_tx_head, rep->re_tx[rep->re_tx_head].ret_busy); - rep->re_need_reset = TRUE; - rep->re_got_int = TRUE; - - check_int_events(); + /* Should collect statistics */ + if (!(++rep->dtcc_counter % RE_DTCC_VALUE)) + rtl8169_update_stat(rep); + + if (!(rep->re_flags & REF_SEND_AVAIL)) { + /* Assume that an idle system is alive */ + rep->re_tx_alive = TRUE; + return; + } + if (rep->re_tx_alive) { + rep->re_tx_alive = FALSE; + return; } + printf("rl_watchdog_f: resetting instance %d mode 0x%x flags 0x%x\n", + re_instance, rep->re_mode, rep->re_flags); + printf("tx_head :%8d busy %d\t", + rep->re_tx_head, rep->re_tx[rep->re_tx_head].ret_busy); + rep->re_need_reset = TRUE; + rep->re_got_int = TRUE; + + check_int_events(); } diff --git a/etc/usr/rc b/etc/usr/rc index b7e20b61d..050a7f4a2 100644 --- a/etc/usr/rc +++ b/etc/usr/rc @@ -74,6 +74,14 @@ upopt() service $opt up /usr/sbin/$service "$@" } +get_eth_labels() { + # Filter out the non-vlan ethernet entries from inet.conf. + # Produce as output a list of "drivername_instancenr"-formatted labels. + # The first sed is taken from /bin as older GNU sed versions don't know '\t'. + /bin/sed 's/\t/ /g' /etc/inet.conf | \ + sed -n 's/^ *eth[0-9][0-9]* *\([^ ][^ ]*\) *\([0-9][0-9]*\).*$/\1_\2/p' | \ + grep -v '^vlan_' +} DAEMONS=/etc/rc.daemons @@ -97,15 +105,14 @@ start) dd if=/dev/random of=$RANDOM_FILE bs=1024 count=1 2> /dev/null fi - # start only network drivers that are in use - for driver in lance rtl8139 rtl8169 fxp e1000 dpeth dp8390 orinoco atl2 dec21140A - do - if grep " $driver " /etc/inet.conf > /dev/null 2>&1 - then - eval arg=\$${driver}_arg - if [ ! -z "$arg" ]; then arg="-args \"$arg\""; fi - eval up $driver $arg -period 5HZ - fi + # start network driver instances for all configured ethernet devices + for label in $(get_eth_labels); do + driver=$(echo $label | sed 's/\(.*\)_.*/\1/') + instance=$(echo $label | sed 's/.*_//') + eval arg=\$${label}_arg + if [ ! -z "$arg" ]; then arg=" $arg"; fi + arg="-args \"instance=$instance$arg\"" + eval up $driver -label $label $arg -period 5HZ done up inet -script /etc/rs.inet -dev /dev/ip -devstyle STYLE_CLONE upopt -n printer -dev /dev/lp -period 10HZ diff --git a/include/minix/com.h b/include/minix/com.h index 9d64eec8f..ab87b66ed 100644 --- a/include/minix/com.h +++ b/include/minix/com.h @@ -262,45 +262,35 @@ #define DL_RS_BASE 0x280 /* Message types for data link layer requests. */ -#define DL_WRITE (DL_RQ_BASE + 3) -#define DL_WRITEV (DL_RQ_BASE + 4) -#define DL_READ (DL_RQ_BASE + 5) -#define DL_READV (DL_RQ_BASE + 6) -#define DL_CONF (DL_RQ_BASE + 7) -#define DL_STOP (DL_RQ_BASE + 8) -#define DL_GETSTAT (DL_RQ_BASE + 9) -#define DL_GETNAME (DL_RQ_BASE +10) -#define DL_WRITEV_S (DL_RQ_BASE +11) -#define DL_READV_S (DL_RQ_BASE +12) -#define DL_GETSTAT_S (DL_RQ_BASE +13) +#define DL_CONF (DL_RQ_BASE + 0) +#define DL_GETSTAT_S (DL_RQ_BASE + 1) +#define DL_WRITEV_S (DL_RQ_BASE + 2) +#define DL_READV_S (DL_RQ_BASE + 3) /* Message type for data link layer replies. */ -#define DL_CONF_REPLY (DL_RS_BASE + 20) -#define DL_TASK_REPLY (DL_RS_BASE + 21) -#define DL_NAME_REPLY (DL_RS_BASE + 22) -#define DL_STAT_REPLY (DL_RS_BASE + 23) +#define DL_CONF_REPLY (DL_RS_BASE + 0) +#define DL_STAT_REPLY (DL_RS_BASE + 1) +#define DL_TASK_REPLY (DL_RS_BASE + 2) /* Field names for data link layer messages. */ -#define DL_PORT m2_i1 -#define DL_PROC m2_i2 /* endpoint */ +#define DL_ENDPT m2_i2 #define DL_COUNT m2_i3 #define DL_MODE m2_l1 -#define DL_CLCK m2_l2 -#define DL_ADDR m2_p1 -#define DL_STAT m2_l1 +#define DL_FLAGS m2_l1 #define DL_GRANT m2_l2 -#define DL_NAME m3_ca1 +#define DL_STAT m3_i1 +#define DL_HWADDR m3_ca1 -/* Bits in 'DL_STAT' field of DL replies. */ +/* Bits in 'DL_FLAGS' field of DL replies. */ +# define DL_NOFLAGS 0x00 # define DL_PACK_SEND 0x01 # define DL_PACK_RECV 0x02 -# define DL_READ_IP 0x04 /* Bits in 'DL_MODE' field of DL requests. */ # define DL_NOMODE 0x0 -# define DL_PROMISC_REQ 0x2 -# define DL_MULTI_REQ 0x4 -# define DL_BROAD_REQ 0x8 +# define DL_PROMISC_REQ 0x1 +# define DL_MULTI_REQ 0x2 +# define DL_BROAD_REQ 0x4 /*===========================================================================* * SYSTASK request types and field names * diff --git a/include/sys/asynchio.h b/include/sys/asynchio.h index 0fa9280f5..726dd1ec4 100644 --- a/include/sys/asynchio.h +++ b/include/sys/asynchio.h @@ -1,38 +1,42 @@ /* asynchio.h - Asynchronous I/O Author: Kees J. Bot - * 26 Jan 1995 - * This is just a fake async I/O library to be used for programs - * written for Minix-vmd that must also run under standard Minix. - * This limits the number of ugly #ifdefs somewhat. The programs must - * be restricted to performing just one service, of course. + * 7 Jul 1997 + * Minix-vmd compatible asynchio(3) using BSD select(2). */ #ifndef _SYS__ASYNCHIO_H #define _SYS__ASYNCHIO_H -#ifndef _ANSI_H -#include -#endif +#include /* for FD_SETSIZE */ -#include +#define SEL_READ 0 /* Code for a read. */ +#define SEL_WRITE 1 /* Code for a write. */ +#define SEL_EXCEPT 2 /* Code for some exception. */ +#define SEL_NR 3 /* Number of codes. */ + +struct _asynfd { + int afd_seen; /* Set if we manage this descriptor. */ + int afd_flags; /* File flags by fcntl(fd, F_GETFL). */ + int afd_state[SEL_NR]; /* Operation state. */ +}; typedef struct { - char state; - char op; - char fd; - char req; - void *data; - ssize_t count; - int errno; + int asyn_more; /* Set if more to do before blocking. */ + struct _asynfd asyn_afd[FD_SETSIZE]; + fd_set asyn_fdset[SEL_NR]; /* Select() fd sets. */ } asynchio_t; -#define ASYN_NONBLOCK 0x01 +#define ASYN_INPROGRESS EAGAIN /* Errno code telling "nothing yet." */ +#define ASYN_NONBLOCK 0x01 /* If asyn_wait() mustn't block. */ -#define ASYN_INPROGRESS EINPROGRESS +struct timeval; void asyn_init(asynchio_t *_asyn); ssize_t asyn_read(asynchio_t *_asyn, int _fd, void *_buf, size_t _len); ssize_t asyn_write(asynchio_t *_asyn, int _fd, const void *_buf, size_t _len); -int asyn_ioctl(asynchio_t *_asyn, int _fd, unsigned long _request, void *_data); +int asyn_special(asynchio_t *_asyn, int _fd, int _op); +int asyn_result(asynchio_t *_asyn, int _fd, int _op, int _result); int asyn_wait(asynchio_t *_asyn, int _flags, struct timeval *to); +int asyn_cancel(asynchio_t *_asyn, int _fd, int _op); +int asyn_pending(asynchio_t *_asyn, int _fd, int _op); int asyn_synch(asynchio_t *_asyn, int _fd); int asyn_close(asynchio_t *_asyn, int _fd); diff --git a/lib/libc/Makefile b/lib/libc/Makefile index 7e95cb1c4..1227c3d35 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -7,7 +7,7 @@ LIB= c CPPFLAGS+=-O -D_MINIX -D_POSIX_SOURCE .include "${.CURDIR}/ansi/Makefile.inc" -.include "${.CURDIR}/wchar/Makefile.inc" +.include "${.CURDIR}/asyn/Makefile.inc" .include "${.CURDIR}/ip/Makefile.inc" .include "${.CURDIR}/math/Makefile.inc" .include "${.CURDIR}/other/Makefile.inc" @@ -17,6 +17,7 @@ CPPFLAGS+=-O -D_MINIX -D_POSIX_SOURCE .include "${.CURDIR}/stdtime/Makefile.inc" .include "${.CURDIR}/syscall/Makefile.inc" .include "${.CURDIR}/sysvipc/Makefile.inc" +.include "${.CURDIR}/wchar/Makefile.inc" .include "${.CURDIR}/arch/${ARCH}/int64/Makefile.inc" .include "${.CURDIR}/arch/${ARCH}/misc/Makefile.inc" diff --git a/lib/libc/asyn/Makefile.inc b/lib/libc/asyn/Makefile.inc new file mode 100644 index 000000000..d2b10bc90 --- /dev/null +++ b/lib/libc/asyn/Makefile.inc @@ -0,0 +1,12 @@ +# ansi sources +.PATH: ${.CURDIR}/asyn + +SRCS+= \ + asyn_cancel.c \ + asyn_close.c \ + asyn_init.c \ + asyn_pending.c \ + asyn_read.c \ + asyn_synch.c \ + asyn_wait.c \ + asyn_write.c diff --git a/lib/libc/asyn/asyn.h b/lib/libc/asyn/asyn.h new file mode 100644 index 000000000..4acfdbbd6 --- /dev/null +++ b/lib/libc/asyn/asyn.h @@ -0,0 +1,17 @@ +/* asyn.h - async I/O + * Author: Kees J. Bot + * 7 Jul 1997 + * Minix-vmd compatible asynchio(3) using BSD select(2). + */ +#define nil 0 +#include +#include +#include +#include +#include +#include +#include + +typedef struct _asynfd asynfd_t; + +typedef enum state { IDLE, WAITING, PENDING } state_t; diff --git a/lib/libc/asyn/asyn_cancel.c b/lib/libc/asyn/asyn_cancel.c new file mode 100644 index 000000000..664c17bd7 --- /dev/null +++ b/lib/libc/asyn/asyn_cancel.c @@ -0,0 +1,21 @@ +/* asyn_cancel() - cancel an asynch operation Author: Kees J. Bot + * 7 Jul 1997 + */ +#include "asyn.h" + +int asyn_cancel(asynchio_t *asyn, int fd, int op) +/* Cancel an asynchronous operation if one is in progress. (This is easy with + * select(2), because no operation is actually happening.) + */ +{ + asynfd_t *afd; + + if ((unsigned) fd >= FD_SETSIZE) { errno= EBADF; return -1; } + afd= &asyn->asyn_afd[fd]; + + if (afd->afd_state[op] == WAITING) { + afd->afd_state[op]= IDLE; + FD_CLR(fd, &asyn->asyn_fdset[SEL_READ]); + } + return 0; +} diff --git a/lib/libc/asyn/asyn_close.c b/lib/libc/asyn/asyn_close.c new file mode 100644 index 000000000..a0154f980 --- /dev/null +++ b/lib/libc/asyn/asyn_close.c @@ -0,0 +1,24 @@ +/* asyn_close() - forcefully forget about a file descriptor + * Author: Kees J. Bot + * 7 Jul 1997 + */ +#include "asyn.h" + +int asyn_close(asynchio_t *asyn, int fd) +/* Stop caring about any async operations on this file descriptor. */ +{ + asynfd_t *afd; + int op; + + if ((unsigned) fd >= FD_SETSIZE) { errno= EBADF; return -1; } + + afd= &asyn->asyn_afd[fd]; + + for (op= 0; op < SEL_NR; op++) { + afd->afd_state[op]= IDLE; + FD_CLR(fd, &asyn->asyn_fdset[op]); + } + afd->afd_seen= 0; + asyn->asyn_more++; + return 0; +} diff --git a/lib/libc/asyn/asyn_init.c b/lib/libc/asyn/asyn_init.c new file mode 100644 index 000000000..f91f4fba7 --- /dev/null +++ b/lib/libc/asyn/asyn_init.c @@ -0,0 +1,9 @@ +/* asyn_init() Author: Kees J. Bot + * 7 Jul 1997 + */ +#include "asyn.h" + +void asyn_init(asynchio_t *asyn) +{ + memset(asyn, 0, sizeof(*asyn)); +} diff --git a/lib/libc/asyn/asyn_pending.c b/lib/libc/asyn/asyn_pending.c new file mode 100644 index 000000000..fa5f74b12 --- /dev/null +++ b/lib/libc/asyn/asyn_pending.c @@ -0,0 +1,14 @@ +/* asyn_pending() - any results pending? Author: Kees J. Bot + * 7 Jul 1997 + */ +#include "asyn.h" + +int asyn_pending(asynchio_t *asyn, int fd, int op) +/* Check if a result of an operation is pending. (This is easy with + * select(2), because no operation is actually happening.) + */ +{ + if ((unsigned) fd >= FD_SETSIZE) { errno= EBADF; return -1; } + + return 0; +} diff --git a/lib/libc/asyn/asyn_read.c b/lib/libc/asyn/asyn_read.c new file mode 100644 index 000000000..b5f02a086 --- /dev/null +++ b/lib/libc/asyn/asyn_read.c @@ -0,0 +1,61 @@ +/* asyn_read() Author: Kees J. Bot + * 7 Jul 1997 + */ +#include "asyn.h" +#include + +ssize_t asyn_read(asynchio_t *asyn, int fd, void *buf, size_t len) +/* Asynchronous read(). Try if a read can be done, if not then set a flag + * indicating that select(2) should look out for it. Returns like a normal + * read or returns -1 with errno set to EAGAIN. + */ +{ + asynfd_t *afd; + + /* Asyn_wait() may block if this counter equals zero indicating that + * all of the asyn_* functions are "in progress". + */ + asyn->asyn_more++; + + if ((unsigned) fd >= FD_SETSIZE) { errno= EBADF; return -1; } + afd= &asyn->asyn_afd[fd]; + + /* If this is the first async call on this filedescriptor then + * remember its file flags. + */ + if (!afd->afd_seen) { + if ((afd->afd_flags= fcntl(fd, F_GETFL)) < 0) return -1; + afd->afd_seen= 1; + } + + /* Try to read if I/O is pending. */ + if (afd->afd_state[SEL_READ] == PENDING) { + sigset_t mask; + ssize_t result; + int err; + + sigemptyset(&mask); + if (sigprocmask(SIG_SETMASK, &mask, &mask) < 0) return -1; + (void) fcntl(fd, F_SETFL, afd->afd_flags | O_NONBLOCK); + + /* Try the actual read. */ + result= read(fd, buf, len); + err= errno; + + (void) fcntl(fd, F_SETFL, afd->afd_flags); + (void) sigprocmask(SIG_SETMASK, &mask, nil); + + errno= err; + if (result != -1 || errno != EAGAIN) { + afd->afd_state[SEL_READ]= IDLE; + return result; + } + } + + /* Record this read as "waiting". */ + afd->afd_state[SEL_READ]= WAITING; + FD_SET(fd, &asyn->asyn_fdset[SEL_READ]); + errno= EAGAIN; + asyn->asyn_more--; + return -1; +} diff --git a/lib/libc/asyn/asyn_special.c b/lib/libc/asyn/asyn_special.c new file mode 100644 index 000000000..544bc4299 --- /dev/null +++ b/lib/libc/asyn/asyn_special.c @@ -0,0 +1,104 @@ +/* asyn_special(), asyn_result() Author: Kees J. Bot + * 8 Jul 1997 + */ +#include "asyn.h" +#include + +/* Saved signal mask between asyn_special() and asyn_result(). */ +static sigset_t mask; + +int asyn_special(asynchio_t *asyn, int fd, int op) +/* Wait for an operation. This is an odd one out compared to asyn_read() + * and asyn_write(). It does not do an operation itself, but together with + * asyn_result() it is a set of brackets around a system call xxx that has + * no asyn_xxx() for itself. It can be used to build an asyn_accept() or + * asyn_connect() for instance. (Minix-vmd has asyn_ioctl() instead, + * which is used for any other event like TCP/IP listen/connect. BSD has + * a myriad of calls that can't be given an asyn_xxx() counterpart each.) + * Asyn_special() returns -1 for "forget it", 0 for "try it", and 1 for + * "very first call, maybe you should try it once, maybe not". Errno is + * set to EAGAIN if the result is -1 or 1. After trying the system call + * make sure errno equals EAGAIN if the call is still in progress and call + * asyn_result with the result of the system call. Asyn_result() must be + * called if asyn_special() returns 0 or 1. + * + * Example use: + * + * int asyn_accept(asynchio_t *asyn, int s, struct sockaddr *addr, int *addrlen) + * { + * int r; + * if ((r= asyn_special(asyn, fd, SEL_READ)) < 0) return -1; + * r= r == 0 ? accept(fd, addr, addrlen) : -1; + * return asyn_result(asyn, fd, SEL_READ, r); + * } + * + * int asyn_connect(asynchio_t *asyn, int s, struct sockaddr *name, int namelen) + * { + * int r; + * if ((r= asyn_special(asyn, fd, SEL_WRITE)) < 0) return -1; + * if (r == 1 && (r= connect(fd, name, namelen)) < 0) { + * if (errno == EINPROGRESS) errno= EAGAIN; + * } + * return asyn_result(asyn, fd, SEL_WRITE, r); + * } + */ +{ + asynfd_t *afd; + int seen; + + asyn->asyn_more++; + + if ((unsigned) fd >= FD_SETSIZE) { errno= EBADF; return -1; } + afd= &asyn->asyn_afd[fd]; + + /* If this is the first async call on this filedescriptor then + * remember its file flags. + */ + if (!(seen= afd->afd_seen)) { + if ((afd->afd_flags= fcntl(fd, F_GETFL)) < 0) return -1; + afd->afd_seen= 1; + } + + /* Try to read if I/O is pending. */ + if (!seen || afd->afd_state[op] == PENDING) { + sigemptyset(&mask); + if (sigprocmask(SIG_SETMASK, &mask, &mask) < 0) return -1; + (void) fcntl(fd, F_SETFL, afd->afd_flags | O_NONBLOCK); + + /* Let the caller try the system call. */ + errno= EAGAIN; + return seen ? 0 : 1; + } + + /* Record this read as "waiting". */ + afd->afd_state[op]= WAITING; + FD_SET(fd, &asyn->asyn_fdset[op]); + errno= EAGAIN; + asyn->asyn_more--; + return -1; +} + +int asyn_result(asynchio_t *asyn, int fd, int op, int result) +/* The caller has tried the system call with the given result. Finish up. */ +{ + int err; + asynfd_t *afd= &asyn->asyn_afd[fd]; + + err= errno; + + (void) fcntl(fd, F_SETFL, afd->afd_flags); + (void) sigprocmask(SIG_SETMASK, &mask, nil); + + errno= err; + if (result != -1 || errno != EAGAIN) { + afd->afd_state[op]= IDLE; + return result; + } + + /* Record this operation as "waiting". */ + afd->afd_state[op]= WAITING; + FD_SET(fd, &asyn->asyn_fdset[op]); + errno= EAGAIN; + asyn->asyn_more--; + return -1; +} diff --git a/lib/libc/asyn/asyn_synch.c b/lib/libc/asyn/asyn_synch.c new file mode 100644 index 000000000..d54be789c --- /dev/null +++ b/lib/libc/asyn/asyn_synch.c @@ -0,0 +1,27 @@ +/* asyn_synch() - step back to synch Author: Kees J. Bot + * 7 Jul 1997 + */ +#include "asyn.h" + +int asyn_synch(asynchio_t *asyn, int fd) +/* No more asynchronous operations on this file descriptor. */ +{ + asynfd_t *afd; + int flags; + int op; + + if ((unsigned) fd >= FD_SETSIZE) { errno= EBADF; return -1; } + afd= &asyn->asyn_afd[fd]; + + for (op= 0; op < SEL_NR; op++) { + if (afd->afd_state[op] != IDLE) { + errno= EAGAIN; + return -1; + } + } + + /* Make sure the file flags are as they once were. */ + if (afd->afd_seen && fcntl(fd, F_SETFL, afd->afd_flags) < 0) return -1; + afd->afd_seen= 0; + return 0; +} diff --git a/lib/libc/asyn/asyn_wait.c b/lib/libc/asyn/asyn_wait.c new file mode 100644 index 000000000..c71e5d074 --- /dev/null +++ b/lib/libc/asyn/asyn_wait.c @@ -0,0 +1,119 @@ +/* asyn_wait() - wait for asynch operations Author: Kees J. Bot + * 7 Jul 1997 + */ +#define DEBUG 0 + +#include "asyn.h" +#include +#if DEBUG +#include +#endif + +#define TBOUND_MIN 1 +#define TBOUND_MAX 16 + +int asyn_wait(asynchio_t *asyn, int flags, struct timeval *to) +/* Wait for one or more nonblocking operations to return a result. */ +{ + int r; + static struct timeval zero_time; + struct timeval t; + static time_t tbound= TBOUND_MIN; + + /* Are there more things to do before we can block? */ + if (asyn->asyn_more > 0) { asyn->asyn_more= 0; return 0; } + + if (flags & ASYN_NONBLOCK) { + /* Don't block by using a zero second timeout. */ + to= &zero_time; + } else + if (to != nil) { + /* asyn_wait() uses an absolute time. */ + if (to->tv_usec >= 1000000L) { + to->tv_sec+= to->tv_usec / 1000000L; + to->tv_usec%= 1000000L; + } + (void) gettimeofday(&t, nil); + if (t.tv_sec > to->tv_sec || (t.tv_sec == to->tv_sec + && t.tv_usec >= to->tv_usec)) { + to= &zero_time; + } else { + t.tv_sec= to->tv_sec - t.tv_sec; + t.tv_usec= to->tv_usec - t.tv_usec; + if (t.tv_usec < 0) { + t.tv_sec--; + t.tv_usec+= 1000000L; + } + to= &t; + } + + /* Don't sleep too long, we don't trust select(). */ + if (to->tv_sec > tbound) goto bound; + } else { + bound: + /* No timeout? Don't hang in (buggy?) select() forever. */ + to= &t; + t.tv_sec= tbound; + t.tv_usec= 0; + } + +#if DEBUG + { + int op; + + fprintf(stderr, "select: "); + for (op= 0; op < SEL_NR; op++) { + fd_set *fdsetp= &asyn->asyn_fdset[op]; + int fd; + + for (fd= 0; fd < FD_SETSIZE; fd++) { + if (FD_ISSET(fd, fdsetp)) { + asyn->asyn_afd[fd].afd_state[op]= + PENDING; + fprintf(stderr, "%d%c", fd, "rwx"[op]); + } + } + } + fflush(stderr); + } +#endif + r= select(FD_SETSIZE, &asyn->asyn_fdset[SEL_READ], + &asyn->asyn_fdset[SEL_WRITE], + &asyn->asyn_fdset[SEL_EXCEPT], to); +#if DEBUG + fprintf(stderr, " (%d) ", r); +#endif + if (r > 0) { + /* An event occurred on one or more file descriptors. */ + int op; + + for (op= 0; op < SEL_NR; op++) { + fd_set *fdsetp= &asyn->asyn_fdset[op]; + int fd; + + for (fd= 0; fd < FD_SETSIZE; fd++) { + if (FD_ISSET(fd, fdsetp)) { + asyn->asyn_afd[fd].afd_state[op]= + PENDING; +#if DEBUG + fprintf(stderr, "%d%c", fd, "rwx"[op]); +#endif + } + } + } + tbound= TBOUND_MIN; + } else + if (r == 0) { + /* If nothing happened then let the time boundary slip a bit. */ + if (tbound < TBOUND_MAX) tbound <<= 1; + } +#if DEBUG + fputc('\n', stderr); +#endif + + FD_ZERO(&asyn->asyn_fdset[SEL_READ]); + FD_ZERO(&asyn->asyn_fdset[SEL_WRITE]); + FD_ZERO(&asyn->asyn_fdset[SEL_EXCEPT]); + + return r == 0 ? (errno= EINTR, -1) : r; +} diff --git a/lib/libc/asyn/asyn_write.c b/lib/libc/asyn/asyn_write.c new file mode 100644 index 000000000..1c3afdd78 --- /dev/null +++ b/lib/libc/asyn/asyn_write.c @@ -0,0 +1,50 @@ +/* asyn_write() Author: Kees J. Bot + * 7 Jul 1997 + */ +#include "asyn.h" +#include + +ssize_t asyn_write(asynchio_t *asyn, int fd, const void *buf, size_t len) +/* Nonblocking write(). (See asyn_read()). */ +{ + asynfd_t *afd; + ssize_t result; + + asyn->asyn_more++; + + if ((unsigned) fd >= FD_SETSIZE) { errno= EBADF; return -1; } + afd= &asyn->asyn_afd[fd]; + + if (!afd->afd_seen) { + if ((afd->afd_flags= fcntl(fd, F_GETFL)) < 0) return -1; + afd->afd_seen= 1; + } + + if (afd->afd_state[SEL_WRITE] == PENDING) { + sigset_t mask; + ssize_t result; + int err; + + sigemptyset(&mask); + if (sigprocmask(SIG_SETMASK, &mask, &mask) < 0) return -1; + (void) fcntl(fd, F_SETFL, afd->afd_flags | O_NONBLOCK); + + result= write(fd, buf, len); + err= errno; + + (void) fcntl(fd, F_SETFL, afd->afd_flags); + (void) sigprocmask(SIG_SETMASK, &mask, nil); + + errno= err; + if (result != -1 || errno != EAGAIN) { + afd->afd_state[SEL_WRITE]= IDLE; + return result; + } + } + + afd->afd_state[SEL_WRITE]= WAITING; + FD_SET(fd, &asyn->asyn_fdset[SEL_WRITE]); + errno= EAGAIN; + asyn->asyn_more--; + return -1; +} diff --git a/lib/libc/other/Makefile.inc b/lib/libc/other/Makefile.inc index 56f6da8f9..1411f7ced 100644 --- a/lib/libc/other/Makefile.inc +++ b/lib/libc/other/Makefile.inc @@ -35,7 +35,6 @@ SRCS+= \ _vm_set_priv.c \ _vm_update.c \ _vm_query_exit.c \ - asynchio.c \ basename.c \ bcmp.c \ bcopy.c \ diff --git a/lib/libc/other/asynchio.c b/lib/libc/other/asynchio.c deleted file mode 100644 index ee7434bda..000000000 --- a/lib/libc/other/asynchio.c +++ /dev/null @@ -1,153 +0,0 @@ -/* asyn_init(), asyn_read(), asyn_write(), asyn_ioctl(), - * asyn_wait(), asyn_synch(), asyn_close() - * Author: Kees J. Bot - * 26 Jan 1995 - * Thise are just stub routines that are call compatible with - * the asynchio(3) library of Minix-vmd. See asynchio.h. - */ -#define alarm _alarm -#define ioctl _ioctl -#define read _read -#define sigaction _sigaction -#define sigfillset _sigfillset -#define time _time -#define write _write -#include -#include -#include -#include -#include -#include -#include -#include - -#define IO_IDLE 0 -#define IO_INPROGRESS 1 -#define IO_RESULT 2 - -#define OP_NOOP 0 -#define OP_READ 1 -#define OP_WRITE 2 -#define OP_IOCTL 3 - -static asynchio_t *asyn_current; - -void asyn_init(asynchio_t *asyn) -{ - asyn->state= IO_IDLE; - asyn->op= OP_NOOP; -} - -static ssize_t operation(int op, asynchio_t *asyn, int fd, int req, - void *data, ssize_t count) -{ - switch (asyn->state) { - case IO_INPROGRESS: - if (asyn_current != asyn && asyn->op != op) abort(); - /*FALL THROUGH*/ - case IO_IDLE: - asyn_current= asyn; - asyn->op= op; - asyn->fd= fd; - asyn->req= req; - asyn->data= data; - asyn->count= count; - asyn->state= IO_INPROGRESS; - errno= EINPROGRESS; - return -1; - case IO_RESULT: - if (asyn_current != asyn && asyn->op != op) abort(); - errno= asyn->errno; - return asyn->count; - } -} - -ssize_t asyn_read(asynchio_t *asyn, int fd, void *buf, size_t len) -{ - return operation(OP_READ, asyn, fd, 0, buf, len); -} - -ssize_t asyn_write(asynchio_t *asyn, int fd, const void *buf, size_t len) -{ - return operation(OP_WRITE, asyn, fd, 0, (void *) buf, len); -} - -int asyn_ioctl(asynchio_t *asyn, int fd, unsigned long request, void *data) -{ - return operation(OP_IOCTL, asyn, fd, request, data, 0); -} - -static void time_out(int sig) -{ - alarm(1); -} - -int asyn_wait(asynchio_t *asyn, int flags, struct timeval *to) -{ - time_t now; - unsigned old_timer, new_timer; - struct sigaction old_sa, new_sa; - - if (asyn_current != asyn) abort(); - if (flags & ASYN_NONBLOCK) abort(); - - if (asyn->state == IO_RESULT) { - asyn->state= IO_IDLE; - asyn->op= OP_NOOP; - return 0; - } - - if (to != NULL) { - now= time(NULL); - if (to->tv_sec <= now) { errno= EINTR; return -1; } - old_timer= alarm(0); - new_sa.sa_handler= time_out; - sigfillset(&new_sa.sa_mask); - new_sa.sa_flags= 0; - sigaction(SIGALRM, &new_sa, &old_sa); - new_timer= to->tv_sec - now; - if (new_timer < old_timer) { - new_timer= old_timer; - } - alarm(new_timer); - } - switch (asyn->op) { - case OP_NOOP: - asyn->count= pause(); - asyn->errno= errno; - case OP_READ: - asyn->count= read(asyn->fd, asyn->data, asyn->count); - asyn->errno= errno; - break; - case OP_WRITE: - asyn->count= write(asyn->fd, asyn->data, asyn->count); - asyn->errno= errno; - break; - case OP_IOCTL: - asyn->count= ioctl(asyn->fd, asyn->req, asyn->data); - asyn->errno= errno; - break; - } - if (to != NULL) { - alarm(0); - sigaction(SIGALRM, &old_sa, (struct sigaction *)0); - alarm(old_timer); - } - - if (asyn->count == -1 && asyn->errno == EINTR) { - errno= EINTR; - return -1; - } else { - asyn->state= IO_RESULT; - return 0; - } -} - -int asyn_synch(asynchio_t *asyn, int fd) -{ -} - -int asyn_close(asynchio_t *asyn, int fd) -{ - asyn_init(asyn); -} diff --git a/lib/libnetdriver/netdriver.c b/lib/libnetdriver/netdriver.c index defc302cd..6d5cc3730 100644 --- a/lib/libnetdriver/netdriver.c +++ b/lib/libnetdriver/netdriver.c @@ -64,7 +64,7 @@ int *status_ptr; if(m_ptr->m_type == DL_CONF) { conf_expected = FALSE; } - else if(m_ptr->m_type != DL_GETNAME) { + else { continue; } } diff --git a/man/man8/inet.8 b/man/man8/inet.8 index 9ebfd3774..a61ac3f82 100644 --- a/man/man8/inet.8 +++ b/man/man8/inet.8 @@ -39,7 +39,7 @@ It tells that network 0 (the one containing devices and .BR udp0 ) uses the ethernet device driver handled -by task "DP8390" at port 0. This network is marked as the default +by driver "DP8390" instance 0. This network is marked as the default network, so most programs use it through the unnumbered devices like .B /dev/tcp or @@ -47,21 +47,20 @@ or Network 1 is a Pseudo IP network that can be used for a serial IP over a modem for instance. .PP -The configuration file may look like a common configuration file as -described by -.BR configfile (5), -but it is currently just a simple subset allowing only what you see here. +The configuration file uses a simple line-based format. +Each network definition has to be fully on its own line. +Empty lines and lines that start with a `#' symbol are ignored. The following network definitions are possible: .PP .BI eth N -.I task port +.I driver instance .RI { options }; .RS This sets up an ethernet with device name .BI /dev/eth N\fR, -built on the given ethernet device driver at the given port at that driver. -(If a network driver manages two network -cards then they are at port 0 and 1.) +built on the given ethernet device driver with the given instance number. +(If there are two network cards of the same type +then they will be managed by instance 0 and 1 of the corresponding driver.) .br .RE .PP diff --git a/servers/inet/generic/ip.c b/servers/inet/generic/ip.c index 193be4df6..a80ac337f 100644 --- a/servers/inet/generic/ip.c +++ b/servers/inet/generic/ip.c @@ -184,8 +184,31 @@ PRIVATE int ip_select(fd, operations) int fd; unsigned operations; { - printf("ip_select: not implemented\n"); - return 0; + unsigned resops; + ip_fd_t *ip_fd; + + ip_fd= &ip_fd_table[fd]; + assert (ip_fd->if_flags & IFF_INUSE); + + resops= 0; + + if (operations & SR_SELECT_READ) + { + if (ip_sel_read(ip_fd)) + resops |= SR_SELECT_READ; + else if (!(operations & SR_SELECT_POLL)) + ip_fd->if_flags |= IFF_SEL_READ; + } + if (operations & SR_SELECT_WRITE) + { + /* Should handle special case when the interface is down */ + resops |= SR_SELECT_WRITE; + } + if (operations & SR_SELECT_EXCEPTION) + { + printf("ip_select: not implemented for exceptions\n"); + } + return resops; } PUBLIC int ip_open (port, srfd, get_userdata, put_userdata, put_pkt, @@ -230,6 +253,7 @@ select_res_t select_res; ip_fd->if_get_userdata= get_userdata; ip_fd->if_put_userdata= put_userdata; ip_fd->if_put_pkt= put_pkt; + ip_fd->if_select_res= select_res; return i; } diff --git a/servers/inet/generic/ip_int.h b/servers/inet/generic/ip_int.h index a9bbfa703..a1c8cf735 100644 --- a/servers/inet/generic/ip_int.h +++ b/servers/inet/generic/ip_int.h @@ -112,6 +112,7 @@ typedef struct ip_fd get_userdata_t if_get_userdata; put_userdata_t if_put_userdata; put_pkt_t if_put_pkt; + select_res_t if_select_res; time_t if_exp_time; size_t if_rd_count; ioreq_t if_ioctl; @@ -120,9 +121,10 @@ typedef struct ip_fd #define IFF_EMPTY 0x00 #define IFF_INUSE 0x01 #define IFF_OPTSET 0x02 -#define IFF_BUSY 0x1C +#define IFF_BUSY 0x0C # define IFF_READ_IP 0x04 # define IFF_IOCTL_IP 0x08 +#define IFF_SEL_READ 0x10 typedef enum nettype { @@ -166,6 +168,7 @@ void ip_port_arrive ARGS(( ip_port_t *port, acc_t *pack, ip_hdr_t *ip_hdr )); void ip_arrived ARGS(( ip_port_t *port, acc_t *pack )); void ip_arrived_broadcast ARGS(( ip_port_t *port, acc_t *pack )); void ip_process_loopb ARGS(( event_t *ev, ev_arg_t arg )); +int ip_sel_read ARGS(( ip_fd_t *ip_fd )); void ip_packet2user ARGS(( ip_fd_t *ip_fd, acc_t *pack, time_t exp_time, size_t data_len )); diff --git a/servers/inet/generic/ip_read.c b/servers/inet/generic/ip_read.c index 5bb89c400..377fd78a6 100644 --- a/servers/inet/generic/ip_read.c +++ b/servers/inet/generic/ip_read.c @@ -16,6 +16,7 @@ Copyright 1995 Philip Homburg #include "ip.h" #include "ip_int.h" #include "ipr.h" +#include "sr.h" THIS_FILE @@ -361,6 +362,28 @@ acc_t *pack; return TRUE; } +PUBLIC int ip_sel_read (ip_fd_t *ip_fd) +{ + acc_t *pack; + + if (!(ip_fd->if_flags & IFF_OPTSET)) + return 1; /* Read will not block */ + + if (ip_fd->if_rdbuf_head) + { + if (get_time() <= ip_fd->if_exp_time) + return 1; + + while (ip_fd->if_rdbuf_head) + { + pack= ip_fd->if_rdbuf_head; + ip_fd->if_rdbuf_head= pack->acc_ext_link; + bf_afree(pack); + } + } + return 0; +} + PUBLIC void ip_packet2user (ip_fd, pack, exp_time, data_len) ip_fd_t *ip_fd; acc_t *pack; @@ -391,6 +414,16 @@ size_t data_len; else ip_fd->if_rdbuf_tail->acc_ext_link= pack; ip_fd->if_rdbuf_tail= pack; + + if (ip_fd->if_flags & IFF_SEL_READ) + { + ip_fd->if_flags & ~IFF_SEL_READ; + if (ip_fd->if_select_res) + ip_fd->if_select_res(ip_fd->if_srfd, + SR_SELECT_READ); + else + printf("ip_packet2user: no select_res\n"); + } return; } diff --git a/servers/inet/inet.c b/servers/inet/inet.c index a9278b23d..3e11a4956 100644 --- a/servers/inet/inet.c +++ b/servers/inet/inet.c @@ -30,16 +30,7 @@ from FS: |_______________|___________|_________|_______|__________|_________| from DL_ETH: - _______________________________________________________________________ -| | | | | | | -| m_type | DL_PORT | DL_PROC | DL_COUNT | DL_STAT | DL_TIME | -|_______________|___________|_________|__________|____________|_________| -| | | | | | | -| DL_CONF_REPLY | minor dev | proc nr | rd_count | 0 | stat | time | -|_______________|___________|_________|__________|____________|_________| -| | | | | | | -| DL_TASK_REPLY | minor dev | proc nr | rd_count | err | stat | time | -|_______________|___________|_________|__________|____________|_________| + (not documented here) */ #include "inet.h" @@ -178,7 +169,7 @@ PUBLIC void main() } } else if (m_type == DL_CONF_REPLY || m_type == DL_TASK_REPLY || - m_type == DL_NAME_REPLY || m_type == DL_STAT_REPLY) + m_type == DL_STAT_REPLY) { eth_rec(&mq->mq_mess); mq_free(mq); @@ -338,32 +329,37 @@ PRIVATE void ds_event() { char key[DS_MAX_KEYLEN]; char *driver_prefix = "drv.net."; + char *label; u32_t value; int type; endpoint_t owner_endpoint; int r; - /* Get the event and the owner from DS. */ - r = ds_check(key, &type, &owner_endpoint); - if(r != OK) { - if(r != ENOENT) - printf("inet: ds_event: ds_check failed: %d\n", r); - return; - } - r = ds_retrieve_u32(key, &value); - if(r != OK) { - printf("inet: ds_event: ds_retrieve_u32 failed\n"); - return; - } + /* We may get one notification for multiple updates from DS. Get events + * and owners from DS, until DS tells us that there are no more. + */ + while ((r = ds_check(key, &type, &owner_endpoint)) == OK) { + r = ds_retrieve_u32(key, &value); + if(r != OK) { + printf("inet: ds_event: ds_retrieve_u32 failed\n"); + return; + } + + /* Only check for network driver up events. */ + if(strncmp(key, driver_prefix, sizeof(driver_prefix)) + || value != DS_DRIVER_UP) { + return; + } + + /* The driver label comes after the prefix. */ + label = key + strlen(driver_prefix); - /* Only check for network driver up events. */ - if(strncmp(key, driver_prefix, sizeof(driver_prefix)) - || value != DS_DRIVER_UP) { - return; + /* A driver is (re)started. */ + eth_check_driver(label, owner_endpoint); } - /* A driver is (re)started. */ - eth_check_driver(owner_endpoint); + if(r != ENOENT) + printf("inet: ds_event: ds_check failed: %d\n", r); } PUBLIC void panic0(file, line) diff --git a/servers/inet/inet_config.c b/servers/inet/inet_config.c index 2005e22dc..af54173a8 100644 --- a/servers/inet/inet_config.c +++ b/servers/inet/inet_config.c @@ -147,18 +147,55 @@ static void check_dev(int type, int ifno) static int cfg_fd; static char word[16]; -static unsigned line; +static unsigned char line[256], *lineptr; +static unsigned linenr; static void error(void) { - printf("inet: error on line %u\n", line); + printf("inet: error on line %u\n", linenr); exit(1); } +static int nextline(void) +{ + /* Read a line from the configuration file, to be used by subsequent + * token() calls. Skip empty lines, and lines where the first character + * after leading "whitespace" is '#'. The last line of the file need + * not be terminated by a newline. Return 1 if a line was read in + * successfully, and 0 on EOF or error. + */ + unsigned char *lp, c; + int r, skip; + + lineptr = lp = line; + linenr++; + skip = -1; + + while ((r = read(cfg_fd, &c, 1)) == 1) { + if (c == '\n') { + if (skip == 0) + break; + + linenr++; + skip = -1; + continue; + } + + if (skip == -1 && c > ' ') + skip = (c == '#'); + + if (skip == 0 && lp < (unsigned char *) line + sizeof(line)-1) + *lp++ = c; + } + + *lp = 0; + return (r == 1 || lp != line); +} + static void token(int need) { - /* Read a word from the configuration file. Return a null string on - * EOF. Return a punctiation as a one character word. If 'need' is + /* Read a word from the configuration line. Return a null string on + * EOL. Return a punctuation as a one character word. If 'need' is * true then an actual word is expected at this point, so err out if * not. */ @@ -169,16 +206,16 @@ static void token(int need) *wp = 0; while (c <= ' ') { - if (c == '\n') line++; - if (read(cfg_fd, &c, 1) != 1) { + if (*lineptr == 0) { if (need) error(); return; } + c = *lineptr++; } do { if (wp < (unsigned char *) word + sizeof(word)-1) *wp++ = c; - if (read(cfg_fd, &c, 1) != 1) c= ' '; + c = (*lineptr != 0) ? *lineptr++ : ' '; if (word[0] == ';' || word[0] == '{' || word[0] == '}') { if (need) error(); break; @@ -215,6 +252,7 @@ void read_conf(void) struct psip_conf *pcp; struct ip_conf *icp; struct stat st; + char buf[sizeof(word)]; { static int first= 1; if (!first) ip_panic(( "read_conf: called a second time" )); @@ -233,7 +271,8 @@ void read_conf(void) pcp= psip_conf; icp= ip_conf; - while (token(0), word[0] != 0) { + while (nextline()) { + token(1); if (strncmp(word, "eth", 3) == 0) { ecp->ec_ifno= ifno= number(word+3, IP_PORT_MAX-1); type= NETTYPE_ETH; @@ -251,10 +290,17 @@ void read_conf(void) } ecp->ec_port= number(word+3, IP_PORT_MAX-1); } else { - ecp->ec_task= alloc(strlen(word)+1); - strcpy(ecp->ec_task, word); + /* The process label consists of the driver + * name, an underscore, and the instance + * number. + */ + strncpy(buf, word, sizeof(buf)-1); + buf[sizeof(buf)-1]= 0; token(1); - ecp->ec_port= number(word, IP_PORT_MAX-1); + ecp->ec_label= + alloc(strlen(buf)+1+strlen(word)+1); + sprintf(ecp->ec_label, "%s_%s", buf, word); + ecp->ec_port= 0; } ecp++; eth_conf_nr++; diff --git a/servers/inet/inet_config.h b/servers/inet/inet_config.h index d0b0d32a0..743ab9a58 100644 --- a/servers/inet/inet_config.h +++ b/servers/inet/inet_config.h @@ -26,12 +26,12 @@ extern dev_t ip_dev; /* Device number of /dev/ip */ struct eth_conf { - char *ec_task; /* Kernel ethernet task name if nonnull */ - u8_t ec_port; /* Task port (!vlan) or Ethernet port (vlan) */ + char *ec_label; /* Process label name if nonnull */ + u8_t ec_port; /* Ethernet port for VLAN if label == NULL */ u8_t ec_ifno; /* Interface number of /dev/eth* */ - u16_t ec_vlan; /* VLAN number of this net if task == NULL */ + u16_t ec_vlan; /* VLAN number of this net if label == NULL */ }; -#define eth_is_vlan(ecp) ((ecp)->ec_task == NULL) +#define eth_is_vlan(ecp) ((ecp)->ec_label == NULL) struct psip_conf { diff --git a/servers/inet/mnx_eth.c b/servers/inet/mnx_eth.c index a04253ebb..a255887cc 100644 --- a/servers/inet/mnx_eth.c +++ b/servers/inet/mnx_eth.c @@ -7,7 +7,6 @@ Copyright 1995 Philip Homburg */ #include "inet.h" -#include #include #include "proto.h" #include "osdep_eth.h" @@ -22,22 +21,17 @@ Copyright 1995 Philip Homburg THIS_FILE -static int recv_debug= 0; - FORWARD _PROTOTYPE( void setup_read, (eth_port_t *eth_port) ); FORWARD _PROTOTYPE( void read_int, (eth_port_t *eth_port, int count) ); FORWARD _PROTOTYPE( void eth_issue_send, (eth_port_t *eth_port) ); FORWARD _PROTOTYPE( void write_int, (eth_port_t *eth_port) ); -FORWARD _PROTOTYPE( void eth_recvev, (event_t *ev, ev_arg_t ev_arg) ); -FORWARD _PROTOTYPE( void eth_sendev, (event_t *ev, ev_arg_t ev_arg) ); -FORWARD _PROTOTYPE( eth_port_t *find_port, (message *m) ); FORWARD _PROTOTYPE( void eth_restart, (eth_port_t *eth_port, endpoint_t endpoint) ); FORWARD _PROTOTYPE( void send_getstat, (eth_port_t *eth_port) ); PUBLIC void osdep_eth_init() { - int i, j, r, rport; + int i, j, rport; struct eth_conf *ecp; eth_port_t *eth_port, *rep; cp_grant_id_t gid; @@ -98,10 +92,8 @@ PUBLIC void osdep_eth_init() } eth_port->etp_osdep.etp_rd_vec_grant= gid; - eth_port->etp_osdep.etp_port= ecp->ec_port; - eth_port->etp_osdep.etp_task= ANY; + eth_port->etp_osdep.etp_task= NONE; eth_port->etp_osdep.etp_recvconf= 0; - eth_port->etp_osdep.etp_send_ev= 0; ev_init(ð_port->etp_osdep.etp_recvev); sr_add_minor(if2minor(ecp->ec_ifno, ETH_DEV_OFF), @@ -122,11 +114,10 @@ PUBLIC void osdep_eth_init() if (!eth_is_vlan(ecp)) continue; - eth_port->etp_osdep.etp_port= ecp->ec_port; - eth_port->etp_osdep.etp_task= ANY; + eth_port->etp_osdep.etp_task= NONE; ev_init(ð_port->etp_osdep.etp_recvev); - rport= eth_port->etp_osdep.etp_port; + rport= ecp->ec_port; assert(rport >= 0 && rport < eth_conf_nr); rep= ð_port_table[rport]; if (!(rep->etp_flags & EPF_ENABLED)) @@ -185,57 +176,25 @@ acc_t *pack; eth_issue_send(eth_port); } -#if 0 -PRIVATE int notification_count; -#endif - PUBLIC void eth_rec(message *m) { - int i, r, m_type, stat; + int i, r, m_type, flags; eth_port_t *loc_port, *vlan_port; - char *drivername; - struct eth_conf *ecp; m_type= m->m_type; - if (m_type == DL_NAME_REPLY) - { - drivername= m->m3_ca1; -#if 0 - printf("eth_rec: got name: %s\n", drivername); - - notification_count= 0; -#endif - - /* Re-init ethernet interfaces */ - for (i= 0, ecp= eth_conf, loc_port= eth_port_table; - iec_task, drivername) != 0) - { - /* Wrong driver */ - continue; - } - eth_restart(loc_port, m->m_source); - } - return; - } assert(m_type == DL_CONF_REPLY || m_type == DL_TASK_REPLY || m_type == DL_STAT_REPLY); for (i=0, loc_port= eth_port_table; ietp_osdep.etp_port == m->DL_PORT && - loc_port->etp_osdep.etp_task == m->m_source) + if (loc_port->etp_osdep.etp_task == m->m_source) break; } if (i >= eth_conf_nr) { - printf("eth_rec: bad port %d in message type 0x%x from %d\n", - m->DL_PORT, m_type, m->m_source); + printf("eth_rec: message 0x%x from unknown driver %d\n", + m_type, m->m_source); return; } @@ -243,11 +202,11 @@ PUBLIC void eth_rec(message *m) { if (m_type == DL_TASK_REPLY) { - stat= m->DL_STAT & 0xffff; + flags= m->DL_FLAGS; - if (stat & DL_PACK_SEND) + if (flags & DL_PACK_SEND) write_int(loc_port); - if (stat & DL_PACK_RECV) + if (flags & DL_PACK_RECV) read_int(loc_port, m->DL_COUNT); return; } @@ -260,18 +219,13 @@ PUBLIC void eth_rec(message *m) return; } - r= m->m3_i1; - if (r == ENXIO) - { - printf( - "eth_rec(conf_reply): no ethernet device at task=%d,port=%d\n", - loc_port->etp_osdep.etp_task, - loc_port->etp_osdep.etp_port); - return; - } + r= m->DL_STAT; if (r < 0) { - ip_panic(("eth_rec: DL_INIT returned error %d\n", r)); + ip_warning(("eth_rec: DL_CONF returned error %d\n", + r)); + + /* Just leave it in limbo. Nothing more we can do. */ return; } @@ -279,7 +233,7 @@ PUBLIC void eth_rec(message *m) loc_port->etp_osdep.etp_state= OEPS_IDLE; loc_port->etp_flags |= EPF_ENABLED; - loc_port->etp_ethaddr= *(ether_addr_t *)m->m3_ca1; + loc_port->etp_ethaddr= *(ether_addr_t *)m->DL_HWADDR; if (!(loc_port->etp_flags & EPF_GOT_ADDR)) { loc_port->etp_flags |= EPF_GOT_ADDR; @@ -332,14 +286,6 @@ PUBLIC void eth_rec(message *m) return; } - r= m->DL_STAT; - if (r != OK) - { - ip_warning(("eth_rec: DL_STAT returned error %d\n", - r)); - return; - } - loc_port->etp_osdep.etp_state= OEPS_IDLE; loc_port->etp_osdep.etp_flags &= ~OEPF_NEED_STAT; @@ -383,27 +329,12 @@ PUBLIC void eth_rec(message *m) (printf("etp_state = %d\n", loc_port->etp_osdep.etp_state), 0)); loc_port->etp_osdep.etp_state= OEPS_IDLE; -#if 0 /* Ethernet driver is not trusted */ - set_time (m->DL_CLCK); -#endif - - stat= m->DL_STAT & 0xffff; + flags= m->DL_FLAGS; -#if 0 - if (!(stat & (DL_PACK_SEND|DL_PACK_RECV))) - printf("eth_rec: neither DL_PACK_SEND nor DL_PACK_RECV\n"); -#endif - if (stat & DL_PACK_SEND) + if (flags & DL_PACK_SEND) write_int(loc_port); - if (stat & DL_PACK_RECV) - { - if (recv_debug) - { - printf("eth_rec: eth%d got DL_PACK_RECV\n", - m->DL_PORT); - } + if (flags & DL_PACK_RECV) read_int(loc_port, m->DL_COUNT); - } if (loc_port->etp_osdep.etp_state == OEPS_IDLE && loc_port->etp_osdep.etp_flags & OEPF_NEED_SEND) @@ -432,18 +363,25 @@ PUBLIC void eth_rec(message *m) } } -PUBLIC void eth_check_driver(endpoint_t endpoint) +PUBLIC void eth_check_driver(char *label, endpoint_t endpoint) { - int r; - message m; + int i; + eth_port_t *loc_port; + struct eth_conf *ecp; - m.m_type = DL_GETNAME; - r= asynsend(endpoint, &m); - if (r != OK) + /* Re-init ethernet interface */ + for (i= 0, ecp= eth_conf, loc_port= eth_port_table; + iec_label, label) != 0) + { + /* Wrong driver */ + continue; + } + eth_restart(loc_port, endpoint); } } @@ -525,8 +463,6 @@ u32_t flags; dl_flags |= DL_PROMISC_REQ; mess.m_type= DL_CONF; - mess.DL_PORT= eth_port->etp_osdep.etp_port; - mess.DL_PROC= this_proc; mess.DL_MODE= dl_flags; assert(eth_port->etp_osdep.etp_state == OEPS_IDLE); @@ -604,13 +540,10 @@ eth_port_t *eth_port; "eth_write_port: cpf_setgrant_direct failed: %d\n", errno)); } + m.m_type= DL_WRITEV_S; + m.DL_ENDPT= this_proc; m.DL_COUNT= i; m.DL_GRANT= eth_port->etp_osdep.etp_wr_vec_grant; - m.m_type= DL_WRITEV_S; - - m.DL_PORT= eth_port->etp_osdep.etp_port; - m.DL_PROC= this_proc; - m.DL_MODE= DL_NOMODE; assert(eth_port->etp_osdep.etp_state == OEPS_IDLE); r= asynsend(eth_port->etp_osdep.etp_task, &m); @@ -634,7 +567,7 @@ PRIVATE void write_int(eth_port_t *eth_port) if (pack == NULL) { printf("write_int: strange no packet on eth port %d\n", - eth_port-eth_port_table); + (int)(eth_port-eth_port_table)); eth_restart_write(eth_port); return; } @@ -698,7 +631,7 @@ PRIVATE void setup_read(eth_port) eth_port_t *eth_port; { acc_t *pack, *pack_ptr; - message mess1; + message mess; iovec_s_t *iovec; int i, r; @@ -747,15 +680,14 @@ eth_port_t *eth_port; errno)); } - mess1.m_type= DL_READV_S; - mess1.DL_PORT= eth_port->etp_osdep.etp_port; - mess1.DL_PROC= this_proc; - mess1.DL_COUNT= i; - mess1.DL_GRANT= eth_port->etp_osdep.etp_rd_vec_grant; + mess.m_type= DL_READV_S; + mess.DL_ENDPT= this_proc; + mess.DL_COUNT= i; + mess.DL_GRANT= eth_port->etp_osdep.etp_rd_vec_grant; assert(eth_port->etp_osdep.etp_state == OEPS_IDLE); - r= asynsend(eth_port->etp_osdep.etp_task, &mess1); + r= asynsend(eth_port->etp_osdep.etp_task, &mess); eth_port->etp_osdep.etp_state= OEPS_RECV_SENT; if (r < 0) @@ -769,72 +701,6 @@ eth_port_t *eth_port; 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 == ð_port->etp_osdep.etp_recvev); - m_ptr= ð_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 == ð_port->etp_sendev); - m_ptr= ð_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; - assert(eth_port->etp_osdep.etp_send_ev); - eth_port->etp_osdep.etp_send_ev= 0; - - /* 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; ietp_osdep.etp_port == m->DL_PORT && - loc_port->etp_osdep.etp_task == m->m_source) - break; - } - assert (ietp_osdep.etp_port; - mess.DL_PROC= this_proc; mess.DL_MODE= dl_flags; compare(eth_port->etp_osdep.etp_state, ==, OEPS_IDLE); @@ -929,8 +793,7 @@ eth_port_t *eth_port; message mess; mess.m_type= DL_GETSTAT_S; - mess.DL_PORT= eth_port->etp_osdep.etp_port; - mess.DL_PROC= this_proc; + mess.DL_ENDPT= this_proc; mess.DL_GRANT= eth_port->etp_osdep.etp_stat_gid; assert(eth_port->etp_osdep.etp_state == OEPS_IDLE); diff --git a/servers/inet/osdep_eth.h b/servers/inet/osdep_eth.h index cb04d5d9c..a683ecc9b 100644 --- a/servers/inet/osdep_eth.h +++ b/servers/inet/osdep_eth.h @@ -19,16 +19,12 @@ typedef struct osdep_eth_port int etp_state; int etp_flags; endpoint_t etp_task; - int etp_port; int etp_recvconf; - int etp_send_ev; iovec_s_t etp_wr_iovec[IOVEC_NR]; cp_grant_id_t etp_wr_vec_grant; iovec_s_t etp_rd_iovec[RD_IOVEC]; cp_grant_id_t etp_rd_vec_grant; event_t etp_recvev; - message etp_sendrepl; - message etp_recvrepl; cp_grant_id_t etp_stat_gid; eth_stat_t *etp_stat_buf; } osdep_eth_port_t; diff --git a/servers/inet/proto.h b/servers/inet/proto.h index 4a8b425ff..3890718af 100644 --- a/servers/inet/proto.h +++ b/servers/inet/proto.h @@ -13,7 +13,7 @@ _PROTOTYPE( void clck_tick, (message *mess) ); /* mnx_eth.c */ _PROTOTYPE( void eth_rec, (message *m) ); -_PROTOTYPE( void eth_check_driver, (endpoint_t endpoint) ); +_PROTOTYPE( void eth_check_driver, (char *label, endpoint_t endpoint) ); /* sr.c */ diff --git a/servers/inet/sr.c b/servers/inet/sr.c index 0146e54ed..8cd39d8c1 100644 --- a/servers/inet/sr.c +++ b/servers/inet/sr.c @@ -94,8 +94,6 @@ FORWARD _PROTOTYPE (void sr_select_res, (int fd, unsigned ops) ); FORWARD _PROTOTYPE ( int sr_repl_queue, (int proc, int ref, int operation) ); FORWARD _PROTOTYPE ( int walk_queue, (sr_fd_t *sr_fd, mq_t **q_head_ptr, mq_t **q_tail_ptr, int type, int proc_nr, int ref, int first_flag) ); -FORWARD _PROTOTYPE ( void process_req_q, (mq_t *mq, mq_t *tail, - mq_t **tail_ptr) ); FORWARD _PROTOTYPE ( void sr_event, (event_t *evp, ev_arg_t arg) ); FORWARD _PROTOTYPE ( int cp_u2b, (endpoint_t proc, cp_grant_id_t gid, vir_bytes offset, acc_t **var_acc_ptr, int size) ); @@ -822,31 +820,6 @@ PRIVATE void sr_select_res(int fd, unsigned ops) notify(sr_fd->srf_select_proc); } -PRIVATE void process_req_q(mq, tail, tail_ptr) -mq_t *mq, *tail, **tail_ptr; -{ - mq_t *m; - int result; - - for(;mq;) - { - m= mq; - mq= mq->mq_next; - - result= sr_rwio(m); - if (result == SUSPEND) - { - if (mq) - { - (*tail_ptr)->mq_next= mq; - *tail_ptr= tail; - } - return; - } - } - return; -} - PRIVATE void sr_event(evp, arg) event_t *evp; ev_arg_t arg; diff --git a/test/select/test06_srv.c b/test/select/test06_srv.c index af0459f40..4834e555a 100644 --- a/test/select/test06_srv.c +++ b/test/select/test06_srv.c @@ -29,7 +29,7 @@ #define PORT 6060L -int listen(long port) { +int my_listen(long port) { char *tcp_device; int netfd; @@ -87,7 +87,7 @@ int main(int argc,char *argv[]) { int ret; fd_set fds_read; - if ((fd = listen(PORT)) < 0) { + if ((fd = my_listen(PORT)) < 0) { exit(-1); } printf("Waiting for messages on port: %ld\n", PORT); diff --git a/test/select/test07_srv.c b/test/select/test07_srv.c index 582318c42..b0cffba36 100644 --- a/test/select/test07_srv.c +++ b/test/select/test07_srv.c @@ -31,7 +31,7 @@ #define PORT 6060L -int listen(long port) { +int my_listen(long port) { char *tcp_device; int netfd; @@ -90,7 +90,7 @@ int main(int argc,char *argv[]) { fd_set fds_read; struct timeval timeout; - if ((fd = listen(PORT)) < 0) { + if ((fd = my_listen(PORT)) < 0) { exit(-1); } printf("Waiting for messages on port: %ld\n", PORT); diff --git a/test/select/test08_srv.c b/test/select/test08_srv.c index 6074035a8..fa4f6f8fb 100644 --- a/test/select/test08_srv.c +++ b/test/select/test08_srv.c @@ -29,7 +29,7 @@ #define PORT 6060L -int listen(long port) { +int my_listen(long port) { char *tcp_device; int netfd; @@ -105,7 +105,7 @@ int main(int argc,char *argv[]) { int ret; fd_set fds_excep; - if ((fd = listen(PORT)) < 0) { + if ((fd = my_listen(PORT)) < 0) { exit(-1); } printf("Waiting for messages on port: %ld\n", PORT);