static int fxp_tasknr= ANY;
static u16_t eth_ign_proto;
static tmra_ut fxp_watchdog;
+static char *progname;
extern int errno;
phys_bytes bus_addr, int check_idle) );
_PROTOTYPE( static void fxp_restart_ru, (fxp_t *fp) );
_PROTOTYPE( static void fxp_getstat, (message *mp) );
+_PROTOTYPE( static void fxp_getname, (message *mp) );
_PROTOTYPE( static int fxp_handler, (fxp_t *fp) );
_PROTOTYPE( static void fxp_check_ints, (fxp_t *fp) );
_PROTOTYPE( static void fxp_watchdog_f, (timer_t *tp) );
/*===========================================================================*
* main *
*===========================================================================*/
-int main(void)
+int main(int argc, char *argv[])
{
message m;
- int i, r;
+ int i, r, tasknr;
fxp_t *fp;
long v;
if ((fxp_tasknr= getprocnr())<0)
panic("FXP", "couldn't get proc nr", errno);
+ if (argc < 1)
+ panic("FXP", "A head which at this time has no name", NO_NUM);
+ (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
+
v= 0;
#if 0
(void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
fxp_init_buf(fp);
#endif
+ /* Try to notify inet that we are present (again) */
+ r = findproc("inet", &tasknr);
+ if (r == OK)
+ notify(tasknr);
+ else
+ printf("fxp: cannot find proc number for inet: %d\n", r);
+
while (TRUE)
{
if ((r= receive(ANY, &m)) != OK)
case DL_READV: fxp_readv(&m, FALSE, TRUE); break;
case DL_INIT: fxp_init(&m); break;
case DL_GETSTAT: fxp_getstat(&m); break;
+ case DL_GETNAME: fxp_getname(&m); break;
case HARD_INT:
for (i= 0, fp= &fxp_table[0]; i<FXP_PORT_NR; i++, fp++)
{
reply(fp, OK, FALSE);
}
+
+/*===========================================================================*
+ * fxp_getname *
+ *===========================================================================*/
+static void fxp_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("FXP", "fxp_getname: send failed: %d\n", r);
+}
+
/*===========================================================================*
* fxp_handler *
*===========================================================================*/
static u8_t do_inb(port_t port)
{
int r;
- u8_t value;
+ u32_t value;
r= sys_inb(port, &value);
if (r != OK)
#define DL_INIT (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)
/* Message type for data link layer replies. */
#define DL_INIT_REPLY (DL_RS_BASE + 20)
#define DL_TASK_REPLY (DL_RS_BASE + 21)
+#define DL_NAME_REPLY (DL_RS_BASE + 22)
/* Field names for data link layer messages. */
#define DL_PORT m2_i1
#define DL_CLCK m2_l2
#define DL_ADDR m2_p1
#define DL_STAT m2_l1
+#define DL_NAME m3_ca1
/* Bits in 'DL_STAT' field of DL replies. */
# define DL_PACK_SEND 0x01
#else /* Minix 3 */
else if (mq->mq_mess.m_type == SYN_ALARM)
{
- clck_tick(&mq->mq_mess);
- mq_free(mq);
+ clck_tick(&mq->mq_mess);
+ mq_free(mq);
}
else if (mq->mq_mess.m_type == SYS_SIG)
{
- /* signaled */
- /* probably SIGTERM */
- mq_free(mq);
+ /* signaled */
+ /* probably SIGTERM */
+ mq_free(mq);
}
+ else if (mq->mq_mess.m_type & NOTIFY_MESSAGE)
+ {
+ /* A driver is (re)started. */
+ eth_check_drivers(&mq->mq_mess);
+ mq_free(mq);
+ }
#endif
else
{
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, int tasknr) );
PUBLIC void osdep_eth_init()
{
}
}
+PUBLIC void eth_check_drivers(m)
+message *m;
+{
+ int i, r, tasknr;
+ struct eth_conf *ecp;
+ eth_port_t *eth_port;
+ char *drivername;
+
+ tasknr= m->m_source;
+ printf("eth_check_drivers: got a notification from %d\n", tasknr);
+
+ m->m_type= DL_GETNAME;
+ r= sendrec(tasknr, m);
+ if (r != OK)
+ {
+ printf("eth_check_drivers: sendrec to %d failed: %d\n",
+ tasknr, r);
+ return;
+ }
+ if (m->m_type != DL_NAME_REPLY)
+ {
+ printf(
+ "eth_check_drivers: got bad getname reply (%d) from %d\n",
+ m->m_type, tasknr);
+ return;
+ }
+
+ drivername= m->m3_ca1;
+ printf("eth_check_drivers: got name: %s\n", drivername);
+
+ /* Re-init ethernet interfaces */
+ for (i= 0, ecp= eth_conf, eth_port= eth_port_table;
+ i<eth_conf_nr; i++, ecp++, eth_port++)
+ {
+ if (eth_is_vlan(ecp))
+ continue;
+
+ if (strcmp(ecp->ec_task, drivername) != 0)
+ {
+ /* Wrong driver */
+ continue;
+ }
+
+ eth_restart(eth_port, tasknr);
+ }
+}
+
PUBLIC int eth_get_stat(eth_port, eth_stat)
eth_port_t *eth_port;
eth_stat_t *eth_stat;
mess.DL_PORT= eth_port->etp_osdep.etp_port;
mess.DL_PROC= this_proc;
mess.DL_MODE= dl_flags;
+ eth_port->etp_osdep.etp_dl_flags= dl_flags;
do
{
return loc_port;
}
+static void eth_restart(eth_port, tasknr)
+eth_port_t *eth_port;
+int tasknr;
+{
+ int r;
+ message mess;
+#if 0
+ int i, r, rport;
+ struct eth_conf *ecp;
+ eth_port_t *rep;
+#endif
+
+ printf("eth_restart: restarting eth%d, task %d, port %d\n",
+ eth_port-eth_port_table, tasknr,
+ eth_port->etp_osdep.etp_port);
+
+ eth_port->etp_osdep.etp_task= tasknr;
+
+ mess.m_type= DL_INIT;
+ mess.DL_PORT= eth_port->etp_osdep.etp_port;
+ mess.DL_PROC= this_proc;
+ mess.DL_MODE= eth_port->etp_osdep.etp_dl_flags;
+
+ r= send(eth_port->etp_osdep.etp_task, &mess);
+ if (r<0)
+ {
+ printf(
+ "osdep_eth_init: unable to send to ethernet task, error= %d\n",
+ r);
+ return;
+ }
+
+ if (receive(eth_port->etp_osdep.etp_task, &mess)<0)
+ ip_panic(("unable to receive"));
+
+ if (mess.m3_i1 == ENXIO)
+ {
+ printf(
+ "osdep_eth_init: no ethernet device at task=%d,port=%d\n",
+ eth_port->etp_osdep.etp_task,
+ eth_port->etp_osdep.etp_port);
+ return;
+ }
+ if (mess.m3_i1 < 0)
+ ip_panic(("osdep_eth_init: DL_INIT returned error %d\n",
+ mess.m3_i1));
+
+ if (mess.m3_i1 != eth_port->etp_osdep.etp_port)
+ {
+ ip_panic((
+"osdep_eth_init: got reply for wrong port (got %d, expected %d)\n",
+ mess.m3_i1, eth_port->etp_osdep.etp_port));
+ }
+
+ eth_port->etp_ethaddr= *(ether_addr_t *)mess.m3_ca1;
+
+ eth_port->etp_flags |= EPF_ENABLED;
+ if (eth_port->etp_wr_pack)
+ ip_panic(("eth_restart: should clear etp_wr_pack\n"));
+ if (eth_port->etp_rd_pack)
+ ip_panic(("eth_restart: should clear etp_rd_pack\n"));
+ setup_read (eth_port);
+}
+
/*
* $PchId: mnx_eth.c,v 1.16 2005/06/28 14:24:37 philip Exp $
*/
int etp_task;
int etp_port;
int etp_recvconf;
+ unsigned etp_dl_flags;
iovec_t etp_wr_iovec[IOVEC_NR];
iovec_t etp_rd_iovec[RD_IOVEC];
event_t etp_recvev;
/* mnx_eth.c */
_PROTOTYPE( void eth_rec, (message *m) );
+_PROTOTYPE( void eth_check_drivers, (message *m) );
/* sr.c */