2 #include "../port/lib.h"
6 #include "../port/error.h"
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);
15 typedef struct Netdevrock Netdevrock;
18 Fs *f; /* file system we belong to */
19 Proc *readp; /* reading process */
20 Chan *mchan; /* Data channel */
31 .unbind= netdevunbind,
32 .bwrite= netdevbwrite,
37 * called to bind an IP ifc to a generic network device
38 * called with ifc qlock'd
41 netdevbind(Ipifc *ifc, int argc, char **argv)
49 mchan = namec(argv[2], Aopen, ORDWR, 0);
51 er = smalloc(sizeof(*er));
53 er->f = ifc->conv->p->f;
57 kproc("netdevread", netdevread, ifc);
61 * called with ifc wlock'd
64 netdevunbind(Ipifc *ifc)
66 Netdevrock *er = ifc->arg;
69 postnote(er->readp, 1, "unbind", 0);
71 /* wait for readers to die */
72 while(er->readp != nil)
73 tsleep(&up->sleep, return0, 0, 300);
82 * called by ipoput with a single block to write
85 netdevbwrite(Ipifc *ifc, Block *bp, int, uchar*)
87 Netdevrock *er = ifc->arg;
89 if(BLEN(bp) < ifc->mintu)
90 bp = adjustblock(bp, ifc->mintu);
92 devtab[er->mchan->type]->bwrite(er->mchan, bp, 0);
97 * process to read from the device
109 er->readp = up; /* hide identity under a rock for unbind */
115 bp = devtab[er->mchan->type]->bread(er->mchan, ifc->maxtu, 0);
118 * get here if mchan is a pipe and other side hangs up
119 * clean up this interface & get out
120 ZZZ is this a good idea?
126 ifc->conv->p->ctl(ifc->conv, argv, 1);
141 ipiput4(er->f, ifc, bp);
148 netdevmediumlink(void)
150 addipmedium(&netdevmedium);