]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/nusb/usbd/usbd.c
nusbd: properly terminate worker proc if no hubs can be found
[plan9front.git] / sys / src / cmd / nusb / usbd / usbd.c
index 97059e11d5d9c2a91f8a950bb447dfbc9d9b1279..2e96df07f92a248bef1a11d1c7d0ad64bbe6eb74 100644 (file)
@@ -65,6 +65,20 @@ initevent(void)
        evlast = emallocz(sizeof(Event), 1);
 }
 
+static Event*
+putevent(Event *e)
+{
+       Event *ee;
+
+       ee = e->link;
+       if(e->ref || e->prev)
+               return ee;
+       ee->prev--;
+       free(e->data);
+       free(e);
+       return ee;
+}
+
 static void
 readevent(Req *req)
 {
@@ -80,11 +94,8 @@ readevent(Req *req)
        fulfill(req, e);
        req->fid->aux = e->link;
        e->link->ref++;
-       if(--e->ref == 0 && e->prev == 0){
-               e->link->prev--;
-               free(e->data);
-               free(e);
-       }
+       e->ref--;
+       putevent(e);
        qunlock(&evlock);
        respond(req, nil);
 }
@@ -112,11 +123,7 @@ pushevent(char *data)
                fulfill(r, e);
                respond(r, nil);
        }
-       if(e->ref == 0 && e->prev == 0){
-               ee->prev--;
-               free(e->data);
-               free(e);
-       }
+       putevent(e);
        reqfirst = nil;
        reqlast = nil;
        qunlock(&evlock);
@@ -203,33 +210,37 @@ usbdstat(Req *req)
 }
 
 static char *
-formatdev(Dev *d)
+formatdev(Dev *d, int type)
 {
        Usbdev *u;
        
        u = d->usb;
-       return smprint("in id %d vid 0x%.4x did 0x%.4x csp 0x%.8lx\n",
-               d->id, u->vid, u->did, u->csp);
+       return smprint("%s %d %.4x %.4x %.8lx\n", type ? "detach" : "attach", d->id, u->vid, u->did, u->csp);
 }
 
 static void
 enumerate(Event **l)
 {
+       extern Hub *hubs;
+
        Event *e;
        Hub *h;
        Port *p;
-       extern Hub *hubs;
+       int i;
        
        for(h = hubs; h != nil; h = h->next){
-               for(p = h->port; p < h->port + h->nport; p++){
+               for(i = 1; i <= h->nport; i++){
+                       p = &h->port[i];
+
                        if(p->dev == nil || p->dev->usb == nil || p->hub != nil)
                                continue;
                        e = emallocz(sizeof(Event), 1);
-                       e->data = formatdev(p->dev);
+                       e->data = formatdev(p->dev, 0);
                        e->len = strlen(e->data);
                        e->prev = 1;
                        *l = e;
                        l = &e->link;
+
                }
        }
        *l = evlast;
@@ -242,11 +253,16 @@ usbdopen(Req *req)
        extern QLock hublock;
 
        if(req->fid->qid.path == Qusbevent){
+               Event *e;
+
                qlock(&hublock);
                qlock(&evlock);
+
                enumerate(&req->fid->aux);
-               ((Event *)req->fid->aux)->ref++;
-               ((Event *)req->fid->aux)->prev--;
+               e = req->fid->aux;
+               e->ref++;
+               e->prev--;
+
                qunlock(&evlock);
                qunlock(&hublock);
        }
@@ -256,20 +272,14 @@ usbdopen(Req *req)
 static void
 usbddestroyfid(Fid *fid)
 {
-       Event *e, *ee;
+       Event *e;
 
        if(fid->qid.path == Qusbevent && fid->aux != nil){
                qlock(&evlock);
                e = fid->aux;
-               if(--e->ref == 0 && e->prev == 0){
-                       while(e->ref == 0 && e->prev == 0 && e != evlast){
-                               ee = e->link;
-                               ee->prev--;
-                               free(e->data);
-                               free(e);
-                               e = ee;
-                       }
-               }
+               if(--e->ref == 0 && e->prev == 0)
+                       while(e->ref == 0 && e->prev == 0 && e != evlast)
+                               e = putevent(e);
                qunlock(&evlock);
        }
 }
@@ -303,14 +313,10 @@ Srv usbdsrv = {
 };
 
 int
-startdev(Port *p)
+attachdev(Port *p)
 {
-       Dev *d;
+       Dev *d = p->dev;
 
-       if((d = p->dev) == nil || p->dev->usb == nil){
-               fprint(2, "okay what?\n");
-               return -1;
-       }
        if(d->usb->class == Clhub){
                /*
                 * Hubs are handled directly by this process avoiding
@@ -322,33 +328,51 @@ startdev(Port *p)
                        return -1;
                return 0;
        }
+
        close(d->dfd);
        d->dfd = -1;
-       pushevent(formatdev(d));
+       pushevent(formatdev(d, 0));
        return 0;
 }
 
+void
+detachdev(Port *p)
+{
+       pushevent(formatdev(p->dev, 1));
+}
+
 void
 main(int argc, char **argv)
 {
        int fd, i, nd;
        Dir *d;
-       
-       argc--; argv++;
+
+       ARGBEGIN {
+       case 'D':
+               chatty9p++;
+               break;
+       case 'd':
+               usbdebug++;
+               break;
+       } ARGEND;
+
        initevent();
        rfork(RFNOTEG);
-       switch(rfork(RFPROC|RFMEM)){
+       switch(rfork(RFPROC|RFMEM|RFNOWAIT)){
        case -1: sysfatal("rfork: %r");
        case 0: work(); exits(nil);
        }
        if(argc == 0){
-               fd = open("/dev/usb", OREAD);
-               if(fd < 0)
+               if((fd = open("/dev/usb", OREAD)) < 0){
+                       rendezvous(work, nil);
                        sysfatal("/dev/usb: %r");
+               }
                nd = dirreadall(fd, &d);
                close(fd);
-               if(nd < 2)
+               if(nd < 2){
+                       rendezvous(work, nil);
                        sysfatal("/dev/usb: no hubs");
+               }
                for(i = 0; i < nd; i++)
                        if(strcmp(d[i].name, "ctl") != 0)
                                rendezvous(work, smprint("/dev/usb/%s", d[i].name));
@@ -357,5 +381,6 @@ main(int argc, char **argv)
                for(i = 0; i < argc; i++)
                        rendezvous(work, strdup(argv[i]));
        rendezvous(work, nil);
-       postsharesrv(&usbdsrv, nil, "usb", "usbd", "b");
+       postsharesrv(&usbdsrv, nil, "usb", "usbd");
+       exits(nil);
 }