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