]> Zhao Yanbai Git Server - minix.git/commitdiff
This patch switches the MINIX3 ethernet driver stack from a port-based
authorDavid van Moolenbroek <david@minix3.org>
Mon, 17 May 2010 22:22:53 +0000 (22:22 +0000)
committerDavid van Moolenbroek <david@minix3.org>
Mon, 17 May 2010 22:22:53 +0000 (22:22 +0000)
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.

55 files changed:
commands/dhcpd/devices.c
commands/dhcpd/dhcpd.c
commands/nonamed/nonamed.c
docs/UPDATING
drivers/atl2/atl2.c
drivers/dec21140A/dec21140A.c
drivers/dec21140A/dec21140A.h
drivers/dp8390/dp8390.c
drivers/dp8390/dp8390.h
drivers/dpeth/dp.c
drivers/dpeth/dp.h
drivers/e1000/e1000.c
drivers/e1000/e1000.h
drivers/fxp/fxp.c
drivers/lance/lance.c
drivers/lance/lance.h
drivers/orinoco/hermes.c
drivers/orinoco/orinoco.c
drivers/orinoco/orinoco.h
drivers/rtl8139/liveupdate.c
drivers/rtl8139/rtl8139.c
drivers/rtl8139/rtl8139.h
drivers/rtl8169/rtl8169.c
etc/usr/rc
include/minix/com.h
include/sys/asynchio.h
lib/libc/Makefile
lib/libc/asyn/Makefile.inc [new file with mode: 0644]
lib/libc/asyn/asyn.h [new file with mode: 0644]
lib/libc/asyn/asyn_cancel.c [new file with mode: 0644]
lib/libc/asyn/asyn_close.c [new file with mode: 0644]
lib/libc/asyn/asyn_init.c [new file with mode: 0644]
lib/libc/asyn/asyn_pending.c [new file with mode: 0644]
lib/libc/asyn/asyn_read.c [new file with mode: 0644]
lib/libc/asyn/asyn_special.c [new file with mode: 0644]
lib/libc/asyn/asyn_synch.c [new file with mode: 0644]
lib/libc/asyn/asyn_wait.c [new file with mode: 0644]
lib/libc/asyn/asyn_write.c [new file with mode: 0644]
lib/libc/other/Makefile.inc
lib/libc/other/asynchio.c [deleted file]
lib/libnetdriver/netdriver.c
man/man8/inet.8
servers/inet/generic/ip.c
servers/inet/generic/ip_int.h
servers/inet/generic/ip_read.c
servers/inet/inet.c
servers/inet/inet_config.c
servers/inet/inet_config.h
servers/inet/mnx_eth.c
servers/inet/osdep_eth.h
servers/inet/proto.h
servers/inet/sr.c
test/select/test06_srv.c
test/select/test07_srv.c
test/select/test08_srv.c

index 3d12a16489e8d0c583d8d84af54c10729b8281c6..f29d2d31435261624b7fa78ddf3afa7152aa66a4 100644 (file)
@@ -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. */
index bd43077ae13aabfd76f424d6cca4f6e24f0a0253..8b82fac1a33a563b15b3a68ac791693cfef86e6a 100644 (file)
@@ -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. */
index 797e6c56a758b4e37fe17554803ca348044b25b6..7dd1d95f4309320ee86750458efde6adeee51268 100644 (file)
@@ -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;
index 75de762b2f6997f472fb2983fafebdd9c4ec4722..97992064109aa6444996a6833bd5dd7eb4207df3 100644 (file)
@@ -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
index b462260caf23e5b96dd660f7478bf78e03d61456..670949006f7ece30add177b6a11e9242661e9b04 100644 (file)
@@ -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;
index 8943003a695fe12c86024ef1aa049e0b2cbf2de9..d16aa8b48faecbabba189ef64c2e33662050903d 100644 (file)
 _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){
index 0a2202eead522421fb2d484be54ed74402a044c1..cf7ff895f97e10b6862feb4f56932e7c20f24d81 100644 (file)
@@ -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
index 2700b348ca9cfe6a6900a73c9990b58107b3d525..78803c5d8fcd3c571cfa1dc4087953092bb37f4c 100644 (file)
@@ -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 <philip@f-mnx.phicoh.com>
  *
  * Modified Mar 10 1994 by Philip Homburg
 #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]; i<DE_PORT_NR; i++, dep++)
-       {
-               if (dep->de_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; i<DE_PORT_NR; i++, dep++)
-       {
-               strcpy(dep->de_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; i<DE_PORT_NR; i++)
-       {
-               if (de_table[i].de_mode != DEM_ENABLED)
-                       continue;
-               mess.m_type= DL_STOP;
-               mess.DL_PORT= i;
-               do_stop(&mess);
-       }
+       if (de_state.de_mode == DEM_ENABLED)
+               dp_stop(&de_state);
 }
 
 #if 0
@@ -374,49 +278,48 @@ PRIVATE void sef_cb_signal_handler(int signo)
 void dp8390_dump()
 {
        dpeth_t *dep;
-       int i, isr;
+       int isr;
+
+       dep = &de_state;
 
        printf("\n");
-       for (i= 0, dep = &de_table[0]; i<DE_PORT_NR; i++, dep++)
-       {
 #if XXX
-               if (dep->de_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; i<DE_PORT_NR; i++, dep++)
-       {
-               envvar= dp_conf[i].dpc_envvar;
-               if (!(dep->de_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; i<DE_PORT_NR; i++, dep++)
-               {
-                       if (!dep->de_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                               *
  *===========================================================================*/
index 901428b1a17de0c74734ace0975650d7297168e3..102f32041bdddf4a53b4c6a62470e7cb9985d7a8 100644 (file)
@@ -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;
index e536f9f5ac9065eb1f12fdafe4a9ec1117cadcc4..df7119634a8b6c1046d55430c3c1f40936c03c9c 100644 (file)
@@ -1,4 +1,3 @@
-#include <assert.h>
 /*
 **  File:      dp.c    Version 1.01,   Oct. 17, 2007
 **  Original:  eth.c   Version 1.00,   Jan. 14, 1997
 **  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 <minix/drivers.h>
 /*
 **  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 **/
index 836346b9d1351fafef6726e7523e9205e65ad171..50ab297e3755c6e7a2a454abdf4975d628db25d1 100644 (file)
@@ -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 */
 
index 4cec31d92e64b3a4539b47da1300c3b8f60d5814..0e1caacd08971d85a76a96697b7dd7ca772567c4 100644 (file)
@@ -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);
index 75f1017ab94686b88c0f731e2e833fbe4f777823..0124c3353cec1a93dc87875d3c48f7980b982c85 100644 (file)
@@ -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
 
index 3a61d3451abcb498ed4aff36d08e98badcd02bf8..01156ba576a71b7b87c36d77d0002c64a25de103 100644 (file)
@@ -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 <philip@f-mnx.phicoh.com>
  */
 
@@ -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]; i<FXP_PORT_NR; i++, fp++) {
-               if (fp->fxp_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]; i<FXP_PORT_NR; i++, fp++)
-       {
-               if (fp->fxp_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; i<FXP_PORT_NR; i++, fp++)
-       {
-               strcpy(fp->fxp_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; i<FXP_PORT_NR; i++, fp++)
-               {
-                       if (fp->fxp_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; i<count; i += IOVEC_NR,
-                       iov_src += IOVEC_NR * sizeof(fp->fxp_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; j<n; j++, iovp++)
-                       {
-                               s= iovp->iov_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; i<count; i += IOVEC_NR,
-                       iov_src += IOVEC_NR * sizeof(fp->fxp_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; j<n; j++, iovp++)
-                       {
-                               s= iovp->iov_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]; i<FXP_PORT_NR; i++, fp++)
-       {
-               if (fp->fxp_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);
        
index 2ad63d23cbacf6bcf637ab8a45519ed66f62e97c..4af5a7c2e86bd86a5ce7715159676f659beb5cde 100644 (file)
@@ -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 <kazuya@nii.ac.jp>
  * Adapted for Minix 3: Sep 05, 2005 by Joren l'Ami <jwlami@cs.vu.nl>
@@ -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;i<EC_PORT_NR_MAX;++i)
-      {
-         ec= &ec_table[i];
-         if (ec->ec_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;i<EC_PORT_NR_MAX;++i)
-      {
-         ec= &ec_table[i];
-         if (ec->ec_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;i<EC_PORT_NR_MAX;++i)
+                             if (ec->mode == 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; i<EC_PORT_NR_MAX; i++)
-   {
-      if (ec_table[i].mode != EC_ENABLED)
-         continue;
-      mess.m_type= DL_STOP;
-      mess.DL_PORT= i;
-      do_stop(&mess);
-   }
+   if (ec_state.mode == EC_ENABLED)
+      lance_stop(&ec_state);
 
 #if VERBOSE
    printf("LANCE driver stopped.\n");
@@ -438,63 +411,60 @@ PRIVATE void sef_cb_signal_handler(int signo)
 static void lance_dump()
 {
    ether_card_t *ec;
-   int i, isr, csr;
+   int isr, csr;
    unsigned short ioaddr;
   
    printf("\n");
-   for (i= 0, ec = &ec_table[0]; i<EC_PORT_NR_MAX; i++, ec++)
-   {
-      if (ec->mode == 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                              *
  *===========================================================================*/
index 67117656b6c86f65d3d6606e394a1dd20cb9d4ee..dc29961125b31bc76db64ee2db06bda845a3b36c 100644 (file)
@@ -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;
index b9ff7141c4d4351339edc7eabcae884dcddf26cb..158cb2e371c29694533facde025aacc208e730c2 100644 (file)
@@ -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;
        }
index 768be268a094830ec8ea360f5e64f0f033ec63ac..97409e9432fc50b56a3df2204f144a96d5283c70 100644 (file)
@@ -7,50 +7,6 @@
  * Created by Stevens Le Blond <slblond@few.vu.nl> 
  *        and Michael Valkering <mjvalker@cs.vu.nl>
  *
- * * 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       <minix/drivers.h>
@@ -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]; i<OR_PORT_NR; i++, orp++) {
-               if (orp->or_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]; i<OR_PORT_NR; i++, orp++) {
-               if (orp->or_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)
index 45daee7e2619bba359b6b0ad929744209de69e52..e48299fa77cec25f3f1cb111d8c714be1191f472 100644 (file)
@@ -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"
index d6af2684feab4b5bba809113781bc7301eac01bc..fc43d5bcf3b3572c73ad01d1795a1133400276ab 100644 (file)
@@ -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; i<RE_PORT_NR && !found_processing; i++) {
-      rep = &re_table[i];
-
-      if (rep->re_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);
 }
 
 /*===========================================================================*
index 61c9619c15a806b5082d5f3301b3598b1c790644..3ba0c411f163ea7a12b1af263ae82ce38cbfc591 100644 (file)
@@ -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 <philip@cs.vu.nl>
  * 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]; 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);
 }
 
@@ -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]; 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);
-                       }
+       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]; i<RE_PORT_NR; i++, rep++)
-       {
-               if (rep->re_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; i<RE_PORT_NR; i++, rep++)
-       {
-               strcpy(rep->re_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; 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;
 }
 
 /*===========================================================================*
@@ -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; i<count; i += IOVEC_NR,
-                       iov_offset += IOVEC_NR * sizeof(rep->re_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; j<n; j++, iovp++)
-                       {
-                               s= iovp->iov_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(o<RX_BUFSIZE);
-                                       s1= RX_BUFSIZE-o;
-
-                                       cps = sys_vircopy(SELF, D,
-                                               (vir_bytes) rep->v_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(o<RX_BUFSIZE);
                                s1= RX_BUFSIZE-o;
 
-                               cps = sys_safecopyto(re_client,
+                               cps = sys_safecopyto(mp->DL_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; i<count; i += IOVEC_NR,
-                       iov_offset += IOVEC_NR * sizeof(rep->re_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; j<n; j++, iovp++)
-                       {
-                               s= iovp->iov_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]; i<RE_PORT_NR; i++, rep++)
+       rep= &re_state;
+
+       if (rep->re_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
index d0e6c2dd5b89ba813785fbfbff03e1efeb18323e..9ed63d914ce486fa39b179c79fd7809cfcdb0434 100644 (file)
@@ -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
 
index b7b073f328b67c80c1939e3e91183f1d00e1f3dd..60c77b1675ae0d5cbd5c122a5c0de335b51c013f 100644 (file)
@@ -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();
 }
 
index b7e20b61d7708777e3b0aaad8c52b8c9b969ac19..050a7f4a24cee1364459784f500543bb1f0590a3 100644 (file)
@@ -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
index 9d64eec8f99da2d02a35cb2449f540ba068dd554..ab87b66ed9ce50d55e77b63efae51f42f4365e35 100644 (file)
 #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                    *
index 0fa9280f5f245abfdee9f4545c7b585550406036..726dd1ec4c3b219194f1bfe0c07a903dab224ad0 100644 (file)
@@ -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 <ansi.h>
-#endif
+#include <sys/select.h>                        /* for FD_SETSIZE */
 
-#include <sys/time.h>
+#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);
 
index 7e95cb1c421d8a40e76122a556e5651634f84487..1227c3d35f98fb821611e294fdff62bce9372b88 100644 (file)
@@ -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 (file)
index 0000000..d2b10bc
--- /dev/null
@@ -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 (file)
index 0000000..4acfdbb
--- /dev/null
@@ -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 <sys/types.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/asynchio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+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 (file)
index 0000000..664c17b
--- /dev/null
@@ -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 (file)
index 0000000..a0154f9
--- /dev/null
@@ -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 (file)
index 0000000..f91f4fb
--- /dev/null
@@ -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 (file)
index 0000000..fa5f74b
--- /dev/null
@@ -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 (file)
index 0000000..b5f02a0
--- /dev/null
@@ -0,0 +1,61 @@
+/*     asyn_read()                                     Author: Kees J. Bot
+ *                                                             7 Jul 1997
+ */
+#include "asyn.h"
+#include <signal.h>
+
+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 (file)
index 0000000..544bc42
--- /dev/null
@@ -0,0 +1,104 @@
+/*     asyn_special(), asyn_result()                   Author: Kees J. Bot
+ *                                                             8 Jul 1997
+ */
+#include "asyn.h"
+#include <signal.h>
+
+/* 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 (file)
index 0000000..d54be78
--- /dev/null
@@ -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 (file)
index 0000000..c71e5d0
--- /dev/null
@@ -0,0 +1,119 @@
+/*     asyn_wait() - wait for asynch operations        Author: Kees J. Bot
+ *                                                             7 Jul 1997
+ */
+#define DEBUG 0
+
+#include "asyn.h"
+#include <time.h>
+#if DEBUG
+#include <stdio.h>
+#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 (file)
index 0000000..1c3afdd
--- /dev/null
@@ -0,0 +1,50 @@
+/*     asyn_write()                                    Author: Kees J. Bot
+ *                                                             7 Jul 1997
+ */
+#include "asyn.h"
+#include <signal.h>
+
+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;
+}
index 56f6da8f92610b73a4ef8905a65818274b9f2a39..1411f7ced9bf080ef86766e1985aa3eafdfe2d97 100644 (file)
@@ -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 (file)
index ee7434b..0000000
+++ /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 <lib.h>
-#include <time.h>
-#include <sys/ioctl.h>
-#include <sys/asynchio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-
-#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);
-}
index defc302cdc4e79c6165531550b9353943fc17017..6d5cc37303728ba7035d1c62b13edbe9bcac6398 100644 (file)
@@ -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;
                }
        }
index 9ebfd3774594512dc209e4463cbf1dce9ae39636..a61ac3f825199ec86467bdc4e1c029fd32e7dda5 100644 (file)
@@ -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
index 193be4df6af4abdd762d02c7d8fe45f5c252fe8a..a80ac337fbdd750b612eeecb2c213cadd5b2da42 100644 (file)
@@ -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;
 }
index a9bbfa7039b9993073395eb68788a0d0c4f0b031..a1c8cf73504a3b40cd34a1c77a2539d787d6a00c 100644 (file)
@@ -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 ));
 
index 5bb89c40024456847330b70ff240b34f8ceca578..377fd78a63e17daf1deb735230468ab557455245 100644 (file)
@@ -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;
        }
 
index a9278b23d41c7dc3489062cd4573768947a62597..3e11a495650029113e12037c07c4b53e08fac150 100644 (file)
@@ -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)
index 2005e22dc8af6a48f3967ef6a58d408e9f2d48d4..af54173a83f68a4f2e144ad0f6f08a9f91eb02b5 100644 (file)
@@ -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++;
index d0b0d32a04844d9450dc93178cf7bc18494f6a79..743ab9a583376702a752982ae8e256791e1b1c35 100644 (file)
@@ -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
 {
index a04253ebb53caa6982ac24d2ed13555a15ca0b1a..a255887ccd1d703b7e9bb2b969c555102da8b71c 100644 (file)
@@ -7,7 +7,6 @@ Copyright 1995 Philip Homburg
 */
 
 #include "inet.h"
-#include <minix/ds.h>
 #include <minix/safecopies.h>
 #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(&eth_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(&eth_port->etp_osdep.etp_recvev);
 
-               rport= eth_port->etp_osdep.etp_port;
+               rport= ecp->ec_port;
                assert(rport >= 0 && rport < eth_conf_nr);
                rep= &eth_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;
-                       i<eth_conf_nr; i++, ecp++, loc_port++)
-               {
-                       if (eth_is_vlan(ecp))
-                               continue;
-
-                       if (strcmp(ecp->ec_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; i<eth_conf_nr; i++, loc_port++)
        {
-               if (loc_port->etp_osdep.etp_port == m->DL_PORT &&
-                       loc_port->etp_osdep.etp_task == m->m_source)
+               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;
+               i<eth_conf_nr; i++, ecp++, loc_port++)
        {
-               printf("eth_check_driver: asynsend to %d failed: %d\n",
-                       endpoint, r);
-               return;
+               if (eth_is_vlan(ecp))
+                       continue;
+
+               if (strcmp(ecp->ec_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 == &eth_port->etp_osdep.etp_recvev);
-       m_ptr= &eth_port->etp_osdep.etp_recvrepl;
-
-       assert(m_ptr->m_type == DL_TASK_REPLY);
-       assert(eth_port->etp_osdep.etp_port == m_ptr->DL_PORT &&
-               eth_port->etp_osdep.etp_task == m_ptr->m_source);
-
-       assert(m_ptr->DL_STAT & DL_PACK_RECV);
-       m_ptr->DL_STAT &= ~DL_PACK_RECV;
-
-       if (recv_debug)
-       {
-               printf("eth_recvev: eth%d got DL_PACK_RECV\n", m_ptr->DL_PORT);
-       }
-
-       read_int(eth_port, m_ptr->DL_COUNT);
-}
-
-PRIVATE void eth_sendev(ev, ev_arg)
-event_t *ev;
-ev_arg_t ev_arg;
-{
-       eth_port_t *eth_port;
-       message *m_ptr;
-
-       eth_port= ev_arg.ev_ptr;
-       assert(ev == &eth_port->etp_sendev);
-       m_ptr= &eth_port->etp_osdep.etp_sendrepl;
-
-       assert (m_ptr->m_type == DL_TASK_REPLY);
-       assert(eth_port->etp_osdep.etp_port == m_ptr->DL_PORT &&
-               eth_port->etp_osdep.etp_task == m_ptr->m_source);
-
-       assert(m_ptr->DL_STAT & DL_PACK_SEND);
-       m_ptr->DL_STAT &= ~DL_PACK_SEND;
-       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; i<eth_conf_nr; i++, loc_port++)
-       {
-               if (loc_port->etp_osdep.etp_port == m->DL_PORT &&
-                       loc_port->etp_osdep.etp_task == m->m_source)
-                       break;
-       }
-       assert (i<eth_conf_nr);
-       return loc_port;
-}
-
 static void eth_restart(eth_port_t *eth_port, endpoint_t endpoint)
 {
        int r;
@@ -892,8 +758,6 @@ static void eth_restart(eth_port_t *eth_port, endpoint_t endpoint)
        if (flags & NWEO_EN_PROMISC)
                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;
 
        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);
index cb04d5d9c967dbd481274ea848c6510a7b0207b5..a683ecc9bbbbaad879501e664e27975dbb0df173 100644 (file)
@@ -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;
index 4a8b425ff86b59d001f488b90077833f387e9495..3890718afc4e81df44eb6b5268133ce5c24101e8 100644 (file)
@@ -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 */
 
index 0146e54ed0adc98c104ed32ecb31c85783d1f088..8cd39d8c137ab8096327684c8e3e7de4fed65439 100644 (file)
@@ -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;
index af0459f40f1313d708b83962acb1ee90b1124766..4834e555a506829899b8ee94c87506e5e2614cdd 100644 (file)
@@ -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);
index 582318c42c0ec1c965bab3c29c3d29dbd86036ea..b0cffba36cfbd63089bdbf9bde1af0d2ec6437e5 100644 (file)
@@ -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);
index 6074035a8919cf66dec6381d46024e827751415d..fa4f6f8fb89e84d58d96dc6b8c5107baf38965e5 100644 (file)
@@ -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);