| //#define DEBUG |
| #include <vfs.h> |
| #include <kfs.h> |
| #include <slab.h> |
| #include <kmalloc.h> |
| #include <kref.h> |
| #include <string.h> |
| #include <stdio.h> |
| #include <assert.h> |
| #include <error.h> |
| #include <cpio.h> |
| #include <pmap.h> |
| #include <smp.h> |
| |
| enum { |
| Qdir = 0, |
| Qctl = 1, |
| Qmalloc, |
| Qmax, |
| }; |
| |
| static struct dirtab regressdir[Qmax] = { |
| {".", {Qdir, 0, QTDIR}, 0, 0555,}, |
| {"regressctl", {Qctl, 0}, 0, 0666,}, |
| {"malloc", {Qmalloc, 0}, 0, 0666,}, |
| }; |
| |
| int verbose = 0; |
| |
| static struct chan *regressattach(char *spec) |
| { |
| return devattach('Z', spec); |
| } |
| |
| struct walkqid *regresswalk(struct chan *c, struct chan *nc, char **name, |
| int nname) |
| { |
| return devwalk(c, nc, name, nname, regressdir, Qmax, devgen); |
| } |
| |
| static long |
| regressstat(struct chan *c, uint8_t * dp, long n) |
| { |
| return devstat(c, dp, n, regressdir, Qmax, devgen); |
| } |
| |
| static struct chan *regressopen(struct chan *c, int omode) |
| { |
| return devopen(c, omode, regressdir, Qmax, devgen); |
| } |
| |
| static void regressclose(struct chan *c) |
| { |
| } |
| |
| static long |
| regressread(struct chan *c, void *a, long n, int64_t offset) |
| { |
| char *buf, *p; |
| static char ctl[128]; |
| printd("regressread %d\n", (uint32_t) c->qid.path); |
| |
| switch ((uint32_t) c->qid.path) { |
| |
| case Qdir: |
| return devdirread(c, a, n, regressdir, Qmax, devgen); |
| |
| case Qmalloc: |
| { |
| char *usage = "malloc size-in-meg"; |
| n = readstr(offset, a, sizeof(usage), usage); |
| break; |
| } |
| |
| case Qctl: |
| snprintf(ctl, sizeof(ctl), "verbosity %d", verbose); |
| n = MIN(strlen(ctl), n); |
| n = readstr(offset, a, sizeof(ctl), ctl); |
| break; |
| |
| default: |
| error(Eperm); |
| break; |
| } |
| |
| return n; |
| } |
| |
| static long |
| regresswrite(struct chan *c, void *a, long n, int64_t offset) |
| { |
| char *p; |
| unsigned long amt; |
| |
| switch ((uint32_t) c->qid.path) { |
| |
| case Qmalloc: |
| return n; |
| |
| case Qctl: |
| p = a; |
| if (*p == 'v') { |
| if (verbose) |
| verbose--; |
| } else if (*p == 'V') |
| verbose++; |
| else |
| error("Only v or V"); |
| printd("Regression verbosity now %d\n", verbose); |
| return n; |
| |
| default: |
| printd("devreg eperm\n"); |
| error(Eperm); |
| break; |
| } |
| return 0; |
| } |
| |
| struct dev regressdevtab = { |
| 'Z', |
| "regress", |
| |
| devreset, |
| devinit, |
| devshutdown, |
| regressattach, |
| regresswalk, |
| regressstat, |
| regressopen, |
| devcreate, |
| regressclose, |
| regressread, |
| devbread, |
| regresswrite, |
| devbwrite, |
| devremove, |
| devwstat, |
| devpower, |
| devconfig, |
| devchaninfo, |
| }; |