The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/drivers/dpeth/dp.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2 **  File:       eth.c   Version 1.00,   Jan. 14, 1997
    3 **
    4 **  Author:     Giovanni Falzoni <gfalzoni@inwind.it>
    5 **
    6 **  This file contains the ethernet device driver main task.
    7 **  It has to be integrated with the board specific drivers.
    8 **  It is a rewriting of Minix 2.0.0 ethernet driver (dp8390.c)
    9 **  to remove bord specific code. It should operate (I hope)
   10 **  with any board driver.
   11 **
   12 **  The valid messages and their parameters are:
   13 **
   14 **    m_type       DL_PORT   DL_PROC  DL_COUNT DL_MODE DL_ADDR
   15 **  +------------+---------+---------+--------+-------+---------+
   16 **  | HARD_INT   |         |         |        |       |         | 
   17 **  +------------+---------+---------+--------+-------+---------+
   18 **  | SYN_ALARM  |         |         |        |       |         | 
   19 **  +------------+---------+---------+--------+-------+---------+
   20 **  | HARD_STOP  |         |         |        |       |         | 
   21 **  +------------+---------+---------+--------+-------+---------+
   22 **  | FKEY_PRESSED         |         |        |       |         | (99)
   23 **  +------------+---------+---------+--------+-------+---------+
   24 **  | DL_WRITE   | port nr | proc nr | count  | mode  | address | (3)
   25 **  +------------+---------+---------+--------+-------+---------+
   26 **  | DL_WRITEV  | port nr | proc nr | count  | mode  | address | (4)
   27 **  +------------+---------+---------+--------+-------+---------+
   28 **  | DL_READ    | port nr | proc nr | count  |       | address | (5)
   29 **  +------------+---------+---------+--------+-------+---------+
   30 **  | DL_READV   | port nr | proc nr | count  |       | address | (6)
   31 **  +------------+---------+---------+--------+-------+---------+
   32 **  | DL_INIT    | port nr | proc nr |        | mode  | address | (7)
   33 **  +------------+---------+---------+--------+-------+---------+
   34 **  | DL_STOP    | port_nr |         |        |       |         | (8)
   35 **  +------------+---------+---------+--------+-------+---------+
   36 **  | DL_GETSTAT | port nr | proc nr |        |       | address | (9)
   37 **  +------------+---------+---------+--------+-------+---------+
   38 **
   39 **  The messages sent are:
   40 **
   41 **    m-type       DL_PORT   DL_PROC  DL_COUNT  DL_STAT   DL_CLCK
   42 **  +------------+---------+---------+--------+---------+---------+
   43 **  |DL_TASK_REPL| port nr | proc nr |rd-count| err|stat| clock   | (21)
   44 **  +------------+---------+---------+--------+---------+---------+
   45 **
   46 **    m_type       m3_i1     m3_i2      m3_ca1
   47 **  +------------+---------+---------+---------------+
   48 **  |DL_INIT_REPL| port nr |last port| ethernet addr | (20)
   49 **  +------------+---------+---------+---------------+
   50 **
   51 **  $Id: dp.c,v 1.11 2005/10/21 17:09:08 philip Exp $
   52 */
   53 
   54 #include "drivers.h"
   55 #include <minix/keymap.h>
   56 #include <net/hton.h>
   57 #include <net/gen/ether.h>
   58 #include <net/gen/eth_io.h>
   59 
   60 #include "dp.h"
   61 
   62 /*
   63 **  Local data
   64 */
   65 extern int errno;
   66 static dpeth_t de_table[DE_PORT_NR];
   67 static char *progname;
   68 
   69 typedef struct dp_conf {        /* Configuration description structure */
   70   port_t dpc_port;
   71   int dpc_irq;
   72   phys_bytes dpc_mem;
   73   char *dpc_envvar;
   74 } dp_conf_t;
   75 
   76 /* Device default configuration */
   77 static dp_conf_t dp_conf[DE_PORT_NR] = {
   78   /* I/O port, IRQ, Buff addr, Env. var, Buf. selector */
   79   {     0x300,   5,   0xC8000,  "DPETH0", },
   80   {     0x280,  10,   0xCC000,  "DPETH1", },
   81 };
   82 
   83 static const char CopyErrMsg[] = "unable to read/write user data";
   84 static const char PortErrMsg[] = "illegal port";
   85 static const char RecvErrMsg[] = "receive failed";
   86 static const char SendErrMsg[] = "send failed";
   87 static const char SizeErrMsg[] = "illegal packet size";
   88 static const char TypeErrMsg[] = "illegal message type";
   89 static const char DevName[] = "eth#?";
   90 
   91 static void do_getname(message *mp);
   92 
   93 /*
   94 **  Name:       void reply(dpeth_t *dep, int err)
   95 **  Function:   Fills a DL_TASK_REPLY reply message and sends it.
   96 */
   97 static void reply(dpeth_t * dep, int err)
   98 {
   99   message reply;
  100   int status = FALSE;
  101 
  102   if (dep->de_flags & DEF_ACK_SEND) status |= DL_PACK_SEND;
  103   if (dep->de_flags & DEF_ACK_RECV) status |= DL_PACK_RECV;
  104 
  105   reply.m_type = DL_TASK_REPLY;
  106   reply.DL_PORT = dep - de_table;
  107   reply.DL_PROC = dep->de_client;
  108   reply.DL_STAT = status /* | ((u32_t) err << 16) */;
  109   reply.DL_COUNT = dep->de_read_s;
  110   getuptime(&reply.DL_CLCK);
  111 
  112   DEBUG(printf("\t reply %d (%ld)\n", reply.m_type, reply.DL_STAT));
  113 
  114   if ((status = send(dep->de_client, &reply)) == OK) {
  115         dep->de_read_s = 0;
  116         dep->de_flags &= NOT(DEF_ACK_SEND | DEF_ACK_RECV);
  117 
  118   } else if (status != ELOCKED || err == OK)
  119         panic(dep->de_name, SendErrMsg, status);
  120 
  121   return;
  122 }
  123 
  124 /*
  125 **  Name:       void dp_confaddr(dpeth_t *dep)
  126 **  Function:   Checks environment for a User defined ethernet address.
  127 */
  128 static void dp_confaddr(dpeth_t * dep)
  129 {
  130   static char ea_fmt[] = "x:x:x:x:x:x";
  131   char ea_key[16];
  132   int ix;
  133   long val;
  134 
  135   strcpy(ea_key, dp_conf[dep - de_table].dpc_envvar);
  136   strcat(ea_key, "_EA");
  137 
  138   for (ix = 0; ix < SA_ADDR_LEN; ix++) {
  139         val = dep->de_address.ea_addr[ix];
  140         if (env_parse(ea_key, ea_fmt, ix, &val, 0x00L, 0xFFL) != EP_SET)
  141                 break;
  142         dep->de_address.ea_addr[ix] = val;
  143   }
  144 
  145   if (ix != 0 && ix != SA_ADDR_LEN)
  146         /* It's all or nothing, force a panic */
  147         env_parse(ea_key, "?", 0, &val, 0L, 0L);
  148   return;
  149 }
  150 
  151 /*
  152 **  Name:       void update_conf(dpeth_t *dep, dp_conf_t *dcp)
  153 **  Function:   Gets the default settings from 'dp_conf' table and
  154 **              modifies them from the environment.
  155 */
  156 static void update_conf(dpeth_t * dep, dp_conf_t * dcp)
  157 {
  158   static char dpc_fmt[] = "x:d:x";
  159   long val;
  160 
  161   dep->de_mode = DEM_SINK;
  162   val = dcp->dpc_port;          /* Get I/O port address */
  163   switch (env_parse(dcp->dpc_envvar, dpc_fmt, 0, &val, 0x000L, 0x3FFL)) {
  164       case EP_OFF:      dep->de_mode = DEM_DISABLED;    break;
  165       case EP_ON:
  166       case EP_SET:      dep->de_mode = DEM_ENABLED;     break;
  167   }
  168   dep->de_base_port = val;
  169 
  170   val = dcp->dpc_irq | DEI_DEFAULT;     /* Get Interrupt line (IRQ) */
  171   env_parse(dcp->dpc_envvar, dpc_fmt, 1, &val, 0L, (long) NR_IRQ_VECTORS - 1);
  172   dep->de_irq = val;
  173 
  174   val = dcp->dpc_mem;           /* Get shared memory address */
  175   env_parse(dcp->dpc_envvar, dpc_fmt, 2, &val, 0L, LONG_MAX);
  176   dep->de_linmem = val;
  177 
  178   return;
  179 }
  180 
  181 /*
  182 **  Name:       void do_dump(message *mp)
  183 **  Function:   Displays statistics on screen (SFx key from console)
  184 */
  185 static void do_dump(message *mp)
  186 {
  187   dpeth_t *dep;
  188   int port;
  189 
  190   printf("\n\n");
  191   for (port = 0, dep = de_table; port < DE_PORT_NR; port += 1, dep += 1) {
  192 
  193         if (dep->de_mode == DEM_DISABLED) continue;
  194 
  195         printf("%s statistics:\t\t", dep->de_name);
  196 
  197         /* Network interface status  */
  198         printf("Status: 0x%04x (%d)\n\n", dep->de_flags, dep->de_int_pending);
  199 
  200         (*dep->de_dumpstatsf) (dep);
  201 
  202         /* Transmitted/received bytes */
  203         printf("Tx bytes:%10ld\t", dep->bytes_Tx);
  204         printf("Rx bytes:%10ld\n", dep->bytes_Rx);
  205 
  206         /* Transmitted/received packets */
  207         printf("Tx OK:     %8ld\t", dep->de_stat.ets_packetT);
  208         printf("Rx OK:     %8ld\n", dep->de_stat.ets_packetR);
  209 
  210         /* Transmit/receive errors */
  211         printf("Tx Err:    %8ld\t", dep->de_stat.ets_sendErr);
  212         printf("Rx Err:    %8ld\n", dep->de_stat.ets_recvErr);
  213 
  214         /* Transmit unnerruns/receive overrruns */
  215         printf("Tx Und:    %8ld\t", dep->de_stat.ets_fifoUnder);
  216         printf("Rx Ovr:    %8ld\n", dep->de_stat.ets_fifoOver);
  217 
  218         /* Transmit collisions/receive CRC errors */
  219         printf("Tx Coll:   %8ld\t", dep->de_stat.ets_collision);
  220         printf("Rx CRC:    %8ld\n", dep->de_stat.ets_CRCerr);
  221   }
  222   return;
  223 }
  224 
  225 /*
  226 **  Name:       void get_userdata(int user_proc, vir_bytes user_addr, int count, void *loc_addr)
  227 **  Function:   Copies data from user area.
  228 */
  229 static void get_userdata(int user_proc, vir_bytes user_addr, int count, void *loc_addr)
  230 {
  231   int rc;
  232   vir_bytes len;
  233 
  234   len = (count > IOVEC_NR ? IOVEC_NR : count) * sizeof(iovec_t);
  235   if ((rc = sys_datacopy(user_proc, user_addr, SELF, (vir_bytes)loc_addr, len)) != OK)
  236         panic(DevName, CopyErrMsg, rc);
  237   return;
  238 }
  239 
  240 /*
  241 **  Name:       void do_first_init(dpeth_t *dep, dp_conf_t *dcp);
  242 **  Function:   Init action to setup task
  243 */
  244 static void do_first_init(dpeth_t *dep, dp_conf_t *dcp)
  245 {
  246 
  247   if (dep->de_linmem != 0) {
  248         dep->de_memsegm = BIOS_SEG;
  249         /* phys2seg(&dep->de_memsegm, &dep->de_memoffs, dep->de_linmem); */
  250   } else
  251         dep->de_linmem = 0xFFFF0000;
  252 
  253   /* Make sure statisics are cleared */
  254   memset((void *) &(dep->de_stat), 0, sizeof(eth_stat_t));
  255 
  256   /* Device specific initialization */
  257   (*dep->de_initf) (dep);
  258 
  259   /* Set the interrupt handler policy. Request interrupts not to be reenabled
  260    * automatically. Return the IRQ line number when an interrupt occurs.
  261    */
  262   dep->de_hook = dep->de_irq;
  263   sys_irqsetpolicy(dep->de_irq, 0 /*IRQ_REENABLE*/, &dep->de_hook);
  264   dep->de_int_pending = FALSE;
  265   sys_irqenable(&dep->de_hook);
  266 
  267   return;
  268 }
  269 
  270 /*
  271 **  Name:       void do_init(message *mp)
  272 **  Function:   Checks for hardware presence.
  273 **              Provides initialization of hardware and data structures
  274 */
  275 static void do_init(message * mp)
  276 {
  277   int port;
  278   dpeth_t *dep;
  279   dp_conf_t *dcp;
  280   message reply_mess;
  281 
  282   port = mp->DL_PORT;
  283   if (port >= 0 && port < DE_PORT_NR) {
  284 
  285         dep = &de_table[port];
  286         dcp = &dp_conf[port];
  287         strcpy(dep->de_name, DevName);
  288         dep->de_name[4] = '' + port;
  289 
  290         if (dep->de_mode == DEM_DISABLED) {
  291 
  292                 update_conf(dep, dcp);  /* First time thru */
  293                 if (dep->de_mode == DEM_ENABLED &&
  294                     !el1_probe(dep) &&  /* Probe for 3c501  */
  295                     !wdeth_probe(dep) &&        /* Probe for WD80x3 */
  296                     !ne_probe(dep) &&   /* Probe for NEx000 */
  297                     !el2_probe(dep) &&  /* Probe for 3c503  */
  298                     !el3_probe(dep)) {  /* Probe for 3c509  */
  299                         printf("%s: warning no ethernet card found at 0x%04X\n",
  300                                dep->de_name, dep->de_base_port);
  301                         dep->de_mode = DEM_DISABLED;
  302                 }
  303         }
  304 
  305         /* 'de_mode' may change if probe routines fail, test again */
  306         switch (dep->de_mode) {
  307 
  308             case DEM_DISABLED:
  309                 /* Device is configured OFF or hardware probe failed */
  310                 port = ENXIO;
  311                 break;
  312 
  313             case DEM_ENABLED:
  314                 /* Device is present and probed */
  315                 if (dep->de_flags == DEF_EMPTY) {
  316                         /* These actions only the first time */
  317                         do_first_init(dep, dcp);
  318                         dep->de_flags |= DEF_ENABLED;
  319                 }
  320                 dep->de_flags &= NOT(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
  321                 if (mp->DL_MODE & DL_PROMISC_REQ)
  322                         dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
  323                 if (mp->DL_MODE & DL_MULTI_REQ) dep->de_flags |= DEF_MULTI;
  324                 if (mp->DL_MODE & DL_BROAD_REQ) dep->de_flags |= DEF_BROAD;
  325                 (*dep->de_flagsf) (dep);
  326                 dep->de_client = mp->m_source;
  327                 break;
  328 
  329             case DEM_SINK:
  330                 /* Device not present (sink mode) */
  331                 memset(dep->de_address.ea_addr, 0, sizeof(ether_addr_t));
  332                 dp_confaddr(dep);       /* Station address from env. */
  333                 break;
  334 
  335             default:    break;
  336         }
  337         *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
  338 
  339   } else                        /* Port number is out of range */
  340         port = ENXIO;
  341 
  342   reply_mess.m_type = DL_INIT_REPLY;
  343   reply_mess.m3_i1 = port;
  344   reply_mess.m3_i2 = DE_PORT_NR;
  345   DEBUG(printf("\t reply %d\n", reply_mess.m_type));
  346   if (send(mp->m_source, &reply_mess) != OK)    /* Can't send */
  347         panic(dep->de_name, SendErrMsg, mp->m_source);
  348 
  349   return;
  350 }
  351 
  352 /*
  353 **  Name:       void dp_next_iovec(iovec_dat_t *iovp)
  354 **  Function:   Retrieves data from next iovec element.
  355 */
  356 PUBLIC void dp_next_iovec(iovec_dat_t * iovp)
  357 {
  358 
  359   iovp->iod_iovec_s -= IOVEC_NR;
  360   iovp->iod_iovec_addr += IOVEC_NR * sizeof(iovec_t);
  361   get_userdata(iovp->iod_proc_nr, iovp->iod_iovec_addr,
  362              iovp->iod_iovec_s, iovp->iod_iovec);
  363   return;
  364 }
  365 
  366 /*
  367 **  Name:       int calc_iovec_size(iovec_dat_t *iovp)
  368 **  Function:   Compute the size of a request.
  369 */
  370 static int calc_iovec_size(iovec_dat_t * iovp)
  371 {
  372   int size, ix;
  373 
  374   size = ix = 0;
  375   do {
  376         size += iovp->iod_iovec[ix].iov_size;
  377         if (++ix >= IOVEC_NR) {
  378                 dp_next_iovec(iovp);
  379                 ix = 0;
  380         }
  381 
  382         /* Till all vectors added */
  383   } while (ix < iovp->iod_iovec_s);
  384   return size;
  385 }
  386 
  387 /*
  388 **  Name:       void do_vwrite(message *mp, int vectored)
  389 **  Function:
  390 */
  391 static void do_vwrite(message * mp, int vectored)
  392 {
  393   int port, size;
  394   dpeth_t *dep;
  395 
  396   port = mp->DL_PORT;
  397   if (port < 0 || port >= DE_PORT_NR)   /* Check for illegal port number */
  398         panic(dep->de_name, PortErrMsg, port);
  399 
  400   dep = &de_table[port];
  401   dep->de_client = mp->DL_PROC;
  402 
  403   if (dep->de_mode == DEM_ENABLED) {
  404 
  405         if (dep->de_flags & DEF_SENDING)        /* Is sending in progress? */
  406                 panic(dep->de_name, "send already in progress ", NO_NUM);
  407 
  408         dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
  409         if (vectored) {
  410                 get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
  411                        mp->DL_COUNT, dep->de_write_iovec.iod_iovec);
  412                 dep->de_write_iovec.iod_iovec_s = mp->DL_COUNT;
  413                 dep->de_write_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
  414                 size = calc_iovec_size(&dep->de_write_iovec);
  415         } else {
  416                 dep->de_write_iovec.iod_iovec[0].iov_addr = (vir_bytes) mp->DL_ADDR;
  417                 dep->de_write_iovec.iod_iovec[0].iov_size = size = mp->DL_COUNT;
  418                 dep->de_write_iovec.iod_iovec_s = 1;
  419                 dep->de_write_iovec.iod_iovec_addr = 0;
  420         }
  421         if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE)
  422                 panic(dep->de_name, SizeErrMsg, size);
  423 
  424         dep->de_flags |= DEF_SENDING;
  425         (*dep->de_sendf) (dep, FALSE, size);
  426 
  427   } else if (dep->de_mode == DEM_SINK)
  428         dep->de_flags |= DEF_ACK_SEND;
  429 
  430   reply(dep, OK);
  431   return;
  432 }
  433 
  434 /*
  435 **  Name:       void do_vread(message *mp, int vectored)
  436 **  Function:
  437 */
  438 static void do_vread(message * mp, int vectored)
  439 {
  440   int port, size;
  441   dpeth_t *dep;
  442 
  443   port = mp->DL_PORT;
  444   if (port < 0 || port >= DE_PORT_NR)   /* Check for illegal port number */
  445         panic(dep->de_name, PortErrMsg, port);
  446 
  447   dep = &de_table[port];
  448   dep->de_client = mp->DL_PROC;
  449 
  450   if (dep->de_mode == DEM_ENABLED) {
  451 
  452         if (dep->de_flags & DEF_READING)        /* Reading in progress */
  453                 panic(dep->de_name, "read already in progress", NO_NUM);
  454 
  455         dep->de_read_iovec.iod_proc_nr = mp->DL_PROC;
  456         if (vectored) {
  457                 get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
  458                         mp->DL_COUNT, dep->de_read_iovec.iod_iovec);
  459                 dep->de_read_iovec.iod_iovec_s = mp->DL_COUNT;
  460                 dep->de_read_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
  461                 size = calc_iovec_size(&dep->de_read_iovec);
  462         } else {
  463                 dep->de_read_iovec.iod_iovec[0].iov_addr = (vir_bytes) mp->DL_ADDR;
  464                 dep->de_read_iovec.iod_iovec[0].iov_size = size = mp->DL_COUNT;
  465                 dep->de_read_iovec.iod_iovec_s = 1;
  466                 dep->de_read_iovec.iod_iovec_addr = 0;
  467         }
  468         if (size < ETH_MAX_PACK_SIZE) panic(dep->de_name, SizeErrMsg, size);
  469 
  470         dep->de_flags |= DEF_READING;
  471         (*dep->de_recvf) (dep, FALSE, size);
  472 #if 0
  473         if ((dep->de_flags & (DEF_READING | DEF_STOPPED)) == (DEF_READING | DEF_STOPPED))
  474                 /* The chip is stopped, and all arrived packets delivered */
  475                 (*dep->de_resetf) (dep);
  476         dep->de_flags &= NOT(DEF_STOPPED);
  477 #endif
  478   }
  479   reply(dep, OK);
  480   return;
  481 }
  482 
  483 /*
  484 **  Name:       void do_getstat(message *mp)
  485 **  Function:   Reports device statistics.
  486 */
  487 static void do_getstat(message * mp)
  488 {
  489   int port, rc;
  490   dpeth_t *dep;
  491 
  492   port = mp->DL_PORT;
  493   if (port < 0 || port >= DE_PORT_NR)   /* Check for illegal port number */
  494         panic(dep->de_name, PortErrMsg, port);
  495 
  496   dep = &de_table[port];
  497   dep->de_client = mp->DL_PROC;
  498 
  499   if (dep->de_mode == DEM_ENABLED) (*dep->de_getstatsf) (dep);
  500   if ((rc = sys_datacopy(SELF, (vir_bytes)&dep->de_stat,
  501                          mp->DL_PROC, (vir_bytes)mp->DL_ADDR,
  502                          (vir_bytes) sizeof(dep->de_stat))) != OK)
  503         panic(DevName, CopyErrMsg, rc);
  504   reply(dep, OK);
  505   return;
  506 }
  507 
  508 static void do_getname(mp)
  509 message *mp;
  510 {
  511         int r;
  512 
  513         strncpy(mp->DL_NAME, progname, sizeof(mp->DL_NAME));
  514         mp->DL_NAME[sizeof(mp->DL_NAME)-1]= '\0';
  515         mp->m_type= DL_NAME_REPLY;
  516         r= send(mp->m_source, mp);
  517         if (r != OK)
  518                 panic("dpeth", "do_getname: send failed: %d\n", r);
  519 }
  520 
  521 /*
  522 **  Name:       void do_stop(message *mp)
  523 **  Function:   Stops network interface.
  524 */
  525 static void do_stop(message * mp)
  526 {
  527   int port;
  528   dpeth_t *dep;
  529 
  530   port = mp->DL_PORT;
  531   if (port < 0 || port >= DE_PORT_NR)   /* Check for illegal port number */
  532         panic(dep->de_name, PortErrMsg, port);
  533 
  534   dep = &de_table[port];
  535   if (dep->de_mode == DEM_ENABLED && (dep->de_flags & DEF_ENABLED)) {
  536 
  537         /* Stop device */
  538         (dep->de_stopf) (dep);
  539         dep->de_flags = DEF_EMPTY;
  540         dep->de_mode = DEM_DISABLED;
  541   }
  542   return;
  543 }
  544 
  545 static void do_watchdog(void *message)
  546 {
  547 
  548   DEBUG(printf("\t no reply"));
  549   return;
  550 }
  551 
  552 /*
  553 **  Name:       int dpeth_task(void)
  554 **  Function:   Main entry for dp task
  555 */
  556 PUBLIC int main(int argc, char **argv)
  557 {
  558   message m;
  559   dpeth_t *dep;
  560   int rc, fkeys, sfkeys, tasknr;
  561 
  562   (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
  563 
  564   env_setargs(argc, argv);
  565 
  566   /* Request function key for debug dumps */
  567   fkeys = sfkeys = 0; bit_set(sfkeys, 8);
  568   if ((fkey_map(&fkeys, &sfkeys)) != OK) 
  569         printf("%s: couldn't program Shift+F8 key (%d)\n", DevName, errno);
  570 
  571 #ifdef ETH_IGN_PROTO
  572   {
  573         static u16_t eth_ign_proto = 0;
  574         long val;
  575         val = 0xFFFF;
  576         env_parse("ETH_IGN_PROTO", "x", 0, &val, 0x0000L, 0xFFFFL);
  577         eth_ign_proto = htons((u16_t) val);
  578   }
  579 #endif
  580 
  581   /* Try to notify inet that we are present (again) */
  582   rc = findproc("inet", &tasknr);
  583   if (rc == OK)
  584         notify(tasknr);
  585 
  586   while (TRUE) {
  587         if ((rc = receive(ANY, &m)) != OK) panic(dep->de_name, RecvErrMsg, rc);
  588 
  589         DEBUG(printf("eth: got message %d, ", m.m_type));
  590 
  591         switch (m.m_type) {
  592             case DEV_PING:      /* Status request from RS */
  593                 notify(m.m_source);
  594                 continue;
  595             case DL_WRITE:      /* Write message to device */
  596                 do_vwrite(&m, FALSE);
  597                 break;
  598             case DL_WRITEV:     /* Write message to device */
  599                 do_vwrite(&m, TRUE);
  600                 break;
  601             case DL_READ:       /* Read message from device */
  602                 do_vread(&m, FALSE);
  603                 break;
  604             case DL_READV:      /* Read message from device */
  605                 do_vread(&m, TRUE);
  606                 break;
  607             case DL_INIT:       /* Initialize device */
  608                 do_init(&m);
  609                 break;
  610             case DL_GETSTAT:    /* Get device statistics */
  611                 do_getstat(&m);
  612                 break;
  613             case DL_GETNAME:
  614                 do_getname(&m);
  615                 break;
  616             case SYN_ALARM:     /* to be defined */
  617                 do_watchdog(&m);
  618                 break;
  619             case DL_STOP:       /* Stop device */
  620                 do_stop(&m);
  621                 break;
  622             case SYS_SIG: {
  623                 sigset_t sigset = m.NOTIFY_ARG;
  624                 if (sigismember(&sigset, SIGKSTOP)) {   /* Shut down */
  625                     for (rc = 0; rc < DE_PORT_NR; rc += 1) {
  626                         if (de_table[rc].de_mode == DEM_ENABLED) {
  627                                 m.m_type = DL_STOP;
  628                                 m.DL_PORT = rc;
  629                                 do_stop(&m);
  630                         }
  631                     }
  632                 }
  633                 break;
  634             }
  635             case HARD_INT:      /* Interrupt from device */
  636                 for (dep = de_table; dep < &de_table[DE_PORT_NR]; dep += 1) {
  637                         /* If device is enabled and interrupt pending */
  638                         if (dep->de_mode == DEM_ENABLED) {
  639                                 dep->de_int_pending = TRUE;
  640                                 (*dep->de_interruptf) (dep);
  641                                 if (dep->de_flags & (DEF_ACK_SEND | DEF_ACK_RECV))
  642                                         reply(dep, !OK);
  643                                 dep->de_int_pending = FALSE;
  644                                 sys_irqenable(&dep->de_hook);
  645                         }
  646                 }
  647                 break;
  648             case FKEY_PRESSED:  /* Function key pressed */
  649                 do_dump(&m);
  650                 break;
  651             default:            /* Invalid message type */
  652                 panic(DevName, TypeErrMsg, m.m_type);
  653                 break;
  654         }
  655   }
  656   return OK;                    /* Never reached, but keeps compiler happy */
  657 }
  658 
  659 /** dp.c **/

Cache object: 77b91efbfca22239020e6a4baa00cef2


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.