xref: /plan9/sys/src/cmd/usb/lib/dump.c (revision bfb6eab9346d861b5f68a2b1af55a1768a8fe25b)
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 
7906943f9SDavid du Colombier int usbdebug;
87f0337cdSDavid du Colombier 
9906943f9SDavid du Colombier static char *edir[] = {"in", "out", "inout"};
10906943f9SDavid du Colombier static char *etype[] = {"ctl", "iso", "bulk", "intr"};
11906943f9SDavid du Colombier static char* cnames[] =
12906943f9SDavid du Colombier {
13906943f9SDavid du Colombier 	"none", "audio", "comms", "hid", "",
14906943f9SDavid du Colombier 	"", "", "printer", "storage", "hub", "data"
159a747e4fSDavid du Colombier };
16906943f9SDavid du Colombier static char* devstates[] =
17906943f9SDavid du Colombier {
18906943f9SDavid du Colombier 	"detached", "attached", "enabled", "assigned", "configured"
199a747e4fSDavid du Colombier };
209a747e4fSDavid du Colombier 
217f0337cdSDavid du Colombier char*
classname(int c)22906943f9SDavid du Colombier classname(int c)
237f0337cdSDavid du Colombier {
24906943f9SDavid du Colombier 	static char buf[30];
257f0337cdSDavid du Colombier 
26906943f9SDavid du Colombier 	if(c >= 0 && c < nelem(cnames))
27906943f9SDavid du Colombier 		return cnames[c];
287f0337cdSDavid du Colombier 	else{
29906943f9SDavid du Colombier 		seprint(buf, buf+30, "%d", c);
30906943f9SDavid du Colombier 		return buf;
317f0337cdSDavid du Colombier 	}
329a747e4fSDavid du Colombier }
339a747e4fSDavid du Colombier 
34906943f9SDavid du Colombier char *
hexstr(void * a,int n)35906943f9SDavid du Colombier hexstr(void *a, int n)
369a747e4fSDavid du Colombier {
37906943f9SDavid du Colombier 	int i;
38*bfb6eab9SDavid du Colombier 	char *dbuff, *s, *e;
39906943f9SDavid du Colombier 	uchar *b;
407f0337cdSDavid du Colombier 
41906943f9SDavid du Colombier 	b = a;
42906943f9SDavid du Colombier 	dbuff = s = emallocz(1024, 0);
43906943f9SDavid du Colombier 	*s = 0;
44906943f9SDavid du Colombier 	e = s + 1024;
45906943f9SDavid du Colombier 	for(i = 0; i < n; i++)
46906943f9SDavid du Colombier 		s = seprint(s, e, " %.2ux", b[i]);
47906943f9SDavid du Colombier 	if(s == e)
48906943f9SDavid du Colombier 		fprint(2, "%s: usb/lib: hexdump: bug: small buffer\n", argv0);
49906943f9SDavid du Colombier 	return dbuff;
507f0337cdSDavid du Colombier }
517f0337cdSDavid du Colombier 
52906943f9SDavid du Colombier static char *
seprintiface(char * s,char * e,Iface * i)53906943f9SDavid du Colombier seprintiface(char *s, char *e, Iface *i)
547f0337cdSDavid du Colombier {
55906943f9SDavid du Colombier 	int	j;
56906943f9SDavid du Colombier 	Altc	*a;
57906943f9SDavid du Colombier 	Ep	*ep;
58906943f9SDavid du Colombier 	char	*eds, *ets;
597f0337cdSDavid du Colombier 
60906943f9SDavid du Colombier 	s = seprint(s, e, "\t\tiface csp %s.%uld.%uld\n",
61906943f9SDavid du Colombier 		classname(Class(i->csp)), Subclass(i->csp), Proto(i->csp));
62906943f9SDavid du Colombier 	for(j = 0; j < Naltc; j++){
63906943f9SDavid du Colombier 		a=i->altc[j];
64906943f9SDavid du Colombier 		if(a == nil)
657f0337cdSDavid du Colombier 			break;
66906943f9SDavid du Colombier 		s = seprint(s, e, "\t\t  alt %d attr %d ival %d",
67906943f9SDavid du Colombier 			j, a->attrib, a->interval);
68906943f9SDavid du Colombier 		if(a->aux != nil)
69906943f9SDavid du Colombier 			s = seprint(s, e, " devspec %p\n", a->aux);
707f0337cdSDavid du Colombier 		else
71906943f9SDavid du Colombier 			s = seprint(s, e, "\n");
727f0337cdSDavid du Colombier 	}
73906943f9SDavid du Colombier 	for(j = 0; j < Nep; j++){
74906943f9SDavid du Colombier 		ep = i->ep[j];
75906943f9SDavid du Colombier 		if(ep == nil)
767f0337cdSDavid du Colombier 			break;
77906943f9SDavid du Colombier 		eds = ets = "";
78906943f9SDavid du Colombier 		if(ep->dir <= nelem(edir))
79906943f9SDavid du Colombier 			eds = edir[ep->dir];
80906943f9SDavid du Colombier 		if(ep->type <= nelem(etype))
81906943f9SDavid du Colombier 			ets = etype[ep->type];
82906943f9SDavid du Colombier 		s = seprint(s, e, "\t\t  ep id %d addr %d dir %s type %s"
83906943f9SDavid du Colombier 			" itype %d maxpkt %d ntds %d\n",
84906943f9SDavid du Colombier 			ep->id, ep->addr, eds, ets, ep->isotype,
85906943f9SDavid du Colombier 			ep->maxpkt, ep->ntds);
867f0337cdSDavid du Colombier 	}
87906943f9SDavid du Colombier 	return s;
887f0337cdSDavid du Colombier }
897f0337cdSDavid du Colombier 
90906943f9SDavid du Colombier static char*
seprintconf(char * s,char * e,Usbdev * d,int ci)91906943f9SDavid du Colombier seprintconf(char *s, char *e, Usbdev *d, int ci)
92906943f9SDavid du Colombier {
93906943f9SDavid du Colombier 	int i;
94906943f9SDavid du Colombier 	Conf *c;
95906943f9SDavid du Colombier 	char *hd;
96906943f9SDavid du Colombier 
97906943f9SDavid du Colombier 	c = d->conf[ci];
98906943f9SDavid du Colombier 	s = seprint(s, e, "\tconf: cval %d attrib %x %d mA\n",
99906943f9SDavid du Colombier 		c->cval, c->attrib, c->milliamps);
100906943f9SDavid du Colombier 	for(i = 0; i < Niface; i++)
101906943f9SDavid du Colombier 		if(c->iface[i] == nil)
10202c76561SDavid du Colombier 			break;
103906943f9SDavid du Colombier 		else
104906943f9SDavid du Colombier 			s = seprintiface(s, e, c->iface[i]);
105906943f9SDavid du Colombier 	for(i = 0; i < Nddesc; i++)
106906943f9SDavid du Colombier 		if(d->ddesc[i] == nil)
10702c76561SDavid du Colombier 			break;
108906943f9SDavid du Colombier 		else if(d->ddesc[i]->conf == c){
109906943f9SDavid du Colombier 			hd = hexstr((uchar*)&d->ddesc[i]->data,
110906943f9SDavid du Colombier 				d->ddesc[i]->data.bLength);
111906943f9SDavid du Colombier 			s = seprint(s, e, "\t\tdev desc %x[%d]: %s\n",
112906943f9SDavid du Colombier 				d->ddesc[i]->data.bDescriptorType,
113906943f9SDavid du Colombier 				d->ddesc[i]->data.bLength, hd);
114906943f9SDavid du Colombier 			free(hd);
11502c76561SDavid du Colombier 		}
116906943f9SDavid du Colombier 	return s;
117906943f9SDavid du Colombier }
118906943f9SDavid du Colombier 
119906943f9SDavid du Colombier int
Ufmt(Fmt * f)120906943f9SDavid du Colombier Ufmt(Fmt *f)
121906943f9SDavid du Colombier {
122906943f9SDavid du Colombier 	int i;
123906943f9SDavid du Colombier 	Dev *d;
124906943f9SDavid du Colombier 	Usbdev *ud;
125906943f9SDavid du Colombier 	char buf[1024];
126906943f9SDavid du Colombier 	char *s, *e;
127906943f9SDavid du Colombier 
128906943f9SDavid du Colombier 	s = buf;
129906943f9SDavid du Colombier 	e = buf+sizeof(buf);
130906943f9SDavid du Colombier 	d = va_arg(f->args, Dev*);
131906943f9SDavid du Colombier 	if(d == nil)
132906943f9SDavid du Colombier 		return fmtprint(f, "<nildev>\n");
133906943f9SDavid du Colombier 	s = seprint(s, e, "%s", d->dir);
134906943f9SDavid du Colombier 	ud = d->usb;
135906943f9SDavid du Colombier 	if(ud == nil)
136906943f9SDavid du Colombier 		return fmtprint(f, "%s %ld refs\n", buf, d->ref);
137906943f9SDavid du Colombier 	s = seprint(s, e, " csp %s.%uld.%uld",
138906943f9SDavid du Colombier 		classname(Class(ud->csp)), Subclass(ud->csp), Proto(ud->csp));
139906943f9SDavid du Colombier 	s = seprint(s, e, " vid %#ux did %#ux", ud->vid, ud->did);
140906943f9SDavid du Colombier 	s = seprint(s, e, " refs %ld\n", d->ref);
141906943f9SDavid du Colombier 	s = seprint(s, e, "\t%s %s %s\n", ud->vendor, ud->product, ud->serial);
142906943f9SDavid du Colombier 	for(i = 0; i < Nconf; i++){
143906943f9SDavid du Colombier 		if(ud->conf[i] == nil)
144208510e1SDavid du Colombier 			break;
145906943f9SDavid du Colombier 		else
146906943f9SDavid du Colombier 			s = seprintconf(s, e, ud, i);
1477f0337cdSDavid du Colombier 	}
148906943f9SDavid du Colombier 	return fmtprint(f, "%s", buf);
1499a747e4fSDavid du Colombier }
150906943f9SDavid du Colombier 
151906943f9SDavid du Colombier char*
estrdup(char * s)152906943f9SDavid du Colombier estrdup(char *s)
153906943f9SDavid du Colombier {
154906943f9SDavid du Colombier 	char *d;
155906943f9SDavid du Colombier 
156906943f9SDavid du Colombier 	d = strdup(s);
157906943f9SDavid du Colombier 	if(d == nil)
158906943f9SDavid du Colombier 		sysfatal("strdup: %r");
159906943f9SDavid du Colombier 	setmalloctag(d, getcallerpc(&s));
160906943f9SDavid du Colombier 	return d;
1619a747e4fSDavid du Colombier }
162906943f9SDavid du Colombier 
163906943f9SDavid du Colombier void*
emallocz(ulong size,int zero)164906943f9SDavid du Colombier emallocz(ulong size, int zero)
165906943f9SDavid du Colombier {
166906943f9SDavid du Colombier 	void *x;
167906943f9SDavid du Colombier 
168906943f9SDavid du Colombier 	x = malloc(size);
169906943f9SDavid du Colombier 	if(x == nil)
170906943f9SDavid du Colombier 		sysfatal("malloc: %r");
171906943f9SDavid du Colombier 	if(zero)
172906943f9SDavid du Colombier 		memset(x, 0, size);
173906943f9SDavid du Colombier 	setmalloctag(x, getcallerpc(&size));
174906943f9SDavid du Colombier 	return x;
175906943f9SDavid du Colombier }
176906943f9SDavid du Colombier 
177