long netifread(struct netif *nif, struct chan *c, void *a, long n, uint32_t offset) { int i, j; struct netfile *f; char *p; if (c->qid.type & QTDIR) return devdirread(c, a, n, (struct dirtab *)nif, 0, netifgen); switch (NETTYPE(c->qid.path)) { case Ndataqid: f = nif->f[NETID(c->qid.path)]; return qread(f->in, a, n); case Nctlqid: return readnum(offset, a, n, NETID(c->qid.path), NUMSIZE); case Nstatqid: p = kzmalloc(READSTR, 0); if (p == NULL) return 0; j = snprintf(p, READSTR, "in: %d\n", nif->inpackets); j += snprintf(p + j, READSTR - j, "link: %d\n", nif->link); j += snprintf(p + j, READSTR - j, "out: %d\n", nif->outpackets); j += snprintf(p + j, READSTR - j, "crc errs: %d\n", nif->crcs); j += snprintf(p + j, READSTR - j, "overflows: %d\n", nif->overflows); j += snprintf(p + j, READSTR - j, "soft overflows: %d\n", nif->soverflows); j += snprintf(p + j, READSTR - j, "framing errs: %d\n", nif->frames); j += snprintf(p + j, READSTR - j, "buffer errs: %d\n", nif->buffs); j += snprintf(p + j, READSTR - j, "output errs: %d\n", nif->oerrs); j += snprintf(p + j, READSTR - j, "prom: %d\n", nif->prom); j += snprintf(p + j, READSTR - j, "mbps: %d\n", nif->mbps); j += snprintf(p + j, READSTR - j, "addr: "); for (i = 0; i < nif->alen; i++) j += snprintf(p + j, READSTR - j, "%02.2x", nif->addr[i]); snprintf(p + j, READSTR - j, "\n"); n = readstr(offset, a, n, p); kfree(p); return n; case Naddrqid: p = kzmalloc(READSTR, 0); if (p == NULL) return 0; j = 0; for (i = 0; i < nif->alen; i++) j += snprintf(p + j, READSTR - j, "%02.2x", nif->addr[i]); n = readstr(offset, a, n, p); kfree(p); return n; case Ntypeqid: f = nif->f[NETID(c->qid.path)]; return readnum(offset, a, n, f->type, NUMSIZE); case Nifstatqid: return 0; } error(Ebadarg); return -1; /* not reached */ }
static int uartstat(Chan *c, uchar *dp, int n) { if(NETTYPE(c->qid.path) == Ndataqid) setlength(NETID(c->qid.path)); return devstat(c, dp, n, uartdir, ndir, devgen); }
static long eiawrite(Chan *c, void *buf, long n, vlong offset) { ssize_t cnt; char cmd[Maxctl]; int port = NETID(c->qid.path); USED(offset); if(c->qid.type & QTDIR) error(Eperm); switch(NETTYPE(c->qid.path)) { case Ndataqid: osenter(); cnt = write(eia[port].fd, buf, n); osleave(); if(cnt == -1) oserror(); return cnt; case Nctlqid: if(n >= (long)sizeof(cmd)) n = sizeof(cmd)-1; memmove(cmd, buf, n); cmd[n] = 0; wrctl(port, cmd); return n; } return 0; }
static long eiaread(Chan *c, void *buf, long n, vlong offset) { DWORD cnt; int port = NETID(c->qid.path); BOOL good; if(c->qid.type & QTDIR) return devdirread(c, buf, n, eiadir, ndir, devgen); switch(NETTYPE(c->qid.path)) { case Ndataqid: cnt = 0; // if ReadFile timeouts and cnt==0 then just re-read // this will give osleave() a chance to detect an // interruption (i.e. killprog) while(cnt==0) { osenter(); good = ReadFile(eia[port].comfh, buf, n, &cnt, NULL); SleepEx(0,FALSE); //allow another thread access to port osleave(); if(!good) oserror(); } return cnt; case Nctlqid: return readnum(offset, buf, n, eia[port].id, NUMSIZE); case Nstatqid: return rdstat(port, buf, n, offset); } return 0; }
static long eiaread(Chan *c, void *buf, long n, vlong offset) { ssize_t cnt; int port = NETID(c->qid.path); if(c->qid.type & QTDIR) return devdirread(c, buf, n, eiadir, ndir, devgen); switch(NETTYPE(c->qid.path)) { case Ndataqid: osenter(); cnt = read(eia[port].fd, buf, n); osleave(); if(cnt == -1) oserror(); return cnt; case Nctlqid: return readnum(offset, buf, n, port, NUMSIZE); case Nstatqid: return rdstat(port, buf, n, offset); } return 0; }
static int pipegen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp) { int id, len; Qid qid; Pipe *p; USED(name); if(i == DEVDOTDOT){ devdir(c, c->qid, "#|", 0, eve, 0555, dp); return 1; } i++; /* skip . */ if(tab==0 || i>=ntab) return -1; tab += i; p = c->aux; switch(NETTYPE(tab->qid.path)){ case Qdata0: len = qlen(p->q[0]); break; case Qdata1: len = qlen(p->q[1]); break; default: len = tab->length; break; } id = NETID(c->qid.path); qid.path = NETQID(id, tab->qid.path); qid.vers = 0; qid.type = QTFILE; devdir(c, qid, tab->name, len, eve, tab->perm, dp); return 1; }
static long uartwrite(Chan *c, void *buf, long n, vlong offset) { Uart *p; char cmd[32]; USED(offset); if(c->qid.type & QTDIR) error(Eperm); p = uart[NETID(c->qid.path)]; switch(NETTYPE(c->qid.path)){ case Ndataqid: return qwrite(p->oq, buf, n); case Nctlqid: if(n >= sizeof(cmd)) n = sizeof(cmd)-1; memmove(cmd, buf, n); cmd[n] = 0; uartctl(p, cmd); return n; } }
static void uartclose(Chan *c) { Uart *p; if(c->qid.type & QTDIR) return; if((c->flag & COPEN) == 0) return; switch(NETTYPE(c->qid.path)){ case Ndataqid: case Nctlqid: p = uart[NETID(c->qid.path)]; qlock(p); if(--(p->opens) == 0){ qclose(p->iq); ilock(&p->rlock); p->ir = p->iw = p->istage; iunlock(&p->rlock); /* */ qhangup(p->oq, nil); if(!waserror()){ uartdrainoutput(p); poperror(); } qclose(p->oq); uartdisable(p); p->dcd = p->dsr = p->dohup = 0; } qunlock(p); break; } }
static int pipegen(Chan *c, char*, Dirtab *tab, int ntab, int i, Dir *dp) { Qid q; int len; Pipe *p; if(i == DEVDOTDOT){ devdir(c, c->qid, "#|", 0, eve, DMDIR|0555, dp); return 1; } i++; /* skip . */ if(tab==0 || i>=ntab) return -1; tab += i; p = c->aux; switch((ulong)tab->qid.path){ case Qdata0: len = qlen(p->q[0]); break; case Qdata1: len = qlen(p->q[1]); break; default: len = tab->length; break; } mkqid(&q, NETQID(NETID(c->qid.path), tab->qid.path), 0, QTFILE); devdir(c, q, tab->name, len, eve, p->perm, dp); return 1; }
int32_t netifwstat(Netif *nif, Chan *c, uint8_t *db, int32_t n) { Proc *up = externup(); Dir *dir; Netfile *f; int l; f = nif->f[NETID(c->qid.path)]; if(f == 0) error(Enonexist); if(netown(f, up->user, OWRITE) < 0) error(Eperm); dir = smalloc(sizeof(Dir)+n); l = convM2D(db, n, &dir[0], (char*)&dir[1]); if(l == 0){ free(dir); error(Eshortstat); } if(!emptystr(dir[0].uid)) strncpy(f->owner, dir[0].uid, KNAMELEN); if(dir[0].mode != (uint32_t)~0UL) f->mode = dir[0].mode; free(dir); return l; }
int netifwstat(struct ether *nif, struct chan *c, uint8_t * db, int n) { struct dir *dir; struct netfile *f; int m; f = nif->f[NETID(c->qid.path)]; if (f == 0) { set_errno(ENOENT); error(Enonexist); } if (netown(f, current->user, OWRITE) < 0) error(Eperm); dir = kzmalloc(sizeof(struct dir) + n, 0); m = convM2D(db, n, &dir[0], (char *)&dir[1]); if (m == 0) { kfree(dir); error(Eshortstat); } if (!emptystr(dir[0].uid)) strncpy(f->owner, dir[0].uid, KNAMELEN); if (dir[0].mode != ~0UL) f->mode = dir[0].mode; kfree(dir); return m; }
Block* netifbread(Netif *nif, Chan *c, long n, vlong offset) { Netfile *f; Block *bp; if((c->qid.type & QTDIR) || NETTYPE(c->qid.path) != Ndataqid) return devbread(c, n, offset); f = nif->f[NETID(c->qid.path)]; if(f->fat){ /* * Frame at a time (fat) allows us to provide * non-blocking performance with blocking semantics * for consumers that know ahead of time data is * contained within a single frame. Once empty, we * get in line with other blocking reads and wait our * turn. */ for(;;){ if(bp = qget(f->iq)) return bp; if(waserror()) return nil; qsleep(f->iq); poperror(); } } return qbread(f->iq, n); }
struct block *netifbread(struct ether *nif, struct chan *c, long n, uint32_t offset) { if ((c->qid.type & QTDIR) || NETTYPE(c->qid.path) != Ndataqid) return devbread(c, n, offset); return qbread(nif->f[NETID(c->qid.path)]->in, n); }
Block* netifbread(Netif *nif, Chan *c, long n, ulong offset) { if((c->qid.type & QTDIR) || NETTYPE(c->qid.path) != Ndataqid) return devbread(c, n, offset); return qbread(nif->f[NETID(c->qid.path)]->in, n); }
Block* netifbread(Netif *nif, Chan *c, int32_t n, int64_t offset) { if((c->qid.type & QTDIR) || NETTYPE(c->qid.path) != Ndataqid) return devbread(c, n, offset); return qbread(nif->f[NETID(c->qid.path)]->iq, n); }
void netifbypass(Netif *nif, Chan *c, void (*bypass)(void*, Block*), void *arg) { Netfile *f; f = nif->f[NETID(c->qid.path)]; qsetbypass(f->iq, bypass, arg); }
void netifclose(Netif *nif, Chan *c) { Netfile *f; int t; Netaddr *ap; if((c->flag & COPEN) == 0) return; t = NETTYPE(c->qid.path); if(t != Ndataqid && t != Nctlqid) return; f = nif->f[NETID(c->qid.path)]; qlock(&f->q); if(--(f->inuse) == 0){ if(f->prom){ qlock(&nif->q); if(--(nif->prom) == 0 && nif->promiscuous != nil) nif->promiscuous(nif->arg, 0); qunlock(&nif->q); f->prom = 0; } if(f->scan){ qlock(&nif->q); if(--(nif->_scan) == 0 && nif->scanbs != nil) nif->scanbs(nif->arg, 0); qunlock(&nif->q); f->prom = 0; f->scan = 0; } if(f->nmaddr){ qlock(&nif->q); t = 0; for(ap = nif->maddr; ap; ap = ap->next){ if(f->maddr[t/8] & (1<<(t%8))) netmulti(nif, f, ap->addr, 0); } qunlock(&nif->q); f->nmaddr = 0; } if(f->type < 0){ qlock(&nif->q); --(nif->all); qunlock(&nif->q); } f->owner[0] = 0; f->type = 0; f->bridge = 0; f->headersonly = 0; qclose(f->iq); } qunlock(&f->q); }
static long uartread(Chan *c, void *buf, long n, vlong offset) { Uart *p; if(c->qid.type & QTDIR){ setlength(-1); return devdirread(c, buf, n, uartdir, ndir, devgen); } p = uart[NETID(c->qid.path)]; switch(NETTYPE(c->qid.path)){ case Ndataqid: return qread(p->iq, buf, n); case Nctlqid: return readnum(offset, buf, n, NETID(c->qid.path), NUMSIZE); case Nstatqid: return uartstatus(c, p, buf, n, offset); } return 0; }
static Chan* eiaopen(Chan *c, int mode) { int port = NETID(c->qid.path); struct termios ts; int r; c = devopen(c, mode, eiadir, ndir, devgen); switch(NETTYPE(c->qid.path)) { case Nctlqid: case Ndataqid: case Nstatqid: if(incref(&eia[port].r) != 1) break; osenter(); eia[port].fd = open(sysdev[port], O_RDWR); osleave(); if(eia[port].fd < 0) oserror(); /* make port settings sane */ if(tcgetattr(eia[port].fd, &ts) < 0) oserror(); ts.c_iflag = ts.c_oflag = ts.c_lflag = 0; if(eia[port].restore) ts = eia[port].ts; else { cfsetispeed(&ts, B9600); cfsetospeed(&ts, B9600); ts.c_iflag |= IGNPAR; ts.c_cflag &= ~CSIZE; ts.c_cflag |= CS8|CREAD; ts.c_cflag &= ~(PARENB|PARODD); ts.c_cc[VMIN] = 1; ts.c_cc[VTIME] = 0; } osenter(); r = tcsetattr(eia[port].fd, TCSANOW, &ts); osleave(); if(r < 0) oserror(); if(eia[port].restore) resxtra(port, &ts); break; } return c; }
int eiawstat(Chan *c, uchar *dp, int n) { Dir d; int i; if(strcmp(up->env->user, eve) != 0) error(Eperm); if(c->qid.type & QTDIR) error(Eperm); n = convM2D(dp, n, &d, nil); i = Nqid*NETID(c->qid.path)+NETTYPE(c->qid.path)-Ndataqid; eiadir[i+1].perm = d.mode&0666; return n; }
static long uartwrite(Chan *c, void *buf, long n, vlong) { Uart *p; char *cmd; if(c->qid.type & QTDIR) error(Eperm); p = uart[NETID(c->qid.path)]; switch(NETTYPE(c->qid.path)){ case Ndataqid: qlock(p); if(waserror()){ qunlock(p); nexterror(); } n = qwrite(p->oq, buf, n); qunlock(p); poperror(); break; case Nctlqid: cmd = malloc(n+1); memmove(cmd, buf, n); cmd[n] = 0; qlock(p); if(waserror()){ qunlock(p); free(cmd); nexterror(); } /* let output drain */ if(uartctl(p, cmd) < 0) error(Ebadarg); qunlock(p); poperror(); free(cmd); break; } return n; }
static int eiawstat(Chan *c, uchar *dp, int n) { Dir d; int i; if(!iseve()) error(Eperm); if(c->qid.type & QTDIR) error(Eperm); if(NETTYPE(c->qid.path) == Nstatqid) error(Eperm); n = convM2D(dp, n, &d, nil); i = Nqid*NETID(c->qid.path)+NETTYPE(c->qid.path)-Ndataqid; if(d.mode != ~0UL) eiadir[i+1].perm = d.mode&0666; return n; }
Chan* netifopen(Netif *nif, Chan *c, int omode) { Proc *up = externup(); int id; Netfile *f; id = 0; if(c->qid.type & QTDIR){ if(omode != OREAD) error(Eperm); } else { switch(NETTYPE(c->qid.path)){ case Ndataqid: case Nctlqid: id = NETID(c->qid.path); openfile(nif, id); break; case Ncloneqid: id = openfile(nif, -1); c->qid.path = NETQID(id, Nctlqid); break; default: if(omode != OREAD) error(Ebadarg); } switch(NETTYPE(c->qid.path)){ case Ndataqid: case Nctlqid: f = nif->f[id]; if(netown(f, up->user, omode&7) < 0){ netifclose(nif, c); error(Eperm); } break; } } c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; c->iounit = qiomaxatomic; return c; }
static int uartwstat(Chan *c, uchar *dp, int n) { Dir d; Dirtab *dt; if(!iseve()) error(Eperm); if(QTDIR & c->qid.type) error(Eperm); if(NETTYPE(c->qid.path) == Nstatqid) error(Eperm); dt = &uartdir[1 + 3 * NETID(c->qid.path)]; n = convM2D(dp, n, &d, nil); if(n == 0) error(Eshortstat); if(d.mode != ~0UL) dt[0].perm = dt[1].perm = d.mode; return n; }
static void eiaclose(Chan *c) { int port = NETID(c->qid.path); if((c->flag & COPEN) == 0) return; switch(NETTYPE(c->qid.path)) { case Nctlqid: case Ndataqid: case Nstatqid: if(decref(&eia[port].r) == 0) { osenter(); CloseHandle(eia[port].comfh); osleave(); } break; } }
static long eiawrite(Chan *c, void *buf, long n, vlong offset) { DWORD cnt; char cmd[Maxctl]; int port = NETID(c->qid.path); BOOL good; uchar *data; if(c->qid.type & QTDIR) error(Eperm); switch(NETTYPE(c->qid.path)) { case Ndataqid: cnt = 0; data = (uchar*)buf; // if WriteFile times out (i.e. return true; cnt<n) then // allow osleave() to check for an interrupt otherwise try // to send the unsent data. while(n>0) { osenter(); good = WriteFile(eia[port].comfh, data, n, &cnt, NULL); osleave(); if(!good) oserror(); data += cnt; n -= cnt; } return (data-(uchar*)buf); case Nctlqid: if(n >= sizeof(cmd)) n = sizeof(cmd)-1; memmove(cmd, buf, n); cmd[n] = 0; wrctl(port, cmd); return n; } return 0; }
static int uartwstat(Chan *c, uchar *dp, int n) { error(Eperm); return 0; #ifdef xxx Dir d; Dirtab *dt; if(!iseve()) error(Eperm); if(c->qid.type & QTDIR) error(Eperm); if(NETTYPE(c->qid.path) == Nstatqid) error(Eperm); dt = &uartdir[3 * NETID(c->qid.path)]; convM2D(dp, &d); d.mode &= 0666; dt[0].perm = dt[1].perm = d.mode; #endif }
struct chan *netifopen(struct ether *nif, struct chan *c, int omode) { int id; struct netfile *f; id = 0; if (c->qid.type & QTDIR) { if (!IS_RDONLY(omode)) error(Eperm); } else { switch (NETTYPE(c->qid.path)) { case Ndataqid: case Nctlqid: id = NETID(c->qid.path); openfile(nif, id); break; case Ncloneqid: id = openfile(nif, -1); c->qid.path = NETQID(id, Nctlqid); break; default: if (!IS_RDONLY(omode)) error(Ebadarg); } switch (NETTYPE(c->qid.path)) { case Ndataqid: case Nctlqid: f = nif->f[id]; if (netown(f, current->user, omode & 7) < 0) error(Eperm); break; } } c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; c->iounit = qiomaxatomic; return c; }
static Chan* uartopen(Chan *c, int omode) { Uart *p; c = devopen(c, omode, uartdir, ndir, devgen); switch(NETTYPE(c->qid.path)){ case Nctlqid: case Ndataqid: p = uart[NETID(c->qid.path)]; qlock(p); if(p->opens++ == 0){ uartenable(p); qreopen(p->iq); qreopen(p->oq); } qunlock(p); break; } return c; }
static Chan* eiaopen(Chan *c, int mode) { int port = NETID(c->qid.path); c = devopen(c, mode, eiadir, ndir, devgen); switch(NETTYPE(c->qid.path)) { case Nctlqid: case Ndataqid: case Nstatqid: if(incref(&eia[port].r) != 1) break; if(waserror()) { decref(&eia[port].r); nexterror(); } openport(port); poperror(); break; } return c; }