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 *
ddihp_get_cn_state(ddi_hp_cn_state_t state)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
hotplug_print(uintptr_t addr,struct dev_info * dev,devinfo_cb_data_t * data)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
hotplug_help(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
hotplug(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)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