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)
{
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);
}
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);
}
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;
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);
}
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);
}
}
};
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
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));
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);
}