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]
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
{
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 */
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 */
74 /* define the known descriptor items */
75 static usb_descr_item_t usb_cfg_descr
[] = {
77 {1, "bDescriptorType"},
79 {1, "bNumInterfaces"},
80 {1, "bConfigurationValue"},
81 {1, "iConfiguration"},
85 static uint_t usb_cfg_item
= 8;
87 static usb_descr_item_t usb_ia_descr
[] = {
89 {1, "bDescriptorType"},
90 {1, "bFirstInterface"},
91 {1, "bInterfaceCount"},
92 {1, "bFunctionClass"},
93 {1, "bFunctionSubClass"},
94 {1, "bFunctionProtocol"},
97 static uint_t usb_ia_item
= 8;
99 static usb_descr_item_t usb_if_descr
[] = {
101 {1, "bDescriptorType"},
102 {1, "bInterfaceNumber"},
103 {1, "bAlternateSetting"},
104 {1, "bNumEndpoints"},
105 {1, "bInterfaceClass"},
106 {1, "bInterfaceSubClass"},
107 {1, "bInterfaceProtocol"},
110 static uint_t usb_if_item
= 9;
112 static usb_descr_item_t usb_ep_descr
[] = {
114 {1, "bDescriptorType"},
115 {1, "bEndpointAddress"},
117 {2, "wMaxPacketSize"},
120 static uint_t usb_ep_item
= 6;
122 static usb_descr_item_t usb_ep_ss_comp_descr
[] = {
124 {1, "bDescriptorType"},
127 {2, "wBytesPerInterval"}
129 static uint_t usb_ep_ss_comp_item
= 5;
131 static usb_descr_item_t usb_qlf_descr
[] = {
133 {1, "bDescriptorType"},
136 {1, "bDeviceSubClass"},
137 {1, "bDeviceProtocol"},
138 {1, "bMaxPacketSize0"},
139 {1, "bNumConfigurations"},
142 static uint_t usb_qlf_item
= 9;
144 static usb_descr_item_t usb_str_descr
[] = {
146 {1, "bDescriptorType"},
149 static uint_t usb_str_item
= 3;
151 static usb_descr_item_t usb_wa_descr
[] = {
153 {1, "bDescriptorType"},
158 {2, "wRPipeMaxBlock"},
159 {1, "bRPipeBlockSize"},
160 {1, "bPwrOn2PwrGood"},
162 {1, "DeviceRemovable"},
165 static uint_t usb_wa_item
= 11;
167 static usb_descr_item_t usb_hid_descr
[] = {
169 {1, "bDescriptorType"},
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
[] = {
180 {1, "bDescriptorType"},
181 {1, "bDescriptorSubType"},
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
[] = {
191 {1, "bDescriptorType"},
192 {1, "bDescriptorSubType"},
194 {2, "wTerminalType"},
195 {1, "bAssocTerminal"},
197 {2, "wChannelConfig"},
198 {1, "iChannelNames"},
201 static uint_t usb_ac_input_term_item
= 10;
203 static usb_descr_item_t usb_ac_output_term_descr
[] = {
205 {1, "bDescriptorType"},
206 {1, "bDescriptorSubType"},
208 {2, "wTerminalType"},
209 {1, "bAssocTerminal"},
213 static uint_t usb_ac_output_term_item
= 8;
215 static usb_descr_item_t usb_ac_mixer_descr
[] = {
217 {1, "bDescriptorType"},
218 {1, "bDescriptorSubType"},
223 static uint_t usb_ac_mixer_item
= 6;
225 static usb_descr_item_t usb_ac_selector_descr
[] = {
227 {1, "bDescriptorType"},
228 {1, "bDescriptorSubType"},
233 static uint_t usb_ac_selector_item
= 6;
235 static usb_descr_item_t usb_ac_feature_descr
[] = {
237 {1, "bDescriptorType"},
238 {1, "bDescriptorSubType"},
244 static uint_t usb_ac_feature_item
= 7;
246 static usb_descr_item_t usb_ac_processing_descr
[] = {
248 {1, "bDescriptorType"},
249 {1, "bDescriptorSubType"},
255 static uint_t usb_ac_processing_item
= 7;
257 static usb_descr_item_t usb_ac_extension_descr
[] = {
259 {1, "bDescriptorType"},
260 {1, "bDescriptorSubType"},
261 {1, "wExtensionCode"},
266 static uint_t usb_ac_extension_item
= 7;
268 static usb_descr_item_t usb_as_ep_descr
[] = {
270 {1, "bDescriptorType"},
271 {1, "bDescriptorSubType"},
273 {1, "bLockDelayUnits"},
276 static uint_t usb_as_ep_item
= 6;
278 static usb_descr_item_t usb_as_if_descr
[] = {
280 {1, "bDescriptorType"},
281 {1, "bDescriptorSubType"},
282 {1, "bTerminalLink"},
286 static uint_t usb_as_if_item
= 6;
288 static usb_descr_item_t usb_as_format_descr
[] = {
290 {1, "bDescriptorType"},
291 {1, "bDescriptorSubType"},
294 {1, "bSubFrameSize"},
295 {1, "bBitResolution"},
299 static uint_t usb_as_format_item
= 9;
301 static usb_descr_item_t usb_vc_header_descr
[] = {
303 {1, "bDescriptorType"},
304 {1, "bDescriptorSubtype"},
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
[] = {
314 {1, "bDescriptorType"},
315 {1, "bDescriptorSubType"},
317 {2, "wTerminalType"},
318 {1, "AssocTerminal"},
321 static uint_t usb_vc_input_term_item
= 7;
323 static usb_descr_item_t usb_vc_output_term_descr
[] = {
325 {1, "bDescriptorType"},
326 {1, "bDescriptorSubType"},
328 {2, "wTerminalType"},
329 {1, "AssocTerminal"},
333 static uint_t usb_vc_output_term_item
= 8;
335 static usb_descr_item_t usb_vc_processing_descr
[] = {
337 {1, "bDescriptorType"},
338 {1, "bDescriptorSubType"},
341 {2, "wMaxMultiplier"},
345 static uint_t usb_vc_processing_item
= 8;
347 static usb_descr_item_t usb_vc_selector_descr
[] = {
349 {1, "bDescriptorType"},
350 {1, "bDescriptorSubType"},
354 static uint_t usb_vc_selector_item
= 5;
356 static usb_descr_item_t usb_vc_extension_descr
[] = {
358 {1, "bDescriptorType"},
359 {1, "bDescriptorSubType"},
361 {16 + BYTE_OFFSET
, "guidExtensionCode[16]"},
365 static uint_t usb_vc_extension_item
= 7;
367 static usb_descr_item_t usb_vs_input_header_descr
[] = {
369 {1, "bDescriptorType"},
370 {1, "bDescriptorSubType"},
373 {1, "bEndpointAddress"},
375 {1, "bTerminalLink"},
376 {1, "bStillCaptureMethod"},
377 {1, "bTriggerSupport"},
378 {1, "bTriggerUsage"},
382 static uint_t usb_vs_input_header_item
= 13;
384 static usb_descr_item_t usb_vs_output_header_descr
[] = {
386 {1, "bDescriptorType"},
387 {1, "bDescriptorSubType"},
390 {1, "bEndpointAddress"},
391 {1, "bTerminalLink"},
395 static uint_t usb_vs_output_header_item
= 9;
397 static usb_descr_item_t usb_vs_still_image_descr
[] = {
399 {1, "bDescriptorType"},
400 {1, "bDescriptorSubType"},
401 {1, "bEndpointAddress"},
402 {1, "bNumImageSizePatterns"},
406 static uint_t usb_vs_still_image_item
= 7;
408 static usb_descr_item_t usb_vs_color_matching_descr
[] = {
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
[] = {
420 {1, "bDescriptorType"},
421 {1, "bDescriptorSubType"},
423 {1, "bmCapabilities"},
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
[] = {
436 {1, "bDescriptorType"},
437 {1, "bDescriptorSubType"},
439 {1, "bNumFrameDescriptors"},
441 {1, "bDefaultFrameIndex"},
442 {1, "bAspectRatioX"},
443 {1, "bAspectRatioY"},
444 {1, "bmInterlaceFlags"},
447 static uint_t usb_vs_format_mjpeg_item
= 11;
449 static usb_descr_item_t usb_vs_format_uncps_descr
[] = {
451 {1, "bDescriptorType"},
452 {1, "bDescriptorSubType"},
454 {1, "bNumFrameDescriptors"},
455 {16 + BYTE_OFFSET
, "guidFormat[16]"},
456 {1, "bBitsPerPixel"},
457 {1, "bDefaultFrameIndex"},
458 {1, "bAspectRatioX"},
459 {1, "bAspectRatioY"},
460 {1, "bmInterlaceFlags"},
463 static uint_t usb_vs_format_uncps_item
= 12;
465 static usb_descr_item_t usb_vs_format_mp2ts_descr
[] = {
467 {1, "bDescriptorType"},
468 {1, "bDescriptorSubType"},
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
[] = {
479 {1, "bDescriptorType"},
480 {1, "bDescriptorSubType"},
482 {4, "dwMaxVideoFrameBufferSize"},
485 static uint_t usb_vs_format_dv_item
= 6;
488 /* ****************************************************************** */
490 typedef struct hci_state
{
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 /* ****************************************************************** */
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;
556 usba_device_t usb_dev
;
557 usb_dev_descr_t dev_desc
;
558 struct dev_info usb_dip
;
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");
572 /* for the first device, print head */
573 if (DCMD_HDRSPEC(flags
)) {
575 mdb_printf("%<u>%-8s%-12s%-6s%-14s%-5s%-12s%-20s%</u>\n",
576 "INDEX", "DRIVER", "INST", "NODE", "GEN", "VID.PID",
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
) {
588 if (mdb_vread(&usb_dev
, sizeof (usba_device_t
), addr
) == -1) {
589 mdb_warn("Failed to read usba_device!\n");
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");
601 /* process the "-i" */
602 if (sel_num
&& sel_num
!= count
) {
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
);
616 if (mdb_readstr(strbuf
, STRLEN
,
617 (uintptr_t)usb_dip
.devi_node_name
) != -1) {
619 mdb_printf("%-14s", strbuf
);
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);
634 mdb_printf("%04x.%04x ",
635 dev_desc
.idVendor
, dev_desc
.idProduct
);
639 if (mdb_readstr(strbuf
, STRLEN
,
640 (uintptr_t)usb_dev
.usb_product_str
) != -1) {
642 mdb_printf("%s\n", strbuf
);
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
);
658 mdb_printf("NULL - ");
660 if (mdb_readstr(strbuf
, STRLEN
,
661 (uintptr_t)usb_dev
.usb_product_str
) != -1) {
662 mdb_printf("%s - ", strbuf
);
664 mdb_printf("NULL -");
666 if (mdb_readstr(strbuf
, STRLEN
,
667 (uintptr_t)usb_dev
.usb_serialno_str
) != -1) {
668 mdb_printf("%s", strbuf
);
674 prt_usb_tree((uintptr_t)usb_dev
.usb_dip
, 0);
677 /* verbose, print all descriptors */
678 if (usb_flag
& OPT_VERB
) {
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) {
691 mdb_printf("-- Active Config Index 0\n");
693 prt_usb_desc((uintptr_t)usb_dev
.usb_cfg
,
694 usb_dev
.usb_cfg_length
);
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
))
702 (mdb_vread(&cfg_buf
, sizeof (uintptr_t),
703 (uintptr_t)(usb_dev
.usb_cfg_array
+ i
))
707 (uintptr_t)usb_dev
.usb_cfg
) {
708 mdb_printf("-- Active Config"
711 mdb_printf("-- Inactive Config"
716 prt_usb_desc(cfg_buf
, cfg_len
);
724 mdb_printf("%<u>%-72s%</u>\n", " ");
730 /* print the info required by "-t" */
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");
742 prt_usb_tree_node(paddr
);
744 if (usb_dip
.devi_child
) {
748 prt_usb_tree((uintptr_t)usb_dip
.devi_child
, 1);
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);
763 prt_usb_tree_node(uintptr_t paddr
)
765 struct dev_info usb_dip
;
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");
778 if (mdb_readstr(strbuf
, STRLEN
,
779 (uintptr_t)usb_dip
.devi_node_name
) != -1) {
780 mdb_printf("%s, ", strbuf
);
782 mdb_printf("%s, ", "node_name");
786 mdb_printf("instance #%d ", usb_dip
.devi_instance
);
789 if (DDI_CF2(&usb_dip
)) {
791 mdb_devinfo2driver(paddr
, driver_name
, STRLEN
);
792 mdb_printf("(driver name: %s)\n", driver_name
);
795 mdb_printf("(driver not attached)\n");
799 mdb_ddi_pathname(paddr
, strbuf
, STRLEN
);
800 mdb_printf(" %s\n", strbuf
);
803 mdb_printf(" dip: 0x%x\n", paddr
);
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
);
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) {
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) {
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) {
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) {
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) {
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) {
861 prt_usb_hid_item((uintptr_t)
862 hid_report
.hidparser_handle_parse_tree
);
874 /* print hid report descriptor */
876 prt_usb_hid_item(uintptr_t paddr
)
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
) {
886 prt_usb_hid_item((uintptr_t)item
.info
.child
);
890 if (item
.entity_item_right_sibling
) {
891 prt_usb_hid_item((uintptr_t)
892 item
.entity_item_right_sibling
);
898 prt_usb_hid_item_params(entity_item_t
*item
)
900 switch (item
->entity_item_type
) {
902 mdb_printf("INPUT ");
906 mdb_printf("OUTPUT ");
910 mdb_printf("COLLECTION ");
914 mdb_printf("FEATURE ");
918 mdb_printf("END_COLLECTION ");
922 mdb_printf("MAIN_ITEM ");
927 prt_usb_hid_item_data((uintptr_t)item
->entity_item_params
,
928 item
->entity_item_params_leng
);
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
);
946 if (attr
.entity_attribute_next
) {
947 prt_usb_hid_item_attrs((uintptr_t)
948 attr
.entity_attribute_next
);
954 prt_usb_hid_item_data(uintptr_t paddr
, uint_t len
)
960 mdb_warn("Incorrect entity_item_length: 0x%x\n", len
);
965 if (mdb_vread(data
, len
, paddr
) != -1) {
968 for (i
= 0; i
< len
; i
++) {
969 mdb_printf("0x%02x ", data
[i
] & 0xff);
976 prt_usb_hid_item_tags(uint_t tag
)
980 mdb_printf("usage page ");
984 mdb_printf("logical minimum ");
988 mdb_printf("logical maximum ");
992 mdb_printf("physical minimum ");
996 mdb_printf("physical maximum ");
1000 mdb_printf("exponent ");
1004 mdb_printf("unit ");
1008 mdb_printf("report size ");
1012 mdb_printf("report id ");
1016 mdb_printf("report count ");
1020 mdb_printf("usage ");
1024 mdb_printf("usage min ");
1028 mdb_printf("usage max ");
1037 /* print the info required by "-v" */
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
;
1047 mdb_arg_t argv
= {MDB_TYPE_STRING
, {"usb_dev_descr_t"}};
1049 if (mdb_vread(&nlen
, 1, paddr
) == -1) {
1053 while ((paddr
+ nlen
<= pend
) && (nlen
> 0)) {
1054 if (mdb_vread(&desc_type
, 1, paddr
+ 1) == -1) {
1059 switch (desc_type
) {
1060 case USB_DESCR_TYPE_DEV
:
1061 mdb_printf("Device Descriptor\n");
1062 print_struct(paddr
, nlen
, &argv
);
1065 case USB_DESCR_TYPE_CFG
:
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
);
1073 case USB_DESCR_TYPE_STRING
:
1074 mdb_printf("String Descriptor\n");
1075 print_descr(paddr
, nlen
, usb_str_descr
, usb_str_item
);
1078 case USB_DESCR_TYPE_IF
:
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
);
1087 case USB_DESCR_TYPE_EP
:
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
);
1095 case USB_DESCR_TYPE_SS_EP_COMP
:
1097 mdb_inc_indent(indent
);
1098 mdb_printf("SuperSpeed Endpoint Companion "
1100 print_descr(paddr
, nlen
, usb_ep_ss_comp_descr
,
1101 usb_ep_ss_comp_item
);
1102 mdb_dec_indent(indent
);
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
);
1110 case USB_DESCR_TYPE_OTHER_SPEED_CFG
:
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
);
1118 case USB_DESCR_TYPE_IA
:
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
);
1126 case 0x21: /* hid descriptor */
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
,
1135 mdb_printf("HID Descriptor\n");
1136 print_descr(paddr
, nlen
, usb_hid_descr
,
1139 mdb_dec_indent(indent
);
1142 case 0x24: /* class specific interfce descriptor */
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
);
1167 mdb_printf("Unknown_Interface:"
1168 "0x%x\n", desc_type
);
1169 prt_usb_buf(paddr
, nlen
);
1171 mdb_dec_indent(indent
);
1174 case 0x25: /* class specific endpoint descriptor */
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
);
1188 mdb_printf("Unknown_Endpoint:"
1189 "0x%x\n", desc_type
);
1190 prt_usb_buf(paddr
, nlen
);
1192 mdb_dec_indent(indent
);
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
);
1205 if (mdb_vread(&nlen
, 1, paddr
) == -1) {
1215 /* print audio class specific control descriptor */
1217 prt_usb_ac_desc(uintptr_t addr
, uint_t nlen
)
1221 if (mdb_vread(&sub_type
, 1, addr
+ 2) == -1) {
1227 mdb_printf("header Descriptor\n");
1228 print_descr(addr
, nlen
,
1229 usb_ac_header_descr
, usb_ac_header_item
);
1233 mdb_printf("input_terminal Descriptor\n");
1234 print_descr(addr
, nlen
,
1235 usb_ac_input_term_descr
, usb_ac_input_term_item
);
1239 mdb_printf("output_terminal Descriptor\n");
1240 print_descr(addr
, nlen
,
1241 usb_ac_output_term_descr
, usb_ac_output_term_item
);
1245 mdb_printf("mixer_unit Descriptor\n");
1246 print_descr(addr
, nlen
,
1247 usb_ac_mixer_descr
, usb_ac_mixer_item
);
1251 mdb_printf("selector_unit Descriptor\n");
1252 print_descr(addr
, nlen
,
1253 usb_ac_selector_descr
, usb_ac_selector_item
);
1257 mdb_printf("feature_unit Descriptor\n");
1258 print_descr(addr
, nlen
,
1259 usb_ac_feature_descr
, usb_ac_feature_item
);
1263 mdb_printf("processing_unit Descriptor\n");
1264 print_descr(addr
, nlen
,
1265 usb_ac_processing_descr
, usb_ac_processing_item
);
1269 mdb_printf("extension_unit Descriptor\n");
1270 print_descr(addr
, nlen
,
1271 usb_ac_extension_descr
, usb_ac_extension_item
);
1275 mdb_printf("Unknown AC sub-descriptor 0x%x\n", sub_type
);
1276 prt_usb_buf(addr
, nlen
);
1284 /* print audio class specific stream descriptor */
1286 prt_usb_as_desc(uintptr_t addr
, uint_t nlen
)
1290 if (mdb_vread(&sub_type
, 1, addr
+ 2) == -1) {
1296 mdb_printf("general_interface Descriptor\n");
1297 print_descr(addr
, nlen
,
1298 usb_as_if_descr
, usb_as_if_item
);
1302 mdb_printf("format_type Descriptor\n");
1303 print_descr(addr
, nlen
,
1304 usb_as_format_descr
, usb_as_format_item
);
1308 mdb_printf("Unknown AS sub-descriptor 0x%x\n", sub_type
);
1309 prt_usb_buf(addr
, nlen
);
1317 /* print video class specific control descriptor */
1319 prt_usb_vc_desc(uintptr_t addr
, uint_t nlen
)
1323 if (mdb_vread(&sub_type
, 1, addr
+ 2) == -1) {
1329 mdb_printf("header Descriptor\n");
1330 print_descr(addr
, nlen
,
1331 usb_vc_header_descr
, usb_vc_header_item
);
1335 mdb_printf("input_terminal Descriptor\n");
1336 print_descr(addr
, nlen
,
1337 usb_vc_input_term_descr
, usb_vc_input_term_item
);
1341 mdb_printf("output_terminal Descriptor\n");
1342 print_descr(addr
, nlen
,
1343 usb_vc_output_term_descr
, usb_vc_output_term_item
);
1347 mdb_printf("selector_unit Descriptor\n");
1348 print_descr(addr
, nlen
,
1349 usb_vc_selector_descr
, usb_vc_selector_item
);
1353 mdb_printf("processing_unit Descriptor\n");
1354 print_descr(addr
, nlen
,
1355 usb_vc_processing_descr
, usb_vc_processing_item
);
1359 mdb_printf("extension_unit Descriptor\n");
1360 print_descr(addr
, nlen
,
1361 usb_vc_extension_descr
, usb_vc_extension_item
);
1365 mdb_printf("Unknown VC sub-descriptor 0x%x\n", sub_type
);
1366 prt_usb_buf(addr
, nlen
);
1374 /* print video class specific stream descriptor */
1376 prt_usb_vs_desc(uintptr_t addr
, uint_t nlen
)
1380 if (mdb_vread(&sub_type
, 1, addr
+ 2) == -1) {
1386 mdb_printf("input_header Descriptor\n");
1387 print_descr(addr
, nlen
,
1388 usb_vs_input_header_descr
, usb_vs_input_header_item
);
1392 mdb_printf("output_header Descriptor\n");
1393 print_descr(addr
, nlen
,
1394 usb_vs_output_header_descr
, usb_vs_output_header_item
);
1398 mdb_printf("still_image_frame Descriptor\n");
1399 print_descr(addr
, nlen
,
1400 usb_vs_still_image_descr
, usb_vs_still_image_item
);
1404 mdb_printf("format_uncompressed Descriptor\n");
1405 print_descr(addr
, nlen
,
1406 usb_vs_format_uncps_descr
, usb_vs_format_uncps_item
);
1410 mdb_printf("frame_uncompressed Descriptor\n");
1411 print_descr(addr
, nlen
,
1412 usb_vs_2frame_descr
, usb_vs_2frame_item
);
1416 mdb_printf("format_mjpeg Descriptor\n");
1417 print_descr(addr
, nlen
,
1418 usb_vs_format_mjpeg_descr
, usb_vs_format_mjpeg_item
);
1422 mdb_printf("frame_mjpeg Descriptor\n");
1423 print_descr(addr
, nlen
,
1424 usb_vs_2frame_descr
, usb_vs_2frame_item
);
1428 mdb_printf("format_mpeg2ts Descriptor\n");
1429 print_descr(addr
, nlen
,
1430 usb_vs_format_mp2ts_descr
, usb_vs_format_mp2ts_item
);
1434 mdb_printf("format_dv Descriptor\n");
1435 print_descr(addr
, nlen
,
1436 usb_vs_format_dv_descr
, usb_vs_format_dv_item
);
1440 mdb_printf("color_matching Descriptor\n");
1441 print_descr(addr
, nlen
,
1442 usb_vs_color_matching_descr
, usb_vs_color_matching_item
);
1446 mdb_printf("Unknown VS sub-descriptor 0x%x\n", sub_type
);
1447 prt_usb_buf(addr
, nlen
);
1455 /* parse and print the descriptor items */
1457 print_descr(uintptr_t addr
, uint_t nlen
, usb_descr_item_t
*item
, uint_t nitem
)
1462 uintptr_t paddr
= addr
;
1463 usb_descr_item_t
*p
= item
;
1466 for (i
= 0; (i
< nitem
) && (paddr
< addr
+ nlen
); i
++) {
1467 mdb_printf("\n %s =", p
->name
);
1469 case 1: /* uint8_t */
1470 if (mdb_vread(buf
, 1, paddr
) == -1) {
1477 case 2: /* uint16_t */
1478 if (mdb_vread(buf
, 2, paddr
) == -1) {
1482 value
= buf
[0] | (buf
[1] << 8);
1485 case 4: /* uint32_t */
1486 if (mdb_vread(buf
, 4, paddr
) == -1) {
1490 value
= buf
[0] | (buf
[1] << 8) |
1491 (buf
[2] << 16) | (buf
[3] << 24);
1494 case 8: /* uint64_t */
1495 if (mdb_vread(buf
, 8, paddr
) == -1) {
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) |
1506 default: /* byte array */
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) {
1514 mdb_printf(" 0x%x", buf
[0]);
1520 if (p
->nlen
> BYTE_OFFSET
) {
1521 paddr
+= p
->nlen
- BYTE_OFFSET
;
1523 mdb_printf(" 0x%x", value
);
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) {
1539 mdb_printf(" 0x%x", buf
[0]);
1541 mdb_printf("\n}\n");
1546 /* print the buffer as a struct */
1548 print_struct(uintptr_t addr
, uint_t nlen
, mdb_arg_t
*arg
)
1551 if (mdb_ctf_lookup_by_name(arg
->a_un
.a_str
, &id
) == 0) {
1553 mdb_call_dcmd("print", addr
, DCMD_ADDRSPEC
, 1, arg
);
1556 prt_usb_buf(addr
, nlen
);
1562 /* print the buffer as a byte array */
1564 prt_usb_buf(uintptr_t addr
, uint_t nlen
)
1570 for (i
= 0; i
< nlen
; i
++) {
1571 if (mdb_vread(&val
, 1, addr
+ i
) == -1) {
1575 mdb_printf("%02x ", val
);