xref: /plan9/sys/src/cmd/usb/lib/dump.c (revision 906943f9f6b8411972abb5e3a03ed19f74be7ccc)
19a747e4fSDavid du Colombier #include <u.h>
29a747e4fSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <thread.h>
49a747e4fSDavid du Colombier #include <bio.h>
59a747e4fSDavid du Colombier #include "usb.h"
69a747e4fSDavid du Colombier 
7*906943f9SDavid du Colombier int usbdebug;
87f0337cdSDavid du Colombier 
9*906943f9SDavid du Colombier static char *edir[] = {"in", "out", "inout"};
10*906943f9SDavid du Colombier static char *etype[] = {"ctl", "iso", "bulk", "intr"};
11*906943f9SDavid du Colombier static char* cnames[] =
12*906943f9SDavid du Colombier {
13*906943f9SDavid du Colombier 	"none", "audio", "comms", "hid", "",
14*906943f9SDavid du Colombier 	"", "", "printer", "storage", "hub", "data"
159a747e4fSDavid du Colombier };
16*906943f9SDavid du Colombier static char* devstates[] =
17*906943f9SDavid du Colombier {
18*906943f9SDavid du Colombier 	"detached", "attached", "enabled", "assigned", "configured"
199a747e4fSDavid du Colombier };
209a747e4fSDavid du Colombier 
217f0337cdSDavid du Colombier char*
22*906943f9SDavid du Colombier classname(int c)
237f0337cdSDavid du Colombier {
24*906943f9SDavid du Colombier 	static char buf[30];
257f0337cdSDavid du Colombier 
26*906943f9SDavid du Colombier 	if(c >= 0 && c < nelem(cnames))
27*906943f9SDavid du Colombier 		return cnames[c];
287f0337cdSDavid du Colombier 	else{
29*906943f9SDavid du Colombier 		seprint(buf, buf+30, "%d", c);
30*906943f9SDavid du Colombier 		return buf;
317f0337cdSDavid du Colombier 	}
329a747e4fSDavid du Colombier }
339a747e4fSDavid du Colombier 
34*906943f9SDavid du Colombier char*
35*906943f9SDavid du Colombier hexstr(void *a, int n)
369a747e4fSDavid du Colombier {
37*906943f9SDavid du Colombier 	int i;
38*906943f9SDavid du Colombier 	uchar *b;
39*906943f9SDavid du Colombier 	char *dbuff;
407f0337cdSDavid du Colombier 	char *s;
41*906943f9SDavid du Colombier 	char *e;
427f0337cdSDavid du Colombier 
43*906943f9SDavid du Colombier 	b = a;
44*906943f9SDavid du Colombier 	dbuff = s = emallocz(1024, 0);
45*906943f9SDavid du Colombier 	*s = 0;
46*906943f9SDavid du Colombier 	e = s+1024;
47*906943f9SDavid du Colombier 	for(i=0; i < n; i++)
48*906943f9SDavid du Colombier 		s = seprint(s, e, " %.2ux", b[i]);
49*906943f9SDavid du Colombier 	if(s == e)
50*906943f9SDavid du Colombier 		fprint(2, "%s: usb/lib: hexdump: bug: small buffer\n", argv0);
51*906943f9SDavid du Colombier 	return dbuff;
527f0337cdSDavid du Colombier }
537f0337cdSDavid du Colombier 
54*906943f9SDavid du Colombier static char*
55*906943f9SDavid du Colombier seprintiface(char *s, char *e, Iface *i)
567f0337cdSDavid du Colombier {
57*906943f9SDavid du Colombier 	int	j;
58*906943f9SDavid du Colombier 	Altc	*a;
59*906943f9SDavid du Colombier 	Ep	*ep;
60*906943f9SDavid du Colombier 	char	*eds, *ets;
617f0337cdSDavid du Colombier 
62*906943f9SDavid du Colombier 	s = seprint(s, e, "\t\tiface csp %s.%uld.%uld\n",
63*906943f9SDavid du Colombier 		classname(Class(i->csp)), Subclass(i->csp), Proto(i->csp));
64*906943f9SDavid du Colombier 	for(j = 0; j < Naltc; j++){
65*906943f9SDavid du Colombier 		a=i->altc[j];
66*906943f9SDavid du Colombier 		if(a == nil)
677f0337cdSDavid du Colombier 			break;
68*906943f9SDavid du Colombier 		s = seprint(s, e, "\t\t  alt %d attr %d ival %d",
69*906943f9SDavid du Colombier 			j, a->attrib, a->interval);
70*906943f9SDavid du Colombier 		if(a->aux != nil)
71*906943f9SDavid du Colombier 			s = seprint(s, e, " devspec %p\n", a->aux);
727f0337cdSDavid du Colombier 		else
73*906943f9SDavid du Colombier 			s = seprint(s, e, "\n");
747f0337cdSDavid du Colombier 	}
75*906943f9SDavid du Colombier 	for(j = 0; j < Nep; j++){
76*906943f9SDavid du Colombier 		ep = i->ep[j];
77*906943f9SDavid du Colombier 		if(ep == nil)
787f0337cdSDavid du Colombier 			break;
79*906943f9SDavid du Colombier 		eds = ets = "";
80*906943f9SDavid du Colombier 		if(ep->dir <= nelem(edir))
81*906943f9SDavid du Colombier 			eds = edir[ep->dir];
82*906943f9SDavid du Colombier 		if(ep->type <= nelem(etype))
83*906943f9SDavid du Colombier 			ets = etype[ep->type];
84*906943f9SDavid du Colombier 		s = seprint(s, e, "\t\t  ep id %d addr %d dir %s type %s"
85*906943f9SDavid du Colombier 			" itype %d maxpkt %d ntds %d\n",
86*906943f9SDavid du Colombier 			ep->id, ep->addr, eds, ets, ep->isotype,
87*906943f9SDavid du Colombier 			ep->maxpkt, ep->ntds);
887f0337cdSDavid du Colombier 	}
89*906943f9SDavid du Colombier 	return s;
907f0337cdSDavid du Colombier }
917f0337cdSDavid du Colombier 
92*906943f9SDavid du Colombier static char*
93*906943f9SDavid du Colombier seprintconf(char *s, char *e, Usbdev *d, int ci)
94*906943f9SDavid du Colombier {
95*906943f9SDavid du Colombier 	int i;
96*906943f9SDavid du Colombier 	Conf *c;
97*906943f9SDavid du Colombier 	char *hd;
98*906943f9SDavid du Colombier 
99*906943f9SDavid du Colombier 	c = d->conf[ci];
100*906943f9SDavid du Colombier 	s = seprint(s, e, "\tconf: cval %d attrib %x %d mA\n",
101*906943f9SDavid du Colombier 		c->cval, c->attrib, c->milliamps);
102*906943f9SDavid du Colombier 	for(i = 0; i < Niface; i++)
103*906943f9SDavid du Colombier 		if(c->iface[i] == nil)
10402c76561SDavid du Colombier 			break;
105*906943f9SDavid du Colombier 		else
106*906943f9SDavid du Colombier 			s = seprintiface(s, e, c->iface[i]);
107*906943f9SDavid du Colombier 	for(i = 0; i < Nddesc; i++)
108*906943f9SDavid du Colombier 		if(d->ddesc[i] == nil)
10902c76561SDavid du Colombier 			break;
110*906943f9SDavid du Colombier 		else if(d->ddesc[i]->conf == c){
111*906943f9SDavid du Colombier 			hd = hexstr((uchar*)&d->ddesc[i]->data,
112*906943f9SDavid du Colombier 				d->ddesc[i]->data.bLength);
113*906943f9SDavid du Colombier 			s = seprint(s, e, "\t\tdev desc %x[%d]: %s\n",
114*906943f9SDavid du Colombier 				d->ddesc[i]->data.bDescriptorType,
115*906943f9SDavid du Colombier 				d->ddesc[i]->data.bLength, hd);
116*906943f9SDavid du Colombier 			free(hd);
11702c76561SDavid du Colombier 		}
118*906943f9SDavid du Colombier 	return s;
119*906943f9SDavid du Colombier }
120*906943f9SDavid du Colombier 
121*906943f9SDavid du Colombier int
122*906943f9SDavid du Colombier Ufmt(Fmt *f)
123*906943f9SDavid du Colombier {
124*906943f9SDavid du Colombier 	int i;
125*906943f9SDavid du Colombier 	Dev *d;
126*906943f9SDavid du Colombier 	Usbdev *ud;
127*906943f9SDavid du Colombier 	char buf[1024];
128*906943f9SDavid du Colombier 	char *s, *e;
129*906943f9SDavid du Colombier 
130*906943f9SDavid du Colombier 	s = buf;
131*906943f9SDavid du Colombier 	e = buf+sizeof(buf);
132*906943f9SDavid du Colombier 	d = va_arg(f->args, Dev*);
133*906943f9SDavid du Colombier 	if(d == nil)
134*906943f9SDavid du Colombier 		return fmtprint(f, "<nildev>\n");
135*906943f9SDavid du Colombier 	s = seprint(s, e, "%s", d->dir);
136*906943f9SDavid du Colombier 	ud = d->usb;
137*906943f9SDavid du Colombier 	if(ud == nil)
138*906943f9SDavid du Colombier 		return fmtprint(f, "%s %ld refs\n", buf, d->ref);
139*906943f9SDavid du Colombier 	s = seprint(s, e, " csp %s.%uld.%uld",
140*906943f9SDavid du Colombier 		classname(Class(ud->csp)), Subclass(ud->csp), Proto(ud->csp));
141*906943f9SDavid du Colombier 	s = seprint(s, e, " vid %#ux did %#ux", ud->vid, ud->did);
142*906943f9SDavid du Colombier 	s = seprint(s, e, " refs %ld\n", d->ref);
143*906943f9SDavid du Colombier 	s = seprint(s, e, "\t%s %s %s\n", ud->vendor, ud->product, ud->serial);
144*906943f9SDavid du Colombier 	for(i = 0; i < Nconf; i++){
145*906943f9SDavid du Colombier 		if(ud->conf[i] == nil)
146208510e1SDavid du Colombier 			break;
147*906943f9SDavid du Colombier 		else
148*906943f9SDavid du Colombier 			s = seprintconf(s, e, ud, i);
1497f0337cdSDavid du Colombier 	}
150*906943f9SDavid du Colombier 	return fmtprint(f, "%s", buf);
1519a747e4fSDavid du Colombier }
152*906943f9SDavid du Colombier 
153*906943f9SDavid du Colombier char*
154*906943f9SDavid du Colombier estrdup(char *s)
155*906943f9SDavid du Colombier {
156*906943f9SDavid du Colombier 	char *d;
157*906943f9SDavid du Colombier 
158*906943f9SDavid du Colombier 	d = strdup(s);
159*906943f9SDavid du Colombier 	if(d == nil)
160*906943f9SDavid du Colombier 		sysfatal("strdup: %r");
161*906943f9SDavid du Colombier 	setmalloctag(d, getcallerpc(&s));
162*906943f9SDavid du Colombier 	return d;
1639a747e4fSDavid du Colombier }
164*906943f9SDavid du Colombier 
165*906943f9SDavid du Colombier void*
166*906943f9SDavid du Colombier emallocz(ulong size, int zero)
167*906943f9SDavid du Colombier {
168*906943f9SDavid du Colombier 	void *x;
169*906943f9SDavid du Colombier 
170*906943f9SDavid du Colombier 	x = malloc(size);
171*906943f9SDavid du Colombier 	if(x == nil)
172*906943f9SDavid du Colombier 		sysfatal("malloc: %r");
173*906943f9SDavid du Colombier 	if(zero)
174*906943f9SDavid du Colombier 		memset(x, 0, size);
175*906943f9SDavid du Colombier 	setmalloctag(x, getcallerpc(&size));
176*906943f9SDavid du Colombier 	return x;
177*906943f9SDavid du Colombier }
178*906943f9SDavid du Colombier 
179