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 panic("usb: epalloc: too few endpoints (%d)", Neps);
337 }
338 ep->idx = i;
339 if(epmax <= i)
340 epmax = i+1;
341 eps[i] = ep;
342 ep->hp = hp;
343 ep->maxpkt = 8;
344 ep->ntds = 1;
345 ep->samplesz = ep->pollival = ep->hz = 0; /* make them void */
346 qunlock(&epslck);
347 return ep;
348 }
349
350 static Ep*
getep(int i)351 getep(int i)
352 {
353 Ep *ep;
354
355 if(i < 0 || i >= epmax || eps[i] == nil)
356 return nil;
357 qlock(&epslck);
358 ep = eps[i];
359 if(ep != nil)
360 incref(ep);
361 qunlock(&epslck);
362 return ep;
363 }
364
365 static void
putep(Ep * ep)366 putep(Ep *ep)
367 {
368 Udev *d;
369
370 if(ep != nil && decref(ep) == 0){
371 d = ep->dev;
372 deprint("usb: ep%d.%d %#p released\n", d->nb, ep->nb, ep);
373 qlock(&epslck);
374 eps[ep->idx] = nil;
375 if(ep->idx == epmax-1)
376 epmax--;
377 if(ep == ep->ep0 && ep->dev != nil && ep->dev->nb == usbidgen)
378 usbidgen--;
379 qunlock(&epslck);
380 if(d != nil){
381 qlock(ep->ep0);
382 d->eps[ep->nb] = nil;
383 qunlock(ep->ep0);
384 }
385 if(ep->ep0 != ep){
386 putep(ep->ep0);
387 ep->ep0 = nil;
388 }
389 free(ep->info);
390 free(ep->name);
391 free(ep);
392 }
393 }
394
395 static void
dumpeps(void)396 dumpeps(void)
397 {
398 int i;
399 static char buf[512];
400 char *s;
401 char *e;
402 Ep *ep;
403
404 print("usb dump eps: epmax %d Neps %d (ref=1+ for dump):\n", epmax, Neps);
405 for(i = 0; i < epmax; i++){
406 s = buf;
407 e = buf+sizeof(buf);
408 ep = getep(i);
409 if(ep != nil){
410 if(waserror()){
411 putep(ep);
412 nexterror();
413 }
414 s = seprint(s, e, "ep%d.%d ", ep->dev->nb, ep->nb);
415 seprintep(s, e, ep, 1);
416 print("%s", buf);
417 ep->hp->seprintep(buf, e, ep);
418 print("%s", buf);
419 poperror();
420 putep(ep);
421 }
422 }
423 print("usb dump hcis:\n");
424 for(i = 0; i < Nhcis; i++)
425 if(hcis[i] != nil)
426 hcis[i]->dump(hcis[i]);
427 }
428
429 static int
newusbid(Hci *)430 newusbid(Hci *)
431 {
432 int id;
433
434 qlock(&epslck);
435 id = ++usbidgen;
436 if(id >= 0x7F)
437 print("#u: too many device addresses; reuse them more\n");
438 qunlock(&epslck);
439 return id;
440 }
441
442 /*
443 * Create endpoint 0 for a new device
444 */
445 static Ep*
newdev(Hci * hp,int ishub,int isroot)446 newdev(Hci *hp, int ishub, int isroot)
447 {
448 Ep *ep;
449 Udev *d;
450
451 ep = epalloc(hp);
452 d = ep->dev = smalloc(sizeof(Udev));
453 d->nb = newusbid(hp);
454 d->eps[0] = ep;
455 ep->nb = 0;
456 ep->toggle[0] = ep->toggle[1] = 0;
457 d->ishub = ishub;
458 d->isroot = isroot;
459 if(hp->highspeed != 0)
460 d->speed = Highspeed;
461 else
462 d->speed = Fullspeed;
463 d->state = Dconfig; /* address not yet set */
464 ep->dev = d;
465 ep->ep0 = ep; /* no ref counted here */
466 ep->ttype = Tctl;
467 ep->tmout = Xfertmout;
468 ep->mode = ORDWR;
469 dprint("newdev %#p ep%d.%d %#p\n", d, d->nb, ep->nb, ep);
470 return ep;
471 }
472
473 /*
474 * Create a new endpoint for the device
475 * accessed via the given endpoint 0.
476 */
477 static Ep*
newdevep(Ep * ep,int i,int tt,int mode)478 newdevep(Ep *ep, int i, int tt, int mode)
479 {
480 Ep *nep;
481 Udev *d;
482
483 d = ep->dev;
484 if(d->eps[i] != nil)
485 error("endpoint already in use");
486 nep = epalloc(ep->hp);
487 incref(ep);
488 d->eps[i] = nep;
489 nep->nb = i;
490 nep->toggle[0] = nep->toggle[1] = 0;
491 nep->ep0 = ep;
492 nep->dev = ep->dev;
493 nep->mode = mode;
494 nep->ttype = tt;
495 nep->debug = ep->debug;
496 /* set defaults */
497 switch(tt){
498 case Tctl:
499 nep->tmout = Xfertmout;
500 break;
501 case Tintr:
502 nep->pollival = 10;
503 break;
504 case Tiso:
505 nep->tmout = Xfertmout;
506 nep->pollival = 10;
507 nep->samplesz = 4;
508 nep->hz = 44100;
509 break;
510 }
511 deprint("newdevep ep%d.%d %#p\n", d->nb, nep->nb, nep);
512 return ep;
513 }
514
515 static int
epdataperm(int mode)516 epdataperm(int mode)
517 {
518
519 switch(mode){
520 case OREAD:
521 return 0440|DMEXCL;
522 break;
523 case OWRITE:
524 return 0220|DMEXCL;
525 break;
526 default:
527 return 0660|DMEXCL;
528 }
529 }
530
531 static int
usbgen(Chan * c,char *,Dirtab *,int,int s,Dir * dp)532 usbgen(Chan *c, char *, Dirtab*, int, int s, Dir *dp)
533 {
534 Qid q;
535 Dirtab *dir;
536 int perm;
537 char *se;
538 Ep *ep;
539 int nb;
540 int mode;
541
542 if(0)ddprint("usbgen q %#x s %d...", QID(c->qid), s);
543 if(s == DEVDOTDOT){
544 if(QID(c->qid) <= Qusbdir){
545 mkqid(&q, Qdir, 0, QTDIR);
546 devdir(c, q, "#u", 0, eve, 0555, dp);
547 }else{
548 mkqid(&q, Qusbdir, 0, QTDIR);
549 devdir(c, q, "usb", 0, eve, 0555, dp);
550 }
551 if(0)ddprint("ok\n");
552 return 1;
553 }
554
555 switch(QID(c->qid)){
556 case Qdir: /* list #u */
557 if(s == 0){
558 mkqid(&q, Qusbdir, 0, QTDIR);
559 devdir(c, q, "usb", 0, eve, 0555, dp);
560 if(0)ddprint("ok\n");
561 return 1;
562 }
563 s--;
564 if(s < 0 || s >= epmax)
565 goto Fail;
566 ep = getep(s);
567 if(ep == nil || ep->name == nil){
568 if(ep != nil)
569 putep(ep);
570 if(0)ddprint("skip\n");
571 return 0;
572 }
573 if(waserror()){
574 putep(ep);
575 nexterror();
576 }
577 mkqid(&q, Qep0io+s*4, 0, QTFILE);
578 devdir(c, q, ep->name, 0, eve, epdataperm(ep->mode), dp);
579 putep(ep);
580 poperror();
581 if(0)ddprint("ok\n");
582 return 1;
583
584 case Qusbdir: /* list #u/usb */
585 Usbdir:
586 if(s < nelem(usbdir)){
587 dir = &usbdir[s];
588 mkqid(&q, dir->qid.path, 0, QTFILE);
589 devdir(c, q, dir->name, dir->length, eve, dir->perm, dp);
590 if(0)ddprint("ok\n");
591 return 1;
592 }
593 s -= nelem(usbdir);
594 if(s < 0 || s >= epmax)
595 goto Fail;
596 ep = getep(s);
597 if(ep == nil){
598 if(0)ddprint("skip\n");
599 return 0;
600 }
601 if(waserror()){
602 putep(ep);
603 nexterror();
604 }
605 se = up->genbuf+sizeof(up->genbuf);
606 seprint(up->genbuf, se, "ep%d.%d", ep->dev->nb, ep->nb);
607 mkqid(&q, Qep0dir+4*s, 0, QTDIR);
608 putep(ep);
609 poperror();
610 devdir(c, q, up->genbuf, 0, eve, 0755, dp);
611 if(0)ddprint("ok\n");
612 return 1;
613
614 case Qctl:
615 s = 0;
616 goto Usbdir;
617
618 default: /* list #u/usb/epN.M */
619 nb = qid2epidx(QID(c->qid));
620 ep = getep(nb);
621 if(ep == nil)
622 goto Fail;
623 mode = ep->mode;
624 putep(ep);
625 if(isqtype(QID(c->qid), Qepdir)){
626 Epdir:
627 switch(s){
628 case 0:
629 mkqid(&q, Qep0io+nb*4, 0, QTFILE);
630 perm = epdataperm(mode);
631 devdir(c, q, "data", 0, eve, perm, dp);
632 break;
633 case 1:
634 mkqid(&q, Qep0ctl+nb*4, 0, QTFILE);
635 devdir(c, q, "ctl", 0, eve, 0664, dp);
636 break;
637 default:
638 goto Fail;
639 }
640 }else if(isqtype(QID(c->qid), Qepctl)){
641 s = 1;
642 goto Epdir;
643 }else{
644 s = 0;
645 goto Epdir;
646 }
647 if(0)ddprint("ok\n");
648 return 1;
649 }
650 Fail:
651 if(0)ddprint("fail\n");
652 return -1;
653 }
654
655 static Hci*
hciprobe(int cardno,int ctlrno)656 hciprobe(int cardno, int ctlrno)
657 {
658 Hci *hp;
659 char *type;
660 char name[64];
661 static int epnb = 1; /* guess the endpoint nb. for the controller */
662
663 ddprint("hciprobe %d %d\n", cardno, ctlrno);
664 hp = smalloc(sizeof(Hci));
665 hp->ctlrno = ctlrno;
666 hp->tbdf = BUSUNKNOWN;
667
668 if(cardno < 0){
669 if(isaconfig("usb", ctlrno, hp) == 0){
670 free(hp);
671 return nil;
672 }
673 for(cardno = 0; cardno < Nhcis; cardno++){
674 if(hcitypes[cardno].type == nil)
675 break;
676 type = hp->type;
677 if(type==nil || *type==0)
678 type = "uhci";
679 if(cistrcmp(hcitypes[cardno].type, type) == 0)
680 break;
681 }
682 }
683
684 if(cardno >= Nhcis || hcitypes[cardno].type == nil){
685 free(hp);
686 return nil;
687 }
688 dprint("%s...", hcitypes[cardno].type);
689 if(hcitypes[cardno].reset(hp) < 0){
690 free(hp);
691 return nil;
692 }
693
694 /*
695 * IRQ2 doesn't really exist, it's used to gang the interrupt
696 * controllers together. A device set to IRQ2 will appear on
697 * the second interrupt controller as IRQ9.
698 */
699 if(hp->irq == 2)
700 hp->irq = 9;
701 snprint(name, sizeof(name), "usb%s", hcitypes[cardno].type);
702 intrenable(hp->irq, hp->interrupt, hp, hp->tbdf, name);
703
704 /*
705 * modern machines have too many usb controllers to list on
706 * the console.
707 */
708 dprint("#u/usb/ep%d.0: %s: port 0x%luX irq %d\n",
709 epnb, hcitypes[cardno].type, hp->port, hp->irq);
710 epnb++;
711 return hp;
712 }
713
714 static void
usbreset(void)715 usbreset(void)
716 {
717 int cardno, ctlrno;
718 Hci *hp;
719
720 if(getconf("*nousbprobe"))
721 return;
722 dprint("usbreset\n");
723
724 for(ctlrno = 0; ctlrno < Nhcis; ctlrno++)
725 if((hp = hciprobe(-1, ctlrno)) != nil)
726 hcis[ctlrno] = hp;
727 cardno = ctlrno = 0;
728 while(cardno < Nhcis && ctlrno < Nhcis && hcitypes[cardno].type != nil)
729 if(hcis[ctlrno] != nil)
730 ctlrno++;
731 else{
732 hp = hciprobe(cardno, ctlrno);
733 if(hp == nil)
734 cardno++;
735 hcis[ctlrno++] = hp;
736 }
737 if(hcis[Nhcis-1] != nil)
738 print("usbreset: bug: Nhcis (%d) too small\n", Nhcis);
739 }
740
741 static void
usbinit(void)742 usbinit(void)
743 {
744 Hci *hp;
745 int ctlrno;
746 Ep *d;
747 char info[40];
748
749 dprint("usbinit\n");
750 for(ctlrno = 0; ctlrno < Nhcis; ctlrno++){
751 hp = hcis[ctlrno];
752 if(hp != nil){
753 if(hp->init != nil)
754 hp->init(hp);
755 d = newdev(hp, 1, 1); /* new root hub */
756 d->dev->state = Denabled; /* although addr == 0 */
757 d->maxpkt = 64;
758 snprint(info, sizeof(info), "ports %d", hp->nports);
759 kstrdup(&d->info, info);
760 }
761 }
762 }
763
764 static Chan*
usbattach(char * spec)765 usbattach(char *spec)
766 {
767 return devattach(L'u', spec);
768 }
769
770 static Walkqid*
usbwalk(Chan * c,Chan * nc,char ** name,int nname)771 usbwalk(Chan *c, Chan *nc, char **name, int nname)
772 {
773 return devwalk(c, nc, name, nname, nil, 0, usbgen);
774 }
775
776 static int
usbstat(Chan * c,uchar * db,int n)777 usbstat(Chan *c, uchar *db, int n)
778 {
779 return devstat(c, db, n, nil, 0, usbgen);
780 }
781
782 /*
783 * µs for the given transfer, for bandwidth allocation.
784 * This is a very rough worst case for what 5.11.3
785 * of the usb 2.0 spec says.
786 * Also, we are using maxpkt and not actual transfer sizes.
787 * Only when we are sure we
788 * are not exceeding b/w might we consider adjusting it.
789 */
790 static ulong
usbload(int speed,int maxpkt)791 usbload(int speed, int maxpkt)
792 {
793 enum{ Hostns = 1000, Hubns = 333 };
794 ulong l;
795 ulong bs;
796
797 l = 0;
798 bs = 10UL * maxpkt;
799 switch(speed){
800 case Highspeed:
801 l = 55*8*2 + 2 * (3 + bs) + Hostns;
802 break;
803 case Fullspeed:
804 l = 9107 + 84 * (4 + bs) + Hostns;
805 break;
806 case Lowspeed:
807 l = 64107 + 2 * Hubns + 667 * (3 + bs) + Hostns;
808 break;
809 default:
810 print("usbload: bad speed %d\n", speed);
811 /* let it run */
812 }
813 return l / 1000UL; /* in µs */
814 }
815
816 static Chan*
usbopen(Chan * c,int omode)817 usbopen(Chan *c, int omode)
818 {
819 int q;
820 Ep *ep;
821 int mode;
822
823 mode = openmode(omode);
824 q = QID(c->qid);
825
826 if(q >= Qep0dir && qid2epidx(q) < 0)
827 error(Eio);
828 if(q < Qep0dir || isqtype(q, Qepctl) || isqtype(q, Qepdir))
829 return devopen(c, omode, nil, 0, usbgen);
830
831 ep = getep(qid2epidx(q));
832 if(ep == nil)
833 error(Eio);
834 deprint("usbopen q %#x fid %d omode %d\n", q, c->fid, mode);
835 if(waserror()){
836 putep(ep);
837 nexterror();
838 }
839 qlock(ep);
840 if(ep->inuse){
841 qunlock(ep);
842 error(Einuse);
843 }
844 ep->inuse = 1;
845 qunlock(ep);
846 if(waserror()){
847 ep->inuse = 0;
848 nexterror();
849 }
850 if(mode != OREAD && ep->mode == OREAD)
851 error(Eperm);
852 if(mode != OWRITE && ep->mode == OWRITE)
853 error(Eperm);
854 if(ep->ttype == Tnone)
855 error(Enotconf);
856 ep->clrhalt = 0;
857 ep->rhrepl = -1;
858 if(ep->load == 0)
859 ep->load = usbload(ep->dev->speed, ep->maxpkt);
860 ep->hp->epopen(ep);
861
862 poperror(); /* ep->inuse */
863 poperror(); /* don't putep(): ref kept for fid using the ep. */
864
865 c->mode = mode;
866 c->flag |= COPEN;
867 c->offset = 0;
868 c->aux = nil; /* paranoia */
869 return c;
870 }
871
872 static void
epclose(Ep * ep)873 epclose(Ep *ep)
874 {
875 qlock(ep);
876 if(waserror()){
877 qunlock(ep);
878 nexterror();
879 }
880 if(ep->inuse){
881 ep->hp->epclose(ep);
882 ep->inuse = 0;
883 }
884 qunlock(ep);
885 poperror();
886 }
887
888 static void
usbclose(Chan * c)889 usbclose(Chan *c)
890 {
891 int q;
892 Ep *ep;
893
894 q = QID(c->qid);
895 if(q < Qep0dir || isqtype(q, Qepctl) || isqtype(q, Qepdir))
896 return;
897
898 ep = getep(qid2epidx(q));
899 if(ep == nil)
900 return;
901 deprint("usbclose q %#x fid %d ref %ld\n", q, c->fid, ep->ref);
902 if(waserror()){
903 putep(ep);
904 nexterror();
905 }
906 if(c->flag & COPEN){
907 free(c->aux);
908 c->aux = nil;
909 epclose(ep);
910 putep(ep); /* release ref kept since usbopen */
911 c->flag &= ~COPEN;
912 }
913 poperror();
914 putep(ep);
915 }
916
917 static long
ctlread(Chan * c,void * a,long n,vlong offset)918 ctlread(Chan *c, void *a, long n, vlong offset)
919 {
920 int q;
921 char *s;
922 char *us;
923 char *se;
924 Ep *ep;
925 int i;
926
927 q = QID(c->qid);
928 us = s = smalloc(READSTR);
929 se = s + READSTR;
930 if(waserror()){
931 free(us);
932 nexterror();
933 }
934 if(q == Qctl)
935 for(i = 0; i < epmax; i++){
936 ep = getep(i);
937 if(ep != nil){
938 if(waserror()){
939 putep(ep);
940 nexterror();
941 }
942 s = seprint(s, se, "ep%d.%d ", ep->dev->nb, ep->nb);
943 s = seprintep(s, se, ep, 0);
944 poperror();
945 }
946 putep(ep);
947 }
948 else{
949 ep = getep(qid2epidx(q));
950 if(ep == nil)
951 error(Eio);
952 if(waserror()){
953 putep(ep);
954 nexterror();
955 }
956 if(c->aux != nil){
957 /* After a new endpoint request we read
958 * the new endpoint name back.
959 */
960 strecpy(s, se, c->aux);
961 free(c->aux);
962 c->aux = nil;
963 }else
964 seprintep(s, se, ep, 0);
965 poperror();
966 putep(ep);
967 }
968 n = readstr(offset, a, n, us);
969 poperror();
970 free(us);
971 return n;
972 }
973
974 /*
975 * Fake root hub emulation.
976 */
977 static long
rhubread(Ep * ep,void * a,long n)978 rhubread(Ep *ep, void *a, long n)
979 {
980 char *b;
981
982 if(ep->dev->isroot == 0 || ep->nb != 0 || n < 2)
983 return -1;
984 if(ep->rhrepl < 0)
985 return -1;
986
987 b = a;
988 memset(b, 0, n);
989 PUT2(b, ep->rhrepl);
990 ep->rhrepl = -1;
991 return n;
992 }
993
994 static long
rhubwrite(Ep * ep,void * a,long n)995 rhubwrite(Ep *ep, void *a, long n)
996 {
997 uchar *s;
998 int cmd;
999 int feature;
1000 int port;
1001 Hci *hp;
1002
1003 if(ep->dev == nil || ep->dev->isroot == 0 || ep->nb != 0)
1004 return -1;
1005 if(n != Rsetuplen)
1006 error("root hub is a toy hub");
1007 ep->rhrepl = -1;
1008 s = a;
1009 if(s[Rtype] != (Rh2d|Rclass|Rother) && s[Rtype] != (Rd2h|Rclass|Rother))
1010 error("root hub is a toy hub");
1011 hp = ep->hp;
1012 cmd = s[Rreq];
1013 feature = GET2(s+Rvalue);
1014 port = GET2(s+Rindex);
1015 if(port < 1 || port > hp->nports)
1016 error("bad hub port number");
1017 switch(feature){
1018 case Rportenable:
1019 ep->rhrepl = hp->portenable(hp, port, cmd == Rsetfeature);
1020 break;
1021 case Rportreset:
1022 ep->rhrepl = hp->portreset(hp, port, cmd == Rsetfeature);
1023 break;
1024 case Rgetstatus:
1025 ep->rhrepl = hp->portstatus(hp, port);
1026 break;
1027 default:
1028 ep->rhrepl = 0;
1029 }
1030 return n;
1031 }
1032
1033 static long
usbread(Chan * c,void * a,long n,vlong offset)1034 usbread(Chan *c, void *a, long n, vlong offset)
1035 {
1036 int q;
1037 Ep *ep;
1038 int nr;
1039
1040 q = QID(c->qid);
1041
1042 if(c->qid.type == QTDIR)
1043 return devdirread(c, a, n, nil, 0, usbgen);
1044
1045 if(q == Qctl || isqtype(q, Qepctl))
1046 return ctlread(c, a, n, offset);
1047
1048 ep = getep(qid2epidx(q));
1049 if(ep == nil)
1050 error(Eio);
1051 if(waserror()){
1052 putep(ep);
1053 nexterror();
1054 }
1055 if(ep->dev->state == Ddetach)
1056 error(Edetach);
1057 if(ep->mode == OWRITE || ep->inuse == 0)
1058 error(Ebadusefd);
1059 switch(ep->ttype){
1060 case Tnone:
1061 error("endpoint not configured");
1062 case Tctl:
1063 nr = rhubread(ep, a, n);
1064 if(nr >= 0){
1065 n = nr;
1066 break;
1067 }
1068 /* else fall */
1069 default:
1070 ddeprint("\nusbread q %#x fid %d cnt %ld off %lld\n",q,c->fid,n,offset);
1071 n = ep->hp->epread(ep, a, n);
1072 break;
1073 }
1074 poperror();
1075 putep(ep);
1076 return n;
1077 }
1078
1079 static long
pow2(int n)1080 pow2(int n)
1081 {
1082 return 1 << n;
1083 }
1084
1085 static void
setmaxpkt(Ep * ep,char * s)1086 setmaxpkt(Ep *ep, char* s)
1087 {
1088 long spp; /* samples per packet */
1089
1090 if(ep->dev->speed == Highspeed)
1091 spp = (ep->hz * ep->pollival * ep->ntds + 7999) / 8000;
1092 else
1093 spp = (ep->hz * ep->pollival + 999) / 1000;
1094 ep->maxpkt = spp * ep->samplesz;
1095 deprint("usb: %s: setmaxpkt: hz %ld poll %ld"
1096 " ntds %d %s speed -> spp %ld maxpkt %ld\n", s,
1097 ep->hz, ep->pollival, ep->ntds, spname[ep->dev->speed],
1098 spp, ep->maxpkt);
1099 if(ep->maxpkt > 1024){
1100 print("usb: %s: maxpkt %ld > 1024. truncating\n", s, ep->maxpkt);
1101 ep->maxpkt = 1024;
1102 }
1103 }
1104
1105 /*
1106 * Many endpoint ctls. simply update the portable representation
1107 * of the endpoint. The actual controller driver will look
1108 * at them to setup the endpoints as dictated.
1109 */
1110 static long
epctl(Ep * ep,Chan * c,void * a,long n)1111 epctl(Ep *ep, Chan *c, void *a, long n)
1112 {
1113 int i, l, mode, nb, tt;
1114 char *b, *s;
1115 Cmdbuf *cb;
1116 Cmdtab *ct;
1117 Ep *nep;
1118 Udev *d;
1119 static char *Info = "info ";
1120
1121 d = ep->dev;
1122
1123 cb = parsecmd(a, n);
1124 if(waserror()){
1125 free(cb);
1126 nexterror();
1127 }
1128 ct = lookupcmd(cb, epctls, nelem(epctls));
1129 if(ct == nil)
1130 error(Ebadctl);
1131 i = ct->index;
1132 if(i == CMnew || i == CMspeed || i == CMhub || i == CMpreset)
1133 if(ep != ep->ep0)
1134 error("allowed only on a setup endpoint");
1135 if(i != CMclrhalt && i != CMdetach && i != CMdebugep && i != CMname)
1136 if(ep != ep->ep0 && ep->inuse != 0)
1137 error("must configure before using");
1138 switch(i){
1139 case CMnew:
1140 deprint("usb epctl %s\n", cb->f[0]);
1141 nb = strtol(cb->f[1], nil, 0);
1142 if(nb < 0 || nb >= Ndeveps)
1143 error("bad endpoint number");
1144 tt = name2ttype(cb->f[2]);
1145 if(tt == Tnone)
1146 error("unknown endpoint type");
1147 mode = name2mode(cb->f[3]);
1148 if(mode < 0)
1149 error("unknown i/o mode");
1150 newdevep(ep, nb, tt, mode);
1151 break;
1152 case CMnewdev:
1153 deprint("usb epctl %s\n", cb->f[0]);
1154 if(ep != ep->ep0 || d->ishub == 0)
1155 error("not a hub setup endpoint");
1156 l = name2speed(cb->f[1]);
1157 if(l == Nospeed)
1158 error("speed must be full|low|high");
1159 nep = newdev(ep->hp, 0, 0);
1160 nep->dev->speed = l;
1161 if(nep->dev->speed != Lowspeed)
1162 nep->maxpkt = 64; /* assume full speed */
1163 nep->dev->hub = d->nb;
1164 nep->dev->port = atoi(cb->f[2]);
1165 /* next read request will read
1166 * the name for the new endpoint
1167 */
1168 l = sizeof(up->genbuf);
1169 snprint(up->genbuf, l, "ep%d.%d", nep->dev->nb, nep->nb);
1170 kstrdup(&c->aux, up->genbuf);
1171 break;
1172 case CMhub:
1173 deprint("usb epctl %s\n", cb->f[0]);
1174 d->ishub = 1;
1175 break;
1176 case CMspeed:
1177 l = name2speed(cb->f[1]);
1178 deprint("usb epctl %s %d\n", cb->f[0], l);
1179 if(l == Nospeed)
1180 error("speed must be full|low|high");
1181 qlock(ep->ep0);
1182 d->speed = l;
1183 qunlock(ep->ep0);
1184 break;
1185 case CMmaxpkt:
1186 l = strtoul(cb->f[1], nil, 0);
1187 deprint("usb epctl %s %d\n", cb->f[0], l);
1188 if(l < 1 || l > 1024)
1189 error("maxpkt not in [1:1024]");
1190 qlock(ep);
1191 ep->maxpkt = l;
1192 qunlock(ep);
1193 break;
1194 case CMntds:
1195 l = strtoul(cb->f[1], nil, 0);
1196 deprint("usb epctl %s %d\n", cb->f[0], l);
1197 if(l < 1 || l > 3)
1198 error("ntds not in [1:3]");
1199 qlock(ep);
1200 ep->ntds = l;
1201 qunlock(ep);
1202 break;
1203 case CMpollival:
1204 if(ep->ttype != Tintr && ep->ttype != Tiso)
1205 error("not an intr or iso endpoint");
1206 l = strtoul(cb->f[1], nil, 0);
1207 deprint("usb epctl %s %d\n", cb->f[0], l);
1208 if(ep->ttype == Tiso ||
1209 (ep->ttype == Tintr && ep->dev->speed == Highspeed)){
1210 if(l < 1 || l > 16)
1211 error("pollival power not in [1:16]");
1212 l = pow2(l-1);
1213 }else
1214 if(l < 1 || l > 255)
1215 error("pollival not in [1:255]");
1216 qlock(ep);
1217 ep->pollival = l;
1218 if(ep->ttype == Tiso)
1219 setmaxpkt(ep, "pollival");
1220 qunlock(ep);
1221 break;
1222 case CMsamplesz:
1223 if(ep->ttype != Tiso)
1224 error("not an iso endpoint");
1225 l = strtoul(cb->f[1], nil, 0);
1226 deprint("usb epctl %s %d\n", cb->f[0], l);
1227 if(l <= 0 || l > 8)
1228 error("samplesz not in [1:8]");
1229 qlock(ep);
1230 ep->samplesz = l;
1231 setmaxpkt(ep, "samplesz");
1232 qunlock(ep);
1233 break;
1234 case CMhz:
1235 if(ep->ttype != Tiso)
1236 error("not an iso endpoint");
1237 l = strtoul(cb->f[1], nil, 0);
1238 deprint("usb epctl %s %d\n", cb->f[0], l);
1239 if(l <= 0 || l > 100000)
1240 error("hz not in [1:100000]");
1241 qlock(ep);
1242 ep->hz = l;
1243 setmaxpkt(ep, "hz");
1244 qunlock(ep);
1245 break;
1246 case CMclrhalt:
1247 qlock(ep);
1248 deprint("usb epctl %s\n", cb->f[0]);
1249 ep->clrhalt = 1;
1250 qunlock(ep);
1251 break;
1252 case CMinfo:
1253 deprint("usb epctl %s\n", cb->f[0]);
1254 l = strlen(Info);
1255 s = a;
1256 if(n < l+2 || strncmp(Info, s, l) != 0)
1257 error(Ebadctl);
1258 if(n > 1024)
1259 n = 1024;
1260 b = smalloc(n);
1261 memmove(b, s+l, n-l);
1262 b[n-l] = 0;
1263 if(b[n-l-1] == '\n')
1264 b[n-l-1] = 0;
1265 qlock(ep);
1266 free(ep->info);
1267 ep->info = b;
1268 qunlock(ep);
1269 break;
1270 case CMaddress:
1271 deprint("usb epctl %s\n", cb->f[0]);
1272 ep->dev->state = Denabled;
1273 break;
1274 case CMdetach:
1275 if(ep->dev->isroot != 0)
1276 error("can't detach a root hub");
1277 deprint("usb epctl %s ep%d.%d\n",
1278 cb->f[0], ep->dev->nb, ep->nb);
1279 ep->dev->state = Ddetach;
1280 /* Release file system ref. for its endpoints */
1281 for(i = 0; i < nelem(ep->dev->eps); i++)
1282 putep(ep->dev->eps[i]);
1283 break;
1284 case CMdebugep:
1285 if(strcmp(cb->f[1], "on") == 0)
1286 ep->debug = 1;
1287 else if(strcmp(cb->f[1], "off") == 0)
1288 ep->debug = 0;
1289 else
1290 ep->debug = strtoul(cb->f[1], nil, 0);
1291 print("usb: ep%d.%d debug %d\n",
1292 ep->dev->nb, ep->nb, ep->debug);
1293 break;
1294 case CMname:
1295 deprint("usb epctl %s %s\n", cb->f[0], cb->f[1]);
1296 validname(cb->f[1], 0);
1297 kstrdup(&ep->name, cb->f[1]);
1298 break;
1299 case CMtmout:
1300 deprint("usb epctl %s\n", cb->f[0]);
1301 if(ep->ttype == Tiso || ep->ttype == Tctl)
1302 error("ctl ignored for this endpoint type");
1303 ep->tmout = strtoul(cb->f[1], nil, 0);
1304 if(ep->tmout != 0 && ep->tmout < Xfertmout)
1305 ep->tmout = Xfertmout;
1306 break;
1307 case CMpreset:
1308 deprint("usb epctl %s\n", cb->f[0]);
1309 if(ep->ttype != Tctl)
1310 error("not a control endpoint");
1311 if(ep->dev->state != Denabled)
1312 error("forbidden on devices not enabled");
1313 ep->dev->state = Dreset;
1314 break;
1315 default:
1316 panic("usb: unknown epctl %d", ct->index);
1317 }
1318 free(cb);
1319 poperror();
1320 return n;
1321 }
1322
1323 static long
usbctl(void * a,long n)1324 usbctl(void *a, long n)
1325 {
1326 Cmdtab *ct;
1327 Cmdbuf *cb;
1328 Ep *ep;
1329 int i;
1330
1331 cb = parsecmd(a, n);
1332 if(waserror()){
1333 free(cb);
1334 nexterror();
1335 }
1336 ct = lookupcmd(cb, usbctls, nelem(usbctls));
1337 dprint("usb ctl %s\n", cb->f[0]);
1338 switch(ct->index){
1339 case CMdebug:
1340 if(strcmp(cb->f[1], "on") == 0)
1341 debug = 1;
1342 else if(strcmp(cb->f[1], "off") == 0)
1343 debug = 0;
1344 else
1345 debug = strtol(cb->f[1], nil, 0);
1346 print("usb: debug %d\n", debug);
1347 for(i = 0; i < epmax; i++)
1348 if((ep = getep(i)) != nil){
1349 ep->hp->debug(ep->hp, debug);
1350 putep(ep);
1351 }
1352 break;
1353 case CMdump:
1354 dumpeps();
1355 break;
1356 }
1357 free(cb);
1358 poperror();
1359 return n;
1360 }
1361
1362 static long
ctlwrite(Chan * c,void * a,long n)1363 ctlwrite(Chan *c, void *a, long n)
1364 {
1365 int q;
1366 Ep *ep;
1367
1368 q = QID(c->qid);
1369 if(q == Qctl)
1370 return usbctl(a, n);
1371
1372 ep = getep(qid2epidx(q));
1373 if(ep == nil)
1374 error(Eio);
1375 if(waserror()){
1376 putep(ep);
1377 nexterror();
1378 }
1379 if(ep->dev->state == Ddetach)
1380 error(Edetach);
1381 if(isqtype(q, Qepctl) && c->aux != nil){
1382 /* Be sure we don't keep a cloned ep name */
1383 free(c->aux);
1384 c->aux = nil;
1385 error("read, not write, expected");
1386 }
1387 n = epctl(ep, c, a, n);
1388 putep(ep);
1389 poperror();
1390 return n;
1391 }
1392
1393 static long
usbwrite(Chan * c,void * a,long n,vlong off)1394 usbwrite(Chan *c, void *a, long n, vlong off)
1395 {
1396 int nr, q;
1397 Ep *ep;
1398
1399 if(c->qid.type == QTDIR)
1400 error(Eisdir);
1401
1402 q = QID(c->qid);
1403
1404 if(q == Qctl || isqtype(q, Qepctl))
1405 return ctlwrite(c, a, n);
1406
1407 ep = getep(qid2epidx(q));
1408 if(ep == nil)
1409 error(Eio);
1410 if(waserror()){
1411 putep(ep);
1412 nexterror();
1413 }
1414 if(ep->dev->state == Ddetach)
1415 error(Edetach);
1416 if(ep->mode == OREAD || ep->inuse == 0)
1417 error(Ebadusefd);
1418
1419 switch(ep->ttype){
1420 case Tnone:
1421 error("endpoint not configured");
1422 case Tctl:
1423 nr = rhubwrite(ep, a, n);
1424 if(nr >= 0){
1425 n = nr;
1426 break;
1427 }
1428 /* else fall */
1429 default:
1430 ddeprint("\nusbwrite q %#x fid %d cnt %ld off %lld\n",q, c->fid, n, off);
1431 ep->hp->epwrite(ep, a, n);
1432 }
1433 putep(ep);
1434 poperror();
1435 return n;
1436 }
1437
1438 void
usbshutdown(void)1439 usbshutdown(void)
1440 {
1441 Hci *hp;
1442 int i;
1443
1444 for(i = 0; i < Nhcis; i++){
1445 hp = hcis[i];
1446 if(hp == nil)
1447 continue;
1448 if(hp->shutdown == nil)
1449 print("#u: no shutdown function for %s\n", hp->type);
1450 else
1451 hp->shutdown(hp);
1452 }
1453 }
1454
1455 Dev usbdevtab = {
1456 L'u',
1457 "usb",
1458
1459 usbreset,
1460 usbinit,
1461 usbshutdown,
1462 usbattach,
1463 usbwalk,
1464 usbstat,
1465 usbopen,
1466 devcreate,
1467 usbclose,
1468 usbread,
1469 devbread,
1470 usbwrite,
1471 devbwrite,
1472 devremove,
1473 devwstat,
1474 };
1475