1*26947304SEvan Yan /* 2*26947304SEvan Yan * CDDL HEADER START 3*26947304SEvan Yan * 4*26947304SEvan Yan * The contents of this file are subject to the terms of the 5*26947304SEvan Yan * Common Development and Distribution License (the "License"). 6*26947304SEvan Yan * You may not use this file except in compliance with the License. 7*26947304SEvan Yan * 8*26947304SEvan Yan * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*26947304SEvan Yan * or http://www.opensolaris.org/os/licensing. 10*26947304SEvan Yan * See the License for the specific language governing permissions 11*26947304SEvan Yan * and limitations under the License. 12*26947304SEvan Yan * 13*26947304SEvan Yan * When distributing Covered Code, include this CDDL HEADER in each 14*26947304SEvan Yan * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*26947304SEvan Yan * If applicable, add the following below this CDDL HEADER, with the 16*26947304SEvan Yan * fields enclosed by brackets "[]" replaced with your own identifying 17*26947304SEvan Yan * information: Portions Copyright [yyyy] [name of copyright owner] 18*26947304SEvan Yan * 19*26947304SEvan Yan * CDDL HEADER END 20*26947304SEvan Yan */ 21*26947304SEvan Yan /* 22*26947304SEvan Yan * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23*26947304SEvan Yan * Use is subject to license terms. 24*26947304SEvan Yan */ 25*26947304SEvan Yan 26*26947304SEvan Yan #include <sys/mdb_modapi.h> 27*26947304SEvan Yan #include <sys/proc.h> 28*26947304SEvan Yan #include <sys/types.h> 29*26947304SEvan Yan #include <sys/sunddi.h> 30*26947304SEvan Yan #include <sys/ddi_hp.h> 31*26947304SEvan Yan #include "devinfo.h" 32*26947304SEvan Yan 33*26947304SEvan Yan static char * 34*26947304SEvan Yan ddihp_get_cn_state(ddi_hp_cn_state_t state) 35*26947304SEvan Yan { 36*26947304SEvan Yan switch (state) { 37*26947304SEvan Yan case DDI_HP_CN_STATE_EMPTY: 38*26947304SEvan Yan return ("Empty"); 39*26947304SEvan Yan case DDI_HP_CN_STATE_PRESENT: 40*26947304SEvan Yan return ("Present"); 41*26947304SEvan Yan case DDI_HP_CN_STATE_POWERED: 42*26947304SEvan Yan return ("Powered"); 43*26947304SEvan Yan case DDI_HP_CN_STATE_ENABLED: 44*26947304SEvan Yan return ("Enabled"); 45*26947304SEvan Yan case DDI_HP_CN_STATE_PORT_EMPTY: 46*26947304SEvan Yan return ("Port_Empty"); 47*26947304SEvan Yan case DDI_HP_CN_STATE_PORT_PRESENT: 48*26947304SEvan Yan return ("Port_Present"); 49*26947304SEvan Yan case DDI_HP_CN_STATE_OFFLINE: 50*26947304SEvan Yan return ("Offline"); 51*26947304SEvan Yan case DDI_HP_CN_STATE_ATTACHED: 52*26947304SEvan Yan return ("Attached"); 53*26947304SEvan Yan case DDI_HP_CN_STATE_MAINTENANCE: 54*26947304SEvan Yan return ("Maintenance"); 55*26947304SEvan Yan case DDI_HP_CN_STATE_ONLINE: 56*26947304SEvan Yan return ("Online"); 57*26947304SEvan Yan default: 58*26947304SEvan Yan return ("Unknown"); 59*26947304SEvan Yan } 60*26947304SEvan Yan } 61*26947304SEvan Yan 62*26947304SEvan Yan /*ARGSUSED*/ 63*26947304SEvan Yan static int 64*26947304SEvan Yan hotplug_print(uintptr_t addr, struct dev_info *dev, devinfo_cb_data_t *data) 65*26947304SEvan Yan { 66*26947304SEvan Yan ddi_hp_cn_handle_t hdl; 67*26947304SEvan Yan uintptr_t hdlp = (uintptr_t)dev->devi_hp_hdlp; 68*26947304SEvan Yan char cn_type[15]; 69*26947304SEvan Yan char cn_name[15]; 70*26947304SEvan Yan 71*26947304SEvan Yan while (hdlp) { 72*26947304SEvan Yan if (mdb_vread(&hdl, sizeof (ddi_hp_cn_handle_t), hdlp) == -1) { 73*26947304SEvan Yan mdb_warn("Failed to read hdlp!\n"); 74*26947304SEvan Yan return (DCMD_ERR); 75*26947304SEvan Yan } 76*26947304SEvan Yan 77*26947304SEvan Yan if (!(data->di_flags & DEVINFO_HP_PHYSICAL) || 78*26947304SEvan Yan hdl.cn_info.cn_type != DDI_HP_CN_TYPE_VIRTUAL_PORT) { 79*26947304SEvan Yan if (mdb_readstr(cn_type, sizeof (cn_type), 80*26947304SEvan Yan (uintptr_t)hdl.cn_info.cn_type_str) == -1) { 81*26947304SEvan Yan mdb_warn("Failed to read cn_type!\n"); 82*26947304SEvan Yan return (DCMD_ERR); 83*26947304SEvan Yan } 84*26947304SEvan Yan if (mdb_readstr(cn_name, sizeof (cn_name), 85*26947304SEvan Yan (uintptr_t)hdl.cn_info.cn_name) == -1) { 86*26947304SEvan Yan mdb_warn("Failed to read cn_name!\n"); 87*26947304SEvan Yan return (DCMD_ERR); 88*26947304SEvan Yan } 89*26947304SEvan Yan mdb_printf("%?p %?p %-12s %-15s %-15s\n", hdl.cn_dip, 90*26947304SEvan Yan hdlp, ddihp_get_cn_state(hdl.cn_info.cn_state), 91*26947304SEvan Yan cn_type, cn_name); 92*26947304SEvan Yan } 93*26947304SEvan Yan hdlp = (uintptr_t)hdl.next; 94*26947304SEvan Yan }; 95*26947304SEvan Yan 96*26947304SEvan Yan return (WALK_NEXT); 97*26947304SEvan Yan } 98*26947304SEvan Yan 99*26947304SEvan Yan void 100*26947304SEvan Yan hotplug_help(void) 101*26947304SEvan Yan { 102*26947304SEvan Yan mdb_printf("Switches:\n" 103*26947304SEvan Yan " -p only print the physical hotplug connectors\n"); 104*26947304SEvan Yan } 105*26947304SEvan Yan 106*26947304SEvan Yan int 107*26947304SEvan Yan hotplug(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 108*26947304SEvan Yan { 109*26947304SEvan Yan devinfo_cb_data_t data; 110*26947304SEvan Yan uintptr_t devinfo_root; /* Address of root of devinfo tree */ 111*26947304SEvan Yan ddi_hp_cn_handle_t hdl; 112*26947304SEvan Yan char cn_type[15]; 113*26947304SEvan Yan char cn_name[15]; 114*26947304SEvan Yan int status; 115*26947304SEvan Yan 116*26947304SEvan Yan data.di_flags = 0; 117*26947304SEvan Yan if (mdb_getopts(argc, argv, 118*26947304SEvan Yan 'p', MDB_OPT_SETBITS, DEVINFO_HP_PHYSICAL, &data.di_flags, NULL) 119*26947304SEvan Yan != argc) 120*26947304SEvan Yan return (DCMD_USAGE); 121*26947304SEvan Yan 122*26947304SEvan Yan if (DCMD_HDRSPEC(flags)) { 123*26947304SEvan Yan mdb_printf("%<u>%?s %?s %-12s %-15s %-15s%</u>\n", 124*26947304SEvan Yan "PARENT_DEVINFO", "HANDLE", "STATE", "TYPE", "CN_NAME"); 125*26947304SEvan Yan } 126*26947304SEvan Yan 127*26947304SEvan Yan if ((flags & DCMD_ADDRSPEC) == 0) { 128*26947304SEvan Yan data.di_flags |= DEVINFO_PARENT | DEVINFO_CHILD; 129*26947304SEvan Yan 130*26947304SEvan Yan if (mdb_readvar(&devinfo_root, "top_devinfo") == -1) { 131*26947304SEvan Yan mdb_warn("failed to read 'top_devinfo'"); 132*26947304SEvan Yan return (NULL); 133*26947304SEvan Yan } 134*26947304SEvan Yan 135*26947304SEvan Yan data.di_base = devinfo_root; 136*26947304SEvan Yan status = mdb_pwalk("devinfo", (mdb_walk_cb_t)hotplug_print, 137*26947304SEvan Yan &data, devinfo_root); 138*26947304SEvan Yan if (status == -1) { 139*26947304SEvan Yan mdb_warn("couldn't walk devinfo tree"); 140*26947304SEvan Yan return (DCMD_ERR); 141*26947304SEvan Yan } 142*26947304SEvan Yan return (DCMD_OK); 143*26947304SEvan Yan } 144*26947304SEvan Yan 145*26947304SEvan Yan if (mdb_vread(&hdl, sizeof (ddi_hp_cn_handle_t), (uintptr_t)addr) 146*26947304SEvan Yan == -1) { 147*26947304SEvan Yan mdb_warn("Failed to read hdlp!\n"); 148*26947304SEvan Yan return (DCMD_ERR); 149*26947304SEvan Yan } 150*26947304SEvan Yan if (mdb_readstr(cn_type, sizeof (cn_type), 151*26947304SEvan Yan (uintptr_t)hdl.cn_info.cn_type_str) == -1) { 152*26947304SEvan Yan mdb_warn("Failed to read cn_type!\n"); 153*26947304SEvan Yan return (DCMD_ERR); 154*26947304SEvan Yan } 155*26947304SEvan Yan if (mdb_readstr(cn_name, sizeof (cn_name), 156*26947304SEvan Yan (uintptr_t)hdl.cn_info.cn_name) == -1) { 157*26947304SEvan Yan mdb_warn("Failed to read cn_name!\n"); 158*26947304SEvan Yan return (DCMD_ERR); 159*26947304SEvan Yan } 160*26947304SEvan Yan mdb_printf("%?p %?p %-12s %-15s %-15s\n", hdl.cn_dip, addr, 161*26947304SEvan Yan ddihp_get_cn_state(hdl.cn_info.cn_state), cn_type, cn_name); 162*26947304SEvan Yan 163*26947304SEvan Yan return (DCMD_OK); 164*26947304SEvan Yan } 165