dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / mdb / common / modules / usba / prtusb.c
blob9f6ffc4177328f02eba07435c222de864c3ee63c
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
25 * Copyright 2016 Joyent, Inc.
29 #include <sys/mdb_modapi.h>
32 #include <sys/usb/usba.h>
33 #include <sys/usb/usba/usba_types.h>
34 #include <sys/usb/clients/hid/hid.h>
35 #include <sys/usb/clients/hidparser/hidparser.h>
36 #include <sys/usb/clients/hidparser/hidparser_impl.h>
37 #include <sys/usb/usba/genconsole.h>
38 #include <sys/usb/clients/hid/hidvar.h>
41 /* ****************************************************************** */
43 /* extenal definition */
45 typedef struct mdb_ctf_id {
46 void *_opaque[2];
47 } mdb_ctf_id_t;
49 extern int mdb_ctf_lookup_by_name(const char *, mdb_ctf_id_t *);
51 extern int mdb_devinfo2driver(uintptr_t, char *, size_t);
53 extern int mdb_devinfo2statep(uintptr_t, char *, uintptr_t *);
55 extern char *mdb_ddi_pathname(uintptr_t, char *, size_t);
58 /* ****************************************************************** */
60 /* internal definition */
62 #define OPT_TREE 0x01
63 #define OPT_VERB 0x02
65 #define STRLEN 256
66 #define BYTE_OFFSET 8
69 typedef struct usb_descr_item {
70 uint_t nlen; /* if it's an byte array, nlen += BYTE_OFFSET */
71 char *name; /* descriptor item name */
72 } usb_descr_item_t;
74 /* define the known descriptor items */
75 static usb_descr_item_t usb_cfg_descr[] = {
76 {1, "bLength"},
77 {1, "bDescriptorType"},
78 {2, "wTotalLength"},
79 {1, "bNumInterfaces"},
80 {1, "bConfigurationValue"},
81 {1, "iConfiguration"},
82 {1, "bmAttributes"},
83 {1, "bMaxPower"},
85 static uint_t usb_cfg_item = 8;
87 static usb_descr_item_t usb_ia_descr[] = {
88 {1, "bLength"},
89 {1, "bDescriptorType"},
90 {1, "bFirstInterface"},
91 {1, "bInterfaceCount"},
92 {1, "bFunctionClass"},
93 {1, "bFunctionSubClass"},
94 {1, "bFunctionProtocol"},
95 {1, "iFunction"},
97 static uint_t usb_ia_item = 8;
99 static usb_descr_item_t usb_if_descr[] = {
100 {1, "bLength"},
101 {1, "bDescriptorType"},
102 {1, "bInterfaceNumber"},
103 {1, "bAlternateSetting"},
104 {1, "bNumEndpoints"},
105 {1, "bInterfaceClass"},
106 {1, "bInterfaceSubClass"},
107 {1, "bInterfaceProtocol"},
108 {1, "iInterface"},
110 static uint_t usb_if_item = 9;
112 static usb_descr_item_t usb_ep_descr[] = {
113 {1, "bLength"},
114 {1, "bDescriptorType"},
115 {1, "bEndpointAddress"},
116 {1, "bmAttributes"},
117 {2, "wMaxPacketSize"},
118 {1, "bInterval"},
120 static uint_t usb_ep_item = 6;
122 static usb_descr_item_t usb_ep_ss_comp_descr[] = {
123 {1, "bLength"},
124 {1, "bDescriptorType"},
125 {1, "bMaxBurst"},
126 {1, "bmAttributes"},
127 {2, "wBytesPerInterval"}
129 static uint_t usb_ep_ss_comp_item = 5;
131 static usb_descr_item_t usb_qlf_descr[] = {
132 {1, "bLength"},
133 {1, "bDescriptorType"},
134 {2, "bcdUSB"},
135 {1, "bDeviceClass"},
136 {1, "bDeviceSubClass"},
137 {1, "bDeviceProtocol"},
138 {1, "bMaxPacketSize0"},
139 {1, "bNumConfigurations"},
140 {1, "bReserved"},
142 static uint_t usb_qlf_item = 9;
144 static usb_descr_item_t usb_str_descr[] = {
145 {1, "bLength"},
146 {1, "bDescriptorType"},
147 {1, "bString"},
149 static uint_t usb_str_item = 3;
151 static usb_descr_item_t usb_wa_descr[] = {
152 {1, "bLength"},
153 {1, "bDescriptorType"},
154 {2, "bcdWAVersion"},
155 {1, "bNumPorts"},
156 {1, "bmAttributes"},
157 {2, "wNumRPipes"},
158 {2, "wRPipeMaxBlock"},
159 {1, "bRPipeBlockSize"},
160 {1, "bPwrOn2PwrGood"},
161 {1, "bNumMMCIEs"},
162 {1, "DeviceRemovable"},
165 static uint_t usb_wa_item = 11;
167 static usb_descr_item_t usb_hid_descr[] = {
168 {1, "bLength"},
169 {1, "bDescriptorType"},
170 {2, "bcdHID"},
171 {1, "bCountryCode"},
172 {1, "bNumDescriptors"},
173 {1, "bReportDescriptorType"},
174 {2, "wReportDescriptorLength"},
176 static uint_t usb_hid_item = 7;
178 static usb_descr_item_t usb_ac_header_descr[] = {
179 {1, "bLength"},
180 {1, "bDescriptorType"},
181 {1, "bDescriptorSubType"},
182 {2, "bcdADC"},
183 {2, "wTotalLength"},
184 {1, "blnCollection"},
185 {1, "baInterfaceNr"},
187 static uint_t usb_ac_header_item = 7;
189 static usb_descr_item_t usb_ac_input_term_descr[] = {
190 {1, "bLength"},
191 {1, "bDescriptorType"},
192 {1, "bDescriptorSubType"},
193 {1, "bTerminalID"},
194 {2, "wTerminalType"},
195 {1, "bAssocTerminal"},
196 {1, "bNrChannels"},
197 {2, "wChannelConfig"},
198 {1, "iChannelNames"},
199 {1, "iTerminal"},
201 static uint_t usb_ac_input_term_item = 10;
203 static usb_descr_item_t usb_ac_output_term_descr[] = {
204 {1, "bLength"},
205 {1, "bDescriptorType"},
206 {1, "bDescriptorSubType"},
207 {1, "bTerminalID"},
208 {2, "wTerminalType"},
209 {1, "bAssocTerminal"},
210 {1, "bSourceID"},
211 {1, "iTerminal"},
213 static uint_t usb_ac_output_term_item = 8;
215 static usb_descr_item_t usb_ac_mixer_descr[] = {
216 {1, "bLength"},
217 {1, "bDescriptorType"},
218 {1, "bDescriptorSubType"},
219 {1, "bUnitID"},
220 {1, "bNrInPins"},
221 {1, "baSourceID"},
223 static uint_t usb_ac_mixer_item = 6;
225 static usb_descr_item_t usb_ac_selector_descr[] = {
226 {1, "bLength"},
227 {1, "bDescriptorType"},
228 {1, "bDescriptorSubType"},
229 {1, "bUnitID"},
230 {1, "bNrInPins"},
231 {1, "baSourceID"},
233 static uint_t usb_ac_selector_item = 6;
235 static usb_descr_item_t usb_ac_feature_descr[] = {
236 {1, "bLength"},
237 {1, "bDescriptorType"},
238 {1, "bDescriptorSubType"},
239 {1, "bUnitID"},
240 {1, "bSourceID"},
241 {1, "bControlSize"},
242 {1, "bmaControls"},
244 static uint_t usb_ac_feature_item = 7;
246 static usb_descr_item_t usb_ac_processing_descr[] = {
247 {1, "bLength"},
248 {1, "bDescriptorType"},
249 {1, "bDescriptorSubType"},
250 {1, "bUnitID"},
251 {1, "wProcessType"},
252 {1, "bNrInPins"},
253 {1, "baSourceID"},
255 static uint_t usb_ac_processing_item = 7;
257 static usb_descr_item_t usb_ac_extension_descr[] = {
258 {1, "bLength"},
259 {1, "bDescriptorType"},
260 {1, "bDescriptorSubType"},
261 {1, "wExtensionCode"},
262 {1, "bUnitID"},
263 {1, "bNrInPins"},
264 {1, "baSourceID"},
266 static uint_t usb_ac_extension_item = 7;
268 static usb_descr_item_t usb_as_ep_descr[] = {
269 {1, "blength"},
270 {1, "bDescriptorType"},
271 {1, "bDescriptorSubType"},
272 {1, "bmAttributes"},
273 {1, "bLockDelayUnits"},
274 {2, "wLockDelay"},
276 static uint_t usb_as_ep_item = 6;
278 static usb_descr_item_t usb_as_if_descr[] = {
279 {1, "blength"},
280 {1, "bDescriptorType"},
281 {1, "bDescriptorSubType"},
282 {1, "bTerminalLink"},
283 {1, "bDelay"},
284 {2, "wFormatTag"},
286 static uint_t usb_as_if_item = 6;
288 static usb_descr_item_t usb_as_format_descr[] = {
289 {1, "blength"},
290 {1, "bDescriptorType"},
291 {1, "bDescriptorSubType"},
292 {1, "bFormatType"},
293 {1, "bNrChannels"},
294 {1, "bSubFrameSize"},
295 {1, "bBitResolution"},
296 {1, "bSamFreqType"},
297 {1, "bSamFreqs"},
299 static uint_t usb_as_format_item = 9;
301 static usb_descr_item_t usb_vc_header_descr[] = {
302 {1, "bLength"},
303 {1, "bDescriptorType"},
304 {1, "bDescriptorSubtype"},
305 {2, "bcdUVC"},
306 {2, "wTotalLength"},
307 {4, "dwClockFrequency"},
308 {1, "bInCollection"},
310 static uint_t usb_vc_header_item = 7;
312 static usb_descr_item_t usb_vc_input_term_descr[] = {
313 {1, "bLength"},
314 {1, "bDescriptorType"},
315 {1, "bDescriptorSubType"},
316 {1, "bTerminalID"},
317 {2, "wTerminalType"},
318 {1, "AssocTerminal"},
319 {1, "iTerminal"},
321 static uint_t usb_vc_input_term_item = 7;
323 static usb_descr_item_t usb_vc_output_term_descr[] = {
324 {1, "bLength"},
325 {1, "bDescriptorType"},
326 {1, "bDescriptorSubType"},
327 {1, "bTerminalID"},
328 {2, "wTerminalType"},
329 {1, "AssocTerminal"},
330 {1, "bSourceID"},
331 {1, "iTerminal"},
333 static uint_t usb_vc_output_term_item = 8;
335 static usb_descr_item_t usb_vc_processing_descr[] = {
336 {1, "bLength"},
337 {1, "bDescriptorType"},
338 {1, "bDescriptorSubType"},
339 {1, "bUnitID"},
340 {1, "bSourceID"},
341 {2, "wMaxMultiplier"},
342 {1, "bControlSize"},
343 {1, "bmControls"},
345 static uint_t usb_vc_processing_item = 8;
347 static usb_descr_item_t usb_vc_selector_descr[] = {
348 {1, "bLength"},
349 {1, "bDescriptorType"},
350 {1, "bDescriptorSubType"},
351 {1, "bUnitID"},
352 {1, "bNrInPins"},
354 static uint_t usb_vc_selector_item = 5;
356 static usb_descr_item_t usb_vc_extension_descr[] = {
357 {1, "bLength"},
358 {1, "bDescriptorType"},
359 {1, "bDescriptorSubType"},
360 {1, "bUnitID"},
361 {16 + BYTE_OFFSET, "guidExtensionCode[16]"},
362 {1, "bNumControls"},
363 {1, "bNrInPins"},
365 static uint_t usb_vc_extension_item = 7;
367 static usb_descr_item_t usb_vs_input_header_descr[] = {
368 {1, "bLength"},
369 {1, "bDescriptorType"},
370 {1, "bDescriptorSubType"},
371 {1, "bNumFormats"},
372 {2, "wTotalLength"},
373 {1, "bEndpointAddress"},
374 {1, "bmInfo"},
375 {1, "bTerminalLink"},
376 {1, "bStillCaptureMethod"},
377 {1, "bTriggerSupport"},
378 {1, "bTriggerUsage"},
379 {1, "bControlSize"},
380 {1, "bmaControls"},
382 static uint_t usb_vs_input_header_item = 13;
384 static usb_descr_item_t usb_vs_output_header_descr[] = {
385 {1, "bLength"},
386 {1, "bDescriptorType"},
387 {1, "bDescriptorSubType"},
388 {1, "bNumFormats"},
389 {2, "wTotalLength"},
390 {1, "bEndpointAddress"},
391 {1, "bTerminalLink"},
392 {1, "bControlSize"},
393 {1, "bmaControls"},
395 static uint_t usb_vs_output_header_item = 9;
397 static usb_descr_item_t usb_vs_still_image_descr[] = {
398 {1, "bLength"},
399 {1, "bDescriptorType"},
400 {1, "bDescriptorSubType"},
401 {1, "bEndpointAddress"},
402 {1, "bNumImageSizePatterns"},
403 {2, "wWidth"},
404 {2, "wHeight"},
406 static uint_t usb_vs_still_image_item = 7;
408 static usb_descr_item_t usb_vs_color_matching_descr[] = {
409 {1, "bLength"},
410 {1, "bDescriptorType"},
411 {1, "bDescriptorSubtype"},
412 {1, "bColorPrimaries"},
413 {1, "bTransferCharacteristics"},
414 {1, "bMatrixCoefficients"},
416 static uint_t usb_vs_color_matching_item = 6;
418 static usb_descr_item_t usb_vs_2frame_descr[] = {
419 {1, "bLength"},
420 {1, "bDescriptorType"},
421 {1, "bDescriptorSubType"},
422 {1, "bFrameIndex"},
423 {1, "bmCapabilities"},
424 {2, "wWidth"},
425 {2, "wHeight"},
426 {4, "dwMinBitRate"},
427 {4, "dwMaxBitRate"},
428 {4, "dwMaxVideoFrameBufferSize"},
429 {4, "dwDefaultFrameInterval"},
430 {1, "bFrameIntervalType"},
432 static uint_t usb_vs_2frame_item = 12;
434 static usb_descr_item_t usb_vs_format_mjpeg_descr[] = {
435 {1, "bLength"},
436 {1, "bDescriptorType"},
437 {1, "bDescriptorSubType"},
438 {1, "bFormatIndex"},
439 {1, "bNumFrameDescriptors"},
440 {1, "bmFlags"},
441 {1, "bDefaultFrameIndex"},
442 {1, "bAspectRatioX"},
443 {1, "bAspectRatioY"},
444 {1, "bmInterlaceFlags"},
445 {1, "bCopyProtect"},
447 static uint_t usb_vs_format_mjpeg_item = 11;
449 static usb_descr_item_t usb_vs_format_uncps_descr[] = {
450 {1, "bLength"},
451 {1, "bDescriptorType"},
452 {1, "bDescriptorSubType"},
453 {1, "bFormatIndex"},
454 {1, "bNumFrameDescriptors"},
455 {16 + BYTE_OFFSET, "guidFormat[16]"},
456 {1, "bBitsPerPixel"},
457 {1, "bDefaultFrameIndex"},
458 {1, "bAspectRatioX"},
459 {1, "bAspectRatioY"},
460 {1, "bmInterlaceFlags"},
461 {1, "bCopyProtect"},
463 static uint_t usb_vs_format_uncps_item = 12;
465 static usb_descr_item_t usb_vs_format_mp2ts_descr[] = {
466 {1, "bLength"},
467 {1, "bDescriptorType"},
468 {1, "bDescriptorSubType"},
469 {1, "bFormatIndex"},
470 {1, "bDataOffset"},
471 {1, "bPacketLength"},
472 {1, "bStrideLength"},
473 {16 + BYTE_OFFSET, "guidStrideFormat[16]"},
475 static uint_t usb_vs_format_mp2ts_item = 8;
477 static usb_descr_item_t usb_vs_format_dv_descr[] = {
478 {1, "bLength"},
479 {1, "bDescriptorType"},
480 {1, "bDescriptorSubType"},
481 {1, "bFormatIndex"},
482 {4, "dwMaxVideoFrameBufferSize"},
483 {1, "bFormatType"},
485 static uint_t usb_vs_format_dv_item = 6;
488 /* ****************************************************************** */
490 typedef struct hci_state {
491 void *hci_dip;
492 uint_t hci_instance;
493 void *hci_hcdi_ops;
494 uint_t hci_flags;
495 uint16_t vendor_id;
496 uint16_t device_id;
497 } hci_state_t;
499 static int prt_usb_tree(uintptr_t paddr, uint_t flag);
501 static int prt_usb_tree_node(uintptr_t paddr);
503 static void prt_usb_hid_item(uintptr_t paddr);
505 static void prt_usb_hid_item_params(entity_item_t *item);
507 static void prt_usb_hid_item_attrs(uintptr_t paddr);
509 static void prt_usb_hid_item_tags(uint_t tag);
511 static void prt_usb_hid_item_data(uintptr_t paddr, uint_t len);
513 static int prt_usb_desc(uintptr_t usb_cfg, uint_t cfg_len);
515 static int prt_usb_ac_desc(uintptr_t paddr, uint_t nlen);
517 static int prt_usb_as_desc(uintptr_t paddr, uint_t nlen);
519 static int prt_usb_vc_desc(uintptr_t paddr, uint_t nlen);
521 static int prt_usb_vs_desc(uintptr_t paddr, uint_t nlen);
523 static int print_descr(uintptr_t, uint_t, usb_descr_item_t *, uint_t);
525 static int print_struct(uintptr_t, uint_t, mdb_arg_t *);
527 static int prt_usb_buf(uintptr_t, uint_t);
530 /* ****************************************************************** */
532 /* exported functions */
534 void prt_usb_usage(void);
536 int prtusb(uintptr_t, uint_t, int, const mdb_arg_t *);
538 /* ****************************************************************** */
540 /* help of prtusb */
541 void
542 prt_usb_usage(void)
544 mdb_printf("%-8s : %s\n", "-v", "print all descriptors");
545 mdb_printf("%-8s : %s\n", "-t", "print device trees");
546 mdb_printf("%-8s : %s\n", "-i index", "print the device by index");
549 /* the entry of ::prtusb */
551 prtusb(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
553 static int count = 1;
554 uint64_t sel_num = 0;
555 uint_t usb_flag = 0;
556 usba_device_t usb_dev;
557 usb_dev_descr_t dev_desc;
558 struct dev_info usb_dip;
559 char strbuf[STRLEN];
561 /* print all usba devices if no address assigned */
562 if (!(flags & DCMD_ADDRSPEC)) {
563 if (mdb_walk_dcmd("usba_device", "prtusb", argc, argv) == -1) {
564 mdb_warn("failed to walk usba_device");
566 return (DCMD_ERR);
569 return (DCMD_OK);
572 /* for the first device, print head */
573 if (DCMD_HDRSPEC(flags)) {
574 count = 1;
575 mdb_printf("%<u>%-8s%-12s%-6s%-14s%-5s%-12s%-20s%</u>\n",
576 "INDEX", "DRIVER", "INST", "NODE", "GEN", "VID.PID",
577 "PRODUCT");
580 if (mdb_getopts(argc, argv,
581 'i', MDB_OPT_UINT64, &sel_num,
582 't', MDB_OPT_SETBITS, OPT_TREE, &usb_flag,
583 'v', MDB_OPT_SETBITS, OPT_VERB, &usb_flag, NULL) != argc) {
585 return (DCMD_USAGE);
588 if (mdb_vread(&usb_dev, sizeof (usba_device_t), addr) == -1) {
589 mdb_warn("Failed to read usba_device!\n");
591 return (DCMD_ERR);
594 if (mdb_vread(&usb_dip, sizeof (struct dev_info),
595 (uintptr_t)usb_dev.usb_dip) == -1) {
596 mdb_warn("Failed to read dev_info!\n");
598 return (DCMD_ERR);
601 /* process the "-i" */
602 if (sel_num && sel_num != count) {
603 count++;
605 return (DCMD_OK);
608 /* index number of device node */
609 mdb_printf("%-8x", count++);
611 /* driver and instance */
612 mdb_devinfo2driver((uintptr_t)usb_dev.usb_dip, strbuf, STRLEN);
613 mdb_printf("%-12s%-6d", strbuf, usb_dip.devi_instance);
615 /* node name */
616 if (mdb_readstr(strbuf, STRLEN,
617 (uintptr_t)usb_dip.devi_node_name) != -1) {
619 mdb_printf("%-14s", strbuf);
620 } else {
622 mdb_printf("%-14s", "No Node Name");
626 if (mdb_vread(&dev_desc, sizeof (usb_dev_descr_t),
627 (uintptr_t)usb_dev.usb_dev_descr) != -1) {
629 /* gen (note we read this from the bcd) */
630 mdb_printf("%01x.%01x ", dev_desc.bcdUSB >> 8,
631 (dev_desc.bcdUSB & 0xf0) >> 4);
633 /* vid.pid */
634 mdb_printf("%04x.%04x ",
635 dev_desc.idVendor, dev_desc.idProduct);
638 /* product string */
639 if (mdb_readstr(strbuf, STRLEN,
640 (uintptr_t)usb_dev.usb_product_str) != -1) {
642 mdb_printf("%s\n", strbuf);
643 } else {
645 mdb_printf("%s\n", "No Product String");
648 /* tree, print usb device tree info */
649 if (usb_flag & OPT_TREE) {
651 mdb_printf("\nusba_device: 0x%x\n", addr);
653 mdb_printf("mfg_prod_sn: ");
654 if (mdb_readstr(strbuf, STRLEN,
655 (uintptr_t)usb_dev.usb_mfg_str) != -1) {
656 mdb_printf("%s - ", strbuf);
657 } else {
658 mdb_printf("NULL - ");
660 if (mdb_readstr(strbuf, STRLEN,
661 (uintptr_t)usb_dev.usb_product_str) != -1) {
662 mdb_printf("%s - ", strbuf);
663 } else {
664 mdb_printf("NULL -");
666 if (mdb_readstr(strbuf, STRLEN,
667 (uintptr_t)usb_dev.usb_serialno_str) != -1) {
668 mdb_printf("%s", strbuf);
669 } else {
670 mdb_printf("NULL");
673 mdb_printf("\n\n");
674 prt_usb_tree((uintptr_t)usb_dev.usb_dip, 0);
677 /* verbose, print all descriptors */
678 if (usb_flag & OPT_VERB) {
679 int i;
680 uintptr_t cfg_buf;
681 uint16_t cfg_len;
683 mdb_printf("\n");
685 /* device descriptor */
686 prt_usb_desc((uintptr_t)usb_dev.usb_dev_descr, 18);
688 /* config cloud descriptors */
689 if (usb_dev.usb_n_cfgs == 1) {
690 mdb_inc_indent(4);
691 mdb_printf("-- Active Config Index 0\n");
692 mdb_dec_indent(4);
693 prt_usb_desc((uintptr_t)usb_dev.usb_cfg,
694 usb_dev.usb_cfg_length);
695 } else {
696 /* multiple configs */
697 for (i = 0; i < usb_dev.usb_n_cfgs; i++) {
699 if ((mdb_vread(&cfg_len, sizeof (uint16_t),
700 (uintptr_t)(usb_dev.usb_cfg_array_len + i))
701 != -1) &&
702 (mdb_vread(&cfg_buf, sizeof (uintptr_t),
703 (uintptr_t)(usb_dev.usb_cfg_array + i))
704 != -1)) {
705 mdb_inc_indent(4);
706 if (cfg_buf ==
707 (uintptr_t)usb_dev.usb_cfg) {
708 mdb_printf("-- Active Config"
709 " Index %x\n", i);
710 } else {
711 mdb_printf("-- Inactive Config"
712 " Index %x\n", i);
714 mdb_dec_indent(4);
716 prt_usb_desc(cfg_buf, cfg_len);
722 if (usb_flag) {
724 mdb_printf("%<u>%-72s%</u>\n", " ");
727 return (DCMD_OK);
730 /* print the info required by "-t" */
731 static int
732 prt_usb_tree(uintptr_t paddr, uint_t flag)
734 struct dev_info usb_dip;
736 if (mdb_vread(&usb_dip, sizeof (struct dev_info), paddr) == -1) {
737 mdb_warn("prt_usb_tree: Failed to read dev_info!\n");
739 return (DCMD_ERR);
742 prt_usb_tree_node(paddr);
744 if (usb_dip.devi_child) {
746 mdb_printf("{\n");
747 mdb_inc_indent(4);
748 prt_usb_tree((uintptr_t)usb_dip.devi_child, 1);
749 mdb_dec_indent(4);
750 mdb_printf("}\n\n");
753 if (usb_dip.devi_sibling && flag == 1) {
754 /* print the sibling if flag == 1 */
756 prt_usb_tree((uintptr_t)usb_dip.devi_sibling, 1);
759 return (DCMD_OK);
762 static int
763 prt_usb_tree_node(uintptr_t paddr)
765 struct dev_info usb_dip;
766 uintptr_t statep;
767 uint_t errlevel;
768 char driver_name[STRLEN] = "";
769 char strbuf[STRLEN] = "";
771 if (mdb_vread(&usb_dip, sizeof (struct dev_info), paddr) == -1) {
772 mdb_warn("prt_usb_tree_node: Failed to read dev_info!\n");
774 return (DCMD_ERR);
777 /* node name */
778 if (mdb_readstr(strbuf, STRLEN,
779 (uintptr_t)usb_dip.devi_node_name) != -1) {
780 mdb_printf("%s, ", strbuf);
781 } else {
782 mdb_printf("%s, ", "node_name");
785 /* instance */
786 mdb_printf("instance #%d ", usb_dip.devi_instance);
788 /* driver name */
789 if (DDI_CF2(&usb_dip)) {
791 mdb_devinfo2driver(paddr, driver_name, STRLEN);
792 mdb_printf("(driver name: %s)\n", driver_name);
793 } else {
795 mdb_printf("(driver not attached)\n");
798 /* device path */
799 mdb_ddi_pathname(paddr, strbuf, STRLEN);
800 mdb_printf(" %s\n", strbuf);
802 /* dip addr */
803 mdb_printf(" dip: 0x%x\n", paddr);
805 /* softe_sate */
806 mdb_snprintf(strbuf, STRLEN, "%s_statep", driver_name);
807 if (mdb_devinfo2statep(paddr, strbuf, &statep) != -1) {
808 mdb_printf(" %s: 0x%x\n", strbuf, statep);
811 /* error level */
812 mdb_snprintf(strbuf, STRLEN, "%s_errlevel", driver_name);
813 if (mdb_readvar(&errlevel, strbuf) != -1) {
814 mdb_printf(" %s: 0x%x\n", strbuf, errlevel);
817 if (strcmp(driver_name, "ehci") == 0) {
818 mdb_arg_t argv[] = {
819 {MDB_TYPE_STRING, {"ehci_state_t"}},
820 {MDB_TYPE_STRING, {"ehci_root_hub.rh_descr"}}
822 mdb_call_dcmd("print", statep, DCMD_ADDRSPEC, 2, argv);
825 if (strcmp(driver_name, "ohci") == 0) {
826 mdb_arg_t argv[] = {
827 {MDB_TYPE_STRING, {"ohci_state_t"}},
828 {MDB_TYPE_STRING, {"ohci_root_hub.rh_descr"}}
830 mdb_call_dcmd("print", statep, DCMD_ADDRSPEC, 2, argv);
833 if (strcmp(driver_name, "uhci") == 0) {
834 mdb_arg_t argv[] = {
835 {MDB_TYPE_STRING, {"uhci_state_t"}},
836 {MDB_TYPE_STRING, {"uhci_root_hub.rh_descr"}}
838 mdb_call_dcmd("print", statep, DCMD_ADDRSPEC, 2, argv);
841 if (strcmp(driver_name, "hubd") == 0) {
842 mdb_arg_t argv[] = {
843 {MDB_TYPE_STRING, {"hubd_t"}},
844 {MDB_TYPE_STRING, {"h_ep1_xdescr.uex_ep"}}
846 mdb_call_dcmd("print", statep, DCMD_ADDRSPEC, 2, argv);
849 if (strcmp(driver_name, "hid") == 0) {
850 hid_state_t hidp;
852 if (mdb_vread(&hidp, sizeof (hid_state_t), statep) != -1) {
853 hidparser_handle hid_report;
855 if (mdb_vread(&hid_report, sizeof (hidparser_handle),
856 (uintptr_t)hidp.hid_report_descr) != -1) {
858 mdb_inc_indent(2);
860 mdb_printf("\n");
861 prt_usb_hid_item((uintptr_t)
862 hid_report.hidparser_handle_parse_tree);
864 mdb_dec_indent(2);
869 mdb_printf("\n");
871 return (DCMD_OK);
874 /* print hid report descriptor */
875 static void
876 prt_usb_hid_item(uintptr_t paddr)
878 entity_item_t item;
879 if (mdb_vread(&item, sizeof (entity_item_t), paddr) != -1) {
881 prt_usb_hid_item_attrs((uintptr_t)item.entity_item_attributes);
882 prt_usb_hid_item_params(&item);
884 if (item.info.child) {
885 mdb_inc_indent(4);
886 prt_usb_hid_item((uintptr_t)item.info.child);
887 mdb_dec_indent(4);
890 if (item.entity_item_right_sibling) {
891 prt_usb_hid_item((uintptr_t)
892 item.entity_item_right_sibling);
897 static void
898 prt_usb_hid_item_params(entity_item_t *item)
900 switch (item->entity_item_type) {
901 case 0x80:
902 mdb_printf("INPUT ");
904 break;
905 case 0x90:
906 mdb_printf("OUTPUT ");
908 break;
909 case 0xA0:
910 mdb_printf("COLLECTION ");
912 break;
913 case 0xB0:
914 mdb_printf("FEATURE ");
916 break;
917 case 0xC0:
918 mdb_printf("END_COLLECTION ");
920 break;
921 default:
922 mdb_printf("MAIN_ITEM ");
924 break;
927 prt_usb_hid_item_data((uintptr_t)item->entity_item_params,
928 item->entity_item_params_leng);
930 mdb_printf("\n");
933 static void
934 prt_usb_hid_item_attrs(uintptr_t paddr)
936 entity_attribute_t attr;
938 if (mdb_vread(&attr, sizeof (entity_attribute_t), paddr) != -1) {
940 prt_usb_hid_item_tags(attr.entity_attribute_tag);
941 prt_usb_hid_item_data((uintptr_t)attr.entity_attribute_value,
942 attr.entity_attribute_length);
944 mdb_printf("\n");
946 if (attr.entity_attribute_next) {
947 prt_usb_hid_item_attrs((uintptr_t)
948 attr.entity_attribute_next);
953 static void
954 prt_usb_hid_item_data(uintptr_t paddr, uint_t len)
956 char data[4];
957 int i;
959 if (len > 4) {
960 mdb_warn("Incorrect entity_item_length: 0x%x\n", len);
962 return;
965 if (mdb_vread(data, len, paddr) != -1) {
967 mdb_printf("( ");
968 for (i = 0; i < len; i++) {
969 mdb_printf("0x%02x ", data[i] & 0xff);
971 mdb_printf(")");
975 static void
976 prt_usb_hid_item_tags(uint_t tag)
978 switch (tag) {
979 case 0x04:
980 mdb_printf("usage page ");
982 break;
983 case 0x14:
984 mdb_printf("logical minimum ");
986 break;
987 case 0x24:
988 mdb_printf("logical maximum ");
990 break;
991 case 0x34:
992 mdb_printf("physical minimum ");
994 break;
995 case 0x44:
996 mdb_printf("physical maximum ");
998 break;
999 case 0x54:
1000 mdb_printf("exponent ");
1002 break;
1003 case 0x64:
1004 mdb_printf("unit ");
1006 break;
1007 case 0x74:
1008 mdb_printf("report size ");
1010 break;
1011 case 0x84:
1012 mdb_printf("report id ");
1014 break;
1015 case 0x94:
1016 mdb_printf("report count ");
1018 break;
1019 case 0x08:
1020 mdb_printf("usage ");
1022 break;
1023 case 0x18:
1024 mdb_printf("usage min ");
1026 break;
1027 case 0x28:
1028 mdb_printf("usage max ");
1030 break;
1032 default:
1033 mdb_printf("tag ");
1037 /* print the info required by "-v" */
1038 static int
1039 prt_usb_desc(uintptr_t usb_cfg, uint_t cfg_len)
1041 uintptr_t paddr = usb_cfg;
1042 uintptr_t pend = usb_cfg + cfg_len;
1043 uchar_t desc_type, nlen;
1044 usb_if_descr_t usb_if;
1045 ulong_t indent = 0;
1047 mdb_arg_t argv = {MDB_TYPE_STRING, {"usb_dev_descr_t"}};
1049 if (mdb_vread(&nlen, 1, paddr) == -1) {
1051 return (DCMD_ERR);
1053 while ((paddr + nlen <= pend) && (nlen > 0)) {
1054 if (mdb_vread(&desc_type, 1, paddr + 1) == -1) {
1056 return (DCMD_ERR);
1059 switch (desc_type) {
1060 case USB_DESCR_TYPE_DEV:
1061 mdb_printf("Device Descriptor\n");
1062 print_struct(paddr, nlen, &argv);
1064 break;
1065 case USB_DESCR_TYPE_CFG:
1066 indent = 4;
1067 mdb_inc_indent(indent);
1068 mdb_printf("Configuration Descriptor\n");
1069 print_descr(paddr, nlen, usb_cfg_descr, usb_cfg_item);
1070 mdb_dec_indent(indent);
1072 break;
1073 case USB_DESCR_TYPE_STRING:
1074 mdb_printf("String Descriptor\n");
1075 print_descr(paddr, nlen, usb_str_descr, usb_str_item);
1077 break;
1078 case USB_DESCR_TYPE_IF:
1079 indent = 8;
1080 mdb_inc_indent(indent);
1081 mdb_printf("Interface Descriptor\n");
1082 print_descr(paddr, nlen, usb_if_descr, usb_if_item);
1083 mdb_dec_indent(indent);
1084 mdb_vread(&usb_if, sizeof (usb_if_descr_t), paddr);
1086 break;
1087 case USB_DESCR_TYPE_EP:
1088 indent = 8;
1089 mdb_inc_indent(indent);
1090 mdb_printf("Endpoint Descriptor\n");
1091 print_descr(paddr, nlen, usb_ep_descr, usb_ep_item);
1092 mdb_dec_indent(indent);
1094 break;
1095 case USB_DESCR_TYPE_SS_EP_COMP:
1096 indent = 12;
1097 mdb_inc_indent(indent);
1098 mdb_printf("SuperSpeed Endpoint Companion "
1099 "Descriptor\n");
1100 print_descr(paddr, nlen, usb_ep_ss_comp_descr,
1101 usb_ep_ss_comp_item);
1102 mdb_dec_indent(indent);
1104 break;
1105 case USB_DESCR_TYPE_DEV_QLF:
1106 mdb_printf("Device_Qualifier Descriptor\n");
1107 print_descr(paddr, nlen, usb_qlf_descr, usb_qlf_item);
1109 break;
1110 case USB_DESCR_TYPE_OTHER_SPEED_CFG:
1111 indent = 4;
1112 mdb_inc_indent(indent);
1113 mdb_printf("Other_Speed_Configuration Descriptor\n");
1114 print_descr(paddr, nlen, usb_cfg_descr, usb_cfg_item);
1115 mdb_dec_indent(indent);
1117 break;
1118 case USB_DESCR_TYPE_IA:
1119 indent = 6;
1120 mdb_inc_indent(indent);
1121 mdb_printf("Interface_Association Descriptor\n");
1122 print_descr(paddr, nlen, usb_ia_descr, usb_ia_item);
1123 mdb_dec_indent(indent);
1125 break;
1126 case 0x21: /* hid descriptor */
1127 indent = 12;
1128 mdb_inc_indent(indent);
1129 if (usb_if.bInterfaceClass == 0xe0 &&
1130 usb_if.bInterfaceSubClass == 0x02) {
1131 mdb_printf("WA Descriptor\n");
1132 print_descr(paddr, nlen, usb_wa_descr,
1133 usb_wa_item);
1134 } else {
1135 mdb_printf("HID Descriptor\n");
1136 print_descr(paddr, nlen, usb_hid_descr,
1137 usb_hid_item);
1139 mdb_dec_indent(indent);
1141 break;
1142 case 0x24: /* class specific interfce descriptor */
1143 indent = 12;
1144 mdb_inc_indent(indent);
1145 if (usb_if.bInterfaceClass == 1 &&
1146 usb_if.bInterfaceSubClass == 1) {
1147 mdb_printf("AudioControl_Interface: ");
1148 prt_usb_ac_desc(paddr, nlen);
1150 } else if (usb_if.bInterfaceClass == 1 &&
1151 usb_if.bInterfaceSubClass == 2) {
1152 mdb_printf("AudioStream_Interface: ");
1153 prt_usb_as_desc(paddr, nlen);
1155 } else if (usb_if.bInterfaceClass == 0x0E &&
1156 usb_if.bInterfaceSubClass == 1) {
1157 mdb_printf("VideoControl_Interface: ");
1158 prt_usb_vc_desc(paddr, nlen);
1161 } else if (usb_if.bInterfaceClass == 0x0E &&
1162 usb_if.bInterfaceSubClass == 2) {
1163 mdb_printf("VideoStream_Interface: ");
1164 prt_usb_vs_desc(paddr, nlen);
1166 } else {
1167 mdb_printf("Unknown_Interface:"
1168 "0x%x\n", desc_type);
1169 prt_usb_buf(paddr, nlen);
1171 mdb_dec_indent(indent);
1173 break;
1174 case 0x25: /* class specific endpoint descriptor */
1175 indent = 12;
1176 mdb_inc_indent(indent);
1177 if (usb_if.bInterfaceClass == 0x01) {
1178 mdb_printf("AudioEndpoint:\n");
1179 print_descr(paddr, nlen,
1180 usb_as_ep_descr, usb_as_ep_item);
1182 } else if (usb_if.bInterfaceClass == 0x0E) {
1183 mdb_printf("VideoEndpoint:\n");
1184 print_descr(paddr, nlen,
1185 usb_ep_descr, usb_ep_item);
1187 } else {
1188 mdb_printf("Unknown_Endpoint:"
1189 "0x%x\n", desc_type);
1190 prt_usb_buf(paddr, nlen);
1192 mdb_dec_indent(indent);
1194 break;
1195 default:
1196 mdb_inc_indent(indent);
1197 mdb_printf("Unknown Descriptor: 0x%x\n", desc_type);
1198 prt_usb_buf(paddr, nlen);
1199 mdb_dec_indent(indent);
1201 break;
1204 paddr += nlen;
1205 if (mdb_vread(&nlen, 1, paddr) == -1) {
1207 return (DCMD_ERR);
1211 return (DCMD_OK);
1215 /* print audio class specific control descriptor */
1216 static int
1217 prt_usb_ac_desc(uintptr_t addr, uint_t nlen)
1219 uchar_t sub_type;
1221 if (mdb_vread(&sub_type, 1, addr + 2) == -1) {
1223 return (DCMD_ERR);
1225 switch (sub_type) {
1226 case 0x01:
1227 mdb_printf("header Descriptor\n");
1228 print_descr(addr, nlen,
1229 usb_ac_header_descr, usb_ac_header_item);
1231 break;
1232 case 0x02:
1233 mdb_printf("input_terminal Descriptor\n");
1234 print_descr(addr, nlen,
1235 usb_ac_input_term_descr, usb_ac_input_term_item);
1237 break;
1238 case 0x03:
1239 mdb_printf("output_terminal Descriptor\n");
1240 print_descr(addr, nlen,
1241 usb_ac_output_term_descr, usb_ac_output_term_item);
1243 break;
1244 case 0x04:
1245 mdb_printf("mixer_unit Descriptor\n");
1246 print_descr(addr, nlen,
1247 usb_ac_mixer_descr, usb_ac_mixer_item);
1249 break;
1250 case 0x05:
1251 mdb_printf("selector_unit Descriptor\n");
1252 print_descr(addr, nlen,
1253 usb_ac_selector_descr, usb_ac_selector_item);
1255 break;
1256 case 0x06:
1257 mdb_printf("feature_unit Descriptor\n");
1258 print_descr(addr, nlen,
1259 usb_ac_feature_descr, usb_ac_feature_item);
1261 break;
1262 case 0x07:
1263 mdb_printf("processing_unit Descriptor\n");
1264 print_descr(addr, nlen,
1265 usb_ac_processing_descr, usb_ac_processing_item);
1267 break;
1268 case 0x08:
1269 mdb_printf("extension_unit Descriptor\n");
1270 print_descr(addr, nlen,
1271 usb_ac_extension_descr, usb_ac_extension_item);
1273 break;
1274 default:
1275 mdb_printf("Unknown AC sub-descriptor 0x%x\n", sub_type);
1276 prt_usb_buf(addr, nlen);
1278 break;
1281 return (DCMD_OK);
1284 /* print audio class specific stream descriptor */
1285 static int
1286 prt_usb_as_desc(uintptr_t addr, uint_t nlen)
1288 uchar_t sub_type;
1290 if (mdb_vread(&sub_type, 1, addr + 2) == -1) {
1292 return (DCMD_ERR);
1294 switch (sub_type) {
1295 case 0x01:
1296 mdb_printf("general_interface Descriptor\n");
1297 print_descr(addr, nlen,
1298 usb_as_if_descr, usb_as_if_item);
1300 break;
1301 case 0x02:
1302 mdb_printf("format_type Descriptor\n");
1303 print_descr(addr, nlen,
1304 usb_as_format_descr, usb_as_format_item);
1306 break;
1307 default:
1308 mdb_printf("Unknown AS sub-descriptor 0x%x\n", sub_type);
1309 prt_usb_buf(addr, nlen);
1311 break;
1314 return (DCMD_OK);
1317 /* print video class specific control descriptor */
1318 static int
1319 prt_usb_vc_desc(uintptr_t addr, uint_t nlen)
1321 uchar_t sub_type;
1323 if (mdb_vread(&sub_type, 1, addr + 2) == -1) {
1325 return (DCMD_ERR);
1327 switch (sub_type) {
1328 case 0x01:
1329 mdb_printf("header Descriptor\n");
1330 print_descr(addr, nlen,
1331 usb_vc_header_descr, usb_vc_header_item);
1333 break;
1334 case 0x02:
1335 mdb_printf("input_terminal Descriptor\n");
1336 print_descr(addr, nlen,
1337 usb_vc_input_term_descr, usb_vc_input_term_item);
1339 break;
1340 case 0x03:
1341 mdb_printf("output_terminal Descriptor\n");
1342 print_descr(addr, nlen,
1343 usb_vc_output_term_descr, usb_vc_output_term_item);
1345 break;
1346 case 0x04:
1347 mdb_printf("selector_unit Descriptor\n");
1348 print_descr(addr, nlen,
1349 usb_vc_selector_descr, usb_vc_selector_item);
1351 break;
1352 case 0x05:
1353 mdb_printf("processing_unit Descriptor\n");
1354 print_descr(addr, nlen,
1355 usb_vc_processing_descr, usb_vc_processing_item);
1357 break;
1358 case 0x06:
1359 mdb_printf("extension_unit Descriptor\n");
1360 print_descr(addr, nlen,
1361 usb_vc_extension_descr, usb_vc_extension_item);
1363 break;
1364 default:
1365 mdb_printf("Unknown VC sub-descriptor 0x%x\n", sub_type);
1366 prt_usb_buf(addr, nlen);
1368 break;
1371 return (DCMD_OK);
1374 /* print video class specific stream descriptor */
1375 static int
1376 prt_usb_vs_desc(uintptr_t addr, uint_t nlen)
1378 uchar_t sub_type;
1380 if (mdb_vread(&sub_type, 1, addr + 2) == -1) {
1382 return (DCMD_ERR);
1384 switch (sub_type) {
1385 case 0x01:
1386 mdb_printf("input_header Descriptor\n");
1387 print_descr(addr, nlen,
1388 usb_vs_input_header_descr, usb_vs_input_header_item);
1390 break;
1391 case 0x02:
1392 mdb_printf("output_header Descriptor\n");
1393 print_descr(addr, nlen,
1394 usb_vs_output_header_descr, usb_vs_output_header_item);
1396 break;
1397 case 0x03:
1398 mdb_printf("still_image_frame Descriptor\n");
1399 print_descr(addr, nlen,
1400 usb_vs_still_image_descr, usb_vs_still_image_item);
1402 break;
1403 case 0x04:
1404 mdb_printf("format_uncompressed Descriptor\n");
1405 print_descr(addr, nlen,
1406 usb_vs_format_uncps_descr, usb_vs_format_uncps_item);
1408 break;
1409 case 0x05:
1410 mdb_printf("frame_uncompressed Descriptor\n");
1411 print_descr(addr, nlen,
1412 usb_vs_2frame_descr, usb_vs_2frame_item);
1414 break;
1415 case 0x06:
1416 mdb_printf("format_mjpeg Descriptor\n");
1417 print_descr(addr, nlen,
1418 usb_vs_format_mjpeg_descr, usb_vs_format_mjpeg_item);
1420 break;
1421 case 0x07:
1422 mdb_printf("frame_mjpeg Descriptor\n");
1423 print_descr(addr, nlen,
1424 usb_vs_2frame_descr, usb_vs_2frame_item);
1426 break;
1427 case 0x0A:
1428 mdb_printf("format_mpeg2ts Descriptor\n");
1429 print_descr(addr, nlen,
1430 usb_vs_format_mp2ts_descr, usb_vs_format_mp2ts_item);
1432 break;
1433 case 0x0C:
1434 mdb_printf("format_dv Descriptor\n");
1435 print_descr(addr, nlen,
1436 usb_vs_format_dv_descr, usb_vs_format_dv_item);
1438 break;
1439 case 0x0D:
1440 mdb_printf("color_matching Descriptor\n");
1441 print_descr(addr, nlen,
1442 usb_vs_color_matching_descr, usb_vs_color_matching_item);
1444 break;
1445 default:
1446 mdb_printf("Unknown VS sub-descriptor 0x%x\n", sub_type);
1447 prt_usb_buf(addr, nlen);
1449 break;
1452 return (DCMD_OK);
1455 /* parse and print the descriptor items */
1456 static int
1457 print_descr(uintptr_t addr, uint_t nlen, usb_descr_item_t *item, uint_t nitem)
1459 int i, j;
1460 uint8_t buf[8];
1461 uint64_t value;
1462 uintptr_t paddr = addr;
1463 usb_descr_item_t *p = item;
1465 mdb_printf("{");
1466 for (i = 0; (i < nitem) && (paddr < addr + nlen); i++) {
1467 mdb_printf("\n %s =", p->name);
1468 switch (p->nlen) {
1469 case 1: /* uint8_t */
1470 if (mdb_vread(buf, 1, paddr) == -1) {
1472 return (DCMD_ERR);
1474 value = buf[0];
1476 break;
1477 case 2: /* uint16_t */
1478 if (mdb_vread(buf, 2, paddr) == -1) {
1480 return (DCMD_ERR);
1482 value = buf[0] | (buf[1] << 8);
1484 break;
1485 case 4: /* uint32_t */
1486 if (mdb_vread(buf, 4, paddr) == -1) {
1488 return (DCMD_ERR);
1490 value = buf[0] | (buf[1] << 8) |
1491 (buf[2] << 16) | (buf[3] << 24);
1493 break;
1494 case 8: /* uint64_t */
1495 if (mdb_vread(buf, 8, paddr) == -1) {
1497 return (DCMD_ERR);
1499 value = buf[4] | (buf[5] << 8) |
1500 (buf[6] << 16) | (buf[7] << 24);
1501 value = buf[0] | (buf[1] << 8) |
1502 (buf[2] << 16) | (buf[3] << 24) |
1503 (value << 32);
1505 break;
1506 default: /* byte array */
1507 value = 0;
1508 /* print an array instead of a value */
1509 for (j = 0; j < p->nlen - BYTE_OFFSET; j++) {
1510 if (mdb_vread(buf, 1, paddr + j) == -1) {
1512 break;
1514 mdb_printf(" 0x%x", buf[0]);
1517 break;
1520 if (p->nlen > BYTE_OFFSET) {
1521 paddr += p->nlen - BYTE_OFFSET;
1522 } else {
1523 mdb_printf(" 0x%x", value);
1524 paddr += p->nlen;
1527 p++;
1530 /* print the unresolved bytes */
1531 if (paddr < addr + nlen) {
1532 mdb_printf("\n ... =");
1534 while (paddr < addr + nlen) {
1535 if (mdb_vread(buf, 1, paddr++) == -1) {
1537 break;
1539 mdb_printf(" 0x%x", buf[0]);
1541 mdb_printf("\n}\n");
1543 return (DCMD_OK);
1546 /* print the buffer as a struct */
1547 static int
1548 print_struct(uintptr_t addr, uint_t nlen, mdb_arg_t *arg)
1550 mdb_ctf_id_t id;
1551 if (mdb_ctf_lookup_by_name(arg->a_un.a_str, &id) == 0) {
1553 mdb_call_dcmd("print", addr, DCMD_ADDRSPEC, 1, arg);
1554 } else {
1556 prt_usb_buf(addr, nlen);
1559 return (DCMD_OK);
1562 /* print the buffer as a byte array */
1563 static int
1564 prt_usb_buf(uintptr_t addr, uint_t nlen)
1566 int i;
1567 uchar_t val;
1569 mdb_printf("{\n");
1570 for (i = 0; i < nlen; i++) {
1571 if (mdb_vread(&val, 1, addr + i) == -1) {
1573 break;
1575 mdb_printf("%02x ", val);
1577 if (nlen) {
1578 mdb_printf("\n");
1580 mdb_printf("}\n");
1582 return (DCMD_OK);