14e968bc2Sgc /* 24e968bc2Sgc * CDDL HEADER START 34e968bc2Sgc * 44e968bc2Sgc * The contents of this file are subject to the terms of the 54e968bc2Sgc * Common Development and Distribution License (the "License"). 64e968bc2Sgc * You may not use this file except in compliance with the License. 74e968bc2Sgc * 84e968bc2Sgc * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 94e968bc2Sgc * or http://www.opensolaris.org/os/licensing. 104e968bc2Sgc * See the License for the specific language governing permissions 114e968bc2Sgc * and limitations under the License. 124e968bc2Sgc * 134e968bc2Sgc * When distributing Covered Code, include this CDDL HEADER in each 144e968bc2Sgc * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 154e968bc2Sgc * If applicable, add the following below this CDDL HEADER, with the 164e968bc2Sgc * fields enclosed by brackets "[]" replaced with your own identifying 174e968bc2Sgc * information: Portions Copyright [yyyy] [name of copyright owner] 184e968bc2Sgc * 194e968bc2Sgc * CDDL HEADER END 204e968bc2Sgc */ 214e968bc2Sgc /* 22ff0e937bSRaymond Chen * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 234e968bc2Sgc * Use is subject to license terms. 24993e3fafSRobert Mustacchi * 25*a61ed2ceSHans Rosenfeld * Copyright 2019 Joyent, Inc. 264e968bc2Sgc */ 274e968bc2Sgc 284e968bc2Sgc 294e968bc2Sgc #include <sys/mdb_modapi.h> 30*a61ed2ceSHans Rosenfeld #include <sys/sysmacros.h> 314e968bc2Sgc 324e968bc2Sgc #include <sys/usb/usba.h> 334e968bc2Sgc #include <sys/usb/usba/usba_types.h> 344e968bc2Sgc #include <sys/usb/clients/hid/hid.h> 354e968bc2Sgc #include <sys/usb/clients/hidparser/hidparser.h> 364e968bc2Sgc #include <sys/usb/clients/hidparser/hidparser_impl.h> 374e968bc2Sgc #include <sys/usb/usba/genconsole.h> 384e968bc2Sgc #include <sys/usb/clients/hid/hidvar.h> 394e968bc2Sgc 404e968bc2Sgc 414e968bc2Sgc /* ****************************************************************** */ 424e968bc2Sgc 434e968bc2Sgc /* extenal definition */ 444e968bc2Sgc 454e968bc2Sgc typedef struct mdb_ctf_id { 464e968bc2Sgc void *_opaque[2]; 474e968bc2Sgc } mdb_ctf_id_t; 484e968bc2Sgc 494e968bc2Sgc extern int mdb_ctf_lookup_by_name(const char *, mdb_ctf_id_t *); 504e968bc2Sgc 514e968bc2Sgc extern int mdb_devinfo2driver(uintptr_t, char *, size_t); 524e968bc2Sgc 534e968bc2Sgc extern int mdb_devinfo2statep(uintptr_t, char *, uintptr_t *); 544e968bc2Sgc 554e968bc2Sgc extern char *mdb_ddi_pathname(uintptr_t, char *, size_t); 564e968bc2Sgc 574e968bc2Sgc 584e968bc2Sgc /* ****************************************************************** */ 594e968bc2Sgc 604e968bc2Sgc /* internal definition */ 614e968bc2Sgc 624e968bc2Sgc #define OPT_TREE 0x01 634e968bc2Sgc #define OPT_VERB 0x02 644e968bc2Sgc 654e968bc2Sgc #define STRLEN 256 664e968bc2Sgc #define BYTE_OFFSET 8 674e968bc2Sgc 684e968bc2Sgc 694e968bc2Sgc typedef struct usb_descr_item { 704e968bc2Sgc uint_t nlen; /* if it's an byte array, nlen += BYTE_OFFSET */ 714e968bc2Sgc char *name; /* descriptor item name */ 724e968bc2Sgc } usb_descr_item_t; 734e968bc2Sgc 744e968bc2Sgc /* define the known descriptor items */ 754e968bc2Sgc static usb_descr_item_t usb_cfg_descr[] = { 764e968bc2Sgc {1, "bLength"}, 774e968bc2Sgc {1, "bDescriptorType"}, 784e968bc2Sgc {2, "wTotalLength"}, 794e968bc2Sgc {1, "bNumInterfaces"}, 804e968bc2Sgc {1, "bConfigurationValue"}, 814e968bc2Sgc {1, "iConfiguration"}, 824e968bc2Sgc {1, "bmAttributes"}, 834e968bc2Sgc {1, "bMaxPower"}, 844e968bc2Sgc }; 854e968bc2Sgc static uint_t usb_cfg_item = 8; 864e968bc2Sgc 874e968bc2Sgc static usb_descr_item_t usb_ia_descr[] = { 884e968bc2Sgc {1, "bLength"}, 894e968bc2Sgc {1, "bDescriptorType"}, 904e968bc2Sgc {1, "bFirstInterface"}, 914e968bc2Sgc {1, "bInterfaceCount"}, 924e968bc2Sgc {1, "bFunctionClass"}, 934e968bc2Sgc {1, "bFunctionSubClass"}, 944e968bc2Sgc {1, "bFunctionProtocol"}, 954e968bc2Sgc {1, "iFunction"}, 964e968bc2Sgc }; 974e968bc2Sgc static uint_t usb_ia_item = 8; 984e968bc2Sgc 994e968bc2Sgc static usb_descr_item_t usb_if_descr[] = { 1004e968bc2Sgc {1, "bLength"}, 1014e968bc2Sgc {1, "bDescriptorType"}, 1024e968bc2Sgc {1, "bInterfaceNumber"}, 1034e968bc2Sgc {1, "bAlternateSetting"}, 1044e968bc2Sgc {1, "bNumEndpoints"}, 1054e968bc2Sgc {1, "bInterfaceClass"}, 1064e968bc2Sgc {1, "bInterfaceSubClass"}, 1074e968bc2Sgc {1, "bInterfaceProtocol"}, 1084e968bc2Sgc {1, "iInterface"}, 1094e968bc2Sgc }; 1104e968bc2Sgc static uint_t usb_if_item = 9; 1114e968bc2Sgc 1124e968bc2Sgc static usb_descr_item_t usb_ep_descr[] = { 1134e968bc2Sgc {1, "bLength"}, 1144e968bc2Sgc {1, "bDescriptorType"}, 1154e968bc2Sgc {1, "bEndpointAddress"}, 1164e968bc2Sgc {1, "bmAttributes"}, 1174e968bc2Sgc {2, "wMaxPacketSize"}, 1184e968bc2Sgc {1, "bInterval"}, 1194e968bc2Sgc }; 1204e968bc2Sgc static uint_t usb_ep_item = 6; 1214e968bc2Sgc 122993e3fafSRobert Mustacchi static usb_descr_item_t usb_ep_ss_comp_descr[] = { 123993e3fafSRobert Mustacchi {1, "bLength"}, 124993e3fafSRobert Mustacchi {1, "bDescriptorType"}, 125993e3fafSRobert Mustacchi {1, "bMaxBurst"}, 126993e3fafSRobert Mustacchi {1, "bmAttributes"}, 127993e3fafSRobert Mustacchi {2, "wBytesPerInterval"} 128993e3fafSRobert Mustacchi }; 129993e3fafSRobert Mustacchi static uint_t usb_ep_ss_comp_item = 5; 130993e3fafSRobert Mustacchi 1314e968bc2Sgc static usb_descr_item_t usb_qlf_descr[] = { 1324e968bc2Sgc {1, "bLength"}, 1334e968bc2Sgc {1, "bDescriptorType"}, 1344e968bc2Sgc {2, "bcdUSB"}, 1354e968bc2Sgc {1, "bDeviceClass"}, 1364e968bc2Sgc {1, "bDeviceSubClass"}, 1374e968bc2Sgc {1, "bDeviceProtocol"}, 1384e968bc2Sgc {1, "bMaxPacketSize0"}, 1394e968bc2Sgc {1, "bNumConfigurations"}, 1404e968bc2Sgc {1, "bReserved"}, 1414e968bc2Sgc }; 1424e968bc2Sgc static uint_t usb_qlf_item = 9; 1434e968bc2Sgc 1444e968bc2Sgc static usb_descr_item_t usb_str_descr[] = { 1454e968bc2Sgc {1, "bLength"}, 1464e968bc2Sgc {1, "bDescriptorType"}, 1474e968bc2Sgc {1, "bString"}, 1484e968bc2Sgc }; 1494e968bc2Sgc static uint_t usb_str_item = 3; 1504e968bc2Sgc 151ff0e937bSRaymond Chen static usb_descr_item_t usb_wa_descr[] = { 152ff0e937bSRaymond Chen {1, "bLength"}, 153ff0e937bSRaymond Chen {1, "bDescriptorType"}, 154ff0e937bSRaymond Chen {2, "bcdWAVersion"}, 155ff0e937bSRaymond Chen {1, "bNumPorts"}, 156ff0e937bSRaymond Chen {1, "bmAttributes"}, 157ff0e937bSRaymond Chen {2, "wNumRPipes"}, 158ff0e937bSRaymond Chen {2, "wRPipeMaxBlock"}, 159ff0e937bSRaymond Chen {1, "bRPipeBlockSize"}, 160ff0e937bSRaymond Chen {1, "bPwrOn2PwrGood"}, 161ff0e937bSRaymond Chen {1, "bNumMMCIEs"}, 162ff0e937bSRaymond Chen {1, "DeviceRemovable"}, 163ff0e937bSRaymond Chen }; 164ff0e937bSRaymond Chen 165ff0e937bSRaymond Chen static uint_t usb_wa_item = 11; 166ff0e937bSRaymond Chen 1674e968bc2Sgc static usb_descr_item_t usb_hid_descr[] = { 1684e968bc2Sgc {1, "bLength"}, 1694e968bc2Sgc {1, "bDescriptorType"}, 1704e968bc2Sgc {2, "bcdHID"}, 1714e968bc2Sgc {1, "bCountryCode"}, 1724e968bc2Sgc {1, "bNumDescriptors"}, 1734e968bc2Sgc {1, "bReportDescriptorType"}, 1744e968bc2Sgc {2, "wReportDescriptorLength"}, 1754e968bc2Sgc }; 1764e968bc2Sgc static uint_t usb_hid_item = 7; 1774e968bc2Sgc 1784e968bc2Sgc static usb_descr_item_t usb_ac_header_descr[] = { 1794e968bc2Sgc {1, "bLength"}, 1804e968bc2Sgc {1, "bDescriptorType"}, 1814e968bc2Sgc {1, "bDescriptorSubType"}, 1824e968bc2Sgc {2, "bcdADC"}, 1834e968bc2Sgc {2, "wTotalLength"}, 1844e968bc2Sgc {1, "blnCollection"}, 1854e968bc2Sgc {1, "baInterfaceNr"}, 1864e968bc2Sgc }; 1874e968bc2Sgc static uint_t usb_ac_header_item = 7; 1884e968bc2Sgc 1894e968bc2Sgc static usb_descr_item_t usb_ac_input_term_descr[] = { 1904e968bc2Sgc {1, "bLength"}, 1914e968bc2Sgc {1, "bDescriptorType"}, 1924e968bc2Sgc {1, "bDescriptorSubType"}, 1934e968bc2Sgc {1, "bTerminalID"}, 1944e968bc2Sgc {2, "wTerminalType"}, 1954e968bc2Sgc {1, "bAssocTerminal"}, 1964e968bc2Sgc {1, "bNrChannels"}, 1974e968bc2Sgc {2, "wChannelConfig"}, 1984e968bc2Sgc {1, "iChannelNames"}, 1994e968bc2Sgc {1, "iTerminal"}, 2004e968bc2Sgc }; 2014e968bc2Sgc static uint_t usb_ac_input_term_item = 10; 2024e968bc2Sgc 2034e968bc2Sgc static usb_descr_item_t usb_ac_output_term_descr[] = { 2044e968bc2Sgc {1, "bLength"}, 2054e968bc2Sgc {1, "bDescriptorType"}, 2064e968bc2Sgc {1, "bDescriptorSubType"}, 2074e968bc2Sgc {1, "bTerminalID"}, 2084e968bc2Sgc {2, "wTerminalType"}, 2094e968bc2Sgc {1, "bAssocTerminal"}, 2104e968bc2Sgc {1, "bSourceID"}, 2114e968bc2Sgc {1, "iTerminal"}, 2124e968bc2Sgc }; 2134e968bc2Sgc static uint_t usb_ac_output_term_item = 8; 2144e968bc2Sgc 2154e968bc2Sgc static usb_descr_item_t usb_ac_mixer_descr[] = { 2164e968bc2Sgc {1, "bLength"}, 2174e968bc2Sgc {1, "bDescriptorType"}, 2184e968bc2Sgc {1, "bDescriptorSubType"}, 2194e968bc2Sgc {1, "bUnitID"}, 2204e968bc2Sgc {1, "bNrInPins"}, 2214e968bc2Sgc {1, "baSourceID"}, 2224e968bc2Sgc }; 2234e968bc2Sgc static uint_t usb_ac_mixer_item = 6; 2244e968bc2Sgc 2254e968bc2Sgc static usb_descr_item_t usb_ac_selector_descr[] = { 2264e968bc2Sgc {1, "bLength"}, 2274e968bc2Sgc {1, "bDescriptorType"}, 2284e968bc2Sgc {1, "bDescriptorSubType"}, 2294e968bc2Sgc {1, "bUnitID"}, 2304e968bc2Sgc {1, "bNrInPins"}, 2314e968bc2Sgc {1, "baSourceID"}, 2324e968bc2Sgc }; 2334e968bc2Sgc static uint_t usb_ac_selector_item = 6; 2344e968bc2Sgc 2354e968bc2Sgc static usb_descr_item_t usb_ac_feature_descr[] = { 2364e968bc2Sgc {1, "bLength"}, 2374e968bc2Sgc {1, "bDescriptorType"}, 2384e968bc2Sgc {1, "bDescriptorSubType"}, 2394e968bc2Sgc {1, "bUnitID"}, 2404e968bc2Sgc {1, "bSourceID"}, 2414e968bc2Sgc {1, "bControlSize"}, 2424e968bc2Sgc {1, "bmaControls"}, 2434e968bc2Sgc }; 2444e968bc2Sgc static uint_t usb_ac_feature_item = 7; 2454e968bc2Sgc 2464e968bc2Sgc static usb_descr_item_t usb_ac_processing_descr[] = { 2474e968bc2Sgc {1, "bLength"}, 2484e968bc2Sgc {1, "bDescriptorType"}, 2494e968bc2Sgc {1, "bDescriptorSubType"}, 2504e968bc2Sgc {1, "bUnitID"}, 2514e968bc2Sgc {1, "wProcessType"}, 2524e968bc2Sgc {1, "bNrInPins"}, 2534e968bc2Sgc {1, "baSourceID"}, 2544e968bc2Sgc }; 2554e968bc2Sgc static uint_t usb_ac_processing_item = 7; 2564e968bc2Sgc 2574e968bc2Sgc static usb_descr_item_t usb_ac_extension_descr[] = { 2584e968bc2Sgc {1, "bLength"}, 2594e968bc2Sgc {1, "bDescriptorType"}, 2604e968bc2Sgc {1, "bDescriptorSubType"}, 2614e968bc2Sgc {1, "wExtensionCode"}, 2624e968bc2Sgc {1, "bUnitID"}, 2634e968bc2Sgc {1, "bNrInPins"}, 2644e968bc2Sgc {1, "baSourceID"}, 2654e968bc2Sgc }; 2664e968bc2Sgc static uint_t usb_ac_extension_item = 7; 2674e968bc2Sgc 2684e968bc2Sgc static usb_descr_item_t usb_as_ep_descr[] = { 2694e968bc2Sgc {1, "blength"}, 2704e968bc2Sgc {1, "bDescriptorType"}, 2714e968bc2Sgc {1, "bDescriptorSubType"}, 2724e968bc2Sgc {1, "bmAttributes"}, 2734e968bc2Sgc {1, "bLockDelayUnits"}, 2744e968bc2Sgc {2, "wLockDelay"}, 2754e968bc2Sgc }; 2764e968bc2Sgc static uint_t usb_as_ep_item = 6; 2774e968bc2Sgc 2784e968bc2Sgc static usb_descr_item_t usb_as_if_descr[] = { 2794e968bc2Sgc {1, "blength"}, 2804e968bc2Sgc {1, "bDescriptorType"}, 2814e968bc2Sgc {1, "bDescriptorSubType"}, 2824e968bc2Sgc {1, "bTerminalLink"}, 2834e968bc2Sgc {1, "bDelay"}, 2844e968bc2Sgc {2, "wFormatTag"}, 2854e968bc2Sgc }; 2864e968bc2Sgc static uint_t usb_as_if_item = 6; 2874e968bc2Sgc 2884e968bc2Sgc static usb_descr_item_t usb_as_format_descr[] = { 2894e968bc2Sgc {1, "blength"}, 2904e968bc2Sgc {1, "bDescriptorType"}, 2914e968bc2Sgc {1, "bDescriptorSubType"}, 2924e968bc2Sgc {1, "bFormatType"}, 2934e968bc2Sgc {1, "bNrChannels"}, 2944e968bc2Sgc {1, "bSubFrameSize"}, 2954e968bc2Sgc {1, "bBitResolution"}, 2964e968bc2Sgc {1, "bSamFreqType"}, 2974e968bc2Sgc {1, "bSamFreqs"}, 2984e968bc2Sgc }; 2994e968bc2Sgc static uint_t usb_as_format_item = 9; 3004e968bc2Sgc 3014e968bc2Sgc static usb_descr_item_t usb_vc_header_descr[] = { 3024e968bc2Sgc {1, "bLength"}, 3034e968bc2Sgc {1, "bDescriptorType"}, 3044e968bc2Sgc {1, "bDescriptorSubtype"}, 3054e968bc2Sgc {2, "bcdUVC"}, 3064e968bc2Sgc {2, "wTotalLength"}, 3074e968bc2Sgc {4, "dwClockFrequency"}, 3084e968bc2Sgc {1, "bInCollection"}, 3094e968bc2Sgc }; 3104e968bc2Sgc static uint_t usb_vc_header_item = 7; 3114e968bc2Sgc 3124e968bc2Sgc static usb_descr_item_t usb_vc_input_term_descr[] = { 3134e968bc2Sgc {1, "bLength"}, 3144e968bc2Sgc {1, "bDescriptorType"}, 3154e968bc2Sgc {1, "bDescriptorSubType"}, 3164e968bc2Sgc {1, "bTerminalID"}, 3174e968bc2Sgc {2, "wTerminalType"}, 3184e968bc2Sgc {1, "AssocTerminal"}, 3194e968bc2Sgc {1, "iTerminal"}, 3204e968bc2Sgc }; 3214e968bc2Sgc static uint_t usb_vc_input_term_item = 7; 3224e968bc2Sgc 3234e968bc2Sgc static usb_descr_item_t usb_vc_output_term_descr[] = { 3244e968bc2Sgc {1, "bLength"}, 3254e968bc2Sgc {1, "bDescriptorType"}, 3264e968bc2Sgc {1, "bDescriptorSubType"}, 3274e968bc2Sgc {1, "bTerminalID"}, 3284e968bc2Sgc {2, "wTerminalType"}, 3294e968bc2Sgc {1, "AssocTerminal"}, 3304e968bc2Sgc {1, "bSourceID"}, 3314e968bc2Sgc {1, "iTerminal"}, 3324e968bc2Sgc }; 3334e968bc2Sgc static uint_t usb_vc_output_term_item = 8; 3344e968bc2Sgc 3354e968bc2Sgc static usb_descr_item_t usb_vc_processing_descr[] = { 3364e968bc2Sgc {1, "bLength"}, 3374e968bc2Sgc {1, "bDescriptorType"}, 3384e968bc2Sgc {1, "bDescriptorSubType"}, 3394e968bc2Sgc {1, "bUnitID"}, 3404e968bc2Sgc {1, "bSourceID"}, 3414e968bc2Sgc {2, "wMaxMultiplier"}, 3424e968bc2Sgc {1, "bControlSize"}, 3434e968bc2Sgc {1, "bmControls"}, 3444e968bc2Sgc }; 3454e968bc2Sgc static uint_t usb_vc_processing_item = 8; 3464e968bc2Sgc 3474e968bc2Sgc static usb_descr_item_t usb_vc_selector_descr[] = { 3484e968bc2Sgc {1, "bLength"}, 3494e968bc2Sgc {1, "bDescriptorType"}, 3504e968bc2Sgc {1, "bDescriptorSubType"}, 3514e968bc2Sgc {1, "bUnitID"}, 3524e968bc2Sgc {1, "bNrInPins"}, 3534e968bc2Sgc }; 3544e968bc2Sgc static uint_t usb_vc_selector_item = 5; 3554e968bc2Sgc 3564e968bc2Sgc static usb_descr_item_t usb_vc_extension_descr[] = { 3574e968bc2Sgc {1, "bLength"}, 3584e968bc2Sgc {1, "bDescriptorType"}, 3594e968bc2Sgc {1, "bDescriptorSubType"}, 3604e968bc2Sgc {1, "bUnitID"}, 3614e968bc2Sgc {16 + BYTE_OFFSET, "guidExtensionCode[16]"}, 3624e968bc2Sgc {1, "bNumControls"}, 3634e968bc2Sgc {1, "bNrInPins"}, 3644e968bc2Sgc }; 3654e968bc2Sgc static uint_t usb_vc_extension_item = 7; 3664e968bc2Sgc 3674e968bc2Sgc static usb_descr_item_t usb_vs_input_header_descr[] = { 3684e968bc2Sgc {1, "bLength"}, 3694e968bc2Sgc {1, "bDescriptorType"}, 3704e968bc2Sgc {1, "bDescriptorSubType"}, 3714e968bc2Sgc {1, "bNumFormats"}, 3724e968bc2Sgc {2, "wTotalLength"}, 3734e968bc2Sgc {1, "bEndpointAddress"}, 3744e968bc2Sgc {1, "bmInfo"}, 3754e968bc2Sgc {1, "bTerminalLink"}, 3764e968bc2Sgc {1, "bStillCaptureMethod"}, 3774e968bc2Sgc {1, "bTriggerSupport"}, 3784e968bc2Sgc {1, "bTriggerUsage"}, 3794e968bc2Sgc {1, "bControlSize"}, 3804e968bc2Sgc {1, "bmaControls"}, 3814e968bc2Sgc }; 3824e968bc2Sgc static uint_t usb_vs_input_header_item = 13; 3834e968bc2Sgc 3844e968bc2Sgc static usb_descr_item_t usb_vs_output_header_descr[] = { 3854e968bc2Sgc {1, "bLength"}, 3864e968bc2Sgc {1, "bDescriptorType"}, 3874e968bc2Sgc {1, "bDescriptorSubType"}, 3884e968bc2Sgc {1, "bNumFormats"}, 3894e968bc2Sgc {2, "wTotalLength"}, 3904e968bc2Sgc {1, "bEndpointAddress"}, 3914e968bc2Sgc {1, "bTerminalLink"}, 3924e968bc2Sgc {1, "bControlSize"}, 3934e968bc2Sgc {1, "bmaControls"}, 3944e968bc2Sgc }; 3954e968bc2Sgc static uint_t usb_vs_output_header_item = 9; 3964e968bc2Sgc 3974e968bc2Sgc static usb_descr_item_t usb_vs_still_image_descr[] = { 3984e968bc2Sgc {1, "bLength"}, 3994e968bc2Sgc {1, "bDescriptorType"}, 4004e968bc2Sgc {1, "bDescriptorSubType"}, 4014e968bc2Sgc {1, "bEndpointAddress"}, 4024e968bc2Sgc {1, "bNumImageSizePatterns"}, 4034e968bc2Sgc {2, "wWidth"}, 4044e968bc2Sgc {2, "wHeight"}, 4054e968bc2Sgc }; 4064e968bc2Sgc static uint_t usb_vs_still_image_item = 7; 4074e968bc2Sgc 4084e968bc2Sgc static usb_descr_item_t usb_vs_color_matching_descr[] = { 4094e968bc2Sgc {1, "bLength"}, 4104e968bc2Sgc {1, "bDescriptorType"}, 4114e968bc2Sgc {1, "bDescriptorSubtype"}, 4124e968bc2Sgc {1, "bColorPrimaries"}, 4134e968bc2Sgc {1, "bTransferCharacteristics"}, 4144e968bc2Sgc {1, "bMatrixCoefficients"}, 4154e968bc2Sgc }; 4164e968bc2Sgc static uint_t usb_vs_color_matching_item = 6; 4174e968bc2Sgc 4184e968bc2Sgc static usb_descr_item_t usb_vs_2frame_descr[] = { 4194e968bc2Sgc {1, "bLength"}, 4204e968bc2Sgc {1, "bDescriptorType"}, 4214e968bc2Sgc {1, "bDescriptorSubType"}, 4224e968bc2Sgc {1, "bFrameIndex"}, 4234e968bc2Sgc {1, "bmCapabilities"}, 4244e968bc2Sgc {2, "wWidth"}, 4254e968bc2Sgc {2, "wHeight"}, 4264e968bc2Sgc {4, "dwMinBitRate"}, 4274e968bc2Sgc {4, "dwMaxBitRate"}, 4284e968bc2Sgc {4, "dwMaxVideoFrameBufferSize"}, 4294e968bc2Sgc {4, "dwDefaultFrameInterval"}, 4304e968bc2Sgc {1, "bFrameIntervalType"}, 4314e968bc2Sgc }; 4324e968bc2Sgc static uint_t usb_vs_2frame_item = 12; 4334e968bc2Sgc 4344e968bc2Sgc static usb_descr_item_t usb_vs_format_mjpeg_descr[] = { 4354e968bc2Sgc {1, "bLength"}, 4364e968bc2Sgc {1, "bDescriptorType"}, 4374e968bc2Sgc {1, "bDescriptorSubType"}, 4384e968bc2Sgc {1, "bFormatIndex"}, 4394e968bc2Sgc {1, "bNumFrameDescriptors"}, 4404e968bc2Sgc {1, "bmFlags"}, 4414e968bc2Sgc {1, "bDefaultFrameIndex"}, 4424e968bc2Sgc {1, "bAspectRatioX"}, 4434e968bc2Sgc {1, "bAspectRatioY"}, 4444e968bc2Sgc {1, "bmInterlaceFlags"}, 4454e968bc2Sgc {1, "bCopyProtect"}, 4464e968bc2Sgc }; 4474e968bc2Sgc static uint_t usb_vs_format_mjpeg_item = 11; 4484e968bc2Sgc 4494e968bc2Sgc static usb_descr_item_t usb_vs_format_uncps_descr[] = { 4504e968bc2Sgc {1, "bLength"}, 4514e968bc2Sgc {1, "bDescriptorType"}, 4524e968bc2Sgc {1, "bDescriptorSubType"}, 4534e968bc2Sgc {1, "bFormatIndex"}, 4544e968bc2Sgc {1, "bNumFrameDescriptors"}, 4554e968bc2Sgc {16 + BYTE_OFFSET, "guidFormat[16]"}, 4564e968bc2Sgc {1, "bBitsPerPixel"}, 4574e968bc2Sgc {1, "bDefaultFrameIndex"}, 4584e968bc2Sgc {1, "bAspectRatioX"}, 4594e968bc2Sgc {1, "bAspectRatioY"}, 4604e968bc2Sgc {1, "bmInterlaceFlags"}, 4614e968bc2Sgc {1, "bCopyProtect"}, 4624e968bc2Sgc }; 4634e968bc2Sgc static uint_t usb_vs_format_uncps_item = 12; 4644e968bc2Sgc 4654e968bc2Sgc static usb_descr_item_t usb_vs_format_mp2ts_descr[] = { 4664e968bc2Sgc {1, "bLength"}, 4674e968bc2Sgc {1, "bDescriptorType"}, 4684e968bc2Sgc {1, "bDescriptorSubType"}, 4694e968bc2Sgc {1, "bFormatIndex"}, 4704e968bc2Sgc {1, "bDataOffset"}, 4714e968bc2Sgc {1, "bPacketLength"}, 4724e968bc2Sgc {1, "bStrideLength"}, 4734e968bc2Sgc {16 + BYTE_OFFSET, "guidStrideFormat[16]"}, 4744e968bc2Sgc }; 4754e968bc2Sgc static uint_t usb_vs_format_mp2ts_item = 8; 4764e968bc2Sgc 4774e968bc2Sgc static usb_descr_item_t usb_vs_format_dv_descr[] = { 4784e968bc2Sgc {1, "bLength"}, 4794e968bc2Sgc {1, "bDescriptorType"}, 4804e968bc2Sgc {1, "bDescriptorSubType"}, 4814e968bc2Sgc {1, "bFormatIndex"}, 4824e968bc2Sgc {4, "dwMaxVideoFrameBufferSize"}, 4834e968bc2Sgc {1, "bFormatType"}, 4844e968bc2Sgc }; 4854e968bc2Sgc static uint_t usb_vs_format_dv_item = 6; 4864e968bc2Sgc 487*a61ed2ceSHans Rosenfeld static usb_descr_item_t usb_ccid_descr[] = { 488*a61ed2ceSHans Rosenfeld {1, "bLength"}, 489*a61ed2ceSHans Rosenfeld {1, "bDescriptorType"}, 490*a61ed2ceSHans Rosenfeld {2, "bcdCCID"}, 491*a61ed2ceSHans Rosenfeld {1, "bMaxSlotIndex"}, 492*a61ed2ceSHans Rosenfeld {1, "bVoltageSupport"}, 493*a61ed2ceSHans Rosenfeld {4, "dwProtocols"}, 494*a61ed2ceSHans Rosenfeld {4, "dwDefaultClock"}, 495*a61ed2ceSHans Rosenfeld {4, "dwMaximumClock"}, 496*a61ed2ceSHans Rosenfeld {1, "bNumClockSupported"}, 497*a61ed2ceSHans Rosenfeld {4, "dwDataRate"}, 498*a61ed2ceSHans Rosenfeld {4, "dwMaxDataRate"}, 499*a61ed2ceSHans Rosenfeld {1, "bNumDataRatesSupported"}, 500*a61ed2ceSHans Rosenfeld {4, "dwMaxIFSD"}, 501*a61ed2ceSHans Rosenfeld {4, "dwSyncProtocols"}, 502*a61ed2ceSHans Rosenfeld {4, "dwMechanical"}, 503*a61ed2ceSHans Rosenfeld {4, "dwFeatures"}, 504*a61ed2ceSHans Rosenfeld {4, "dwMaxCCIDMessageLength"}, 505*a61ed2ceSHans Rosenfeld {1, "bClassGetResponse"}, 506*a61ed2ceSHans Rosenfeld {1, "bClassEnvelope"}, 507*a61ed2ceSHans Rosenfeld {2, "wLcdLayout"}, 508*a61ed2ceSHans Rosenfeld {1, "bPinSupport"}, 509*a61ed2ceSHans Rosenfeld {1, "bMaxCCIDBusySlots"} 510*a61ed2ceSHans Rosenfeld }; 511*a61ed2ceSHans Rosenfeld static uint_t usb_ccid_item = ARRAY_SIZE(usb_ccid_descr); 512*a61ed2ceSHans Rosenfeld 5134e968bc2Sgc 5144e968bc2Sgc /* ****************************************************************** */ 5154e968bc2Sgc 5164e968bc2Sgc typedef struct hci_state { 5174e968bc2Sgc void *hci_dip; 5184e968bc2Sgc uint_t hci_instance; 5194e968bc2Sgc void *hci_hcdi_ops; 5204e968bc2Sgc uint_t hci_flags; 5214e968bc2Sgc uint16_t vendor_id; 5224e968bc2Sgc uint16_t device_id; 5234e968bc2Sgc } hci_state_t; 5244e968bc2Sgc 5254e968bc2Sgc static int prt_usb_tree(uintptr_t paddr, uint_t flag); 5264e968bc2Sgc 5274e968bc2Sgc static int prt_usb_tree_node(uintptr_t paddr); 5284e968bc2Sgc 5294e968bc2Sgc static void prt_usb_hid_item(uintptr_t paddr); 5304e968bc2Sgc 5314e968bc2Sgc static void prt_usb_hid_item_params(entity_item_t *item); 5324e968bc2Sgc 5334e968bc2Sgc static void prt_usb_hid_item_attrs(uintptr_t paddr); 5344e968bc2Sgc 5354e968bc2Sgc static void prt_usb_hid_item_tags(uint_t tag); 5364e968bc2Sgc 5374e968bc2Sgc static void prt_usb_hid_item_data(uintptr_t paddr, uint_t len); 5384e968bc2Sgc 5394e968bc2Sgc static int prt_usb_desc(uintptr_t usb_cfg, uint_t cfg_len); 5404e968bc2Sgc 5414e968bc2Sgc static int prt_usb_ac_desc(uintptr_t paddr, uint_t nlen); 5424e968bc2Sgc 5434e968bc2Sgc static int prt_usb_as_desc(uintptr_t paddr, uint_t nlen); 5444e968bc2Sgc 5454e968bc2Sgc static int prt_usb_vc_desc(uintptr_t paddr, uint_t nlen); 5464e968bc2Sgc 5474e968bc2Sgc static int prt_usb_vs_desc(uintptr_t paddr, uint_t nlen); 5484e968bc2Sgc 5494e968bc2Sgc static int print_descr(uintptr_t, uint_t, usb_descr_item_t *, uint_t); 5504e968bc2Sgc 5514e968bc2Sgc static int print_struct(uintptr_t, uint_t, mdb_arg_t *); 5524e968bc2Sgc 5534e968bc2Sgc static int prt_usb_buf(uintptr_t, uint_t); 5544e968bc2Sgc 5554e968bc2Sgc 5564e968bc2Sgc /* ****************************************************************** */ 5574e968bc2Sgc 5584e968bc2Sgc /* exported functions */ 5594e968bc2Sgc 5604e968bc2Sgc void prt_usb_usage(void); 5614e968bc2Sgc 5624e968bc2Sgc int prtusb(uintptr_t, uint_t, int, const mdb_arg_t *); 5634e968bc2Sgc 5644e968bc2Sgc /* ****************************************************************** */ 5654e968bc2Sgc 5664e968bc2Sgc /* help of prtusb */ 5674e968bc2Sgc void 5684e968bc2Sgc prt_usb_usage(void) 5694e968bc2Sgc { 5704e968bc2Sgc mdb_printf("%-8s : %s\n", "-v", "print all descriptors"); 5714e968bc2Sgc mdb_printf("%-8s : %s\n", "-t", "print device trees"); 572eae66f16Sgc mdb_printf("%-8s : %s\n", "-i index", "print the device by index"); 5734e968bc2Sgc } 5744e968bc2Sgc 5754e968bc2Sgc /* the entry of ::prtusb */ 5764e968bc2Sgc int 5774e968bc2Sgc prtusb(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 5784e968bc2Sgc { 5794e968bc2Sgc static int count = 1; 5804e968bc2Sgc uint64_t sel_num = 0; 5814e968bc2Sgc uint_t usb_flag = 0; 5824e968bc2Sgc usba_device_t usb_dev; 5834e968bc2Sgc usb_dev_descr_t dev_desc; 5844e968bc2Sgc struct dev_info usb_dip; 5854e968bc2Sgc char strbuf[STRLEN]; 5864e968bc2Sgc 5874e968bc2Sgc /* print all usba devices if no address assigned */ 5884e968bc2Sgc if (!(flags & DCMD_ADDRSPEC)) { 5894e968bc2Sgc if (mdb_walk_dcmd("usba_device", "prtusb", argc, argv) == -1) { 5904e968bc2Sgc mdb_warn("failed to walk usba_device"); 5914e968bc2Sgc 5924e968bc2Sgc return (DCMD_ERR); 5934e968bc2Sgc } 5944e968bc2Sgc 5954e968bc2Sgc return (DCMD_OK); 5964e968bc2Sgc } 5974e968bc2Sgc 5984e968bc2Sgc /* for the first device, print head */ 5994e968bc2Sgc if (DCMD_HDRSPEC(flags)) { 6004e968bc2Sgc count = 1; 601993e3fafSRobert Mustacchi mdb_printf("%<u>%-8s%-12s%-6s%-14s%-5s%-12s%-20s%</u>\n", 602993e3fafSRobert Mustacchi "INDEX", "DRIVER", "INST", "NODE", "GEN", "VID.PID", 603993e3fafSRobert Mustacchi "PRODUCT"); 6044e968bc2Sgc } 6054e968bc2Sgc 6064e968bc2Sgc if (mdb_getopts(argc, argv, 6074e968bc2Sgc 'i', MDB_OPT_UINT64, &sel_num, 6084e968bc2Sgc 't', MDB_OPT_SETBITS, OPT_TREE, &usb_flag, 6094e968bc2Sgc 'v', MDB_OPT_SETBITS, OPT_VERB, &usb_flag, NULL) != argc) { 6104e968bc2Sgc 6114e968bc2Sgc return (DCMD_USAGE); 6124e968bc2Sgc } 6134e968bc2Sgc 6144e968bc2Sgc if (mdb_vread(&usb_dev, sizeof (usba_device_t), addr) == -1) { 6154e968bc2Sgc mdb_warn("Failed to read usba_device!\n"); 6164e968bc2Sgc 6174e968bc2Sgc return (DCMD_ERR); 6184e968bc2Sgc } 6194e968bc2Sgc 6204e968bc2Sgc if (mdb_vread(&usb_dip, sizeof (struct dev_info), 6214e968bc2Sgc (uintptr_t)usb_dev.usb_dip) == -1) { 6224e968bc2Sgc mdb_warn("Failed to read dev_info!\n"); 6234e968bc2Sgc 6244e968bc2Sgc return (DCMD_ERR); 6254e968bc2Sgc } 6264e968bc2Sgc 6274e968bc2Sgc /* process the "-i" */ 6284e968bc2Sgc if (sel_num && sel_num != count) { 6294e968bc2Sgc count++; 6304e968bc2Sgc 6314e968bc2Sgc return (DCMD_OK); 6324e968bc2Sgc } 6334e968bc2Sgc 634eae66f16Sgc /* index number of device node */ 635eae66f16Sgc mdb_printf("%-8x", count++); 6364e968bc2Sgc 6374e968bc2Sgc /* driver and instance */ 6384e968bc2Sgc mdb_devinfo2driver((uintptr_t)usb_dev.usb_dip, strbuf, STRLEN); 6394e968bc2Sgc mdb_printf("%-12s%-6d", strbuf, usb_dip.devi_instance); 6404e968bc2Sgc 6414e968bc2Sgc /* node name */ 6424e968bc2Sgc if (mdb_readstr(strbuf, STRLEN, 6434e968bc2Sgc (uintptr_t)usb_dip.devi_node_name) != -1) { 6444e968bc2Sgc 645993e3fafSRobert Mustacchi mdb_printf("%-14s", strbuf); 6464e968bc2Sgc } else { 6474e968bc2Sgc 648993e3fafSRobert Mustacchi mdb_printf("%-14s", "No Node Name"); 6494e968bc2Sgc } 6504e968bc2Sgc 651993e3fafSRobert Mustacchi 6524e968bc2Sgc if (mdb_vread(&dev_desc, sizeof (usb_dev_descr_t), 6534e968bc2Sgc (uintptr_t)usb_dev.usb_dev_descr) != -1) { 6544e968bc2Sgc 655993e3fafSRobert Mustacchi /* gen (note we read this from the bcd) */ 656993e3fafSRobert Mustacchi mdb_printf("%01x.%01x ", dev_desc.bcdUSB >> 8, 657993e3fafSRobert Mustacchi (dev_desc.bcdUSB & 0xf0) >> 4); 658993e3fafSRobert Mustacchi 659993e3fafSRobert Mustacchi /* vid.pid */ 6604e968bc2Sgc mdb_printf("%04x.%04x ", 6614e968bc2Sgc dev_desc.idVendor, dev_desc.idProduct); 6624e968bc2Sgc } 6634e968bc2Sgc 6644e968bc2Sgc /* product string */ 6654e968bc2Sgc if (mdb_readstr(strbuf, STRLEN, 6664e968bc2Sgc (uintptr_t)usb_dev.usb_product_str) != -1) { 6674e968bc2Sgc 6684e968bc2Sgc mdb_printf("%s\n", strbuf); 6694e968bc2Sgc } else { 6704e968bc2Sgc 6714e968bc2Sgc mdb_printf("%s\n", "No Product String"); 6724e968bc2Sgc } 6734e968bc2Sgc 6744e968bc2Sgc /* tree, print usb device tree info */ 6754e968bc2Sgc if (usb_flag & OPT_TREE) { 6764e968bc2Sgc 6774e968bc2Sgc mdb_printf("\nusba_device: 0x%x\n", addr); 6784e968bc2Sgc 6794e968bc2Sgc mdb_printf("mfg_prod_sn: "); 6804e968bc2Sgc if (mdb_readstr(strbuf, STRLEN, 6814e968bc2Sgc (uintptr_t)usb_dev.usb_mfg_str) != -1) { 6824e968bc2Sgc mdb_printf("%s - ", strbuf); 6834e968bc2Sgc } else { 6844e968bc2Sgc mdb_printf("NULL - "); 6854e968bc2Sgc } 6864e968bc2Sgc if (mdb_readstr(strbuf, STRLEN, 6874e968bc2Sgc (uintptr_t)usb_dev.usb_product_str) != -1) { 6884e968bc2Sgc mdb_printf("%s - ", strbuf); 6894e968bc2Sgc } else { 6904e968bc2Sgc mdb_printf("NULL -"); 6914e968bc2Sgc } 6924e968bc2Sgc if (mdb_readstr(strbuf, STRLEN, 6934e968bc2Sgc (uintptr_t)usb_dev.usb_serialno_str) != -1) { 6944e968bc2Sgc mdb_printf("%s", strbuf); 6954e968bc2Sgc } else { 6964e968bc2Sgc mdb_printf("NULL"); 6974e968bc2Sgc } 6984e968bc2Sgc 6994e968bc2Sgc mdb_printf("\n\n"); 7004e968bc2Sgc prt_usb_tree((uintptr_t)usb_dev.usb_dip, 0); 7014e968bc2Sgc } 7024e968bc2Sgc 7034e968bc2Sgc /* verbose, print all descriptors */ 7044e968bc2Sgc if (usb_flag & OPT_VERB) { 7054e968bc2Sgc int i; 7064e968bc2Sgc uintptr_t cfg_buf; 7074e968bc2Sgc uint16_t cfg_len; 7084e968bc2Sgc 7094e968bc2Sgc mdb_printf("\n"); 7104e968bc2Sgc 7114e968bc2Sgc /* device descriptor */ 7124e968bc2Sgc prt_usb_desc((uintptr_t)usb_dev.usb_dev_descr, 18); 7134e968bc2Sgc 7144e968bc2Sgc /* config cloud descriptors */ 7154e968bc2Sgc if (usb_dev.usb_n_cfgs == 1) { 7164e968bc2Sgc mdb_inc_indent(4); 7174e968bc2Sgc mdb_printf("-- Active Config Index 0\n"); 7184e968bc2Sgc mdb_dec_indent(4); 7194e968bc2Sgc prt_usb_desc((uintptr_t)usb_dev.usb_cfg, 7204e968bc2Sgc usb_dev.usb_cfg_length); 7214e968bc2Sgc } else { 7224e968bc2Sgc /* multiple configs */ 7234e968bc2Sgc for (i = 0; i < usb_dev.usb_n_cfgs; i++) { 7244e968bc2Sgc 7254e968bc2Sgc if ((mdb_vread(&cfg_len, sizeof (uint16_t), 7264e968bc2Sgc (uintptr_t)(usb_dev.usb_cfg_array_len + i)) 7274e968bc2Sgc != -1) && 7284e968bc2Sgc (mdb_vread(&cfg_buf, sizeof (uintptr_t), 7294e968bc2Sgc (uintptr_t)(usb_dev.usb_cfg_array + i)) 7304e968bc2Sgc != -1)) { 7314e968bc2Sgc mdb_inc_indent(4); 7324e968bc2Sgc if (cfg_buf == 7334e968bc2Sgc (uintptr_t)usb_dev.usb_cfg) { 7344e968bc2Sgc mdb_printf("-- Active Config" 7354e968bc2Sgc " Index %x\n", i); 7364e968bc2Sgc } else { 7374e968bc2Sgc mdb_printf("-- Inactive Config" 7384e968bc2Sgc " Index %x\n", i); 7394e968bc2Sgc } 7404e968bc2Sgc mdb_dec_indent(4); 7414e968bc2Sgc 7424e968bc2Sgc prt_usb_desc(cfg_buf, cfg_len); 7434e968bc2Sgc } 7444e968bc2Sgc } 7454e968bc2Sgc } 7464e968bc2Sgc } 7474e968bc2Sgc 7484e968bc2Sgc if (usb_flag) { 7494e968bc2Sgc 7504e968bc2Sgc mdb_printf("%<u>%-72s%</u>\n", " "); 7514e968bc2Sgc } 7524e968bc2Sgc 7534e968bc2Sgc return (DCMD_OK); 7544e968bc2Sgc } 7554e968bc2Sgc 7564e968bc2Sgc /* print the info required by "-t" */ 7574e968bc2Sgc static int 7584e968bc2Sgc prt_usb_tree(uintptr_t paddr, uint_t flag) 7594e968bc2Sgc { 7604e968bc2Sgc struct dev_info usb_dip; 7614e968bc2Sgc 7624e968bc2Sgc if (mdb_vread(&usb_dip, sizeof (struct dev_info), paddr) == -1) { 7634e968bc2Sgc mdb_warn("prt_usb_tree: Failed to read dev_info!\n"); 7644e968bc2Sgc 7654e968bc2Sgc return (DCMD_ERR); 7664e968bc2Sgc } 7674e968bc2Sgc 7684e968bc2Sgc prt_usb_tree_node(paddr); 7694e968bc2Sgc 7704e968bc2Sgc if (usb_dip.devi_child) { 7714e968bc2Sgc 7724e968bc2Sgc mdb_printf("{\n"); 7734e968bc2Sgc mdb_inc_indent(4); 7744e968bc2Sgc prt_usb_tree((uintptr_t)usb_dip.devi_child, 1); 7754e968bc2Sgc mdb_dec_indent(4); 7764e968bc2Sgc mdb_printf("}\n\n"); 7774e968bc2Sgc } 7784e968bc2Sgc 7794e968bc2Sgc if (usb_dip.devi_sibling && flag == 1) { 7804e968bc2Sgc /* print the sibling if flag == 1 */ 7814e968bc2Sgc 7824e968bc2Sgc prt_usb_tree((uintptr_t)usb_dip.devi_sibling, 1); 7834e968bc2Sgc } 7844e968bc2Sgc 7854e968bc2Sgc return (DCMD_OK); 7864e968bc2Sgc } 7874e968bc2Sgc 7884e968bc2Sgc static int 7894e968bc2Sgc prt_usb_tree_node(uintptr_t paddr) 7904e968bc2Sgc { 7914e968bc2Sgc struct dev_info usb_dip; 7924e968bc2Sgc uintptr_t statep; 7934e968bc2Sgc uint_t errlevel; 7944e968bc2Sgc char driver_name[STRLEN] = ""; 7954e968bc2Sgc char strbuf[STRLEN] = ""; 7964e968bc2Sgc 7974e968bc2Sgc if (mdb_vread(&usb_dip, sizeof (struct dev_info), paddr) == -1) { 7984e968bc2Sgc mdb_warn("prt_usb_tree_node: Failed to read dev_info!\n"); 7994e968bc2Sgc 8004e968bc2Sgc return (DCMD_ERR); 8014e968bc2Sgc } 8024e968bc2Sgc 8034e968bc2Sgc /* node name */ 8044e968bc2Sgc if (mdb_readstr(strbuf, STRLEN, 805ff0e937bSRaymond Chen (uintptr_t)usb_dip.devi_node_name) != -1) { 8064e968bc2Sgc mdb_printf("%s, ", strbuf); 8074e968bc2Sgc } else { 8084e968bc2Sgc mdb_printf("%s, ", "node_name"); 8094e968bc2Sgc } 8104e968bc2Sgc 8114e968bc2Sgc /* instance */ 8124e968bc2Sgc mdb_printf("instance #%d ", usb_dip.devi_instance); 8134e968bc2Sgc 8144e968bc2Sgc /* driver name */ 8154e968bc2Sgc if (DDI_CF2(&usb_dip)) { 8164e968bc2Sgc 8174e968bc2Sgc mdb_devinfo2driver(paddr, driver_name, STRLEN); 8184e968bc2Sgc mdb_printf("(driver name: %s)\n", driver_name); 8194e968bc2Sgc } else { 8204e968bc2Sgc 8214e968bc2Sgc mdb_printf("(driver not attached)\n"); 8224e968bc2Sgc } 8234e968bc2Sgc 8244e968bc2Sgc /* device path */ 8254e968bc2Sgc mdb_ddi_pathname(paddr, strbuf, STRLEN); 8264e968bc2Sgc mdb_printf(" %s\n", strbuf); 8274e968bc2Sgc 8284e968bc2Sgc /* dip addr */ 8294e968bc2Sgc mdb_printf(" dip: 0x%x\n", paddr); 8304e968bc2Sgc 8314e968bc2Sgc /* softe_sate */ 8324e968bc2Sgc mdb_snprintf(strbuf, STRLEN, "%s_statep", driver_name); 8334e968bc2Sgc if (mdb_devinfo2statep(paddr, strbuf, &statep) != -1) { 8344e968bc2Sgc mdb_printf(" %s: 0x%x\n", strbuf, statep); 8354e968bc2Sgc } 8364e968bc2Sgc 8374e968bc2Sgc /* error level */ 8384e968bc2Sgc mdb_snprintf(strbuf, STRLEN, "%s_errlevel", driver_name); 8394e968bc2Sgc if (mdb_readvar(&errlevel, strbuf) != -1) { 8404e968bc2Sgc mdb_printf(" %s: 0x%x\n", strbuf, errlevel); 8414e968bc2Sgc } 8424e968bc2Sgc 8434e968bc2Sgc if (strcmp(driver_name, "ehci") == 0) { 8444e968bc2Sgc mdb_arg_t argv[] = { 8454e968bc2Sgc {MDB_TYPE_STRING, {"ehci_state_t"}}, 8464e968bc2Sgc {MDB_TYPE_STRING, {"ehci_root_hub.rh_descr"}} 8474e968bc2Sgc }; 8484e968bc2Sgc mdb_call_dcmd("print", statep, DCMD_ADDRSPEC, 2, argv); 8494e968bc2Sgc } 8504e968bc2Sgc 8514e968bc2Sgc if (strcmp(driver_name, "ohci") == 0) { 8524e968bc2Sgc mdb_arg_t argv[] = { 8534e968bc2Sgc {MDB_TYPE_STRING, {"ohci_state_t"}}, 8544e968bc2Sgc {MDB_TYPE_STRING, {"ohci_root_hub.rh_descr"}} 8554e968bc2Sgc }; 8564e968bc2Sgc mdb_call_dcmd("print", statep, DCMD_ADDRSPEC, 2, argv); 8574e968bc2Sgc } 8584e968bc2Sgc 8594e968bc2Sgc if (strcmp(driver_name, "uhci") == 0) { 8604e968bc2Sgc mdb_arg_t argv[] = { 8614e968bc2Sgc {MDB_TYPE_STRING, {"uhci_state_t"}}, 8624e968bc2Sgc {MDB_TYPE_STRING, {"uhci_root_hub.rh_descr"}} 8634e968bc2Sgc }; 8644e968bc2Sgc mdb_call_dcmd("print", statep, DCMD_ADDRSPEC, 2, argv); 8654e968bc2Sgc } 8664e968bc2Sgc 8674e968bc2Sgc if (strcmp(driver_name, "hubd") == 0) { 8684e968bc2Sgc mdb_arg_t argv[] = { 8694e968bc2Sgc {MDB_TYPE_STRING, {"hubd_t"}}, 870993e3fafSRobert Mustacchi {MDB_TYPE_STRING, {"h_ep1_xdescr.uex_ep"}} 8714e968bc2Sgc }; 8724e968bc2Sgc mdb_call_dcmd("print", statep, DCMD_ADDRSPEC, 2, argv); 8734e968bc2Sgc } 8744e968bc2Sgc 8754e968bc2Sgc if (strcmp(driver_name, "hid") == 0) { 8764e968bc2Sgc hid_state_t hidp; 8774e968bc2Sgc 8784e968bc2Sgc if (mdb_vread(&hidp, sizeof (hid_state_t), statep) != -1) { 8794e968bc2Sgc hidparser_handle hid_report; 8804e968bc2Sgc 8814e968bc2Sgc if (mdb_vread(&hid_report, sizeof (hidparser_handle), 8824e968bc2Sgc (uintptr_t)hidp.hid_report_descr) != -1) { 8834e968bc2Sgc 8844e968bc2Sgc mdb_inc_indent(2); 8854e968bc2Sgc 8864e968bc2Sgc mdb_printf("\n"); 8874e968bc2Sgc prt_usb_hid_item((uintptr_t) 8884e968bc2Sgc hid_report.hidparser_handle_parse_tree); 8894e968bc2Sgc 8904e968bc2Sgc mdb_dec_indent(2); 8914e968bc2Sgc } 8924e968bc2Sgc } 8934e968bc2Sgc } 8944e968bc2Sgc 8954e968bc2Sgc mdb_printf("\n"); 8964e968bc2Sgc 8974e968bc2Sgc return (DCMD_OK); 8984e968bc2Sgc } 8994e968bc2Sgc 9004e968bc2Sgc /* print hid report descriptor */ 9014e968bc2Sgc static void 9024e968bc2Sgc prt_usb_hid_item(uintptr_t paddr) 9034e968bc2Sgc { 9044e968bc2Sgc entity_item_t item; 9054e968bc2Sgc if (mdb_vread(&item, sizeof (entity_item_t), paddr) != -1) { 9064e968bc2Sgc 9074e968bc2Sgc prt_usb_hid_item_attrs((uintptr_t)item.entity_item_attributes); 9084e968bc2Sgc prt_usb_hid_item_params(&item); 9094e968bc2Sgc 9104e968bc2Sgc if (item.info.child) { 9114e968bc2Sgc mdb_inc_indent(4); 9124e968bc2Sgc prt_usb_hid_item((uintptr_t)item.info.child); 9134e968bc2Sgc mdb_dec_indent(4); 9144e968bc2Sgc } 9154e968bc2Sgc 9164e968bc2Sgc if (item.entity_item_right_sibling) { 9174e968bc2Sgc prt_usb_hid_item((uintptr_t) 9184e968bc2Sgc item.entity_item_right_sibling); 9194e968bc2Sgc } 9204e968bc2Sgc } 9214e968bc2Sgc } 9224e968bc2Sgc 9234e968bc2Sgc static void 9244e968bc2Sgc prt_usb_hid_item_params(entity_item_t *item) 9254e968bc2Sgc { 9264e968bc2Sgc switch (item->entity_item_type) { 9274e968bc2Sgc case 0x80: 9284e968bc2Sgc mdb_printf("INPUT "); 9294e968bc2Sgc 9304e968bc2Sgc break; 9314e968bc2Sgc case 0x90: 9324e968bc2Sgc mdb_printf("OUTPUT "); 9334e968bc2Sgc 9344e968bc2Sgc break; 9354e968bc2Sgc case 0xA0: 9364e968bc2Sgc mdb_printf("COLLECTION "); 9374e968bc2Sgc 9384e968bc2Sgc break; 9394e968bc2Sgc case 0xB0: 9404e968bc2Sgc mdb_printf("FEATURE "); 9414e968bc2Sgc 9424e968bc2Sgc break; 9434e968bc2Sgc case 0xC0: 9444e968bc2Sgc mdb_printf("END_COLLECTION "); 9454e968bc2Sgc 9464e968bc2Sgc break; 9474e968bc2Sgc default: 9484e968bc2Sgc mdb_printf("MAIN_ITEM "); 9494e968bc2Sgc 9504e968bc2Sgc break; 9514e968bc2Sgc } 9524e968bc2Sgc 9534e968bc2Sgc prt_usb_hid_item_data((uintptr_t)item->entity_item_params, 9544e968bc2Sgc item->entity_item_params_leng); 9554e968bc2Sgc 9564e968bc2Sgc mdb_printf("\n"); 9574e968bc2Sgc } 9584e968bc2Sgc 9594e968bc2Sgc static void 9604e968bc2Sgc prt_usb_hid_item_attrs(uintptr_t paddr) 9614e968bc2Sgc { 9624e968bc2Sgc entity_attribute_t attr; 9634e968bc2Sgc 9644e968bc2Sgc if (mdb_vread(&attr, sizeof (entity_attribute_t), paddr) != -1) { 9654e968bc2Sgc 9664e968bc2Sgc prt_usb_hid_item_tags(attr.entity_attribute_tag); 9674e968bc2Sgc prt_usb_hid_item_data((uintptr_t)attr.entity_attribute_value, 9684e968bc2Sgc attr.entity_attribute_length); 9694e968bc2Sgc 9704e968bc2Sgc mdb_printf("\n"); 9714e968bc2Sgc 9724e968bc2Sgc if (attr.entity_attribute_next) { 9734e968bc2Sgc prt_usb_hid_item_attrs((uintptr_t) 9744e968bc2Sgc attr.entity_attribute_next); 9754e968bc2Sgc } 9764e968bc2Sgc } 9774e968bc2Sgc } 9784e968bc2Sgc 9794e968bc2Sgc static void 9804e968bc2Sgc prt_usb_hid_item_data(uintptr_t paddr, uint_t len) 9814e968bc2Sgc { 9824e968bc2Sgc char data[4]; 9834e968bc2Sgc int i; 9844e968bc2Sgc 9854e968bc2Sgc if (len > 4) { 9864e968bc2Sgc mdb_warn("Incorrect entity_item_length: 0x%x\n", len); 9874e968bc2Sgc 9884e968bc2Sgc return; 9894e968bc2Sgc } 9904e968bc2Sgc 9914e968bc2Sgc if (mdb_vread(data, len, paddr) != -1) { 9924e968bc2Sgc 9934e968bc2Sgc mdb_printf("( "); 9944e968bc2Sgc for (i = 0; i < len; i++) { 9954e968bc2Sgc mdb_printf("0x%02x ", data[i] & 0xff); 9964e968bc2Sgc } 9974e968bc2Sgc mdb_printf(")"); 9984e968bc2Sgc } 9994e968bc2Sgc } 10004e968bc2Sgc 10014e968bc2Sgc static void 10024e968bc2Sgc prt_usb_hid_item_tags(uint_t tag) 10034e968bc2Sgc { 10044e968bc2Sgc switch (tag) { 10054e968bc2Sgc case 0x04: 10064e968bc2Sgc mdb_printf("usage page "); 10074e968bc2Sgc 10084e968bc2Sgc break; 10094e968bc2Sgc case 0x14: 10104e968bc2Sgc mdb_printf("logical minimum "); 10114e968bc2Sgc 10124e968bc2Sgc break; 10134e968bc2Sgc case 0x24: 10144e968bc2Sgc mdb_printf("logical maximum "); 10154e968bc2Sgc 10164e968bc2Sgc break; 10174e968bc2Sgc case 0x34: 10184e968bc2Sgc mdb_printf("physical minimum "); 10194e968bc2Sgc 10204e968bc2Sgc break; 10214e968bc2Sgc case 0x44: 10224e968bc2Sgc mdb_printf("physical maximum "); 10234e968bc2Sgc 10244e968bc2Sgc break; 10254e968bc2Sgc case 0x54: 10264e968bc2Sgc mdb_printf("exponent "); 10274e968bc2Sgc 10284e968bc2Sgc break; 10294e968bc2Sgc case 0x64: 10304e968bc2Sgc mdb_printf("unit "); 10314e968bc2Sgc 10324e968bc2Sgc break; 10334e968bc2Sgc case 0x74: 10344e968bc2Sgc mdb_printf("report size "); 10354e968bc2Sgc 10364e968bc2Sgc break; 10374e968bc2Sgc case 0x84: 10384e968bc2Sgc mdb_printf("report id "); 10394e968bc2Sgc 10404e968bc2Sgc break; 10414e968bc2Sgc case 0x94: 10424e968bc2Sgc mdb_printf("report count "); 10434e968bc2Sgc 10444e968bc2Sgc break; 10454e968bc2Sgc case 0x08: 10464e968bc2Sgc mdb_printf("usage "); 10474e968bc2Sgc 10484e968bc2Sgc break; 10494e968bc2Sgc case 0x18: 10504e968bc2Sgc mdb_printf("usage min "); 10514e968bc2Sgc 10524e968bc2Sgc break; 10534e968bc2Sgc case 0x28: 10544e968bc2Sgc mdb_printf("usage max "); 10554e968bc2Sgc 10564e968bc2Sgc break; 10574e968bc2Sgc 10584e968bc2Sgc default: 10594e968bc2Sgc mdb_printf("tag "); 10604e968bc2Sgc } 10614e968bc2Sgc } 10624e968bc2Sgc 10634e968bc2Sgc /* print the info required by "-v" */ 10644e968bc2Sgc static int 10654e968bc2Sgc prt_usb_desc(uintptr_t usb_cfg, uint_t cfg_len) 10664e968bc2Sgc { 10674e968bc2Sgc uintptr_t paddr = usb_cfg; 10684e968bc2Sgc uintptr_t pend = usb_cfg + cfg_len; 10694e968bc2Sgc uchar_t desc_type, nlen; 10704e968bc2Sgc usb_if_descr_t usb_if; 10714e968bc2Sgc ulong_t indent = 0; 10724e968bc2Sgc 10734e968bc2Sgc mdb_arg_t argv = {MDB_TYPE_STRING, {"usb_dev_descr_t"}}; 10744e968bc2Sgc 10754e968bc2Sgc if (mdb_vread(&nlen, 1, paddr) == -1) { 10764e968bc2Sgc 10774e968bc2Sgc return (DCMD_ERR); 10784e968bc2Sgc } 10794e968bc2Sgc while ((paddr + nlen <= pend) && (nlen > 0)) { 10804e968bc2Sgc if (mdb_vread(&desc_type, 1, paddr + 1) == -1) { 10814e968bc2Sgc 10824e968bc2Sgc return (DCMD_ERR); 10834e968bc2Sgc } 10844e968bc2Sgc 10854e968bc2Sgc switch (desc_type) { 10864e968bc2Sgc case USB_DESCR_TYPE_DEV: 10874e968bc2Sgc mdb_printf("Device Descriptor\n"); 10884e968bc2Sgc print_struct(paddr, nlen, &argv); 10894e968bc2Sgc 10904e968bc2Sgc break; 10914e968bc2Sgc case USB_DESCR_TYPE_CFG: 10924e968bc2Sgc indent = 4; 10934e968bc2Sgc mdb_inc_indent(indent); 10944e968bc2Sgc mdb_printf("Configuration Descriptor\n"); 10954e968bc2Sgc print_descr(paddr, nlen, usb_cfg_descr, usb_cfg_item); 10964e968bc2Sgc mdb_dec_indent(indent); 10974e968bc2Sgc 10984e968bc2Sgc break; 10994e968bc2Sgc case USB_DESCR_TYPE_STRING: 11004e968bc2Sgc mdb_printf("String Descriptor\n"); 11014e968bc2Sgc print_descr(paddr, nlen, usb_str_descr, usb_str_item); 11024e968bc2Sgc 11034e968bc2Sgc break; 11044e968bc2Sgc case USB_DESCR_TYPE_IF: 11054e968bc2Sgc indent = 8; 11064e968bc2Sgc mdb_inc_indent(indent); 11074e968bc2Sgc mdb_printf("Interface Descriptor\n"); 11084e968bc2Sgc print_descr(paddr, nlen, usb_if_descr, usb_if_item); 11094e968bc2Sgc mdb_dec_indent(indent); 11104e968bc2Sgc mdb_vread(&usb_if, sizeof (usb_if_descr_t), paddr); 11114e968bc2Sgc 11124e968bc2Sgc break; 11134e968bc2Sgc case USB_DESCR_TYPE_EP: 11144e968bc2Sgc indent = 8; 11154e968bc2Sgc mdb_inc_indent(indent); 11164e968bc2Sgc mdb_printf("Endpoint Descriptor\n"); 11174e968bc2Sgc print_descr(paddr, nlen, usb_ep_descr, usb_ep_item); 11184e968bc2Sgc mdb_dec_indent(indent); 11194e968bc2Sgc 1120993e3fafSRobert Mustacchi break; 1121993e3fafSRobert Mustacchi case USB_DESCR_TYPE_SS_EP_COMP: 1122993e3fafSRobert Mustacchi indent = 12; 1123993e3fafSRobert Mustacchi mdb_inc_indent(indent); 1124993e3fafSRobert Mustacchi mdb_printf("SuperSpeed Endpoint Companion " 1125993e3fafSRobert Mustacchi "Descriptor\n"); 1126993e3fafSRobert Mustacchi print_descr(paddr, nlen, usb_ep_ss_comp_descr, 1127993e3fafSRobert Mustacchi usb_ep_ss_comp_item); 1128993e3fafSRobert Mustacchi mdb_dec_indent(indent); 1129993e3fafSRobert Mustacchi 11304e968bc2Sgc break; 11314e968bc2Sgc case USB_DESCR_TYPE_DEV_QLF: 11324e968bc2Sgc mdb_printf("Device_Qualifier Descriptor\n"); 11334e968bc2Sgc print_descr(paddr, nlen, usb_qlf_descr, usb_qlf_item); 11344e968bc2Sgc 11354e968bc2Sgc break; 11364e968bc2Sgc case USB_DESCR_TYPE_OTHER_SPEED_CFG: 11374e968bc2Sgc indent = 4; 11384e968bc2Sgc mdb_inc_indent(indent); 11394e968bc2Sgc mdb_printf("Other_Speed_Configuration Descriptor\n"); 11404e968bc2Sgc print_descr(paddr, nlen, usb_cfg_descr, usb_cfg_item); 11414e968bc2Sgc mdb_dec_indent(indent); 11424e968bc2Sgc 11434e968bc2Sgc break; 11444e968bc2Sgc case USB_DESCR_TYPE_IA: 11454e968bc2Sgc indent = 6; 11464e968bc2Sgc mdb_inc_indent(indent); 11474e968bc2Sgc mdb_printf("Interface_Association Descriptor\n"); 11484e968bc2Sgc print_descr(paddr, nlen, usb_ia_descr, usb_ia_item); 11494e968bc2Sgc mdb_dec_indent(indent); 11504e968bc2Sgc 11514e968bc2Sgc break; 11524e968bc2Sgc case 0x21: /* hid descriptor */ 11534e968bc2Sgc indent = 12; 11544e968bc2Sgc mdb_inc_indent(indent); 1155ff0e937bSRaymond Chen if (usb_if.bInterfaceClass == 0xe0 && 1156ff0e937bSRaymond Chen usb_if.bInterfaceSubClass == 0x02) { 1157ff0e937bSRaymond Chen mdb_printf("WA Descriptor\n"); 1158ff0e937bSRaymond Chen print_descr(paddr, nlen, usb_wa_descr, 1159ff0e937bSRaymond Chen usb_wa_item); 1160*a61ed2ceSHans Rosenfeld } else if (usb_if.bInterfaceClass == USB_CLASS_CCID && 1161*a61ed2ceSHans Rosenfeld usb_if.bInterfaceSubClass == 0x0) { 1162*a61ed2ceSHans Rosenfeld mdb_printf("CCID Descriptor\n"); 1163*a61ed2ceSHans Rosenfeld print_descr(paddr, nlen, usb_ccid_descr, 1164*a61ed2ceSHans Rosenfeld usb_ccid_item); 1165ff0e937bSRaymond Chen } else { 1166ff0e937bSRaymond Chen mdb_printf("HID Descriptor\n"); 1167ff0e937bSRaymond Chen print_descr(paddr, nlen, usb_hid_descr, 1168ff0e937bSRaymond Chen usb_hid_item); 1169ff0e937bSRaymond Chen } 11704e968bc2Sgc mdb_dec_indent(indent); 11714e968bc2Sgc 11724e968bc2Sgc break; 11734e968bc2Sgc case 0x24: /* class specific interfce descriptor */ 11744e968bc2Sgc indent = 12; 11754e968bc2Sgc mdb_inc_indent(indent); 11764e968bc2Sgc if (usb_if.bInterfaceClass == 1 && 11774e968bc2Sgc usb_if.bInterfaceSubClass == 1) { 11784e968bc2Sgc mdb_printf("AudioControl_Interface: "); 11794e968bc2Sgc prt_usb_ac_desc(paddr, nlen); 11804e968bc2Sgc 11814e968bc2Sgc } else if (usb_if.bInterfaceClass == 1 && 11824e968bc2Sgc usb_if.bInterfaceSubClass == 2) { 11834e968bc2Sgc mdb_printf("AudioStream_Interface: "); 11844e968bc2Sgc prt_usb_as_desc(paddr, nlen); 11854e968bc2Sgc 11864e968bc2Sgc } else if (usb_if.bInterfaceClass == 0x0E && 11874e968bc2Sgc usb_if.bInterfaceSubClass == 1) { 11884e968bc2Sgc mdb_printf("VideoControl_Interface: "); 11894e968bc2Sgc prt_usb_vc_desc(paddr, nlen); 11904e968bc2Sgc 11914e968bc2Sgc 11924e968bc2Sgc } else if (usb_if.bInterfaceClass == 0x0E && 11934e968bc2Sgc usb_if.bInterfaceSubClass == 2) { 11944e968bc2Sgc mdb_printf("VideoStream_Interface: "); 11954e968bc2Sgc prt_usb_vs_desc(paddr, nlen); 11964e968bc2Sgc 11974e968bc2Sgc } else { 11984e968bc2Sgc mdb_printf("Unknown_Interface:" 11994e968bc2Sgc "0x%x\n", desc_type); 12004e968bc2Sgc prt_usb_buf(paddr, nlen); 12014e968bc2Sgc } 12024e968bc2Sgc mdb_dec_indent(indent); 12034e968bc2Sgc 12044e968bc2Sgc break; 12054e968bc2Sgc case 0x25: /* class specific endpoint descriptor */ 12064e968bc2Sgc indent = 12; 12074e968bc2Sgc mdb_inc_indent(indent); 12084e968bc2Sgc if (usb_if.bInterfaceClass == 0x01) { 12094e968bc2Sgc mdb_printf("AudioEndpoint:\n"); 12104e968bc2Sgc print_descr(paddr, nlen, 12114e968bc2Sgc usb_as_ep_descr, usb_as_ep_item); 12124e968bc2Sgc 12134e968bc2Sgc } else if (usb_if.bInterfaceClass == 0x0E) { 12144e968bc2Sgc mdb_printf("VideoEndpoint:\n"); 12154e968bc2Sgc print_descr(paddr, nlen, 12164e968bc2Sgc usb_ep_descr, usb_ep_item); 12174e968bc2Sgc 12184e968bc2Sgc } else { 12194e968bc2Sgc mdb_printf("Unknown_Endpoint:" 12204e968bc2Sgc "0x%x\n", desc_type); 12214e968bc2Sgc prt_usb_buf(paddr, nlen); 12224e968bc2Sgc } 12234e968bc2Sgc mdb_dec_indent(indent); 12244e968bc2Sgc 12254e968bc2Sgc break; 12264e968bc2Sgc default: 12274e968bc2Sgc mdb_inc_indent(indent); 12284e968bc2Sgc mdb_printf("Unknown Descriptor: 0x%x\n", desc_type); 12294e968bc2Sgc prt_usb_buf(paddr, nlen); 12304e968bc2Sgc mdb_dec_indent(indent); 12314e968bc2Sgc 12324e968bc2Sgc break; 12334e968bc2Sgc } 12344e968bc2Sgc 12354e968bc2Sgc paddr += nlen; 12364e968bc2Sgc if (mdb_vread(&nlen, 1, paddr) == -1) { 12374e968bc2Sgc 12384e968bc2Sgc return (DCMD_ERR); 12394e968bc2Sgc } 12404e968bc2Sgc }; 12414e968bc2Sgc 12424e968bc2Sgc return (DCMD_OK); 12434e968bc2Sgc } 12444e968bc2Sgc 12454e968bc2Sgc 12464e968bc2Sgc /* print audio class specific control descriptor */ 12474e968bc2Sgc static int 12484e968bc2Sgc prt_usb_ac_desc(uintptr_t addr, uint_t nlen) 12494e968bc2Sgc { 12504e968bc2Sgc uchar_t sub_type; 12514e968bc2Sgc 12524e968bc2Sgc if (mdb_vread(&sub_type, 1, addr + 2) == -1) { 12534e968bc2Sgc 12544e968bc2Sgc return (DCMD_ERR); 12554e968bc2Sgc } 12564e968bc2Sgc switch (sub_type) { 12574e968bc2Sgc case 0x01: 12584e968bc2Sgc mdb_printf("header Descriptor\n"); 12594e968bc2Sgc print_descr(addr, nlen, 12604e968bc2Sgc usb_ac_header_descr, usb_ac_header_item); 12614e968bc2Sgc 12624e968bc2Sgc break; 12634e968bc2Sgc case 0x02: 12644e968bc2Sgc mdb_printf("input_terminal Descriptor\n"); 12654e968bc2Sgc print_descr(addr, nlen, 12664e968bc2Sgc usb_ac_input_term_descr, usb_ac_input_term_item); 12674e968bc2Sgc 12684e968bc2Sgc break; 12694e968bc2Sgc case 0x03: 12704e968bc2Sgc mdb_printf("output_terminal Descriptor\n"); 12714e968bc2Sgc print_descr(addr, nlen, 12724e968bc2Sgc usb_ac_output_term_descr, usb_ac_output_term_item); 12734e968bc2Sgc 12744e968bc2Sgc break; 12754e968bc2Sgc case 0x04: 12764e968bc2Sgc mdb_printf("mixer_unit Descriptor\n"); 12774e968bc2Sgc print_descr(addr, nlen, 12784e968bc2Sgc usb_ac_mixer_descr, usb_ac_mixer_item); 12794e968bc2Sgc 12804e968bc2Sgc break; 12814e968bc2Sgc case 0x05: 12824e968bc2Sgc mdb_printf("selector_unit Descriptor\n"); 12834e968bc2Sgc print_descr(addr, nlen, 12844e968bc2Sgc usb_ac_selector_descr, usb_ac_selector_item); 12854e968bc2Sgc 12864e968bc2Sgc break; 12874e968bc2Sgc case 0x06: 12884e968bc2Sgc mdb_printf("feature_unit Descriptor\n"); 12894e968bc2Sgc print_descr(addr, nlen, 12904e968bc2Sgc usb_ac_feature_descr, usb_ac_feature_item); 12914e968bc2Sgc 12924e968bc2Sgc break; 12934e968bc2Sgc case 0x07: 12944e968bc2Sgc mdb_printf("processing_unit Descriptor\n"); 12954e968bc2Sgc print_descr(addr, nlen, 12964e968bc2Sgc usb_ac_processing_descr, usb_ac_processing_item); 12974e968bc2Sgc 12984e968bc2Sgc break; 12994e968bc2Sgc case 0x08: 13004e968bc2Sgc mdb_printf("extension_unit Descriptor\n"); 13014e968bc2Sgc print_descr(addr, nlen, 13024e968bc2Sgc usb_ac_extension_descr, usb_ac_extension_item); 13034e968bc2Sgc 13044e968bc2Sgc break; 13054e968bc2Sgc default: 13064e968bc2Sgc mdb_printf("Unknown AC sub-descriptor 0x%x\n", sub_type); 13074e968bc2Sgc prt_usb_buf(addr, nlen); 13084e968bc2Sgc 13094e968bc2Sgc break; 13104e968bc2Sgc } 13114e968bc2Sgc 13124e968bc2Sgc return (DCMD_OK); 13134e968bc2Sgc } 13144e968bc2Sgc 13154e968bc2Sgc /* print audio class specific stream descriptor */ 13164e968bc2Sgc static int 13174e968bc2Sgc prt_usb_as_desc(uintptr_t addr, uint_t nlen) 13184e968bc2Sgc { 13194e968bc2Sgc uchar_t sub_type; 13204e968bc2Sgc 13214e968bc2Sgc if (mdb_vread(&sub_type, 1, addr + 2) == -1) { 13224e968bc2Sgc 13234e968bc2Sgc return (DCMD_ERR); 13244e968bc2Sgc } 13254e968bc2Sgc switch (sub_type) { 13264e968bc2Sgc case 0x01: 13274e968bc2Sgc mdb_printf("general_interface Descriptor\n"); 13284e968bc2Sgc print_descr(addr, nlen, 13294e968bc2Sgc usb_as_if_descr, usb_as_if_item); 13304e968bc2Sgc 13314e968bc2Sgc break; 13324e968bc2Sgc case 0x02: 13334e968bc2Sgc mdb_printf("format_type Descriptor\n"); 13344e968bc2Sgc print_descr(addr, nlen, 13354e968bc2Sgc usb_as_format_descr, usb_as_format_item); 13364e968bc2Sgc 13374e968bc2Sgc break; 13384e968bc2Sgc default: 13394e968bc2Sgc mdb_printf("Unknown AS sub-descriptor 0x%x\n", sub_type); 13404e968bc2Sgc prt_usb_buf(addr, nlen); 13414e968bc2Sgc 13424e968bc2Sgc break; 13434e968bc2Sgc } 13444e968bc2Sgc 13454e968bc2Sgc return (DCMD_OK); 13464e968bc2Sgc } 13474e968bc2Sgc 13484e968bc2Sgc /* print video class specific control descriptor */ 13494e968bc2Sgc static int 13504e968bc2Sgc prt_usb_vc_desc(uintptr_t addr, uint_t nlen) 13514e968bc2Sgc { 13524e968bc2Sgc uchar_t sub_type; 13534e968bc2Sgc 13544e968bc2Sgc if (mdb_vread(&sub_type, 1, addr + 2) == -1) { 13554e968bc2Sgc 13564e968bc2Sgc return (DCMD_ERR); 13574e968bc2Sgc } 13584e968bc2Sgc switch (sub_type) { 13594e968bc2Sgc case 0x01: 13604e968bc2Sgc mdb_printf("header Descriptor\n"); 13614e968bc2Sgc print_descr(addr, nlen, 13624e968bc2Sgc usb_vc_header_descr, usb_vc_header_item); 13634e968bc2Sgc 13644e968bc2Sgc break; 13654e968bc2Sgc case 0x02: 13664e968bc2Sgc mdb_printf("input_terminal Descriptor\n"); 13674e968bc2Sgc print_descr(addr, nlen, 13684e968bc2Sgc usb_vc_input_term_descr, usb_vc_input_term_item); 13694e968bc2Sgc 13704e968bc2Sgc break; 13714e968bc2Sgc case 0x03: 13724e968bc2Sgc mdb_printf("output_terminal Descriptor\n"); 13734e968bc2Sgc print_descr(addr, nlen, 13744e968bc2Sgc usb_vc_output_term_descr, usb_vc_output_term_item); 13754e968bc2Sgc 13764e968bc2Sgc break; 13774e968bc2Sgc case 0x04: 13784e968bc2Sgc mdb_printf("selector_unit Descriptor\n"); 13794e968bc2Sgc print_descr(addr, nlen, 13804e968bc2Sgc usb_vc_selector_descr, usb_vc_selector_item); 13814e968bc2Sgc 13824e968bc2Sgc break; 13834e968bc2Sgc case 0x05: 13844e968bc2Sgc mdb_printf("processing_unit Descriptor\n"); 13854e968bc2Sgc print_descr(addr, nlen, 13864e968bc2Sgc usb_vc_processing_descr, usb_vc_processing_item); 13874e968bc2Sgc 13884e968bc2Sgc break; 13894e968bc2Sgc case 0x06: 13904e968bc2Sgc mdb_printf("extension_unit Descriptor\n"); 13914e968bc2Sgc print_descr(addr, nlen, 13924e968bc2Sgc usb_vc_extension_descr, usb_vc_extension_item); 13934e968bc2Sgc 13944e968bc2Sgc break; 13954e968bc2Sgc default: 13964e968bc2Sgc mdb_printf("Unknown VC sub-descriptor 0x%x\n", sub_type); 13974e968bc2Sgc prt_usb_buf(addr, nlen); 13984e968bc2Sgc 13994e968bc2Sgc break; 14004e968bc2Sgc } 14014e968bc2Sgc 14024e968bc2Sgc return (DCMD_OK); 14034e968bc2Sgc } 14044e968bc2Sgc 14054e968bc2Sgc /* print video class specific stream descriptor */ 14064e968bc2Sgc static int 14074e968bc2Sgc prt_usb_vs_desc(uintptr_t addr, uint_t nlen) 14084e968bc2Sgc { 14094e968bc2Sgc uchar_t sub_type; 14104e968bc2Sgc 14114e968bc2Sgc if (mdb_vread(&sub_type, 1, addr + 2) == -1) { 14124e968bc2Sgc 14134e968bc2Sgc return (DCMD_ERR); 14144e968bc2Sgc } 14154e968bc2Sgc switch (sub_type) { 14164e968bc2Sgc case 0x01: 14174e968bc2Sgc mdb_printf("input_header Descriptor\n"); 14184e968bc2Sgc print_descr(addr, nlen, 14194e968bc2Sgc usb_vs_input_header_descr, usb_vs_input_header_item); 14204e968bc2Sgc 14214e968bc2Sgc break; 14224e968bc2Sgc case 0x02: 14234e968bc2Sgc mdb_printf("output_header Descriptor\n"); 14244e968bc2Sgc print_descr(addr, nlen, 14254e968bc2Sgc usb_vs_output_header_descr, usb_vs_output_header_item); 14264e968bc2Sgc 14274e968bc2Sgc break; 14284e968bc2Sgc case 0x03: 14294e968bc2Sgc mdb_printf("still_image_frame Descriptor\n"); 14304e968bc2Sgc print_descr(addr, nlen, 14314e968bc2Sgc usb_vs_still_image_descr, usb_vs_still_image_item); 14324e968bc2Sgc 14334e968bc2Sgc break; 14344e968bc2Sgc case 0x04: 14354e968bc2Sgc mdb_printf("format_uncompressed Descriptor\n"); 14364e968bc2Sgc print_descr(addr, nlen, 14374e968bc2Sgc usb_vs_format_uncps_descr, usb_vs_format_uncps_item); 14384e968bc2Sgc 14394e968bc2Sgc break; 14404e968bc2Sgc case 0x05: 14414e968bc2Sgc mdb_printf("frame_uncompressed Descriptor\n"); 14424e968bc2Sgc print_descr(addr, nlen, 14434e968bc2Sgc usb_vs_2frame_descr, usb_vs_2frame_item); 14444e968bc2Sgc 14454e968bc2Sgc break; 14464e968bc2Sgc case 0x06: 14474e968bc2Sgc mdb_printf("format_mjpeg Descriptor\n"); 14484e968bc2Sgc print_descr(addr, nlen, 14494e968bc2Sgc usb_vs_format_mjpeg_descr, usb_vs_format_mjpeg_item); 14504e968bc2Sgc 14514e968bc2Sgc break; 14524e968bc2Sgc case 0x07: 14534e968bc2Sgc mdb_printf("frame_mjpeg Descriptor\n"); 14544e968bc2Sgc print_descr(addr, nlen, 14554e968bc2Sgc usb_vs_2frame_descr, usb_vs_2frame_item); 14564e968bc2Sgc 14574e968bc2Sgc break; 14584e968bc2Sgc case 0x0A: 14594e968bc2Sgc mdb_printf("format_mpeg2ts Descriptor\n"); 14604e968bc2Sgc print_descr(addr, nlen, 14614e968bc2Sgc usb_vs_format_mp2ts_descr, usb_vs_format_mp2ts_item); 14624e968bc2Sgc 14634e968bc2Sgc break; 14644e968bc2Sgc case 0x0C: 14654e968bc2Sgc mdb_printf("format_dv Descriptor\n"); 14664e968bc2Sgc print_descr(addr, nlen, 14674e968bc2Sgc usb_vs_format_dv_descr, usb_vs_format_dv_item); 14684e968bc2Sgc 14694e968bc2Sgc break; 14704e968bc2Sgc case 0x0D: 14714e968bc2Sgc mdb_printf("color_matching Descriptor\n"); 14724e968bc2Sgc print_descr(addr, nlen, 14734e968bc2Sgc usb_vs_color_matching_descr, usb_vs_color_matching_item); 14744e968bc2Sgc 14754e968bc2Sgc break; 14764e968bc2Sgc default: 14774e968bc2Sgc mdb_printf("Unknown VS sub-descriptor 0x%x\n", sub_type); 14784e968bc2Sgc prt_usb_buf(addr, nlen); 14794e968bc2Sgc 14804e968bc2Sgc break; 14814e968bc2Sgc } 14824e968bc2Sgc 14834e968bc2Sgc return (DCMD_OK); 14844e968bc2Sgc } 14854e968bc2Sgc 14864e968bc2Sgc /* parse and print the descriptor items */ 14874e968bc2Sgc static int 14884e968bc2Sgc print_descr(uintptr_t addr, uint_t nlen, usb_descr_item_t *item, uint_t nitem) 14894e968bc2Sgc { 14904e968bc2Sgc int i, j; 14914e968bc2Sgc uint8_t buf[8]; 14924e968bc2Sgc uint64_t value; 14934e968bc2Sgc uintptr_t paddr = addr; 14944e968bc2Sgc usb_descr_item_t *p = item; 14954e968bc2Sgc 14964e968bc2Sgc mdb_printf("{"); 14974e968bc2Sgc for (i = 0; (i < nitem) && (paddr < addr + nlen); i++) { 14984e968bc2Sgc mdb_printf("\n %s =", p->name); 14994e968bc2Sgc switch (p->nlen) { 15004e968bc2Sgc case 1: /* uint8_t */ 15014e968bc2Sgc if (mdb_vread(buf, 1, paddr) == -1) { 15024e968bc2Sgc 15034e968bc2Sgc return (DCMD_ERR); 15044e968bc2Sgc } 15054e968bc2Sgc value = buf[0]; 15064e968bc2Sgc 15074e968bc2Sgc break; 15084e968bc2Sgc case 2: /* uint16_t */ 15094e968bc2Sgc if (mdb_vread(buf, 2, paddr) == -1) { 15104e968bc2Sgc 15114e968bc2Sgc return (DCMD_ERR); 15124e968bc2Sgc } 15134e968bc2Sgc value = buf[0] | (buf[1] << 8); 15144e968bc2Sgc 15154e968bc2Sgc break; 15164e968bc2Sgc case 4: /* uint32_t */ 15174e968bc2Sgc if (mdb_vread(buf, 4, paddr) == -1) { 15184e968bc2Sgc 15194e968bc2Sgc return (DCMD_ERR); 15204e968bc2Sgc } 15214e968bc2Sgc value = buf[0] | (buf[1] << 8) | 1522ff0e937bSRaymond Chen (buf[2] << 16) | (buf[3] << 24); 15234e968bc2Sgc 15244e968bc2Sgc break; 15254e968bc2Sgc case 8: /* uint64_t */ 15264e968bc2Sgc if (mdb_vread(buf, 8, paddr) == -1) { 15274e968bc2Sgc 15284e968bc2Sgc return (DCMD_ERR); 15294e968bc2Sgc } 15304e968bc2Sgc value = buf[4] | (buf[5] << 8) | 1531ff0e937bSRaymond Chen (buf[6] << 16) | (buf[7] << 24); 15324e968bc2Sgc value = buf[0] | (buf[1] << 8) | 1533ff0e937bSRaymond Chen (buf[2] << 16) | (buf[3] << 24) | 1534ff0e937bSRaymond Chen (value << 32); 15354e968bc2Sgc 15364e968bc2Sgc break; 15374e968bc2Sgc default: /* byte array */ 15384e968bc2Sgc value = 0; 15394e968bc2Sgc /* print an array instead of a value */ 15404e968bc2Sgc for (j = 0; j < p->nlen - BYTE_OFFSET; j++) { 15414e968bc2Sgc if (mdb_vread(buf, 1, paddr + j) == -1) { 15424e968bc2Sgc 15434e968bc2Sgc break; 15444e968bc2Sgc } 15454e968bc2Sgc mdb_printf(" 0x%x", buf[0]); 15464e968bc2Sgc } 15474e968bc2Sgc 15484e968bc2Sgc break; 15494e968bc2Sgc } 15504e968bc2Sgc 15514e968bc2Sgc if (p->nlen > BYTE_OFFSET) { 15524e968bc2Sgc paddr += p->nlen - BYTE_OFFSET; 15534e968bc2Sgc } else { 15544e968bc2Sgc mdb_printf(" 0x%x", value); 15554e968bc2Sgc paddr += p->nlen; 15564e968bc2Sgc } 15574e968bc2Sgc 15584e968bc2Sgc p++; 15594e968bc2Sgc } 15604e968bc2Sgc 15614e968bc2Sgc /* print the unresolved bytes */ 15624e968bc2Sgc if (paddr < addr + nlen) { 15634e968bc2Sgc mdb_printf("\n ... ="); 15644e968bc2Sgc } 15654e968bc2Sgc while (paddr < addr + nlen) { 15664e968bc2Sgc if (mdb_vread(buf, 1, paddr++) == -1) { 15674e968bc2Sgc 15684e968bc2Sgc break; 15694e968bc2Sgc } 15704e968bc2Sgc mdb_printf(" 0x%x", buf[0]); 15714e968bc2Sgc } 15724e968bc2Sgc mdb_printf("\n}\n"); 15734e968bc2Sgc 15744e968bc2Sgc return (DCMD_OK); 15754e968bc2Sgc } 15764e968bc2Sgc 15774e968bc2Sgc /* print the buffer as a struct */ 15784e968bc2Sgc static int 15794e968bc2Sgc print_struct(uintptr_t addr, uint_t nlen, mdb_arg_t *arg) 15804e968bc2Sgc { 15814e968bc2Sgc mdb_ctf_id_t id; 15824e968bc2Sgc if (mdb_ctf_lookup_by_name(arg->a_un.a_str, &id) == 0) { 15834e968bc2Sgc 15844e968bc2Sgc mdb_call_dcmd("print", addr, DCMD_ADDRSPEC, 1, arg); 15854e968bc2Sgc } else { 15864e968bc2Sgc 15874e968bc2Sgc prt_usb_buf(addr, nlen); 15884e968bc2Sgc } 15894e968bc2Sgc 15904e968bc2Sgc return (DCMD_OK); 15914e968bc2Sgc } 15924e968bc2Sgc 15934e968bc2Sgc /* print the buffer as a byte array */ 15944e968bc2Sgc static int 15954e968bc2Sgc prt_usb_buf(uintptr_t addr, uint_t nlen) 15964e968bc2Sgc { 15974e968bc2Sgc int i; 15984e968bc2Sgc uchar_t val; 15994e968bc2Sgc 16004e968bc2Sgc mdb_printf("{\n"); 16014e968bc2Sgc for (i = 0; i < nlen; i++) { 16024e968bc2Sgc if (mdb_vread(&val, 1, addr + i) == -1) { 16034e968bc2Sgc 16044e968bc2Sgc break; 16054e968bc2Sgc } 16064e968bc2Sgc mdb_printf("%02x ", val); 16074e968bc2Sgc } 16084e968bc2Sgc if (nlen) { 16094e968bc2Sgc mdb_printf("\n"); 16104e968bc2Sgc } 16114e968bc2Sgc mdb_printf("}\n"); 16124e968bc2Sgc 16134e968bc2Sgc return (DCMD_OK); 16144e968bc2Sgc } 1615