static int kernelproxy(Ether *e) { int ctlfd, n; char eaddr[13]; ctlfd = open("#l0/ether0/clone", ORDWR); if(ctlfd < 0){ deprint(2, "%s: etherusb bind #l0: %r\n", argv0); return -1; } close(e->epin->dfd); close(e->epout->dfd); seprintaddr(eaddr, eaddr+sizeof(eaddr), e->addr); n = fprint(ctlfd, "bind %s #u/usb/ep%d.%d/data #u/usb/ep%d.%d/data %s %d %d", e->name, e->dev->id, e->epin->id, e->dev->id, e->epout->id, eaddr, e->bufsize, e->epout->maxpkt); if(n < 0){ deprint(2, "%s: etherusb bind #l0: %r\n", argv0); opendevdata(e->epin, OREAD); opendevdata(e->epout, OWRITE); close(ctlfd); return -1; } close(ctlfd); return 0; }
static int openeps(Ether *e, int epin, int epout) { e->epin = openep(e->dev, epin); if(e->epin == nil){ fprint(2, "ether: in: openep %d: %r\n", epin); return -1; } if(epout == epin){ incref(e->epin); e->epout = e->epin; }else e->epout = openep(e->dev, epout); if(e->epout == nil){ fprint(2, "ether: out: openep %d: %r\n", epout); closedev(e->epin); return -1; } if(e->epin == e->epout) opendevdata(e->epin, ORDWR); else{ opendevdata(e->epin, OREAD); opendevdata(e->epout, OWRITE); } if(e->epin->dfd < 0 || e->epout->dfd < 0){ fprint(2, "ether: open i/o ep data: %r\n"); closedev(e->epin); closedev(e->epout); return -1; } dprint(2, "ether: ep in %s maxpkt %d; ep out %s maxpkt %d\n", e->epin->dir, e->epin->maxpkt, e->epout->dir, e->epout->maxpkt); /* time outs are not activated for I/O endpoints */ if(usbdebug > 2 || etherdebug > 2){ devctl(e->epin, "debug 1"); devctl(e->epout, "debug 1"); devctl(e->dev, "debug 1"); } return 0; }
static void portreset(Hub *h, int p) { int sts; Dev *d, *nd; Port *pp; d = h->dev; pp = &h->port[p]; nd = pp->dev; dprint(2, "%s: %s: port %d: resetting\n", argv0, d->dir, p); if(hubfeature(h, p, Fportreset, 1) < 0){ dprint(2, "%s: %s: port %d: reset: %r\n", argv0, d->dir, p); goto Fail; } sleep(Resetdelay); sts = portstatus(h, p); if(sts < 0) goto Fail; if((sts & PSenable) == 0){ dprint(2, "%s: %s: port %d: not enabled?\n", argv0, d->dir, p); hubfeature(h, p, Fportenable, 1); sts = portstatus(h, p); if((sts & PSenable) == 0) goto Fail; } nd = pp->dev; opendevdata(nd, ORDWR); if(usbcmd(nd, Rh2d|Rstd|Rdev, Rsetaddress, nd->id, 0, nil, 0) < 0){ dprint(2, "%s: %s: port %d: setaddress: %r\n", argv0, d->dir, p); goto Fail; } if(devctl(nd, "address") < 0){ dprint(2, "%s: %s: port %d: set address: %r\n", argv0, d->dir, p); goto Fail; } if(usbcmd(nd, Rh2d|Rstd|Rdev, Rsetconf, 1, 0, nil, 0) < 0){ dprint(2, "%s: %s: port %d: setconf: %r\n", argv0, d->dir, p); unstall(nd, nd, Eout); if(usbcmd(nd, Rh2d|Rstd|Rdev, Rsetconf, 1, 0, nil, 0) < 0) goto Fail; } if(nd->dfd >= 0) close(nd->dfd); return; Fail: pp->state = Pdisabled; pp->sts = 0; if(pp->hub != nil) pp->hub = nil; /* hub closed by enumhub */ hubfeature(h, p, Fportenable, 0); if(nd != nil) devctl(nd, "detach"); closedev(nd); }
int configdev(Dev *d) { int i; if(d->dfd < 0) opendevdata(d, ORDWR); if(d->dfd < 0) return -1; if(loaddevdesc(d) < 0) return -1; for(i = 0; i < d->usb->nconf; i++) if(loaddevconf(d, i) < 0) return -1; return 0; }
void threadmain(int argc, char **argv) { Dev *yd; char *devdir = nil; Ep *ep; int csps[] = {YurexCSP, 0}; int i; if(finddevs(matchdevcsp, csps, &devdir, 1) < 1){ fprint(2, "No yurex device\n"); threadexitsall("yurex not found"); } yd = opendev(devdir); if(yd == nil) sysfatal("opendev: %r"); if(configdev(yd)<0) sysfatal("configdev: %r"); for(i = 0; i < nelem(yd->usb->ep); i++){ if((ep = yd->usb->ep[i]) == nil) break; if(ep->type == Eintr && ep->dir == Ein) if(ep->iface->csp == YurexCSP){ yc.ep = openep(yd, ep->id); if(yc.ep == nil) sysfatal("YUREX: %s: openep %d: %r\n", yd->dir, ep->id); if(opendevdata(yc.ep, OREAD) < 0){ fprint(2, "YUERX: %s: opendevdata: %r\n", yc.ep->dir); closedev(yc.ep); yc.ep = nil; break; } fs.tree = alloctree(nil, nil, DMDIR|0777, destroyfile); createfile(fs.tree->root, "bbu", nil, 0444, nil); createfile(fs.tree->root, "mbbups", nil, 0444, nil); threadpostmountsrv(&fs, "yurex", nil, MREPL|MCREATE); proccreate(yurexwork, nil, Stack); } } threadexits(nil); }
/* * BUG: does not consider max. power avail. */ static Dev* portattach(Hub *h, int p, int sts) { Dev *d; Port *pp; Dev *nd; char fname[80]; char buf[40]; char *sp; int mp; int nr; d = h->dev; pp = &h->port[p]; nd = nil; pp->state = Pattached; dprint(2, "%s: %s: port %d attach sts %#x\n", argv0, d->dir, p, sts); sleep(Connectdelay); if(hubfeature(h, p, Fportenable, 1) < 0) dprint(2, "%s: %s: port %d: enable: %r\n", argv0, d->dir, p); sleep(Enabledelay); if(hubfeature(h, p, Fportreset, 1) < 0){ dprint(2, "%s: %s: port %d: reset: %r\n", argv0, d->dir, p); goto Fail; } sleep(Resetdelay); sts = portstatus(h, p); if(sts < 0) goto Fail; if((sts & PSenable) == 0){ dprint(2, "%s: %s: port %d: not enabled?\n", argv0, d->dir, p); hubfeature(h, p, Fportenable, 1); sts = portstatus(h, p); if((sts & PSenable) == 0) goto Fail; } sp = "full"; if(sts & PSslow) sp = "low"; if(sts & PShigh) sp = "high"; dprint(2, "%s: %s: port %d: attached status %#x\n", argv0, d->dir, p, sts); if(devctl(d, "newdev %s %d", sp, p) < 0){ fprint(2, "%s: %s: port %d: newdev: %r\n", argv0, d->dir, p); goto Fail; } seek(d->cfd, 0, 0); nr = read(d->cfd, buf, sizeof(buf)-1); if(nr == 0){ fprint(2, "%s: %s: port %d: newdev: eof\n", argv0, d->dir, p); goto Fail; } if(nr < 0){ fprint(2, "%s: %s: port %d: newdev: %r\n", argv0, d->dir, p); goto Fail; } buf[nr] = 0; snprint(fname, sizeof(fname), "/dev/usb/%s", buf); nd = opendev(fname); if(nd == nil){ fprint(2, "%s: %s: port %d: opendev: %r\n", argv0, d->dir, p); goto Fail; } if(usbdebug > 2) devctl(nd, "debug 1"); if(opendevdata(nd, ORDWR) < 0){ fprint(2, "%s: %s: opendevdata: %r\n", argv0, nd->dir); goto Fail; } if(usbcmd(nd, Rh2d|Rstd|Rdev, Rsetaddress, nd->id, 0, nil, 0) < 0){ dprint(2, "%s: %s: port %d: setaddress: %r\n", argv0, d->dir, p); goto Fail; } if(devctl(nd, "address") < 0){ dprint(2, "%s: %s: port %d: set address: %r\n", argv0, d->dir, p); goto Fail; } mp=getmaxpkt(nd, strcmp(sp, "low") == 0); if(mp < 0){ dprint(2, "%s: %s: port %d: getmaxpkt: %r\n", argv0, d->dir, p); goto Fail; }else{ dprint(2, "%s; %s: port %d: maxpkt %d\n", argv0, d->dir, p, mp); devctl(nd, "maxpkt %d", mp); } if((sts & PSslow) != 0 && strcmp(sp, "full") == 0) dprint(2, "%s: %s: port %d: %s is full speed when port is low\n", argv0, d->dir, p, nd->dir); if(configdev(nd) < 0){ dprint(2, "%s: %s: port %d: configdev: %r\n", argv0, d->dir, p); goto Fail; } /* * We always set conf #1. BUG. */ if(usbcmd(nd, Rh2d|Rstd|Rdev, Rsetconf, 1, 0, nil, 0) < 0){ dprint(2, "%s: %s: port %d: setconf: %r\n", argv0, d->dir, p); unstall(nd, nd, Eout); if(usbcmd(nd, Rh2d|Rstd|Rdev, Rsetconf, 1, 0, nil, 0) < 0) goto Fail; } dprint(2, "%s: %U\n", argv0, nd); pp->state = Pconfiged; dprint(2, "%s: %s: port %d: configed: %s\n", argv0, d->dir, p, nd->dir); return pp->dev = nd; Fail: pp->state = Pdisabled; pp->sts = 0; if(pp->hub != nil) pp->hub = nil; /* hub closed by enumhub */ hubfeature(h, p, Fportenable, 0); if(nd != nil) devctl(nd, "detach"); closedev(nd); return nil; }
Hub* newhub(char *fn, Dev *d) { Hub *h; int i; Usbdev *ud; h = emallocz(sizeof(Hub), 1); h->isroot = (d == nil); if(h->isroot){ h->dev = opendev(fn); if(h->dev == nil){ fprint(2, "%s: opendev: %s: %r\n", argv0, fn); goto Fail; } if(opendevdata(h->dev, ORDWR) < 0){ fprint(2, "%s: opendevdata: %s: %r\n", argv0, fn); goto Fail; } configroothub(h); /* never fails */ }else{ h->dev = d; if(confighub(h) < 0){ fprint(2, "%s: %s: config: %r\n", argv0, fn); goto Fail; } } if(h->dev == nil){ fprint(2, "%s: opendev: %s: %r\n", argv0, fn); goto Fail; } devctl(h->dev, "hub"); ud = h->dev->usb; if(h->isroot) devctl(h->dev, "info roothub csp %#08ux ports %d", 0x000009, h->nport); else{ devctl(h->dev, "info hub csp %#08ulx ports %d %q %q", ud->csp, h->nport, ud->vendor, ud->product); for(i = 1; i <= h->nport; i++) if(hubfeature(h, i, Fportpower, 1) < 0) fprint(2, "%s: %s: power: %r\n", argv0, fn); sleep(h->pwrms); for(i = 1; i <= h->nport; i++) if(h->leds != 0) hubfeature(h, i, Fportindicator, 1); } h->next = hubs; hubs = h; nhubs++; dprint(2, "%s: hub %#p allocated:", argv0, h); dprint(2, " ports %d pwrms %d max curr %d pwrm %d cmp %d leds %d\n", h->nport, h->pwrms, h->maxcurrent, h->pwrmode, h->compound, h->leds); incref(&h->dev->Ref); return h; Fail: if(d != nil) devctl(d, "detach"); free(h->port); free(h); dprint(2, "%s: hub %#p failed to start\n", argv0, h); return nil; }
void threadmain(int argc, char **argv) { char *devdir; int i; long value[8], volume[8]; Audiocontrol *c; char *p; extern int attachok; Ep *ep; int csps[] = { Audiocsp, 0}; devdir = nil; volume[0] = Undef; for(i = 0; i<8; i++) value[i] = 0; fmtinstall('A', Aconv); fmtinstall('U', Ufmt); quotefmtinstall(); ARGBEGIN{ case 'N': p = EARGF(usage()); /* ignore dev nb */ break; case 'd': usbdebug++; verbose++; break; case 'm': mntpt = EARGF(usage()); break; case 'p': attachok++; break; case 's': srvpost = EARGF(usage()); break; case 'v': volume[0] = strtol(EARGF(usage()), &p, 0); for(i = 1; i < 8; i++) volume[i] = volume[0]; break; case 'V': verbose++; break; default: usage(); }ARGEND switch(argc){ case 0: break; case 1: devdir = argv[0]; break; default: usage(); } if(devdir == nil) if(finddevs(matchdevcsp, csps, &devdir, 1) < 1){ fprint(2, "No usb audio\n"); threadexitsall("usbaudio not found"); } ad = opendev(devdir); if(ad == nil) sysfatal("opendev: %r"); if(configdev(ad) < 0) sysfatal("configdev: %r"); for(i = 0; i < nelem(ad->usb->ddesc); i++) if(ad->usb->ddesc[i] != nil) switch(ad->usb->ddesc[i]->data.bDescriptorType){ case AUDIO_INTERFACE: audio_interface(ad, ad->usb->ddesc[i]); break; case AUDIO_ENDPOINT: audio_endpoint(ad, ad->usb->ddesc[i]); break; } controlchan = chancreate(sizeof(char*), 8); for(i = 0; i < nelem(ad->usb->ep); i++) if((ep = ad->usb->ep[i]) != nil){ if(ep->iface->csp == CSP(Claudio, 2, 0) && ep->dir == Eout) endpt[0] = ep->id; if(ep->iface->csp == CSP(Claudio, 2, 0) && ep->dir == Ein) endpt[1] = ep->id; if(buttonendpt<0 && Class(ep->iface->csp) == Clhid) buttonendpt = ep->id; } if(endpt[0] != -1){ if(verbose) fprint(2, "usb/audio: playback on ep %d\n", endpt[0]); interface[0] = ad->usb->ep[endpt[0]]->iface->id; } if(endpt[1] != -1){ if(verbose) fprint(2, "usb/audio: record on ep %d\n", endpt[0]); interface[1] = ad->usb->ep[endpt[1]]->iface->id; } if(verbose && buttonendpt >= 0) fprint(2, "usb/audio: buttons on ep %d\n", buttonendpt); if(endpt[Play] >= 0){ if(verbose) fprint(2, "Setting default play parameters: %d Hz, %d channels at %d bits\n", defaultspeed[Play], 2, 16); if(findalt(Play, 2, 16, defaultspeed[Play]) < 0){ if(findalt(Play, 2, 16, 48000) < 0) sysfatal("Can't configure playout for %d or %d Hz", defaultspeed[Play], 48000); fprint(2, "Warning, can't configure playout for %d Hz, configuring for %d Hz instead\n", defaultspeed[Play], 48000); defaultspeed[Play] = 48000; } value[0] = 2; if(setcontrol(Play, "channels", value) == Undef) sysfatal("Can't set play channels"); value[0] = 16; if(setcontrol(Play, "resolution", value) == Undef) sysfatal("Can't set play resolution"); } if(endpt[Record] >= 0){ setrec = 1; if(verbose) fprint(2, "Setting default record parameters: " "%d Hz, %d channels at %d bits\n", defaultspeed[Record], 2, 16); i = 2; while(findalt(Record, i, 16, defaultspeed[Record]) < 0) if(i == 2 && controls[Record][Channel_control].max == 1){ fprint(2, "Warning, can't configure stereo " "recording, configuring mono instead\n"); i = 1; }else break; if(findalt(Record, i, 16, 48000) < 0){ endpt[Record] = -1; /* disable recording */ setrec = 0; fprint(2, "Warning, can't configure record for %d Hz or %d Hz\n", defaultspeed[Record], 48000); }else fprint(2, "Warning, can't configure record for %d Hz, " "configuring for %d Hz instead\n", defaultspeed[Record], 48000); defaultspeed[Record] = 48000; if(setrec){ value[0] = i; if(setcontrol(Record, "channels", value) == Undef) sysfatal("Can't set record channels"); value[0] = 16; if(setcontrol(Record, "resolution", value) == Undef) sysfatal("Can't set record resolution"); } } getcontrols(); /* Get the initial value of all controls */ value[0] = defaultspeed[Play]; if(endpt[Play] >= 0 && setcontrol(Play, "speed", value) < 0) sysfatal("can't set play speed"); value[0] = defaultspeed[Record]; if(endpt[Record] >= 0 && setcontrol(Record, "speed", value) < 0) fprint(2, "%s: can't set record speed\n", argv0); value[0] = 0; setcontrol(Play, "mute", value); if(volume[0] != Undef){ c = &controls[Play][Volume_control]; if(*p == '%' && c->min != Undef) for(i = 0; i < 8; i++) volume[i] = (volume[i]*c->max + (100-volume[i])*c->min)/100; if(c->settable) setcontrol(Play, "volume", volume); c = &controls[Record][Volume_control]; if(c->settable && setrec) setcontrol(Record, "volume", volume); } if(buttonendpt > 0){ buttondev = openep(ad, buttonendpt); if(buttondev == nil) sysfatal("openep: buttons: %r"); if(opendevdata(buttondev, OREAD) < 0) sysfatal("open buttons fd: %r"); proccreate(buttonproc, nil, STACKSIZE); } proccreate(controlproc, nil, STACKSIZE); proccreate(serve, nil, STACKSIZE); threadexits(nil); }