]> Zhao Yanbai Git Server - minix.git/commitdiff
Prelim commit for ethernet driver crash recovery.
authorPhilip Homburg <philip@cs.vu.nl>
Fri, 21 Oct 2005 11:51:45 +0000 (11:51 +0000)
committerPhilip Homburg <philip@cs.vu.nl>
Fri, 21 Oct 2005 11:51:45 +0000 (11:51 +0000)
drivers/fxp/fxp.c
include/minix/com.h
servers/inet/inet.c
servers/inet/mnx_eth.c
servers/inet/osdep_eth.h
servers/inet/proto.h

index bd2ad67912c5985c4d5fb573c5f204b784202bcc..cea26046d14a6b15aae9227607c71495a531dc06 100644 (file)
@@ -201,6 +201,7 @@ static fxp_t fxp_table[FXP_PORT_NR];
 static int fxp_tasknr= ANY;
 static u16_t eth_ign_proto;
 static tmra_ut fxp_watchdog;
+static char *progname;
 
 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)    );
 _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)                  );
@@ -255,16 +257,20 @@ _PROTOTYPE( static void do_outl, (port_t port, u32_t v)                   );
 /*===========================================================================*
  *                             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);
@@ -277,6 +283,13 @@ int main(void)
                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)
@@ -292,6 +305,7 @@ int main(void)
                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++)
                        {
@@ -1571,6 +1585,23 @@ message *mp;
        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                                  *
  *===========================================================================*/
@@ -2417,7 +2448,7 @@ static void micro_delay(unsigned long usecs)
 static u8_t do_inb(port_t port)
 {
        int r;
-       u8_t value;
+       u32_t value;
 
        r= sys_inb(port, &value);
        if (r != OK)
index 41a37d38d09fe9bf742a92820900cdd297bd92a2..a56517426ff2e4da7c74f8af049482a9a89f130a 100755 (executable)
 #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
index 4c9f387626662a066728b73887e467a90544892b..9f650ba270daf4d1bcbe69308ddccb7e19c53c67 100644 (file)
@@ -242,15 +242,21 @@ PUBLIC void main()
 #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
                {
index 6466cb042bd9ee8fc27cf31e40eb05eff2c3714e..463c2ebf4e48cf51d6a7ab59abafb1a18b4002f5 100644 (file)
@@ -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_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()
 {
@@ -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)
 eth_port_t *eth_port;
 eth_stat_t *eth_stat;
@@ -410,6 +458,7 @@ u32_t flags;
        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
        {
@@ -683,6 +732,70 @@ message *m;
        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 $
  */
index f6742f85f691ab5382ec0d485436957f742882bd..a1304fe2b183a99c6a96c15cd1e8004b4c3bbc6e 100644 (file)
@@ -19,6 +19,7 @@ typedef struct osdep_eth_port
        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;
index be2977a784c426606d2a307a4f00f72de2afcded..cfbecca51e59344e46e9af43bdfb38e632706d18 100644 (file)
@@ -13,6 +13,7 @@ _PROTOTYPE( void clck_tick, (message *mess) );
 /* mnx_eth.c */
 
 _PROTOTYPE( void eth_rec, (message *m) );
+_PROTOTYPE( void eth_check_drivers, (message *m) );
 
 /* sr.c */