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