18 strecpy(nm, nm+sizeof(nm), r+1);
27 openep(Dev *d, int id)
29 char *mode; /* How many modes? */
36 if(access("/dev/usb", AEXIST) < 0 && bind("#u", "/dev", MBEFORE) < 0)
38 if(d->cfd < 0 || d->usb == nil){
39 werrstr("device not configured");
43 if(id < 0 || id >= nelem(ud->ep) || ud->ep[id] == nil){
44 werrstr("bad enpoint number");
53 snprint(name, sizeof(name), "/dev/usb/ep%d.%d", d->id, id);
54 if(access(name, AEXIST) == 0){
55 dprint(2, "%s: %s already exists; trying to open\n", argv0, name);
59 epd->maxpkt = ep->maxpkt; /* guess */
63 if(devctl(d, "new %d %d %s", id, ep->type, mode) < 0){
64 dprint(2, "%s: %s: new: %r\n", argv0, d->dir);
71 if(devctl(epd, "maxpkt %d", ep->maxpkt) < 0)
72 fprint(2, "%s: %s: openep: maxpkt: %r\n", argv0, epd->dir);
74 dprint(2, "%s: %s: maxpkt %d\n", argv0, epd->dir, ep->maxpkt);
75 epd->maxpkt = ep->maxpkt;
76 ac = ep->iface->altc[0];
77 if(ep->ntds > 1 && devctl(epd, "ntds %d", ep->ntds) < 0)
78 fprint(2, "%s: %s: openep: ntds: %r\n", argv0, epd->dir);
80 dprint(2, "%s: %s: ntds %d\n", argv0, epd->dir, ep->ntds);
83 * For iso endpoints and high speed interrupt endpoints the pollival is
84 * actually 2ⁿ and not n.
85 * The kernel usb driver must take that into account.
86 * It's simpler this way.
89 if(ac != nil && (ep->type == Eintr || ep->type == Eiso) && ac->interval != 0)
90 if(devctl(epd, "pollival %d", ac->interval) < 0)
91 fprint(2, "%s: %s: openep: pollival: %r\n", argv0, epd->dir);
101 if(access("/dev/usb", AEXIST) < 0 && bind("#u", "/dev", MBEFORE) < 0)
103 d = emallocz(sizeof(Dev), 1);
109 * +30 to allocate extra size to concat "/<epfilename>"
110 * we should probably remove that feature from the manual
111 * and from the code after checking out that nobody relies on
114 d->dir = emallocz(l + 30, 0);
116 strcpy(d->dir+l, "/ctl");
117 d->cfd = open(d->dir, ORDWR|OCEXEC);
121 werrstr("can't open endpoint %s: %r", d->dir);
127 dprint(2, "%s: opendev %#p %s\n", argv0, d, fn);
132 opendevdata(Dev *d, int mode)
134 char buf[80]; /* more than enough for a usb path */
136 seprint(buf, buf+sizeof(buf), "%s/data", d->dir);
137 d->dfd = open(buf, mode|OCEXEC);
144 * Max device conf is also limited by max control request size as
145 * limited by Maxctllen in the kernel usb.h (both limits are arbitrary).
147 Maxdevconf = 4 * 1024, /* asking for 16K kills Newsham's disk */
151 loaddevconf(Dev *d, int n)
157 if(n >= nelem(d->usb->conf)){
158 werrstr("loaddevconf: bug: out of configurations in device");
159 fprint(2, "%s: %r\n", argv0);
162 buf = emallocz(Maxdevconf, 0);
163 type = Rd2h|Rstd|Rdev;
164 nr = usbcmd(d, type, Rgetdesc, Dconf<<8|n, 0, buf, Maxdevconf);
169 if(d->usb->conf[n] == nil)
170 d->usb->conf[n] = emallocz(sizeof(Conf), 1);
171 nr = parseconf(d->usb, d->usb->conf[n], buf, nr);
177 mkep(Usbdev *d, int id)
181 d->ep[id] = ep = emallocz(sizeof(Ep), 1);
187 mkstr(uchar *b, int n)
193 if(n > 0 && n > b[0])
195 if(n <= 2 || (n & 1) != 0)
196 return strdup("none");
199 us = s = emallocz(n*UTFmax+1, 0);
200 for(; --n >= 0; b += 2){
202 s += runetochar(s, &r);
209 loaddevstr(Dev *d, int sid)
217 return estrdup("none");
218 type = Rd2h|Rstd|Rdev;
221 * there are devices which do not return a string if used
222 * with invalid language id, so at least try to use the first
223 * one and choose english if failed
225 nr=usbcmd(d, type, Rgetdesc, Dstr<<8, 0, buf, sizeof(buf));
227 langid = 0x0409; // english
229 langid = buf[3]<<8|buf[2];
231 nr=usbcmd(d, type, Rgetdesc, Dstr<<8|sid, langid, buf, sizeof(buf));
232 return mkstr(buf, nr);
243 type = Rd2h|Rstd|Rdev;
246 if((nr=usbcmd(d, type, Rgetdesc, Ddev<<8|0, 0, buf, nr)) < 0)
249 * Several hubs are returning descriptors of 17 bytes, not 18.
250 * We accept them and leave number of configurations as zero.
251 * (a get configuration descriptor also fails for them!)
254 print("%s: %s: warning: device with short descriptor\n",
257 werrstr("short device descriptor (%d bytes)", nr);
261 d->usb = emallocz(sizeof(Usbdev), 1);
262 ep0 = mkep(d->usb, 0);
264 ep0->type = Econtrol;
265 ep0->maxpkt = d->maxpkt = 8; /* a default */
266 nr = parsedev(d, buf, nr);
268 d->usb->vendor = loaddevstr(d, d->usb->vsid);
269 if(strcmp(d->usb->vendor, "none") != 0){
270 d->usb->product = loaddevstr(d, d->usb->psid);
271 d->usb->serial = loaddevstr(d, d->usb->ssid);
283 opendevdata(d, ORDWR);
286 if(loaddevdesc(d) < 0)
288 for(i = 0; i < d->usb->nconf; i++)
289 if(loaddevconf(d, i) < 0)
302 for(i = 0; i < nelem(c->iface); i++)
303 if(c->iface[i] != nil){
304 for(a = 0; a < nelem(c->iface[i]->altc); a++)
305 free(c->iface[i]->altc[a]);
317 if(d==nil || decref(d) != 0)
319 dprint(2, "%s: closedev %#p %s\n", argv0, d, d->dir);
326 d->cfd = d->dfd = -1;
337 for(i = 0; i < nelem(ud->ep); i++)
339 for(i = 0; i < nelem(ud->ddesc); i++)
342 for(i = 0; i < nelem(ud->conf); i++)
343 closeconf(ud->conf[i]);
350 reqstr(int type, int req)
353 static char* ds[] = { "dev", "if", "ep", "oth" };
357 s = seprint(buf, buf+sizeof(buf), "d2h");
359 s = seprint(buf, buf+sizeof(buf), "h2d");
361 s = seprint(s, buf+sizeof(buf), "|cls");
362 else if(type&Rvendor)
363 s = seprint(s, buf+sizeof(buf), "|vnd");
365 s = seprint(s, buf+sizeof(buf), "|std");
366 s = seprint(s, buf+sizeof(buf), "|%s", ds[type&3]);
369 case Rgetstatus: s = seprint(s, buf+sizeof(buf), " getsts"); break;
370 case Rclearfeature: s = seprint(s, buf+sizeof(buf), " clrfeat"); break;
371 case Rsetfeature: s = seprint(s, buf+sizeof(buf), " setfeat"); break;
372 case Rsetaddress: s = seprint(s, buf+sizeof(buf), " setaddr"); break;
373 case Rgetdesc: s = seprint(s, buf+sizeof(buf), " getdesc"); break;
374 case Rsetdesc: s = seprint(s, buf+sizeof(buf), " setdesc"); break;
375 case Rgetconf: s = seprint(s, buf+sizeof(buf), " getcnf"); break;
376 case Rsetconf: s = seprint(s, buf+sizeof(buf), " setcnf"); break;
377 case Rgetiface: s = seprint(s, buf+sizeof(buf), " getif"); break;
378 case Rsetiface: s = seprint(s, buf+sizeof(buf), " setif"); break;
385 cmdreq(Dev *d, int type, int req, int value, int index, uchar *data, int count)
398 wp = emallocz(8+ndata, 0);
406 memmove(wp+8, data, ndata);
408 hd = hexstr(wp, ndata+8);
409 rs = reqstr(type, req);
410 fprint(2, "%s: %s val %d|%d idx %d cnt %d out[%d] %s\n",
411 d->dir, rs, value>>8, value&0xFF,
412 index, count, ndata+8, hd);
415 n = write(d->dfd, wp, 8+ndata);
421 dprint(2, "%s: cmd: short write: %d\n", argv0, n);
428 cmdrep(Dev *d, void *buf, int nb)
432 nb = read(d->dfd, buf, nb);
433 if(nb >0 && usbdebug > 2){
434 hd = hexstr(buf, nb);
435 fprint(2, "%s: in[%d] %s\n", d->dir, nb, hd);
442 usbcmd(Dev *d, int type, int req, int value, int index, uchar *data, int count)
448 * Some devices do not respond to commands some times.
449 * Others even report errors but later work just fine. Retry.
453 for(i = nerr = 0; i < Uctries; i++){
455 r = cmdreq(d, type, req, value, index, nil, count);
457 r = cmdreq(d, type, req, value, index, data, count);
459 if((type & Rd2h) == 0)
461 r = cmdrep(d, data, count);
465 werrstr("no data from device");
469 rerrstr(err, sizeof(err));
473 /* let the user know the device is not in good shape */
474 fprint(2, "%s: usbcmd: %s: required %d attempts (%s)\n",
475 argv0, d->dir, i, err);
480 unstall(Dev *dev, Dev *ep, int dir)
489 if(usbcmd(dev, r, Rclearfeature, Fhalt, (ep->id&0xF)|dir, nil, 0)<0){
490 werrstr("unstall: %s: %r", ep->dir);
493 if(devctl(ep, "clrhalt") < 0){
494 werrstr("clrhalt: %s: %r", ep->dir);
501 * To be sure it uses a single write.
504 devctl(Dev *dev, char *fmt, ...)
511 e = vseprint(buf, buf+sizeof(buf), fmt, arg);
513 return write(dev->cfd, buf, e-buf);
522 if(devid[0] == '/' || devid[0] == '#'){
523 snprint(buf, sizeof buf, "%s", devid);
524 p = strrchr(buf, '/');
526 p = strrchr(buf, ':');
532 snprint(buf, sizeof buf, "/dev/usb/ep%ld.0", strtol(devid, &p, 10));
540 if(configdev(d) < 0){
546 snprint(buf, sizeof buf, ":%d", d->id);
549 d->hname = strdup(p+1);