Do not abort/panic when an ethernet driver does something unexpected.
This commit is contained in:
parent
0ac9521c94
commit
66f9a5f508
3 changed files with 114 additions and 28 deletions
|
@ -258,10 +258,15 @@ PUBLIC void main()
|
|||
mq_free(mq);
|
||||
}
|
||||
#endif
|
||||
else if (mq->mq_mess.m_type == DL_TASK_REPLY)
|
||||
{
|
||||
eth_rec(&mq->mq_mess);
|
||||
mq_free(mq);
|
||||
}
|
||||
else
|
||||
{
|
||||
compare(mq->mq_mess.m_type, ==, DL_TASK_REPLY);
|
||||
eth_rec(&mq->mq_mess);
|
||||
printf("inet: got bad message type 0x%x from %d\n",
|
||||
mq->mq_mess.m_type, mq->mq_mess.m_source);
|
||||
mq_free(mq);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,6 +108,7 @@ PUBLIC void osdep_eth_init()
|
|||
|
||||
eth_port->etp_osdep.etp_port= ecp->ec_port;
|
||||
eth_port->etp_osdep.etp_task= tasknr;
|
||||
eth_port->etp_osdep.etp_send_ev= 0;
|
||||
ev_init(ð_port->etp_osdep.etp_recvev);
|
||||
|
||||
mess.m_type= DL_CONF;
|
||||
|
@ -335,6 +336,8 @@ acc_t *pack;
|
|||
assert(loc_port != eth_port);
|
||||
loc_port->etp_osdep.etp_sendrepl= block_msg;
|
||||
ev_arg.ev_ptr= loc_port;
|
||||
assert(!loc_port->etp_osdep.etp_send_ev);
|
||||
loc_port->etp_osdep.etp_send_ev= 1;
|
||||
ev_enqueue(&loc_port->etp_sendev, eth_sendev, ev_arg);
|
||||
}
|
||||
if (block_msg.DL_STAT & DL_PACK_RECV)
|
||||
|
@ -359,6 +362,17 @@ acc_t *pack;
|
|||
return;
|
||||
}
|
||||
|
||||
if (mess1.m_type != DL_TASK_REPLY ||
|
||||
mess1.DL_PORT != eth_port->etp_osdep.etp_port ||
|
||||
mess1.DL_PROC != this_proc)
|
||||
{
|
||||
printf(
|
||||
"eth_write_port: ignoring bad message (type = 0x%x, port = %d, proc = %d) from %d\n",
|
||||
mess1.m_type, mess1.DL_PORT, mess1.DL_PROC,
|
||||
mess1.m_source);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(mess1.m_type == DL_TASK_REPLY &&
|
||||
mess1.DL_PORT == eth_port->etp_osdep.etp_port &&
|
||||
mess1.DL_PROC == this_proc);
|
||||
|
@ -392,6 +406,8 @@ acc_t *pack;
|
|||
{
|
||||
eth_port->etp_osdep.etp_sendrepl= mess1;
|
||||
ev_arg.ev_ptr= eth_port;
|
||||
assert(!eth_port->etp_osdep.etp_send_ev);
|
||||
eth_port->etp_osdep.etp_send_ev= 1;
|
||||
ev_enqueue(ð_port->etp_sendev, eth_sendev, ev_arg);
|
||||
|
||||
/* Pretend that we didn't get a reply. */
|
||||
|
@ -428,7 +444,8 @@ message *m;
|
|||
|
||||
stat= m->DL_STAT & 0xffff;
|
||||
|
||||
assert(stat & (DL_PACK_SEND|DL_PACK_RECV));
|
||||
if (!(stat & (DL_PACK_SEND|DL_PACK_RECV)))
|
||||
printf("eth_rec: neither DL_PACK_SEND nor DL_PACK_RECV\n");
|
||||
if (stat & DL_PACK_SEND)
|
||||
write_int(loc_port);
|
||||
if (stat & DL_PACK_RECV)
|
||||
|
@ -615,6 +632,14 @@ eth_port_t *eth_port;
|
|||
u8_t *eth_dst_ptr;
|
||||
|
||||
pack= eth_port->etp_wr_pack;
|
||||
if (pack == NULL)
|
||||
{
|
||||
printf("write_int: strange no packet on eth port %d\n",
|
||||
eth_port-eth_port_table);
|
||||
eth_restart_write(eth_port);
|
||||
return;
|
||||
}
|
||||
|
||||
eth_port->etp_wr_pack= NULL;
|
||||
|
||||
eth_dst_ptr= (u8_t *)ptr2acc_data(pack);
|
||||
|
@ -642,14 +667,29 @@ int count;
|
|||
pack= eth_port->etp_rd_pack;
|
||||
eth_port->etp_rd_pack= NULL;
|
||||
|
||||
cut_pack= bf_cut(pack, 0, count);
|
||||
bf_afree(pack);
|
||||
if (count < ETH_MIN_PACK_SIZE)
|
||||
{
|
||||
printf("mnx_eth`read_int: packet size too small (%d)\n",
|
||||
count);
|
||||
bf_afree(pack);
|
||||
}
|
||||
else if (count > ETH_MAX_PACK_SIZE_TAGGED)
|
||||
{
|
||||
printf("mnx_eth`read_int: packet size too big (%d)\n",
|
||||
count);
|
||||
bf_afree(pack);
|
||||
}
|
||||
else
|
||||
{
|
||||
cut_pack= bf_cut(pack, 0, count);
|
||||
bf_afree(pack);
|
||||
|
||||
assert(!no_ethWritePort);
|
||||
no_ethWritePort= 1;
|
||||
eth_arrive(eth_port, cut_pack, count);
|
||||
assert(no_ethWritePort);
|
||||
no_ethWritePort= 0;
|
||||
assert(!no_ethWritePort);
|
||||
no_ethWritePort= 1;
|
||||
eth_arrive(eth_port, cut_pack, count);
|
||||
assert(no_ethWritePort);
|
||||
no_ethWritePort= 0;
|
||||
}
|
||||
|
||||
eth_port->etp_flags &= ~(EPF_READ_IP|EPF_READ_SP);
|
||||
setup_read(eth_port);
|
||||
|
@ -738,10 +778,13 @@ eth_port_t *eth_port;
|
|||
(DL_PACK_SEND|DL_PACK_RECV));
|
||||
if (block_msg.DL_STAT & DL_PACK_SEND)
|
||||
{
|
||||
loc_port->etp_osdep.etp_sendrepl= block_msg;
|
||||
loc_port->etp_osdep.etp_sendrepl=
|
||||
block_msg;
|
||||
ev_arg.ev_ptr= loc_port;
|
||||
ev_enqueue(&loc_port->etp_sendev, eth_sendev,
|
||||
ev_arg);
|
||||
assert(!loc_port->etp_osdep.etp_send_ev);
|
||||
loc_port->etp_osdep.etp_send_ev= 1;
|
||||
ev_enqueue(&loc_port->etp_sendev,
|
||||
eth_sendev, ev_arg);
|
||||
}
|
||||
if (block_msg.DL_STAT & DL_PACK_RECV)
|
||||
{
|
||||
|
@ -768,10 +811,23 @@ eth_port_t *eth_port;
|
|||
continue;
|
||||
}
|
||||
|
||||
assert (mess1.m_type == DL_TASK_REPLY &&
|
||||
mess1.DL_PORT == mess1.DL_PORT &&
|
||||
mess1.DL_PROC == this_proc);
|
||||
compare((mess1.DL_STAT >> 16), ==, OK);
|
||||
if (mess1.m_type != DL_TASK_REPLY ||
|
||||
mess1.DL_PORT != eth_port->etp_osdep.etp_port ||
|
||||
mess1.DL_PROC != this_proc)
|
||||
{
|
||||
printf("mnx_eth`setup_read: bad type, port or proc\n");
|
||||
printf("got type %d, port %d, proc %d\n",
|
||||
mess1.m_type, mess1.DL_PORT, mess1.DL_PROC);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((mess1.DL_STAT >> 16) != OK)
|
||||
{
|
||||
printf(
|
||||
"mnx_eth`setup_read: bad value in DL_STAT: 0x%x\n",
|
||||
mess1.DL_STAT);
|
||||
mess1.DL_STAT= 0;
|
||||
}
|
||||
|
||||
if (mess1.DL_STAT & DL_PACK_RECV)
|
||||
{
|
||||
|
@ -781,15 +837,26 @@ eth_port_t *eth_port;
|
|||
"setup_read(mess1): eth%d: got DL_PACK_RECV\n",
|
||||
mess1.DL_PORT);
|
||||
}
|
||||
/* packet received */
|
||||
pack_ptr= bf_cut(pack, 0, mess1.DL_COUNT);
|
||||
bf_afree(pack);
|
||||
|
||||
assert(!no_ethWritePort);
|
||||
no_ethWritePort= 1;
|
||||
eth_arrive(eth_port, pack_ptr, mess1.DL_COUNT);
|
||||
assert(no_ethWritePort);
|
||||
no_ethWritePort= 0;
|
||||
if (mess1.DL_COUNT < ETH_MIN_PACK_SIZE)
|
||||
{
|
||||
printf(
|
||||
"mnx_eth`setup_read: packet size too small (%d)\n",
|
||||
mess1.DL_COUNT);
|
||||
bf_afree(pack);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* packet received */
|
||||
pack_ptr= bf_cut(pack, 0, mess1.DL_COUNT);
|
||||
bf_afree(pack);
|
||||
|
||||
assert(!no_ethWritePort);
|
||||
no_ethWritePort= 1;
|
||||
eth_arrive(eth_port, pack_ptr, mess1.DL_COUNT);
|
||||
assert(no_ethWritePort);
|
||||
no_ethWritePort= 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -800,9 +867,20 @@ eth_port_t *eth_port;
|
|||
|
||||
if (mess1.DL_STAT & DL_PACK_SEND)
|
||||
{
|
||||
eth_port->etp_osdep.etp_sendrepl= mess1;
|
||||
ev_arg.ev_ptr= eth_port;
|
||||
ev_enqueue(ð_port->etp_sendev, eth_sendev, ev_arg);
|
||||
if (eth_port->etp_osdep.etp_send_ev)
|
||||
{
|
||||
printf(
|
||||
"mnx_eth`setup_read: etp_send_ev is set, ignoring DL_PACK_SEND\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
eth_port->etp_osdep.etp_sendrepl= mess1;
|
||||
ev_arg.ev_ptr= eth_port;
|
||||
assert(!eth_port->etp_osdep.etp_send_ev);
|
||||
eth_port->etp_osdep.etp_send_ev= 1;
|
||||
ev_enqueue(ð_port->etp_sendev, eth_sendev,
|
||||
ev_arg);
|
||||
}
|
||||
}
|
||||
} while (!(eth_port->etp_flags & EPF_READ_IP));
|
||||
eth_port->etp_flags |= EPF_READ_SP;
|
||||
|
@ -851,6 +929,8 @@ ev_arg_t ev_arg;
|
|||
|
||||
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);
|
||||
|
|
|
@ -19,6 +19,7 @@ typedef struct osdep_eth_port
|
|||
int 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];
|
||||
|
|
Loading…
Reference in a new issue