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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 ));
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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++;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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(ð_port->etp_osdep.etp_recvev);
|
||||
|
||||
sr_add_minor(if2minor(ecp->ec_ifno, ETH_DEV_OFF),
|
||||
@@ -122,11 +114,10 @@ PUBLIC void osdep_eth_init()
|
||||
if (!eth_is_vlan(ecp))
|
||||
continue;
|
||||
|
||||
eth_port->etp_osdep.etp_port= ecp->ec_port;
|
||||
eth_port->etp_osdep.etp_task= ANY;
|
||||
eth_port->etp_osdep.etp_task= NONE;
|
||||
ev_init(ð_port->etp_osdep.etp_recvev);
|
||||
|
||||
rport= eth_port->etp_osdep.etp_port;
|
||||
rport= ecp->ec_port;
|
||||
assert(rport >= 0 && rport < eth_conf_nr);
|
||||
rep= ð_port_table[rport];
|
||||
if (!(rep->etp_flags & EPF_ENABLED))
|
||||
@@ -185,57 +176,25 @@ acc_t *pack;
|
||||
eth_issue_send(eth_port);
|
||||
}
|
||||
|
||||
#if 0
|
||||
PRIVATE int notification_count;
|
||||
#endif
|
||||
|
||||
PUBLIC void eth_rec(message *m)
|
||||
{
|
||||
int i, r, m_type, stat;
|
||||
int i, r, m_type, flags;
|
||||
eth_port_t *loc_port, *vlan_port;
|
||||
char *drivername;
|
||||
struct eth_conf *ecp;
|
||||
|
||||
m_type= m->m_type;
|
||||
if (m_type == DL_NAME_REPLY)
|
||||
{
|
||||
drivername= m->m3_ca1;
|
||||
#if 0
|
||||
printf("eth_rec: got name: %s\n", drivername);
|
||||
|
||||
notification_count= 0;
|
||||
#endif
|
||||
|
||||
/* Re-init ethernet interfaces */
|
||||
for (i= 0, ecp= eth_conf, loc_port= eth_port_table;
|
||||
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 == ð_port->etp_osdep.etp_recvev);
|
||||
m_ptr= ð_port->etp_osdep.etp_recvrepl;
|
||||
|
||||
assert(m_ptr->m_type == DL_TASK_REPLY);
|
||||
assert(eth_port->etp_osdep.etp_port == m_ptr->DL_PORT &&
|
||||
eth_port->etp_osdep.etp_task == m_ptr->m_source);
|
||||
|
||||
assert(m_ptr->DL_STAT & DL_PACK_RECV);
|
||||
m_ptr->DL_STAT &= ~DL_PACK_RECV;
|
||||
|
||||
if (recv_debug)
|
||||
{
|
||||
printf("eth_recvev: eth%d got DL_PACK_RECV\n", m_ptr->DL_PORT);
|
||||
}
|
||||
|
||||
read_int(eth_port, m_ptr->DL_COUNT);
|
||||
}
|
||||
|
||||
PRIVATE void eth_sendev(ev, ev_arg)
|
||||
event_t *ev;
|
||||
ev_arg_t ev_arg;
|
||||
{
|
||||
eth_port_t *eth_port;
|
||||
message *m_ptr;
|
||||
|
||||
eth_port= ev_arg.ev_ptr;
|
||||
assert(ev == ð_port->etp_sendev);
|
||||
m_ptr= ð_port->etp_osdep.etp_sendrepl;
|
||||
|
||||
assert (m_ptr->m_type == DL_TASK_REPLY);
|
||||
assert(eth_port->etp_osdep.etp_port == m_ptr->DL_PORT &&
|
||||
eth_port->etp_osdep.etp_task == m_ptr->m_source);
|
||||
|
||||
assert(m_ptr->DL_STAT & DL_PACK_SEND);
|
||||
m_ptr->DL_STAT &= ~DL_PACK_SEND;
|
||||
assert(eth_port->etp_osdep.etp_send_ev);
|
||||
eth_port->etp_osdep.etp_send_ev= 0;
|
||||
|
||||
/* packet is sent */
|
||||
write_int(eth_port);
|
||||
}
|
||||
|
||||
PRIVATE eth_port_t *find_port(m)
|
||||
message *m;
|
||||
{
|
||||
eth_port_t *loc_port;
|
||||
int i;
|
||||
|
||||
for (i=0, loc_port= eth_port_table; 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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user