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