21 static char Enonexist[] = "does not exist";
23 typedef struct Event Event;
29 int ref; /* number of readers which will read this one
30 the next time they'll read */
31 int prev; /* number of events pointing to this one with
32 their link pointers */
36 static Req *reqfirst, *reqlast;
51 fulfill(Req *req, Event *e)
56 if(n > req->ifcall.count)
57 n = req->ifcall.count;
58 memmove(req->ofcall.data, e->data, n);
59 req->ofcall.count = n;
65 evlast = emallocz(sizeof(Event), 1);
81 req->fid->aux = e->link;
83 if(--e->ref == 0 && e->prev == 0){
100 ee = emallocz(sizeof(Event), 1);
103 e->len = strlen(data);
106 for(r = reqfirst; r != nil; r = rr){
115 if(e->ref == 0 && e->prev == 0){
126 dirgen(int n, Dir *d, void *)
136 d->uid = strdup(getuser());
137 d->gid = strdup(d->uid);
138 d->muid = strdup(d->uid);
139 d->name = strdup(names[n+1]);
140 d->mode = 0555 | (d->qid.type << 24);
141 d->atime = d->mtime = time(0);
149 req->fid->qid = (Qid) {Qroot, 0, QTDIR};
150 req->ofcall.qid = req->fid->qid;
155 usbdwalk(Fid *fid, char *name, Qid *qid)
159 if(strcmp(name, "..") == 0){
160 fid->qid = (Qid) {Qroot, 0, QTDIR};
164 if(fid->qid.path != Qroot)
165 return "not a directory";
166 for(i = 0; i < Qmax; i++)
167 if(strcmp(name, names[i]) == 0){
168 fid->qid = (Qid) {i, 0, 0};
172 return "does not exist";
178 switch((long)req->fid->qid.path){
180 dirread9p(req, dirgen, nil);
184 if(req->fid->aux == nil){
185 respond(req, "the front fell off");
191 respond(req, Enonexist);
199 if(dirgen(req->fid->qid.path - 1, &req->d, nil) < 0)
200 respond(req, "the front fell off");
211 return smprint("in id %d vid 0x%.4x did 0x%.4x csp 0x%.8lx\n",
212 d->id, u->vid, u->did, u->csp);
223 for(h = hubs; h != nil; h = h->next){
224 for(p = h->port; p < h->port + h->nport; p++){
225 if(p->dev == nil || p->dev->usb == nil || p->hub != nil)
227 e = emallocz(sizeof(Event), 1);
228 e->data = formatdev(p->dev);
229 e->len = strlen(e->data);
242 extern QLock hublock;
244 if(req->fid->qid.path == Qusbevent){
247 enumerate(&req->fid->aux);
248 ((Event *)req->fid->aux)->ref++;
249 ((Event *)req->fid->aux)->prev--;
257 usbddestroyfid(Fid *fid)
261 if(fid->qid.path == Qusbevent && fid->aux != nil){
264 if(--e->ref == 0 && e->prev == 0){
265 while(e->ref == 0 && e->prev == 0 && e != evlast){
284 if(r == req->oldreq){
291 respond(req->oldreq, "interrupted");
296 .attach = usbdattach,
302 .destroyfid = usbddestroyfid,
310 if((d = p->dev) == nil || p->dev->usb == nil){
311 fprint(2, "okay what?\n");
316 pushevent(formatdev(d));
321 main(int argc, char **argv)
329 switch(rfork(RFPROC|RFMEM)){
330 case -1: sysfatal("rfork: %r");
331 case 0: work(); exits(nil);
334 fd = open("/dev/usb", OREAD);
336 sysfatal("/dev/usb: %r");
337 nd = dirreadall(fd, &d);
340 sysfatal("/dev/usb: no hubs");
341 for(i = 0; i < nd; i++)
342 if(strcmp(d[i].name, "ctl") != 0)
343 rendezvous(work, smprint("/dev/usb/%s", d[i].name));
346 for(i = 0; i < argc; i++)
347 rendezvous(work, strdup(argv[i]));
348 rendezvous(work, nil);
349 postsharesrv(&usbdsrv, nil, "usb", "usbd", "b");