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 hp->tbdf = BUSUNKNOWN;
668
669 if(cardno < 0)
670 for(cardno = 0; cardno < Nhcis; cardno++){
671 if(hcitypes[cardno].type == nil)
672 break;
673 type = hp->type;
674 if(type==nil || *type==0)
675 type = "uhci";
676 if(cistrcmp(hcitypes[cardno].type, type) == 0)
677 break;
678 }
679
680 if(cardno >= Nhcis || hcitypes[cardno].type == nil){
681 free(hp);
682 return nil;
683 }
684 dprint("%s...", hcitypes[cardno].type);
685 if(hcitypes[cardno].reset(hp) < 0){
686 free(hp);
687 return nil;
688 }
689
690 snprint(name, sizeof(name), "usb%s", hcitypes[cardno].type);
691 intrenable(Irqlo, hp->irq, hp->interrupt, hp, name);
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 return hp;
696 }
697
698 static void
usbreset(void)699 usbreset(void)
700 {
701 int cardno, ctlrno;
702 Hci *hp;
703
704 dprint("usbreset\n");
705
706 for(ctlrno = 0; ctlrno < Nhcis; ctlrno++)
707 if((hp = hciprobe(-1, ctlrno)) != nil)
708 hcis[ctlrno] = hp;
709 cardno = ctlrno = 0;
710 while(cardno < Nhcis && ctlrno < Nhcis && hcitypes[cardno].type != nil)
711 if(hcis[ctlrno] != nil)
712 ctlrno++;
713 else{
714 hp = hciprobe(cardno, ctlrno);
715 if(hp == nil)
716 cardno++;
717 hcis[ctlrno++] = hp;
718 }
719 if(hcis[Nhcis-1] != nil)
720 print("usbreset: bug: Nhcis too small\n");
721 }
722
723 static void
usbinit(void)724 usbinit(void)
725 {
726 Hci *hp;
727 int ctlrno;
728 Ep *d;
729 char info[40];
730
731 dprint("usbinit\n");
732 for(ctlrno = 0; ctlrno < Nhcis; ctlrno++){
733 hp = hcis[ctlrno];
734 if(hp != nil){
735 if(hp->init != nil)
736 hp->init(hp);
737 d = newdev(hp, 1, 1); /* new root hub */
738 d->dev->state = Denabled; /* although addr == 0 */
739 d->maxpkt = 64;
740 snprint(info, sizeof(info), "ports %d", hp->nports);
741 kstrdup(&d->info, info);
742 }
743 }
744 }
745
746 static Chan*
usbattach(char * spec)747 usbattach(char *spec)
748 {
749 return devattach(L'u', spec);
750 }
751
752 static Walkqid*
usbwalk(Chan * c,Chan * nc,char ** name,int nname)753 usbwalk(Chan *c, Chan *nc, char **name, int nname)
754 {
755 return devwalk(c, nc, name, nname, nil, 0, usbgen);
756 }
757
758 static int
usbstat(Chan * c,uchar * db,int n)759 usbstat(Chan *c, uchar *db, int n)
760 {
761 return devstat(c, db, n, nil, 0, usbgen);
762 }
763
764 /*
765 * µs for the given transfer, for bandwidth allocation.
766 * This is a very rough worst case for what 5.11.3
767 * of the usb 2.0 spec says.
768 * Also, we are using maxpkt and not actual transfer sizes.
769 * Only when we are sure we
770 * are not exceeding b/w might we consider adjusting it.
771 */
772 static ulong
usbload(int speed,int maxpkt)773 usbload(int speed, int maxpkt)
774 {
775 enum{ Hostns = 1000, Hubns = 333 };
776 ulong l;
777 ulong bs;
778
779 l = 0;
780 bs = 10UL * maxpkt;
781 switch(speed){
782 case Highspeed:
783 l = 55*8*2 + 2 * (3 + bs) + Hostns;
784 break;
785 case Fullspeed:
786 l = 9107 + 84 * (4 + bs) + Hostns;
787 break;
788 case Lowspeed:
789 l = 64107 + 2 * Hubns + 667 * (3 + bs) + Hostns;
790 break;
791 default:
792 print("usbload: bad speed %d\n", speed);
793 /* let it run */
794 }
795 return l / 1000UL; /* in µs */
796 }
797
798 static Chan*
usbopen(Chan * c,int omode)799 usbopen(Chan *c, int omode)
800 {
801 int q;
802 Ep *ep;
803 int mode;
804
805 mode = openmode(omode);
806 q = QID(c->qid);
807
808 if(q >= Qep0dir && qid2epidx(q) < 0)
809 error(Eio);
810 if(q < Qep0dir || isqtype(q, Qepctl) || isqtype(q, Qepdir))
811 return devopen(c, omode, nil, 0, usbgen);
812
813 ep = getep(qid2epidx(q));
814 if(ep == nil)
815 error(Eio);
816 deprint("usbopen q %#x fid %d omode %d\n", q, c->fid, mode);
817 if(waserror()){
818 putep(ep);
819 nexterror();
820 }
821 qlock(ep);
822 if(ep->inuse){
823 qunlock(ep);
824 error(Einuse);
825 }
826 ep->inuse = 1;
827 qunlock(ep);
828 if(waserror()){
829 ep->inuse = 0;
830 nexterror();
831 }
832 if(mode != OREAD && ep->mode == OREAD)
833 error(Eperm);
834 if(mode != OWRITE && ep->mode == OWRITE)
835 error(Eperm);
836 if(ep->ttype == Tnone)
837 error(Enotconf);
838 ep->clrhalt = 0;
839 ep->rhrepl = -1;
840 if(ep->load == 0)
841 ep->load = usbload(ep->dev->speed, ep->maxpkt);
842 ep->hp->epopen(ep);
843
844 poperror(); /* ep->inuse */
845 poperror(); /* don't putep(): ref kept for fid using the ep. */
846
847 c->mode = mode;
848 c->flag |= COPEN;
849 c->offset = 0;
850 c->aux = nil; /* paranoia */
851 return c;
852 }
853
854 static void
epclose(Ep * ep)855 epclose(Ep *ep)
856 {
857 qlock(ep);
858 if(waserror()){
859 qunlock(ep);
860 nexterror();
861 }
862 if(ep->inuse){
863 ep->hp->epclose(ep);
864 ep->inuse = 0;
865 }
866 qunlock(ep);
867 poperror();
868 }
869
870 static void
usbclose(Chan * c)871 usbclose(Chan *c)
872 {
873 int q;
874 Ep *ep;
875
876 q = QID(c->qid);
877 if(q < Qep0dir || isqtype(q, Qepctl) || isqtype(q, Qepdir))
878 return;
879
880 ep = getep(qid2epidx(q));
881 if(ep == nil)
882 return;
883 deprint("usbclose q %#x fid %d ref %ld\n", q, c->fid, ep->ref);
884 if(waserror()){
885 putep(ep);
886 nexterror();
887 }
888 if(c->flag & COPEN){
889 free(c->aux);
890 c->aux = nil;
891 epclose(ep);
892 putep(ep); /* release ref kept since usbopen */
893 c->flag &= ~COPEN;
894 }
895 poperror();
896 putep(ep);
897 }
898
899 static long
ctlread(Chan * c,void * a,long n,vlong offset)900 ctlread(Chan *c, void *a, long n, vlong offset)
901 {
902 int q;
903 char *s;
904 char *us;
905 char *se;
906 Ep *ep;
907 int i;
908
909 q = QID(c->qid);
910 us = s = smalloc(READSTR);
911 se = s + READSTR;
912 if(waserror()){
913 free(us);
914 nexterror();
915 }
916 if(q == Qctl)
917 for(i = 0; i < epmax; i++){
918 ep = getep(i);
919 if(ep != nil){
920 if(waserror()){
921 putep(ep);
922 nexterror();
923 }
924 s = seprint(s, se, "ep%d.%d ", ep->dev->nb, ep->nb);
925 s = seprintep(s, se, ep, 0);
926 poperror();
927 }
928 putep(ep);
929 }
930 else{
931 ep = getep(qid2epidx(q));
932 if(ep == nil)
933 error(Eio);
934 if(waserror()){
935 putep(ep);
936 nexterror();
937 }
938 if(c->aux != nil){
939 /* After a new endpoint request we read
940 * the new endpoint name back.
941 */
942 strecpy(s, se, c->aux);
943 free(c->aux);
944 c->aux = nil;
945 }else
946 seprintep(s, se, ep, 0);
947 poperror();
948 putep(ep);
949 }
950 n = readstr(offset, a, n, us);
951 poperror();
952 free(us);
953 return n;
954 }
955
956 /*
957 * Fake root hub emulation.
958 */
959 static long
rhubread(Ep * ep,void * a,long n)960 rhubread(Ep *ep, void *a, long n)
961 {
962 char *b;
963
964 if(ep->dev->isroot == 0 || ep->nb != 0 || n < 2)
965 return -1;
966 if(ep->rhrepl < 0)
967 return -1;
968
969 b = a;
970 memset(b, 0, n);
971 PUT2(b, ep->rhrepl);
972 ep->rhrepl = -1;
973 return n;
974 }
975
976 static long
rhubwrite(Ep * ep,void * a,long n)977 rhubwrite(Ep *ep, void *a, long n)
978 {
979 uchar *s;
980 int cmd;
981 int feature;
982 int port;
983 Hci *hp;
984
985 if(ep->dev == nil || ep->dev->isroot == 0 || ep->nb != 0)
986 return -1;
987 if(n != Rsetuplen)
988 error("root hub is a toy hub");
989 ep->rhrepl = -1;
990 s = a;
991 if(s[Rtype] != (Rh2d|Rclass|Rother) && s[Rtype] != (Rd2h|Rclass|Rother))
992 error("root hub is a toy hub");
993 hp = ep->hp;
994 cmd = s[Rreq];
995 feature = GET2(s+Rvalue);
996 port = GET2(s+Rindex);
997 if(port < 1 || port > hp->nports)
998 error("bad hub port number");
999 switch(feature){
1000 case Rportenable:
1001 ep->rhrepl = hp->portenable(hp, port, cmd == Rsetfeature);
1002 break;
1003 case Rportreset:
1004 ep->rhrepl = hp->portreset(hp, port, cmd == Rsetfeature);
1005 break;
1006 case Rgetstatus:
1007 ep->rhrepl = hp->portstatus(hp, port);
1008 break;
1009 default:
1010 ep->rhrepl = 0;
1011 }
1012 return n;
1013 }
1014
1015 static long
usbread(Chan * c,void * a,long n,vlong offset)1016 usbread(Chan *c, void *a, long n, vlong offset)
1017 {
1018 int q;
1019 Ep *ep;
1020 int nr;
1021
1022 q = QID(c->qid);
1023
1024 if(c->qid.type == QTDIR)
1025 return devdirread(c, a, n, nil, 0, usbgen);
1026
1027 if(q == Qctl || isqtype(q, Qepctl))
1028 return ctlread(c, a, n, offset);
1029
1030 ep = getep(qid2epidx(q));
1031 if(ep == nil)
1032 error(Eio);
1033 if(waserror()){
1034 putep(ep);
1035 nexterror();
1036 }
1037 if(ep->dev->state == Ddetach)
1038 error(Edetach);
1039 if(ep->mode == OWRITE || ep->inuse == 0)
1040 error(Ebadusefd);
1041 switch(ep->ttype){
1042 case Tnone:
1043 error("endpoint not configured");
1044 case Tctl:
1045 nr = rhubread(ep, a, n);
1046 if(nr >= 0){
1047 n = nr;
1048 break;
1049 }
1050 /* else fall */
1051 default:
1052 ddeprint("\nusbread q %#x fid %d cnt %ld off %lld\n",q,c->fid,n,offset);
1053 n = ep->hp->epread(ep, a, n);
1054 break;
1055 }
1056 poperror();
1057 putep(ep);
1058 return n;
1059 }
1060
1061 static long
pow2(int n)1062 pow2(int n)
1063 {
1064 return 1 << n;
1065 }
1066
1067 static void
setmaxpkt(Ep * ep,char * s)1068 setmaxpkt(Ep *ep, char* s)
1069 {
1070 long spp; /* samples per packet */
1071
1072 if(ep->dev->speed == Highspeed)
1073 spp = (ep->hz * ep->pollival * ep->ntds + 7999) / 8000;
1074 else
1075 spp = (ep->hz * ep->pollival + 999) / 1000;
1076 ep->maxpkt = spp * ep->samplesz;
1077 deprint("usb: %s: setmaxpkt: hz %ld poll %ld"
1078 " ntds %d %s speed -> spp %ld maxpkt %ld\n", s,
1079 ep->hz, ep->pollival, ep->ntds, spname[ep->dev->speed],
1080 spp, ep->maxpkt);
1081 if(ep->maxpkt > 1024){
1082 print("usb: %s: maxpkt %ld > 1024. truncating\n", s, ep->maxpkt);
1083 ep->maxpkt = 1024;
1084 }
1085 }
1086
1087 /*
1088 * Many endpoint ctls. simply update the portable representation
1089 * of the endpoint. The actual controller driver will look
1090 * at them to setup the endpoints as dictated.
1091 */
1092 static long
epctl(Ep * ep,Chan * c,void * a,long n)1093 epctl(Ep *ep, Chan *c, void *a, long n)
1094 {
1095 int i, l, mode, nb, tt;
1096 char *b, *s;
1097 Cmdbuf *cb;
1098 Cmdtab *ct;
1099 Ep *nep;
1100 Udev *d;
1101 static char *Info = "info ";
1102
1103 d = ep->dev;
1104
1105 cb = parsecmd(a, n);
1106 if(waserror()){
1107 free(cb);
1108 nexterror();
1109 }
1110 ct = lookupcmd(cb, epctls, nelem(epctls));
1111 if(ct == nil)
1112 error(Ebadctl);
1113 i = ct->index;
1114 if(i == CMnew || i == CMspeed || i == CMhub || i == CMpreset)
1115 if(ep != ep->ep0)
1116 error("allowed only on a setup endpoint");
1117 if(i != CMclrhalt && i != CMdetach && i != CMdebugep && i != CMname)
1118 if(ep != ep->ep0 && ep->inuse != 0)
1119 error("must configure before using");
1120 switch(i){
1121 case CMnew:
1122 deprint("usb epctl %s\n", cb->f[0]);
1123 nb = strtol(cb->f[1], nil, 0);
1124 if(nb < 0 || nb >= Ndeveps)
1125 error("bad endpoint number");
1126 tt = name2ttype(cb->f[2]);
1127 if(tt == Tnone)
1128 error("unknown endpoint type");
1129 mode = name2mode(cb->f[3]);
1130 if(mode < 0)
1131 error("unknown i/o mode");
1132 newdevep(ep, nb, tt, mode);
1133 break;
1134 case CMnewdev:
1135 deprint("usb epctl %s\n", cb->f[0]);
1136 if(ep != ep->ep0 || d->ishub == 0)
1137 error("not a hub setup endpoint");
1138 l = name2speed(cb->f[1]);
1139 if(l == Nospeed)
1140 error("speed must be full|low|high");
1141 nep = newdev(ep->hp, 0, 0);
1142 nep->dev->speed = l;
1143 if(nep->dev->speed != Lowspeed)
1144 nep->maxpkt = 64; /* assume full speed */
1145 nep->dev->hub = d->nb;
1146 nep->dev->port = atoi(cb->f[2]);
1147 /* next read request will read
1148 * the name for the new endpoint
1149 */
1150 l = sizeof(up->genbuf);
1151 snprint(up->genbuf, l, "ep%d.%d", nep->dev->nb, nep->nb);
1152 kstrdup(&c->aux, up->genbuf);
1153 break;
1154 case CMhub:
1155 deprint("usb epctl %s\n", cb->f[0]);
1156 d->ishub = 1;
1157 break;
1158 case CMspeed:
1159 l = name2speed(cb->f[1]);
1160 deprint("usb epctl %s %d\n", cb->f[0], l);
1161 if(l == Nospeed)
1162 error("speed must be full|low|high");
1163 qlock(ep->ep0);
1164 d->speed = l;
1165 qunlock(ep->ep0);
1166 break;
1167 case CMmaxpkt:
1168 l = strtoul(cb->f[1], nil, 0);
1169 deprint("usb epctl %s %d\n", cb->f[0], l);
1170 if(l < 1 || l > 1024)
1171 error("maxpkt not in [1:1024]");
1172 qlock(ep);
1173 ep->maxpkt = l;
1174 qunlock(ep);
1175 break;
1176 case CMntds:
1177 l = strtoul(cb->f[1], nil, 0);
1178 deprint("usb epctl %s %d\n", cb->f[0], l);
1179 if(l < 1 || l > 3)
1180 error("ntds not in [1:3]");
1181 qlock(ep);
1182 ep->ntds = l;
1183 qunlock(ep);
1184 break;
1185 case CMpollival:
1186 if(ep->ttype != Tintr && ep->ttype != Tiso)
1187 error("not an intr or iso endpoint");
1188 l = strtoul(cb->f[1], nil, 0);
1189 deprint("usb epctl %s %d\n", cb->f[0], l);
1190 if(ep->ttype == Tiso ||
1191 (ep->ttype == Tintr && ep->dev->speed == Highspeed)){
1192 if(l < 1 || l > 16)
1193 error("pollival power not in [1:16]");
1194 l = pow2(l-1);
1195 }else
1196 if(l < 1 || l > 255)
1197 error("pollival not in [1:255]");
1198 qlock(ep);
1199 ep->pollival = l;
1200 if(ep->ttype == Tiso)
1201 setmaxpkt(ep, "pollival");
1202 qunlock(ep);
1203 break;
1204 case CMsamplesz:
1205 if(ep->ttype != Tiso)
1206 error("not an iso endpoint");
1207 l = strtoul(cb->f[1], nil, 0);
1208 deprint("usb epctl %s %d\n", cb->f[0], l);
1209 if(l <= 0 || l > 8)
1210 error("samplesz not in [1:8]");
1211 qlock(ep);
1212 ep->samplesz = l;
1213 setmaxpkt(ep, "samplesz");
1214 qunlock(ep);
1215 break;
1216 case CMhz:
1217 if(ep->ttype != Tiso)
1218 error("not an iso endpoint");
1219 l = strtoul(cb->f[1], nil, 0);
1220 deprint("usb epctl %s %d\n", cb->f[0], l);
1221 if(l <= 0 || l > 100000)
1222 error("hz not in [1:100000]");
1223 qlock(ep);
1224 ep->hz = l;
1225 setmaxpkt(ep, "hz");
1226 qunlock(ep);
1227 break;
1228 case CMclrhalt:
1229 qlock(ep);
1230 deprint("usb epctl %s\n", cb->f[0]);
1231 ep->clrhalt = 1;
1232 qunlock(ep);
1233 break;
1234 case CMinfo:
1235 deprint("usb epctl %s\n", cb->f[0]);
1236 l = strlen(Info);
1237 s = a;
1238 if(n < l+2 || strncmp(Info, s, l) != 0)
1239 error(Ebadctl);
1240 if(n > 1024)
1241 n = 1024;
1242 b = smalloc(n);
1243 memmove(b, s+l, n-l);
1244 b[n-l] = 0;
1245 if(b[n-l-1] == '\n')
1246 b[n-l-1] = 0;
1247 qlock(ep);
1248 free(ep->info);
1249 ep->info = b;
1250 qunlock(ep);
1251 break;
1252 case CMaddress:
1253 deprint("usb epctl %s\n", cb->f[0]);
1254 ep->dev->state = Denabled;
1255 break;
1256 case CMdetach:
1257 if(ep->dev->isroot != 0)
1258 error("can't detach a root hub");
1259 deprint("usb epctl %s ep%d.%d\n",
1260 cb->f[0], ep->dev->nb, ep->nb);
1261 ep->dev->state = Ddetach;
1262 /* Release file system ref. for its endpoints */
1263 for(i = 0; i < nelem(ep->dev->eps); i++)
1264 putep(ep->dev->eps[i]);
1265 break;
1266 case CMdebugep:
1267 if(strcmp(cb->f[1], "on") == 0)
1268 ep->debug = 1;
1269 else if(strcmp(cb->f[1], "off") == 0)
1270 ep->debug = 0;
1271 else
1272 ep->debug = strtoul(cb->f[1], nil, 0);
1273 print("usb: ep%d.%d debug %d\n",
1274 ep->dev->nb, ep->nb, ep->debug);
1275 break;
1276 case CMname:
1277 deprint("usb epctl %s %s\n", cb->f[0], cb->f[1]);
1278 validname(cb->f[1], 0);
1279 kstrdup(&ep->name, cb->f[1]);
1280 break;
1281 case CMtmout:
1282 deprint("usb epctl %s\n", cb->f[0]);
1283 if(ep->ttype == Tiso || ep->ttype == Tctl)
1284 error("ctl ignored for this endpoint type");
1285 ep->tmout = strtoul(cb->f[1], nil, 0);
1286 if(ep->tmout != 0 && ep->tmout < Xfertmout)
1287 ep->tmout = Xfertmout;
1288 break;
1289 case CMpreset:
1290 deprint("usb epctl %s\n", cb->f[0]);
1291 if(ep->ttype != Tctl)
1292 error("not a control endpoint");
1293 if(ep->dev->state != Denabled)
1294 error("forbidden on devices not enabled");
1295 ep->dev->state = Dreset;
1296 break;
1297 default:
1298 panic("usb: unknown epctl %d", ct->index);
1299 }
1300 free(cb);
1301 poperror();
1302 return n;
1303 }
1304
1305 static long
usbctl(void * a,long n)1306 usbctl(void *a, long n)
1307 {
1308 Cmdtab *ct;
1309 Cmdbuf *cb;
1310 Ep *ep;
1311 int i;
1312
1313 cb = parsecmd(a, n);
1314 if(waserror()){
1315 free(cb);
1316 nexterror();
1317 }
1318 ct = lookupcmd(cb, usbctls, nelem(usbctls));
1319 dprint("usb ctl %s\n", cb->f[0]);
1320 switch(ct->index){
1321 case CMdebug:
1322 if(strcmp(cb->f[1], "on") == 0)
1323 debug = 1;
1324 else if(strcmp(cb->f[1], "off") == 0)
1325 debug = 0;
1326 else
1327 debug = strtol(cb->f[1], nil, 0);
1328 print("usb: debug %d\n", debug);
1329 for(i = 0; i < epmax; i++)
1330 if((ep = getep(i)) != nil){
1331 ep->hp->debug(ep->hp, debug);
1332 putep(ep);
1333 }
1334 break;
1335 case CMdump:
1336 dumpeps();
1337 break;
1338 }
1339 free(cb);
1340 poperror();
1341 return n;
1342 }
1343
1344 static long
ctlwrite(Chan * c,void * a,long n)1345 ctlwrite(Chan *c, void *a, long n)
1346 {
1347 int q;
1348 Ep *ep;
1349
1350 q = QID(c->qid);
1351 if(q == Qctl)
1352 return usbctl(a, n);
1353
1354 ep = getep(qid2epidx(q));
1355 if(ep == nil)
1356 error(Eio);
1357 if(waserror()){
1358 putep(ep);
1359 nexterror();
1360 }
1361 if(ep->dev->state == Ddetach)
1362 error(Edetach);
1363 if(isqtype(q, Qepctl) && c->aux != nil){
1364 /* Be sure we don't keep a cloned ep name */
1365 free(c->aux);
1366 c->aux = nil;
1367 error("read, not write, expected");
1368 }
1369 n = epctl(ep, c, a, n);
1370 putep(ep);
1371 poperror();
1372 return n;
1373 }
1374
1375 static long
usbwrite(Chan * c,void * a,long n,vlong off)1376 usbwrite(Chan *c, void *a, long n, vlong off)
1377 {
1378 int nr, q;
1379 Ep *ep;
1380
1381 if(c->qid.type == QTDIR)
1382 error(Eisdir);
1383
1384 q = QID(c->qid);
1385
1386 if(q == Qctl || isqtype(q, Qepctl))
1387 return ctlwrite(c, a, n);
1388
1389 ep = getep(qid2epidx(q));
1390 if(ep == nil)
1391 error(Eio);
1392 if(waserror()){
1393 putep(ep);
1394 nexterror();
1395 }
1396 if(ep->dev->state == Ddetach)
1397 error(Edetach);
1398 if(ep->mode == OREAD || ep->inuse == 0)
1399 error(Ebadusefd);
1400
1401 switch(ep->ttype){
1402 case Tnone:
1403 error("endpoint not configured");
1404 case Tctl:
1405 nr = rhubwrite(ep, a, n);
1406 if(nr >= 0){
1407 n = nr;
1408 break;
1409 }
1410 /* else fall */
1411 default:
1412 ddeprint("\nusbwrite q %#x fid %d cnt %ld off %lld\n",q, c->fid, n, off);
1413 ep->hp->epwrite(ep, a, n);
1414 }
1415 putep(ep);
1416 poperror();
1417 return n;
1418 }
1419
1420 void
usbshutdown(void)1421 usbshutdown(void)
1422 {
1423 Hci *hp;
1424 int i;
1425
1426 for(i = 0; i < Nhcis; i++){
1427 hp = hcis[i];
1428 if(hp == nil)
1429 continue;
1430 if(hp->shutdown == nil)
1431 print("#u: no shutdown function for %s\n", hp->type);
1432 else
1433 hp->shutdown(hp);
1434 }
1435 }
1436
1437 Dev usbdevtab = {
1438 L'u',
1439 "usb",
1440
1441 usbreset,
1442 usbinit,
1443 usbshutdown,
1444 usbattach,
1445 usbwalk,
1446 usbstat,
1447 usbopen,
1448 devcreate,
1449 usbclose,
1450 usbread,
1451 devbread,
1452 usbwrite,
1453 devbwrite,
1454 devremove,
1455 devwstat,
1456 };
1457