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