This patch switches the MINIX3 ethernet driver stack from a port-based

model to an instance-based model. Each ethernet driver instance is now
responsible for exactly one network interface card. The port field in
/etc/inet.conf now acts as an instance field instead.

This patch also updates the data link protocol. This update:
- eliminates the concept of ports entirely;
- eliminates DL_GETNAME entirely;
- standardizes on using m_source for IPC and DL_ENDPT for safecopies;
- removes error codes from TASK/STAT replies, as they were unused;
- removes a number of other old or unused fields;
- names and renames a few other fields.

All ethernet drivers have been changed to:
- conform to the new protocol, and exactly that;
- take on an instance number based on a given "instance" argument;
- skip that number of PCI devices in probe iterations;
- use config tables and environment variables based on that number;
- no longer be limited to a predefined maximum of cards in any way;
- get rid of any leftover non-safecopy support and other ancient junk;
- have a correct banner protocol figure, or none at all.

Other changes:
* Inet.conf is now taken to be line-based, and supports #-comments.
  No existing installations are expected to be affected by this.
* A new, select-based asynchio library replaces the old one.
  Kindly contributed by Kees J. Bot.
* Inet now supports use of select() on IP devices.
  Combined, the last two changes together speed up dhcpd
  considerably in the presence of multiple interfaces.
* A small bug has been fixed in nonamed.
This commit is contained in:
David van Moolenbroek
2010-05-17 22:22:53 +00:00
parent f5bce90216
commit 9ba65d2ea8
55 changed files with 1971 additions and 4794 deletions

View 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;
}

View 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 ));

View 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;
}

View 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);
/* A driver is (re)started. */
eth_check_driver(label, owner_endpoint);
}
/* 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(owner_endpoint);
if(r != ENOENT)
printf("inet: ds_event: ds_check failed: %d\n", r);
}
PUBLIC void panic0(file, line)

View 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++;

View 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
{

View 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
flags= m->DL_FLAGS;
stat= m->DL_STAT & 0xffff;
#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);

View 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;

View 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 */

View 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;