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