Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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*
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
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
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
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
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
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
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*
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*
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*
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
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
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
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*
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*
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
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
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*
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
 
668
	if(cardno < 0)
669
		for(cardno = 0; cardno < Nhcis; cardno++){
670
			if(hcitypes[cardno].type == nil)
671
				break;
672
			type = hp->type;
673
			if(type==nil || *type==0)
674
				type = "uhci";
675
			if(cistrcmp(hcitypes[cardno].type, type) == 0)
676
				break;
677
		}
678
 
679
	if(cardno >= Nhcis || hcitypes[cardno].type == nil){
680
		free(hp);
681
		return nil;
682
	}
683
	dprint("%s...", hcitypes[cardno].type);
684
	if(hcitypes[cardno].reset(hp) < 0){
685
		free(hp);
686
		return nil;
687
	}
688
 
689
	snprint(name, sizeof(name), "usb%s", hcitypes[cardno].type);
690
	intrenable(hp->irq, hp->interrupt, hp, UNKNOWN, name);
691
 
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
 
696
	return hp;
697
}
698
 
699
static void
700
usbreset(void)
701
{
702
	int cardno, ctlrno;
703
	Hci *hp;
704
 
705
	dprint("usbreset\n");
706
 
707
	for(ctlrno = 0; ctlrno < Nhcis; ctlrno++)
708
		if((hp = hciprobe(-1, ctlrno)) != nil)
709
			hcis[ctlrno] = hp;
710
	cardno = ctlrno = 0;
711
	while(cardno < Nhcis && ctlrno < Nhcis && hcitypes[cardno].type != nil)
712
		if(hcis[ctlrno] != nil)
713
			ctlrno++;
714
		else{
715
			hp = hciprobe(cardno, ctlrno);
716
			if(hp == nil)
717
				cardno++;
718
			hcis[ctlrno++] = hp;
719
		}
720
	if(hcis[Nhcis-1] != nil)
721
		print("usbreset: bug: Nhcis too small\n");
722
}
723
 
724
static void
725
usbinit(void)
726
{
727
	Hci *hp;
728
	int ctlrno;
729
	Ep *d;
730
	char info[40];
731
 
732
	dprint("usbinit\n");
733
	for(ctlrno = 0; ctlrno < Nhcis; ctlrno++){
734
		hp = hcis[ctlrno];
735
		if(hp != nil){
736
			if(hp->init != nil)
737
				hp->init(hp);
738
			d = newdev(hp, 1, 1);		/* new root hub */
739
			d->dev->state = Denabled;	/* although addr == 0 */
740
			d->maxpkt = 64;
741
			snprint(info, sizeof(info), "ports %d", hp->nports);
742
			kstrdup(&d->info, info);
743
		}
744
	}
745
}
746
 
747
static Chan*
748
usbattach(char *spec)
749
{
750
	return devattach(L'u', spec);
751
}
752
 
753
static Walkqid*
754
usbwalk(Chan *c, Chan *nc, char **name, int nname)
755
{
756
	return devwalk(c, nc, name, nname, nil, 0, usbgen);
757
}
758
 
759
static int
760
usbstat(Chan *c, uchar *db, int n)
761
{
762
	return devstat(c, db, n, nil, 0, usbgen);
763
}
764
 
765
/*
766
 * µs for the given transfer, for bandwidth allocation.
767
 * This is a very rough worst case for what 5.11.3
768
 * of the usb 2.0 spec says.
769
 * Also, we are using maxpkt and not actual transfer sizes.
770
 * Only when we are sure we
771
 * are not exceeding b/w might we consider adjusting it.
772
 */
773
static ulong
774
usbload(int speed, int maxpkt)
775
{
776
	enum{ Hostns = 1000, Hubns = 333 };
777
	ulong l;
778
	ulong bs;
779
 
780
	l = 0;
781
	bs = 10UL * maxpkt;
782
	switch(speed){
783
	case Highspeed:
784
		l = 55*8*2 + 2 * (3 + bs) + Hostns;
785
		break;
786
	case Fullspeed:
787
		l = 9107 + 84 * (4 + bs) + Hostns;
788
		break;
789
	case Lowspeed:
790
		l = 64107 + 2 * Hubns + 667 * (3 + bs) + Hostns;
791
		break;
792
	default:
793
		print("usbload: bad speed %d\n", speed);
794
		/* let it run */
795
	}
796
	return l / 1000UL;	/* in µs */
797
}
798
 
799
static Chan*
800
usbopen(Chan *c, int omode)
801
{
802
	int q;
803
	Ep *ep;
804
	int mode;
805
 
806
	mode = openmode(omode);
807
	q = QID(c->qid);
808
 
809
	if(q >= Qep0dir && qid2epidx(q) < 0)
810
		error(Eio);
811
	if(q < Qep0dir || isqtype(q, Qepctl) || isqtype(q, Qepdir))
812
		return devopen(c, omode, nil, 0, usbgen);
813
 
814
	ep = getep(qid2epidx(q));
815
	if(ep == nil)
816
		error(Eio);
817
	deprint("usbopen q %#x fid %d omode %d\n", q, c->fid, mode);
818
	if(waserror()){
819
		putep(ep);
820
		nexterror();
821
	}
822
	qlock(ep);
823
	if(ep->inuse){
824
		qunlock(ep);
825
		error(Einuse);
826
	}
827
	ep->inuse = 1;
828
	qunlock(ep);
829
	if(waserror()){
830
		ep->inuse = 0;
831
		nexterror();
832
	}
833
	if(mode != OREAD && ep->mode == OREAD)
834
		error(Eperm);
835
	if(mode != OWRITE && ep->mode == OWRITE)
836
		error(Eperm);
837
	if(ep->ttype == Tnone)
838
		error(Enotconf);
839
	ep->clrhalt = 0;
840
	ep->rhrepl = -1;
841
	if(ep->load == 0)
842
		ep->load = usbload(ep->dev->speed, ep->maxpkt);
843
	ep->hp->epopen(ep);
844
 
845
	poperror();	/* ep->inuse */
846
	poperror();	/* don't putep(): ref kept for fid using the ep. */
847
 
848
	c->mode = mode;
849
	c->flag |= COPEN;
850
	c->offset = 0;
851
	c->aux = nil;	/* paranoia */
852
	return c;
853
}
854
 
855
static void
856
epclose(Ep *ep)
857
{
858
	qlock(ep);
859
	if(waserror()){
860
		qunlock(ep);
861
		nexterror();
862
	}
863
	if(ep->inuse){
864
		ep->hp->epclose(ep);
865
		ep->inuse = 0;
866
	}
867
	qunlock(ep);
868
	poperror();
869
}
870
 
871
static void
872
usbclose(Chan *c)
873
{
874
	int q;
875
	Ep *ep;
876
 
877
	q = QID(c->qid);
878
	if(q < Qep0dir || isqtype(q, Qepctl) || isqtype(q, Qepdir))
879
		return;
880
 
881
	ep = getep(qid2epidx(q));
882
	if(ep == nil)
883
		return;
884
	deprint("usbclose q %#x fid %d ref %ld\n", q, c->fid, ep->ref);
885
	if(waserror()){
886
		putep(ep);
887
		nexterror();
888
	}
889
	if(c->flag & COPEN){
890
		free(c->aux);
891
		c->aux = nil;
892
		epclose(ep);
893
		putep(ep);	/* release ref kept since usbopen */
894
		c->flag &= ~COPEN;
895
	}
896
	poperror();
897
	putep(ep);
898
}
899
 
900
static long
901
ctlread(Chan *c, void *a, long n, vlong offset)
902
{
903
	int q;
904
	char *s;
905
	char *us;
906
	char *se;
907
	Ep *ep;
908
	int i;
909
 
910
	q = QID(c->qid);
911
	us = s = smalloc(READSTR);
912
	se = s + READSTR;
913
	if(waserror()){
914
		free(us);
915
		nexterror();
916
	}
917
	if(q == Qctl)
918
		for(i = 0; i < epmax; i++){
919
			ep = getep(i);
920
			if(ep != nil){
921
				if(waserror()){
922
					putep(ep);
923
					nexterror();
924
				}
925
				s = seprint(s, se, "ep%d.%d ", ep->dev->nb, ep->nb);
926
				s = seprintep(s, se, ep, 0);
927
				poperror();
928
			}
929
			putep(ep);
930
		}
931
	else{
932
		ep = getep(qid2epidx(q));
933
		if(ep == nil)
934
			error(Eio);
935
		if(waserror()){
936
			putep(ep);
937
			nexterror();
938
		}
939
		if(c->aux != nil){
940
			/* After a new endpoint request we read
941
			 * the new endpoint name back.
942
			 */
943
			strecpy(s, se, c->aux);
944
			free(c->aux);
945
			c->aux = nil;
946
		}else
947
			seprintep(s, se, ep, 0);
948
		poperror();
949
		putep(ep);
950
	}
951
	n = readstr(offset, a, n, us);
952
	poperror();
953
	free(us);
954
	return n;
955
}
956
 
957
/*
958
 * Fake root hub emulation.
959
 */
960
static long
961
rhubread(Ep *ep, void *a, long n)
962
{
963
	char *b;
964
 
965
	if(ep->dev->isroot == 0 || ep->nb != 0 || n < 2)
966
		return -1;
967
	if(ep->rhrepl < 0)
968
		return -1;
969
 
970
	b = a;
971
	memset(b, 0, n);
972
	PUT2(b, ep->rhrepl);
973
	ep->rhrepl = -1;
974
	return n;
975
}
976
 
977
static long
978
rhubwrite(Ep *ep, void *a, long n)
979
{
980
	uchar *s;
981
	int cmd;
982
	int feature;
983
	int port;
984
	Hci *hp;
985
 
986
	if(ep->dev == nil || ep->dev->isroot == 0 || ep->nb != 0)
987
		return -1;
988
	if(n != Rsetuplen)
989
		error("root hub is a toy hub");
990
	ep->rhrepl = -1;
991
	s = a;
992
	if(s[Rtype] != (Rh2d|Rclass|Rother) && s[Rtype] != (Rd2h|Rclass|Rother))
993
		error("root hub is a toy hub");
994
	hp = ep->hp;
995
	cmd = s[Rreq];
996
	feature = GET2(s+Rvalue);
997
	port = GET2(s+Rindex);
998
	if(port < 1 || port > hp->nports)
999
		error("bad hub port number");
1000
	switch(feature){
1001
	case Rportenable:
1002
		ep->rhrepl = hp->portenable(hp, port, cmd == Rsetfeature);
1003
		break;
1004
	case Rportreset:
1005
		ep->rhrepl = hp->portreset(hp, port, cmd == Rsetfeature);
1006
		break;
1007
	case Rgetstatus:
1008
		ep->rhrepl = hp->portstatus(hp, port);
1009
		break;
1010
	default:
1011
		ep->rhrepl = 0;
1012
	}
1013
	return n;
1014
}
1015
 
1016
static long
1017
usbread(Chan *c, void *a, long n, vlong offset)
1018
{
1019
	int q;
1020
	Ep *ep;
1021
	int nr;
1022
 
1023
	q = QID(c->qid);
1024
 
1025
	if(c->qid.type == QTDIR)
1026
		return devdirread(c, a, n, nil, 0, usbgen);
1027
 
1028
	if(q == Qctl || isqtype(q, Qepctl))
1029
		return ctlread(c, a, n, offset);
1030
 
1031
	ep = getep(qid2epidx(q));
1032
	if(ep == nil)
1033
		error(Eio);
1034
	if(waserror()){
1035
		putep(ep);
1036
		nexterror();
1037
	}
1038
	if(ep->dev->state == Ddetach)
1039
		error(Edetach);
1040
	if(ep->mode == OWRITE || ep->inuse == 0)
1041
		error(Ebadusefd);
1042
	switch(ep->ttype){
1043
	case Tnone:
1044
		error("endpoint not configured");
1045
	case Tctl:
1046
		nr = rhubread(ep, a, n);
1047
		if(nr >= 0){
1048
			n = nr;
1049
			break;
1050
		}
1051
		/* else fall */
1052
	default:
1053
		ddeprint("\nusbread q %#x fid %d cnt %ld off %lld\n",q,c->fid,n,offset);
1054
		n = ep->hp->epread(ep, a, n);
1055
		break;
1056
	}
1057
	poperror();
1058
	putep(ep);
1059
	return n;
1060
}
1061
 
1062
static long
1063
pow2(int n)
1064
{
1065
	return 1 << n;
1066
}
1067
 
1068
static void
1069
setmaxpkt(Ep *ep, char* s)
1070
{
1071
	long spp;	/* samples per packet */
1072
 
1073
	if(ep->dev->speed == Highspeed)
1074
		spp = (ep->hz * ep->pollival * ep->ntds + 7999) / 8000;
1075
	else
1076
		spp = (ep->hz * ep->pollival + 999) / 1000;
1077
	ep->maxpkt = spp * ep->samplesz;
1078
	deprint("usb: %s: setmaxpkt: hz %ld poll %ld"
1079
		" ntds %d %s speed -> spp %ld maxpkt %ld\n", s,
1080
		ep->hz, ep->pollival, ep->ntds, spname[ep->dev->speed],
1081
		spp, ep->maxpkt);
1082
	if(ep->maxpkt > 1024){
1083
		print("usb: %s: maxpkt %ld > 1024. truncating\n", s, ep->maxpkt);
1084
		ep->maxpkt = 1024;
1085
	}
1086
}
1087
 
1088
/*
1089
 * Many endpoint ctls. simply update the portable representation
1090
 * of the endpoint. The actual controller driver will look
1091
 * at them to setup the endpoints as dictated.
1092
 */
1093
static long
1094
epctl(Ep *ep, Chan *c, void *a, long n)
1095
{
1096
	int i, l, mode, nb, tt;
1097
	char *b, *s;
1098
	Cmdbuf *cb;
1099
	Cmdtab *ct;
1100
	Ep *nep;
1101
	Udev *d;
1102
	static char *Info = "info ";
1103
 
1104
	d = ep->dev;
1105
 
1106
	cb = parsecmd(a, n);
1107
	if(waserror()){
1108
		free(cb);
1109
		nexterror();
1110
	}
1111
	ct = lookupcmd(cb, epctls, nelem(epctls));
1112
	if(ct == nil)
1113
		error(Ebadctl);
1114
	i = ct->index;
1115
	if(i == CMnew || i == CMspeed || i == CMhub || i == CMpreset)
1116
		if(ep != ep->ep0)
1117
			error("allowed only on a setup endpoint");
1118
	if(i != CMclrhalt && i != CMdetach && i != CMdebugep && i != CMname)
1119
		if(ep != ep->ep0 && ep->inuse != 0)
1120
			error("must configure before using");
1121
	switch(i){
1122
	case CMnew:
1123
		deprint("usb epctl %s\n", cb->f[0]);
1124
		nb = strtol(cb->f[1], nil, 0);
1125
		if(nb < 0 || nb >= Ndeveps)
1126
			error("bad endpoint number");
1127
		tt = name2ttype(cb->f[2]);
1128
		if(tt == Tnone)
1129
			error("unknown endpoint type");
1130
		mode = name2mode(cb->f[3]);
1131
		if(mode < 0)
1132
			error("unknown i/o mode");
1133
		newdevep(ep, nb, tt, mode);
1134
		break;
1135
	case CMnewdev:
1136
		deprint("usb epctl %s\n", cb->f[0]);
1137
		if(ep != ep->ep0 || d->ishub == 0)
1138
			error("not a hub setup endpoint");
1139
		l = name2speed(cb->f[1]);
1140
		if(l == Nospeed)
1141
			error("speed must be full|low|high");
1142
		nep = newdev(ep->hp, 0, 0);
1143
		nep->dev->speed = l;
1144
		if(nep->dev->speed  != Lowspeed)
1145
			nep->maxpkt = 64;	/* assume full speed */
1146
		nep->dev->hub = d->nb;
1147
		nep->dev->port = atoi(cb->f[2]);
1148
		/* next read request will read
1149
		 * the name for the new endpoint
1150
		 */
1151
		l = sizeof(up->genbuf);
1152
		snprint(up->genbuf, l, "ep%d.%d", nep->dev->nb, nep->nb);
1153
		kstrdup(&c->aux, up->genbuf);
1154
		break;
1155
	case CMhub:
1156
		deprint("usb epctl %s\n", cb->f[0]);
1157
		d->ishub = 1;
1158
		break;
1159
	case CMspeed:
1160
		l = name2speed(cb->f[1]);
1161
		deprint("usb epctl %s %d\n", cb->f[0], l);
1162
		if(l == Nospeed)
1163
			error("speed must be full|low|high");
1164
		qlock(ep->ep0);
1165
		d->speed = l;
1166
		qunlock(ep->ep0);
1167
		break;
1168
	case CMmaxpkt:
1169
		l = strtoul(cb->f[1], nil, 0);
1170
		deprint("usb epctl %s %d\n", cb->f[0], l);
1171
		if(l < 1 || l > 1024)
1172
			error("maxpkt not in [1:1024]");
1173
		qlock(ep);
1174
		ep->maxpkt = l;
1175
		qunlock(ep);
1176
		break;
1177
	case CMntds:
1178
		l = strtoul(cb->f[1], nil, 0);
1179
		deprint("usb epctl %s %d\n", cb->f[0], l);
1180
		if(l < 1 || l > 3)
1181
			error("ntds not in [1:3]");
1182
		qlock(ep);
1183
		ep->ntds = l;
1184
		qunlock(ep);
1185
		break;
1186
	case CMpollival:
1187
		if(ep->ttype != Tintr && ep->ttype != Tiso)
1188
			error("not an intr or iso endpoint");
1189
		l = strtoul(cb->f[1], nil, 0);
1190
		deprint("usb epctl %s %d\n", cb->f[0], l);
1191
		if(ep->ttype == Tiso ||
1192
		   (ep->ttype == Tintr && ep->dev->speed == Highspeed)){
1193
			if(l < 1 || l > 16)
1194
				error("pollival power not in [1:16]");
1195
			l = pow2(l-1);
1196
		}else
1197
			if(l < 1 || l > 255)
1198
				error("pollival not in [1:255]");
1199
		qlock(ep);
1200
		ep->pollival = l;
1201
		if(ep->ttype == Tiso)
1202
			setmaxpkt(ep, "pollival");
1203
		qunlock(ep);
1204
		break;
1205
	case CMsamplesz:
1206
		if(ep->ttype != Tiso)
1207
			error("not an iso endpoint");
1208
		l = strtoul(cb->f[1], nil, 0);
1209
		deprint("usb epctl %s %d\n", cb->f[0], l);
1210
		if(l <= 0 || l > 8)
1211
			error("samplesz not in [1:8]");
1212
		qlock(ep);
1213
		ep->samplesz = l;
1214
		setmaxpkt(ep, "samplesz");
1215
		qunlock(ep);
1216
		break;
1217
	case CMhz:
1218
		if(ep->ttype != Tiso)
1219
			error("not an iso endpoint");
1220
		l = strtoul(cb->f[1], nil, 0);
1221
		deprint("usb epctl %s %d\n", cb->f[0], l);
1222
		if(l <= 0 || l > 100000)
1223
			error("hz not in [1:100000]");
1224
		qlock(ep);
1225
		ep->hz = l;
1226
		setmaxpkt(ep, "hz");
1227
		qunlock(ep);
1228
		break;
1229
	case CMclrhalt:
1230
		qlock(ep);
1231
		deprint("usb epctl %s\n", cb->f[0]);
1232
		ep->clrhalt = 1;
1233
		qunlock(ep);
1234
		break;
1235
	case CMinfo:
1236
		deprint("usb epctl %s\n", cb->f[0]);
1237
		l = strlen(Info);
1238
		s = a;
1239
		if(n < l+2 || strncmp(Info, s, l) != 0)
1240
			error(Ebadctl);
1241
		if(n > 1024)
1242
			n = 1024;
1243
		b = smalloc(n);
1244
		memmove(b, s+l, n-l);
1245
		b[n-l] = 0;
1246
		if(b[n-l-1] == '\n')
1247
			b[n-l-1] = 0;
1248
		qlock(ep);
1249
		free(ep->info);
1250
		ep->info = b;
1251
		qunlock(ep);
1252
		break;
1253
	case CMaddress:
1254
		deprint("usb epctl %s\n", cb->f[0]);
1255
		ep->dev->state = Denabled;
1256
		break;
1257
	case CMdetach:
1258
		if(ep->dev->isroot != 0)
1259
			error("can't detach a root hub");
1260
		deprint("usb epctl %s ep%d.%d\n",
1261
			cb->f[0], ep->dev->nb, ep->nb);
1262
		ep->dev->state = Ddetach;
1263
		/* Release file system ref. for its endpoints */
1264
		for(i = 0; i < nelem(ep->dev->eps); i++)
1265
			putep(ep->dev->eps[i]);
1266
		break;
1267
	case CMdebugep:
1268
		if(strcmp(cb->f[1], "on") == 0)
1269
			ep->debug = 1;
1270
		else if(strcmp(cb->f[1], "off") == 0)
1271
			ep->debug = 0;
1272
		else
1273
			ep->debug = strtoul(cb->f[1], nil, 0);
1274
		print("usb: ep%d.%d debug %d\n",
1275
			ep->dev->nb, ep->nb, ep->debug);
1276
		break;
1277
	case CMname:
1278
		deprint("usb epctl %s %s\n", cb->f[0], cb->f[1]);
1279
		validname(cb->f[1], 0);
1280
		kstrdup(&ep->name, cb->f[1]);
1281
		break;
1282
	case CMtmout:
1283
		deprint("usb epctl %s\n", cb->f[0]);
1284
		if(ep->ttype == Tiso || ep->ttype == Tctl)
1285
			error("ctl ignored for this endpoint type");
1286
		ep->tmout = strtoul(cb->f[1], nil, 0);
1287
		if(ep->tmout != 0 && ep->tmout < Xfertmout)
1288
			ep->tmout = Xfertmout;
1289
		break;
1290
	case CMpreset:
1291
		deprint("usb epctl %s\n", cb->f[0]);
1292
		if(ep->ttype != Tctl)
1293
			error("not a control endpoint");
1294
		if(ep->dev->state != Denabled)
1295
			error("forbidden on devices not enabled");
1296
		ep->dev->state = Dreset;
1297
		break;
1298
	default:
1299
		panic("usb: unknown epctl %d", ct->index);
1300
	}
1301
	free(cb);
1302
	poperror();
1303
	return n;
1304
}
1305
 
1306
static long
1307
usbctl(void *a, long n)
1308
{
1309
	Cmdtab *ct;
1310
	Cmdbuf *cb;
1311
	Ep *ep;
1312
	int i;
1313
 
1314
	cb = parsecmd(a, n);
1315
	if(waserror()){
1316
		free(cb);
1317
		nexterror();
1318
	}
1319
	ct = lookupcmd(cb, usbctls, nelem(usbctls));
1320
	dprint("usb ctl %s\n", cb->f[0]);
1321
	switch(ct->index){
1322
	case CMdebug:
1323
		if(strcmp(cb->f[1], "on") == 0)
1324
			debug = 1;
1325
		else if(strcmp(cb->f[1], "off") == 0)
1326
			debug = 0;
1327
		else
1328
			debug = strtol(cb->f[1], nil, 0);
1329
		print("usb: debug %d\n", debug);
1330
		for(i = 0; i < epmax; i++)
1331
			if((ep = getep(i)) != nil){
1332
				ep->hp->debug(ep->hp, debug);
1333
				putep(ep);
1334
			}
1335
		break;
1336
	case CMdump:
1337
		dumpeps();
1338
		break;
1339
	}
1340
	free(cb);
1341
	poperror();
1342
	return n;
1343
}
1344
 
1345
static long
1346
ctlwrite(Chan *c, void *a, long n)
1347
{
1348
	int q;
1349
	Ep *ep;
1350
 
1351
	q = QID(c->qid);
1352
	if(q == Qctl)
1353
		return usbctl(a, n);
1354
 
1355
	ep = getep(qid2epidx(q));
1356
	if(ep == nil)
1357
		error(Eio);
1358
	if(waserror()){
1359
		putep(ep);
1360
		nexterror();
1361
	}
1362
	if(ep->dev->state == Ddetach)
1363
		error(Edetach);
1364
	if(isqtype(q, Qepctl) && c->aux != nil){
1365
		/* Be sure we don't keep a cloned ep name */
1366
		free(c->aux);
1367
		c->aux = nil;
1368
		error("read, not write, expected");
1369
	}
1370
	n = epctl(ep, c, a, n);
1371
	putep(ep);
1372
	poperror();
1373
	return n;
1374
}
1375
 
1376
static long
1377
usbwrite(Chan *c, void *a, long n, vlong off)
1378
{
1379
	int nr, q;
1380
	Ep *ep;
1381
 
1382
	if(c->qid.type == QTDIR)
1383
		error(Eisdir);
1384
 
1385
	q = QID(c->qid);
1386
 
1387
	if(q == Qctl || isqtype(q, Qepctl))
1388
		return ctlwrite(c, a, n);
1389
 
1390
	ep = getep(qid2epidx(q));
1391
	if(ep == nil)
1392
		error(Eio);
1393
	if(waserror()){
1394
		putep(ep);
1395
		nexterror();
1396
	}
1397
	if(ep->dev->state == Ddetach)
1398
		error(Edetach);
1399
	if(ep->mode == OREAD || ep->inuse == 0)
1400
		error(Ebadusefd);
1401
 
1402
	switch(ep->ttype){
1403
	case Tnone:
1404
		error("endpoint not configured");
1405
	case Tctl:
1406
		nr = rhubwrite(ep, a, n);
1407
		if(nr >= 0){
1408
			n = nr;
1409
			break;
1410
		}
1411
		/* else fall */
1412
	default:
1413
		ddeprint("\nusbwrite q %#x fid %d cnt %ld off %lld\n",q, c->fid, n, off);
1414
		ep->hp->epwrite(ep, a, n);
1415
	}
1416
	putep(ep);
1417
	poperror();
1418
	return n;
1419
}
1420
 
1421
void
1422
usbshutdown(void)
1423
{
1424
	Hci *hp;
1425
	int i;
1426
 
1427
	for(i = 0; i < Nhcis; i++){
1428
		hp = hcis[i];
1429
		if(hp == nil)
1430
			continue;
1431
		if(hp->shutdown == nil)
1432
			print("#u: no shutdown function for %s\n", hp->type);
1433
		else
1434
			hp->shutdown(hp);
1435
	}
1436
}
1437
 
1438
Dev usbdevtab = {
1439
	L'u',
1440
	"usb",
1441
 
1442
	usbreset,
1443
	usbinit,
1444
	usbshutdown,
1445
	usbattach,
1446
	usbwalk,
1447
	usbstat,
1448
	usbopen,
1449
	devcreate,
1450
	usbclose,
1451
	usbread,
1452
	devbread,
1453
	usbwrite,
1454
	devbwrite,
1455
	devremove,
1456
	devwstat,
1457
};