xref: /plan9-contrib/sys/src/cmd/usb/lib/dump.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
1*9a747e4fSDavid du Colombier #include <u.h>
2*9a747e4fSDavid du Colombier #include <libc.h>
3*9a747e4fSDavid du Colombier #include <thread.h>
4*9a747e4fSDavid du Colombier #include <bio.h>
5*9a747e4fSDavid du Colombier #include "usb.h"
6*9a747e4fSDavid du Colombier 
7*9a747e4fSDavid du Colombier static char *type[] =
8*9a747e4fSDavid du Colombier {
9*9a747e4fSDavid du Colombier 	[Econtrol]		"Control",
10*9a747e4fSDavid du Colombier 	[Eiso]		"Isochronous",
11*9a747e4fSDavid du Colombier 	[Ebulk]		"Bulk",
12*9a747e4fSDavid du Colombier 	[Eintr]		"Interrupt",
13*9a747e4fSDavid du Colombier };
14*9a747e4fSDavid du Colombier 
15*9a747e4fSDavid du Colombier static char *isotype[] =
16*9a747e4fSDavid du Colombier {
17*9a747e4fSDavid du Colombier 	[Eunknown]	"",
18*9a747e4fSDavid du Colombier 	[Easync]		" (Asynchronous)",
19*9a747e4fSDavid du Colombier 	[Eadapt]		" (Adaptive)",
20*9a747e4fSDavid du Colombier 	[Esync]		" (Synchronous)",
21*9a747e4fSDavid du Colombier };
22*9a747e4fSDavid du Colombier 
23*9a747e4fSDavid du Colombier void
24*9a747e4fSDavid du Colombier dumpstring(int fd, char *prefix, Device *d, int index)
25*9a747e4fSDavid du Colombier {
26*9a747e4fSDavid du Colombier 	char *s;
27*9a747e4fSDavid du Colombier 
28*9a747e4fSDavid du Colombier 	if(index == 0)
29*9a747e4fSDavid du Colombier 		return;
30*9a747e4fSDavid du Colombier 	s = d->strings[index];
31*9a747e4fSDavid du Colombier 	if(s == nil)
32*9a747e4fSDavid du Colombier 		fprint(fd, "%s<string %d>\n", prefix, index);
33*9a747e4fSDavid du Colombier 	else
34*9a747e4fSDavid du Colombier 		fprint(fd, "%s%s\n", prefix, s);
35*9a747e4fSDavid du Colombier }
36*9a747e4fSDavid du Colombier 
37*9a747e4fSDavid du Colombier void
38*9a747e4fSDavid du Colombier dumpdesc(int fd, char *prefix, Ddesc *desc)
39*9a747e4fSDavid du Colombier {
40*9a747e4fSDavid du Colombier 	uchar *p;
41*9a747e4fSDavid du Colombier 	int i, j, len;
42*9a747e4fSDavid du Colombier 
43*9a747e4fSDavid du Colombier 	if(desc->ndesc == 0)
44*9a747e4fSDavid du Colombier 		return;
45*9a747e4fSDavid du Colombier 	fprint(fd, "%s%d descriptors\n", prefix, desc->ndesc);
46*9a747e4fSDavid du Colombier 	p = desc->data;
47*9a747e4fSDavid du Colombier 	for(i = 0; i < desc->ndesc; i++) {
48*9a747e4fSDavid du Colombier 		fprint(fd, "%s\t", prefix);
49*9a747e4fSDavid du Colombier 		len = *p++;
50*9a747e4fSDavid du Colombier 		for(j = 1; j < len; j++)
51*9a747e4fSDavid du Colombier 			fprint(fd, "%.2ux ", *p++);
52*9a747e4fSDavid du Colombier 		fprint(fd, "\n");
53*9a747e4fSDavid du Colombier 	}
54*9a747e4fSDavid du Colombier }
55*9a747e4fSDavid du Colombier 
56*9a747e4fSDavid du Colombier void
57*9a747e4fSDavid du Colombier dumpdevice(int fd, Device *d)
58*9a747e4fSDavid du Colombier {
59*9a747e4fSDavid du Colombier 	int i, j, k;
60*9a747e4fSDavid du Colombier 	Dconf *c;
61*9a747e4fSDavid du Colombier 	Dinf *intf;
62*9a747e4fSDavid du Colombier 	Dalt *alt;
63*9a747e4fSDavid du Colombier 	Endpt *ep;
64*9a747e4fSDavid du Colombier 
65*9a747e4fSDavid du Colombier 	fprint(fd, "device %D: %lud.%lud.%lud %.4x/%.4x\n",
66*9a747e4fSDavid du Colombier 		d, Class(d->csp), Subclass(d->csp), Proto(d->csp), d->vid, d->did);
67*9a747e4fSDavid du Colombier 	fprint(fd, "\tUSB version: %x.%.2x\n", d->vers>>8, d->vers&0xff);
68*9a747e4fSDavid du Colombier 	fprint(fd, "\tmaximum control packet size: %d\n", d->max0);
69*9a747e4fSDavid du Colombier 	fprint(fd, "\tdevice release: %x.%.2x\n", d->release>>8, d->release&0xff);
70*9a747e4fSDavid du Colombier 	dumpstring(fd, "\tmanufacturer: ", d, d->manufacturer);
71*9a747e4fSDavid du Colombier 	dumpstring(fd, "\tproduct: ", d, d->product);
72*9a747e4fSDavid du Colombier 	dumpstring(fd, "\tserial: ", d, d->serial);
73*9a747e4fSDavid du Colombier 	fprint(fd, "\tconfigurations: %d\n", d->nconf);
74*9a747e4fSDavid du Colombier 	for(i = 0; i < d->nconf; i++) {
75*9a747e4fSDavid du Colombier 		c = &d->config[i];
76*9a747e4fSDavid du Colombier 		fprint(fd, "\t\tconfiguration %d: %d interfaces, %dmA required\n", c->cval, c->nif, c->milliamps);
77*9a747e4fSDavid du Colombier 		dumpstring(fd, "\t\tname: ", d, c->config);
78*9a747e4fSDavid du Colombier 		fprint(fd, "\t\tattributes:");
79*9a747e4fSDavid du Colombier 		if(c->attrib & Cbuspowered)
80*9a747e4fSDavid du Colombier 			fprint(fd, " buspowered");
81*9a747e4fSDavid du Colombier 		if(c->attrib & Cselfpowered)
82*9a747e4fSDavid du Colombier 			fprint(fd, " selfpowered");
83*9a747e4fSDavid du Colombier 		if(c->attrib & Cremotewakeup)
84*9a747e4fSDavid du Colombier 			fprint(fd, " remotewakeup");
85*9a747e4fSDavid du Colombier 		fprint(fd, "\n");
86*9a747e4fSDavid du Colombier 		dumpdesc(fd, "\t\t\t", &c->desc);
87*9a747e4fSDavid du Colombier 		for(j = 0; j < c->nif; j++) {
88*9a747e4fSDavid du Colombier 			intf = &c->iface[j];
89*9a747e4fSDavid du Colombier 			fprint(fd, "\t\tinterface %d: %lud.%lud.%lud\n", j, Class(intf->csp), Subclass(intf->csp), Proto(intf->csp));
90*9a747e4fSDavid du Colombier 			dumpstring(fd, "\t\tname: ", d, intf->interface);
91*9a747e4fSDavid du Colombier 			for(alt = intf->alt; alt != nil; alt = alt->next) {
92*9a747e4fSDavid du Colombier 				fprint(fd, "\t\t\talternate %d: %d endpoints\n", alt->alt, alt->npt);
93*9a747e4fSDavid du Colombier 				dumpdesc(fd, "\t\t\t\t", &alt->desc);
94*9a747e4fSDavid du Colombier 				for(k = 0; k < alt->npt; k++) {
95*9a747e4fSDavid du Colombier 					ep = &alt->ep[k];
96*9a747e4fSDavid du Colombier 					fprint(2, "\t\t\t\tendpoint %d-%s: type %s%s maxpkt %d poll %dms\n",
97*9a747e4fSDavid du Colombier 						ep->addr, ep->dir == Ein ? "in" : "out", type[ep->type], isotype[ep->isotype],
98*9a747e4fSDavid du Colombier 						ep->maxpkt, ep->pollms);
99*9a747e4fSDavid du Colombier 					dumpdesc(fd, "\t\t\t\t\t", &ep->desc);
100*9a747e4fSDavid du Colombier 				}
101*9a747e4fSDavid du Colombier 			}
102*9a747e4fSDavid du Colombier 		}
103*9a747e4fSDavid du Colombier 	}
104*9a747e4fSDavid du Colombier }
105