xref: /titanic_51/usr/src/cmd/mdb/common/modules/genunix/hotplug.c (revision 269473047d747f7815af570197e4ef7322d3632c)
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