1*13101SVenki.Rajagopalan@Sun.COM /*
2*13101SVenki.Rajagopalan@Sun.COM * CDDL HEADER START
3*13101SVenki.Rajagopalan@Sun.COM *
4*13101SVenki.Rajagopalan@Sun.COM * The contents of this file are subject to the terms of the
5*13101SVenki.Rajagopalan@Sun.COM * Common Development and Distribution License (the "License").
6*13101SVenki.Rajagopalan@Sun.COM * You may not use this file except in compliance with the License.
7*13101SVenki.Rajagopalan@Sun.COM *
8*13101SVenki.Rajagopalan@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*13101SVenki.Rajagopalan@Sun.COM * or http://www.opensolaris.org/os/licensing.
10*13101SVenki.Rajagopalan@Sun.COM * See the License for the specific language governing permissions
11*13101SVenki.Rajagopalan@Sun.COM * and limitations under the License.
12*13101SVenki.Rajagopalan@Sun.COM *
13*13101SVenki.Rajagopalan@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
14*13101SVenki.Rajagopalan@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*13101SVenki.Rajagopalan@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
16*13101SVenki.Rajagopalan@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*13101SVenki.Rajagopalan@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*13101SVenki.Rajagopalan@Sun.COM *
19*13101SVenki.Rajagopalan@Sun.COM * CDDL HEADER END
20*13101SVenki.Rajagopalan@Sun.COM */
21*13101SVenki.Rajagopalan@Sun.COM
22*13101SVenki.Rajagopalan@Sun.COM /*
23*13101SVenki.Rajagopalan@Sun.COM * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24*13101SVenki.Rajagopalan@Sun.COM */
25*13101SVenki.Rajagopalan@Sun.COM
26*13101SVenki.Rajagopalan@Sun.COM #include <sys/types.h>
27*13101SVenki.Rajagopalan@Sun.COM #include <sys/kmem.h>
28*13101SVenki.Rajagopalan@Sun.COM #include <sys/ksynch.h>
29*13101SVenki.Rajagopalan@Sun.COM #include <sys/conf.h>
30*13101SVenki.Rajagopalan@Sun.COM #include <sys/ddi.h>
31*13101SVenki.Rajagopalan@Sun.COM #include <sys/sunddi.h>
32*13101SVenki.Rajagopalan@Sun.COM #include <sys/sunndi.h>
33*13101SVenki.Rajagopalan@Sun.COM
34*13101SVenki.Rajagopalan@Sun.COM #include <sys/ib/clients/eoib/enx_impl.h>
35*13101SVenki.Rajagopalan@Sun.COM
36*13101SVenki.Rajagopalan@Sun.COM static char *eibnx_make_nodename(eibnx_thr_info_t *, uint16_t);
37*13101SVenki.Rajagopalan@Sun.COM
38*13101SVenki.Rajagopalan@Sun.COM /*
39*13101SVenki.Rajagopalan@Sun.COM * This routine is only called when the port-monitor thread is
40*13101SVenki.Rajagopalan@Sun.COM * about to die. Between the time the first mcast solicitation
41*13101SVenki.Rajagopalan@Sun.COM * was done by the port-monitor thread and the time it is asked
42*13101SVenki.Rajagopalan@Sun.COM * to die, a lot of things could've happened and we need to
43*13101SVenki.Rajagopalan@Sun.COM * cleanup all of it.
44*13101SVenki.Rajagopalan@Sun.COM */
45*13101SVenki.Rajagopalan@Sun.COM void
eibnx_cleanup_port_nodes(eibnx_thr_info_t * info)46*13101SVenki.Rajagopalan@Sun.COM eibnx_cleanup_port_nodes(eibnx_thr_info_t *info)
47*13101SVenki.Rajagopalan@Sun.COM {
48*13101SVenki.Rajagopalan@Sun.COM eibnx_t *ss = enx_global_ss;
49*13101SVenki.Rajagopalan@Sun.COM eibnx_nodeq_t *node;
50*13101SVenki.Rajagopalan@Sun.COM eibnx_nodeq_t *prev;
51*13101SVenki.Rajagopalan@Sun.COM eibnx_gw_info_t *gwi;
52*13101SVenki.Rajagopalan@Sun.COM eibnx_gw_info_t *gw_list;
53*13101SVenki.Rajagopalan@Sun.COM eibnx_gw_info_t *nxt_gwi;
54*13101SVenki.Rajagopalan@Sun.COM eibnx_child_t *child;
55*13101SVenki.Rajagopalan@Sun.COM eibnx_child_t *nxt_child;
56*13101SVenki.Rajagopalan@Sun.COM eibnx_child_t *children;
57*13101SVenki.Rajagopalan@Sun.COM
58*13101SVenki.Rajagopalan@Sun.COM /*
59*13101SVenki.Rajagopalan@Sun.COM * Since we would've already stopped processing completions for
60*13101SVenki.Rajagopalan@Sun.COM * this thread's work queue, we don't have to worry about requests
61*13101SVenki.Rajagopalan@Sun.COM * coming in for creation of new eoib nodes. However, there may
62*13101SVenki.Rajagopalan@Sun.COM * be pending node creation requests for this port (thr_info)
63*13101SVenki.Rajagopalan@Sun.COM * that we will have to drop.
64*13101SVenki.Rajagopalan@Sun.COM */
65*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->nx_nodeq_lock);
66*13101SVenki.Rajagopalan@Sun.COM prev = NULL;
67*13101SVenki.Rajagopalan@Sun.COM for (node = ss->nx_nodeq; node; node = node->nc_next) {
68*13101SVenki.Rajagopalan@Sun.COM if (node->nc_info != info) {
69*13101SVenki.Rajagopalan@Sun.COM prev = node;
70*13101SVenki.Rajagopalan@Sun.COM } else {
71*13101SVenki.Rajagopalan@Sun.COM if (prev == NULL) {
72*13101SVenki.Rajagopalan@Sun.COM ss->nx_nodeq = node->nc_next;
73*13101SVenki.Rajagopalan@Sun.COM } else {
74*13101SVenki.Rajagopalan@Sun.COM prev->nc_next = node->nc_next;
75*13101SVenki.Rajagopalan@Sun.COM }
76*13101SVenki.Rajagopalan@Sun.COM kmem_free(node, sizeof (eibnx_nodeq_t));
77*13101SVenki.Rajagopalan@Sun.COM }
78*13101SVenki.Rajagopalan@Sun.COM }
79*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->nx_nodeq_lock);
80*13101SVenki.Rajagopalan@Sun.COM
81*13101SVenki.Rajagopalan@Sun.COM /*
82*13101SVenki.Rajagopalan@Sun.COM * Now go through the list of all children and free up any
83*13101SVenki.Rajagopalan@Sun.COM * resource we might've allocated; note that the child dips
84*13101SVenki.Rajagopalan@Sun.COM * could've been offlined/removed by now, so we don't do
85*13101SVenki.Rajagopalan@Sun.COM * anything with them.
86*13101SVenki.Rajagopalan@Sun.COM */
87*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&info->ti_child_lock);
88*13101SVenki.Rajagopalan@Sun.COM children = info->ti_child;
89*13101SVenki.Rajagopalan@Sun.COM info->ti_child = NULL;
90*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&info->ti_child_lock);
91*13101SVenki.Rajagopalan@Sun.COM
92*13101SVenki.Rajagopalan@Sun.COM for (child = children; child; child = nxt_child) {
93*13101SVenki.Rajagopalan@Sun.COM nxt_child = child->ch_next;
94*13101SVenki.Rajagopalan@Sun.COM
95*13101SVenki.Rajagopalan@Sun.COM if (child->ch_node_name) {
96*13101SVenki.Rajagopalan@Sun.COM kmem_free(child->ch_node_name, MAXNAMELEN);
97*13101SVenki.Rajagopalan@Sun.COM }
98*13101SVenki.Rajagopalan@Sun.COM kmem_free(child, sizeof (eibnx_child_t));
99*13101SVenki.Rajagopalan@Sun.COM }
100*13101SVenki.Rajagopalan@Sun.COM
101*13101SVenki.Rajagopalan@Sun.COM /*
102*13101SVenki.Rajagopalan@Sun.COM * Return all the swqes we've acquired for the gateway unicast
103*13101SVenki.Rajagopalan@Sun.COM * solicitations, free any address vectors we've allocated and
104*13101SVenki.Rajagopalan@Sun.COM * finally free the gw entries from the list.
105*13101SVenki.Rajagopalan@Sun.COM */
106*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&info->ti_gw_lock);
107*13101SVenki.Rajagopalan@Sun.COM gw_list = info->ti_gw;
108*13101SVenki.Rajagopalan@Sun.COM info->ti_gw = NULL;
109*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&info->ti_gw_lock);
110*13101SVenki.Rajagopalan@Sun.COM
111*13101SVenki.Rajagopalan@Sun.COM for (gwi = gw_list; gwi; gwi = nxt_gwi) {
112*13101SVenki.Rajagopalan@Sun.COM nxt_gwi = gwi->gw_next;
113*13101SVenki.Rajagopalan@Sun.COM
114*13101SVenki.Rajagopalan@Sun.COM eibnx_release_swqe((eibnx_wqe_t *)(gwi->gw_swqe));
115*13101SVenki.Rajagopalan@Sun.COM if ((gwi->gw_addr).ga_vect) {
116*13101SVenki.Rajagopalan@Sun.COM kmem_free((gwi->gw_addr).ga_vect,
117*13101SVenki.Rajagopalan@Sun.COM sizeof (ibt_adds_vect_t));
118*13101SVenki.Rajagopalan@Sun.COM (gwi->gw_addr).ga_vect = NULL;
119*13101SVenki.Rajagopalan@Sun.COM }
120*13101SVenki.Rajagopalan@Sun.COM mutex_destroy(&gwi->gw_adv_lock);
121*13101SVenki.Rajagopalan@Sun.COM
122*13101SVenki.Rajagopalan@Sun.COM kmem_free(gwi, sizeof (eibnx_gw_info_t));
123*13101SVenki.Rajagopalan@Sun.COM }
124*13101SVenki.Rajagopalan@Sun.COM }
125*13101SVenki.Rajagopalan@Sun.COM
126*13101SVenki.Rajagopalan@Sun.COM /*
127*13101SVenki.Rajagopalan@Sun.COM * Communicate all the details we received about the gateway (via the
128*13101SVenki.Rajagopalan@Sun.COM * advertisement control message) to the eoib instance we're creating.
129*13101SVenki.Rajagopalan@Sun.COM */
130*13101SVenki.Rajagopalan@Sun.COM void
eibnx_create_node_props(dev_info_t * dip,eibnx_thr_info_t * info,eibnx_gw_info_t * gwi)131*13101SVenki.Rajagopalan@Sun.COM eibnx_create_node_props(dev_info_t *dip, eibnx_thr_info_t *info,
132*13101SVenki.Rajagopalan@Sun.COM eibnx_gw_info_t *gwi)
133*13101SVenki.Rajagopalan@Sun.COM {
134*13101SVenki.Rajagopalan@Sun.COM int ret;
135*13101SVenki.Rajagopalan@Sun.COM
136*13101SVenki.Rajagopalan@Sun.COM ret = ndi_prop_update_int64(DDI_DEV_T_NONE, dip, EIB_PROP_HCA_GUID,
137*13101SVenki.Rajagopalan@Sun.COM info->ti_hca_guid);
138*13101SVenki.Rajagopalan@Sun.COM if (ret != DDI_PROP_SUCCESS) {
139*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ndi_prop_update_int64() failed to set "
140*13101SVenki.Rajagopalan@Sun.COM "%s property to 0x%llx for child dip 0x%llx, ret=%d",
141*13101SVenki.Rajagopalan@Sun.COM EIB_PROP_HCA_GUID, info->ti_hca_guid, dip, ret);
142*13101SVenki.Rajagopalan@Sun.COM }
143*13101SVenki.Rajagopalan@Sun.COM
144*13101SVenki.Rajagopalan@Sun.COM ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip, EIB_PROP_HCA_PORTNUM,
145*13101SVenki.Rajagopalan@Sun.COM info->ti_pi->p_port_num);
146*13101SVenki.Rajagopalan@Sun.COM if (ret != DDI_PROP_SUCCESS) {
147*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ndi_prop_update_int() failed to set "
148*13101SVenki.Rajagopalan@Sun.COM "%s property to 0x%lx for child dip 0x%llx, ret=%d",
149*13101SVenki.Rajagopalan@Sun.COM EIB_PROP_HCA_PORTNUM, info->ti_pi->p_port_num, dip, ret);
150*13101SVenki.Rajagopalan@Sun.COM }
151*13101SVenki.Rajagopalan@Sun.COM
152*13101SVenki.Rajagopalan@Sun.COM ret = ndi_prop_update_int64(DDI_DEV_T_NONE, dip, EIB_PROP_GW_SYS_GUID,
153*13101SVenki.Rajagopalan@Sun.COM gwi->gw_system_guid);
154*13101SVenki.Rajagopalan@Sun.COM if (ret != DDI_PROP_SUCCESS) {
155*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ndi_prop_update_int64() failed to set "
156*13101SVenki.Rajagopalan@Sun.COM "%s property to 0x%llx for child dip 0x%llx, ret=%d",
157*13101SVenki.Rajagopalan@Sun.COM EIB_PROP_GW_SYS_GUID, gwi->gw_system_guid, dip, ret);
158*13101SVenki.Rajagopalan@Sun.COM }
159*13101SVenki.Rajagopalan@Sun.COM
160*13101SVenki.Rajagopalan@Sun.COM ret = ndi_prop_update_int64(DDI_DEV_T_NONE, dip, EIB_PROP_GW_GUID,
161*13101SVenki.Rajagopalan@Sun.COM gwi->gw_guid);
162*13101SVenki.Rajagopalan@Sun.COM if (ret != DDI_PROP_SUCCESS) {
163*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ndi_prop_update_int64() failed to set "
164*13101SVenki.Rajagopalan@Sun.COM "%s property to 0x%llx for child dip 0x%llx, ret=%d",
165*13101SVenki.Rajagopalan@Sun.COM EIB_PROP_GW_GUID, gwi->gw_guid, dip, ret);
166*13101SVenki.Rajagopalan@Sun.COM }
167*13101SVenki.Rajagopalan@Sun.COM
168*13101SVenki.Rajagopalan@Sun.COM ret = ndi_prop_update_int64(DDI_DEV_T_NONE, dip, EIB_PROP_GW_SN_PREFIX,
169*13101SVenki.Rajagopalan@Sun.COM (gwi->gw_addr).ga_gid.gid_prefix);
170*13101SVenki.Rajagopalan@Sun.COM if (ret != DDI_PROP_SUCCESS) {
171*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ndi_prop_update_int64() failed to set "
172*13101SVenki.Rajagopalan@Sun.COM "%s property to 0x%llx for child dip 0x%llx, ret=%d",
173*13101SVenki.Rajagopalan@Sun.COM EIB_PROP_GW_SN_PREFIX, (gwi->gw_addr).ga_gid.gid_prefix,
174*13101SVenki.Rajagopalan@Sun.COM dip, ret);
175*13101SVenki.Rajagopalan@Sun.COM }
176*13101SVenki.Rajagopalan@Sun.COM
177*13101SVenki.Rajagopalan@Sun.COM ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip, EIB_PROP_GW_ADV_PERIOD,
178*13101SVenki.Rajagopalan@Sun.COM gwi->gw_adv_period);
179*13101SVenki.Rajagopalan@Sun.COM if (ret != DDI_PROP_SUCCESS) {
180*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ndi_prop_update_int() failed to set "
181*13101SVenki.Rajagopalan@Sun.COM "%s property to 0x%lx for child dip 0x%llx, ret=%d",
182*13101SVenki.Rajagopalan@Sun.COM EIB_PROP_GW_ADV_PERIOD, gwi->gw_adv_period, dip, ret);
183*13101SVenki.Rajagopalan@Sun.COM }
184*13101SVenki.Rajagopalan@Sun.COM
185*13101SVenki.Rajagopalan@Sun.COM ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip, EIB_PROP_GW_KA_PERIOD,
186*13101SVenki.Rajagopalan@Sun.COM gwi->gw_ka_period);
187*13101SVenki.Rajagopalan@Sun.COM if (ret != DDI_PROP_SUCCESS) {
188*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ndi_prop_update_int() failed to set "
189*13101SVenki.Rajagopalan@Sun.COM "%s property to 0x%lx for child dip 0x%llx, ret=%d",
190*13101SVenki.Rajagopalan@Sun.COM EIB_PROP_GW_KA_PERIOD, gwi->gw_ka_period, dip, ret);
191*13101SVenki.Rajagopalan@Sun.COM }
192*13101SVenki.Rajagopalan@Sun.COM
193*13101SVenki.Rajagopalan@Sun.COM ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip, EIB_PROP_VNIC_KA_PERIOD,
194*13101SVenki.Rajagopalan@Sun.COM gwi->gw_vnic_ka_period);
195*13101SVenki.Rajagopalan@Sun.COM if (ret != DDI_PROP_SUCCESS) {
196*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ndi_prop_update_int() failed to set "
197*13101SVenki.Rajagopalan@Sun.COM "%s property to 0x%lx for child dip 0x%llx, ret=%d",
198*13101SVenki.Rajagopalan@Sun.COM EIB_PROP_VNIC_KA_PERIOD, gwi->gw_vnic_ka_period, dip, ret);
199*13101SVenki.Rajagopalan@Sun.COM }
200*13101SVenki.Rajagopalan@Sun.COM
201*13101SVenki.Rajagopalan@Sun.COM ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip, EIB_PROP_GW_CTRL_QPN,
202*13101SVenki.Rajagopalan@Sun.COM gwi->gw_ctrl_qpn);
203*13101SVenki.Rajagopalan@Sun.COM if (ret != DDI_PROP_SUCCESS) {
204*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ndi_prop_update_int() failed to set "
205*13101SVenki.Rajagopalan@Sun.COM "%s property to 0x%lx for child dip 0x%llx, ret=%d",
206*13101SVenki.Rajagopalan@Sun.COM EIB_PROP_GW_CTRL_QPN, gwi->gw_ctrl_qpn, dip, ret);
207*13101SVenki.Rajagopalan@Sun.COM }
208*13101SVenki.Rajagopalan@Sun.COM
209*13101SVenki.Rajagopalan@Sun.COM ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip, EIB_PROP_GW_LID,
210*13101SVenki.Rajagopalan@Sun.COM gwi->gw_lid);
211*13101SVenki.Rajagopalan@Sun.COM if (ret != DDI_PROP_SUCCESS) {
212*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ndi_prop_update_int() failed to set "
213*13101SVenki.Rajagopalan@Sun.COM "%s property to 0x%lx for child dip 0x%llx, ret=%d",
214*13101SVenki.Rajagopalan@Sun.COM EIB_PROP_GW_LID, gwi->gw_lid, dip, ret);
215*13101SVenki.Rajagopalan@Sun.COM }
216*13101SVenki.Rajagopalan@Sun.COM
217*13101SVenki.Rajagopalan@Sun.COM ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip, EIB_PROP_GW_PORTID,
218*13101SVenki.Rajagopalan@Sun.COM gwi->gw_portid);
219*13101SVenki.Rajagopalan@Sun.COM if (ret != DDI_PROP_SUCCESS) {
220*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ndi_prop_update_int() failed to set "
221*13101SVenki.Rajagopalan@Sun.COM "%s property to 0x%lx for child dip 0x%llx, ret=%d",
222*13101SVenki.Rajagopalan@Sun.COM EIB_PROP_GW_PORTID, gwi->gw_portid, dip, ret);
223*13101SVenki.Rajagopalan@Sun.COM }
224*13101SVenki.Rajagopalan@Sun.COM
225*13101SVenki.Rajagopalan@Sun.COM ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
226*13101SVenki.Rajagopalan@Sun.COM EIB_PROP_GW_NUM_NET_VNICS, gwi->gw_num_net_vnics);
227*13101SVenki.Rajagopalan@Sun.COM if (ret != DDI_PROP_SUCCESS) {
228*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ndi_prop_update_int() failed to set "
229*13101SVenki.Rajagopalan@Sun.COM "%s property to 0x%lx for child dip 0x%llx, ret=%d",
230*13101SVenki.Rajagopalan@Sun.COM EIB_PROP_GW_NUM_NET_VNICS, gwi->gw_num_net_vnics, dip, ret);
231*13101SVenki.Rajagopalan@Sun.COM }
232*13101SVenki.Rajagopalan@Sun.COM
233*13101SVenki.Rajagopalan@Sun.COM ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip, EIB_PROP_GW_AVAILABLE,
234*13101SVenki.Rajagopalan@Sun.COM gwi->gw_flag_available);
235*13101SVenki.Rajagopalan@Sun.COM if (ret != DDI_PROP_SUCCESS) {
236*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ndi_prop_update_int() failed to set "
237*13101SVenki.Rajagopalan@Sun.COM "%s property to 0x%lx for child dip 0x%llx, ret=%d",
238*13101SVenki.Rajagopalan@Sun.COM EIB_PROP_GW_AVAILABLE, gwi->gw_flag_available, dip, ret);
239*13101SVenki.Rajagopalan@Sun.COM }
240*13101SVenki.Rajagopalan@Sun.COM
241*13101SVenki.Rajagopalan@Sun.COM ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip, EIB_PROP_GW_HOST_VNICS,
242*13101SVenki.Rajagopalan@Sun.COM gwi->gw_is_host_adm_vnics);
243*13101SVenki.Rajagopalan@Sun.COM if (ret != DDI_PROP_SUCCESS) {
244*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ndi_prop_update_int() failed to set "
245*13101SVenki.Rajagopalan@Sun.COM "%s property to 0x%lx for child dip 0x%llx, ret=%d",
246*13101SVenki.Rajagopalan@Sun.COM EIB_PROP_GW_HOST_VNICS, gwi->gw_is_host_adm_vnics,
247*13101SVenki.Rajagopalan@Sun.COM dip, ret);
248*13101SVenki.Rajagopalan@Sun.COM }
249*13101SVenki.Rajagopalan@Sun.COM
250*13101SVenki.Rajagopalan@Sun.COM ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip, EIB_PROP_GW_SL,
251*13101SVenki.Rajagopalan@Sun.COM gwi->gw_sl);
252*13101SVenki.Rajagopalan@Sun.COM if (ret != DDI_PROP_SUCCESS) {
253*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ndi_prop_update_int() failed to set "
254*13101SVenki.Rajagopalan@Sun.COM "%s property to 0x%lx for child dip 0x%llx, ret=%d",
255*13101SVenki.Rajagopalan@Sun.COM EIB_PROP_GW_SL, gwi->gw_sl, dip, ret);
256*13101SVenki.Rajagopalan@Sun.COM }
257*13101SVenki.Rajagopalan@Sun.COM
258*13101SVenki.Rajagopalan@Sun.COM ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip, EIB_PROP_GW_N_RSS_QPN,
259*13101SVenki.Rajagopalan@Sun.COM gwi->gw_n_rss_qpn);
260*13101SVenki.Rajagopalan@Sun.COM if (ret != DDI_PROP_SUCCESS) {
261*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ndi_prop_update_int() failed to set "
262*13101SVenki.Rajagopalan@Sun.COM "%s property to 0x%lx for child dip 0x%llx, ret=%d",
263*13101SVenki.Rajagopalan@Sun.COM EIB_PROP_GW_N_RSS_QPN, gwi->gw_n_rss_qpn, dip, ret);
264*13101SVenki.Rajagopalan@Sun.COM }
265*13101SVenki.Rajagopalan@Sun.COM
266*13101SVenki.Rajagopalan@Sun.COM ret = ndi_prop_update_string(DDI_DEV_T_NONE, dip, EIB_PROP_GW_SYS_NAME,
267*13101SVenki.Rajagopalan@Sun.COM (char *)(gwi->gw_system_name));
268*13101SVenki.Rajagopalan@Sun.COM if (ret != DDI_PROP_SUCCESS) {
269*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ndi_prop_update_string() failed to set "
270*13101SVenki.Rajagopalan@Sun.COM "%s property to '%s' for child dip 0x%llx, ret=%d",
271*13101SVenki.Rajagopalan@Sun.COM EIB_PROP_GW_SYS_NAME, gwi->gw_system_name, dip, ret);
272*13101SVenki.Rajagopalan@Sun.COM }
273*13101SVenki.Rajagopalan@Sun.COM
274*13101SVenki.Rajagopalan@Sun.COM ret = ndi_prop_update_string(DDI_DEV_T_NONE, dip, EIB_PROP_GW_PORT_NAME,
275*13101SVenki.Rajagopalan@Sun.COM (char *)(gwi->gw_port_name));
276*13101SVenki.Rajagopalan@Sun.COM if (ret != DDI_PROP_SUCCESS) {
277*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ndi_prop_update_string() failed to set "
278*13101SVenki.Rajagopalan@Sun.COM "%s property to '%s' for child dip 0x%llx, ret=%d",
279*13101SVenki.Rajagopalan@Sun.COM EIB_PROP_GW_PORT_NAME, gwi->gw_port_name, dip, ret);
280*13101SVenki.Rajagopalan@Sun.COM }
281*13101SVenki.Rajagopalan@Sun.COM
282*13101SVenki.Rajagopalan@Sun.COM ret = ndi_prop_update_string(DDI_DEV_T_NONE, dip, EIB_PROP_GW_VENDOR_ID,
283*13101SVenki.Rajagopalan@Sun.COM (char *)(gwi->gw_vendor_id));
284*13101SVenki.Rajagopalan@Sun.COM if (ret != DDI_PROP_SUCCESS) {
285*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ndi_prop_update_string() failed to set "
286*13101SVenki.Rajagopalan@Sun.COM "%s property to '%s' for child dip 0x%llx, ret=%d",
287*13101SVenki.Rajagopalan@Sun.COM EIB_PROP_GW_VENDOR_ID, gwi->gw_vendor_id, dip, ret);
288*13101SVenki.Rajagopalan@Sun.COM }
289*13101SVenki.Rajagopalan@Sun.COM }
290*13101SVenki.Rajagopalan@Sun.COM
291*13101SVenki.Rajagopalan@Sun.COM int
eibnx_name_child(dev_info_t * child,char * name,size_t namesz)292*13101SVenki.Rajagopalan@Sun.COM eibnx_name_child(dev_info_t *child, char *name, size_t namesz)
293*13101SVenki.Rajagopalan@Sun.COM {
294*13101SVenki.Rajagopalan@Sun.COM char *node_name;
295*13101SVenki.Rajagopalan@Sun.COM
296*13101SVenki.Rajagopalan@Sun.COM if ((node_name = ddi_get_parent_data(child)) == NULL) {
297*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("ddi_get_parent_data(child=0x%llx) "
298*13101SVenki.Rajagopalan@Sun.COM "returned NULL", child);
299*13101SVenki.Rajagopalan@Sun.COM return (DDI_NOT_WELL_FORMED);
300*13101SVenki.Rajagopalan@Sun.COM }
301*13101SVenki.Rajagopalan@Sun.COM
302*13101SVenki.Rajagopalan@Sun.COM /*
303*13101SVenki.Rajagopalan@Sun.COM * Skip the name and "@" part in the eoib node path and copy the
304*13101SVenki.Rajagopalan@Sun.COM * address part out to the caller.
305*13101SVenki.Rajagopalan@Sun.COM */
306*13101SVenki.Rajagopalan@Sun.COM (void) strlcpy(name, node_name + strlen(EIB_DRV_NAME) + 1, namesz);
307*13101SVenki.Rajagopalan@Sun.COM
308*13101SVenki.Rajagopalan@Sun.COM return (DDI_SUCCESS);
309*13101SVenki.Rajagopalan@Sun.COM }
310*13101SVenki.Rajagopalan@Sun.COM
311*13101SVenki.Rajagopalan@Sun.COM /*
312*13101SVenki.Rajagopalan@Sun.COM * Synchronization functions to mark/clear the in-progress status of
313*13101SVenki.Rajagopalan@Sun.COM * bus config/unconfig operations
314*13101SVenki.Rajagopalan@Sun.COM */
315*13101SVenki.Rajagopalan@Sun.COM
316*13101SVenki.Rajagopalan@Sun.COM void
eibnx_busop_inprog_enter(eibnx_t * ss)317*13101SVenki.Rajagopalan@Sun.COM eibnx_busop_inprog_enter(eibnx_t *ss)
318*13101SVenki.Rajagopalan@Sun.COM {
319*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->nx_busop_lock);
320*13101SVenki.Rajagopalan@Sun.COM
321*13101SVenki.Rajagopalan@Sun.COM while (ss->nx_busop_flags & NX_FL_BUSOP_INPROG)
322*13101SVenki.Rajagopalan@Sun.COM cv_wait(&ss->nx_busop_cv, &ss->nx_busop_lock);
323*13101SVenki.Rajagopalan@Sun.COM
324*13101SVenki.Rajagopalan@Sun.COM ss->nx_busop_flags |= NX_FL_BUSOP_INPROG;
325*13101SVenki.Rajagopalan@Sun.COM
326*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->nx_busop_lock);
327*13101SVenki.Rajagopalan@Sun.COM }
328*13101SVenki.Rajagopalan@Sun.COM
329*13101SVenki.Rajagopalan@Sun.COM void
eibnx_busop_inprog_exit(eibnx_t * ss)330*13101SVenki.Rajagopalan@Sun.COM eibnx_busop_inprog_exit(eibnx_t *ss)
331*13101SVenki.Rajagopalan@Sun.COM {
332*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->nx_busop_lock);
333*13101SVenki.Rajagopalan@Sun.COM
334*13101SVenki.Rajagopalan@Sun.COM ss->nx_busop_flags &= (~NX_FL_BUSOP_INPROG);
335*13101SVenki.Rajagopalan@Sun.COM
336*13101SVenki.Rajagopalan@Sun.COM cv_broadcast(&ss->nx_busop_cv);
337*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->nx_busop_lock);
338*13101SVenki.Rajagopalan@Sun.COM }
339*13101SVenki.Rajagopalan@Sun.COM
340*13101SVenki.Rajagopalan@Sun.COM eibnx_thr_info_t *
eibnx_start_port_monitor(eibnx_hca_t * hca,eibnx_port_t * port)341*13101SVenki.Rajagopalan@Sun.COM eibnx_start_port_monitor(eibnx_hca_t *hca, eibnx_port_t *port)
342*13101SVenki.Rajagopalan@Sun.COM {
343*13101SVenki.Rajagopalan@Sun.COM eibnx_thr_info_t *ti;
344*13101SVenki.Rajagopalan@Sun.COM kthread_t *kt;
345*13101SVenki.Rajagopalan@Sun.COM dev_info_t *hca_dip;
346*13101SVenki.Rajagopalan@Sun.COM const char *hca_drv_name;
347*13101SVenki.Rajagopalan@Sun.COM int hca_drv_inst;
348*13101SVenki.Rajagopalan@Sun.COM
349*13101SVenki.Rajagopalan@Sun.COM ti = kmem_zalloc(sizeof (eibnx_thr_info_t), KM_SLEEP);
350*13101SVenki.Rajagopalan@Sun.COM
351*13101SVenki.Rajagopalan@Sun.COM mutex_init(&ti->ti_mcg_lock, NULL, MUTEX_DRIVER, NULL);
352*13101SVenki.Rajagopalan@Sun.COM mutex_init(&ti->ti_gw_lock, NULL, MUTEX_DRIVER, NULL);
353*13101SVenki.Rajagopalan@Sun.COM mutex_init(&ti->ti_child_lock, NULL, MUTEX_DRIVER, NULL);
354*13101SVenki.Rajagopalan@Sun.COM mutex_init(&ti->ti_event_lock, NULL, MUTEX_DRIVER, NULL);
355*13101SVenki.Rajagopalan@Sun.COM cv_init(&ti->ti_event_cv, NULL, CV_DEFAULT, NULL);
356*13101SVenki.Rajagopalan@Sun.COM
357*13101SVenki.Rajagopalan@Sun.COM ti->ti_next = NULL;
358*13101SVenki.Rajagopalan@Sun.COM ti->ti_hca_guid = hca->hc_guid;
359*13101SVenki.Rajagopalan@Sun.COM ti->ti_hca = hca->hc_hdl;
360*13101SVenki.Rajagopalan@Sun.COM ti->ti_pd = hca->hc_pd;
361*13101SVenki.Rajagopalan@Sun.COM ti->ti_pi = port->po_pi;
362*13101SVenki.Rajagopalan@Sun.COM ti->ti_ident = kmem_zalloc(MAXNAMELEN, KM_SLEEP);
363*13101SVenki.Rajagopalan@Sun.COM
364*13101SVenki.Rajagopalan@Sun.COM /*
365*13101SVenki.Rajagopalan@Sun.COM * Prepare the "ident" for EoIB nodes from this port monitor. To
366*13101SVenki.Rajagopalan@Sun.COM * associate eoib instances with the corresponding HCA nodes easily,
367*13101SVenki.Rajagopalan@Sun.COM * and to make sure eoib instance numbers do not change when
368*13101SVenki.Rajagopalan@Sun.COM * like-for-like HCA replacements are made, tie up the ident to
369*13101SVenki.Rajagopalan@Sun.COM * HCA driver name, HCA driver instance and the HCA port number.
370*13101SVenki.Rajagopalan@Sun.COM * The eoib node address is later composed using this ident and
371*13101SVenki.Rajagopalan@Sun.COM * the gateway port ids after discovery.
372*13101SVenki.Rajagopalan@Sun.COM */
373*13101SVenki.Rajagopalan@Sun.COM if ((hca_dip = ibtl_ibnex_hcaguid2dip(ti->ti_hca_guid)) == NULL) {
374*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("ibtl_ibnex_hcaguid2dip(hca_guid=0x%llx) "
375*13101SVenki.Rajagopalan@Sun.COM "returned NULL", ti->ti_hca_guid);
376*13101SVenki.Rajagopalan@Sun.COM } else if ((hca_drv_name = ddi_driver_name(hca_dip)) == NULL) {
377*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_WARN("hca driver name NULL for "
378*13101SVenki.Rajagopalan@Sun.COM "hca_guid=0x%llx, hca_dip=0x%llx",
379*13101SVenki.Rajagopalan@Sun.COM ti->ti_hca_guid, hca_dip);
380*13101SVenki.Rajagopalan@Sun.COM } else if ((hca_drv_inst = ddi_get_instance(hca_dip)) < 0) {
381*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("hca driver instance (%d) invalid for "
382*13101SVenki.Rajagopalan@Sun.COM "hca_guid=0x%llx, hca_dip=0x%llx",
383*13101SVenki.Rajagopalan@Sun.COM ti->ti_hca_guid, hca_dip);
384*13101SVenki.Rajagopalan@Sun.COM } else {
385*13101SVenki.Rajagopalan@Sun.COM (void) snprintf(ti->ti_ident, MAXNAMELEN, "%s%d,%x",
386*13101SVenki.Rajagopalan@Sun.COM hca_drv_name, hca_drv_inst, ti->ti_pi->p_port_num);
387*13101SVenki.Rajagopalan@Sun.COM }
388*13101SVenki.Rajagopalan@Sun.COM
389*13101SVenki.Rajagopalan@Sun.COM kt = thread_create(NULL, 0, eibnx_port_monitor,
390*13101SVenki.Rajagopalan@Sun.COM ti, 0, &p0, TS_RUN, minclsyspri);
391*13101SVenki.Rajagopalan@Sun.COM
392*13101SVenki.Rajagopalan@Sun.COM ti->ti_kt_did = kt->t_did;
393*13101SVenki.Rajagopalan@Sun.COM
394*13101SVenki.Rajagopalan@Sun.COM return (ti);
395*13101SVenki.Rajagopalan@Sun.COM }
396*13101SVenki.Rajagopalan@Sun.COM
397*13101SVenki.Rajagopalan@Sun.COM void
eibnx_stop_port_monitor(eibnx_thr_info_t * ti)398*13101SVenki.Rajagopalan@Sun.COM eibnx_stop_port_monitor(eibnx_thr_info_t *ti)
399*13101SVenki.Rajagopalan@Sun.COM {
400*13101SVenki.Rajagopalan@Sun.COM /*
401*13101SVenki.Rajagopalan@Sun.COM * Tell the port monitor thread to stop and wait for it to
402*13101SVenki.Rajagopalan@Sun.COM * happen. Before marking it for death, make sure there
403*13101SVenki.Rajagopalan@Sun.COM * aren't any completions being processed.
404*13101SVenki.Rajagopalan@Sun.COM */
405*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ti->ti_event_lock);
406*13101SVenki.Rajagopalan@Sun.COM while (ti->ti_event & ENX_EVENT_COMPLETION) {
407*13101SVenki.Rajagopalan@Sun.COM cv_wait(&ti->ti_event_cv, &ti->ti_event_lock);
408*13101SVenki.Rajagopalan@Sun.COM }
409*13101SVenki.Rajagopalan@Sun.COM ti->ti_event |= ENX_EVENT_DIE;
410*13101SVenki.Rajagopalan@Sun.COM cv_broadcast(&ti->ti_event_cv);
411*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ti->ti_event_lock);
412*13101SVenki.Rajagopalan@Sun.COM
413*13101SVenki.Rajagopalan@Sun.COM thread_join(ti->ti_kt_did);
414*13101SVenki.Rajagopalan@Sun.COM
415*13101SVenki.Rajagopalan@Sun.COM /*
416*13101SVenki.Rajagopalan@Sun.COM * Destroy synchronization primitives initialized for this ti
417*13101SVenki.Rajagopalan@Sun.COM */
418*13101SVenki.Rajagopalan@Sun.COM cv_destroy(&ti->ti_event_cv);
419*13101SVenki.Rajagopalan@Sun.COM mutex_destroy(&ti->ti_event_lock);
420*13101SVenki.Rajagopalan@Sun.COM mutex_destroy(&ti->ti_child_lock);
421*13101SVenki.Rajagopalan@Sun.COM mutex_destroy(&ti->ti_gw_lock);
422*13101SVenki.Rajagopalan@Sun.COM mutex_destroy(&ti->ti_mcg_lock);
423*13101SVenki.Rajagopalan@Sun.COM
424*13101SVenki.Rajagopalan@Sun.COM kmem_free(ti->ti_ident, MAXNAMELEN);
425*13101SVenki.Rajagopalan@Sun.COM kmem_free(ti, sizeof (eibnx_thr_info_t));
426*13101SVenki.Rajagopalan@Sun.COM }
427*13101SVenki.Rajagopalan@Sun.COM
428*13101SVenki.Rajagopalan@Sun.COM void
eibnx_terminate_monitors(void)429*13101SVenki.Rajagopalan@Sun.COM eibnx_terminate_monitors(void)
430*13101SVenki.Rajagopalan@Sun.COM {
431*13101SVenki.Rajagopalan@Sun.COM eibnx_t *ss = enx_global_ss;
432*13101SVenki.Rajagopalan@Sun.COM eibnx_thr_info_t *ti_list;
433*13101SVenki.Rajagopalan@Sun.COM eibnx_thr_info_t *ti;
434*13101SVenki.Rajagopalan@Sun.COM eibnx_thr_info_t *ti_next;
435*13101SVenki.Rajagopalan@Sun.COM
436*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->nx_lock);
437*13101SVenki.Rajagopalan@Sun.COM ti_list = ss->nx_thr_info;
438*13101SVenki.Rajagopalan@Sun.COM ss->nx_thr_info = NULL;
439*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->nx_lock);
440*13101SVenki.Rajagopalan@Sun.COM
441*13101SVenki.Rajagopalan@Sun.COM /*
442*13101SVenki.Rajagopalan@Sun.COM * Ask all the port_monitor threads to die. Before marking them
443*13101SVenki.Rajagopalan@Sun.COM * for death, make sure there aren't any completions being
444*13101SVenki.Rajagopalan@Sun.COM * processed by the thread.
445*13101SVenki.Rajagopalan@Sun.COM */
446*13101SVenki.Rajagopalan@Sun.COM for (ti = ti_list; ti; ti = ti_next) {
447*13101SVenki.Rajagopalan@Sun.COM ti_next = ti->ti_next;
448*13101SVenki.Rajagopalan@Sun.COM eibnx_stop_port_monitor(ti);
449*13101SVenki.Rajagopalan@Sun.COM }
450*13101SVenki.Rajagopalan@Sun.COM
451*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->nx_lock);
452*13101SVenki.Rajagopalan@Sun.COM ss->nx_monitors_up = B_FALSE;
453*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->nx_lock);
454*13101SVenki.Rajagopalan@Sun.COM }
455*13101SVenki.Rajagopalan@Sun.COM
456*13101SVenki.Rajagopalan@Sun.COM int
eibnx_configure_node(eibnx_thr_info_t * ti,eibnx_gw_info_t * gwi,dev_info_t ** childp)457*13101SVenki.Rajagopalan@Sun.COM eibnx_configure_node(eibnx_thr_info_t *ti, eibnx_gw_info_t *gwi,
458*13101SVenki.Rajagopalan@Sun.COM dev_info_t **childp)
459*13101SVenki.Rajagopalan@Sun.COM {
460*13101SVenki.Rajagopalan@Sun.COM eibnx_t *ss = enx_global_ss;
461*13101SVenki.Rajagopalan@Sun.COM dev_info_t *child_dip;
462*13101SVenki.Rajagopalan@Sun.COM char *node_name;
463*13101SVenki.Rajagopalan@Sun.COM int circular;
464*13101SVenki.Rajagopalan@Sun.COM int ret;
465*13101SVenki.Rajagopalan@Sun.COM
466*13101SVenki.Rajagopalan@Sun.COM /*
467*13101SVenki.Rajagopalan@Sun.COM * Prepare the new node's name
468*13101SVenki.Rajagopalan@Sun.COM */
469*13101SVenki.Rajagopalan@Sun.COM if ((node_name = eibnx_make_nodename(ti, gwi->gw_portid)) == NULL)
470*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
471*13101SVenki.Rajagopalan@Sun.COM
472*13101SVenki.Rajagopalan@Sun.COM ndi_devi_enter(ss->nx_dip, &circular);
473*13101SVenki.Rajagopalan@Sun.COM
474*13101SVenki.Rajagopalan@Sun.COM if (child_dip = ndi_devi_findchild(ss->nx_dip, node_name)) {
475*13101SVenki.Rajagopalan@Sun.COM ret = eibnx_update_child(ti, gwi, child_dip);
476*13101SVenki.Rajagopalan@Sun.COM if (ret == ENX_E_SUCCESS) {
477*13101SVenki.Rajagopalan@Sun.COM ndi_devi_exit(ss->nx_dip, circular);
478*13101SVenki.Rajagopalan@Sun.COM kmem_free(node_name, MAXNAMELEN);
479*13101SVenki.Rajagopalan@Sun.COM
480*13101SVenki.Rajagopalan@Sun.COM if (childp) {
481*13101SVenki.Rajagopalan@Sun.COM *childp = child_dip;
482*13101SVenki.Rajagopalan@Sun.COM }
483*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_SUCCESS);
484*13101SVenki.Rajagopalan@Sun.COM }
485*13101SVenki.Rajagopalan@Sun.COM }
486*13101SVenki.Rajagopalan@Sun.COM
487*13101SVenki.Rajagopalan@Sun.COM /*
488*13101SVenki.Rajagopalan@Sun.COM * If the node does not already exist, we may need to create it
489*13101SVenki.Rajagopalan@Sun.COM */
490*13101SVenki.Rajagopalan@Sun.COM if (child_dip == NULL) {
491*13101SVenki.Rajagopalan@Sun.COM ndi_devi_alloc_sleep(ss->nx_dip, EIB_DRV_NAME,
492*13101SVenki.Rajagopalan@Sun.COM (pnode_t)DEVI_SID_NODEID, &child_dip);
493*13101SVenki.Rajagopalan@Sun.COM
494*13101SVenki.Rajagopalan@Sun.COM ddi_set_parent_data(child_dip, node_name);
495*13101SVenki.Rajagopalan@Sun.COM eibnx_create_node_props(child_dip, ti, gwi);
496*13101SVenki.Rajagopalan@Sun.COM }
497*13101SVenki.Rajagopalan@Sun.COM
498*13101SVenki.Rajagopalan@Sun.COM /*
499*13101SVenki.Rajagopalan@Sun.COM * Whether there was no devinfo node at all for the given node name or
500*13101SVenki.Rajagopalan@Sun.COM * we had a devinfo node, but it wasn't in our list of eoib children,
501*13101SVenki.Rajagopalan@Sun.COM * we'll try to online the instance here.
502*13101SVenki.Rajagopalan@Sun.COM */
503*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_DEBUG("onlining %s", node_name);
504*13101SVenki.Rajagopalan@Sun.COM ret = ndi_devi_online(child_dip, 0);
505*13101SVenki.Rajagopalan@Sun.COM if (ret != NDI_SUCCESS) {
506*13101SVenki.Rajagopalan@Sun.COM ENX_DPRINTF_ERR("ndi_devi_online(node_name=%s) failed "
507*13101SVenki.Rajagopalan@Sun.COM "with ret=0x%x", node_name, ret);
508*13101SVenki.Rajagopalan@Sun.COM
509*13101SVenki.Rajagopalan@Sun.COM ddi_set_parent_data(child_dip, NULL);
510*13101SVenki.Rajagopalan@Sun.COM (void) ndi_devi_free(child_dip);
511*13101SVenki.Rajagopalan@Sun.COM
512*13101SVenki.Rajagopalan@Sun.COM ndi_devi_exit(ss->nx_dip, circular);
513*13101SVenki.Rajagopalan@Sun.COM kmem_free(node_name, MAXNAMELEN);
514*13101SVenki.Rajagopalan@Sun.COM
515*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
516*13101SVenki.Rajagopalan@Sun.COM }
517*13101SVenki.Rajagopalan@Sun.COM
518*13101SVenki.Rajagopalan@Sun.COM eibnx_enqueue_child(ti, gwi, node_name, child_dip);
519*13101SVenki.Rajagopalan@Sun.COM
520*13101SVenki.Rajagopalan@Sun.COM ndi_devi_exit(ss->nx_dip, circular);
521*13101SVenki.Rajagopalan@Sun.COM
522*13101SVenki.Rajagopalan@Sun.COM if (childp) {
523*13101SVenki.Rajagopalan@Sun.COM *childp = child_dip;
524*13101SVenki.Rajagopalan@Sun.COM }
525*13101SVenki.Rajagopalan@Sun.COM
526*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_SUCCESS);
527*13101SVenki.Rajagopalan@Sun.COM }
528*13101SVenki.Rajagopalan@Sun.COM
529*13101SVenki.Rajagopalan@Sun.COM int
eibnx_unconfigure_node(eibnx_thr_info_t * ti,eibnx_gw_info_t * gwi)530*13101SVenki.Rajagopalan@Sun.COM eibnx_unconfigure_node(eibnx_thr_info_t *ti, eibnx_gw_info_t *gwi)
531*13101SVenki.Rajagopalan@Sun.COM {
532*13101SVenki.Rajagopalan@Sun.COM /*
533*13101SVenki.Rajagopalan@Sun.COM * To unconfigure an eoib node, we only need to set the child's
534*13101SVenki.Rajagopalan@Sun.COM * dip to NULL. When the node gets configured again, we either
535*13101SVenki.Rajagopalan@Sun.COM * find the dip for the pathname and set it in this child, or
536*13101SVenki.Rajagopalan@Sun.COM * allocate a new dip and set it in this child.
537*13101SVenki.Rajagopalan@Sun.COM */
538*13101SVenki.Rajagopalan@Sun.COM return (eibnx_update_child(ti, gwi, NULL));
539*13101SVenki.Rajagopalan@Sun.COM }
540*13101SVenki.Rajagopalan@Sun.COM
541*13101SVenki.Rajagopalan@Sun.COM int
eibnx_locate_node_name(char * devname,eibnx_thr_info_t ** ti_p,eibnx_gw_info_t ** gwi_p)542*13101SVenki.Rajagopalan@Sun.COM eibnx_locate_node_name(char *devname, eibnx_thr_info_t **ti_p,
543*13101SVenki.Rajagopalan@Sun.COM eibnx_gw_info_t **gwi_p)
544*13101SVenki.Rajagopalan@Sun.COM {
545*13101SVenki.Rajagopalan@Sun.COM eibnx_t *ss = enx_global_ss;
546*13101SVenki.Rajagopalan@Sun.COM eibnx_thr_info_t *ti;
547*13101SVenki.Rajagopalan@Sun.COM eibnx_gw_info_t *gwi;
548*13101SVenki.Rajagopalan@Sun.COM char name[MAXNAMELEN];
549*13101SVenki.Rajagopalan@Sun.COM
550*13101SVenki.Rajagopalan@Sun.COM /*
551*13101SVenki.Rajagopalan@Sun.COM * Locate the port monitor thread info and gateway info
552*13101SVenki.Rajagopalan@Sun.COM * that corresponds to the supplied devname.
553*13101SVenki.Rajagopalan@Sun.COM */
554*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->nx_lock);
555*13101SVenki.Rajagopalan@Sun.COM for (ti = ss->nx_thr_info; ti; ti = ti->ti_next) {
556*13101SVenki.Rajagopalan@Sun.COM if (ti->ti_ident[0] == '\0')
557*13101SVenki.Rajagopalan@Sun.COM continue;
558*13101SVenki.Rajagopalan@Sun.COM
559*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ti->ti_gw_lock);
560*13101SVenki.Rajagopalan@Sun.COM for (gwi = ti->ti_gw; gwi; gwi = gwi->gw_next) {
561*13101SVenki.Rajagopalan@Sun.COM (void) snprintf(name, MAXNAMELEN,
562*13101SVenki.Rajagopalan@Sun.COM "%s@%s,%x", EIB_DRV_NAME, ti->ti_ident,
563*13101SVenki.Rajagopalan@Sun.COM gwi->gw_portid);
564*13101SVenki.Rajagopalan@Sun.COM
565*13101SVenki.Rajagopalan@Sun.COM if (strcmp(name, devname) == 0)
566*13101SVenki.Rajagopalan@Sun.COM break;
567*13101SVenki.Rajagopalan@Sun.COM }
568*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ti->ti_gw_lock);
569*13101SVenki.Rajagopalan@Sun.COM
570*13101SVenki.Rajagopalan@Sun.COM if (gwi) {
571*13101SVenki.Rajagopalan@Sun.COM break;
572*13101SVenki.Rajagopalan@Sun.COM }
573*13101SVenki.Rajagopalan@Sun.COM }
574*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->nx_lock);
575*13101SVenki.Rajagopalan@Sun.COM
576*13101SVenki.Rajagopalan@Sun.COM if (ti == NULL || gwi == NULL) {
577*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
578*13101SVenki.Rajagopalan@Sun.COM }
579*13101SVenki.Rajagopalan@Sun.COM
580*13101SVenki.Rajagopalan@Sun.COM *ti_p = ti;
581*13101SVenki.Rajagopalan@Sun.COM *gwi_p = gwi;
582*13101SVenki.Rajagopalan@Sun.COM
583*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_SUCCESS);
584*13101SVenki.Rajagopalan@Sun.COM }
585*13101SVenki.Rajagopalan@Sun.COM
586*13101SVenki.Rajagopalan@Sun.COM int
eibnx_locate_unconfigured_node(eibnx_thr_info_t ** ti_p,eibnx_gw_info_t ** gwi_p)587*13101SVenki.Rajagopalan@Sun.COM eibnx_locate_unconfigured_node(eibnx_thr_info_t **ti_p, eibnx_gw_info_t **gwi_p)
588*13101SVenki.Rajagopalan@Sun.COM {
589*13101SVenki.Rajagopalan@Sun.COM eibnx_t *ss = enx_global_ss;
590*13101SVenki.Rajagopalan@Sun.COM eibnx_thr_info_t *ti;
591*13101SVenki.Rajagopalan@Sun.COM eibnx_child_t *ch;
592*13101SVenki.Rajagopalan@Sun.COM
593*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ss->nx_lock);
594*13101SVenki.Rajagopalan@Sun.COM for (ti = ss->nx_thr_info; ti; ti = ti->ti_next) {
595*13101SVenki.Rajagopalan@Sun.COM mutex_enter(&ti->ti_child_lock);
596*13101SVenki.Rajagopalan@Sun.COM for (ch = ti->ti_child; ch; ch = ch->ch_next) {
597*13101SVenki.Rajagopalan@Sun.COM if (ch->ch_dip == NULL) {
598*13101SVenki.Rajagopalan@Sun.COM *ti_p = ti;
599*13101SVenki.Rajagopalan@Sun.COM *gwi_p = ch->ch_gwi;
600*13101SVenki.Rajagopalan@Sun.COM
601*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ti->ti_child_lock);
602*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->nx_lock);
603*13101SVenki.Rajagopalan@Sun.COM
604*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_SUCCESS);
605*13101SVenki.Rajagopalan@Sun.COM }
606*13101SVenki.Rajagopalan@Sun.COM }
607*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ti->ti_child_lock);
608*13101SVenki.Rajagopalan@Sun.COM }
609*13101SVenki.Rajagopalan@Sun.COM mutex_exit(&ss->nx_lock);
610*13101SVenki.Rajagopalan@Sun.COM
611*13101SVenki.Rajagopalan@Sun.COM return (ENX_E_FAILURE);
612*13101SVenki.Rajagopalan@Sun.COM }
613*13101SVenki.Rajagopalan@Sun.COM
614*13101SVenki.Rajagopalan@Sun.COM static char *
eibnx_make_nodename(eibnx_thr_info_t * info,uint16_t gw_portid)615*13101SVenki.Rajagopalan@Sun.COM eibnx_make_nodename(eibnx_thr_info_t *info, uint16_t gw_portid)
616*13101SVenki.Rajagopalan@Sun.COM {
617*13101SVenki.Rajagopalan@Sun.COM char *name;
618*13101SVenki.Rajagopalan@Sun.COM
619*13101SVenki.Rajagopalan@Sun.COM if (info->ti_ident[0] == NULL)
620*13101SVenki.Rajagopalan@Sun.COM return (NULL);
621*13101SVenki.Rajagopalan@Sun.COM
622*13101SVenki.Rajagopalan@Sun.COM name = kmem_zalloc(MAXNAMELEN, KM_SLEEP);
623*13101SVenki.Rajagopalan@Sun.COM (void) snprintf(name, MAXNAMELEN, "%s@%s,%x", EIB_DRV_NAME,
624*13101SVenki.Rajagopalan@Sun.COM info->ti_ident, gw_portid);
625*13101SVenki.Rajagopalan@Sun.COM
626*13101SVenki.Rajagopalan@Sun.COM return (name);
627*13101SVenki.Rajagopalan@Sun.COM }
628