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