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