]> git.lizzy.rs Git - plan9front.git/commitdiff
usbd: added event file, removed usbdb
authoraiju <aiju@phicode.de>
Thu, 28 Jul 2011 15:31:45 +0000 (17:31 +0200)
committeraiju <aiju@phicode.de>
Thu, 28 Jul 2011 15:31:45 +0000 (17:31 +0200)
sys/src/cmd/nusb/usbd/dat.h
sys/src/cmd/nusb/usbd/fns.h
sys/src/cmd/nusb/usbd/mkfile
sys/src/cmd/nusb/usbd/rules.c [deleted file]
sys/src/cmd/nusb/usbd/usbd.c

index d87b25c622c2bef137b29806c792e4232a292373..e67ff6dc586d2ca794857fd6cf881d333af341c9 100644 (file)
@@ -1,24 +1,7 @@
-typedef struct Rule Rule;
-typedef struct Cond Cond;
 typedef struct Hub Hub;
 typedef struct DHub DHub;
 typedef struct Port Port;
 
-struct Rule {
-       char **argv;
-       int argc;
-       Cond *cond;
-       Rule *next;
-} *rulefirst, *rulelast;
-
-RWLock rulelock;
-
-struct Cond {
-       int field;
-       u32int value;
-       Cond *and, *or;
-};
-
 enum
 {
        Stack   = 32*1024,
index 3879ae8bc98bd4d0a48dca44f8bf4bfa0ec48fc3..7f016536f4807e22aa749f016b3fc87946337b80 100644 (file)
@@ -1,4 +1,2 @@
-void   parserules(char*);
-Rule*  rulesmatch(Usbdev*);
 int    startdev(Port*);
 void   work(void);
index b0b3c5050713e6b583af8d91ec73c7f871069306..4e8beeb6acdd1ceb0660047f0f231b9a7798db5e 100644 (file)
@@ -2,7 +2,6 @@
 
 OFILES=\
        usbd.$O\
-       rules.$O\
        hub.$O\
 
 HFILES=\
diff --git a/sys/src/cmd/nusb/usbd/rules.c b/sys/src/cmd/nusb/usbd/rules.c
deleted file mode 100644 (file)
index eae988f..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include <ctype.h>
-#include "usb.h"
-#include "dat.h"
-#include "fns.h"
-
-static char *pos;
-static int lineno;
-
-static void
-skipempty(void)
-{
-       char *s;
-
-       for(;;){
-               s = pos;
-               if(*s == 0)
-                       return;
-               while(*s != '\n' && isspace(*s))
-                       s++;
-               if(*s == '#')
-                       while(*s != 0 && *s != '\n')
-                               s++;
-               if(*s != 0 && *s != '\n')
-                       return;
-               pos = s;
-               if(*pos != 0){
-                       pos++;
-                       lineno++;
-               }
-       }
-}
-
-static void
-parsesh(int *argc, char ***argv)
-{
-       char *e;
-
-       *argc = 0;
-       *argv = nil;
-       for(;;){
-               while(isspace(*pos) && *pos != '\n')
-                       pos++;
-               if(*pos == '\n' || *pos == 0 || *pos == '#')
-                       break;
-               e = pos;
-               while(*e != 0 && *e != '#' && !isspace(*e))
-                       e++;
-               (*argc)++;
-               *argv = realloc(*argv, (*argc + 2) * sizeof(char *));
-               if(*argv == nil)
-                       sysfatal("realloc: %r");
-               (*argv)[*argc - 1] = mallocz(e - pos + 1, 1);
-               if((*argv)[*argc - 1] == nil)
-                       sysfatal("malloc: %r");
-               memmove((*argv)[*argc - 1], pos, e - pos);
-               pos = e;
-       }
-       if(*argv != nil){
-               (*argv)[*argc] = nil;
-               (*argv)[*argc + 1] = nil;
-       }
-}
-
-static Usbdev dummy;
-
-struct field {
-       char *s;
-       void* v;
-} fields[] = {
-       "class", &dummy.class,
-       "vid", &dummy.vid,
-       "did", &dummy.did,
-       "csp", &dummy.csp,
-       nil, nil,
-};
-
-static int
-parsecond(Rule *r, Cond **last)
-{
-       Cond *c, *cc, **l;
-       char *e;
-       struct field *f;
-
-       skipempty();
-       if(!isspace(*pos))
-               return 0;
-       l = nil;
-       for(;;){
-               while(isspace(*pos) && *pos != '\n')
-                       pos++;
-               if(*pos == '\n' || *pos == '#')
-                       return 1;
-               e = pos;
-               while(*e != 0 && *e != '\n' && *e != '=')
-                       e++;
-               if(*e != '=')
-                       return -1;
-               c = mallocz(sizeof(*c), 1);
-               if(c == nil)
-                       sysfatal("malloc: %r");
-               for(f = fields; f->s != nil; f++)
-                       if(strlen(f->s) == e - pos && strncmp(pos, f->s, e - pos) == 0){
-                               c->field = (int)((char*)f->v - (char*)&dummy);
-                               break;
-                       }
-               if(f->s == nil)
-                       goto Error;
-               pos = e + 1;
-               c->value = strtol(pos, &e, 0);
-               if(pos == e)
-                       goto Error;
-               pos = e;
-               if(l != nil)
-                       *l = c;
-               else if(*last){
-                       for(cc = *last; cc != nil; cc = cc->and)
-                               cc->or = c;
-                       *last = c;
-               }else
-                       *last = r->cond = c;
-               l = &c->and;
-       }
-Error:
-       free(c);
-       return -1;
-}
-
-static int
-parserule(void)
-{
-       Rule *r;
-       int rc;
-       Cond *c;
-       
-       skipempty();
-       if(*pos == 0)
-               return 0;
-       if(isspace(*pos))
-               return -1;
-       r = mallocz(sizeof(*r), 1);
-       if(r == nil)
-               sysfatal("malloc: %r");
-       parsesh(&r->argc, &r->argv);
-       c = nil;
-       do
-               rc = parsecond(r, &c);
-       while(rc > 0);
-       if(rc < 0)
-               return -1;
-       if(rulefirst != nil)
-               rulelast->next = r;
-       else
-               rulefirst = r;
-       rulelast = r;
-       return 1;
-}
-
-static void
-freerules(void)
-{
-       Rule *r, *rr;
-       Cond *c, *cc;
-       
-       wlock(&rulelock);
-       for(r = rulefirst; r != nil; r = rr){
-               for(c = r->cond; c != nil; c = cc){
-                       cc = c->and;
-                       if(cc == nil)
-                               cc = c->or;
-                       free(c);
-               }
-               rr = r->next;
-               free(r);
-       }
-       rulefirst = rulelast = nil;
-       wunlock(&rulelock);
-}
-
-static void
-printrules(void)
-{
-       Rule *r;
-       Cond *c;
-       int i;
-
-       for(r = rulefirst; r != nil; r = r->next){
-               for(i = 0; i < r->argc; i++)
-                       print("[%s] ", r->argv[i]);
-               print("\n\t");
-               for(c = r->cond; c != nil; ){
-                       print("%d=%ud", c->field, c->value);
-                       if(c->and == nil){
-                               print("\n\t");
-                               c = c->or;
-                       }else{
-                               print(" ");
-                               c = c->and;
-                       }
-               }
-               print("\n");
-       }
-}
-
-void
-parserules(char *s)
-{
-       int rc;
-
-       freerules();
-       lineno = 1;
-       pos = s;
-       do
-               rc = parserule();
-       while(rc > 0);
-       if(rc < 0)
-               sysfatal("syntax error in line %d", lineno);
-}
-
-Rule *
-rulesmatch(Usbdev *dev)
-{
-       Rule *r;
-       Cond *c;
-
-       for(r = rulefirst; r != nil; r = r->next){
-               c = r->cond;
-               while(c){
-                       if(*(u32int*)((char*)dev + c->field) == c->value){
-                               if(c->and == nil)
-                                       goto yes;
-                               c = c->and;
-                       }else
-                               c = c->or;
-               }
-       }
-yes:
-       return r;
-}
index ee5ed20753a3254a2a25b02e9e962b59af214d7c..81aedcdb359894b25f9787bdb129358627cfe492 100644 (file)
 #include "dat.h"
 #include "fns.h"
 
-char *luser;
-char *rules;
+enum {
+       Qroot,
+       Qusbevent,
+       Qmax
+};
+
+char *names[] = {
+       "",
+       "usbevent",
+};
 
-static File *usbdb;
 static char Enonexist[] = "does not exist";
 
+typedef struct Event Event;
+
+struct Event {
+       char *data;
+       int len;
+       Event *link;
+       int ref;
+};
+
+static Event *evfirst, *evlast;
+static Req *reqfirst, *reqlast;
+static QLock evlock;
+
+static void
+addreader(Req *req)
+{
+       req->aux = nil;
+       if(reqfirst == nil)
+               reqfirst = req;
+       else
+               reqlast->aux = req;
+       reqlast = req;
+}
+
+static void
+fulfill(Req *req, Event *e)
+{
+       int n;
+       
+       n = e->len;
+       if(n > req->ifcall.count)
+               n = req->ifcall.count;
+       memmove(req->ofcall.data, e->data, n);
+       req->ofcall.count = n;
+}
+
+static void
+initevent(void)
+{
+       evfirst = mallocz(sizeof(*evfirst), 1);
+       if(evfirst == nil)
+               sysfatal("malloc: %r");
+       evlast = evfirst;
+}
+
+static void
+readevent(Req *req)
+{
+       Event *e;
+
+       qlock(&evlock);
+       e = req->fid->aux;
+       if(e == evlast){
+               addreader(req);
+               qunlock(&evlock);
+               return;
+       }
+       fulfill(req, e);
+       req->fid->aux = e->link;
+       e->link->ref++;
+       if(--e->ref == 0 && e == evfirst){
+               evfirst = e->link;
+               free(e->data);
+               free(e);
+       }
+       qunlock(&evlock);
+       respond(req, nil);
+}
+
+static void
+pushevent(char *data)
+{
+       Event *e, *ee;
+       Req *r, *rr;
+       
+       qlock(&evlock);
+       e = evlast;
+       ee = emallocz(sizeof(Event), 1);
+       if(ee == nil)
+               sysfatal("malloc: %r");
+       evlast = ee;
+       e->data = data;
+       e->len = strlen(data);
+       e->link = ee;
+       for(r = reqfirst; r != nil; r = rr){
+               rr = r->aux;
+               r->aux = nil;
+               r->fid->aux = ee;
+               ee->ref++;
+               e->ref--;
+               fulfill(r, e);
+               respond(r, nil);
+       }
+       if(e->ref == 0 && e == evfirst){
+               evfirst = ee;
+               free(e->data);
+               free(e);
+       }
+       reqfirst = nil;
+       reqlast = nil;
+       qunlock(&evlock);
+}
+
+static int
+dirgen(int n, Dir *d, void *)
+{
+       if(n >= Qmax - 1)
+               return -1;
+       d->qid.path = n + 1;
+       d->qid.vers = 0;
+       if(n >= 0)
+               d->qid.type = 0;
+       else
+               d->qid.type = QTDIR;
+       d->uid = strdup(getuser());
+       d->gid = strdup(d->uid);
+       d->muid = strdup(d->uid);
+       d->name = strdup(names[n+1]);
+       d->mode = 0555 | (d->qid.type << 24);
+       d->atime = d->mtime = time(0);
+       d->length = 0;
+       return 0;
+}
+
+static void
+usbdattach(Req *req)
+{
+       req->fid->qid = (Qid) {Qroot, 0, QTDIR};
+       req->ofcall.qid = req->fid->qid;
+       respond(req, nil);
+}
+
+static char *
+usbdwalk(Fid *fid, char *name, Qid *qid)
+{
+       int i;
+
+       if(strcmp(name, "..") == 0){
+               fid->qid = (Qid) {Qroot, 0, QTDIR};
+               *qid = fid->qid;
+               return nil;
+       }
+       if(fid->qid.path != Qroot)
+               return "not a directory";
+       for(i = 0; i < Qmax; i++)
+               if(strcmp(name, names[i]) == 0){
+                       fid->qid = (Qid) {i, 0, 0};
+                       *qid = fid->qid;
+                       return nil;
+               }
+       return "does not exist";
+}
+
 static void
 usbdread(Req *req)
 {
-       if(usbdb->qid.path == req->fid->qid.path){
-               readstr(req, rules);
+       switch((long)req->fid->qid.path){
+       case Qroot:
+               dirread9p(req, dirgen, nil);
                respond(req, nil);
-               return;
+               break;
+       case Qusbevent:
+               readevent(req);
+               break;
+       default:
+               respond(req, Enonexist);
+               break;
        }
-       respond(req, Enonexist);
 }
 
-Srv usbdsrv = {
-       .read = usbdread,
-};
+static void
+usbdstat(Req *req)
+{
+       if(dirgen(req->fid->qid.path - 1, &req->d, nil) < 0)
+               respond(req, "the front fell off");
+       else
+               respond(req, nil);
+}
 
 static void
-readrules(void)
+usbdopen(Req *req)
 {
-       int fd, rc, n;
-       char buf[4096];
-       
-       fd = open("/lib/usbdb", OREAD);
-       if(fd < 0)
-               sysfatal("open /lib/usbdb: %r");
-       rules = nil;
-       n = 0;
-       for(;;){
-               rc = readn(fd, buf, sizeof buf);
-               if(rc == 0)
+       if(req->fid->qid.path == Qusbevent){
+               qlock(&evlock);
+               req->fid->aux = evlast;
+               evlast->ref++;
+               qunlock(&evlock);
+       }
+       respond(req, nil);
+}
+
+static void
+usbddestroyfid(Fid *fid)
+{
+       Event *e, *ee;
+
+       if(fid->qid.path == Qusbevent){
+               qlock(&evlock);
+               e = fid->aux;
+               if(--e->ref == 0 && e == evfirst){
+                       while(e->ref == 0 && e != evlast){
+                               ee = e->link;
+                               free(e->data);
+                               free(e);
+                               e = ee;
+                       }
+                       evfirst = e;
+               }
+               qunlock(&evlock);
+       }
+}
+
+static void
+usbdflush(Req *req)
+{
+       Req **l, *r;
+       qlock(&evlock);
+       l = &reqfirst;
+       while(r = *l){
+               if(r == req->oldreq){
+                       *l = r->aux;
                        break;
-               if(rc < 0)
-                       sysfatal("read: %r");
-               rules = realloc(rules, 1 + n + rc);
-               if(rules == nil)
-                       sysfatal("realloc: %r");
-               memmove(rules + n, buf, rc);
-               n += rc;
-               rules[n] = 0;
+               }
+               l = &r->aux;
        }
-       if(rules == nil)
-               rules = "";
-       close(fd);
+       qunlock(&evlock);
+       respond(req->oldreq, "interrupted");
+       respond(req, nil);
 }
 
+Srv usbdsrv = {
+       .attach = usbdattach,
+       .walk1 = usbdwalk,
+       .read = usbdread,
+       .stat = usbdstat,
+       .open = usbdopen,
+       .flush = usbdflush,
+       .destroyfid = usbddestroyfid,
+};
+
 int
 startdev(Port *p)
 {
-       Rule *r;
-       char buf[14];
+       Dev *d;
+       Usbdev *u;
 
-       if(p->dev == nil || p->dev->usb == nil){
+       if((d = p->dev) == nil || (u = p->dev->usb) == nil){
                fprint(2, "okay what?\n");
                return -1;
        }
-       rlock(&rulelock);
-       r = rulesmatch(p->dev->usb);
-       if(r == nil || r->argv == nil){
-               fprint(2, "no driver for device\n");
-               runlock(&rulelock);
-               return -1;
-       }
-       snprint(buf, sizeof buf, "%d", p->dev->id);
-       r->argv[r->argc] = buf;
+       pushevent(smprint("in id %d vid 0x%.4x did 0x%.4x csp 0x%.8x\n",
+               d->id, u->vid, u->did, u->csp));
        closedev(p->dev);
-       switch(fork()){
-       case -1:
-               fprint(2, "fork: %r");
-               runlock(&rulelock);
-               return -1;
-       case 0:
-               chdir("/bin");
-               exec(r->argv[0], r->argv);
-               sysfatal("exec: %r");
-       }
-       runlock(&rulelock);
        return 0;
 }
 
@@ -96,13 +281,9 @@ main(int argc, char **argv)
 {
        int fd, i, nd;
        Dir *d;
-
-       readrules();
-       parserules(rules);
-       luser = getuser();
        
        argc--; argv++;
-
+       initevent();
        rfork(RFNOTEG);
        switch(rfork(RFPROC|RFMEM)){
        case -1: sysfatal("rfork: %r");
@@ -124,7 +305,5 @@ main(int argc, char **argv)
                for(i = 0; i < argc; i++)
                        rendezvous(work, strdup(argv[i]));
        rendezvous(work, nil);
-       usbdsrv.tree = alloctree(luser, luser, 0555, nil);
-       usbdb = createfile(usbdsrv.tree->root, "usbdb", luser, 0775, nil);
        postsharesrv(&usbdsrv, nil, "usb", "usbd", "b");
 }