source: mainline/uspace/lib/usb/src/dump.c@ e0a5d4c

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since e0a5d4c was e0a5d4c, checked in by Ondřej Hlavatý <aearsis@…>, 7 years ago

usb: update copyrights

The data was generated by a script, guided manually. If you feel your
name is missing somewhere, please add it!

The semi-automated process was roughly:

1) Changes per file and author (limited to our team) were counted
2) Trivial numbers were thrown away
3) Authors were sorted by lines added to file
4) All previous copyrights were replaced by the newly generated one
5) Hunks changing only year were discarded

It seems that a lot of my copyrights were added. It is due to me being
both sticking my nose everywhere and lazy to update the copyright right
away :)

  • Property mode set to 100644
File size: 13.2 KB
Line 
1/*
2 * Copyright (c) 2011 Vojtech Horky
3 * Copyright (c) 2018 Ondrej Hlavaty
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup libusb
31 * @{
32 */
33/** @file
34 * Descriptor dumping.
35 */
36#include <stdlib.h>
37#include <stdio.h>
38#include <stddef.h>
39#include <usb/debug.h>
40#include <usb/descriptor.h>
41#include <usb/classes/classes.h>
42#include <usb/classes/hub.h>
43#include <usb/usb.h>
44
45/** Mapping between descriptor id and dumping function. */
46typedef struct {
47 /** Descriptor id. */
48 int id;
49 /** Dumping function. */
50 void (*dump)(FILE *, const char *, const char *,
51 const uint8_t *, size_t);
52} descriptor_dump_t;
53
54static void usb_dump_descriptor_device(FILE *, const char *, const char *,
55 const uint8_t *, size_t);
56static void usb_dump_descriptor_configuration(FILE *, const char *, const char *,
57 const uint8_t *, size_t);
58static void usb_dump_descriptor_interface(FILE *, const char *, const char *,
59 const uint8_t *, size_t);
60static void usb_dump_descriptor_string(FILE *, const char *, const char *,
61 const uint8_t *, size_t);
62static void usb_dump_descriptor_endpoint(FILE *, const char *, const char *,
63 const uint8_t *, size_t);
64static void usb_dump_descriptor_superspeed_endpoint_companion(FILE *, const char *, const char *,
65 const uint8_t *, size_t);
66static void usb_dump_descriptor_hid(FILE *, const char *, const char *,
67 const uint8_t *, size_t);
68static void usb_dump_descriptor_hub(FILE *, const char *, const char *,
69 const uint8_t *, size_t);
70static void usb_dump_descriptor_generic(FILE *, const char *, const char *,
71 const uint8_t *, size_t);
72
73/** Descriptor dumpers mapping. */
74static descriptor_dump_t descriptor_dumpers[] = {
75 { USB_DESCTYPE_DEVICE, usb_dump_descriptor_device },
76 { USB_DESCTYPE_CONFIGURATION, usb_dump_descriptor_configuration },
77 { USB_DESCTYPE_STRING, usb_dump_descriptor_string },
78 { USB_DESCTYPE_INTERFACE, usb_dump_descriptor_interface },
79 { USB_DESCTYPE_ENDPOINT, usb_dump_descriptor_endpoint },
80 { USB_DESCTYPE_SSPEED_EP_COMPANION, usb_dump_descriptor_superspeed_endpoint_companion },
81 { USB_DESCTYPE_HID, usb_dump_descriptor_hid },
82 { USB_DESCTYPE_HUB, usb_dump_descriptor_hub },
83 { -1, usb_dump_descriptor_generic },
84 { -1, NULL }
85};
86
87/** Dumps standard USB descriptor.
88 * The @p line_suffix must contain the newline <code>\\n</code> character.
89 * When @p line_suffix or @p line_prefix is NULL, they are substitued with
90 * default values
91 * (<code> - </code> for prefix and line termination for suffix).
92 *
93 * @param output Output file stream to dump descriptor to.
94 * @param line_prefix Prefix for each line of output.
95 * @param line_suffix Suffix of each line of output.
96 * @param descriptor Actual descriptor.
97 * @param descriptor_length Descriptor size.
98 */
99void usb_dump_standard_descriptor(FILE *output,
100 const char *line_prefix, const char *line_suffix,
101 const uint8_t *descriptor, size_t descriptor_length)
102{
103 if (descriptor_length < 2) {
104 return;
105 }
106 int type = descriptor[1];
107
108 descriptor_dump_t *dumper = descriptor_dumpers;
109 while (dumper->dump != NULL) {
110 if ((dumper->id == type) || (dumper->id < 0)) {
111 dumper->dump(output, line_prefix, line_suffix,
112 descriptor, descriptor_length);
113 return;
114 }
115 dumper++;
116 }
117}
118
119/** Prints single line of USB descriptor dump.
120 * @warning This macro abuses heavily the naming conventions used
121 * by all dumping functions (i.e. names for output file stream (@c output) and
122 * line prefix and suffix (@c line_prefix and @c line_suffix respectively))-
123 *
124 * @param fmt Formatting string.
125 */
126#define PRINTLINE(fmt, ...) \
127 fprintf(output, "%s" fmt "%s", \
128 line_prefix ? line_prefix : " - ", \
129 __VA_ARGS__, \
130 line_suffix ? line_suffix : "\n")
131
132#define BCD_INT(a) (((unsigned int)(a)) / 256)
133#define BCD_FRAC(a) (((unsigned int)(a)) % 256)
134
135#define BCD_FMT "%x.%x"
136#define BCD_ARGS(a) BCD_INT((a)), BCD_FRAC((a))
137
138static void usb_dump_descriptor_device(FILE *output,
139 const char *line_prefix, const char *line_suffix,
140 const uint8_t *descriptor, size_t descriptor_length)
141{
142 usb_standard_device_descriptor_t *d
143 = (usb_standard_device_descriptor_t *) descriptor;
144 if (descriptor_length < sizeof(*d)) {
145 return;
146 }
147
148 PRINTLINE("bLength = %d", d->length);
149 PRINTLINE("bDescriptorType = 0x%02x", d->descriptor_type);
150 PRINTLINE("bcdUSB = %d (" BCD_FMT ")", d->usb_spec_version,
151 BCD_ARGS(d->usb_spec_version));
152 PRINTLINE("bDeviceClass = 0x%02x", d->device_class);
153 PRINTLINE("bDeviceSubClass = 0x%02x", d->device_subclass);
154 PRINTLINE("bDeviceProtocol = 0x%02x", d->device_protocol);
155 PRINTLINE("bMaxPacketSize0 = %d", d->max_packet_size);
156 PRINTLINE("idVendor = 0x%04x", d->vendor_id);
157 PRINTLINE("idProduct = 0x%04x", d->product_id);
158 PRINTLINE("bcdDevice = %d", d->device_version);
159 PRINTLINE("iManufacturer = %d", d->str_manufacturer);
160 PRINTLINE("iProduct = %d", d->str_product);
161 PRINTLINE("iSerialNumber = %d", d->str_serial_number);
162 PRINTLINE("bNumConfigurations = %d", d->configuration_count);
163}
164
165static void usb_dump_descriptor_configuration(FILE *output,
166 const char *line_prefix, const char *line_suffix,
167 const uint8_t *descriptor, size_t descriptor_length)
168{
169 usb_standard_configuration_descriptor_t *d
170 = (usb_standard_configuration_descriptor_t *) descriptor;
171 if (descriptor_length < sizeof(*d)) {
172 return;
173 }
174
175 bool self_powered = d->attributes & 64;
176 bool remote_wakeup = d->attributes & 32;
177
178 PRINTLINE("bLength = %d", d->length);
179 PRINTLINE("bDescriptorType = 0x%02x", d->descriptor_type);
180 PRINTLINE("wTotalLength = %d", d->total_length);
181 PRINTLINE("bNumInterfaces = %d", d->interface_count);
182 PRINTLINE("bConfigurationValue = %d", d->configuration_number);
183 PRINTLINE("iConfiguration = %d", d->str_configuration);
184 PRINTLINE("bmAttributes = %d [%s%s%s]", d->attributes,
185 self_powered ? "self-powered" : "",
186 (self_powered & remote_wakeup) ? ", " : "",
187 remote_wakeup ? "remote-wakeup" : "");
188 PRINTLINE("MaxPower = %d (%dmA)", d->max_power,
189 2 * d->max_power);
190}
191
192static void usb_dump_descriptor_interface(FILE *output,
193 const char *line_prefix, const char *line_suffix,
194 const uint8_t *descriptor, size_t descriptor_length)
195{
196 usb_standard_interface_descriptor_t *d
197 = (usb_standard_interface_descriptor_t *) descriptor;
198 if (descriptor_length < sizeof(*d)) {
199 return;
200 }
201
202 PRINTLINE("bLength = %d", d->length);
203 PRINTLINE("bDescriptorType = 0x%02x", d->descriptor_type);
204 PRINTLINE("bInterfaceNumber = %d", d->interface_number);
205 PRINTLINE("bAlternateSetting = %d", d->alternate_setting);
206 PRINTLINE("bNumEndpoints = %d", d->endpoint_count);
207 PRINTLINE("bInterfaceClass = %s", d->interface_class == 0
208 ? "reserved (0)" : usb_str_class(d->interface_class));
209 PRINTLINE("bInterfaceSubClass = %d", d->interface_subclass);
210 PRINTLINE("bInterfaceProtocol = %d", d->interface_protocol);
211 PRINTLINE("iInterface = %d", d->str_interface);
212}
213
214static void usb_dump_descriptor_string(FILE *output,
215 const char *line_prefix, const char *line_suffix,
216 const uint8_t *descriptor, size_t descriptor_length)
217{
218}
219
220static void usb_dump_descriptor_endpoint(FILE *output,
221 const char *line_prefix, const char *line_suffix,
222 const uint8_t *descriptor, size_t descriptor_length)
223{
224 usb_standard_endpoint_descriptor_t *d
225 = (usb_standard_endpoint_descriptor_t *) descriptor;
226 if (descriptor_length < sizeof(*d)) {
227 return;
228 }
229
230 int endpoint = d->endpoint_address & 15;
231 usb_direction_t direction = d->endpoint_address & 128
232 ? USB_DIRECTION_IN : USB_DIRECTION_OUT;
233 usb_transfer_type_t transfer_type = d->attributes & 3;
234
235 PRINTLINE("bLength = %d", d->length);
236 PRINTLINE("bDescriptorType = 0x%02X", d->descriptor_type);
237 PRINTLINE("bEndpointAddress = 0x%02X [%d, %s]",
238 d->endpoint_address, endpoint,
239 direction == USB_DIRECTION_IN ? "in" : "out");
240 PRINTLINE("bmAttributes = %d [%s]", d->attributes,
241 usb_str_transfer_type(transfer_type));
242 PRINTLINE("wMaxPacketSize = %d", d->max_packet_size);
243 PRINTLINE("bInterval = %dms", d->poll_interval);
244}
245
246static void usb_dump_descriptor_superspeed_endpoint_companion(FILE *output,
247 const char *line_prefix, const char *line_suffix,
248 const uint8_t *descriptor, size_t descriptor_length)
249{
250 usb_superspeed_endpoint_companion_descriptor_t *d
251 = (usb_superspeed_endpoint_companion_descriptor_t *) descriptor;
252 if (descriptor_length < sizeof(*d)) {
253 return;
254 }
255
256 PRINTLINE("bLength = %u", d->length);
257 PRINTLINE("bDescriptorType = 0x%02X", d->descriptor_type);
258 PRINTLINE("bMaxBurst = %u", d->max_burst);
259 PRINTLINE("bmAttributes = %d", d->attributes);
260 PRINTLINE("wBytesPerInterval = %u", d->bytes_per_interval);
261}
262
263static void usb_dump_descriptor_hid(FILE *output,
264 const char *line_prefix, const char *line_suffix,
265 const uint8_t *descriptor, size_t descriptor_length)
266{
267 usb_standard_hid_descriptor_t *d
268 = (usb_standard_hid_descriptor_t *) descriptor;
269 if (descriptor_length < sizeof(*d)) {
270 return;
271 }
272
273 PRINTLINE("bLength = %d", d->length);
274 PRINTLINE("bDescriptorType = 0x%02x", d->descriptor_type);
275 PRINTLINE("bcdHID = %d (" BCD_FMT ")", d->spec_release,
276 BCD_ARGS(d->spec_release));
277 PRINTLINE("bCountryCode = %d", d->country_code);
278 PRINTLINE("bNumDescriptors = %d", d->class_desc_count);
279 PRINTLINE("bDescriptorType = %d", d->report_desc_info.type);
280 PRINTLINE("wDescriptorLength = %d", d->report_desc_info.length);
281
282 /* Print info about report descriptors. */
283 size_t i;
284 size_t count = (descriptor_length - sizeof(*d))
285 / sizeof(usb_standard_hid_class_descriptor_info_t);
286 usb_standard_hid_class_descriptor_info_t *d2
287 = (usb_standard_hid_class_descriptor_info_t *)
288 (descriptor + sizeof(*d));
289 for (i = 0; i < count; i++, d2++) {
290 PRINTLINE("bDescriptorType = %d", d2->type);
291 PRINTLINE("wDescriptorLength = %d", d2->length);
292 }
293}
294
295static void usb_dump_descriptor_hub(FILE *output,
296 const char *line_prefix, const char *line_suffix,
297 const uint8_t *descriptor, size_t descriptor_length)
298{
299 usb_hub_descriptor_header_t *d =
300 (usb_hub_descriptor_header_t *) descriptor;
301 if (descriptor_length < sizeof(d))
302 return;
303
304 PRINTLINE("bDescLength: = %d", d->length);
305 PRINTLINE("bDescriptorType = 0x%02x", d->descriptor_type);
306 PRINTLINE("bNbrPorts = %d", d->port_count);
307 PRINTLINE("bHubCharacteristics = 0x%02x%02x (%s;%s%s)",
308 d->characteristics_reserved, d->characteristics,
309 (d->characteristics & HUB_CHAR_NO_POWER_SWITCH_FLAG) ?
310 "No Power Switching" :
311 ((d->characteristics & HUB_CHAR_POWER_PER_PORT_FLAG) ?
312 "Per-Port Switching" : "Ganged Power Switching"),
313 (d->characteristics & HUB_CHAR_COMPOUND_DEVICE) ?
314 "Compound Device;" : "",
315 (d->characteristics & HUB_CHAR_NO_OC_FLAG) ?
316 "No OC Protection" :
317 ((d->characteristics & HUB_CHAR_OC_PER_PORT_FLAG) ?
318 "Individual Port OC Protection" :
319 "Global OC Protection")
320 );
321 PRINTLINE("bPwrOn2PwrGood = %d (%d ms)",
322 d->power_good_time, d->power_good_time * 2);
323 PRINTLINE("bHubContrCurrent = %d (%d mA)",
324 d->max_current, d->max_current);
325 const size_t port_bytes = (descriptor_length - sizeof(*d)) / 2;
326 const uint8_t *removable_mask = descriptor + sizeof(*d);
327 const uint8_t *powered_mask = descriptor + sizeof(*d) + port_bytes;
328
329 if (port_bytes == 0
330 || port_bytes > (((d->port_count / (unsigned)8) + 1) * 2)) {
331 PRINTLINE("::CORRUPTED DESCRIPTOR:: (%zu bytes remain)",
332 port_bytes * 2);
333 }
334
335 fprintf(output, "%sDeviceRemovable = 0x",
336 line_prefix ? line_prefix : " - ");
337 for (unsigned i = port_bytes; i > 0; --i)
338 fprintf(output, "%02x", removable_mask[i - 1]);
339 fprintf(output, " (0b1 - Device non-removable)%s",
340 line_suffix ? line_suffix : "\n");
341
342 fprintf(output, "%sPortPwrCtrlMask = 0x",
343 line_prefix ? line_prefix : " - ");
344 for (unsigned i = port_bytes; i > 0; --i)
345 fprintf(output, "%02x", powered_mask[i - 1]);
346 fprintf(output, " (Legacy - All should be 0b1)%s",
347 line_suffix ? line_suffix : "\n");
348}
349
350static void usb_dump_descriptor_generic(FILE *output,
351 const char *line_prefix, const char *line_suffix,
352 const uint8_t *descriptor, size_t descriptor_length)
353{
354 /* TODO */
355}
356
357
358/**
359 * @}
360 */
Note: See TracBrowser for help on using the repository browser.