1 /*
2 * USB device driver framework.
3 *
4 * This is in charge of providing access to actual HCIs
5 * and providing I/O to the various endpoints of devices.
6 * A separate user program (usbd) is in charge of
7 * enumerating the bus, setting up endpoints and
8 * starting devices (also user programs).
9 *
10 * The interface provided is a violation of the standard:
11 * you're welcome.
12 *
13 * The interface consists of a root directory with several files
14 * plus a directory (epN.M) with two files per endpoint.
15 * A device is represented by its first endpoint, which
16 * is a control endpoint automatically allocated for each device.
17 * Device control endpoints may be used to create new endpoints.
18 * Devices corresponding to hubs may also allocate new devices,
19 * perhaps also hubs. Initially, a hub device is allocated for
20 * each controller present, to represent its root hub. Those can
21 * never be removed.
22 *
23 * All endpoints refer to the first endpoint (epN.0) of the device,
24 * which keeps per-device information, and also to the HCI used
25 * to reach them. Although all endpoints cache that information.
26 *
27 * epN.M/data files permit I/O and are considered DMEXCL.
28 * epN.M/ctl files provide status info and accept control requests.
29 *
30 * Endpoints may be given file names to be listed also at #u,
31 * for those drivers that have nothing to do after configuring the
32 * device and its endpoints.
33 *
34 * Drivers for different controllers are kept at usb[oue]hci.c
35 * It's likely we could factor out much from controllers into
36 * a generic controller driver, the problem is that details
37 * regarding how to handle toggles, tokens, Tds, etc. will
38 * get in the way. Thus, code is probably easier the way it is.
39 */
40
41 #include "u.h"
42 #include "../port/lib.h"
43 #include "mem.h"
44 #include "dat.h"
45 #include "fns.h"
46 #include "io.h"
47 #include "../port/error.h"
48 #include "../port/usb.h"
49
50 typedef struct Hcitype Hcitype;
51
52 enum
53 {
54 /* Qid numbers */
55 Qdir = 0, /* #u */
56 Qusbdir, /* #u/usb */
57 Qctl, /* #u/usb/ctl - control requests */
58
59 Qep0dir, /* #u/usb/ep0.0 - endpoint 0 dir */
60 Qep0io, /* #u/usb/ep0.0/data - endpoint 0 I/O */
61 Qep0ctl, /* #u/usb/ep0.0/ctl - endpoint 0 ctl. */
62 Qep0dummy, /* give 4 qids to each endpoint */
63
64 Qepdir = 0, /* (qid-qep0dir)&3 is one of these */
65 Qepio, /* to identify which file for the endpoint */
66 Qepctl,
67
68 /* ... */
69
70 /* Usb ctls. */
71 CMdebug = 0, /* debug on|off */
72 CMdump, /* dump (data structures for debug) */
73
74 /* Ep. ctls */
75 CMnew = 0, /* new nb ctl|bulk|intr|iso r|w|rw (endpoint) */
76 CMnewdev, /* newdev full|low|high portnb (allocate new devices) */
77 CMhub, /* hub (set the device as a hub) */
78 CMspeed, /* speed full|low|high|no */
79 CMmaxpkt, /* maxpkt size */
80 CMntds, /* ntds nb (max nb. of tds per µframe) */
81 CMclrhalt, /* clrhalt (halt was cleared on endpoint) */
82 CMpollival, /* pollival interval (interrupt/iso) */
83 CMhz, /* hz n (samples/sec; iso) */
84 CMsamplesz, /* samplesz n (sample size; iso) */
85 CMinfo, /* info infostr (ke.ep info for humans) */
86 CMdetach, /* detach (abort I/O forever on this ep). */
87 CMaddress, /* address (address is assigned) */
88 CMdebugep, /* debug n (set/clear debug for this ep) */
89 CMname, /* name str (show up as #u/name as well) */
90 CMtmout, /* timeout n (activate timeouts for ep) */
91 CMpreset, /* reset the port */
92
93 /* Hub feature selectors */
94 Rportenable = 1,
95 Rportreset = 4,
96
97 };
98
99 struct Hcitype
100 {
101 char* type;
102 int (*reset)(Hci*);
103 };
104
105 #define QID(q) ((int)(q).path)
106
107 static Cmdtab usbctls[] =
108 {
109 {CMdebug, "debug", 2},
110 {CMdump, "dump", 1},
111 };
112
113 static Cmdtab epctls[] =
114 {
115 {CMnew, "new", 4},
116 {CMnewdev, "newdev", 3},
117 {CMhub, "hub", 1},
118 {CMspeed, "speed", 2},
119 {CMmaxpkt, "maxpkt", 2},
120 {CMntds, "ntds", 2},
121 {CMpollival, "pollival", 2},
122 {CMsamplesz, "samplesz", 2},
123 {CMhz, "hz", 2},
124 {CMinfo, "info", 0},
125 {CMdetach, "detach", 1},
126 {CMaddress, "address", 1},
127 {CMdebugep, "debug", 2},
128 {CMclrhalt, "clrhalt", 1},
129 {CMname, "name", 2},
130 {CMtmout, "timeout", 2},
131 {CMpreset, "reset", 1},
132 };
133
134 static Dirtab usbdir[] =
135 {
136 "ctl", {Qctl}, 0, 0666,
137 };
138
139 char *usbmodename[] =
140 {
141 [OREAD] "r",
142 [OWRITE] "w",
143 [ORDWR] "rw",
144 };
145
146 static char *ttname[] =
147 {
148 [Tnone] "none",
149 [Tctl] "control",
150 [Tiso] "iso",
151 [Tintr] "interrupt",
152 [Tbulk] "bulk",
153 };
154
155 static char *spname[] =
156 {
157 [Fullspeed] "full",
158 [Lowspeed] "low",
159 [Highspeed] "high",
160 [Nospeed] "no",
161 };
162
163 static int debug;
164 static Hcitype hcitypes[Nhcis];
165 static Hci* hcis[Nhcis];
166 static QLock epslck; /* add, del, lookup endpoints */
167 static Ep* eps[Neps]; /* all endpoints known */
168 static int epmax; /* 1 + last endpoint index used */
169 static int usbidgen; /* device address generator */
170
171 /*
172 * Is there something like this in a library? should it be?
173 */
174 char*
seprintdata(char * s,char * se,uchar * d,int n)175 seprintdata(char *s, char *se, uchar *d, int n)
176 {
177 int i, l;
178
179 s = seprint(s, se, " %#p[%d]: ", d, n);
180 l = n;
181 if(l > 10)
182 l = 10;
183 for(i=0; i<l; i++)
184 s = seprint(s, se, " %2.2ux", d[i]);
185 if(l < n)
186 s = seprint(s, se, "...");
187 return s;
188 }
189
190 static int
name2speed(char * name)191 name2speed(char *name)
192 {
193 int i;
194
195 for(i = 0; i < nelem(spname); i++)
196 if(strcmp(name, spname[i]) == 0)
197 return i;
198 return Nospeed;
199 }
200
201 static int
name2ttype(char * name)202 name2ttype(char *name)
203 {
204 int i;
205
206 for(i = 0; i < nelem(ttname); i++)
207 if(strcmp(name, ttname[i]) == 0)
208 return i;
209 /* may be a std. USB ep. type */
210 i = strtol(name, nil, 0);
211 switch(i+1){
212 case Tctl:
213 case Tiso:
214 case Tbulk:
215 case Tintr:
216 return i+1;
217 default:
218 return Tnone;
219 }
220 }
221
222 static int
name2mode(char * mode)223 name2mode(char *mode)
224 {
225 int i;
226
227 for(i = 0; i < nelem(usbmodename); i++)
228 if(strcmp(mode, usbmodename[i]) == 0)
229 return i;
230 return -1;
231 }
232
233 static int
qid2epidx(int q)234 qid2epidx(int q)
235 {
236 q = (q-Qep0dir)/4;
237 if(q < 0 || q >= epmax || eps[q] == nil)
238 return -1;
239 return q;
240 }
241
242 static int
isqtype(int q,int type)243 isqtype(int q, int type)
244 {
245 if(q < Qep0dir)
246 return 0;
247 q -= Qep0dir;
248 return (q & 3) == type;
249 }
250
251 void
addhcitype(char * t,int (* r)(Hci *))252 addhcitype(char* t, int (*r)(Hci*))
253 {
254 static int ntype;
255
256 if(ntype == Nhcis)
257 panic("too many USB host interface types");
258 hcitypes[ntype].type = t;
259 hcitypes[ntype].reset = r;
260 ntype++;
261 }
262
263 static char*
seprintep(char * s,char * se,Ep * ep,int all)264 seprintep(char *s, char *se, Ep *ep, int all)
265 {
266 static char* dsnames[] = { "config", "enabled", "detached", "reset" };
267 Udev *d;
268 int i;
269 int di;
270
271 d = ep->dev;
272
273 qlock(ep);
274 if(waserror()){
275 qunlock(ep);
276 nexterror();
277 }
278 di = ep->dev->nb;
279 if(all)
280 s = seprint(s, se, "dev %d ep %d ", di, ep->nb);
281 s = seprint(s, se, "%s", dsnames[ep->dev->state]);
282 s = seprint(s, se, " %s", ttname[ep->ttype]);
283 assert(ep->mode == OREAD || ep->mode == OWRITE || ep->mode == ORDWR);
284 s = seprint(s, se, " %s", usbmodename[ep->mode]);
285 s = seprint(s, se, " speed %s", spname[d->speed]);
286 s = seprint(s, se, " maxpkt %ld", ep->maxpkt);
287 s = seprint(s, se, " pollival %ld", ep->pollival);
288 s = seprint(s, se, " samplesz %ld", ep->samplesz);
289 s = seprint(s, se, " hz %ld", ep->hz);
290 s = seprint(s, se, " hub %d", ep->dev->hub);
291 s = seprint(s, se, " port %d", ep->dev->port);
292 if(ep->inuse)
293 s = seprint(s, se, " busy");
294 else
295 s = seprint(s, se, " idle");
296 if(all){
297 s = seprint(s, se, " load %uld", ep->load);
298 s = seprint(s, se, " ref %ld addr %#p", ep->ref, ep);
299 s = seprint(s, se, " idx %d", ep->idx);
300 if(ep->name != nil)
301 s = seprint(s, se, " name '%s'", ep->name);
302 if(ep->tmout != 0)
303 s = seprint(s, se, " tmout");
304 if(ep == ep->ep0){
305 s = seprint(s, se, " ctlrno %#x", ep->hp->ctlrno);
306 s = seprint(s, se, " eps:");
307 for(i = 0; i < nelem(d->eps); i++)
308 if(d->eps[i] != nil)
309 s = seprint(s, se, " ep%d.%d", di, i);
310 }
311 }
312 if(ep->info != nil)
313 s = seprint(s, se, "\n%s %s\n", ep->info, ep->hp->type);
314 else
315 s = seprint(s, se, "\n");
316 qunlock(ep);
317 poperror();
318 return s;
319 }
320
321 static Ep*
epalloc(Hci * hp)322 epalloc(Hci *hp)
323 {
324 Ep *ep;
325 int i;
326
327 ep = smalloc(sizeof(Ep));
328 ep->ref = 1;
329 qlock(&epslck);
330 for(i = 0; i < Neps; i++)
331 if(eps[i] == nil)
332 break;
333 if(i == Neps){
334 qunlock(&epslck);
335 free(ep);
336 print("usb: bug: too few endpoints.\n");
337 return nil;
338 }
339 ep->idx = i;
340 if(epmax <= i)
341 epmax = i+1;
342 eps[i] = ep;
343 ep->hp = hp;
344 ep->maxpkt = 8;
345 ep->ntds = 1;
346 ep->samplesz = ep->pollival = ep->hz = 0; /* make them void */
347 qunlock(&epslck);
348 return ep;
349 }
350
351 static Ep*
getep(int i)352 getep(int i)
353 {
354 Ep *ep;
355
356 if(i < 0 || i >= epmax || eps[i] == nil)
357 return nil;
358 qlock(&epslck);
359 ep = eps[i];
360 if(ep != nil)
361 incref(ep);
362 qunlock(&epslck);
363 return ep;
364 }
365
366 static void
putep(Ep * ep)367 putep(Ep *ep)
368 {
369 Udev *d;
370
371 if(ep != nil && decref(ep) == 0){
372 d = ep->dev;
373 deprint("usb: ep%d.%d %#p released\n", d->nb, ep->nb, ep);
374 qlock(&epslck);
375 eps[ep->idx] = nil;
376 if(ep->idx == epmax-1)
377 epmax--;
378 if(ep == ep->ep0 && ep->dev != nil && ep->dev->nb == usbidgen)
379 usbidgen--;
380 qunlock(&epslck);
381 if(d != nil){
382 qlock(ep->ep0);
383 d->eps[ep->nb] = nil;
384 qunlock(ep->ep0);
385 }
386 if(ep->ep0 != ep){
387 putep(ep->ep0);
388 ep->ep0 = nil;
389 }
390 free(ep->info);
391 free(ep->name);
392 free(ep);
393 }
394 }
395
396 static void
dumpeps(void)397 dumpeps(void)
398 {
399 int i;
400 static char buf[512];
401 char *s;
402 char *e;
403 Ep *ep;
404
405 print("usb dump eps: epmax %d Neps %d (ref=1+ for dump):\n", epmax, Neps);
406 for(i = 0; i < epmax; i++){
407 s = buf;
408 e = buf+sizeof(buf);
409 ep = getep(i);
410 if(ep != nil){
411 if(waserror()){
412 putep(ep);
413 nexterror();
414 }
415 s = seprint(s, e, "ep%d.%d ", ep->dev->nb, ep->nb);
416 seprintep(s, e, ep, 1);
417 print("%s", buf);
418 ep->hp->seprintep(buf, e, ep);
419 print("%s", buf);
420 poperror();
421 putep(ep);
422 }
423 }
424 print("usb dump hcis:\n");
425 for(i = 0; i < Nhcis; i++)
426 if(hcis[i] != nil)
427 hcis[i]->dump(hcis[i]);
428 }
429
430 static int
newusbid(Hci *)431 newusbid(Hci *)
432 {
433 int id;
434
435 qlock(&epslck);
436 id = ++usbidgen;
437 if(id >= 0x7F)
438 print("#u: too many device addresses; reuse them more\n");
439 qunlock(&epslck);
440 return id;
441 }
442
443 /*
444 * Create endpoint 0 for a new device
445 */
446 static Ep*
newdev(Hci * hp,int ishub,int isroot)447 newdev(Hci *hp, int ishub, int isroot)
448 {
449 Ep *ep;
450 Udev *d;
451
452 ep = epalloc(hp);
453 d = ep->dev = smalloc(sizeof(Udev));
454 d->nb = newusbid(hp);
455 d->eps[0] = ep;
456 ep->nb = 0;
457 ep->toggle[0] = ep->toggle[1] = 0;
458 d->ishub = ishub;
459 d->isroot = isroot;
460 if(hp->highspeed != 0)
461 d->speed = Highspeed;
462 else
463 d->speed = Fullspeed;
464 d->state = Dconfig; /* address not yet set */
465 ep->dev = d;
466 ep->ep0 = ep; /* no ref counted here */
467 ep->ttype = Tctl;
468 ep->tmout = Xfertmout;
469 ep->mode = ORDWR;
470 dprint("newdev %#p ep%d.%d %#p\n", d, d->nb, ep->nb, ep);
471 return ep;
472 }
473
474 /*
475 * Create a new endpoint for the device
476 * accessed via the given endpoint 0.
477 */
478 static Ep*
newdevep(Ep * ep,int i,int tt,int mode)479 newdevep(Ep *ep, int i, int tt, int mode)
480 {
481 Ep *nep;
482 Udev *d;
483
484 d = ep->dev;
485 if(d->eps[i] != nil)
486 error("endpoint already in use");
487 nep = epalloc(ep->hp);
488 incref(ep);
489 d->eps[i] = nep;
490 nep->nb = i;
491 nep->toggle[0] = nep->toggle[1] = 0;
492 nep->ep0 = ep;
493 nep->dev = ep->dev;
494 nep->mode = mode;
495 nep->ttype = tt;
496 nep->debug = ep->debug;
497 /* set defaults */
498 switch(tt){
499 case Tctl:
500 nep->tmout = Xfertmout;
501 break;
502 case Tintr:
503 nep->pollival = 10;
504 break;
505 case Tiso:
506 nep->tmout = Xfertmout;
507 nep->pollival = 10;
508 nep->samplesz = 4;
509 nep->hz = 44100;
510 break;
511 }
512 deprint("newdevep ep%d.%d %#p\n", d->nb, nep->nb, nep);
513 return ep;
514 }
515
516 static int
epdataperm(int mode)517 epdataperm(int mode)
518 {
519
520 switch(mode){
521 case OREAD:
522 return 0440|DMEXCL;
523 break;
524 case OWRITE:
525 return 0220|DMEXCL;
526 break;
527 default:
528 return 0660|DMEXCL;
529 }
530 }
531
532 static int
usbgen(Chan * c,char *,Dirtab *,int,int s,Dir * dp)533 usbgen(Chan *c, char *, Dirtab*, int, int s, Dir *dp)
534 {
535 Qid q;
536 Dirtab *dir;
537 int perm;
538 char *se;
539 Ep *ep;
540 int nb;
541 int mode;
542
543 if(0)ddprint("usbgen q %#x s %d...", QID(c->qid), s);
544 if(s == DEVDOTDOT){
545 if(QID(c->qid) <= Qusbdir){
546 mkqid(&q, Qdir, 0, QTDIR);
547 devdir(c, q, "#u", 0, eve, 0555, dp);
548 }else{
549 mkqid(&q, Qusbdir, 0, QTDIR);
550 devdir(c, q, "usb", 0, eve, 0555, dp);
551 }
552 if(0)ddprint("ok\n");
553 return 1;
554 }
555
556 switch(QID(c->qid)){
557 case Qdir: /* list #u */
558 if(s == 0){
559 mkqid(&q, Qusbdir, 0, QTDIR);
560 devdir(c, q, "usb", 0, eve, 0555, dp);
561 if(0)ddprint("ok\n");
562 return 1;
563 }
564 s--;
565 if(s < 0 || s >= epmax)
566 goto Fail;
567 ep = getep(s);
568 if(ep == nil || ep->name == nil){
569 if(ep != nil)
570 putep(ep);
571 if(0)ddprint("skip\n");
572 return 0;
573 }
574 if(waserror()){
575 putep(ep);
576 nexterror();
577 }
578 mkqid(&q, Qep0io+s*4, 0, QTFILE);
579 devdir(c, q, ep->name, 0, eve, epdataperm(ep->mode), dp);
580 putep(ep);
581 poperror();
582 if(0)ddprint("ok\n");
583 return 1;
584
585 case Qusbdir: /* list #u/usb */
586 Usbdir:
587 if(s < nelem(usbdir)){
588 dir = &usbdir[s];
589 mkqid(&q, dir->qid.path, 0, QTFILE);
590 devdir(c, q, dir->name, dir->length, eve, dir->perm, dp);
591 if(0)ddprint("ok\n");
592 return 1;
593 }
594 s -= nelem(usbdir);
595 if(s < 0 || s >= epmax)
596 goto Fail;
597 ep = getep(s);
598 if(ep == nil){
599 if(0)ddprint("skip\n");
600 return 0;
601 }
602 if(waserror()){
603 putep(ep);
604 nexterror();
605 }
606 se = up->genbuf+sizeof(up->genbuf);
607 seprint(up->genbuf, se, "ep%d.%d", ep->dev->nb, ep->nb);
608 mkqid(&q, Qep0dir+4*s, 0, QTDIR);
609 putep(ep);
610 poperror();
611 devdir(c, q, up->genbuf, 0, eve, 0755, dp);
612 if(0)ddprint("ok\n");
613 return 1;
614
615 case Qctl:
616 s = 0;
617 goto Usbdir;
618
619 default: /* list #u/usb/epN.M */
620 nb = qid2epidx(QID(c->qid));
621 ep = getep(nb);
622 if(ep == nil)
623 goto Fail;
624 mode = ep->mode;
625 putep(ep);
626 if(isqtype(QID(c->qid), Qepdir)){
627 Epdir:
628 switch(s){
629 case 0:
630 mkqid(&q, Qep0io+nb*4, 0, QTFILE);
631 perm = epdataperm(mode);
632 devdir(c, q, "data", 0, eve, perm, dp);
633 break;
634 case 1:
635 mkqid(&q, Qep0ctl+nb*4, 0, QTFILE);
636 devdir(c, q, "ctl", 0, eve, 0664, dp);
637 break;
638 default:
639 goto Fail;
640 }
641 }else if(isqtype(QID(c->qid), Qepctl)){
642 s = 1;
643 goto Epdir;
644 }else{
645 s = 0;
646 goto Epdir;
647 }
648 if(0)ddprint("ok\n");
649 return 1;
650 }
651 Fail:
652 if(0)ddprint("fail\n");
653 return -1;
654 }
655
656 static Hci*
hciprobe(int cardno,int ctlrno)657 hciprobe(int cardno, int ctlrno)
658 {
659 Hci *hp;
660 char *type;
661 char name[64];
662 static int epnb = 1; /* guess the endpoint nb. for the controller */
663
664 ddprint("hciprobe %d %d\n", cardno, ctlrno);
665 hp = smalloc(sizeof(Hci));
666 hp->ctlrno = ctlrno;
667
668 if(cardno < 0)
669 for(cardno = 0; cardno < Nhcis; cardno++){
670 if(hcitypes[cardno].type == nil)
671 break;
672 type = hp->type;
673 if(type==nil || *type==0)
674 type = "uhci";
675 if(cistrcmp(hcitypes[cardno].type, type) == 0)
676 break;
677 }
678
679 if(cardno >= Nhcis || hcitypes[cardno].type == nil){
680 free(hp);
681 return nil;
682 }
683 dprint("%s...", hcitypes[cardno].type);
684 if(hcitypes[cardno].reset(hp) < 0){
685 free(hp);
686 return nil;
687 }
688
689 snprint(name, sizeof(name), "usb%s", hcitypes[cardno].type);
690 intrenable(hp->irq, hp->interrupt, hp, UNKNOWN, name);
691
692 print("#u/usb/ep%d.0: %s: port %#luX irq %d\n",
693 epnb, hcitypes[cardno].type, hp->port, hp->irq);
694 epnb++;
695
696 return hp;
697 }
698
699 static void
usbreset(void)700 usbreset(void)
701 {
702 int cardno, ctlrno;
703 Hci *hp;
704
705 dprint("usbreset\n");
706
707 for(ctlrno = 0; ctlrno < Nhcis; ctlrno++)
708 if((hp = hciprobe(-1, ctlrno)) != nil)
709 hcis[ctlrno] = hp;
710 cardno = ctlrno = 0;
711 while(cardno < Nhcis && ctlrno < Nhcis && hcitypes[cardno].type != nil)
712 if(hcis[ctlrno] != nil)
713 ctlrno++;
714 else{
715 hp = hciprobe(cardno, ctlrno);
716 if(hp == nil)
717 cardno++;
718 hcis[ctlrno++] = hp;
719 }
720 if(hcis[Nhcis-1] != nil)
721 print("usbreset: bug: Nhcis too small\n");
722 }
723
724 static void
usbinit(void)725 usbinit(void)
726 {
727 Hci *hp;
728 int ctlrno;
729 Ep *d;
730 char info[40];
731
732 dprint("usbinit\n");
733 for(ctlrno = 0; ctlrno < Nhcis; ctlrno++){
734 hp = hcis[ctlrno];
735 if(hp != nil){
736 if(hp->init != nil)
737 hp->init(hp);
738 d = newdev(hp, 1, 1); /* new root hub */
739 d->dev->state = Denabled; /* although addr == 0 */
740 d->maxpkt = 64;
741 snprint(info, sizeof(info), "ports %d", hp->nports);
742 kstrdup(&d->info, info);
743 }
744 }
745 }
746
747 static Chan*
usbattach(char * spec)748 usbattach(char *spec)
749 {
750 return devattach(L'u', spec);
751 }
752
753 static Walkqid*
usbwalk(Chan * c,Chan * nc,char ** name,int nname)754 usbwalk(Chan *c, Chan *nc, char **name, int nname)
755 {
756 return devwalk(c, nc, name, nname, nil, 0, usbgen);
757 }
758
759 static int
usbstat(Chan * c,uchar * db,int n)760 usbstat(Chan *c, uchar *db, int n)
761 {
762 return devstat(c, db, n, nil, 0, usbgen);
763 }
764
765 /*
766 * µs for the given transfer, for bandwidth allocation.
767 * This is a very rough worst case for what 5.11.3
768 * of the usb 2.0 spec says.
769 * Also, we are using maxpkt and not actual transfer sizes.
770 * Only when we are sure we
771 * are not exceeding b/w might we consider adjusting it.
772 */
773 static ulong
usbload(int speed,int maxpkt)774 usbload(int speed, int maxpkt)
775 {
776 enum{ Hostns = 1000, Hubns = 333 };
777 ulong l;
778 ulong bs;
779
780 l = 0;
781 bs = 10UL * maxpkt;
782 switch(speed){
783 case Highspeed:
784 l = 55*8*2 + 2 * (3 + bs) + Hostns;
785 break;
786 case Fullspeed:
787 l = 9107 + 84 * (4 + bs) + Hostns;
788 break;
789 case Lowspeed:
790 l = 64107 + 2 * Hubns + 667 * (3 + bs) + Hostns;
791 break;
792 default:
793 print("usbload: bad speed %d\n", speed);
794 /* let it run */
795 }
796 return l / 1000UL; /* in µs */
797 }
798
799 static Chan*
usbopen(Chan * c,int omode)800 usbopen(Chan *c, int omode)
801 {
802 int q;
803 Ep *ep;
804 int mode;
805
806 mode = openmode(omode);
807 q = QID(c->qid);
808
809 if(q >= Qep0dir && qid2epidx(q) < 0)
810 error(Eio);
811 if(q < Qep0dir || isqtype(q, Qepctl) || isqtype(q, Qepdir))
812 return devopen(c, omode, nil, 0, usbgen);
813
814 ep = getep(qid2epidx(q));
815 if(ep == nil)
816 error(Eio);
817 deprint("usbopen q %#x fid %d omode %d\n", q, c->fid, mode);
818 if(waserror()){
819 putep(ep);
820 nexterror();
821 }
822 qlock(ep);
823 if(ep->inuse){
824 qunlock(ep);
825 error(Einuse);
826 }
827 ep->inuse = 1;
828 qunlock(ep);
829 if(waserror()){
830 ep->inuse = 0;
831 nexterror();
832 }
833 if(mode != OREAD && ep->mode == OREAD)
834 error(Eperm);
835 if(mode != OWRITE && ep->mode == OWRITE)
836 error(Eperm);
837 if(ep->ttype == Tnone)
838 error(Enotconf);
839 ep->clrhalt = 0;
840 ep->rhrepl = -1;
841 if(ep->load == 0)
842 ep->load = usbload(ep->dev->speed, ep->maxpkt);
843 ep->hp->epopen(ep);
844
845 poperror(); /* ep->inuse */
846 poperror(); /* don't putep(): ref kept for fid using the ep. */
847
848 c->mode = mode;
849 c->flag |= COPEN;
850 c->offset = 0;
851 c->aux = nil; /* paranoia */
852 return c;
853 }
854
855 static void
epclose(Ep * ep)856 epclose(Ep *ep)
857 {
858 qlock(ep);
859 if(waserror()){
860 qunlock(ep);
861 nexterror();
862 }
863 if(ep->inuse){
864 ep->hp->epclose(ep);
865 ep->inuse = 0;
866 }
867 qunlock(ep);
868 poperror();
869 }
870
871 static void
usbclose(Chan * c)872 usbclose(Chan *c)
873 {
874 int q;
875 Ep *ep;
876
877 q = QID(c->qid);
878 if(q < Qep0dir || isqtype(q, Qepctl) || isqtype(q, Qepdir))
879 return;
880
881 ep = getep(qid2epidx(q));
882 if(ep == nil)
883 return;
884 deprint("usbclose q %#x fid %d ref %ld\n", q, c->fid, ep->ref);
885 if(waserror()){
886 putep(ep);
887 nexterror();
888 }
889 if(c->flag & COPEN){
890 free(c->aux);
891 c->aux = nil;
892 epclose(ep);
893 putep(ep); /* release ref kept since usbopen */
894 c->flag &= ~COPEN;
895 }
896 poperror();
897 putep(ep);
898 }
899
900 static long
ctlread(Chan * c,void * a,long n,vlong offset)901 ctlread(Chan *c, void *a, long n, vlong offset)
902 {
903 int q;
904 char *s;
905 char *us;
906 char *se;
907 Ep *ep;
908 int i;
909
910 q = QID(c->qid);
911 us = s = smalloc(READSTR);
912 se = s + READSTR;
913 if(waserror()){
914 free(us);
915 nexterror();
916 }
917 if(q == Qctl)
918 for(i = 0; i < epmax; i++){
919 ep = getep(i);
920 if(ep != nil){
921 if(waserror()){
922 putep(ep);
923 nexterror();
924 }
925 s = seprint(s, se, "ep%d.%d ", ep->dev->nb, ep->nb);
926 s = seprintep(s, se, ep, 0);
927 poperror();
928 }
929 putep(ep);
930 }
931 else{
932 ep = getep(qid2epidx(q));
933 if(ep == nil)
934 error(Eio);
935 if(waserror()){
936 putep(ep);
937 nexterror();
938 }
939 if(c->aux != nil){
940 /* After a new endpoint request we read
941 * the new endpoint name back.
942 */
943 strecpy(s, se, c->aux);
944 free(c->aux);
945 c->aux = nil;
946 }else
947 seprintep(s, se, ep, 0);
948 poperror();
949 putep(ep);
950 }
951 n = readstr(offset, a, n, us);
952 poperror();
953 free(us);
954 return n;
955 }
956
957 /*
958 * Fake root hub emulation.
959 */
960 static long
rhubread(Ep * ep,void * a,long n)961 rhubread(Ep *ep, void *a, long n)
962 {
963 char *b;
964
965 if(ep->dev->isroot == 0 || ep->nb != 0 || n < 2)
966 return -1;
967 if(ep->rhrepl < 0)
968 return -1;
969
970 b = a;
971 memset(b, 0, n);
972 PUT2(b, ep->rhrepl);
973 ep->rhrepl = -1;
974 return n;
975 }
976
977 static long
rhubwrite(Ep * ep,void * a,long n)978 rhubwrite(Ep *ep, void *a, long n)
979 {
980 uchar *s;
981 int cmd;
982 int feature;
983 int port;
984 Hci *hp;
985
986 if(ep->dev == nil || ep->dev->isroot == 0 || ep->nb != 0)
987 return -1;
988 if(n != Rsetuplen)
989 error("root hub is a toy hub");
990 ep->rhrepl = -1;
991 s = a;
992 if(s[Rtype] != (Rh2d|Rclass|Rother) && s[Rtype] != (Rd2h|Rclass|Rother))
993 error("root hub is a toy hub");
994 hp = ep->hp;
995 cmd = s[Rreq];
996 feature = GET2(s+Rvalue);
997 port = GET2(s+Rindex);
998 if(port < 1 || port > hp->nports)
999 error("bad hub port number");
1000 switch(feature){
1001 case Rportenable:
1002 ep->rhrepl = hp->portenable(hp, port, cmd == Rsetfeature);
1003 break;
1004 case Rportreset:
1005 ep->rhrepl = hp->portreset(hp, port, cmd == Rsetfeature);
1006 break;
1007 case Rgetstatus:
1008 ep->rhrepl = hp->portstatus(hp, port);
1009 break;
1010 default:
1011 ep->rhrepl = 0;
1012 }
1013 return n;
1014 }
1015
1016 static long
usbread(Chan * c,void * a,long n,vlong offset)1017 usbread(Chan *c, void *a, long n, vlong offset)
1018 {
1019 int q;
1020 Ep *ep;
1021 int nr;
1022
1023 q = QID(c->qid);
1024
1025 if(c->qid.type == QTDIR)
1026 return devdirread(c, a, n, nil, 0, usbgen);
1027
1028 if(q == Qctl || isqtype(q, Qepctl))
1029 return ctlread(c, a, n, offset);
1030
1031 ep = getep(qid2epidx(q));
1032 if(ep == nil)
1033 error(Eio);
1034 if(waserror()){
1035 putep(ep);
1036 nexterror();
1037 }
1038 if(ep->dev->state == Ddetach)
1039 error(Edetach);
1040 if(ep->mode == OWRITE || ep->inuse == 0)
1041 error(Ebadusefd);
1042 switch(ep->ttype){
1043 case Tnone:
1044 error("endpoint not configured");
1045 case Tctl:
1046 nr = rhubread(ep, a, n);
1047 if(nr >= 0){
1048 n = nr;
1049 break;
1050 }
1051 /* else fall */
1052 default:
1053 ddeprint("\nusbread q %#x fid %d cnt %ld off %lld\n",q,c->fid,n,offset);
1054 n = ep->hp->epread(ep, a, n);
1055 break;
1056 }
1057 poperror();
1058 putep(ep);
1059 return n;
1060 }
1061
1062 static long
pow2(int n)1063 pow2(int n)
1064 {
1065 return 1 << n;
1066 }
1067
1068 static void
setmaxpkt(Ep * ep,char * s)1069 setmaxpkt(Ep *ep, char* s)
1070 {
1071 long spp; /* samples per packet */
1072
1073 if(ep->dev->speed == Highspeed)
1074 spp = (ep->hz * ep->pollival * ep->ntds + 7999) / 8000;
1075 else
1076 spp = (ep->hz * ep->pollival + 999) / 1000;
1077 ep->maxpkt = spp * ep->samplesz;
1078 deprint("usb: %s: setmaxpkt: hz %ld poll %ld"
1079 " ntds %d %s speed -> spp %ld maxpkt %ld\n", s,
1080 ep->hz, ep->pollival, ep->ntds, spname[ep->dev->speed],
1081 spp, ep->maxpkt);
1082 if(ep->maxpkt > 1024){
1083 print("usb: %s: maxpkt %ld > 1024. truncating\n", s, ep->maxpkt);
1084 ep->maxpkt = 1024;
1085 }
1086 }
1087
1088 /*
1089 * Many endpoint ctls. simply update the portable representation
1090 * of the endpoint. The actual controller driver will look
1091 * at them to setup the endpoints as dictated.
1092 */
1093 static long
epctl(Ep * ep,Chan * c,void * a,long n)1094 epctl(Ep *ep, Chan *c, void *a, long n)
1095 {
1096 int i, l, mode, nb, tt;
1097 char *b, *s;
1098 Cmdbuf *cb;
1099 Cmdtab *ct;
1100 Ep *nep;
1101 Udev *d;
1102 static char *Info = "info ";
1103
1104 d = ep->dev;
1105
1106 cb = parsecmd(a, n);
1107 if(waserror()){
1108 free(cb);
1109 nexterror();
1110 }
1111 ct = lookupcmd(cb, epctls, nelem(epctls));
1112 if(ct == nil)
1113 error(Ebadctl);
1114 i = ct->index;
1115 if(i == CMnew || i == CMspeed || i == CMhub || i == CMpreset)
1116 if(ep != ep->ep0)
1117 error("allowed only on a setup endpoint");
1118 if(i != CMclrhalt && i != CMdetach && i != CMdebugep && i != CMname)
1119 if(ep != ep->ep0 && ep->inuse != 0)
1120 error("must configure before using");
1121 switch(i){
1122 case CMnew:
1123 deprint("usb epctl %s\n", cb->f[0]);
1124 nb = strtol(cb->f[1], nil, 0);
1125 if(nb < 0 || nb >= Ndeveps)
1126 error("bad endpoint number");
1127 tt = name2ttype(cb->f[2]);
1128 if(tt == Tnone)
1129 error("unknown endpoint type");
1130 mode = name2mode(cb->f[3]);
1131 if(mode < 0)
1132 error("unknown i/o mode");
1133 newdevep(ep, nb, tt, mode);
1134 break;
1135 case CMnewdev:
1136 deprint("usb epctl %s\n", cb->f[0]);
1137 if(ep != ep->ep0 || d->ishub == 0)
1138 error("not a hub setup endpoint");
1139 l = name2speed(cb->f[1]);
1140 if(l == Nospeed)
1141 error("speed must be full|low|high");
1142 nep = newdev(ep->hp, 0, 0);
1143 nep->dev->speed = l;
1144 if(nep->dev->speed != Lowspeed)
1145 nep->maxpkt = 64; /* assume full speed */
1146 nep->dev->hub = d->nb;
1147 nep->dev->port = atoi(cb->f[2]);
1148 /* next read request will read
1149 * the name for the new endpoint
1150 */
1151 l = sizeof(up->genbuf);
1152 snprint(up->genbuf, l, "ep%d.%d", nep->dev->nb, nep->nb);
1153 kstrdup(&c->aux, up->genbuf);
1154 break;
1155 case CMhub:
1156 deprint("usb epctl %s\n", cb->f[0]);
1157 d->ishub = 1;
1158 break;
1159 case CMspeed:
1160 l = name2speed(cb->f[1]);
1161 deprint("usb epctl %s %d\n", cb->f[0], l);
1162 if(l == Nospeed)
1163 error("speed must be full|low|high");
1164 qlock(ep->ep0);
1165 d->speed = l;
1166 qunlock(ep->ep0);
1167 break;
1168 case CMmaxpkt:
1169 l = strtoul(cb->f[1], nil, 0);
1170 deprint("usb epctl %s %d\n", cb->f[0], l);
1171 if(l < 1 || l > 1024)
1172 error("maxpkt not in [1:1024]");
1173 qlock(ep);
1174 ep->maxpkt = l;
1175 qunlock(ep);
1176 break;
1177 case CMntds:
1178 l = strtoul(cb->f[1], nil, 0);
1179 deprint("usb epctl %s %d\n", cb->f[0], l);
1180 if(l < 1 || l > 3)
1181 error("ntds not in [1:3]");
1182 qlock(ep);
1183 ep->ntds = l;
1184 qunlock(ep);
1185 break;
1186 case CMpollival:
1187 if(ep->ttype != Tintr && ep->ttype != Tiso)
1188 error("not an intr or iso endpoint");
1189 l = strtoul(cb->f[1], nil, 0);
1190 deprint("usb epctl %s %d\n", cb->f[0], l);
1191 if(ep->ttype == Tiso ||
1192 (ep->ttype == Tintr && ep->dev->speed == Highspeed)){
1193 if(l < 1 || l > 16)
1194 error("pollival power not in [1:16]");
1195 l = pow2(l-1);
1196 }else
1197 if(l < 1 || l > 255)
1198 error("pollival not in [1:255]");
1199 qlock(ep);
1200 ep->pollival = l;
1201 if(ep->ttype == Tiso)
1202 setmaxpkt(ep, "pollival");
1203 qunlock(ep);
1204 break;
1205 case CMsamplesz:
1206 if(ep->ttype != Tiso)
1207 error("not an iso endpoint");
1208 l = strtoul(cb->f[1], nil, 0);
1209 deprint("usb epctl %s %d\n", cb->f[0], l);
1210 if(l <= 0 || l > 8)
1211 error("samplesz not in [1:8]");
1212 qlock(ep);
1213 ep->samplesz = l;
1214 setmaxpkt(ep, "samplesz");
1215 qunlock(ep);
1216 break;
1217 case CMhz:
1218 if(ep->ttype != Tiso)
1219 error("not an iso endpoint");
1220 l = strtoul(cb->f[1], nil, 0);
1221 deprint("usb epctl %s %d\n", cb->f[0], l);
1222 if(l <= 0 || l > 100000)
1223 error("hz not in [1:100000]");
1224 qlock(ep);
1225 ep->hz = l;
1226 setmaxpkt(ep, "hz");
1227 qunlock(ep);
1228 break;
1229 case CMclrhalt:
1230 qlock(ep);
1231 deprint("usb epctl %s\n", cb->f[0]);
1232 ep->clrhalt = 1;
1233 qunlock(ep);
1234 break;
1235 case CMinfo:
1236 deprint("usb epctl %s\n", cb->f[0]);
1237 l = strlen(Info);
1238 s = a;
1239 if(n < l+2 || strncmp(Info, s, l) != 0)
1240 error(Ebadctl);
1241 if(n > 1024)
1242 n = 1024;
1243 b = smalloc(n);
1244 memmove(b, s+l, n-l);
1245 b[n-l] = 0;
1246 if(b[n-l-1] == '\n')
1247 b[n-l-1] = 0;
1248 qlock(ep);
1249 free(ep->info);
1250 ep->info = b;
1251 qunlock(ep);
1252 break;
1253 case CMaddress:
1254 deprint("usb epctl %s\n", cb->f[0]);
1255 ep->dev->state = Denabled;
1256 break;
1257 case CMdetach:
1258 if(ep->dev->isroot != 0)
1259 error("can't detach a root hub");
1260 deprint("usb epctl %s ep%d.%d\n",
1261 cb->f[0], ep->dev->nb, ep->nb);
1262 ep->dev->state = Ddetach;
1263 /* Release file system ref. for its endpoints */
1264 for(i = 0; i < nelem(ep->dev->eps); i++)
1265 putep(ep->dev->eps[i]);
1266 break;
1267 case CMdebugep:
1268 if(strcmp(cb->f[1], "on") == 0)
1269 ep->debug = 1;
1270 else if(strcmp(cb->f[1], "off") == 0)
1271 ep->debug = 0;
1272 else
1273 ep->debug = strtoul(cb->f[1], nil, 0);
1274 print("usb: ep%d.%d debug %d\n",
1275 ep->dev->nb, ep->nb, ep->debug);
1276 break;
1277 case CMname:
1278 deprint("usb epctl %s %s\n", cb->f[0], cb->f[1]);
1279 validname(cb->f[1], 0);
1280 kstrdup(&ep->name, cb->f[1]);
1281 break;
1282 case CMtmout:
1283 deprint("usb epctl %s\n", cb->f[0]);
1284 if(ep->ttype == Tiso || ep->ttype == Tctl)
1285 error("ctl ignored for this endpoint type");
1286 ep->tmout = strtoul(cb->f[1], nil, 0);
1287 if(ep->tmout != 0 && ep->tmout < Xfertmout)
1288 ep->tmout = Xfertmout;
1289 break;
1290 case CMpreset:
1291 deprint("usb epctl %s\n", cb->f[0]);
1292 if(ep->ttype != Tctl)
1293 error("not a control endpoint");
1294 if(ep->dev->state != Denabled)
1295 error("forbidden on devices not enabled");
1296 ep->dev->state = Dreset;
1297 break;
1298 default:
1299 panic("usb: unknown epctl %d", ct->index);
1300 }
1301 free(cb);
1302 poperror();
1303 return n;
1304 }
1305
1306 static long
usbctl(void * a,long n)1307 usbctl(void *a, long n)
1308 {
1309 Cmdtab *ct;
1310 Cmdbuf *cb;
1311 Ep *ep;
1312 int i;
1313
1314 cb = parsecmd(a, n);
1315 if(waserror()){
1316 free(cb);
1317 nexterror();
1318 }
1319 ct = lookupcmd(cb, usbctls, nelem(usbctls));
1320 dprint("usb ctl %s\n", cb->f[0]);
1321 switch(ct->index){
1322 case CMdebug:
1323 if(strcmp(cb->f[1], "on") == 0)
1324 debug = 1;
1325 else if(strcmp(cb->f[1], "off") == 0)
1326 debug = 0;
1327 else
1328 debug = strtol(cb->f[1], nil, 0);
1329 print("usb: debug %d\n", debug);
1330 for(i = 0; i < epmax; i++)
1331 if((ep = getep(i)) != nil){
1332 ep->hp->debug(ep->hp, debug);
1333 putep(ep);
1334 }
1335 break;
1336 case CMdump:
1337 dumpeps();
1338 break;
1339 }
1340 free(cb);
1341 poperror();
1342 return n;
1343 }
1344
1345 static long
ctlwrite(Chan * c,void * a,long n)1346 ctlwrite(Chan *c, void *a, long n)
1347 {
1348 int q;
1349 Ep *ep;
1350
1351 q = QID(c->qid);
1352 if(q == Qctl)
1353 return usbctl(a, n);
1354
1355 ep = getep(qid2epidx(q));
1356 if(ep == nil)
1357 error(Eio);
1358 if(waserror()){
1359 putep(ep);
1360 nexterror();
1361 }
1362 if(ep->dev->state == Ddetach)
1363 error(Edetach);
1364 if(isqtype(q, Qepctl) && c->aux != nil){
1365 /* Be sure we don't keep a cloned ep name */
1366 free(c->aux);
1367 c->aux = nil;
1368 error("read, not write, expected");
1369 }
1370 n = epctl(ep, c, a, n);
1371 putep(ep);
1372 poperror();
1373 return n;
1374 }
1375
1376 static long
usbwrite(Chan * c,void * a,long n,vlong off)1377 usbwrite(Chan *c, void *a, long n, vlong off)
1378 {
1379 int nr, q;
1380 Ep *ep;
1381
1382 if(c->qid.type == QTDIR)
1383 error(Eisdir);
1384
1385 q = QID(c->qid);
1386
1387 if(q == Qctl || isqtype(q, Qepctl))
1388 return ctlwrite(c, a, n);
1389
1390 ep = getep(qid2epidx(q));
1391 if(ep == nil)
1392 error(Eio);
1393 if(waserror()){
1394 putep(ep);
1395 nexterror();
1396 }
1397 if(ep->dev->state == Ddetach)
1398 error(Edetach);
1399 if(ep->mode == OREAD || ep->inuse == 0)
1400 error(Ebadusefd);
1401
1402 switch(ep->ttype){
1403 case Tnone:
1404 error("endpoint not configured");
1405 case Tctl:
1406 nr = rhubwrite(ep, a, n);
1407 if(nr >= 0){
1408 n = nr;
1409 break;
1410 }
1411 /* else fall */
1412 default:
1413 ddeprint("\nusbwrite q %#x fid %d cnt %ld off %lld\n",q, c->fid, n, off);
1414 ep->hp->epwrite(ep, a, n);
1415 }
1416 putep(ep);
1417 poperror();
1418 return n;
1419 }
1420
1421 Block*
usbbread(Chan * c,long n,ulong offset)1422 usbbread(Chan *c, long n, ulong offset)
1423 {
1424 Block *bp;
1425
1426 bp = allocb(n);
1427 if(bp == 0)
1428 error(Enomem);
1429 if(waserror()) {
1430 freeb(bp);
1431 nexterror();
1432 }
1433 bp->wp += usbread(c, bp->wp, n, offset);
1434 poperror();
1435 return bp;
1436 }
1437
1438 long
usbbwrite(Chan * c,Block * bp,ulong offset)1439 usbbwrite(Chan *c, Block *bp, ulong offset)
1440 {
1441 long n;
1442
1443 if(waserror()) {
1444 freeb(bp);
1445 nexterror();
1446 }
1447 n = usbwrite(c, bp->rp, BLEN(bp), offset);
1448 poperror();
1449 freeb(bp);
1450
1451 return n;
1452 }
1453
1454 void
usbshutdown(void)1455 usbshutdown(void)
1456 {
1457 Hci *hp;
1458 int i;
1459
1460 for(i = 0; i < Nhcis; i++){
1461 hp = hcis[i];
1462 if(hp == nil)
1463 continue;
1464 if(hp->shutdown == nil)
1465 print("#u: no shutdown function for %s\n", hp->type);
1466 else
1467 hp->shutdown(hp);
1468 }
1469 }
1470
1471 Dev usbdevtab = {
1472 L'u',
1473 "usb",
1474
1475 usbreset,
1476 usbinit,
1477 usbshutdown,
1478 usbattach,
1479 usbwalk,
1480 usbstat,
1481 usbopen,
1482 devcreate,
1483 usbclose,
1484 usbread,
1485 usbbread,
1486 usbwrite,
1487 usbbwrite,
1488 devremove,
1489 devwstat,
1490 };
1491