1/*  *********************************************************************
2    *  Broadcom Common Firmware Environment (CFE)
3    *
4    *  USB debugging code			File: usbdebug.c
5    *
6    *  This module contains debug code for USB.
7    *
8    *  Author:  Mitch Lichtenberg
9    *
10    *********************************************************************
11    *
12    *  Copyright 2000,2001,2002,2003,2004,2005
13    *  Broadcom Corporation. All rights reserved.
14    *
15    *  This software is furnished under license and may be used and
16    *  copied only in accordance with the following terms and
17    *  conditions.  Subject to these conditions, you may download,
18    *  copy, install, use, modify and distribute modified or unmodified
19    *  copies of this software in source and/or binary form.  No title
20    *  or ownership is transferred hereby.
21    *
22    *  1) Any source code used, modified or distributed must reproduce
23    *     and retain this copyright notice and list of conditions
24    *     as they appear in the source file.
25    *
26    *  2) No right is granted to use any trade name, trademark, or
27    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
28    *     name may not be used to endorse or promote products derived
29    *     from this software without the prior written permission of
30    *     Broadcom Corporation.
31    *
32    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
33    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
34    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
35    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
36    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
37    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
38    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
40    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
42    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
43    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
44    *     THE POSSIBILITY OF SUCH DAMAGE.
45    ********************************************************************* */
46
47
48#ifndef _CFE_
49#include <stdio.h>
50#include <time.h>
51#include <memory.h>
52#include <stdint.h>
53#include "usbhack.h"
54#include "lib_malloc.h"
55#include "lib_queue.h"
56#else
57#include "cfe.h"
58#endif
59
60#include "usbchap9.h"
61#include "usbd.h"
62
63
64void usb_dbg_dumpportstatus(int port,usb_port_status_t *portstatus,int level)
65{
66    int idx;
67    uint16_t x;
68
69    for (idx = 0; idx < level; idx++) printf("  ");
70    printf("PORT %d STATUS\n",port);
71
72    for (idx = 0; idx < level; idx++) printf("  ");
73    x = GETUSBFIELD((portstatus),wPortStatus);
74    printf("wPortStatus     = %04X  ",x);
75    if (x & 1) printf("DevicePresent ");
76    if (x & 2) printf("Enabled ");
77    if (x & 4) printf("Suspend ");
78    if (x & 8) printf("OverCurrent ");
79    if (x & 16) printf("InReset ");
80    if (x & 256) printf("Powered ");
81    if (x & 512) printf("LowSpeed ");
82    printf("\n");
83    for (idx = 0; idx < level; idx++) printf("  ");
84    x = GETUSBFIELD((portstatus),wPortChange);
85    printf("wPortChange     = %04X  ",x);
86    if (x & 1) printf("ConnectChange ");
87    if (x & 2) printf("EnableChange ");
88    if (x & 4) printf("SuspendChange ");
89    if (x & 8) printf("OverCurrentChange ");
90    if (x & 16) printf("ResetChange ");
91    printf("\n");
92}
93
94static char *getstringmaybe(usbdev_t *dev,unsigned int string)
95{
96    static char buf[256];
97
98    if (string == 0) {
99	strcpy(buf,"");
100	return buf;
101	}
102    else {
103	memset(buf,0,sizeof(buf));
104	usb_get_string(dev,string,buf,sizeof(buf));
105	}
106
107    return buf;
108}
109
110void usb_dbg_dumpdescriptors(usbdev_t *dev,uint8_t *ptr,int len)
111{
112    uint8_t *endptr;
113    usb_config_descr_t  *cfgdscr;
114    usb_interface_descr_t *ifdscr;
115    usb_device_descr_t *devdscr;
116    usb_endpoint_descr_t *epdscr;
117    usb_hid_descr_t *hiddscr;
118    usb_hub_descr_t *hubdscr;
119    static char *eptattribs[4] = {"Control","Isoc","Bulk","Interrupt"};
120    int idx;
121
122    endptr = ptr + len;
123
124    while (ptr < endptr) {
125
126	cfgdscr = (usb_config_descr_t *) ptr;
127
128	switch (cfgdscr->bDescriptorType) {
129	    case USB_DEVICE_DESCRIPTOR_TYPE:
130		devdscr = (usb_device_descr_t *) ptr;
131		printf("---------------------------------------------------\n");
132		printf("DEVICE DESCRIPTOR\n");
133		printf("bLength         = %d\n",devdscr->bLength);
134		printf("bDescriptorType = %d\n",devdscr->bDescriptorType);
135		printf("bcdUSB          = %04X\n",GETUSBFIELD(devdscr,bcdUSB));
136		printf("bDeviceClass    = %d\n",devdscr->bDeviceClass);
137		printf("bDeviceSubClass = %d\n",devdscr->bDeviceSubClass);
138		printf("bDeviceProtocol = %d\n",devdscr->bDeviceProtocol);
139		printf("bMaxPktSize0    = %d\n",devdscr->bMaxPacketSize0);
140		if (endptr-ptr <= 8) break;
141		printf("idVendor        = %04X (%d)\n",
142		       GETUSBFIELD(devdscr,idVendor),
143		       GETUSBFIELD(devdscr,idVendor));
144		printf("idProduct       = %04X (%d)\n",
145		       GETUSBFIELD(devdscr,idProduct),
146		       GETUSBFIELD(devdscr,idProduct));
147		printf("bcdDevice       = %04X\n",GETUSBFIELD(devdscr,bcdDevice));
148		printf("iManufacturer   = %d (%s)\n",
149		       devdscr->iManufacturer,
150		       getstringmaybe(dev,devdscr->iManufacturer));
151		printf("iProduct        = %d (%s)\n",
152		       devdscr->iProduct,
153		       getstringmaybe(dev,devdscr->iProduct));
154		printf("iSerialNumber   = %d (%s)\n",
155		       devdscr->iSerialNumber,
156		       getstringmaybe(dev,devdscr->iSerialNumber));
157		printf("bNumConfigs     = %d\n",devdscr->bNumConfigurations);
158		break;
159
160	    case USB_CONFIGURATION_DESCRIPTOR_TYPE:
161		cfgdscr = (usb_config_descr_t *) ptr;
162		printf("---------------------------------------------------\n");
163		printf("CONFIG DESCRIPTOR\n");
164
165		printf("bLength         = %d\n",cfgdscr->bLength);
166		printf("bDescriptorType = %d\n",cfgdscr->bDescriptorType);
167		printf("wTotalLength    = %d\n",GETUSBFIELD(cfgdscr,wTotalLength));
168		printf("bNumInterfaces  = %d\n",cfgdscr->bNumInterfaces);
169		printf("bConfigValue    = %d\n",cfgdscr->bConfigurationValue);
170		printf("iConfiguration  = %d (%s)\n",
171		       cfgdscr->iConfiguration,
172		       getstringmaybe(dev,cfgdscr->iConfiguration));
173		printf("bmAttributes    = %02X\n",cfgdscr->bmAttributes);
174		printf("MaxPower        = %d (%dma)\n",cfgdscr->MaxPower,cfgdscr->MaxPower*2);
175		break;
176
177	    case USB_INTERFACE_DESCRIPTOR_TYPE:
178		printf("---------------------------------------------------\n");
179		printf("INTERFACE DESCRIPTOR\n");
180
181		ifdscr = (usb_interface_descr_t *) ptr;
182
183		printf("bLength         = %d\n",ifdscr->bLength);
184		printf("bDescriptorType = %d\n",ifdscr->bDescriptorType);
185		printf("bInterfaceNum   = %d\n",ifdscr->bInterfaceNumber);
186		printf("bAlternateSet   = %d\n",ifdscr->bAlternateSetting);
187		printf("bNumEndpoints   = %d\n",ifdscr->bNumEndpoints);
188		printf("bInterfaceClass = %d\n",ifdscr->bInterfaceClass);
189		printf("bInterSubClass  = %d\n",ifdscr->bInterfaceSubClass);
190		printf("bInterfaceProto = %d\n",ifdscr->bInterfaceProtocol);
191		printf("iInterface      = %d (%s)\n",
192		       ifdscr->iInterface,
193		       getstringmaybe(dev,ifdscr->iInterface));
194		break;
195
196	    case USB_ENDPOINT_DESCRIPTOR_TYPE:
197		printf("---------------------------------------------------\n");
198		printf("ENDPOINT DESCRIPTOR\n");
199
200		epdscr = (usb_endpoint_descr_t *) ptr;
201
202		printf("bLength         = %d\n",epdscr->bLength);
203		printf("bDescriptorType = %d\n",epdscr->bDescriptorType);
204		printf("bEndpointAddr   = %02X (%d,%s)\n",
205		       epdscr->bEndpointAddress,
206		       epdscr->bEndpointAddress & 0x0F,
207		       (epdscr->bEndpointAddress & USB_ENDPOINT_DIRECTION_IN) ? "IN" : "OUT"
208		       );
209		printf("bmAttrbutes     = %02X (%s)\n",
210		       epdscr->bmAttributes,
211		       eptattribs[epdscr->bmAttributes&3]);
212		printf("wMaxPacketSize  = %d\n",GETUSBFIELD(epdscr,wMaxPacketSize));
213		printf("bInterval       = %d\n",epdscr->bInterval);
214		break;
215
216	    case USB_HID_DESCRIPTOR_TYPE:
217		printf("---------------------------------------------------\n");
218		printf("HID DESCRIPTOR\n");
219
220		hiddscr = (usb_hid_descr_t *) ptr;
221
222		printf("bLength         = %d\n",hiddscr->bLength);
223		printf("bDescriptorType = %d\n",hiddscr->bDescriptorType);
224		printf("bcdHID          = %04X\n",GETUSBFIELD(hiddscr,bcdHID));
225		printf("bCountryCode    = %d\n",hiddscr->bCountryCode);
226		printf("bNumDescriptors = %d\n",hiddscr->bNumDescriptors);
227		printf("bClassDescrType = %d\n",hiddscr->bClassDescrType);
228		printf("wClassDescrLen  = %d\n",GETUSBFIELD(hiddscr,wClassDescrLength));
229		break;
230
231	    case USB_HUB_DESCRIPTOR_TYPE:
232		printf("---------------------------------------------------\n");
233		printf("HUB DESCRIPTOR\n");
234
235		hubdscr = (usb_hub_descr_t *) ptr;
236
237		printf("bLength         = %d\n",hubdscr->bDescriptorLength);
238		printf("bDescriptorType = %d\n",hubdscr->bDescriptorType);
239		printf("bNumberOfPorts  = %d\n",hubdscr->bNumberOfPorts);
240		printf("wHubCharacters  = %04X\n",GETUSBFIELD(hubdscr,wHubCharacteristics));
241		printf("bPowerOnToPwrGd = %d\n",hubdscr->bPowerOnToPowerGood);
242		printf("bHubControlCurr = %d (ma)\n",hubdscr->bHubControlCurrent);
243		printf("bRemPwerMask[0] = %02X\n",hubdscr->bRemoveAndPowerMask[0]);
244
245		break;
246
247	    default:
248		printf("---------------------------------------------------\n");
249		printf("UNKNOWN DESCRIPTOR\n");
250		printf("bLength         = %d\n",cfgdscr->bLength);
251		printf("bDescriptorType = %d\n",cfgdscr->bDescriptorType);
252		printf("Data Bytes      = ");
253		for (idx = 0; idx < cfgdscr->bLength; idx++) {
254		    printf("%02X ",ptr[idx]);
255		    }
256		printf("\n");
257
258	    }
259
260	ptr += cfgdscr->bLength;
261
262	}
263}
264
265
266void usb_dbg_dumpcfgdescr(usbdev_t *dev,unsigned int index)
267{
268    uint8_t buffer[512];
269    int res;
270    int len;
271    usb_config_descr_t *cfgdscr;
272
273    memset(buffer,0,sizeof(buffer));
274
275    cfgdscr = (usb_config_descr_t *) &buffer[0];
276
277    res = usb_get_config_descriptor(dev,cfgdscr,index,
278				    sizeof(usb_config_descr_t));
279    if (res != sizeof(usb_config_descr_t)) {
280	printf("[a] usb_get_config_descriptor returns %d\n",res);
281	}
282
283    len = GETUSBFIELD(cfgdscr,wTotalLength);
284
285    res = usb_get_config_descriptor(dev,cfgdscr,0,len);
286    if (res != len) {
287	printf("[b] usb_get_config_descriptor returns %d\n",res);
288	}
289
290    usb_dbg_dumpdescriptors(dev,&buffer[0],res);
291}
292
293void usb_dbg_dumpdevice(usbdev_t *dev)
294{
295    usb_device_descr_t *devdscr;
296    int i;
297
298    devdscr = &dev->ud_devdescr;
299
300    printf("Device %d\n", dev->ud_address);
301    printf(" Vendor: %s (%04x)\n",getstringmaybe(dev,devdscr->iManufacturer),
302	   GETUSBFIELD(devdscr, idVendor));
303    printf(" Product: %s (%04x)\n",getstringmaybe(dev,devdscr->iProduct),
304	   GETUSBFIELD(devdscr, idProduct));
305
306    usb_dbg_dumpdescriptors(dev,(uint8_t *)devdscr,sizeof(usb_device_descr_t));
307
308    for (i = 0; i < devdscr->bNumConfigurations; i++) {
309	usb_dbg_dumpcfgdescr(dev,i);
310	}
311}
312
313
314void usb_dbg_showdevice(usbdev_t *dev)
315{
316    printf("USB bus %d device %d: vendor %04X product %04X class %d  [%s]\n",
317	   dev->ud_bus->ub_num, dev->ud_address,
318	   GETUSBFIELD(&(dev->ud_devdescr), idVendor),
319	   GETUSBFIELD(&(dev->ud_devdescr), idProduct),
320	   dev->ud_devdescr.bDeviceClass,
321	   (IS_HUB(dev) ? "HUB" : "DEVICE"));
322}
323
324