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

@ -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. */

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

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

View 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

View 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;
state.mode = m->DL_MODE;
atl2_set_mode();
atl2_set_mode();
addr = (ether_addr_t *) m->m3_ca1;
addr = (ether_addr_t *) m->DL_HWADDR;
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->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;

View file

@ -29,10 +29,9 @@
_PROTOTYPE( PRIVATE u32_t io_inl, (u16_t); );
_PROTOTYPE( PRIVATE void io_outl, (u16_t, u32_t); );
_PROTOTYPE( PRIVATE void do_conf, (const message *); );
_PROTOTYPE( PRIVATE void do_get_name, (message *); );
_PROTOTYPE( PRIVATE void do_get_stat_s, (message *); );
_PROTOTYPE( PRIVATE void do_interrupt, (const dpeth_t *); );
_PROTOTYPE( PRIVATE void do_reply, (dpeth_t *, int, int); );
_PROTOTYPE( PRIVATE void do_reply, (dpeth_t *); );
_PROTOTYPE( PRIVATE void do_vread_s, (const message *, int); );
_PROTOTYPE( PRIVATE void do_watchdog, (void *); );
@ -53,7 +52,6 @@ _PROTOTYPE( PRIVATE void de_get_userdata_s, (int, cp_grant_id_t,
/* Error messages */
static char str_CopyErrMsg[] = "unable to read/write user data";
static char str_PortErrMsg[] = "illegal port";
static char str_SendErrMsg[] = "send failed";
static char str_SizeErrMsg[] = "illegal packet size";
static char str_UmapErrMsg[] = "Unable to sys_umap";
@ -62,8 +60,8 @@ static char str_StatErrMsg[] = "Unable to send stats";
static char str_AlignErrMsg[] = "Bad align of buffer/descriptor";
static char str_DevName[] = "dec21140A:eth#?";
PRIVATE dpeth_t de_table[DE_PORT_NR];
PRIVATE const char *progname;
PRIVATE dpeth_t de_state;
PRIVATE int de_instance;
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
@ -96,13 +94,12 @@ int main(int argc, char *argv[])
break;
case HARDWARE:
for (dep = de_table; dep < &de_table[DE_PORT_NR]; dep += 1) {
if (dep->de_mode == DEM_ENABLED) {
do_interrupt(dep);
if (dep->de_flags & (DEF_ACK_SEND | DEF_ACK_RECV))
do_reply(dep, OK, TRUE);
sys_irqenable(&dep->de_hook);
}
dep = &de_state;
if (dep->de_mode == DEM_ENABLED) {
do_interrupt(dep);
if (dep->de_flags & (DEF_ACK_SEND | DEF_ACK_RECV))
do_reply(dep);
sys_irqenable(&dep->de_hook);
}
break;
default:
@ -118,8 +115,6 @@ int main(int argc, char *argv[])
case DL_READV_S: do_vread_s(&m, FALSE); break;
case DL_CONF: do_conf(&m); break;
case DL_GETSTAT_S: do_get_stat_s(&m); break;
case DL_GETNAME: do_get_name(&m); break;
case DL_STOP: /* nothing */ break;
default:
printf("message 0x%lx; %d from %d\n",
@ -157,8 +152,11 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
{
/* Initialize the DEC 21140A driver. */
int fkeys, sfkeys;
long v;
(progname=strrchr(env_argv[0],'/')) ? progname++ : (progname=env_argv[0]);
v = 0;
(void) env_parse("instance", "d", 0, &v, 0, 255);
de_instance = (int) v;
/* Request function key for debug dumps */
fkeys = sfkeys = 0;
@ -174,24 +172,17 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
PRIVATE void do_get_stat_s(message * mp)
{
int port, rc;
int rc;
dpeth_t *dep;
port = mp->DL_PORT;
if (port < 0 || port >= DE_PORT_NR)
panic(str_PortErrMsg, port);
dep = &de_state;
dep = &de_table[port];
dep->de_client = mp->DL_PROC;
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)
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;
/* 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;
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){

View 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

File diff suppressed because it is too large Load diff

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

View 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
@ -11,47 +10,7 @@
** to remove bord specific code. It should operate (I hope)
** with any board driver.
**
** The valid messages and their parameters are:
**
** m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR
** +------------+---------+---------+--------+-------+---------+
** | NOTIFY from HARDWARE, CLOCK, TTY, RS, PM, SYSTEM |
** +------------+---------+---------+--------+-------+---------+
** | HARD_STOP | | | | | |
** +------------+---------+---------+--------+-------+---------+
** | DL_WRITE | port nr | proc nr | count | mode | address | (3)
** +------------+---------+---------+--------+-------+---------+
** | DL_WRITEV | port nr | proc nr | count | mode | address | (4)
** +------------+---------+---------+--------+-------+---------+
** | DL_READ | port nr | proc nr | count | | address | (5)
** +------------+---------+---------+--------+-------+---------+
** | DL_READV | port nr | proc nr | count | | address | (6)
** +------------+---------+---------+--------+-------+---------+
** | DL_CONF | port nr | proc nr | | mode | address | (7)
** +------------+---------+---------+--------+-------+---------+
** | DL_STOP | port_nr | | | | | (8)
** +------------+---------+---------+--------+-------+---------+
** | DL_GETSTAT | port nr | proc nr | | | address | (9)
** +------------+---------+---------+--------+-------+---------+
**
** The messages sent are:
**
** m-type DL_PORT DL_PROC DL_COUNT DL_STAT DL_CLCK
** +------------+---------+---------+--------+---------+---------+
** |DL_TASK_REPL| port nr | proc nr |rd-count| err|stat| clock | (21)
** +------------+---------+---------+--------+---------+---------+
**
** m_type m3_i1 m3_i2 m3_ca1
** +------------+---------+---------+---------------+
** |DL_CONF_REPL| port nr |last port| ethernet addr | (20)
** +------------+---------+---------+---------------+
**
** $Id$
**
** 2007-10-17: modified by jfdsmit@gmail.com
** added a third argument to the reply() function because not
** every reply should be of DL_TASK_REPLY (one should be
** DL_STAT_REPLY)
*/
#include <minix/drivers.h>
@ -66,61 +25,55 @@
/*
** Local data
*/
extern int errno;
static dpeth_t de_table[DE_PORT_NR];
static const char *progname;
static dpeth_t de_state;
static int de_instance;
typedef struct dp_conf { /* Configuration description structure */
port_t dpc_port;
int dpc_irq;
phys_bytes dpc_mem;
char *dpc_envvar;
} dp_conf_t;
/* Device default configuration */
static dp_conf_t dp_conf[DE_PORT_NR] = {
/* I/O port, IRQ, Buff addr, Env. var, Buf. selector */
{ 0x300, 5, 0xC8000, "DPETH0", },
{ 0x280, 10, 0xCC000, "DPETH1", },
#define DP_CONF_NR 3
static dp_conf_t dp_conf[DP_CONF_NR] = {
/* I/O port, IRQ, Buff addr, Env. var */
{ 0x300, 5, 0xC8000, },
{ 0x280, 10, 0xCC000, },
{ 0x000, 0, 0x00000, },
};
static char CopyErrMsg[] = "unable to read/write user data";
static char PortErrMsg[] = "illegal port";
static char RecvErrMsg[] = "netdriver_receive failed";
static char SendErrMsg[] = "send failed";
static char SizeErrMsg[] = "illegal packet size";
static char TypeErrMsg[] = "illegal message type";
static char DevName[] = "eth#?";
static void do_getname(message *mp);
/*
** Name: void reply(dpeth_t *dep, int err, int m_type)
** Function: Fills a reply message and sends it.
*/
static void reply(dpeth_t * dep, int err, int m_type)
static void reply(dpeth_t * dep)
{
message reply;
int status = FALSE;
int r, flags;
if (dep->de_flags & DEF_ACK_SEND) status |= DL_PACK_SEND;
if (dep->de_flags & DEF_ACK_RECV) status |= DL_PACK_RECV;
flags = DL_NOFLAGS;
if (dep->de_flags & DEF_ACK_SEND) flags |= DL_PACK_SEND;
if (dep->de_flags & DEF_ACK_RECV) flags |= DL_PACK_RECV;
reply.m_type = m_type;
reply.DL_PORT = dep - de_table;
reply.DL_PROC = dep->de_client;
reply.DL_STAT = status /* | ((u32_t) err << 16) */;
reply.m_type = DL_TASK_REPLY;
reply.DL_FLAGS = flags;
reply.DL_COUNT = dep->de_read_s;
getuptime(&reply.DL_CLCK);
DEBUG(printf("\t reply %d (%ld)\n", reply.m_type, reply.DL_STAT));
DEBUG(printf("\t reply %d (%lx)\n", reply.m_type, reply.DL_FLAGS));
if ((status = send(dep->de_client, &reply)) == OK) {
dep->de_read_s = 0;
dep->de_flags &= NOT(DEF_ACK_SEND | DEF_ACK_RECV);
if ((r = send(dep->de_client, &reply)) != OK)
panic(SendErrMsg, r);
} else if (status != ELOCKED || err == OK)
panic(SendErrMsg, status);
dep->de_read_s = 0;
dep->de_flags &= NOT(DEF_ACK_SEND | DEF_ACK_RECV);
return;
}
@ -136,8 +89,8 @@ static void dp_confaddr(dpeth_t * dep)
int ix;
long val;
strcpy(ea_key, dp_conf[dep - de_table].dpc_envvar);
strcat(ea_key, "_EA");
strcpy(ea_key, "DPETH0_EA");
ea_key[5] += de_instance;
for (ix = 0; ix < SA_ADDR_LEN; ix++) {
val = dep->de_address.ea_addr[ix];
@ -160,11 +113,15 @@ static void dp_confaddr(dpeth_t * dep)
static void update_conf(dpeth_t * dep, const dp_conf_t * dcp)
{
static char dpc_fmt[] = "x:d:x";
char ec_key[16];
long val;
strcpy(ec_key, "DPETH0");
ec_key[5] += de_instance;
dep->de_mode = DEM_SINK;
val = dcp->dpc_port; /* Get I/O port address */
switch (env_parse(dcp->dpc_envvar, dpc_fmt, 0, &val, 0x000L, 0x3FFL)) {
switch (env_parse(ec_key, dpc_fmt, 0, &val, 0x000L, 0x3FFL)) {
case EP_OFF: dep->de_mode = DEM_DISABLED; break;
case EP_ON:
case EP_SET: dep->de_mode = DEM_ENABLED; break;
@ -172,11 +129,11 @@ static void update_conf(dpeth_t * dep, const dp_conf_t * dcp)
dep->de_base_port = val;
val = dcp->dpc_irq | DEI_DEFAULT; /* Get Interrupt line (IRQ) */
env_parse(dcp->dpc_envvar, dpc_fmt, 1, &val, 0L, (long) NR_IRQ_VECTORS - 1);
env_parse(ec_key, dpc_fmt, 1, &val, 0L, (long) NR_IRQ_VECTORS - 1);
dep->de_irq = val;
val = dcp->dpc_mem; /* Get shared memory address */
env_parse(dcp->dpc_envvar, dpc_fmt, 2, &val, 0L, LONG_MAX);
env_parse(ec_key, dpc_fmt, 2, &val, 0L, LONG_MAX);
dep->de_linmem = val;
return;
@ -189,40 +146,40 @@ static void update_conf(dpeth_t * dep, const dp_conf_t * dcp)
static void do_dump(const message *mp)
{
dpeth_t *dep;
int port;
dep = &de_state;
printf("\n\n");
for (port = 0, dep = de_table; port < DE_PORT_NR; port += 1, dep += 1) {
if (dep->de_mode == DEM_DISABLED) continue;
if (dep->de_mode == DEM_DISABLED) return;
printf("%s statistics:\t\t", dep->de_name);
printf("%s statistics:\t\t", dep->de_name);
/* Network interface status */
printf("Status: 0x%04x (%d)\n\n", dep->de_flags, dep->de_int_pending);
/* Network interface status */
printf("Status: 0x%04x (%d)\n\n", dep->de_flags, dep->de_int_pending);
(*dep->de_dumpstatsf) (dep);
(*dep->de_dumpstatsf) (dep);
/* Transmitted/received bytes */
printf("Tx bytes:%10ld\t", dep->bytes_Tx);
printf("Rx bytes:%10ld\n", dep->bytes_Rx);
/* Transmitted/received bytes */
printf("Tx bytes:%10ld\t", dep->bytes_Tx);
printf("Rx bytes:%10ld\n", dep->bytes_Rx);
/* Transmitted/received packets */
printf("Tx OK: %8ld\t", dep->de_stat.ets_packetT);
printf("Rx OK: %8ld\n", dep->de_stat.ets_packetR);
/* Transmitted/received packets */
printf("Tx OK: %8ld\t", dep->de_stat.ets_packetT);
printf("Rx OK: %8ld\n", dep->de_stat.ets_packetR);
/* Transmit/receive errors */
printf("Tx Err: %8ld\t", dep->de_stat.ets_sendErr);
printf("Rx Err: %8ld\n", dep->de_stat.ets_recvErr);
/* Transmit/receive errors */
printf("Tx Err: %8ld\t", dep->de_stat.ets_sendErr);
printf("Rx Err: %8ld\n", dep->de_stat.ets_recvErr);
/* Transmit unnerruns/receive overrruns */
printf("Tx Und: %8ld\t", dep->de_stat.ets_fifoUnder);
printf("Rx Ovr: %8ld\n", dep->de_stat.ets_fifoOver);
/* Transmit unnerruns/receive overrruns */
printf("Tx Und: %8ld\t", dep->de_stat.ets_fifoUnder);
printf("Rx Ovr: %8ld\n", dep->de_stat.ets_fifoOver);
/* Transmit collisions/receive CRC errors */
printf("Tx Coll: %8ld\t", dep->de_stat.ets_collision);
printf("Rx CRC: %8ld\n", dep->de_stat.ets_CRCerr);
/* Transmit collisions/receive CRC errors */
printf("Tx Coll: %8ld\t", dep->de_stat.ets_collision);
printf("Rx CRC: %8ld\n", dep->de_stat.ets_CRCerr);
}
return;
}
@ -279,75 +236,73 @@ static void do_first_init(dpeth_t *dep, const dp_conf_t *dcp)
*/
static void do_init(const message * mp)
{
int port;
dpeth_t *dep;
dp_conf_t *dcp;
message reply_mess;
int r, confnr;
port = mp->DL_PORT;
if (port >= 0 && port < DE_PORT_NR) {
dep = &de_state;
dep = &de_table[port];
dcp = &dp_conf[port];
strcpy(dep->de_name, DevName);
dep->de_name[4] = '0' + port;
/* Pick a default configuration for this instance. */
confnr = MIN(de_instance, DP_CONF_NR-1);
if (dep->de_mode == DEM_DISABLED) {
dcp = &dp_conf[confnr];
strcpy(dep->de_name, DevName);
dep->de_name[4] = '0' + de_instance;
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;
}
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;
}
}
/* 'de_mode' may change if probe routines fail, test again */
switch (dep->de_mode) {
r = OK;
case DEM_DISABLED:
/* Device is configured OFF or hardware probe failed */
port = ENXIO;
break;
/* 'de_mode' may change if probe routines fail, test again */
switch (dep->de_mode) {
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;
case DEM_DISABLED:
/* Device is configured OFF or hardware probe failed */
r = ENXIO;
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;
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;
}
*(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
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;
} else { /* Port number is out of range */
port = ENXIO;
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);
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;
}
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);
}
/*
** 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 **/

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

View 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_state;
/* Re-enable interrupts. */
if (sys_irqenable(&e->irq_hook) != OK)
{
e = e1000_port(i);
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);
if (cause & (E1000_REG_ICR_RXO | E1000_REG_ICR_RXT))
e1000_readv_s(&e->rx_message, TRUE);
/* 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);
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);

View 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

File diff suppressed because it is too large Load diff

View 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);
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;
if (ec->mode != EC_ENABLED)
continue;
printf("lance statistics of instance %d:\n", ec_instance);
printf("lance statistics of port %d:\n", i);
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);
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);
}
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;
count = mp->DL_COUNT;
ec= &ec_table[port];
ec->client= mp->DL_PROC;
ec= &ec_state;
r = sys_safecopyfrom(mp->DL_PROC, mp->DL_GRANT, 0,
ec->client= mp->m_source;
count = mp->DL_COUNT;
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_state;
ec= &ec_table[port];
ec->client= mp->DL_PROC;
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 *
*===========================================================================*/

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

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

File diff suppressed because it is too large Load diff

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

View 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];
rep = &re_state;
if (rep->re_flags & REF_READING) {
is_reading = TRUE;
}
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);
}
/*===========================================================================*

File diff suppressed because it is too large Load diff

View 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

View 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;
int s;
for (i = 0; i < RE_PORT_NR; i++) {
/* Run interrupt handler at driver level. */
rl_handler(&re_state);
/* Run interrupt handler at driver level. */
rl_handler(&re_table[i]);
/* 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;
/* Should collect statistics */
if (!(++rep->dtcc_counter % RE_DTCC_VALUE))
rtl8169_update_stat(rep);
check_int_events();
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();
}

View 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

View file

@ -262,45 +262,35 @@
#define DL_RS_BASE 0x280
/* Message types for data link layer requests. */
#define DL_WRITE (DL_RQ_BASE + 3)
#define DL_WRITEV (DL_RQ_BASE + 4)
#define DL_READ (DL_RQ_BASE + 5)
#define DL_READV (DL_RQ_BASE + 6)
#define DL_CONF (DL_RQ_BASE + 7)
#define DL_STOP (DL_RQ_BASE + 8)
#define DL_GETSTAT (DL_RQ_BASE + 9)
#define DL_GETNAME (DL_RQ_BASE +10)
#define DL_WRITEV_S (DL_RQ_BASE +11)
#define DL_READV_S (DL_RQ_BASE +12)
#define DL_GETSTAT_S (DL_RQ_BASE +13)
#define DL_CONF (DL_RQ_BASE + 0)
#define DL_GETSTAT_S (DL_RQ_BASE + 1)
#define DL_WRITEV_S (DL_RQ_BASE + 2)
#define DL_READV_S (DL_RQ_BASE + 3)
/* Message type for data link layer replies. */
#define DL_CONF_REPLY (DL_RS_BASE + 20)
#define DL_TASK_REPLY (DL_RS_BASE + 21)
#define DL_NAME_REPLY (DL_RS_BASE + 22)
#define DL_STAT_REPLY (DL_RS_BASE + 23)
#define DL_CONF_REPLY (DL_RS_BASE + 0)
#define DL_STAT_REPLY (DL_RS_BASE + 1)
#define DL_TASK_REPLY (DL_RS_BASE + 2)
/* Field names for data link layer messages. */
#define DL_PORT m2_i1
#define DL_PROC m2_i2 /* endpoint */
#define DL_ENDPT m2_i2
#define DL_COUNT m2_i3
#define DL_MODE m2_l1
#define DL_CLCK m2_l2
#define DL_ADDR m2_p1
#define DL_STAT m2_l1
#define DL_FLAGS m2_l1
#define DL_GRANT m2_l2
#define DL_NAME m3_ca1
#define DL_STAT m3_i1
#define DL_HWADDR m3_ca1
/* Bits in 'DL_STAT' field of DL replies. */
/* Bits in 'DL_FLAGS' field of DL replies. */
# define DL_NOFLAGS 0x00
# define DL_PACK_SEND 0x01
# define DL_PACK_RECV 0x02
# define DL_READ_IP 0x04
/* Bits in 'DL_MODE' field of DL requests. */
# define DL_NOMODE 0x0
# define DL_PROMISC_REQ 0x2
# define DL_MULTI_REQ 0x4
# define DL_BROAD_REQ 0x8
# define DL_PROMISC_REQ 0x1
# define DL_MULTI_REQ 0x2
# define DL_BROAD_REQ 0x4
/*===========================================================================*
* SYSTASK request types and field names *

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

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

View file

@ -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

17
lib/libc/asyn/asyn.h Normal file
View file

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

View file

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

View file

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

View file

@ -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));
}

View file

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

61
lib/libc/asyn/asyn_read.c Normal file
View file

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

View file

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

View file

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

119
lib/libc/asyn/asyn_wait.c Normal file
View file

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

View file

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

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

View file

@ -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);
}

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

View 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

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;

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

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

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