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