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:
parent
f5bce90216
commit
9ba65d2ea8
55 changed files with 1971 additions and 4794 deletions
|
@ -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. */
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,15 +1031,11 @@ PRIVATE void atl2_conf(message *m)
|
|||
ether_addr_t *addr;
|
||||
int r;
|
||||
|
||||
if (m->DL_PORT != 0) {
|
||||
m->m3_i1 = ENXIO;
|
||||
}
|
||||
else {
|
||||
state.mode = m->DL_MODE;
|
||||
|
||||
atl2_set_mode();
|
||||
|
||||
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;
|
||||
|
@ -1068,10 +1044,8 @@ PRIVATE void atl2_conf(message *m)
|
|||
addr->ea_addr[4] = (state.hwaddr[0] >> 8) & 0xff;
|
||||
addr->ea_addr[5] = state.hwaddr[0] & 0xff;
|
||||
|
||||
m->m3_i1 = OK;
|
||||
}
|
||||
|
||||
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,
|
||||
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;
|
||||
|
|
|
@ -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,14 +94,13 @@ int main(int argc, char *argv[])
|
|||
break;
|
||||
|
||||
case HARDWARE:
|
||||
for (dep = de_table; dep < &de_table[DE_PORT_NR]; dep += 1) {
|
||||
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, OK, TRUE);
|
||||
do_reply(dep);
|
||||
sys_irqenable(&dep->de_hook);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("ignoring notify from %d\n", m.m_source);
|
||||
|
@ -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,31 +191,32 @@ 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;
|
||||
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_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;
|
||||
}
|
||||
}
|
||||
|
||||
r = OK;
|
||||
|
||||
/* 'de_mode' may change if probe routines fail, test again */
|
||||
switch (dep->de_mode) {
|
||||
|
||||
case DEM_DISABLED:
|
||||
port = ENXIO; /* Device is OFF or hardware probe failed */
|
||||
r = ENXIO; /* Device is OFF or hardware probe failed */
|
||||
break;
|
||||
|
||||
case DEM_ENABLED:
|
||||
|
@ -243,7 +235,6 @@ PRIVATE void do_conf(const message * mp)
|
|||
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:
|
||||
|
@ -254,16 +245,11 @@ PRIVATE void do_conf(const message * mp)
|
|||
|
||||
default: break;
|
||||
}
|
||||
} else { /* Port number is out of range */
|
||||
port = ENXIO;
|
||||
dep = NULL;
|
||||
}
|
||||
|
||||
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){
|
||||
|
|
|
@ -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
|
@ -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;
|
||||
|
|
|
@ -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,62 +25,56 @@
|
|||
/*
|
||||
** 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 ((r = send(dep->de_client, &reply)) != OK)
|
||||
panic(SendErrMsg, r);
|
||||
|
||||
if ((status = send(dep->de_client, &reply)) == OK) {
|
||||
dep->de_read_s = 0;
|
||||
dep->de_flags &= NOT(DEF_ACK_SEND | DEF_ACK_RECV);
|
||||
|
||||
} else if (status != ELOCKED || err == OK)
|
||||
panic(SendErrMsg, status);
|
||||
|
||||
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,12 +146,12 @@ 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);
|
||||
|
||||
|
@ -222,7 +179,7 @@ static void do_dump(const message *mp)
|
|||
/* 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,18 +236,19 @@ 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];
|
||||
/* Pick a default configuration for this instance. */
|
||||
confnr = MIN(de_instance, DP_CONF_NR-1);
|
||||
|
||||
dcp = &dp_conf[confnr];
|
||||
strcpy(dep->de_name, DevName);
|
||||
dep->de_name[4] = '0' + port;
|
||||
dep->de_name[4] = '0' + de_instance;
|
||||
|
||||
if (dep->de_mode == DEM_DISABLED) {
|
||||
|
||||
|
@ -307,12 +265,14 @@ static void do_init(const message * mp)
|
|||
}
|
||||
}
|
||||
|
||||
r = OK;
|
||||
|
||||
/* 'de_mode' may change if probe routines fail, test again */
|
||||
switch (dep->de_mode) {
|
||||
|
||||
case DEM_DISABLED:
|
||||
/* Device is configured OFF or hardware probe failed */
|
||||
port = ENXIO;
|
||||
r = ENXIO;
|
||||
break;
|
||||
|
||||
case DEM_ENABLED:
|
||||
|
@ -328,7 +288,6 @@ static void do_init(const message * mp)
|
|||
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_SINK:
|
||||
|
@ -339,15 +298,11 @@ static void do_init(const message * mp)
|
|||
|
||||
default: break;
|
||||
}
|
||||
*(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
|
||||
|
||||
} else { /* Port number is out of range */
|
||||
port = ENXIO;
|
||||
}
|
||||
|
||||
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,18 +476,18 @@ PRIVATE void handle_hw_intr(void)
|
|||
{
|
||||
dpeth_t *dep;
|
||||
|
||||
for (dep = de_table; dep < &de_table[DE_PORT_NR]; dep += 1) {
|
||||
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, !OK, DL_TASK_REPLY);
|
||||
reply(dep);
|
||||
dep->de_int_pending = FALSE;
|
||||
sys_irqenable(&dep->de_hook);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* SEF functions and variables. */
|
||||
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
|
||||
|
@ -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 **/
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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.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.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++)
|
||||
{
|
||||
e = &e1000_state;
|
||||
strcpy(e->name, "e1000#0");
|
||||
e->name[6] += i;
|
||||
e1000_probe(e, i);
|
||||
}
|
||||
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,16 +796,13 @@ message *mp;
|
|||
{
|
||||
e1000_t *e;
|
||||
u32_t cause;
|
||||
unsigned int i;
|
||||
|
||||
E1000_DEBUG(3, ("e1000: interrupt\n"));
|
||||
|
||||
/*
|
||||
* Loop all cards. Check for interrupt reason(s).
|
||||
* Check the card for interrupt reason(s).
|
||||
*/
|
||||
for (i = 0; i < E1000_PORT_NR; i++)
|
||||
{
|
||||
e = e1000_port(i);
|
||||
e = &e1000_state;
|
||||
|
||||
/* Re-enable interrupts. */
|
||||
if (sys_irqenable(&e->irq_hook) != OK)
|
||||
|
@ -858,8 +822,6 @@ message *mp;
|
|||
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);
|
||||
|
|
|
@ -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
|
@ -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,13 +102,11 @@ _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_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,
|
||||
|
@ -118,8 +119,7 @@ _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 getAddressing, (int devind, ether_card_t *ec) );
|
||||
|
@ -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 ((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 (is_ipc_notify(ipc_status)) {
|
||||
switch(_ENDPOINT_P(m.m_source)) {
|
||||
|
@ -306,18 +300,12 @@ void main( int argc, char **argv )
|
|||
lance_dump();
|
||||
break;
|
||||
case HARDWARE:
|
||||
for (i=0;i<EC_PORT_NR_MAX;++i)
|
||||
{
|
||||
ec= &ec_table[i];
|
||||
if (ec->mode != EC_ENABLED)
|
||||
continue;
|
||||
|
||||
if (ec->mode == EC_ENABLED)
|
||||
{
|
||||
ec->ec_int_pending = 0;
|
||||
ec_check_ints(ec);
|
||||
do_int(ec);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
panic("illegal notify source: %d", m.m_source);
|
||||
|
@ -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 );
|
||||
|
@ -396,8 +377,8 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
|
|||
#endif
|
||||
|
||||
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);
|
||||
ec_instance = (int) v;
|
||||
|
||||
/* Announce we are up! */
|
||||
netdriver_announce();
|
||||
|
@ -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,21 +411,20 @@ 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++)
|
||||
{
|
||||
ec = &ec_state;
|
||||
if (ec->mode == EC_DISABLED)
|
||||
printf("lance port %d is disabled\n", i);
|
||||
printf("lance instance %d is disabled\n", ec_instance);
|
||||
else if (ec->mode == EC_SINK)
|
||||
printf("lance port %d is in sink mode\n", i);
|
||||
printf("lance instance %d is in sink mode\n", ec_instance);
|
||||
|
||||
if (ec->mode != EC_ENABLED)
|
||||
continue;
|
||||
return;
|
||||
|
||||
printf("lance statistics of port %d:\n", i);
|
||||
printf("lance statistics of instance %d:\n", ec_instance);
|
||||
|
||||
printf("recvErr :%8ld\t", ec->eth_stat.ets_recvErr);
|
||||
printf("sendErr :%8ld\t", ec->eth_stat.ets_sendErr);
|
||||
|
@ -493,8 +465,6 @@ static void lance_dump()
|
|||
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;
|
||||
{
|
||||
int port;
|
||||
static void lance_stop(ec)
|
||||
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 *
|
||||
*===========================================================================*/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
@ -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"
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
||||
|
|
|
@ -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,19 +436,18 @@ 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++) {
|
||||
rep = &re_state;
|
||||
|
||||
if (rep->re_mode != REM_ENABLED)
|
||||
continue;
|
||||
return;
|
||||
if (!rep->re_got_int)
|
||||
continue;
|
||||
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,19 +484,20 @@ 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);
|
||||
printf("Realtek RTL 8169 instance %d is disabled\n",
|
||||
re_instance);
|
||||
|
||||
if (rep->re_mode != REM_ENABLED)
|
||||
continue;
|
||||
return;
|
||||
|
||||
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);
|
||||
|
@ -577,7 +563,6 @@ static void rtl8169_dump(void)
|
|||
printf("tx_head :%8d busy %d\t",
|
||||
rep->re_tx_head, rep->re_tx[rep->re_tx_head].ret_busy);
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* do_init *
|
||||
|
@ -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,18 +625,18 @@ 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++) {
|
||||
rep = &re_state;
|
||||
|
||||
strcpy(rep->re_name, "rtl8169#0");
|
||||
rep->re_name[8] += i;
|
||||
rep->re_name[8] += re_instance;
|
||||
rep->re_seen = FALSE;
|
||||
envvar[sizeof(RL_ENVVAR)-1] = '0' + i;
|
||||
envvar[sizeof(RL_ENVVAR)-1] = '0' + re_instance;
|
||||
if (0 == env_get_param(envvar, val, sizeof(val)) &&
|
||||
!env_prefix(envvar, "pci"))
|
||||
{
|
||||
|
@ -676,21 +651,12 @@ static void rl_pci_conf()
|
|||
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))
|
||||
if (rl_probe(rep, re_instance))
|
||||
rep->re_seen = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* rl_probe *
|
||||
|
@ -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,18 +1849,15 @@ static void dump_phy(const re_t *rep)
|
|||
|
||||
static void do_hard_int(void)
|
||||
{
|
||||
int i, s;
|
||||
|
||||
for (i = 0; i < RE_PORT_NR; i++) {
|
||||
int s;
|
||||
|
||||
/* Run interrupt handler at driver level. */
|
||||
rl_handler(&re_table[i]);
|
||||
rl_handler(&re_state);
|
||||
|
||||
/* Reenable interrupts for this hook. */
|
||||
if ((s = sys_irqenable(&re_table[i].re_hook_id)) != OK)
|
||||
if ((s = sys_irqenable(&re_state.re_hook_id)) != OK)
|
||||
printf("RTL8169: error, couldn't enable interrupts: %d\n", s);
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* rl_handler *
|
||||
|
@ -2091,14 +1973,14 @@ 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++) {
|
||||
rep = &re_state;
|
||||
|
||||
if (rep->re_mode != REM_ENABLED)
|
||||
continue;
|
||||
return;
|
||||
|
||||
/* Should collect statistics */
|
||||
if (!(++rep->dtcc_counter % RE_DTCC_VALUE))
|
||||
|
@ -2107,14 +1989,14 @@ timer_t *tp;
|
|||
if (!(rep->re_flags & REF_SEND_AVAIL)) {
|
||||
/* Assume that an idle system is alive */
|
||||
rep->re_tx_alive = TRUE;
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
if (rep->re_tx_alive) {
|
||||
rep->re_tx_alive = FALSE;
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
printf("rl_watchdog_f: resetting port %d mode 0x%x flags 0x%x\n",
|
||||
i, rep->re_mode, rep->re_flags);
|
||||
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;
|
||||
|
@ -2122,5 +2004,4 @@ timer_t *tp;
|
|||
|
||||
check_int_events();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
25
etc/usr/rc
25
etc/usr/rc
|
@ -74,6 +74,14 @@ upopt()
|
|||
service $opt up /usr/sbin/$service "$@"
|
||||
}
|
||||
|
||||
get_eth_labels() {
|
||||
# Filter out the non-vlan ethernet entries from inet.conf.
|
||||
# Produce as output a list of "drivername_instancenr"-formatted labels.
|
||||
# The first sed is taken from /bin as older GNU sed versions don't know '\t'.
|
||||
/bin/sed 's/\t/ /g' /etc/inet.conf | \
|
||||
sed -n 's/^ *eth[0-9][0-9]* *\([^ ][^ ]*\) *\([0-9][0-9]*\).*$/\1_\2/p' | \
|
||||
grep -v '^vlan_'
|
||||
}
|
||||
|
||||
DAEMONS=/etc/rc.daemons
|
||||
|
||||
|
@ -97,15 +105,14 @@ start)
|
|||
dd if=/dev/random of=$RANDOM_FILE bs=1024 count=1 2> /dev/null
|
||||
fi
|
||||
|
||||
# start only network drivers that are in use
|
||||
for driver in lance rtl8139 rtl8169 fxp e1000 dpeth dp8390 orinoco atl2 dec21140A
|
||||
do
|
||||
if grep " $driver " /etc/inet.conf > /dev/null 2>&1
|
||||
then
|
||||
eval arg=\$${driver}_arg
|
||||
if [ ! -z "$arg" ]; then arg="-args \"$arg\""; fi
|
||||
eval up $driver $arg -period 5HZ
|
||||
fi
|
||||
# start network driver instances for all configured ethernet devices
|
||||
for label in $(get_eth_labels); do
|
||||
driver=$(echo $label | sed 's/\(.*\)_.*/\1/')
|
||||
instance=$(echo $label | sed 's/.*_//')
|
||||
eval arg=\$${label}_arg
|
||||
if [ ! -z "$arg" ]; then arg=" $arg"; fi
|
||||
arg="-args \"instance=$instance$arg\""
|
||||
eval up $driver -label $label $arg -period 5HZ
|
||||
done
|
||||
up inet -script /etc/rs.inet -dev /dev/ip -devstyle STYLE_CLONE
|
||||
upopt -n printer -dev /dev/lp -period 10HZ
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
12
lib/libc/asyn/Makefile.inc
Normal file
12
lib/libc/asyn/Makefile.inc
Normal 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
17
lib/libc/asyn/asyn.h
Normal 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;
|
21
lib/libc/asyn/asyn_cancel.c
Normal file
21
lib/libc/asyn/asyn_cancel.c
Normal 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;
|
||||
}
|
24
lib/libc/asyn/asyn_close.c
Normal file
24
lib/libc/asyn/asyn_close.c
Normal 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;
|
||||
}
|
9
lib/libc/asyn/asyn_init.c
Normal file
9
lib/libc/asyn/asyn_init.c
Normal 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));
|
||||
}
|
14
lib/libc/asyn/asyn_pending.c
Normal file
14
lib/libc/asyn/asyn_pending.c
Normal 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
61
lib/libc/asyn/asyn_read.c
Normal 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;
|
||||
}
|
104
lib/libc/asyn/asyn_special.c
Normal file
104
lib/libc/asyn/asyn_special.c
Normal 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;
|
||||
}
|
27
lib/libc/asyn/asyn_synch.c
Normal file
27
lib/libc/asyn/asyn_synch.c
Normal 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
119
lib/libc/asyn/asyn_wait.c
Normal 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;
|
||||
}
|
50
lib/libc/asyn/asyn_write.c
Normal file
50
lib/libc/asyn/asyn_write.c
Normal 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;
|
||||
}
|
|
@ -35,7 +35,6 @@ SRCS+= \
|
|||
_vm_set_priv.c \
|
||||
_vm_update.c \
|
||||
_vm_query_exit.c \
|
||||
asynchio.c \
|
||||
basename.c \
|
||||
bcmp.c \
|
||||
bcopy.c \
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -184,8 +184,31 @@ PRIVATE int ip_select(fd, operations)
|
|||
int fd;
|
||||
unsigned operations;
|
||||
{
|
||||
printf("ip_select: not implemented\n");
|
||||
return 0;
|
||||
unsigned resops;
|
||||
ip_fd_t *ip_fd;
|
||||
|
||||
ip_fd= &ip_fd_table[fd];
|
||||
assert (ip_fd->if_flags & IFF_INUSE);
|
||||
|
||||
resops= 0;
|
||||
|
||||
if (operations & SR_SELECT_READ)
|
||||
{
|
||||
if (ip_sel_read(ip_fd))
|
||||
resops |= SR_SELECT_READ;
|
||||
else if (!(operations & SR_SELECT_POLL))
|
||||
ip_fd->if_flags |= IFF_SEL_READ;
|
||||
}
|
||||
if (operations & SR_SELECT_WRITE)
|
||||
{
|
||||
/* Should handle special case when the interface is down */
|
||||
resops |= SR_SELECT_WRITE;
|
||||
}
|
||||
if (operations & SR_SELECT_EXCEPTION)
|
||||
{
|
||||
printf("ip_select: not implemented for exceptions\n");
|
||||
}
|
||||
return resops;
|
||||
}
|
||||
|
||||
PUBLIC int ip_open (port, srfd, get_userdata, put_userdata, put_pkt,
|
||||
|
@ -230,6 +253,7 @@ select_res_t select_res;
|
|||
ip_fd->if_get_userdata= get_userdata;
|
||||
ip_fd->if_put_userdata= put_userdata;
|
||||
ip_fd->if_put_pkt= put_pkt;
|
||||
ip_fd->if_select_res= select_res;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -112,6 +112,7 @@ typedef struct ip_fd
|
|||
get_userdata_t if_get_userdata;
|
||||
put_userdata_t if_put_userdata;
|
||||
put_pkt_t if_put_pkt;
|
||||
select_res_t if_select_res;
|
||||
time_t if_exp_time;
|
||||
size_t if_rd_count;
|
||||
ioreq_t if_ioctl;
|
||||
|
@ -120,9 +121,10 @@ typedef struct ip_fd
|
|||
#define IFF_EMPTY 0x00
|
||||
#define IFF_INUSE 0x01
|
||||
#define IFF_OPTSET 0x02
|
||||
#define IFF_BUSY 0x1C
|
||||
#define IFF_BUSY 0x0C
|
||||
# define IFF_READ_IP 0x04
|
||||
# define IFF_IOCTL_IP 0x08
|
||||
#define IFF_SEL_READ 0x10
|
||||
|
||||
typedef enum nettype
|
||||
{
|
||||
|
@ -166,6 +168,7 @@ void ip_port_arrive ARGS(( ip_port_t *port, acc_t *pack, ip_hdr_t *ip_hdr ));
|
|||
void ip_arrived ARGS(( ip_port_t *port, acc_t *pack ));
|
||||
void ip_arrived_broadcast ARGS(( ip_port_t *port, acc_t *pack ));
|
||||
void ip_process_loopb ARGS(( event_t *ev, ev_arg_t arg ));
|
||||
int ip_sel_read ARGS(( ip_fd_t *ip_fd ));
|
||||
void ip_packet2user ARGS(( ip_fd_t *ip_fd, acc_t *pack, time_t exp_time,
|
||||
size_t data_len ));
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ Copyright 1995 Philip Homburg
|
|||
#include "ip.h"
|
||||
#include "ip_int.h"
|
||||
#include "ipr.h"
|
||||
#include "sr.h"
|
||||
|
||||
THIS_FILE
|
||||
|
||||
|
@ -361,6 +362,28 @@ acc_t *pack;
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
PUBLIC int ip_sel_read (ip_fd_t *ip_fd)
|
||||
{
|
||||
acc_t *pack;
|
||||
|
||||
if (!(ip_fd->if_flags & IFF_OPTSET))
|
||||
return 1; /* Read will not block */
|
||||
|
||||
if (ip_fd->if_rdbuf_head)
|
||||
{
|
||||
if (get_time() <= ip_fd->if_exp_time)
|
||||
return 1;
|
||||
|
||||
while (ip_fd->if_rdbuf_head)
|
||||
{
|
||||
pack= ip_fd->if_rdbuf_head;
|
||||
ip_fd->if_rdbuf_head= pack->acc_ext_link;
|
||||
bf_afree(pack);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
PUBLIC void ip_packet2user (ip_fd, pack, exp_time, data_len)
|
||||
ip_fd_t *ip_fd;
|
||||
acc_t *pack;
|
||||
|
@ -391,6 +414,16 @@ size_t data_len;
|
|||
else
|
||||
ip_fd->if_rdbuf_tail->acc_ext_link= pack;
|
||||
ip_fd->if_rdbuf_tail= pack;
|
||||
|
||||
if (ip_fd->if_flags & IFF_SEL_READ)
|
||||
{
|
||||
ip_fd->if_flags & ~IFF_SEL_READ;
|
||||
if (ip_fd->if_select_res)
|
||||
ip_fd->if_select_res(ip_fd->if_srfd,
|
||||
SR_SELECT_READ);
|
||||
else
|
||||
printf("ip_packet2user: no select_res\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,16 +30,7 @@ from FS:
|
|||
|_______________|___________|_________|_______|__________|_________|
|
||||
|
||||
from DL_ETH:
|
||||
_______________________________________________________________________
|
||||
| | | | | | |
|
||||
| m_type | DL_PORT | DL_PROC | DL_COUNT | DL_STAT | DL_TIME |
|
||||
|_______________|___________|_________|__________|____________|_________|
|
||||
| | | | | | |
|
||||
| DL_CONF_REPLY | minor dev | proc nr | rd_count | 0 | stat | time |
|
||||
|_______________|___________|_________|__________|____________|_________|
|
||||
| | | | | | |
|
||||
| DL_TASK_REPLY | minor dev | proc nr | rd_count | err | stat | time |
|
||||
|_______________|___________|_________|__________|____________|_________|
|
||||
(not documented here)
|
||||
*/
|
||||
|
||||
#include "inet.h"
|
||||
|
@ -178,7 +169,7 @@ PUBLIC void main()
|
|||
}
|
||||
}
|
||||
else if (m_type == DL_CONF_REPLY || m_type == DL_TASK_REPLY ||
|
||||
m_type == DL_NAME_REPLY || m_type == DL_STAT_REPLY)
|
||||
m_type == DL_STAT_REPLY)
|
||||
{
|
||||
eth_rec(&mq->mq_mess);
|
||||
mq_free(mq);
|
||||
|
@ -338,18 +329,16 @@ 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;
|
||||
}
|
||||
/* 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");
|
||||
|
@ -362,8 +351,15 @@ PRIVATE void ds_event()
|
|||
return;
|
||||
}
|
||||
|
||||
/* The driver label comes after the prefix. */
|
||||
label = key + strlen(driver_prefix);
|
||||
|
||||
/* A driver is (re)started. */
|
||||
eth_check_driver(owner_endpoint);
|
||||
eth_check_driver(label, owner_endpoint);
|
||||
}
|
||||
|
||||
if(r != ENOENT)
|
||||
printf("inet: ds_event: ds_check failed: %d\n", r);
|
||||
}
|
||||
|
||||
PUBLIC void panic0(file, line)
|
||||
|
|
|
@ -147,18 +147,55 @@ static void check_dev(int type, int ifno)
|
|||
|
||||
static int cfg_fd;
|
||||
static char word[16];
|
||||
static unsigned line;
|
||||
static unsigned char line[256], *lineptr;
|
||||
static unsigned linenr;
|
||||
|
||||
static void error(void)
|
||||
{
|
||||
printf("inet: error on line %u\n", line);
|
||||
printf("inet: error on line %u\n", linenr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int nextline(void)
|
||||
{
|
||||
/* Read a line from the configuration file, to be used by subsequent
|
||||
* token() calls. Skip empty lines, and lines where the first character
|
||||
* after leading "whitespace" is '#'. The last line of the file need
|
||||
* not be terminated by a newline. Return 1 if a line was read in
|
||||
* successfully, and 0 on EOF or error.
|
||||
*/
|
||||
unsigned char *lp, c;
|
||||
int r, skip;
|
||||
|
||||
lineptr = lp = line;
|
||||
linenr++;
|
||||
skip = -1;
|
||||
|
||||
while ((r = read(cfg_fd, &c, 1)) == 1) {
|
||||
if (c == '\n') {
|
||||
if (skip == 0)
|
||||
break;
|
||||
|
||||
linenr++;
|
||||
skip = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (skip == -1 && c > ' ')
|
||||
skip = (c == '#');
|
||||
|
||||
if (skip == 0 && lp < (unsigned char *) line + sizeof(line)-1)
|
||||
*lp++ = c;
|
||||
}
|
||||
|
||||
*lp = 0;
|
||||
return (r == 1 || lp != line);
|
||||
}
|
||||
|
||||
static void token(int need)
|
||||
{
|
||||
/* Read a word from the configuration file. Return a null string on
|
||||
* EOF. Return a punctiation as a one character word. If 'need' is
|
||||
/* Read a word from the configuration line. Return a null string on
|
||||
* EOL. Return a punctuation as a one character word. If 'need' is
|
||||
* true then an actual word is expected at this point, so err out if
|
||||
* not.
|
||||
*/
|
||||
|
@ -169,16 +206,16 @@ static void token(int need)
|
|||
*wp = 0;
|
||||
|
||||
while (c <= ' ') {
|
||||
if (c == '\n') line++;
|
||||
if (read(cfg_fd, &c, 1) != 1) {
|
||||
if (*lineptr == 0) {
|
||||
if (need) error();
|
||||
return;
|
||||
}
|
||||
c = *lineptr++;
|
||||
}
|
||||
|
||||
do {
|
||||
if (wp < (unsigned char *) word + sizeof(word)-1) *wp++ = c;
|
||||
if (read(cfg_fd, &c, 1) != 1) c= ' ';
|
||||
c = (*lineptr != 0) ? *lineptr++ : ' ';
|
||||
if (word[0] == ';' || word[0] == '{' || word[0] == '}') {
|
||||
if (need) error();
|
||||
break;
|
||||
|
@ -215,6 +252,7 @@ void read_conf(void)
|
|||
struct psip_conf *pcp;
|
||||
struct ip_conf *icp;
|
||||
struct stat st;
|
||||
char buf[sizeof(word)];
|
||||
|
||||
{ static int first= 1;
|
||||
if (!first) ip_panic(( "read_conf: called a second time" ));
|
||||
|
@ -233,7 +271,8 @@ void read_conf(void)
|
|||
pcp= psip_conf;
|
||||
icp= ip_conf;
|
||||
|
||||
while (token(0), word[0] != 0) {
|
||||
while (nextline()) {
|
||||
token(1);
|
||||
if (strncmp(word, "eth", 3) == 0) {
|
||||
ecp->ec_ifno= ifno= number(word+3, IP_PORT_MAX-1);
|
||||
type= NETTYPE_ETH;
|
||||
|
@ -251,10 +290,17 @@ void read_conf(void)
|
|||
}
|
||||
ecp->ec_port= number(word+3, IP_PORT_MAX-1);
|
||||
} else {
|
||||
ecp->ec_task= alloc(strlen(word)+1);
|
||||
strcpy(ecp->ec_task, word);
|
||||
/* The process label consists of the driver
|
||||
* name, an underscore, and the instance
|
||||
* number.
|
||||
*/
|
||||
strncpy(buf, word, sizeof(buf)-1);
|
||||
buf[sizeof(buf)-1]= 0;
|
||||
token(1);
|
||||
ecp->ec_port= number(word, IP_PORT_MAX-1);
|
||||
ecp->ec_label=
|
||||
alloc(strlen(buf)+1+strlen(word)+1);
|
||||
sprintf(ecp->ec_label, "%s_%s", buf, word);
|
||||
ecp->ec_port= 0;
|
||||
}
|
||||
ecp++;
|
||||
eth_conf_nr++;
|
||||
|
|
|
@ -26,12 +26,12 @@ extern dev_t ip_dev; /* Device number of /dev/ip */
|
|||
|
||||
struct eth_conf
|
||||
{
|
||||
char *ec_task; /* Kernel ethernet task name if nonnull */
|
||||
u8_t ec_port; /* Task port (!vlan) or Ethernet port (vlan) */
|
||||
char *ec_label; /* Process label name if nonnull */
|
||||
u8_t ec_port; /* Ethernet port for VLAN if label == NULL */
|
||||
u8_t ec_ifno; /* Interface number of /dev/eth* */
|
||||
u16_t ec_vlan; /* VLAN number of this net if task == NULL */
|
||||
u16_t ec_vlan; /* VLAN number of this net if label == NULL */
|
||||
};
|
||||
#define eth_is_vlan(ecp) ((ecp)->ec_task == NULL)
|
||||
#define eth_is_vlan(ecp) ((ecp)->ec_label == NULL)
|
||||
|
||||
struct psip_conf
|
||||
{
|
||||
|
|
|
@ -7,7 +7,6 @@ Copyright 1995 Philip Homburg
|
|||
*/
|
||||
|
||||
#include "inet.h"
|
||||
#include <minix/ds.h>
|
||||
#include <minix/safecopies.h>
|
||||
#include "proto.h"
|
||||
#include "osdep_eth.h"
|
||||
|
@ -22,22 +21,17 @@ Copyright 1995 Philip Homburg
|
|||
|
||||
THIS_FILE
|
||||
|
||||
static int recv_debug= 0;
|
||||
|
||||
FORWARD _PROTOTYPE( void setup_read, (eth_port_t *eth_port) );
|
||||
FORWARD _PROTOTYPE( void read_int, (eth_port_t *eth_port, int count) );
|
||||
FORWARD _PROTOTYPE( void eth_issue_send, (eth_port_t *eth_port) );
|
||||
FORWARD _PROTOTYPE( void write_int, (eth_port_t *eth_port) );
|
||||
FORWARD _PROTOTYPE( void eth_recvev, (event_t *ev, ev_arg_t ev_arg) );
|
||||
FORWARD _PROTOTYPE( void eth_sendev, (event_t *ev, ev_arg_t ev_arg) );
|
||||
FORWARD _PROTOTYPE( eth_port_t *find_port, (message *m) );
|
||||
FORWARD _PROTOTYPE( void eth_restart, (eth_port_t *eth_port,
|
||||
endpoint_t endpoint) );
|
||||
FORWARD _PROTOTYPE( void send_getstat, (eth_port_t *eth_port) );
|
||||
|
||||
PUBLIC void osdep_eth_init()
|
||||
{
|
||||
int i, j, r, rport;
|
||||
int i, j, rport;
|
||||
struct eth_conf *ecp;
|
||||
eth_port_t *eth_port, *rep;
|
||||
cp_grant_id_t gid;
|
||||
|
@ -98,10 +92,8 @@ PUBLIC void osdep_eth_init()
|
|||
}
|
||||
eth_port->etp_osdep.etp_rd_vec_grant= gid;
|
||||
|
||||
eth_port->etp_osdep.etp_port= ecp->ec_port;
|
||||
eth_port->etp_osdep.etp_task= ANY;
|
||||
eth_port->etp_osdep.etp_task= NONE;
|
||||
eth_port->etp_osdep.etp_recvconf= 0;
|
||||
eth_port->etp_osdep.etp_send_ev= 0;
|
||||
ev_init(ð_port->etp_osdep.etp_recvev);
|
||||
|
||||
sr_add_minor(if2minor(ecp->ec_ifno, ETH_DEV_OFF),
|
||||
|
@ -122,11 +114,10 @@ PUBLIC void osdep_eth_init()
|
|||
if (!eth_is_vlan(ecp))
|
||||
continue;
|
||||
|
||||
eth_port->etp_osdep.etp_port= ecp->ec_port;
|
||||
eth_port->etp_osdep.etp_task= ANY;
|
||||
eth_port->etp_osdep.etp_task= NONE;
|
||||
ev_init(ð_port->etp_osdep.etp_recvev);
|
||||
|
||||
rport= eth_port->etp_osdep.etp_port;
|
||||
rport= ecp->ec_port;
|
||||
assert(rport >= 0 && rport < eth_conf_nr);
|
||||
rep= ð_port_table[rport];
|
||||
if (!(rep->etp_flags & EPF_ENABLED))
|
||||
|
@ -185,57 +176,25 @@ acc_t *pack;
|
|||
eth_issue_send(eth_port);
|
||||
}
|
||||
|
||||
#if 0
|
||||
PRIVATE int notification_count;
|
||||
#endif
|
||||
|
||||
PUBLIC void eth_rec(message *m)
|
||||
{
|
||||
int i, r, m_type, stat;
|
||||
int i, r, m_type, flags;
|
||||
eth_port_t *loc_port, *vlan_port;
|
||||
char *drivername;
|
||||
struct eth_conf *ecp;
|
||||
|
||||
m_type= m->m_type;
|
||||
if (m_type == DL_NAME_REPLY)
|
||||
{
|
||||
drivername= m->m3_ca1;
|
||||
#if 0
|
||||
printf("eth_rec: got name: %s\n", drivername);
|
||||
|
||||
notification_count= 0;
|
||||
#endif
|
||||
|
||||
/* Re-init ethernet interfaces */
|
||||
for (i= 0, ecp= eth_conf, loc_port= eth_port_table;
|
||||
i<eth_conf_nr; i++, ecp++, loc_port++)
|
||||
{
|
||||
if (eth_is_vlan(ecp))
|
||||
continue;
|
||||
|
||||
if (strcmp(ecp->ec_task, drivername) != 0)
|
||||
{
|
||||
/* Wrong driver */
|
||||
continue;
|
||||
}
|
||||
eth_restart(loc_port, m->m_source);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
assert(m_type == DL_CONF_REPLY || m_type == DL_TASK_REPLY ||
|
||||
m_type == DL_STAT_REPLY);
|
||||
|
||||
for (i=0, loc_port= eth_port_table; i<eth_conf_nr; i++, loc_port++)
|
||||
{
|
||||
if (loc_port->etp_osdep.etp_port == m->DL_PORT &&
|
||||
loc_port->etp_osdep.etp_task == m->m_source)
|
||||
if (loc_port->etp_osdep.etp_task == m->m_source)
|
||||
break;
|
||||
}
|
||||
if (i >= eth_conf_nr)
|
||||
{
|
||||
printf("eth_rec: bad port %d in message type 0x%x from %d\n",
|
||||
m->DL_PORT, m_type, m->m_source);
|
||||
printf("eth_rec: message 0x%x from unknown driver %d\n",
|
||||
m_type, m->m_source);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -243,11 +202,11 @@ PUBLIC void eth_rec(message *m)
|
|||
{
|
||||
if (m_type == DL_TASK_REPLY)
|
||||
{
|
||||
stat= m->DL_STAT & 0xffff;
|
||||
flags= m->DL_FLAGS;
|
||||
|
||||
if (stat & DL_PACK_SEND)
|
||||
if (flags & DL_PACK_SEND)
|
||||
write_int(loc_port);
|
||||
if (stat & DL_PACK_RECV)
|
||||
if (flags & DL_PACK_RECV)
|
||||
read_int(loc_port, m->DL_COUNT);
|
||||
return;
|
||||
}
|
||||
|
@ -260,18 +219,13 @@ PUBLIC void eth_rec(message *m)
|
|||
return;
|
||||
}
|
||||
|
||||
r= m->m3_i1;
|
||||
if (r == ENXIO)
|
||||
{
|
||||
printf(
|
||||
"eth_rec(conf_reply): no ethernet device at task=%d,port=%d\n",
|
||||
loc_port->etp_osdep.etp_task,
|
||||
loc_port->etp_osdep.etp_port);
|
||||
return;
|
||||
}
|
||||
r= m->DL_STAT;
|
||||
if (r < 0)
|
||||
{
|
||||
ip_panic(("eth_rec: DL_INIT returned error %d\n", r));
|
||||
ip_warning(("eth_rec: DL_CONF returned error %d\n",
|
||||
r));
|
||||
|
||||
/* Just leave it in limbo. Nothing more we can do. */
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -279,7 +233,7 @@ PUBLIC void eth_rec(message *m)
|
|||
loc_port->etp_osdep.etp_state= OEPS_IDLE;
|
||||
loc_port->etp_flags |= EPF_ENABLED;
|
||||
|
||||
loc_port->etp_ethaddr= *(ether_addr_t *)m->m3_ca1;
|
||||
loc_port->etp_ethaddr= *(ether_addr_t *)m->DL_HWADDR;
|
||||
if (!(loc_port->etp_flags & EPF_GOT_ADDR))
|
||||
{
|
||||
loc_port->etp_flags |= EPF_GOT_ADDR;
|
||||
|
@ -332,14 +286,6 @@ PUBLIC void eth_rec(message *m)
|
|||
return;
|
||||
}
|
||||
|
||||
r= m->DL_STAT;
|
||||
if (r != OK)
|
||||
{
|
||||
ip_warning(("eth_rec: DL_STAT returned error %d\n",
|
||||
r));
|
||||
return;
|
||||
}
|
||||
|
||||
loc_port->etp_osdep.etp_state= OEPS_IDLE;
|
||||
loc_port->etp_osdep.etp_flags &= ~OEPF_NEED_STAT;
|
||||
|
||||
|
@ -383,27 +329,12 @@ PUBLIC void eth_rec(message *m)
|
|||
(printf("etp_state = %d\n", loc_port->etp_osdep.etp_state), 0));
|
||||
loc_port->etp_osdep.etp_state= OEPS_IDLE;
|
||||
|
||||
#if 0 /* Ethernet driver is not trusted */
|
||||
set_time (m->DL_CLCK);
|
||||
#endif
|
||||
flags= m->DL_FLAGS;
|
||||
|
||||
stat= m->DL_STAT & 0xffff;
|
||||
|
||||
#if 0
|
||||
if (!(stat & (DL_PACK_SEND|DL_PACK_RECV)))
|
||||
printf("eth_rec: neither DL_PACK_SEND nor DL_PACK_RECV\n");
|
||||
#endif
|
||||
if (stat & DL_PACK_SEND)
|
||||
if (flags & DL_PACK_SEND)
|
||||
write_int(loc_port);
|
||||
if (stat & DL_PACK_RECV)
|
||||
{
|
||||
if (recv_debug)
|
||||
{
|
||||
printf("eth_rec: eth%d got DL_PACK_RECV\n",
|
||||
m->DL_PORT);
|
||||
}
|
||||
if (flags & DL_PACK_RECV)
|
||||
read_int(loc_port, m->DL_COUNT);
|
||||
}
|
||||
|
||||
if (loc_port->etp_osdep.etp_state == OEPS_IDLE &&
|
||||
loc_port->etp_osdep.etp_flags & OEPF_NEED_SEND)
|
||||
|
@ -432,18 +363,25 @@ PUBLIC void eth_rec(message *m)
|
|||
}
|
||||
}
|
||||
|
||||
PUBLIC void eth_check_driver(endpoint_t endpoint)
|
||||
PUBLIC void eth_check_driver(char *label, endpoint_t endpoint)
|
||||
{
|
||||
int r;
|
||||
message m;
|
||||
int i;
|
||||
eth_port_t *loc_port;
|
||||
struct eth_conf *ecp;
|
||||
|
||||
m.m_type = DL_GETNAME;
|
||||
r= asynsend(endpoint, &m);
|
||||
if (r != OK)
|
||||
/* Re-init ethernet interface */
|
||||
for (i= 0, ecp= eth_conf, loc_port= eth_port_table;
|
||||
i<eth_conf_nr; i++, ecp++, loc_port++)
|
||||
{
|
||||
printf("eth_check_driver: asynsend to %d failed: %d\n",
|
||||
endpoint, r);
|
||||
return;
|
||||
if (eth_is_vlan(ecp))
|
||||
continue;
|
||||
|
||||
if (strcmp(ecp->ec_label, label) != 0)
|
||||
{
|
||||
/* Wrong driver */
|
||||
continue;
|
||||
}
|
||||
eth_restart(loc_port, endpoint);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -525,8 +463,6 @@ u32_t flags;
|
|||
dl_flags |= DL_PROMISC_REQ;
|
||||
|
||||
mess.m_type= DL_CONF;
|
||||
mess.DL_PORT= eth_port->etp_osdep.etp_port;
|
||||
mess.DL_PROC= this_proc;
|
||||
mess.DL_MODE= dl_flags;
|
||||
|
||||
assert(eth_port->etp_osdep.etp_state == OEPS_IDLE);
|
||||
|
@ -604,13 +540,10 @@ eth_port_t *eth_port;
|
|||
"eth_write_port: cpf_setgrant_direct failed: %d\n",
|
||||
errno));
|
||||
}
|
||||
m.m_type= DL_WRITEV_S;
|
||||
m.DL_ENDPT= this_proc;
|
||||
m.DL_COUNT= i;
|
||||
m.DL_GRANT= eth_port->etp_osdep.etp_wr_vec_grant;
|
||||
m.m_type= DL_WRITEV_S;
|
||||
|
||||
m.DL_PORT= eth_port->etp_osdep.etp_port;
|
||||
m.DL_PROC= this_proc;
|
||||
m.DL_MODE= DL_NOMODE;
|
||||
|
||||
assert(eth_port->etp_osdep.etp_state == OEPS_IDLE);
|
||||
r= asynsend(eth_port->etp_osdep.etp_task, &m);
|
||||
|
@ -634,7 +567,7 @@ PRIVATE void write_int(eth_port_t *eth_port)
|
|||
if (pack == NULL)
|
||||
{
|
||||
printf("write_int: strange no packet on eth port %d\n",
|
||||
eth_port-eth_port_table);
|
||||
(int)(eth_port-eth_port_table));
|
||||
eth_restart_write(eth_port);
|
||||
return;
|
||||
}
|
||||
|
@ -698,7 +631,7 @@ PRIVATE void setup_read(eth_port)
|
|||
eth_port_t *eth_port;
|
||||
{
|
||||
acc_t *pack, *pack_ptr;
|
||||
message mess1;
|
||||
message mess;
|
||||
iovec_s_t *iovec;
|
||||
int i, r;
|
||||
|
||||
|
@ -747,15 +680,14 @@ eth_port_t *eth_port;
|
|||
errno));
|
||||
}
|
||||
|
||||
mess1.m_type= DL_READV_S;
|
||||
mess1.DL_PORT= eth_port->etp_osdep.etp_port;
|
||||
mess1.DL_PROC= this_proc;
|
||||
mess1.DL_COUNT= i;
|
||||
mess1.DL_GRANT= eth_port->etp_osdep.etp_rd_vec_grant;
|
||||
mess.m_type= DL_READV_S;
|
||||
mess.DL_ENDPT= this_proc;
|
||||
mess.DL_COUNT= i;
|
||||
mess.DL_GRANT= eth_port->etp_osdep.etp_rd_vec_grant;
|
||||
|
||||
assert(eth_port->etp_osdep.etp_state == OEPS_IDLE);
|
||||
|
||||
r= asynsend(eth_port->etp_osdep.etp_task, &mess1);
|
||||
r= asynsend(eth_port->etp_osdep.etp_task, &mess);
|
||||
eth_port->etp_osdep.etp_state= OEPS_RECV_SENT;
|
||||
|
||||
if (r < 0)
|
||||
|
@ -769,72 +701,6 @@ eth_port_t *eth_port;
|
|||
eth_port->etp_flags |= EPF_READ_SP;
|
||||
}
|
||||
|
||||
PRIVATE void eth_recvev(ev, ev_arg)
|
||||
event_t *ev;
|
||||
ev_arg_t ev_arg;
|
||||
{
|
||||
eth_port_t *eth_port;
|
||||
message *m_ptr;
|
||||
|
||||
eth_port= ev_arg.ev_ptr;
|
||||
assert(ev == ð_port->etp_osdep.etp_recvev);
|
||||
m_ptr= ð_port->etp_osdep.etp_recvrepl;
|
||||
|
||||
assert(m_ptr->m_type == DL_TASK_REPLY);
|
||||
assert(eth_port->etp_osdep.etp_port == m_ptr->DL_PORT &&
|
||||
eth_port->etp_osdep.etp_task == m_ptr->m_source);
|
||||
|
||||
assert(m_ptr->DL_STAT & DL_PACK_RECV);
|
||||
m_ptr->DL_STAT &= ~DL_PACK_RECV;
|
||||
|
||||
if (recv_debug)
|
||||
{
|
||||
printf("eth_recvev: eth%d got DL_PACK_RECV\n", m_ptr->DL_PORT);
|
||||
}
|
||||
|
||||
read_int(eth_port, m_ptr->DL_COUNT);
|
||||
}
|
||||
|
||||
PRIVATE void eth_sendev(ev, ev_arg)
|
||||
event_t *ev;
|
||||
ev_arg_t ev_arg;
|
||||
{
|
||||
eth_port_t *eth_port;
|
||||
message *m_ptr;
|
||||
|
||||
eth_port= ev_arg.ev_ptr;
|
||||
assert(ev == ð_port->etp_sendev);
|
||||
m_ptr= ð_port->etp_osdep.etp_sendrepl;
|
||||
|
||||
assert (m_ptr->m_type == DL_TASK_REPLY);
|
||||
assert(eth_port->etp_osdep.etp_port == m_ptr->DL_PORT &&
|
||||
eth_port->etp_osdep.etp_task == m_ptr->m_source);
|
||||
|
||||
assert(m_ptr->DL_STAT & DL_PACK_SEND);
|
||||
m_ptr->DL_STAT &= ~DL_PACK_SEND;
|
||||
assert(eth_port->etp_osdep.etp_send_ev);
|
||||
eth_port->etp_osdep.etp_send_ev= 0;
|
||||
|
||||
/* packet is sent */
|
||||
write_int(eth_port);
|
||||
}
|
||||
|
||||
PRIVATE eth_port_t *find_port(m)
|
||||
message *m;
|
||||
{
|
||||
eth_port_t *loc_port;
|
||||
int i;
|
||||
|
||||
for (i=0, loc_port= eth_port_table; i<eth_conf_nr; i++, loc_port++)
|
||||
{
|
||||
if (loc_port->etp_osdep.etp_port == m->DL_PORT &&
|
||||
loc_port->etp_osdep.etp_task == m->m_source)
|
||||
break;
|
||||
}
|
||||
assert (i<eth_conf_nr);
|
||||
return loc_port;
|
||||
}
|
||||
|
||||
static void eth_restart(eth_port_t *eth_port, endpoint_t endpoint)
|
||||
{
|
||||
int r;
|
||||
|
@ -892,8 +758,6 @@ static void eth_restart(eth_port_t *eth_port, endpoint_t endpoint)
|
|||
if (flags & NWEO_EN_PROMISC)
|
||||
dl_flags |= DL_PROMISC_REQ;
|
||||
mess.m_type= DL_CONF;
|
||||
mess.DL_PORT= eth_port->etp_osdep.etp_port;
|
||||
mess.DL_PROC= this_proc;
|
||||
mess.DL_MODE= dl_flags;
|
||||
|
||||
compare(eth_port->etp_osdep.etp_state, ==, OEPS_IDLE);
|
||||
|
@ -929,8 +793,7 @@ eth_port_t *eth_port;
|
|||
message mess;
|
||||
|
||||
mess.m_type= DL_GETSTAT_S;
|
||||
mess.DL_PORT= eth_port->etp_osdep.etp_port;
|
||||
mess.DL_PROC= this_proc;
|
||||
mess.DL_ENDPT= this_proc;
|
||||
mess.DL_GRANT= eth_port->etp_osdep.etp_stat_gid;
|
||||
|
||||
assert(eth_port->etp_osdep.etp_state == OEPS_IDLE);
|
||||
|
|
|
@ -19,16 +19,12 @@ typedef struct osdep_eth_port
|
|||
int etp_state;
|
||||
int etp_flags;
|
||||
endpoint_t etp_task;
|
||||
int etp_port;
|
||||
int etp_recvconf;
|
||||
int etp_send_ev;
|
||||
iovec_s_t etp_wr_iovec[IOVEC_NR];
|
||||
cp_grant_id_t etp_wr_vec_grant;
|
||||
iovec_s_t etp_rd_iovec[RD_IOVEC];
|
||||
cp_grant_id_t etp_rd_vec_grant;
|
||||
event_t etp_recvev;
|
||||
message etp_sendrepl;
|
||||
message etp_recvrepl;
|
||||
cp_grant_id_t etp_stat_gid;
|
||||
eth_stat_t *etp_stat_buf;
|
||||
} osdep_eth_port_t;
|
||||
|
|
|
@ -13,7 +13,7 @@ _PROTOTYPE( void clck_tick, (message *mess) );
|
|||
/* mnx_eth.c */
|
||||
|
||||
_PROTOTYPE( void eth_rec, (message *m) );
|
||||
_PROTOTYPE( void eth_check_driver, (endpoint_t endpoint) );
|
||||
_PROTOTYPE( void eth_check_driver, (char *label, endpoint_t endpoint) );
|
||||
|
||||
/* sr.c */
|
||||
|
||||
|
|
|
@ -94,8 +94,6 @@ FORWARD _PROTOTYPE (void sr_select_res, (int fd, unsigned ops) );
|
|||
FORWARD _PROTOTYPE ( int sr_repl_queue, (int proc, int ref, int operation) );
|
||||
FORWARD _PROTOTYPE ( int walk_queue, (sr_fd_t *sr_fd, mq_t **q_head_ptr,
|
||||
mq_t **q_tail_ptr, int type, int proc_nr, int ref, int first_flag) );
|
||||
FORWARD _PROTOTYPE ( void process_req_q, (mq_t *mq, mq_t *tail,
|
||||
mq_t **tail_ptr) );
|
||||
FORWARD _PROTOTYPE ( void sr_event, (event_t *evp, ev_arg_t arg) );
|
||||
FORWARD _PROTOTYPE ( int cp_u2b, (endpoint_t proc, cp_grant_id_t gid,
|
||||
vir_bytes offset, acc_t **var_acc_ptr, int size) );
|
||||
|
@ -822,31 +820,6 @@ PRIVATE void sr_select_res(int fd, unsigned ops)
|
|||
notify(sr_fd->srf_select_proc);
|
||||
}
|
||||
|
||||
PRIVATE void process_req_q(mq, tail, tail_ptr)
|
||||
mq_t *mq, *tail, **tail_ptr;
|
||||
{
|
||||
mq_t *m;
|
||||
int result;
|
||||
|
||||
for(;mq;)
|
||||
{
|
||||
m= mq;
|
||||
mq= mq->mq_next;
|
||||
|
||||
result= sr_rwio(m);
|
||||
if (result == SUSPEND)
|
||||
{
|
||||
if (mq)
|
||||
{
|
||||
(*tail_ptr)->mq_next= mq;
|
||||
*tail_ptr= tail;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
PRIVATE void sr_event(evp, arg)
|
||||
event_t *evp;
|
||||
ev_arg_t arg;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue