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