1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26
27 #include <sys/mdb_modapi.h>
28
29
30 #include <sys/usb/usba.h>
31 #include <sys/usb/usba/usba_types.h>
32 #include <sys/usb/clients/hid/hid.h>
33 #include <sys/usb/clients/hidparser/hidparser.h>
34 #include <sys/usb/clients/hidparser/hidparser_impl.h>
35 #include <sys/usb/usba/genconsole.h>
36 #include <sys/usb/clients/hid/hidvar.h>
37
38
39 /* ****************************************************************** */
40
41 /* extenal definition */
42
43 typedef struct mdb_ctf_id {
44 void *_opaque[2];
45 } mdb_ctf_id_t;
46
47 extern int mdb_ctf_lookup_by_name(const char *, mdb_ctf_id_t *);
48
49 extern int mdb_devinfo2driver(uintptr_t, char *, size_t);
50
51 extern int mdb_devinfo2statep(uintptr_t, char *, uintptr_t *);
52
53 extern char *mdb_ddi_pathname(uintptr_t, char *, size_t);
54
55
56 /* ****************************************************************** */
57
58 /* internal definition */
59
60 #define OPT_TREE 0x01
61 #define OPT_VERB 0x02
62
63 #define STRLEN 256
64 #define BYTE_OFFSET 8
65
66
67 typedef struct usb_descr_item {
68 uint_t nlen; /* if it's an byte array, nlen += BYTE_OFFSET */
69 char *name; /* descriptor item name */
70 } usb_descr_item_t;
71
72 /* define the known descriptor items */
73 static usb_descr_item_t usb_cfg_descr[] = {
74 {1, "bLength"},
75 {1, "bDescriptorType"},
76 {2, "wTotalLength"},
77 {1, "bNumInterfaces"},
78 {1, "bConfigurationValue"},
79 {1, "iConfiguration"},
80 {1, "bmAttributes"},
81 {1, "bMaxPower"},
82 };
83 static uint_t usb_cfg_item = 8;
84
85 static usb_descr_item_t usb_ia_descr[] = {
86 {1, "bLength"},
87 {1, "bDescriptorType"},
88 {1, "bFirstInterface"},
89 {1, "bInterfaceCount"},
90 {1, "bFunctionClass"},
91 {1, "bFunctionSubClass"},
92 {1, "bFunctionProtocol"},
93 {1, "iFunction"},
94 };
95 static uint_t usb_ia_item = 8;
96
97 static usb_descr_item_t usb_if_descr[] = {
98 {1, "bLength"},
99 {1, "bDescriptorType"},
100 {1, "bInterfaceNumber"},
101 {1, "bAlternateSetting"},
102 {1, "bNumEndpoints"},
103 {1, "bInterfaceClass"},
104 {1, "bInterfaceSubClass"},
105 {1, "bInterfaceProtocol"},
106 {1, "iInterface"},
107 };
108 static uint_t usb_if_item = 9;
109
110 static usb_descr_item_t usb_ep_descr[] = {
111 {1, "bLength"},
112 {1, "bDescriptorType"},
113 {1, "bEndpointAddress"},
114 {1, "bmAttributes"},
115 {2, "wMaxPacketSize"},
116 {1, "bInterval"},
117 };
118 static uint_t usb_ep_item = 6;
119
120 static usb_descr_item_t usb_qlf_descr[] = {
121 {1, "bLength"},
122 {1, "bDescriptorType"},
123 {2, "bcdUSB"},
124 {1, "bDeviceClass"},
125 {1, "bDeviceSubClass"},
126 {1, "bDeviceProtocol"},
127 {1, "bMaxPacketSize0"},
128 {1, "bNumConfigurations"},
129 {1, "bReserved"},
130 };
131 static uint_t usb_qlf_item = 9;
132
133 static usb_descr_item_t usb_str_descr[] = {
134 {1, "bLength"},
135 {1, "bDescriptorType"},
136 {1, "bString"},
137 };
138 static uint_t usb_str_item = 3;
139
140 static usb_descr_item_t usb_wa_descr[] = {
141 {1, "bLength"},
142 {1, "bDescriptorType"},
143 {2, "bcdWAVersion"},
144 {1, "bNumPorts"},
145 {1, "bmAttributes"},
146 {2, "wNumRPipes"},
147 {2, "wRPipeMaxBlock"},
148 {1, "bRPipeBlockSize"},
149 {1, "bPwrOn2PwrGood"},
150 {1, "bNumMMCIEs"},
151 {1, "DeviceRemovable"},
152 };
153
154 static uint_t usb_wa_item = 11;
155
156 static usb_descr_item_t usb_hid_descr[] = {
157 {1, "bLength"},
158 {1, "bDescriptorType"},
159 {2, "bcdHID"},
160 {1, "bCountryCode"},
161 {1, "bNumDescriptors"},
162 {1, "bReportDescriptorType"},
163 {2, "wReportDescriptorLength"},
164 };
165 static uint_t usb_hid_item = 7;
166
167 static usb_descr_item_t usb_ac_header_descr[] = {
168 {1, "bLength"},
169 {1, "bDescriptorType"},
170 {1, "bDescriptorSubType"},
171 {2, "bcdADC"},
172 {2, "wTotalLength"},
173 {1, "blnCollection"},
174 {1, "baInterfaceNr"},
175 };
176 static uint_t usb_ac_header_item = 7;
177
178 static usb_descr_item_t usb_ac_input_term_descr[] = {
179 {1, "bLength"},
180 {1, "bDescriptorType"},
181 {1, "bDescriptorSubType"},
182 {1, "bTerminalID"},
183 {2, "wTerminalType"},
184 {1, "bAssocTerminal"},
185 {1, "bNrChannels"},
186 {2, "wChannelConfig"},
187 {1, "iChannelNames"},
188 {1, "iTerminal"},
189 };
190 static uint_t usb_ac_input_term_item = 10;
191
192 static usb_descr_item_t usb_ac_output_term_descr[] = {
193 {1, "bLength"},
194 {1, "bDescriptorType"},
195 {1, "bDescriptorSubType"},
196 {1, "bTerminalID"},
197 {2, "wTerminalType"},
198 {1, "bAssocTerminal"},
199 {1, "bSourceID"},
200 {1, "iTerminal"},
201 };
202 static uint_t usb_ac_output_term_item = 8;
203
204 static usb_descr_item_t usb_ac_mixer_descr[] = {
205 {1, "bLength"},
206 {1, "bDescriptorType"},
207 {1, "bDescriptorSubType"},
208 {1, "bUnitID"},
209 {1, "bNrInPins"},
210 {1, "baSourceID"},
211 };
212 static uint_t usb_ac_mixer_item = 6;
213
214 static usb_descr_item_t usb_ac_selector_descr[] = {
215 {1, "bLength"},
216 {1, "bDescriptorType"},
217 {1, "bDescriptorSubType"},
218 {1, "bUnitID"},
219 {1, "bNrInPins"},
220 {1, "baSourceID"},
221 };
222 static uint_t usb_ac_selector_item = 6;
223
224 static usb_descr_item_t usb_ac_feature_descr[] = {
225 {1, "bLength"},
226 {1, "bDescriptorType"},
227 {1, "bDescriptorSubType"},
228 {1, "bUnitID"},
229 {1, "bSourceID"},
230 {1, "bControlSize"},
231 {1, "bmaControls"},
232 };
233 static uint_t usb_ac_feature_item = 7;
234
235 static usb_descr_item_t usb_ac_processing_descr[] = {
236 {1, "bLength"},
237 {1, "bDescriptorType"},
238 {1, "bDescriptorSubType"},
239 {1, "bUnitID"},
240 {1, "wProcessType"},
241 {1, "bNrInPins"},
242 {1, "baSourceID"},
243 };
244 static uint_t usb_ac_processing_item = 7;
245
246 static usb_descr_item_t usb_ac_extension_descr[] = {
247 {1, "bLength"},
248 {1, "bDescriptorType"},
249 {1, "bDescriptorSubType"},
250 {1, "wExtensionCode"},
251 {1, "bUnitID"},
252 {1, "bNrInPins"},
253 {1, "baSourceID"},
254 };
255 static uint_t usb_ac_extension_item = 7;
256
257 static usb_descr_item_t usb_as_ep_descr[] = {
258 {1, "blength"},
259 {1, "bDescriptorType"},
260 {1, "bDescriptorSubType"},
261 {1, "bmAttributes"},
262 {1, "bLockDelayUnits"},
263 {2, "wLockDelay"},
264 };
265 static uint_t usb_as_ep_item = 6;
266
267 static usb_descr_item_t usb_as_if_descr[] = {
268 {1, "blength"},
269 {1, "bDescriptorType"},
270 {1, "bDescriptorSubType"},
271 {1, "bTerminalLink"},
272 {1, "bDelay"},
273 {2, "wFormatTag"},
274 };
275 static uint_t usb_as_if_item = 6;
276
277 static usb_descr_item_t usb_as_format_descr[] = {
278 {1, "blength"},
279 {1, "bDescriptorType"},
280 {1, "bDescriptorSubType"},
281 {1, "bFormatType"},
282 {1, "bNrChannels"},
283 {1, "bSubFrameSize"},
284 {1, "bBitResolution"},
285 {1, "bSamFreqType"},
286 {1, "bSamFreqs"},
287 };
288 static uint_t usb_as_format_item = 9;
289
290 static usb_descr_item_t usb_vc_header_descr[] = {
291 {1, "bLength"},
292 {1, "bDescriptorType"},
293 {1, "bDescriptorSubtype"},
294 {2, "bcdUVC"},
295 {2, "wTotalLength"},
296 {4, "dwClockFrequency"},
297 {1, "bInCollection"},
298 };
299 static uint_t usb_vc_header_item = 7;
300
301 static usb_descr_item_t usb_vc_input_term_descr[] = {
302 {1, "bLength"},
303 {1, "bDescriptorType"},
304 {1, "bDescriptorSubType"},
305 {1, "bTerminalID"},
306 {2, "wTerminalType"},
307 {1, "AssocTerminal"},
308 {1, "iTerminal"},
309 };
310 static uint_t usb_vc_input_term_item = 7;
311
312 static usb_descr_item_t usb_vc_output_term_descr[] = {
313 {1, "bLength"},
314 {1, "bDescriptorType"},
315 {1, "bDescriptorSubType"},
316 {1, "bTerminalID"},
317 {2, "wTerminalType"},
318 {1, "AssocTerminal"},
319 {1, "bSourceID"},
320 {1, "iTerminal"},
321 };
322 static uint_t usb_vc_output_term_item = 8;
323
324 static usb_descr_item_t usb_vc_processing_descr[] = {
325 {1, "bLength"},
326 {1, "bDescriptorType"},
327 {1, "bDescriptorSubType"},
328 {1, "bUnitID"},
329 {1, "bSourceID"},
330 {2, "wMaxMultiplier"},
331 {1, "bControlSize"},
332 {1, "bmControls"},
333 };
334 static uint_t usb_vc_processing_item = 8;
335
336 static usb_descr_item_t usb_vc_selector_descr[] = {
337 {1, "bLength"},
338 {1, "bDescriptorType"},
339 {1, "bDescriptorSubType"},
340 {1, "bUnitID"},
341 {1, "bNrInPins"},
342 };
343 static uint_t usb_vc_selector_item = 5;
344
345 static usb_descr_item_t usb_vc_extension_descr[] = {
346 {1, "bLength"},
347 {1, "bDescriptorType"},
348 {1, "bDescriptorSubType"},
349 {1, "bUnitID"},
350 {16 + BYTE_OFFSET, "guidExtensionCode[16]"},
351 {1, "bNumControls"},
352 {1, "bNrInPins"},
353 };
354 static uint_t usb_vc_extension_item = 7;
355
356 static usb_descr_item_t usb_vs_input_header_descr[] = {
357 {1, "bLength"},
358 {1, "bDescriptorType"},
359 {1, "bDescriptorSubType"},
360 {1, "bNumFormats"},
361 {2, "wTotalLength"},
362 {1, "bEndpointAddress"},
363 {1, "bmInfo"},
364 {1, "bTerminalLink"},
365 {1, "bStillCaptureMethod"},
366 {1, "bTriggerSupport"},
367 {1, "bTriggerUsage"},
368 {1, "bControlSize"},
369 {1, "bmaControls"},
370 };
371 static uint_t usb_vs_input_header_item = 13;
372
373 static usb_descr_item_t usb_vs_output_header_descr[] = {
374 {1, "bLength"},
375 {1, "bDescriptorType"},
376 {1, "bDescriptorSubType"},
377 {1, "bNumFormats"},
378 {2, "wTotalLength"},
379 {1, "bEndpointAddress"},
380 {1, "bTerminalLink"},
381 {1, "bControlSize"},
382 {1, "bmaControls"},
383 };
384 static uint_t usb_vs_output_header_item = 9;
385
386 static usb_descr_item_t usb_vs_still_image_descr[] = {
387 {1, "bLength"},
388 {1, "bDescriptorType"},
389 {1, "bDescriptorSubType"},
390 {1, "bEndpointAddress"},
391 {1, "bNumImageSizePatterns"},
392 {2, "wWidth"},
393 {2, "wHeight"},
394 };
395 static uint_t usb_vs_still_image_item = 7;
396
397 static usb_descr_item_t usb_vs_color_matching_descr[] = {
398 {1, "bLength"},
399 {1, "bDescriptorType"},
400 {1, "bDescriptorSubtype"},
401 {1, "bColorPrimaries"},
402 {1, "bTransferCharacteristics"},
403 {1, "bMatrixCoefficients"},
404 };
405 static uint_t usb_vs_color_matching_item = 6;
406
407 static usb_descr_item_t usb_vs_2frame_descr[] = {
408 {1, "bLength"},
409 {1, "bDescriptorType"},
410 {1, "bDescriptorSubType"},
411 {1, "bFrameIndex"},
412 {1, "bmCapabilities"},
413 {2, "wWidth"},
414 {2, "wHeight"},
415 {4, "dwMinBitRate"},
416 {4, "dwMaxBitRate"},
417 {4, "dwMaxVideoFrameBufferSize"},
418 {4, "dwDefaultFrameInterval"},
419 {1, "bFrameIntervalType"},
420 };
421 static uint_t usb_vs_2frame_item = 12;
422
423 static usb_descr_item_t usb_vs_format_mjpeg_descr[] = {
424 {1, "bLength"},
425 {1, "bDescriptorType"},
426 {1, "bDescriptorSubType"},
427 {1, "bFormatIndex"},
428 {1, "bNumFrameDescriptors"},
429 {1, "bmFlags"},
430 {1, "bDefaultFrameIndex"},
431 {1, "bAspectRatioX"},
432 {1, "bAspectRatioY"},
433 {1, "bmInterlaceFlags"},
434 {1, "bCopyProtect"},
435 };
436 static uint_t usb_vs_format_mjpeg_item = 11;
437
438 static usb_descr_item_t usb_vs_format_uncps_descr[] = {
439 {1, "bLength"},
440 {1, "bDescriptorType"},
441 {1, "bDescriptorSubType"},
442 {1, "bFormatIndex"},
443 {1, "bNumFrameDescriptors"},
444 {16 + BYTE_OFFSET, "guidFormat[16]"},
445 {1, "bBitsPerPixel"},
446 {1, "bDefaultFrameIndex"},
447 {1, "bAspectRatioX"},
448 {1, "bAspectRatioY"},
449 {1, "bmInterlaceFlags"},
450 {1, "bCopyProtect"},
451 };
452 static uint_t usb_vs_format_uncps_item = 12;
453
454 static usb_descr_item_t usb_vs_format_mp2ts_descr[] = {
455 {1, "bLength"},
456 {1, "bDescriptorType"},
457 {1, "bDescriptorSubType"},
458 {1, "bFormatIndex"},
459 {1, "bDataOffset"},
460 {1, "bPacketLength"},
461 {1, "bStrideLength"},
462 {16 + BYTE_OFFSET, "guidStrideFormat[16]"},
463 };
464 static uint_t usb_vs_format_mp2ts_item = 8;
465
466 static usb_descr_item_t usb_vs_format_dv_descr[] = {
467 {1, "bLength"},
468 {1, "bDescriptorType"},
469 {1, "bDescriptorSubType"},
470 {1, "bFormatIndex"},
471 {4, "dwMaxVideoFrameBufferSize"},
472 {1, "bFormatType"},
473 };
474 static uint_t usb_vs_format_dv_item = 6;
475
476
477 /* ****************************************************************** */
478
479 typedef struct hci_state {
480 void *hci_dip;
481 uint_t hci_instance;
482 void *hci_hcdi_ops;
483 uint_t hci_flags;
484 uint16_t vendor_id;
485 uint16_t device_id;
486 } hci_state_t;
487
488 static int prt_usb_tree(uintptr_t paddr, uint_t flag);
489
490 static int prt_usb_tree_node(uintptr_t paddr);
491
492 static void prt_usb_hid_item(uintptr_t paddr);
493
494 static void prt_usb_hid_item_params(entity_item_t *item);
495
496 static void prt_usb_hid_item_attrs(uintptr_t paddr);
497
498 static void prt_usb_hid_item_tags(uint_t tag);
499
500 static void prt_usb_hid_item_data(uintptr_t paddr, uint_t len);
501
502 static int prt_usb_desc(uintptr_t usb_cfg, uint_t cfg_len);
503
504 static int prt_usb_ac_desc(uintptr_t paddr, uint_t nlen);
505
506 static int prt_usb_as_desc(uintptr_t paddr, uint_t nlen);
507
508 static int prt_usb_vc_desc(uintptr_t paddr, uint_t nlen);
509
510 static int prt_usb_vs_desc(uintptr_t paddr, uint_t nlen);
511
512 static int print_descr(uintptr_t, uint_t, usb_descr_item_t *, uint_t);
513
514 static int print_struct(uintptr_t, uint_t, mdb_arg_t *);
515
516 static int prt_usb_buf(uintptr_t, uint_t);
517
518
519 /* ****************************************************************** */
520
521 /* exported functions */
522
523 void prt_usb_usage(void);
524
525 int prtusb(uintptr_t, uint_t, int, const mdb_arg_t *);
526
527 /* ****************************************************************** */
528
529 /* help of prtusb */
530 void
prt_usb_usage(void)531 prt_usb_usage(void)
532 {
533 mdb_printf("%-8s : %s\n", "-v", "print all descriptors");
534 mdb_printf("%-8s : %s\n", "-t", "print device trees");
535 mdb_printf("%-8s : %s\n", "-i index", "print the device by index");
536 }
537
538 /* the entry of ::prtusb */
539 int
prtusb(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)540 prtusb(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
541 {
542 static int count = 1;
543 uint64_t sel_num = 0;
544 uint_t usb_flag = 0;
545 usba_device_t usb_dev;
546 usb_dev_descr_t dev_desc;
547 struct dev_info usb_dip;
548 char strbuf[STRLEN];
549
550 /* print all usba devices if no address assigned */
551 if (!(flags & DCMD_ADDRSPEC)) {
552 if (mdb_walk_dcmd("usba_device", "prtusb", argc, argv) == -1) {
553 mdb_warn("failed to walk usba_device");
554
555 return (DCMD_ERR);
556 }
557
558 return (DCMD_OK);
559 }
560
561 /* for the first device, print head */
562 if (DCMD_HDRSPEC(flags)) {
563 count = 1;
564 mdb_printf("%<u>%-8s%-12s%-6s%-16s%-12s%-20s%</u>\n",
565 "INDEX", "DRIVER", "INST", "NODE", "VID.PID", "PRODUCT");
566 }
567
568 if (mdb_getopts(argc, argv,
569 'i', MDB_OPT_UINT64, &sel_num,
570 't', MDB_OPT_SETBITS, OPT_TREE, &usb_flag,
571 'v', MDB_OPT_SETBITS, OPT_VERB, &usb_flag, NULL) != argc) {
572
573 return (DCMD_USAGE);
574 }
575
576 if (mdb_vread(&usb_dev, sizeof (usba_device_t), addr) == -1) {
577 mdb_warn("Failed to read usba_device!\n");
578
579 return (DCMD_ERR);
580 }
581
582 if (mdb_vread(&usb_dip, sizeof (struct dev_info),
583 (uintptr_t)usb_dev.usb_dip) == -1) {
584 mdb_warn("Failed to read dev_info!\n");
585
586 return (DCMD_ERR);
587 }
588
589 /* process the "-i" */
590 if (sel_num && sel_num != count) {
591 count++;
592
593 return (DCMD_OK);
594 }
595
596 /* index number of device node */
597 mdb_printf("%-8x", count++);
598
599 /* driver and instance */
600 mdb_devinfo2driver((uintptr_t)usb_dev.usb_dip, strbuf, STRLEN);
601 mdb_printf("%-12s%-6d", strbuf, usb_dip.devi_instance);
602
603 /* node name */
604 if (mdb_readstr(strbuf, STRLEN,
605 (uintptr_t)usb_dip.devi_node_name) != -1) {
606
607 mdb_printf("%-16s", strbuf);
608 } else {
609
610 mdb_printf("%-16s", "No Node Name");
611 }
612
613 /* vid.pid */
614 if (mdb_vread(&dev_desc, sizeof (usb_dev_descr_t),
615 (uintptr_t)usb_dev.usb_dev_descr) != -1) {
616
617 mdb_printf("%04x.%04x ",
618 dev_desc.idVendor, dev_desc.idProduct);
619 }
620
621 /* product string */
622 if (mdb_readstr(strbuf, STRLEN,
623 (uintptr_t)usb_dev.usb_product_str) != -1) {
624
625 mdb_printf("%s\n", strbuf);
626 } else {
627
628 mdb_printf("%s\n", "No Product String");
629 }
630
631 /* tree, print usb device tree info */
632 if (usb_flag & OPT_TREE) {
633
634 mdb_printf("\nusba_device: 0x%x\n", addr);
635
636 mdb_printf("mfg_prod_sn: ");
637 if (mdb_readstr(strbuf, STRLEN,
638 (uintptr_t)usb_dev.usb_mfg_str) != -1) {
639 mdb_printf("%s - ", strbuf);
640 } else {
641 mdb_printf("NULL - ");
642 }
643 if (mdb_readstr(strbuf, STRLEN,
644 (uintptr_t)usb_dev.usb_product_str) != -1) {
645 mdb_printf("%s - ", strbuf);
646 } else {
647 mdb_printf("NULL -");
648 }
649 if (mdb_readstr(strbuf, STRLEN,
650 (uintptr_t)usb_dev.usb_serialno_str) != -1) {
651 mdb_printf("%s", strbuf);
652 } else {
653 mdb_printf("NULL");
654 }
655
656 mdb_printf("\n\n");
657 prt_usb_tree((uintptr_t)usb_dev.usb_dip, 0);
658 }
659
660 /* verbose, print all descriptors */
661 if (usb_flag & OPT_VERB) {
662 int i;
663 uintptr_t cfg_buf;
664 uint16_t cfg_len;
665
666 mdb_printf("\n");
667
668 /* device descriptor */
669 prt_usb_desc((uintptr_t)usb_dev.usb_dev_descr, 18);
670
671 /* config cloud descriptors */
672 if (usb_dev.usb_n_cfgs == 1) {
673 mdb_inc_indent(4);
674 mdb_printf("-- Active Config Index 0\n");
675 mdb_dec_indent(4);
676 prt_usb_desc((uintptr_t)usb_dev.usb_cfg,
677 usb_dev.usb_cfg_length);
678 } else {
679 /* multiple configs */
680 for (i = 0; i < usb_dev.usb_n_cfgs; i++) {
681
682 if ((mdb_vread(&cfg_len, sizeof (uint16_t),
683 (uintptr_t)(usb_dev.usb_cfg_array_len + i))
684 != -1) &&
685 (mdb_vread(&cfg_buf, sizeof (uintptr_t),
686 (uintptr_t)(usb_dev.usb_cfg_array + i))
687 != -1)) {
688 mdb_inc_indent(4);
689 if (cfg_buf ==
690 (uintptr_t)usb_dev.usb_cfg) {
691 mdb_printf("-- Active Config"
692 " Index %x\n", i);
693 } else {
694 mdb_printf("-- Inactive Config"
695 " Index %x\n", i);
696 }
697 mdb_dec_indent(4);
698
699 prt_usb_desc(cfg_buf, cfg_len);
700 }
701 }
702 }
703 }
704
705 if (usb_flag) {
706
707 mdb_printf("%<u>%-72s%</u>\n", " ");
708 }
709
710 return (DCMD_OK);
711 }
712
713 /* print the info required by "-t" */
714 static int
prt_usb_tree(uintptr_t paddr,uint_t flag)715 prt_usb_tree(uintptr_t paddr, uint_t flag)
716 {
717 struct dev_info usb_dip;
718
719 if (mdb_vread(&usb_dip, sizeof (struct dev_info), paddr) == -1) {
720 mdb_warn("prt_usb_tree: Failed to read dev_info!\n");
721
722 return (DCMD_ERR);
723 }
724
725 prt_usb_tree_node(paddr);
726
727 if (usb_dip.devi_child) {
728
729 mdb_printf("{\n");
730 mdb_inc_indent(4);
731 prt_usb_tree((uintptr_t)usb_dip.devi_child, 1);
732 mdb_dec_indent(4);
733 mdb_printf("}\n\n");
734 }
735
736 if (usb_dip.devi_sibling && flag == 1) {
737 /* print the sibling if flag == 1 */
738
739 prt_usb_tree((uintptr_t)usb_dip.devi_sibling, 1);
740 }
741
742 return (DCMD_OK);
743 }
744
745 static int
prt_usb_tree_node(uintptr_t paddr)746 prt_usb_tree_node(uintptr_t paddr)
747 {
748 struct dev_info usb_dip;
749 uintptr_t statep;
750 uint_t errlevel;
751 char driver_name[STRLEN] = "";
752 char strbuf[STRLEN] = "";
753
754 if (mdb_vread(&usb_dip, sizeof (struct dev_info), paddr) == -1) {
755 mdb_warn("prt_usb_tree_node: Failed to read dev_info!\n");
756
757 return (DCMD_ERR);
758 }
759
760 /* node name */
761 if (mdb_readstr(strbuf, STRLEN,
762 (uintptr_t)usb_dip.devi_node_name) != -1) {
763 mdb_printf("%s, ", strbuf);
764 } else {
765 mdb_printf("%s, ", "node_name");
766 }
767
768 /* instance */
769 mdb_printf("instance #%d ", usb_dip.devi_instance);
770
771 /* driver name */
772 if (DDI_CF2(&usb_dip)) {
773
774 mdb_devinfo2driver(paddr, driver_name, STRLEN);
775 mdb_printf("(driver name: %s)\n", driver_name);
776 } else {
777
778 mdb_printf("(driver not attached)\n");
779 }
780
781 /* device path */
782 mdb_ddi_pathname(paddr, strbuf, STRLEN);
783 mdb_printf(" %s\n", strbuf);
784
785 /* dip addr */
786 mdb_printf(" dip: 0x%x\n", paddr);
787
788 /* softe_sate */
789 mdb_snprintf(strbuf, STRLEN, "%s_statep", driver_name);
790 if (mdb_devinfo2statep(paddr, strbuf, &statep) != -1) {
791 mdb_printf(" %s: 0x%x\n", strbuf, statep);
792 }
793
794 /* error level */
795 mdb_snprintf(strbuf, STRLEN, "%s_errlevel", driver_name);
796 if (mdb_readvar(&errlevel, strbuf) != -1) {
797 mdb_printf(" %s: 0x%x\n", strbuf, errlevel);
798 }
799
800 if (strcmp(driver_name, "ehci") == 0) {
801 mdb_arg_t argv[] = {
802 {MDB_TYPE_STRING, {"ehci_state_t"}},
803 {MDB_TYPE_STRING, {"ehci_root_hub.rh_descr"}}
804 };
805 mdb_call_dcmd("print", statep, DCMD_ADDRSPEC, 2, argv);
806 }
807
808 if (strcmp(driver_name, "ohci") == 0) {
809 mdb_arg_t argv[] = {
810 {MDB_TYPE_STRING, {"ohci_state_t"}},
811 {MDB_TYPE_STRING, {"ohci_root_hub.rh_descr"}}
812 };
813 mdb_call_dcmd("print", statep, DCMD_ADDRSPEC, 2, argv);
814 }
815
816 if (strcmp(driver_name, "uhci") == 0) {
817 mdb_arg_t argv[] = {
818 {MDB_TYPE_STRING, {"uhci_state_t"}},
819 {MDB_TYPE_STRING, {"uhci_root_hub.rh_descr"}}
820 };
821 mdb_call_dcmd("print", statep, DCMD_ADDRSPEC, 2, argv);
822 }
823
824 if (strcmp(driver_name, "hubd") == 0) {
825 mdb_arg_t argv[] = {
826 {MDB_TYPE_STRING, {"hubd_t"}},
827 {MDB_TYPE_STRING, {"h_hub_descr"}}
828 };
829 mdb_call_dcmd("print", statep, DCMD_ADDRSPEC, 2, argv);
830 }
831
832 if (strcmp(driver_name, "hid") == 0) {
833 hid_state_t hidp;
834
835 if (mdb_vread(&hidp, sizeof (hid_state_t), statep) != -1) {
836 hidparser_handle hid_report;
837
838 if (mdb_vread(&hid_report, sizeof (hidparser_handle),
839 (uintptr_t)hidp.hid_report_descr) != -1) {
840
841 mdb_inc_indent(2);
842
843 mdb_printf("\n");
844 prt_usb_hid_item((uintptr_t)
845 hid_report.hidparser_handle_parse_tree);
846
847 mdb_dec_indent(2);
848 }
849 }
850 }
851
852 mdb_printf("\n");
853
854 return (DCMD_OK);
855 }
856
857 /* print hid report descriptor */
858 static void
prt_usb_hid_item(uintptr_t paddr)859 prt_usb_hid_item(uintptr_t paddr)
860 {
861 entity_item_t item;
862 if (mdb_vread(&item, sizeof (entity_item_t), paddr) != -1) {
863
864 prt_usb_hid_item_attrs((uintptr_t)item.entity_item_attributes);
865 prt_usb_hid_item_params(&item);
866
867 if (item.info.child) {
868 mdb_inc_indent(4);
869 prt_usb_hid_item((uintptr_t)item.info.child);
870 mdb_dec_indent(4);
871 }
872
873 if (item.entity_item_right_sibling) {
874 prt_usb_hid_item((uintptr_t)
875 item.entity_item_right_sibling);
876 }
877 }
878 }
879
880 static void
prt_usb_hid_item_params(entity_item_t * item)881 prt_usb_hid_item_params(entity_item_t *item)
882 {
883 switch (item->entity_item_type) {
884 case 0x80:
885 mdb_printf("INPUT ");
886
887 break;
888 case 0x90:
889 mdb_printf("OUTPUT ");
890
891 break;
892 case 0xA0:
893 mdb_printf("COLLECTION ");
894
895 break;
896 case 0xB0:
897 mdb_printf("FEATURE ");
898
899 break;
900 case 0xC0:
901 mdb_printf("END_COLLECTION ");
902
903 break;
904 default:
905 mdb_printf("MAIN_ITEM ");
906
907 break;
908 }
909
910 prt_usb_hid_item_data((uintptr_t)item->entity_item_params,
911 item->entity_item_params_leng);
912
913 mdb_printf("\n");
914 }
915
916 static void
prt_usb_hid_item_attrs(uintptr_t paddr)917 prt_usb_hid_item_attrs(uintptr_t paddr)
918 {
919 entity_attribute_t attr;
920
921 if (mdb_vread(&attr, sizeof (entity_attribute_t), paddr) != -1) {
922
923 prt_usb_hid_item_tags(attr.entity_attribute_tag);
924 prt_usb_hid_item_data((uintptr_t)attr.entity_attribute_value,
925 attr.entity_attribute_length);
926
927 mdb_printf("\n");
928
929 if (attr.entity_attribute_next) {
930 prt_usb_hid_item_attrs((uintptr_t)
931 attr.entity_attribute_next);
932 }
933 }
934 }
935
936 static void
prt_usb_hid_item_data(uintptr_t paddr,uint_t len)937 prt_usb_hid_item_data(uintptr_t paddr, uint_t len)
938 {
939 char data[4];
940 int i;
941
942 if (len > 4) {
943 mdb_warn("Incorrect entity_item_length: 0x%x\n", len);
944
945 return;
946 }
947
948 if (mdb_vread(data, len, paddr) != -1) {
949
950 mdb_printf("( ");
951 for (i = 0; i < len; i++) {
952 mdb_printf("0x%02x ", data[i] & 0xff);
953 }
954 mdb_printf(")");
955 }
956 }
957
958 static void
prt_usb_hid_item_tags(uint_t tag)959 prt_usb_hid_item_tags(uint_t tag)
960 {
961 switch (tag) {
962 case 0x04:
963 mdb_printf("usage page ");
964
965 break;
966 case 0x14:
967 mdb_printf("logical minimum ");
968
969 break;
970 case 0x24:
971 mdb_printf("logical maximum ");
972
973 break;
974 case 0x34:
975 mdb_printf("physical minimum ");
976
977 break;
978 case 0x44:
979 mdb_printf("physical maximum ");
980
981 break;
982 case 0x54:
983 mdb_printf("exponent ");
984
985 break;
986 case 0x64:
987 mdb_printf("unit ");
988
989 break;
990 case 0x74:
991 mdb_printf("report size ");
992
993 break;
994 case 0x84:
995 mdb_printf("report id ");
996
997 break;
998 case 0x94:
999 mdb_printf("report count ");
1000
1001 break;
1002 case 0x08:
1003 mdb_printf("usage ");
1004
1005 break;
1006 case 0x18:
1007 mdb_printf("usage min ");
1008
1009 break;
1010 case 0x28:
1011 mdb_printf("usage max ");
1012
1013 break;
1014
1015 default:
1016 mdb_printf("tag ");
1017 }
1018 }
1019
1020 /* print the info required by "-v" */
1021 static int
prt_usb_desc(uintptr_t usb_cfg,uint_t cfg_len)1022 prt_usb_desc(uintptr_t usb_cfg, uint_t cfg_len)
1023 {
1024 uintptr_t paddr = usb_cfg;
1025 uintptr_t pend = usb_cfg + cfg_len;
1026 uchar_t desc_type, nlen;
1027 usb_if_descr_t usb_if;
1028 ulong_t indent = 0;
1029
1030 mdb_arg_t argv = {MDB_TYPE_STRING, {"usb_dev_descr_t"}};
1031
1032 if (mdb_vread(&nlen, 1, paddr) == -1) {
1033
1034 return (DCMD_ERR);
1035 }
1036 while ((paddr + nlen <= pend) && (nlen > 0)) {
1037 if (mdb_vread(&desc_type, 1, paddr + 1) == -1) {
1038
1039 return (DCMD_ERR);
1040 }
1041
1042 switch (desc_type) {
1043 case USB_DESCR_TYPE_DEV:
1044 mdb_printf("Device Descriptor\n");
1045 print_struct(paddr, nlen, &argv);
1046
1047 break;
1048 case USB_DESCR_TYPE_CFG:
1049 indent = 4;
1050 mdb_inc_indent(indent);
1051 mdb_printf("Configuration Descriptor\n");
1052 print_descr(paddr, nlen, usb_cfg_descr, usb_cfg_item);
1053 mdb_dec_indent(indent);
1054
1055 break;
1056 case USB_DESCR_TYPE_STRING:
1057 mdb_printf("String Descriptor\n");
1058 print_descr(paddr, nlen, usb_str_descr, usb_str_item);
1059
1060 break;
1061 case USB_DESCR_TYPE_IF:
1062 indent = 8;
1063 mdb_inc_indent(indent);
1064 mdb_printf("Interface Descriptor\n");
1065 print_descr(paddr, nlen, usb_if_descr, usb_if_item);
1066 mdb_dec_indent(indent);
1067 mdb_vread(&usb_if, sizeof (usb_if_descr_t), paddr);
1068
1069 break;
1070 case USB_DESCR_TYPE_EP:
1071 indent = 8;
1072 mdb_inc_indent(indent);
1073 mdb_printf("Endpoint Descriptor\n");
1074 print_descr(paddr, nlen, usb_ep_descr, usb_ep_item);
1075 mdb_dec_indent(indent);
1076
1077 break;
1078 case USB_DESCR_TYPE_DEV_QLF:
1079 mdb_printf("Device_Qualifier Descriptor\n");
1080 print_descr(paddr, nlen, usb_qlf_descr, usb_qlf_item);
1081
1082 break;
1083 case USB_DESCR_TYPE_OTHER_SPEED_CFG:
1084 indent = 4;
1085 mdb_inc_indent(indent);
1086 mdb_printf("Other_Speed_Configuration Descriptor\n");
1087 print_descr(paddr, nlen, usb_cfg_descr, usb_cfg_item);
1088 mdb_dec_indent(indent);
1089
1090 break;
1091 case USB_DESCR_TYPE_IA:
1092 indent = 6;
1093 mdb_inc_indent(indent);
1094 mdb_printf("Interface_Association Descriptor\n");
1095 print_descr(paddr, nlen, usb_ia_descr, usb_ia_item);
1096 mdb_dec_indent(indent);
1097
1098 break;
1099 case 0x21: /* hid descriptor */
1100 indent = 12;
1101 mdb_inc_indent(indent);
1102 if (usb_if.bInterfaceClass == 0xe0 &&
1103 usb_if.bInterfaceSubClass == 0x02) {
1104 mdb_printf("WA Descriptor\n");
1105 print_descr(paddr, nlen, usb_wa_descr,
1106 usb_wa_item);
1107 } else {
1108 mdb_printf("HID Descriptor\n");
1109 print_descr(paddr, nlen, usb_hid_descr,
1110 usb_hid_item);
1111 }
1112 mdb_dec_indent(indent);
1113
1114 break;
1115 case 0x24: /* class specific interfce descriptor */
1116 indent = 12;
1117 mdb_inc_indent(indent);
1118 if (usb_if.bInterfaceClass == 1 &&
1119 usb_if.bInterfaceSubClass == 1) {
1120 mdb_printf("AudioControl_Interface: ");
1121 prt_usb_ac_desc(paddr, nlen);
1122
1123 } else if (usb_if.bInterfaceClass == 1 &&
1124 usb_if.bInterfaceSubClass == 2) {
1125 mdb_printf("AudioStream_Interface: ");
1126 prt_usb_as_desc(paddr, nlen);
1127
1128 } else if (usb_if.bInterfaceClass == 0x0E &&
1129 usb_if.bInterfaceSubClass == 1) {
1130 mdb_printf("VideoControl_Interface: ");
1131 prt_usb_vc_desc(paddr, nlen);
1132
1133
1134 } else if (usb_if.bInterfaceClass == 0x0E &&
1135 usb_if.bInterfaceSubClass == 2) {
1136 mdb_printf("VideoStream_Interface: ");
1137 prt_usb_vs_desc(paddr, nlen);
1138
1139 } else {
1140 mdb_printf("Unknown_Interface:"
1141 "0x%x\n", desc_type);
1142 prt_usb_buf(paddr, nlen);
1143 }
1144 mdb_dec_indent(indent);
1145
1146 break;
1147 case 0x25: /* class specific endpoint descriptor */
1148 indent = 12;
1149 mdb_inc_indent(indent);
1150 if (usb_if.bInterfaceClass == 0x01) {
1151 mdb_printf("AudioEndpoint:\n");
1152 print_descr(paddr, nlen,
1153 usb_as_ep_descr, usb_as_ep_item);
1154
1155 } else if (usb_if.bInterfaceClass == 0x0E) {
1156 mdb_printf("VideoEndpoint:\n");
1157 print_descr(paddr, nlen,
1158 usb_ep_descr, usb_ep_item);
1159
1160 } else {
1161 mdb_printf("Unknown_Endpoint:"
1162 "0x%x\n", desc_type);
1163 prt_usb_buf(paddr, nlen);
1164 }
1165 mdb_dec_indent(indent);
1166
1167 break;
1168 default:
1169 mdb_inc_indent(indent);
1170 mdb_printf("Unknown Descriptor: 0x%x\n", desc_type);
1171 prt_usb_buf(paddr, nlen);
1172 mdb_dec_indent(indent);
1173
1174 break;
1175 }
1176
1177 paddr += nlen;
1178 if (mdb_vread(&nlen, 1, paddr) == -1) {
1179
1180 return (DCMD_ERR);
1181 }
1182 };
1183
1184 return (DCMD_OK);
1185 }
1186
1187
1188 /* print audio class specific control descriptor */
1189 static int
prt_usb_ac_desc(uintptr_t addr,uint_t nlen)1190 prt_usb_ac_desc(uintptr_t addr, uint_t nlen)
1191 {
1192 uchar_t sub_type;
1193
1194 if (mdb_vread(&sub_type, 1, addr + 2) == -1) {
1195
1196 return (DCMD_ERR);
1197 }
1198 switch (sub_type) {
1199 case 0x01:
1200 mdb_printf("header Descriptor\n");
1201 print_descr(addr, nlen,
1202 usb_ac_header_descr, usb_ac_header_item);
1203
1204 break;
1205 case 0x02:
1206 mdb_printf("input_terminal Descriptor\n");
1207 print_descr(addr, nlen,
1208 usb_ac_input_term_descr, usb_ac_input_term_item);
1209
1210 break;
1211 case 0x03:
1212 mdb_printf("output_terminal Descriptor\n");
1213 print_descr(addr, nlen,
1214 usb_ac_output_term_descr, usb_ac_output_term_item);
1215
1216 break;
1217 case 0x04:
1218 mdb_printf("mixer_unit Descriptor\n");
1219 print_descr(addr, nlen,
1220 usb_ac_mixer_descr, usb_ac_mixer_item);
1221
1222 break;
1223 case 0x05:
1224 mdb_printf("selector_unit Descriptor\n");
1225 print_descr(addr, nlen,
1226 usb_ac_selector_descr, usb_ac_selector_item);
1227
1228 break;
1229 case 0x06:
1230 mdb_printf("feature_unit Descriptor\n");
1231 print_descr(addr, nlen,
1232 usb_ac_feature_descr, usb_ac_feature_item);
1233
1234 break;
1235 case 0x07:
1236 mdb_printf("processing_unit Descriptor\n");
1237 print_descr(addr, nlen,
1238 usb_ac_processing_descr, usb_ac_processing_item);
1239
1240 break;
1241 case 0x08:
1242 mdb_printf("extension_unit Descriptor\n");
1243 print_descr(addr, nlen,
1244 usb_ac_extension_descr, usb_ac_extension_item);
1245
1246 break;
1247 default:
1248 mdb_printf("Unknown AC sub-descriptor 0x%x\n", sub_type);
1249 prt_usb_buf(addr, nlen);
1250
1251 break;
1252 }
1253
1254 return (DCMD_OK);
1255 }
1256
1257 /* print audio class specific stream descriptor */
1258 static int
prt_usb_as_desc(uintptr_t addr,uint_t nlen)1259 prt_usb_as_desc(uintptr_t addr, uint_t nlen)
1260 {
1261 uchar_t sub_type;
1262
1263 if (mdb_vread(&sub_type, 1, addr + 2) == -1) {
1264
1265 return (DCMD_ERR);
1266 }
1267 switch (sub_type) {
1268 case 0x01:
1269 mdb_printf("general_interface Descriptor\n");
1270 print_descr(addr, nlen,
1271 usb_as_if_descr, usb_as_if_item);
1272
1273 break;
1274 case 0x02:
1275 mdb_printf("format_type Descriptor\n");
1276 print_descr(addr, nlen,
1277 usb_as_format_descr, usb_as_format_item);
1278
1279 break;
1280 default:
1281 mdb_printf("Unknown AS sub-descriptor 0x%x\n", sub_type);
1282 prt_usb_buf(addr, nlen);
1283
1284 break;
1285 }
1286
1287 return (DCMD_OK);
1288 }
1289
1290 /* print video class specific control descriptor */
1291 static int
prt_usb_vc_desc(uintptr_t addr,uint_t nlen)1292 prt_usb_vc_desc(uintptr_t addr, uint_t nlen)
1293 {
1294 uchar_t sub_type;
1295
1296 if (mdb_vread(&sub_type, 1, addr + 2) == -1) {
1297
1298 return (DCMD_ERR);
1299 }
1300 switch (sub_type) {
1301 case 0x01:
1302 mdb_printf("header Descriptor\n");
1303 print_descr(addr, nlen,
1304 usb_vc_header_descr, usb_vc_header_item);
1305
1306 break;
1307 case 0x02:
1308 mdb_printf("input_terminal Descriptor\n");
1309 print_descr(addr, nlen,
1310 usb_vc_input_term_descr, usb_vc_input_term_item);
1311
1312 break;
1313 case 0x03:
1314 mdb_printf("output_terminal Descriptor\n");
1315 print_descr(addr, nlen,
1316 usb_vc_output_term_descr, usb_vc_output_term_item);
1317
1318 break;
1319 case 0x04:
1320 mdb_printf("selector_unit Descriptor\n");
1321 print_descr(addr, nlen,
1322 usb_vc_selector_descr, usb_vc_selector_item);
1323
1324 break;
1325 case 0x05:
1326 mdb_printf("processing_unit Descriptor\n");
1327 print_descr(addr, nlen,
1328 usb_vc_processing_descr, usb_vc_processing_item);
1329
1330 break;
1331 case 0x06:
1332 mdb_printf("extension_unit Descriptor\n");
1333 print_descr(addr, nlen,
1334 usb_vc_extension_descr, usb_vc_extension_item);
1335
1336 break;
1337 default:
1338 mdb_printf("Unknown VC sub-descriptor 0x%x\n", sub_type);
1339 prt_usb_buf(addr, nlen);
1340
1341 break;
1342 }
1343
1344 return (DCMD_OK);
1345 }
1346
1347 /* print video class specific stream descriptor */
1348 static int
prt_usb_vs_desc(uintptr_t addr,uint_t nlen)1349 prt_usb_vs_desc(uintptr_t addr, uint_t nlen)
1350 {
1351 uchar_t sub_type;
1352
1353 if (mdb_vread(&sub_type, 1, addr + 2) == -1) {
1354
1355 return (DCMD_ERR);
1356 }
1357 switch (sub_type) {
1358 case 0x01:
1359 mdb_printf("input_header Descriptor\n");
1360 print_descr(addr, nlen,
1361 usb_vs_input_header_descr, usb_vs_input_header_item);
1362
1363 break;
1364 case 0x02:
1365 mdb_printf("output_header Descriptor\n");
1366 print_descr(addr, nlen,
1367 usb_vs_output_header_descr, usb_vs_output_header_item);
1368
1369 break;
1370 case 0x03:
1371 mdb_printf("still_image_frame Descriptor\n");
1372 print_descr(addr, nlen,
1373 usb_vs_still_image_descr, usb_vs_still_image_item);
1374
1375 break;
1376 case 0x04:
1377 mdb_printf("format_uncompressed Descriptor\n");
1378 print_descr(addr, nlen,
1379 usb_vs_format_uncps_descr, usb_vs_format_uncps_item);
1380
1381 break;
1382 case 0x05:
1383 mdb_printf("frame_uncompressed Descriptor\n");
1384 print_descr(addr, nlen,
1385 usb_vs_2frame_descr, usb_vs_2frame_item);
1386
1387 break;
1388 case 0x06:
1389 mdb_printf("format_mjpeg Descriptor\n");
1390 print_descr(addr, nlen,
1391 usb_vs_format_mjpeg_descr, usb_vs_format_mjpeg_item);
1392
1393 break;
1394 case 0x07:
1395 mdb_printf("frame_mjpeg Descriptor\n");
1396 print_descr(addr, nlen,
1397 usb_vs_2frame_descr, usb_vs_2frame_item);
1398
1399 break;
1400 case 0x0A:
1401 mdb_printf("format_mpeg2ts Descriptor\n");
1402 print_descr(addr, nlen,
1403 usb_vs_format_mp2ts_descr, usb_vs_format_mp2ts_item);
1404
1405 break;
1406 case 0x0C:
1407 mdb_printf("format_dv Descriptor\n");
1408 print_descr(addr, nlen,
1409 usb_vs_format_dv_descr, usb_vs_format_dv_item);
1410
1411 break;
1412 case 0x0D:
1413 mdb_printf("color_matching Descriptor\n");
1414 print_descr(addr, nlen,
1415 usb_vs_color_matching_descr, usb_vs_color_matching_item);
1416
1417 break;
1418 default:
1419 mdb_printf("Unknown VS sub-descriptor 0x%x\n", sub_type);
1420 prt_usb_buf(addr, nlen);
1421
1422 break;
1423 }
1424
1425 return (DCMD_OK);
1426 }
1427
1428 /* parse and print the descriptor items */
1429 static int
print_descr(uintptr_t addr,uint_t nlen,usb_descr_item_t * item,uint_t nitem)1430 print_descr(uintptr_t addr, uint_t nlen, usb_descr_item_t *item, uint_t nitem)
1431 {
1432 int i, j;
1433 uint8_t buf[8];
1434 uint64_t value;
1435 uintptr_t paddr = addr;
1436 usb_descr_item_t *p = item;
1437
1438 mdb_printf("{");
1439 for (i = 0; (i < nitem) && (paddr < addr + nlen); i++) {
1440 mdb_printf("\n %s =", p->name);
1441 switch (p->nlen) {
1442 case 1: /* uint8_t */
1443 if (mdb_vread(buf, 1, paddr) == -1) {
1444
1445 return (DCMD_ERR);
1446 }
1447 value = buf[0];
1448
1449 break;
1450 case 2: /* uint16_t */
1451 if (mdb_vread(buf, 2, paddr) == -1) {
1452
1453 return (DCMD_ERR);
1454 }
1455 value = buf[0] | (buf[1] << 8);
1456
1457 break;
1458 case 4: /* uint32_t */
1459 if (mdb_vread(buf, 4, paddr) == -1) {
1460
1461 return (DCMD_ERR);
1462 }
1463 value = buf[0] | (buf[1] << 8) |
1464 (buf[2] << 16) | (buf[3] << 24);
1465
1466 break;
1467 case 8: /* uint64_t */
1468 if (mdb_vread(buf, 8, paddr) == -1) {
1469
1470 return (DCMD_ERR);
1471 }
1472 value = buf[4] | (buf[5] << 8) |
1473 (buf[6] << 16) | (buf[7] << 24);
1474 value = buf[0] | (buf[1] << 8) |
1475 (buf[2] << 16) | (buf[3] << 24) |
1476 (value << 32);
1477
1478 break;
1479 default: /* byte array */
1480 value = 0;
1481 /* print an array instead of a value */
1482 for (j = 0; j < p->nlen - BYTE_OFFSET; j++) {
1483 if (mdb_vread(buf, 1, paddr + j) == -1) {
1484
1485 break;
1486 }
1487 mdb_printf(" 0x%x", buf[0]);
1488 }
1489
1490 break;
1491 }
1492
1493 if (p->nlen > BYTE_OFFSET) {
1494 paddr += p->nlen - BYTE_OFFSET;
1495 } else {
1496 mdb_printf(" 0x%x", value);
1497 paddr += p->nlen;
1498 }
1499
1500 p++;
1501 }
1502
1503 /* print the unresolved bytes */
1504 if (paddr < addr + nlen) {
1505 mdb_printf("\n ... =");
1506 }
1507 while (paddr < addr + nlen) {
1508 if (mdb_vread(buf, 1, paddr++) == -1) {
1509
1510 break;
1511 }
1512 mdb_printf(" 0x%x", buf[0]);
1513 }
1514 mdb_printf("\n}\n");
1515
1516 return (DCMD_OK);
1517 }
1518
1519 /* print the buffer as a struct */
1520 static int
print_struct(uintptr_t addr,uint_t nlen,mdb_arg_t * arg)1521 print_struct(uintptr_t addr, uint_t nlen, mdb_arg_t *arg)
1522 {
1523 mdb_ctf_id_t id;
1524 if (mdb_ctf_lookup_by_name(arg->a_un.a_str, &id) == 0) {
1525
1526 mdb_call_dcmd("print", addr, DCMD_ADDRSPEC, 1, arg);
1527 } else {
1528
1529 prt_usb_buf(addr, nlen);
1530 }
1531
1532 return (DCMD_OK);
1533 }
1534
1535 /* print the buffer as a byte array */
1536 static int
prt_usb_buf(uintptr_t addr,uint_t nlen)1537 prt_usb_buf(uintptr_t addr, uint_t nlen)
1538 {
1539 int i;
1540 uchar_t val;
1541
1542 mdb_printf("{\n");
1543 for (i = 0; i < nlen; i++) {
1544 if (mdb_vread(&val, 1, addr + i) == -1) {
1545
1546 break;
1547 }
1548 mdb_printf("%02x ", val);
1549 }
1550 if (nlen) {
1551 mdb_printf("\n");
1552 }
1553 mdb_printf("}\n");
1554
1555 return (DCMD_OK);
1556 }
1557