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/ip/netdevmedium.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 #include "u.h"
    2 #include "../port/lib.h"
    3 #include "mem.h"
    4 #include "dat.h"
    5 #include "fns.h"
    6 #include "../port/error.h"
    7 
    8 #include "ip.h"
    9 
   10 static void     netdevbind(Ipifc *ifc, int argc, char **argv);
   11 static void     netdevunbind(Ipifc *ifc);
   12 static void     netdevbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip);
   13 static void     netdevread(void *a);
   14 
   15 typedef struct  Netdevrock Netdevrock;
   16 struct Netdevrock
   17 {
   18         Fs      *f;             /* file system we belong to */
   19         Proc    *readp;         /* reading process */
   20         Chan    *mchan;         /* Data channel */
   21 };
   22 
   23 Medium netdevmedium =
   24 {
   25 .name=          "netdev",
   26 .hsize=         0,
   27 .mintu= 0,
   28 .maxtu= 64000,
   29 .maclen=        0,
   30 .bind=          netdevbind,
   31 .unbind=        netdevunbind,
   32 .bwrite=        netdevbwrite,
   33 .unbindonclose= 0,
   34 };
   35 
   36 /*
   37  *  called to bind an IP ifc to a generic network device
   38  *  called with ifc qlock'd
   39  */
   40 static void
   41 netdevbind(Ipifc *ifc, int argc, char **argv)
   42 {
   43         Chan *mchan;
   44         Netdevrock *er;
   45 
   46         if(argc < 2)
   47                 error(Ebadarg);
   48 
   49         mchan = namec(argv[2], Aopen, ORDWR, 0);
   50 
   51         er = smalloc(sizeof(*er));
   52         er->mchan = mchan;
   53         er->f = ifc->conv->p->f;
   54 
   55         ifc->arg = er;
   56 
   57         kproc("netdevread", netdevread, ifc);
   58 }
   59 
   60 /*
   61  *  called with ifc wlock'd
   62  */
   63 static void
   64 netdevunbind(Ipifc *ifc)
   65 {
   66         Netdevrock *er = ifc->arg;
   67 
   68         if(er->readp != nil)
   69                 postnote(er->readp, 1, "unbind", 0);
   70 
   71         /* wait for readers to die */
   72         while(er->readp != nil)
   73                 tsleep(&up->sleep, return0, 0, 300);
   74 
   75         if(er->mchan != nil)
   76                 cclose(er->mchan);
   77 
   78         free(er);
   79 }
   80 
   81 /*
   82  *  called by ipoput with a single block to write
   83  */
   84 static void
   85 netdevbwrite(Ipifc *ifc, Block *bp, int, uchar*)
   86 {
   87         Netdevrock *er = ifc->arg;
   88 
   89         if(bp->next)
   90                 bp = concatblock(bp);
   91         if(BLEN(bp) < ifc->mintu)
   92                 bp = adjustblock(bp, ifc->mintu);
   93 
   94         devtab[er->mchan->type]->bwrite(er->mchan, bp, 0);
   95         ifc->out++;
   96 }
   97 
   98 /*
   99  *  process to read from the device
  100  */
  101 static void
  102 netdevread(void *a)
  103 {
  104         Ipifc *ifc;
  105         Block *bp;
  106         Netdevrock *er;
  107         char *argv[1];
  108 
  109         ifc = a;
  110         er = ifc->arg;
  111         er->readp = up; /* hide identity under a rock for unbind */
  112         if(waserror()){
  113                 er->readp = nil;
  114                 pexit("hangup", 1);
  115         }
  116         for(;;){
  117                 bp = devtab[er->mchan->type]->bread(er->mchan, ifc->maxtu, 0);
  118                 if(bp == nil){
  119                         /*
  120                          * get here if mchan is a pipe and other side hangs up
  121                          * clean up this interface & get out
  122 ZZZ is this a good idea?
  123                          */
  124                         poperror();
  125                         er->readp = nil;
  126                         argv[0] = "unbind";
  127                         if(!waserror())
  128                                 ifc->conv->p->ctl(ifc->conv, argv, 1);
  129                         pexit("hangup", 1);
  130                 }
  131                 if(!canrlock(ifc)){
  132                         freeb(bp);
  133                         continue;
  134                 }
  135                 if(waserror()){
  136                         runlock(ifc);
  137                         nexterror();
  138                 }
  139                 ifc->in++;
  140                 if(ifc->lifc == nil)
  141                         freeb(bp);
  142                 else
  143                         ipiput4(er->f, ifc, bp);
  144                 runlock(ifc);
  145                 poperror();
  146         }
  147 }
  148 
  149 void
  150 netdevmediumlink(void)
  151 {
  152         addipmedium(&netdevmedium);
  153 }

Cache object: 59a0ad7531a0f4b2019881604928e639


[ 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.