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