xref: /titanic_50/usr/src/cmd/mdb/common/modules/genunix/hotplug.c (revision 269473047d747f7815af570197e4ef7322d3632c)
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 *
ddihp_get_cn_state(ddi_hp_cn_state_t state)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
hotplug_print(uintptr_t addr,struct dev_info * dev,devinfo_cb_data_t * data)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
hotplug_help(void)100 hotplug_help(void)
101 {
102 	mdb_printf("Switches:\n"
103 	    "  -p   only print the physical hotplug connectors\n");
104 }
105 
106 int
hotplug(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)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 	if (mdb_getopts(argc, argv,
118 	    'p', MDB_OPT_SETBITS, DEVINFO_HP_PHYSICAL, &data.di_flags, NULL)
119 	    != argc)
120 		return (DCMD_USAGE);
121 
122 	if (DCMD_HDRSPEC(flags)) {
123 		mdb_printf("%<u>%?s %?s %-12s %-15s %-15s%</u>\n",
124 		    "PARENT_DEVINFO", "HANDLE", "STATE", "TYPE", "CN_NAME");
125 	}
126 
127 	if ((flags & DCMD_ADDRSPEC) == 0) {
128 		data.di_flags |= DEVINFO_PARENT | DEVINFO_CHILD;
129 
130 		if (mdb_readvar(&devinfo_root, "top_devinfo") == -1) {
131 			mdb_warn("failed to read 'top_devinfo'");
132 			return (NULL);
133 		}
134 
135 		data.di_base = devinfo_root;
136 		status = mdb_pwalk("devinfo", (mdb_walk_cb_t)hotplug_print,
137 		    &data, devinfo_root);
138 		if (status == -1) {
139 			mdb_warn("couldn't walk devinfo tree");
140 			return (DCMD_ERR);
141 		}
142 		return (DCMD_OK);
143 	}
144 
145 	if (mdb_vread(&hdl, sizeof (ddi_hp_cn_handle_t), (uintptr_t)addr)
146 	    == -1) {
147 		mdb_warn("Failed to read hdlp!\n");
148 		return (DCMD_ERR);
149 	}
150 	if (mdb_readstr(cn_type, sizeof (cn_type),
151 	    (uintptr_t)hdl.cn_info.cn_type_str) == -1) {
152 		mdb_warn("Failed to read cn_type!\n");
153 		return (DCMD_ERR);
154 	}
155 	if (mdb_readstr(cn_name, sizeof (cn_name),
156 	    (uintptr_t)hdl.cn_info.cn_name) == -1) {
157 		mdb_warn("Failed to read cn_name!\n");
158 		return (DCMD_ERR);
159 	}
160 	mdb_printf("%?p %?p %-12s %-15s %-15s\n", hdl.cn_dip, addr,
161 	    ddihp_get_cn_state(hdl.cn_info.cn_state), cn_type, cn_name);
162 
163 	return (DCMD_OK);
164 }
165