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);
|
mq_free(mq);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
else if (mq->mq_mess.m_type == DL_TASK_REPLY)
|
||||||
|
{
|
||||||
|
eth_rec(&mq->mq_mess);
|
||||||
|
mq_free(mq);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
compare(mq->mq_mess.m_type, ==, DL_TASK_REPLY);
|
printf("inet: got bad message type 0x%x from %d\n",
|
||||||
eth_rec(&mq->mq_mess);
|
mq->mq_mess.m_type, mq->mq_mess.m_source);
|
||||||
mq_free(mq);
|
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_port= ecp->ec_port;
|
||||||
eth_port->etp_osdep.etp_task= tasknr;
|
eth_port->etp_osdep.etp_task= tasknr;
|
||||||
|
eth_port->etp_osdep.etp_send_ev= 0;
|
||||||
ev_init(ð_port->etp_osdep.etp_recvev);
|
ev_init(ð_port->etp_osdep.etp_recvev);
|
||||||
|
|
||||||
mess.m_type= DL_CONF;
|
mess.m_type= DL_CONF;
|
||||||
|
@ -335,6 +336,8 @@ acc_t *pack;
|
||||||
assert(loc_port != eth_port);
|
assert(loc_port != eth_port);
|
||||||
loc_port->etp_osdep.etp_sendrepl= block_msg;
|
loc_port->etp_osdep.etp_sendrepl= block_msg;
|
||||||
ev_arg.ev_ptr= loc_port;
|
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);
|
ev_enqueue(&loc_port->etp_sendev, eth_sendev, ev_arg);
|
||||||
}
|
}
|
||||||
if (block_msg.DL_STAT & DL_PACK_RECV)
|
if (block_msg.DL_STAT & DL_PACK_RECV)
|
||||||
|
@ -359,6 +362,17 @@ acc_t *pack;
|
||||||
return;
|
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 &&
|
assert(mess1.m_type == DL_TASK_REPLY &&
|
||||||
mess1.DL_PORT == eth_port->etp_osdep.etp_port &&
|
mess1.DL_PORT == eth_port->etp_osdep.etp_port &&
|
||||||
mess1.DL_PROC == this_proc);
|
mess1.DL_PROC == this_proc);
|
||||||
|
@ -392,6 +406,8 @@ acc_t *pack;
|
||||||
{
|
{
|
||||||
eth_port->etp_osdep.etp_sendrepl= mess1;
|
eth_port->etp_osdep.etp_sendrepl= mess1;
|
||||||
ev_arg.ev_ptr= eth_port;
|
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);
|
ev_enqueue(ð_port->etp_sendev, eth_sendev, ev_arg);
|
||||||
|
|
||||||
/* Pretend that we didn't get a reply. */
|
/* Pretend that we didn't get a reply. */
|
||||||
|
@ -428,7 +444,8 @@ message *m;
|
||||||
|
|
||||||
stat= m->DL_STAT & 0xffff;
|
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)
|
if (stat & DL_PACK_SEND)
|
||||||
write_int(loc_port);
|
write_int(loc_port);
|
||||||
if (stat & DL_PACK_RECV)
|
if (stat & DL_PACK_RECV)
|
||||||
|
@ -615,6 +632,14 @@ eth_port_t *eth_port;
|
||||||
u8_t *eth_dst_ptr;
|
u8_t *eth_dst_ptr;
|
||||||
|
|
||||||
pack= eth_port->etp_wr_pack;
|
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_port->etp_wr_pack= NULL;
|
||||||
|
|
||||||
eth_dst_ptr= (u8_t *)ptr2acc_data(pack);
|
eth_dst_ptr= (u8_t *)ptr2acc_data(pack);
|
||||||
|
@ -642,6 +667,20 @@ int count;
|
||||||
pack= eth_port->etp_rd_pack;
|
pack= eth_port->etp_rd_pack;
|
||||||
eth_port->etp_rd_pack= NULL;
|
eth_port->etp_rd_pack= NULL;
|
||||||
|
|
||||||
|
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);
|
cut_pack= bf_cut(pack, 0, count);
|
||||||
bf_afree(pack);
|
bf_afree(pack);
|
||||||
|
|
||||||
|
@ -650,6 +689,7 @@ int count;
|
||||||
eth_arrive(eth_port, cut_pack, count);
|
eth_arrive(eth_port, cut_pack, count);
|
||||||
assert(no_ethWritePort);
|
assert(no_ethWritePort);
|
||||||
no_ethWritePort= 0;
|
no_ethWritePort= 0;
|
||||||
|
}
|
||||||
|
|
||||||
eth_port->etp_flags &= ~(EPF_READ_IP|EPF_READ_SP);
|
eth_port->etp_flags &= ~(EPF_READ_IP|EPF_READ_SP);
|
||||||
setup_read(eth_port);
|
setup_read(eth_port);
|
||||||
|
@ -738,10 +778,13 @@ eth_port_t *eth_port;
|
||||||
(DL_PACK_SEND|DL_PACK_RECV));
|
(DL_PACK_SEND|DL_PACK_RECV));
|
||||||
if (block_msg.DL_STAT & DL_PACK_SEND)
|
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_arg.ev_ptr= loc_port;
|
||||||
ev_enqueue(&loc_port->etp_sendev, eth_sendev,
|
assert(!loc_port->etp_osdep.etp_send_ev);
|
||||||
ev_arg);
|
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)
|
if (block_msg.DL_STAT & DL_PACK_RECV)
|
||||||
{
|
{
|
||||||
|
@ -768,10 +811,23 @@ eth_port_t *eth_port;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert (mess1.m_type == DL_TASK_REPLY &&
|
if (mess1.m_type != DL_TASK_REPLY ||
|
||||||
mess1.DL_PORT == mess1.DL_PORT &&
|
mess1.DL_PORT != eth_port->etp_osdep.etp_port ||
|
||||||
mess1.DL_PROC == this_proc);
|
mess1.DL_PROC != this_proc)
|
||||||
compare((mess1.DL_STAT >> 16), ==, OK);
|
{
|
||||||
|
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)
|
if (mess1.DL_STAT & DL_PACK_RECV)
|
||||||
{
|
{
|
||||||
|
@ -781,6 +837,16 @@ eth_port_t *eth_port;
|
||||||
"setup_read(mess1): eth%d: got DL_PACK_RECV\n",
|
"setup_read(mess1): eth%d: got DL_PACK_RECV\n",
|
||||||
mess1.DL_PORT);
|
mess1.DL_PORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 */
|
/* packet received */
|
||||||
pack_ptr= bf_cut(pack, 0, mess1.DL_COUNT);
|
pack_ptr= bf_cut(pack, 0, mess1.DL_COUNT);
|
||||||
bf_afree(pack);
|
bf_afree(pack);
|
||||||
|
@ -791,6 +857,7 @@ eth_port_t *eth_port;
|
||||||
assert(no_ethWritePort);
|
assert(no_ethWritePort);
|
||||||
no_ethWritePort= 0;
|
no_ethWritePort= 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* no packet received */
|
/* no packet received */
|
||||||
|
@ -799,10 +866,21 @@ eth_port_t *eth_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mess1.DL_STAT & DL_PACK_SEND)
|
if (mess1.DL_STAT & DL_PACK_SEND)
|
||||||
|
{
|
||||||
|
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;
|
eth_port->etp_osdep.etp_sendrepl= mess1;
|
||||||
ev_arg.ev_ptr= eth_port;
|
ev_arg.ev_ptr= eth_port;
|
||||||
ev_enqueue(ð_port->etp_sendev, eth_sendev, ev_arg);
|
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));
|
} while (!(eth_port->etp_flags & EPF_READ_IP));
|
||||||
eth_port->etp_flags |= EPF_READ_SP;
|
eth_port->etp_flags |= EPF_READ_SP;
|
||||||
|
@ -851,6 +929,8 @@ ev_arg_t ev_arg;
|
||||||
|
|
||||||
assert(m_ptr->DL_STAT & DL_PACK_SEND);
|
assert(m_ptr->DL_STAT & DL_PACK_SEND);
|
||||||
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 */
|
/* packet is sent */
|
||||||
write_int(eth_port);
|
write_int(eth_port);
|
||||||
|
|
|
@ -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;
|
||||||
|
int etp_send_ev;
|
||||||
iovec_s_t etp_wr_iovec[IOVEC_NR];
|
iovec_s_t etp_wr_iovec[IOVEC_NR];
|
||||||
cp_grant_id_t etp_wr_vec_grant;
|
cp_grant_id_t etp_wr_vec_grant;
|
||||||
iovec_s_t etp_rd_iovec[RD_IOVEC];
|
iovec_s_t etp_rd_iovec[RD_IOVEC];
|
||||||
|
|
Loading…
Reference in a new issue