Prelim commit for ethernet driver crash recovery.
This commit is contained in:
parent
f0985a4e97
commit
724813fdce
|
@ -201,6 +201,7 @@ static fxp_t fxp_table[FXP_PORT_NR];
|
||||||
static int fxp_tasknr= ANY;
|
static int fxp_tasknr= ANY;
|
||||||
static u16_t eth_ign_proto;
|
static u16_t eth_ign_proto;
|
||||||
static tmra_ut fxp_watchdog;
|
static tmra_ut fxp_watchdog;
|
||||||
|
static char *progname;
|
||||||
|
|
||||||
extern int errno;
|
extern int errno;
|
||||||
|
|
||||||
|
@ -231,6 +232,7 @@ _PROTOTYPE( static void fxp_ru_ptr_cmd, (fxp_t *fp, int cmd,
|
||||||
phys_bytes bus_addr, int check_idle) );
|
phys_bytes bus_addr, int check_idle) );
|
||||||
_PROTOTYPE( static void fxp_restart_ru, (fxp_t *fp) );
|
_PROTOTYPE( static void fxp_restart_ru, (fxp_t *fp) );
|
||||||
_PROTOTYPE( static void fxp_getstat, (message *mp) );
|
_PROTOTYPE( static void fxp_getstat, (message *mp) );
|
||||||
|
_PROTOTYPE( static void fxp_getname, (message *mp) );
|
||||||
_PROTOTYPE( static int fxp_handler, (fxp_t *fp) );
|
_PROTOTYPE( static int fxp_handler, (fxp_t *fp) );
|
||||||
_PROTOTYPE( static void fxp_check_ints, (fxp_t *fp) );
|
_PROTOTYPE( static void fxp_check_ints, (fxp_t *fp) );
|
||||||
_PROTOTYPE( static void fxp_watchdog_f, (timer_t *tp) );
|
_PROTOTYPE( static void fxp_watchdog_f, (timer_t *tp) );
|
||||||
|
@ -255,16 +257,20 @@ _PROTOTYPE( static void do_outl, (port_t port, u32_t v) );
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* main *
|
* main *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
int main(void)
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
message m;
|
message m;
|
||||||
int i, r;
|
int i, r, tasknr;
|
||||||
fxp_t *fp;
|
fxp_t *fp;
|
||||||
long v;
|
long v;
|
||||||
|
|
||||||
if ((fxp_tasknr= getprocnr())<0)
|
if ((fxp_tasknr= getprocnr())<0)
|
||||||
panic("FXP", "couldn't get proc nr", errno);
|
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;
|
v= 0;
|
||||||
#if 0
|
#if 0
|
||||||
(void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
|
(void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
|
||||||
|
@ -277,6 +283,13 @@ int main(void)
|
||||||
fxp_init_buf(fp);
|
fxp_init_buf(fp);
|
||||||
#endif
|
#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)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
if ((r= receive(ANY, &m)) != OK)
|
if ((r= receive(ANY, &m)) != OK)
|
||||||
|
@ -292,6 +305,7 @@ int main(void)
|
||||||
case DL_READV: fxp_readv(&m, FALSE, TRUE); break;
|
case DL_READV: fxp_readv(&m, FALSE, TRUE); break;
|
||||||
case DL_INIT: fxp_init(&m); break;
|
case DL_INIT: fxp_init(&m); break;
|
||||||
case DL_GETSTAT: fxp_getstat(&m); break;
|
case DL_GETSTAT: fxp_getstat(&m); break;
|
||||||
|
case DL_GETNAME: fxp_getname(&m); break;
|
||||||
case HARD_INT:
|
case HARD_INT:
|
||||||
for (i= 0, fp= &fxp_table[0]; i<FXP_PORT_NR; i++, fp++)
|
for (i= 0, fp= &fxp_table[0]; i<FXP_PORT_NR; i++, fp++)
|
||||||
{
|
{
|
||||||
|
@ -1571,6 +1585,23 @@ message *mp;
|
||||||
reply(fp, OK, FALSE);
|
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 *
|
* fxp_handler *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
|
@ -2417,7 +2448,7 @@ static void micro_delay(unsigned long usecs)
|
||||||
static u8_t do_inb(port_t port)
|
static u8_t do_inb(port_t port)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
u8_t value;
|
u32_t value;
|
||||||
|
|
||||||
r= sys_inb(port, &value);
|
r= sys_inb(port, &value);
|
||||||
if (r != OK)
|
if (r != OK)
|
||||||
|
|
|
@ -150,10 +150,12 @@
|
||||||
#define DL_INIT (DL_RQ_BASE + 7)
|
#define DL_INIT (DL_RQ_BASE + 7)
|
||||||
#define DL_STOP (DL_RQ_BASE + 8)
|
#define DL_STOP (DL_RQ_BASE + 8)
|
||||||
#define DL_GETSTAT (DL_RQ_BASE + 9)
|
#define DL_GETSTAT (DL_RQ_BASE + 9)
|
||||||
|
#define DL_GETNAME (DL_RQ_BASE +10)
|
||||||
|
|
||||||
/* Message type for data link layer replies. */
|
/* Message type for data link layer replies. */
|
||||||
#define DL_INIT_REPLY (DL_RS_BASE + 20)
|
#define DL_INIT_REPLY (DL_RS_BASE + 20)
|
||||||
#define DL_TASK_REPLY (DL_RS_BASE + 21)
|
#define DL_TASK_REPLY (DL_RS_BASE + 21)
|
||||||
|
#define DL_NAME_REPLY (DL_RS_BASE + 22)
|
||||||
|
|
||||||
/* Field names for data link layer messages. */
|
/* Field names for data link layer messages. */
|
||||||
#define DL_PORT m2_i1
|
#define DL_PORT m2_i1
|
||||||
|
@ -163,6 +165,7 @@
|
||||||
#define DL_CLCK m2_l2
|
#define DL_CLCK m2_l2
|
||||||
#define DL_ADDR m2_p1
|
#define DL_ADDR m2_p1
|
||||||
#define DL_STAT m2_l1
|
#define DL_STAT m2_l1
|
||||||
|
#define DL_NAME m3_ca1
|
||||||
|
|
||||||
/* Bits in 'DL_STAT' field of DL replies. */
|
/* Bits in 'DL_STAT' field of DL replies. */
|
||||||
# define DL_PACK_SEND 0x01
|
# define DL_PACK_SEND 0x01
|
||||||
|
|
|
@ -251,6 +251,12 @@ PUBLIC void main()
|
||||||
/* probably SIGTERM */
|
/* probably SIGTERM */
|
||||||
mq_free(mq);
|
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
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,6 +28,7 @@ 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_recvev, (event_t *ev, ev_arg_t ev_arg) );
|
||||||
FORWARD _PROTOTYPE( void eth_sendev, (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( 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 osdep_eth_init()
|
||||||
{
|
{
|
||||||
|
@ -344,6 +345,53 @@ message *m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
PUBLIC int eth_get_stat(eth_port, eth_stat)
|
||||||
eth_port_t *eth_port;
|
eth_port_t *eth_port;
|
||||||
eth_stat_t *eth_stat;
|
eth_stat_t *eth_stat;
|
||||||
|
@ -410,6 +458,7 @@ u32_t flags;
|
||||||
mess.DL_PORT= eth_port->etp_osdep.etp_port;
|
mess.DL_PORT= eth_port->etp_osdep.etp_port;
|
||||||
mess.DL_PROC= this_proc;
|
mess.DL_PROC= this_proc;
|
||||||
mess.DL_MODE= dl_flags;
|
mess.DL_MODE= dl_flags;
|
||||||
|
eth_port->etp_osdep.etp_dl_flags= dl_flags;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -683,6 +732,70 @@ message *m;
|
||||||
return loc_port;
|
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 $
|
* $PchId: mnx_eth.c,v 1.16 2005/06/28 14:24:37 philip Exp $
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -19,6 +19,7 @@ typedef struct osdep_eth_port
|
||||||
int etp_task;
|
int etp_task;
|
||||||
int etp_port;
|
int etp_port;
|
||||||
int etp_recvconf;
|
int etp_recvconf;
|
||||||
|
unsigned etp_dl_flags;
|
||||||
iovec_t etp_wr_iovec[IOVEC_NR];
|
iovec_t etp_wr_iovec[IOVEC_NR];
|
||||||
iovec_t etp_rd_iovec[RD_IOVEC];
|
iovec_t etp_rd_iovec[RD_IOVEC];
|
||||||
event_t etp_recvev;
|
event_t etp_recvev;
|
||||||
|
|
|
@ -13,6 +13,7 @@ _PROTOTYPE( void clck_tick, (message *mess) );
|
||||||
/* mnx_eth.c */
|
/* mnx_eth.c */
|
||||||
|
|
||||||
_PROTOTYPE( void eth_rec, (message *m) );
|
_PROTOTYPE( void eth_rec, (message *m) );
|
||||||
|
_PROTOTYPE( void eth_check_drivers, (message *m) );
|
||||||
|
|
||||||
/* sr.c */
|
/* sr.c */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue