xref: /illumos-gate/usr/src/cmd/mdb/common/modules/genunix/hotplug.c (revision 892ad1623e11186cba8b2eb40d70318d2cb89605)
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 (0);
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