Print this page
8368 remove warlock leftovers from usr/src/uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/ib/mgt/ibcm/ibcm_ti.c
+++ new/usr/src/uts/common/io/ib/mgt/ibcm/ibcm_ti.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23 23 */
24 24
25 25 #include <sys/ib/mgt/ibcm/ibcm_impl.h>
26 26 #include <sys/ib/ibtl/ibti.h>
27 27 #include <sys/ib/mgt/ibcm/ibcm_arp.h>
28 28
29 29 /*
30 30 * ibcm_ti.c
31 31 * These routines implement the Communication Manager's interfaces to IBTL.
32 32 */
↓ open down ↓ |
32 lines elided |
↑ open up ↑ |
33 33
34 34 /* CM rc recycle task args structure definition */
35 35 typedef struct ibcm_taskq_recycle_arg_s {
36 36 ibt_channel_hdl_t rc_chan;
37 37 ibt_cep_flags_t control;
38 38 uint8_t hca_port_num;
39 39 ibt_recycle_handler_t func;
40 40 void *arg;
41 41 } ibcm_taskq_recycle_arg_t;
42 42
43 -_NOTE(READ_ONLY_DATA(ibcm_taskq_recycle_arg_s))
44 -
45 43 static ibt_status_t ibcm_init_reply_addr(ibcm_hca_info_t *hcap,
46 44 ibcm_mad_addr_t *reply_addr, ibt_chan_open_args_t *chan_args,
47 45 ibt_chan_open_flags_t flags, ib_time_t *cm_pkt_lt, ib_lid_t prim_slid);
48 46 static void ibcm_process_abort_via_taskq(void *args);
49 47 static ibt_status_t ibcm_process_rc_recycle_ret(void *recycle_arg);
50 48 static ibt_status_t ibcm_process_join_mcg(void *taskq_arg);
51 49 static void ibcm_process_async_join_mcg(void *tq_arg);
52 50
53 51 ibt_status_t ibcm_get_node_rec(ibmf_saa_handle_t, sa_node_record_t *,
54 52 uint64_t c_mask, void *, size_t *);
55 53
56 54 static ibt_status_t ibcm_close_rc_channel(ibt_channel_hdl_t channel,
57 55 ibcm_state_data_t *statep, ibt_execution_mode_t mode);
58 56
59 57 /* Address Record management definitions */
60 58 #define IBCM_DAPL_ATS_NAME "DAPL Address Translation Service"
61 59 #define IBCM_DAPL_ATS_SID 0x10000CE100415453ULL
62 60 #define IBCM_DAPL_ATS_NBYTES 16
63 61 ibcm_svc_info_t *ibcm_ar_svcinfop;
64 62 ibcm_ar_t *ibcm_ar_list;
65 63
66 64 /*
67 65 * Tunable parameter to turnoff the overriding of pi_path_mtu value.
68 66 * 1 By default override the path record's pi_path_mtu value to
69 67 * IB_MTU_1K for all RC channels. This is done only for the
70 68 * channels established on Tavor HCA and the path's pi_path_mtu
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
71 69 * is greater than IB_MTU_1K.
72 70 * 0 Do not override, use pi_path_mtu by default.
73 71 */
74 72 int ibcm_override_path_mtu = 1;
75 73
76 74 #ifdef DEBUG
77 75 static void ibcm_print_reply_addr(ibt_channel_hdl_t channel,
78 76 ibcm_mad_addr_t *cm_reply_addr);
79 77 #endif
80 78
81 -_NOTE(DATA_READABLE_WITHOUT_LOCK(ibcm_port_info_s::{port_ibmf_hdl}))
82 -
83 -/* access is controlled between ibcm_sm.c and ibcm_ti.c by CVs */
84 -_NOTE(SCHEME_PROTECTS_DATA("Serialized access by CV", {ibt_rc_returns_t
85 - ibt_ud_returns_t ibt_ap_returns_t ibt_ar_t}))
86 -
87 79 /*
88 - * Typically, clients initialize these args in one api call, and use in
89 - * another api
90 - */
91 -_NOTE(SCHEME_PROTECTS_DATA("Expected usage of ibtl api by client",
92 - {ibt_path_info_s ibt_cep_path_s ibt_adds_vect_s ibt_mcg_info_s ib_gid_s
93 - ibt_ud_dest_attr_s ibt_ud_dest_s ibt_srv_data_s ibt_redirect_info_s}))
94 -
95 -/*
96 80 * ibt_open_rc_channel()
97 81 * ibt_open_rc_channel opens a communication channel on the specified
98 82 * channel to the specified service. For connection service type qp's
99 83 * the CM initiates the CEP to establish the connection and transitions
100 84 * the QP/EEC to the "Ready to send" State modifying the QP/EEC's
101 85 * attributes as necessary.
102 86 * The implementation of this function assumes that alt path is different
103 87 * from primary path. It is assumed that the Path functions ensure that.
104 88 *
105 89 * RETURN VALUES:
106 90 * IBT_SUCCESS on success (or respective failure on error)
107 91 */
108 92 ibt_status_t
109 93 ibt_open_rc_channel(ibt_channel_hdl_t channel, ibt_chan_open_flags_t flags,
110 94 ibt_execution_mode_t mode, ibt_chan_open_args_t *chan_args,
111 95 ibt_rc_returns_t *ret_args)
112 96 {
113 97 /* all fields that are related to REQ MAD formation */
114 98
115 99 ib_pkey_t prim_pkey;
116 100 ib_lid_t primary_slid, alternate_slid;
117 101 ib_qpn_t local_qpn = 0;
118 102 ib_guid_t hca_guid;
119 103 ib_qkey_t local_qkey = 0;
120 104 ib_eecn_t local_eecn = 0;
121 105 ib_eecn_t remote_eecn = 0;
122 106 boolean_t primary_grh;
123 107 boolean_t alternate_grh = B_FALSE;
124 108 ib_lid_t base_lid;
125 109 ib_com_id_t local_comid;
126 110 ibmf_msg_t *ibmf_msg, *ibmf_msg_dreq;
127 111 ibcm_req_msg_t *req_msgp;
128 112
129 113 uint8_t rdma_in, rdma_out;
130 114 uint8_t cm_retries;
131 115 uint64_t local_cm_proc_time; /* In usec */
132 116 uint8_t local_cm_resp_time; /* IB time */
133 117 uint64_t remote_cm_resp_time; /* In usec */
134 118 uint32_t starting_psn = 0;
135 119
136 120 /* CM path related fields */
137 121 ibmf_handle_t ibmf_hdl;
138 122 ibcm_qp_list_t *cm_qp_entry;
139 123 ibcm_mad_addr_t cm_reply_addr;
140 124
141 125 uint8_t cm_pkt_lt;
142 126
143 127 /* Local args for ibtl/internal CM functions called within */
144 128 ibt_status_t status;
145 129 ibcm_status_t lkup_status;
146 130 ibt_qp_query_attr_t qp_query_attr;
147 131
148 132 /* Other misc local args */
149 133 ibt_priv_data_len_t len;
150 134 ibcm_hca_info_t *hcap;
151 135 ibcm_state_data_t *statep;
152 136 uint8_t port_no;
153 137
154 138 IBTF_DPRINTF_L3(cmlog, "ibt_open_rc_channel(chan %p, %X, %x, %p, %p)",
155 139 channel, flags, mode, chan_args, ret_args);
156 140
157 141 if (IBCM_INVALID_CHANNEL(channel)) {
158 142 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: invalid channel");
159 143 return (IBT_CHAN_HDL_INVALID);
160 144 }
161 145
162 146 /* cm handler should always be specified */
163 147 if (chan_args->oc_cm_handler == NULL) {
164 148 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
165 149 "CM handler is not be specified", channel);
166 150 return (IBT_INVALID_PARAM);
167 151 }
168 152
169 153 if (mode == IBT_NONBLOCKING) {
170 154 if (ret_args != NULL) {
171 155 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p"
172 156 " ret_args should be NULL when called in "
173 157 "non-blocking mode", channel);
174 158 return (IBT_INVALID_PARAM);
175 159 }
176 160 } else if (mode == IBT_BLOCKING) {
177 161 if (ret_args == NULL) {
178 162 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p"
179 163 " ret_args should be Non-NULL when called in "
180 164 "blocking mode", channel);
181 165 return (IBT_INVALID_PARAM);
182 166 }
183 167 if (ret_args->rc_priv_data_len > IBT_REP_PRIV_DATA_SZ) {
184 168 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p"
185 169 " private data length is too large", channel);
186 170 return (IBT_INVALID_PARAM);
187 171 }
188 172 if ((ret_args->rc_priv_data_len > 0) &&
189 173 (ret_args->rc_priv_data == NULL)) {
190 174 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p"
191 175 " rc_priv_data_len > 0, but rc_priv_data NULL",
192 176 channel);
193 177 return (IBT_INVALID_PARAM);
194 178 }
195 179 } else { /* any other mode is not valid for ibt_open_rc_channel */
196 180 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
197 181 "invalid mode %x specified", channel, mode);
198 182 return (IBT_INVALID_PARAM);
199 183 }
200 184
201 185 /*
202 186 * XXX: no support yet for ibt_chan_open_flags_t - IBT_OCHAN_DUP
203 187 */
204 188 if (flags & IBT_OCHAN_DUP) {
205 189 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
206 190 "Unsupported Flags specified: 0x%X", channel, flags);
207 191 return (IBT_INVALID_PARAM);
208 192 }
209 193
210 194 if ((flags & IBT_OCHAN_REDIRECTED) &&
211 195 (flags & IBT_OCHAN_PORT_REDIRECTED)) {
212 196 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
213 197 "Illegal to specify IBT_OCHAN_REDIRECTED and "
214 198 "IBT_OCHAN_PORT_REDIRECTED flags together", channel);
215 199 return (IBT_INVALID_PARAM);
216 200 }
217 201
218 202 if (((flags & IBT_OCHAN_REDIRECTED) &&
219 203 (chan_args->oc_cm_redirect_info == NULL)) ||
220 204 ((flags & IBT_OCHAN_PORT_REDIRECTED) &&
221 205 (chan_args->oc_cm_cep_path == NULL))) {
222 206 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
223 207 "Redirect flag specified, but respective arg is NULL",
224 208 channel);
225 209 return (IBT_INVALID_PARAM);
226 210 }
227 211
228 212 if ((flags & IBT_OCHAN_REDIRECTED) &&
229 213 (chan_args->oc_cm_redirect_info->rdi_dlid == 0) &&
230 214 (chan_args->oc_cm_redirect_info->rdi_gid.gid_guid == 0)) {
231 215 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
232 216 "Either rdi_dlid or rdi_gid must be specified for"
233 217 " IBT_OCHAN_REDIRECTED", channel);
234 218 return (IBT_INVALID_PARAM);
235 219 }
236 220
237 221 /* primary dlid and hca_port_num should never be zero */
238 222 port_no = IBCM_PRIM_CEP_PATH(chan_args).cep_hca_port_num;
239 223
240 224 if ((IBCM_PRIM_ADDS_VECT(chan_args).av_dlid == 0) && (port_no == 0)) {
241 225 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
242 226 "Primary Path's information is not valid", channel);
243 227 return (IBT_INVALID_PARAM);
244 228 }
245 229
246 230 /* validate SID */
247 231 if (chan_args->oc_path->pi_sid == 0) {
248 232 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
249 233 "ERROR: Service ID in path information is 0", channel);
250 234 return (IBT_INVALID_PARAM);
251 235 }
252 236 IBTF_DPRINTF_L3(cmlog, "ibt_open_rc_channel: chan 0x%p SID %llX",
253 237 channel, chan_args->oc_path->pi_sid);
254 238
255 239 /* validate rnr_retry_cnt (enum has more than 3 bits) */
256 240 if ((uint_t)chan_args->oc_path_rnr_retry_cnt > IBT_RNR_INFINITE_RETRY) {
257 241 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
258 242 "ERROR: oc_path_rnr_retry_cnt(%d) is out of range",
259 243 channel, chan_args->oc_path_rnr_retry_cnt);
260 244 return (IBT_INVALID_PARAM);
261 245 }
262 246
263 247 /*
264 248 * Ensure that client is not re-using a QP that is still associated
265 249 * with a statep
266 250 */
267 251 IBCM_GET_CHAN_PRIVATE(channel, statep);
268 252 if (statep != NULL) {
269 253 IBCM_RELEASE_CHAN_PRIVATE(channel);
270 254 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
271 255 "Channel being re-used on active side", channel);
272 256 return (IBT_CHAN_IN_USE);
273 257 }
274 258
275 259 /* Get GUID from Channel */
276 260 hca_guid = ibt_channel_to_hca_guid(channel);
277 261
278 262 /* validate QP's hca guid with that from primary path */
279 263 if (hca_guid != chan_args->oc_path->pi_hca_guid) {
280 264 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
281 265 "GUID from Channel and primary path don't match", channel);
282 266 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
283 267 "Channel GUID %llX primary path GUID %llX", channel,
284 268 hca_guid, chan_args->oc_path->pi_hca_guid);
285 269 return (IBT_CHAN_HDL_INVALID);
286 270 }
287 271
288 272 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
289 273 "Local HCA GUID %llX", channel, hca_guid);
290 274
291 275 status = ibt_query_qp(channel, &qp_query_attr);
292 276 if (status != IBT_SUCCESS) {
293 277 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
294 278 "ibt_query_qp failed %d", channel, status);
295 279 return (status);
296 280 }
297 281
298 282 /* If client specified "no port change on QP" */
299 283 if ((qp_query_attr.qp_info.qp_transport.rc.rc_path.cep_hca_port_num !=
300 284 port_no) && (flags & IBT_OCHAN_PORT_FIXED)) {
301 285 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
302 286 "chan port %d and path port %d does not match", channel,
303 287 qp_query_attr.qp_info.qp_transport.rc.rc_path. \
304 288 cep_hca_port_num, port_no);
305 289 return (IBT_INVALID_PARAM);
306 290 }
307 291
308 292 if (qp_query_attr.qp_info.qp_trans != IBT_RC_SRV) {
309 293 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
310 294 "Invalid Channel type: Applicable only to RC Channel",
311 295 channel);
312 296 return (IBT_CHAN_SRV_TYPE_INVALID);
313 297 }
314 298
315 299 /* Check if QP is in INIT state or not */
316 300 if (qp_query_attr.qp_info.qp_state != IBT_STATE_INIT) {
317 301 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
318 302 "QP is not in INIT state %x", channel,
319 303 qp_query_attr.qp_info.qp_state);
320 304 return (IBT_CHAN_STATE_INVALID);
321 305 }
322 306
323 307 local_qpn = qp_query_attr.qp_qpn;
324 308
325 309 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p Active QPN 0x%x",
326 310 channel, local_qpn);
327 311
328 312 #ifdef NO_EEC_SUPPORT_YET
329 313
330 314 if (flags & IBT_OCHAN_RDC_EXISTS) {
331 315 ibt_eec_query_attr_t eec_query_attr;
332 316
333 317 local_qkey = qp_query_attr.qp_info.qp_transport.rd_qkey;
334 318
335 319 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: RD");
336 320
337 321 status = ibt_query_eec(channel, &eec_query_attr);
338 322 if (status != IBT_SUCCESS) {
339 323 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p"
340 324 " ibt_query_eec failed %d", channel, status);
341 325 return (status);
342 326 }
343 327 local_eecn = eec_query_attr.eec_eecn;
344 328 }
345 329
346 330 #endif
347 331 if (chan_args->oc_path->pi_prim_pkt_lt > ibcm_max_ib_pkt_lt) {
348 332 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
349 333 "Huge PktLifeTime %d, Max is %d", channel,
350 334 chan_args->oc_path->pi_prim_pkt_lt, ibcm_max_ib_pkt_lt);
351 335 return (IBT_PATH_PKT_LT_TOO_HIGH);
352 336 }
353 337
354 338 /* If no HCA found return failure */
355 339 if ((hcap = ibcm_find_hca_entry(hca_guid)) == NULL) {
356 340 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
357 341 "hcap is NULL. Probably hca is not in active state",
358 342 channel);
359 343 return (IBT_CHAN_HDL_INVALID);
360 344 }
361 345
362 346 rdma_out = chan_args->oc_rdma_ra_out;
363 347 rdma_in = chan_args->oc_rdma_ra_in;
364 348
365 349 if ((rdma_in > hcap->hca_max_rdma_in_qp) ||
366 350 (rdma_out > hcap->hca_max_rdma_out_qp)) {
367 351 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
368 352 "rdma in %d/out %d values exceed hca limits(%d/%d)",
369 353 channel, rdma_in, rdma_out, hcap->hca_max_rdma_in_qp,
370 354 hcap->hca_max_rdma_out_qp);
371 355 ibcm_dec_hca_acc_cnt(hcap);
372 356 return (IBT_INVALID_PARAM);
373 357 }
374 358
375 359 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
376 360 "rdma_in %d rdma_out %d", channel, rdma_in, rdma_out);
377 361
378 362 status = ibt_get_port_state_byguid(hcap->hca_guid, port_no,
379 363 NULL, &base_lid);
380 364 if (status != IBT_SUCCESS) {
381 365 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
382 366 "primary port_num %d not active", channel, port_no);
383 367 ibcm_dec_hca_acc_cnt(hcap);
384 368 return (status);
385 369 }
386 370
387 371 /* Validate P_KEY Index */
388 372 status = ibt_index2pkey_byguid(hcap->hca_guid, port_no,
389 373 IBCM_PRIM_CEP_PATH(chan_args).cep_pkey_ix, &prim_pkey);
390 374 if (status != IBT_SUCCESS) {
391 375 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
392 376 "Invalid Primary PKeyIx %x", channel,
393 377 IBCM_PRIM_CEP_PATH(chan_args).cep_pkey_ix);
394 378 ibcm_dec_hca_acc_cnt(hcap);
395 379 return (status);
396 380 }
397 381
398 382 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
399 383 "primary_port_num %d primary_pkey 0x%x", channel, port_no,
400 384 prim_pkey);
401 385
402 386 if ((hcap->hca_port_info[port_no - 1].port_ibmf_hdl == NULL) &&
403 387 ((status = ibcm_hca_reinit_port(hcap, port_no - 1))
404 388 != IBT_SUCCESS)) {
405 389 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
406 390 "ibmf reg or callback setup failed during re-initialize",
407 391 channel);
408 392 ibcm_dec_hca_acc_cnt(hcap);
409 393 return (status);
410 394 }
411 395
412 396 ibmf_hdl = hcap->hca_port_info[port_no - 1].port_ibmf_hdl;
413 397 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
414 398 "primary ibmf_hdl = 0x%p", channel, ibmf_hdl);
415 399
416 400 primary_slid = base_lid + IBCM_PRIM_ADDS_VECT(chan_args).av_src_path;
417 401
418 402 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: channel 0x%p "
419 403 "primary SLID = %x", channel, primary_slid);
420 404
421 405 /* check first if alternate path exists or not as it is OPTIONAL */
422 406 if (IBCM_ALT_CEP_PATH(chan_args).cep_hca_port_num != 0) {
423 407 uint8_t alt_port_no;
424 408
425 409 alt_port_no = IBCM_ALT_CEP_PATH(chan_args).cep_hca_port_num;
426 410
427 411 if (chan_args->oc_path->pi_alt_pkt_lt > ibcm_max_ib_pkt_lt) {
428 412 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
429 413 "Huge Alt Pkt lt %d", channel,
430 414 chan_args->oc_path->pi_alt_pkt_lt);
431 415 ibcm_dec_hca_acc_cnt(hcap);
432 416 return (IBT_PATH_PKT_LT_TOO_HIGH);
433 417 }
434 418
435 419 if (port_no != alt_port_no) {
436 420
437 421 status = ibt_get_port_state_byguid(hcap->hca_guid,
438 422 alt_port_no, NULL, &base_lid);
439 423 if (status != IBT_SUCCESS) {
440 424
441 425 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: "
442 426 "chan 0x%p alt_port_num %d inactive %d",
443 427 channel, alt_port_no, status);
444 428 ibcm_dec_hca_acc_cnt(hcap);
445 429 return (status);
446 430 }
447 431
448 432 }
449 433 alternate_slid =
450 434 base_lid + IBCM_ALT_ADDS_VECT(chan_args).av_src_path;
451 435
452 436 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
453 437 "alternate SLID = %x", channel, alternate_slid);
454 438 }
455 439
456 440 /*
457 441 * only pkey needs to be zero'ed, because all other fields are set in
458 442 * in ibcm_init_reply_addr. But, let's bzero the complete struct for
459 443 * any future modifications.
460 444 */
461 445 bzero(&cm_reply_addr, sizeof (cm_reply_addr));
462 446
463 447 /* Initialize the MAD destination address in stored_reply_addr */
464 448 if ((status = ibcm_init_reply_addr(hcap, &cm_reply_addr, chan_args,
465 449 flags, &cm_pkt_lt, primary_slid)) != IBT_SUCCESS) {
466 450
467 451 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
468 452 "ibcm_init_reply_addr failed status %d ", channel, status);
469 453 ibcm_dec_hca_acc_cnt(hcap);
470 454 return (status);
471 455 }
472 456
473 457
474 458 /* Initialize the pkey for CM MAD communication */
475 459 if (cm_reply_addr.rcvd_addr.ia_p_key == 0)
476 460 cm_reply_addr.rcvd_addr.ia_p_key = prim_pkey;
477 461
478 462 #ifdef DEBUG
479 463 ibcm_print_reply_addr(channel, &cm_reply_addr);
480 464 #endif
481 465
482 466 /* Retrieve an ibmf qp for sending CM MADs */
483 467 if ((cm_qp_entry = ibcm_find_qp(hcap, port_no,
484 468 cm_reply_addr.rcvd_addr.ia_p_key)) == NULL) {
485 469 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
486 470 "unable to allocate ibmf qp for CM MADs", channel);
487 471 ibcm_dec_hca_acc_cnt(hcap);
488 472 return (IBT_INSUFF_RESOURCE);
489 473 }
490 474
491 475
492 476 if (ibcm_alloc_comid(hcap, &local_comid) != IBCM_SUCCESS) {
493 477 ibcm_release_qp(cm_qp_entry);
494 478 ibcm_dec_hca_acc_cnt(hcap);
495 479 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p"
496 480 " Unable to allocate comid", channel);
497 481 return (IBT_INSUFF_KERNEL_RESOURCE);
498 482 }
499 483
500 484 /* allocate an IBMF mad buffer (REQ) */
501 485 if ((status = ibcm_alloc_out_msg(ibmf_hdl, &ibmf_msg,
502 486 MAD_METHOD_SEND)) != IBT_SUCCESS) {
503 487 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: "
504 488 "chan 0x%p ibcm_alloc_out_msg failed", channel);
505 489 ibcm_release_qp(cm_qp_entry);
506 490 ibcm_free_comid(hcap, local_comid);
507 491 ibcm_dec_hca_acc_cnt(hcap);
508 492 return (status);
509 493 }
510 494
511 495 /* allocate an IBMF mad buffer (DREQ) */
512 496 if ((status = ibcm_alloc_out_msg(ibmf_hdl, &ibmf_msg_dreq,
513 497 MAD_METHOD_SEND)) != IBT_SUCCESS) {
514 498 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: "
515 499 "chan 0x%p ibcm_alloc_out_msg failed", channel);
516 500 (void) ibcm_free_out_msg(ibmf_hdl, &ibmf_msg);
517 501 ibcm_release_qp(cm_qp_entry);
518 502 ibcm_free_comid(hcap, local_comid);
519 503 ibcm_dec_hca_acc_cnt(hcap);
520 504 return (status);
521 505 }
522 506
523 507 /* Init to Init, if QP's port does not match with path information */
524 508 if (qp_query_attr.qp_info.qp_transport.rc.rc_path.cep_hca_port_num !=
525 509 IBCM_PRIM_CEP_PATH(chan_args).cep_hca_port_num) {
526 510
527 511 ibt_qp_info_t qp_info;
528 512 ibt_cep_modify_flags_t cep_flags;
529 513
530 514 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: "
531 515 "chan 0x%p chan port %d", channel,
532 516 qp_query_attr.qp_info.qp_transport.rc.rc_path.\
533 517 cep_hca_port_num);
534 518
535 519 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: "
536 520 "chan 0x%p path port %d", channel, port_no);
537 521
538 522 bzero(&qp_info, sizeof (qp_info));
539 523 /* For now, set it to RC type */
540 524
541 525 qp_info.qp_trans = IBT_RC_SRV;
542 526 qp_info.qp_state = IBT_STATE_INIT;
543 527 qp_info.qp_transport.rc.rc_path.cep_hca_port_num = port_no;
544 528
545 529 cep_flags = IBT_CEP_SET_STATE | IBT_CEP_SET_PORT;
546 530
547 531 status = ibt_modify_qp(channel, cep_flags, &qp_info, NULL);
548 532
549 533 if (status != IBT_SUCCESS) {
550 534 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: "
551 535 "chan 0x%p ibt_modify_qp() = %d", channel, status);
552 536 ibcm_release_qp(cm_qp_entry);
553 537 ibcm_free_comid(hcap, local_comid);
554 538 ibcm_dec_hca_acc_cnt(hcap);
555 539 (void) ibcm_free_out_msg(ibmf_hdl, &ibmf_msg);
556 540 (void) ibcm_free_out_msg(ibmf_hdl, &ibmf_msg_dreq);
557 541 return (status);
558 542 } else
559 543 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: "
560 544 "chan 0x%p ibt_modify_qp() = %d", channel, status);
561 545 }
562 546
563 547 /* allocate ibcm_state_data_t before grabbing the WRITER lock */
564 548 statep = kmem_zalloc(sizeof (ibcm_state_data_t), KM_SLEEP);
565 549 rw_enter(&hcap->hca_state_rwlock, RW_WRITER);
566 550 lkup_status = ibcm_lookup_msg(IBCM_OUTGOING_REQ, local_comid, 0, 0,
567 551 hcap, &statep);
568 552 rw_exit(&hcap->hca_state_rwlock);
↓ open down ↓ |
463 lines elided |
↑ open up ↑ |
569 553
570 554 /* CM should be seeing this for the first time */
571 555 ASSERT(lkup_status == IBCM_LOOKUP_NEW);
572 556
573 557 /* Increment the hca's resource count */
574 558 ibcm_inc_hca_res_cnt(hcap);
575 559
576 560 /* Once a resource created on hca, no need to hold the acc cnt */
577 561 ibcm_dec_hca_acc_cnt(hcap);
578 562
579 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
580 -
581 563 statep->timerid = 0;
582 564 statep->local_hca_guid = hca_guid;
583 565 statep->local_qpn = local_qpn;
584 566 statep->stored_reply_addr.cm_qp_entry = cm_qp_entry;
585 567 statep->prim_port = IBCM_PRIM_CEP_PATH(chan_args).cep_hca_port_num;
586 568 statep->alt_port = IBCM_ALT_CEP_PATH(chan_args).cep_hca_port_num;
587 569
588 570
589 571 /* Save "statep" as channel's CM private data. */
590 572 statep->channel = channel;
591 573 IBCM_SET_CHAN_PRIVATE(statep->channel, statep);
592 574
593 575 statep->stored_msg = ibmf_msg;
594 576 statep->dreq_msg = ibmf_msg_dreq;
595 577
596 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*req_msgp))
597 -
598 578 /* Start filling in the REQ MAD */
599 579 req_msgp = (ibcm_req_msg_t *)IBCM_OUT_MSGP(statep->stored_msg);
600 580 req_msgp->req_local_comm_id = h2b32(local_comid);
601 581 req_msgp->req_svc_id = h2b64(chan_args->oc_path->pi_sid);
602 582 req_msgp->req_local_ca_guid = h2b64(hca_guid);
603 583 req_msgp->req_local_qkey = h2b32(local_qkey); /* for EEC/RD */
604 584
605 585 /* Bytes 32-35 are req_local_qpn and req_off_resp_resources */
606 586 req_msgp->req_local_qpn_plus = h2b32(local_qpn << 8 | rdma_in);
607 587
608 588 /* Bytes 36-39 are req_local_eec_no and req_off_initiator_depth */
609 589 req_msgp->req_local_eec_no_plus = h2b32(local_eecn << 8 | rdma_out);
610 590
611 591 if (flags & IBT_OCHAN_REMOTE_CM_TM)
612 592 remote_cm_resp_time = chan_args->oc_remote_cm_time;
613 593 else
614 594 remote_cm_resp_time = ibcm_remote_response_time;
615 595
616 596 /*
617 597 * Bytes 40-43 - remote_eecn, remote_cm_resp_time, tran_type,
618 598 * IBT_CM_FLOW_CONTROL is always set by default.
619 599 */
620 600 req_msgp->req_remote_eecn_plus = h2b32(
621 601 remote_eecn << 8 | (ibt_usec2ib(remote_cm_resp_time) & 0x1f) << 3 |
622 602 IBT_RC_SRV << 1 | IBT_CM_FLOW_CONTROL);
623 603
624 604 if (flags & IBT_OCHAN_LOCAL_CM_TM)
625 605 local_cm_proc_time = chan_args->oc_local_cm_time;
626 606 else
627 607 local_cm_proc_time = ibcm_local_processing_time;
628 608
629 609 local_cm_resp_time = ibt_usec2ib(local_cm_proc_time +
630 610 2 * ibt_ib2usec(chan_args->oc_path->pi_prim_pkt_lt) +
631 611 ibcm_sw_delay);
632 612
633 613 /* save retry count */
634 614 statep->cep_retry_cnt = chan_args->oc_path_retry_cnt;
635 615
636 616 if (flags & IBT_OCHAN_STARTING_PSN)
637 617 starting_psn = chan_args->oc_starting_psn;
638 618
639 619 if (local_cm_resp_time > 0x1f)
640 620 local_cm_resp_time = 0x1f;
641 621
642 622 /* Bytes 44-47 are req_starting_psn, local_cm_resp_time and retry_cnt */
643 623 req_msgp->req_starting_psn_plus = h2b32(starting_psn << 8 |
644 624 local_cm_resp_time << 3 | statep->cep_retry_cnt);
645 625
646 626 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
647 627 "Prim Pkt lt (IB time) 0x%x", channel,
648 628 chan_args->oc_path->pi_prim_pkt_lt);
649 629
650 630 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
651 631 "local_cm_proc_time(usec) %d ", channel, local_cm_proc_time);
652 632
653 633 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
654 634 "local_cm_resp_time(ib_time) %d", channel, local_cm_resp_time);
655 635
656 636 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
657 637 "remote_cm_resp_time (usec) %d", channel, remote_cm_resp_time);
658 638
659 639 statep->starting_psn = starting_psn;
660 640
661 641 /* Pkey - bytes 48-49 */
662 642 req_msgp->req_part_key = h2b16(prim_pkey);
663 643
664 644 if (flags & IBT_OCHAN_CM_RETRY)
665 645 cm_retries = chan_args->oc_cm_retry_cnt;
666 646 else
667 647 cm_retries = ibcm_max_retries;
668 648
669 649 statep->max_cm_retries = statep->remaining_retry_cnt = cm_retries;
670 650 req_msgp->req_max_cm_retries_plus = statep->max_cm_retries << 4;
671 651
672 652 /*
673 653 * Check whether SRQ is associated with this Channel, if yes, then
674 654 * set the SRQ Exists bit in the REQ.
675 655 */
676 656 if (qp_query_attr.qp_srq != NULL) {
677 657 req_msgp->req_max_cm_retries_plus |= (1 << 3);
678 658 }
679 659
680 660 /*
681 661 * By default on Tavor, we override the PathMTU to 1K.
682 662 * To turn this off, set ibcm_override_path_mtu = 0.
683 663 */
684 664 if (ibcm_override_path_mtu && IBCM_IS_HCA_TAVOR(hcap) &&
685 665 (chan_args->oc_path->pi_path_mtu > IB_MTU_1K)) {
686 666 req_msgp->req_mtu_plus = IB_MTU_1K << 4 |
687 667 chan_args->oc_path_rnr_retry_cnt;
688 668 IBTF_DPRINTF_L3(cmlog, "ibt_open_rc_channel: chan 0x%p PathMTU"
689 669 " overridden to IB_MTU_1K(%d) from %d", channel, IB_MTU_1K,
690 670 chan_args->oc_path->pi_path_mtu);
691 671 } else
692 672 req_msgp->req_mtu_plus = chan_args->oc_path->pi_path_mtu << 4 |
693 673 chan_args->oc_path_rnr_retry_cnt;
694 674
695 675 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p CM retry cnt %d"
696 676 " staring PSN %x", channel, cm_retries, starting_psn);
697 677
698 678
699 679 #ifdef NO_EEC_SUPPORT_YET
700 680 if (flags & IBT_OCHAN_RDC_EXISTS)
701 681 req_msgp->req_mtu_plus |= 8;
702 682 #endif
703 683
704 684 /* Initialize the "primary" port stuff next - bytes 52-95 */
705 685 req_msgp->req_primary_l_port_lid = h2b16(primary_slid);
706 686 req_msgp->req_primary_r_port_lid =
707 687 h2b16(IBCM_PRIM_ADDS_VECT(chan_args).av_dlid);
708 688 req_msgp->req_primary_l_port_gid.gid_prefix =
709 689 h2b64(IBCM_PRIM_ADDS_VECT(chan_args).av_sgid.gid_prefix);
710 690 req_msgp->req_primary_l_port_gid.gid_guid =
711 691 h2b64(IBCM_PRIM_ADDS_VECT(chan_args).av_sgid.gid_guid);
712 692 req_msgp->req_primary_r_port_gid.gid_prefix =
713 693 h2b64(IBCM_PRIM_ADDS_VECT(chan_args).av_dgid.gid_prefix);
714 694 req_msgp->req_primary_r_port_gid.gid_guid =
715 695 h2b64(IBCM_PRIM_ADDS_VECT(chan_args).av_dgid.gid_guid);
716 696 primary_grh = IBCM_PRIM_ADDS_VECT(chan_args).av_send_grh;
717 697
718 698 statep->remote_hca_guid = /* not correct, but helpful for debugging */
719 699 IBCM_PRIM_ADDS_VECT(chan_args).av_dgid.gid_guid;
720 700
721 701 /* Bytes 88-91 - primary_flowlbl, and primary_srate */
722 702 req_msgp->req_primary_flow_label_plus =
723 703 h2b32(((primary_grh == B_TRUE) ?
724 704 (IBCM_PRIM_ADDS_VECT(chan_args).av_flow << 12) : 0) |
725 705 IBCM_PRIM_ADDS_VECT(chan_args).av_srate);
726 706 req_msgp->req_primary_traffic_class = (primary_grh == B_TRUE) ?
727 707 IBCM_PRIM_ADDS_VECT(chan_args).av_tclass : 0;
728 708 req_msgp->req_primary_hop_limit = (primary_grh == B_TRUE) ?
729 709 IBCM_PRIM_ADDS_VECT(chan_args).av_hop : 1;
730 710 req_msgp->req_primary_sl_plus =
731 711 IBCM_PRIM_ADDS_VECT(chan_args).av_srvl << 4 |
732 712 ((primary_grh == B_TRUE) ? 0 : 8);
733 713
734 714 req_msgp->req_primary_localtime_plus =
735 715 ibt_usec2ib((2 * ibt_ib2usec(chan_args->oc_path->pi_prim_pkt_lt)) +
736 716 ibt_ib2usec(hcap->hca_ack_delay)) << 3;
737 717
738 718 IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan %p statep %p",
739 719 channel, statep);
740 720 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
741 721 "active hca_ack_delay (usec) %d", channel,
742 722 req_msgp->req_primary_localtime_plus);
743 723
744 724 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
745 725 "Sent primary cep timeout (IB Time) %d", channel,
746 726 hcap->hca_ack_delay);
747 727
748 728 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p prim_dlid %x ",
749 729 channel, IBCM_PRIM_ADDS_VECT(chan_args).av_dlid);
750 730
751 731 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
752 732 "prim GID %llX:%llX", channel,
753 733 IBCM_PRIM_ADDS_VECT(chan_args).av_dgid.gid_prefix,
754 734 IBCM_PRIM_ADDS_VECT(chan_args).av_dgid.gid_guid);
755 735
756 736 /* Initialize the "alternate" port stuff - optional */
757 737 if (chan_args->oc_path->pi_alt_cep_path.cep_hca_port_num != 0) {
758 738 ib_gid_t tmp_gid;
759 739
760 740 req_msgp->req_alt_l_port_lid = h2b16(alternate_slid);
761 741 req_msgp->req_alt_r_port_lid =
762 742 h2b16(IBCM_ALT_ADDS_VECT(chan_args).av_dlid);
763 743 /*
764 744 * doing all this as req_alt_r/l_port_gid is at offset
765 745 * 100, 116 which is not divisible by 8
766 746 */
767 747
768 748 tmp_gid.gid_prefix =
769 749 h2b64(IBCM_ALT_ADDS_VECT(chan_args).av_dgid.gid_prefix);
770 750 tmp_gid.gid_guid =
771 751 h2b64(IBCM_ALT_ADDS_VECT(chan_args).av_dgid.gid_guid);
772 752 bcopy(&tmp_gid, &req_msgp->req_alt_r_port_gid[0],
773 753 sizeof (ib_gid_t));
774 754 tmp_gid.gid_prefix =
775 755 h2b64(IBCM_ALT_ADDS_VECT(chan_args).av_sgid.gid_prefix);
776 756 tmp_gid.gid_guid =
777 757 h2b64(IBCM_ALT_ADDS_VECT(chan_args).av_sgid.gid_guid);
778 758
779 759 bcopy(&tmp_gid, &req_msgp->req_alt_l_port_gid[0],
780 760 sizeof (ib_gid_t));
781 761 alternate_grh = IBCM_ALT_ADDS_VECT(chan_args).av_send_grh;
782 762
783 763 /* Bytes 132-135 - alternate_flow_label, and alternate srate */
784 764 req_msgp->req_alt_flow_label_plus = h2b32(
785 765 (((alternate_grh == B_TRUE) ?
786 766 (IBCM_ALT_ADDS_VECT(chan_args).av_flow << 12) : 0) |
787 767 IBCM_ALT_ADDS_VECT(chan_args).av_srate));
788 768 req_msgp->req_alt_traffic_class = (alternate_grh == B_TRUE) ?
789 769 IBCM_ALT_ADDS_VECT(chan_args).av_tclass : 0;
790 770 req_msgp->req_alt_hop_limit = (alternate_grh == B_TRUE) ?
791 771 IBCM_ALT_ADDS_VECT(chan_args).av_hop : 1;
792 772 req_msgp->req_alt_sl_plus =
793 773 IBCM_ALT_ADDS_VECT(chan_args).av_srvl << 4 |
794 774 ((alternate_grh == B_TRUE) ? 0 : 8);
795 775 req_msgp->req_alt_localtime_plus = ibt_usec2ib((2 *
796 776 ibt_ib2usec(chan_args->oc_path->pi_alt_pkt_lt)) +
797 777 ibt_ib2usec(hcap->hca_ack_delay)) << 3;
798 778
799 779 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
800 780 "alt_dlid %x ", channel,
801 781 IBCM_ALT_ADDS_VECT(chan_args).av_dlid);
802 782
↓ open down ↓ |
195 lines elided |
↑ open up ↑ |
803 783 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
804 784 "alt GID %llX:%llX", channel,
805 785 IBCM_ALT_ADDS_VECT(chan_args).av_dgid.gid_prefix,
806 786 IBCM_ALT_ADDS_VECT(chan_args).av_dgid.gid_guid);
807 787 }
808 788
809 789 len = min(chan_args->oc_priv_data_len, IBT_REQ_PRIV_DATA_SZ);
810 790 if ((len > 0) && chan_args->oc_priv_data)
811 791 bcopy(chan_args->oc_priv_data, req_msgp->req_private_data, len);
812 792
813 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*req_msgp))
814 -
815 793 /* return_data is filled up in the state machine code */
816 794 if (ret_args != NULL) {
817 795 statep->open_return_data = ret_args;
818 796 }
819 797
820 798 /* initialize some statep fields here */
821 799 statep->mode = IBCM_ACTIVE_MODE;
822 800 statep->hcap = hcap;
823 801
824 802 statep->cm_handler = chan_args->oc_cm_handler;
825 803 statep->state_cm_private = chan_args->oc_cm_clnt_private;
826 804
827 805 statep->pkt_life_time =
828 806 ibt_ib2usec(chan_args->oc_path->pi_prim_pkt_lt);
829 807
830 808 statep->timer_value = ibt_ib2usec(ibt_usec2ib(
831 809 2 * ibt_ib2usec(cm_pkt_lt) + remote_cm_resp_time));
832 810
833 811 /* Initialize statep->stored_reply_addr */
834 812 statep->stored_reply_addr.ibmf_hdl = ibmf_hdl;
835 813
836 814 /* Initialize stored reply addr fields */
837 815 statep->stored_reply_addr.grh_hdr = cm_reply_addr.grh_hdr;
838 816 statep->stored_reply_addr.rcvd_addr = cm_reply_addr.rcvd_addr;
839 817 statep->stored_reply_addr.grh_exists = cm_reply_addr.grh_exists;
840 818 statep->stored_reply_addr.port_num = cm_reply_addr.port_num;
841 819
842 820 /*
843 821 * The IPD on local/active side is calculated by path functions,
844 822 * hence available in the args of ibt_open_rc_channel
845 823 */
846 824 statep->local_srate = IBCM_PRIM_ADDS_VECT(chan_args).av_srate;
847 825 statep->local_alt_srate = IBCM_ALT_ADDS_VECT(chan_args).av_srate;
848 826
849 827 /* Store the source path bits for primary and alt paths */
850 828 statep->prim_src_path_bits = IBCM_PRIM_ADDS_VECT(chan_args).av_src_path;
851 829 statep->alt_src_path_bits = IBCM_ALT_ADDS_VECT(chan_args).av_src_path;
852 830
853 831 statep->open_flow = 1;
854 832 statep->open_done = B_FALSE;
855 833 statep->state = statep->timer_stored_state = IBCM_STATE_REQ_SENT;
856 834 IBCM_REF_CNT_INCR(statep); /* Decremented before return */
857 835 IBCM_REF_CNT_INCR(statep); /* Decremented after REQ is posted */
858 836 statep->send_mad_flags |= IBCM_REQ_POST_BUSY;
859 837
860 838 /*
861 839 * Skip moving channel to error state during close, for OFUV clients.
862 840 * OFUV clients transition the channel to error state by itself.
863 841 */
↓ open down ↓ |
39 lines elided |
↑ open up ↑ |
864 842 if (flags & IBT_OCHAN_OFUV)
865 843 statep->is_this_ofuv_chan = B_TRUE;
866 844
867 845 IBCM_OUT_HDRP(statep->stored_msg)->AttributeID =
868 846 h2b16(IBCM_INCOMING_REQ + IBCM_ATTR_BASE_ID);
869 847
870 848 IBCM_OUT_HDRP(statep->stored_msg)->TransactionID =
871 849 h2b64(ibcm_generate_tranid(IBCM_INCOMING_REQ, statep->local_comid,
872 850 0));
873 851
874 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*statep))
875 -
876 852 ibtl_cm_chan_is_opening(channel);
877 853
878 854 ibcm_open_enqueue(statep);
879 855
880 856 mutex_enter(&statep->state_mutex);
881 857
882 858 if (mode == IBT_BLOCKING) {
883 859
884 860 /* wait for REQ/REP/RTU */
885 861 while (statep->open_done != B_TRUE) {
886 862 cv_wait(&statep->block_client_cv, &statep->state_mutex);
887 863 }
888 864
889 865 /*
890 866 * In the case that open_channel() fails because of a
891 867 * REJ or timeout, change retval to IBT_CM_FAILURE
892 868 */
893 869 if (statep->open_return_data->rc_status != IBT_CM_SUCCESS) {
894 870 status = IBT_CM_FAILURE;
895 871 ibtl_cm_chan_open_is_aborted(channel);
896 872 }
897 873
898 874 IBTF_DPRINTF_L3(cmlog, "ibt_open_rc_channel: chan 0x%p "
899 875 "ret status %d cm status %d", channel, status,
900 876 statep->open_return_data->rc_status);
901 877 }
902 878
903 879 /* decrement the ref-count before leaving here */
904 880 IBCM_REF_CNT_DECR(statep);
905 881
906 882 mutex_exit(&statep->state_mutex);
907 883
908 884 IBTF_DPRINTF_L4(cmlog, "ibt_open_rc_channel: chan 0x%p done", channel);
909 885 return (status);
910 886 }
911 887
912 888 /*
913 889 * ibcm_init_reply_addr:
914 890 *
915 891 * The brief description of functionality below.
916 892 *
917 893 * For IBT_OCHAN_PORT_REDIRECTED (ie., port redirected case):
918 894 * Build CM path from chan_args->oc_cm_cep_path
919 895 * Set CM pkt lt (ie.,life time) to chan_args->oc_cm_pkt_lt
920 896 *
921 897 * For IBT_OCHAN_REDIRECTED (ie., port and CM redirected case):
922 898 * If Redirect LID is specified,
923 899 * If Redirect GID is not specified or specified to be on the same
924 900 * subnet, then
925 901 * Build CM path from chan_args->oc_cm_redirect_info
926 902 * Set CM pkt lt to subnet timeout
927 903 * Else (ie., GID specified, but on a different subnet)
928 904 * Do a path lookup to build CM Path and set CM pkt lt
929 905 *
930 906 */
931 907 static ibt_status_t
932 908 ibcm_init_reply_addr(ibcm_hca_info_t *hcap, ibcm_mad_addr_t *reply_addr,
↓ open down ↓ |
47 lines elided |
↑ open up ↑ |
933 909 ibt_chan_open_args_t *chan_args, ibt_chan_open_flags_t flags,
934 910 ib_time_t *cm_pkt_lt, ib_lid_t prim_slid)
935 911 {
936 912 ibt_adds_vect_t *cm_adds;
937 913 ibt_path_info_t path;
938 914 boolean_t cm_grh;
939 915 ibt_status_t status;
940 916
941 917 IBTF_DPRINTF_L5(cmlog, "ibcm_init_reply_addr:");
942 918
943 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*reply_addr))
944 -
945 919 /*
946 920 * sending side CM lid/gid/port num are not based on any redirect
947 921 * params. These values are set to primary RC path lid/gid/port num.
948 922 * In the future, these values can be set based on framework policy
949 923 * decisions ensuring reachability.
950 924 */
951 925 reply_addr->grh_hdr.ig_sender_gid =
952 926 IBCM_PRIM_ADDS_VECT(chan_args).av_sgid;
953 927 reply_addr->rcvd_addr.ia_local_lid = prim_slid;
954 928 reply_addr->port_num = IBCM_PRIM_CEP_PATH(chan_args).cep_hca_port_num;
955 929
956 930 if (flags & IBT_OCHAN_PORT_REDIRECTED) {
957 931 IBTF_DPRINTF_L4(cmlog, "ibcm_init_rely_addr: "
958 932 "IBT_OCHAN_PORT_REDIRECTED specified");
959 933
960 934 status = ibt_index2pkey_byguid(hcap->hca_guid,
961 935 chan_args->oc_cm_cep_path->cep_hca_port_num,
962 936 chan_args->oc_cm_cep_path->cep_pkey_ix,
963 937 &reply_addr->rcvd_addr.ia_p_key);
964 938
965 939 if (status != IBT_SUCCESS) {
966 940 IBTF_DPRINTF_L2(cmlog, "ibcm_init_rely_addr: Invalid "
967 941 "CM PKeyIx %x port_num %x",
968 942 chan_args->oc_cm_cep_path->cep_pkey_ix,
969 943 chan_args->oc_cm_cep_path->cep_hca_port_num);
970 944 return (status);
971 945 }
972 946
973 947 cm_adds = &(chan_args->oc_cm_cep_path->cep_adds_vect);
974 948 IBTF_DPRINTF_L4(cmlog, "ibcm_init_rely_addr: dlid = %x",
975 949 cm_adds->av_dlid);
976 950
977 951 reply_addr->rcvd_addr.ia_q_key = IB_GSI_QKEY;
978 952 reply_addr->rcvd_addr.ia_remote_qno = 1;
979 953 *cm_pkt_lt = chan_args->oc_cm_pkt_lt;
980 954
981 955 } else if (flags & IBT_OCHAN_REDIRECTED) {
982 956 ibt_redirect_info_t *redirect_info;
983 957 ibt_hca_portinfo_t *port_infop;
984 958 uint_t psize, nports;
985 959
986 960 IBTF_DPRINTF_L4(cmlog, "ibcm_init_rely_addr: "
987 961 "IBT_OCHAN_REDIRECTED specified");
988 962
989 963 redirect_info = chan_args->oc_cm_redirect_info;
990 964
991 965 if ((redirect_info->rdi_gid.gid_prefix == 0) ||
992 966 (redirect_info->rdi_gid.gid_guid == 0)) {
993 967 IBTF_DPRINTF_L2(cmlog, "ibcm_init_reply_addr: "
994 968 "ERROR: Re-direct GID value NOT Provided.");
995 969 return (IBT_INVALID_PARAM);
996 970 }
997 971
998 972 /* As per spec definition 1.1, it's always IB_GSI_QKEY */
999 973 reply_addr->rcvd_addr.ia_q_key = redirect_info->rdi_qkey;
1000 974 reply_addr->rcvd_addr.ia_remote_qno = redirect_info->rdi_qpn;
1001 975 reply_addr->rcvd_addr.ia_p_key = redirect_info->rdi_pkey;
1002 976
1003 977 /*
1004 978 * if LID is non-zero in classportinfo then use classportinfo
1005 979 * fields to form CM MAD destination address.
1006 980 */
1007 981 if (redirect_info->rdi_dlid != 0) {
1008 982 status = ibtl_cm_query_hca_ports_byguid(hcap->hca_guid,
1009 983 reply_addr->port_num, &port_infop, &nports, &psize);
1010 984 if ((status != IBT_SUCCESS) || (nports == 0)) {
1011 985 IBTF_DPRINTF_L2(cmlog, "ibcm_init_reply_addr: "
1012 986 "Query Ports Failed: %d", status);
1013 987 return (status);
1014 988 } else if (port_infop->p_subnet_timeout >
1015 989 ibcm_max_ib_pkt_lt) {
1016 990 IBTF_DPRINTF_L2(cmlog, "ibcm_init_reply_addr: "
1017 991 "large subnet timeout %x port_no %x",
1018 992 port_infop->p_subnet_timeout,
1019 993 reply_addr->port_num);
1020 994 ibt_free_portinfo(port_infop, psize);
1021 995 return (IBT_PATH_PKT_LT_TOO_HIGH);
1022 996 } else {
1023 997 IBTF_DPRINTF_L3(cmlog, "ibcm_init_reply_addr: "
1024 998 "subnet timeout %x port_no %x",
1025 999 port_infop->p_subnet_timeout,
1026 1000 reply_addr->port_num);
1027 1001
1028 1002 *cm_pkt_lt =
1029 1003 ibt_ib2usec(min(ibcm_max_ib_mad_pkt_lt,
1030 1004 port_infop->p_subnet_timeout));
1031 1005
1032 1006 ibt_free_portinfo(port_infop, psize);
1033 1007 }
1034 1008
1035 1009 reply_addr->rcvd_addr.ia_remote_lid =
1036 1010 redirect_info->rdi_dlid;
1037 1011 reply_addr->rcvd_addr.ia_service_level =
1038 1012 redirect_info->rdi_sl;
1039 1013 reply_addr->grh_exists = B_TRUE;
1040 1014 reply_addr->grh_hdr.ig_recver_gid =
1041 1015 redirect_info->rdi_gid;
1042 1016 reply_addr->grh_hdr.ig_tclass =
1043 1017 redirect_info->rdi_tclass;
1044 1018 reply_addr->grh_hdr.ig_flow_label =
1045 1019 redirect_info->rdi_flow;
1046 1020
1047 1021 /* Classportinfo doesn't have hoplimit field */
1048 1022 reply_addr->grh_hdr.ig_hop_limit = 1;
1049 1023 return (IBT_SUCCESS);
1050 1024
1051 1025 } else {
1052 1026 ibt_path_attr_t path_attr;
1053 1027 ib_gid_t path_dgid[1];
1054 1028
1055 1029 /*
1056 1030 * If GID is specified, and LID is zero in classportinfo
1057 1031 * do a path lookup using specified GID, Pkey,
1058 1032 * in classportinfo
1059 1033 */
1060 1034
1061 1035 bzero(&path_attr, sizeof (path_attr));
1062 1036
1063 1037 path_attr.pa_dgids = &path_dgid[0];
1064 1038 path_attr.pa_dgids[0] = redirect_info->rdi_gid;
1065 1039
1066 1040 /*
1067 1041 * use reply_addr below, as sender_gid in reply_addr
1068 1042 * may have been set above based on some policy decision
1069 1043 * for originating end point for CM MADs above
1070 1044 */
1071 1045 path_attr.pa_sgid = reply_addr->grh_hdr.ig_sender_gid;
1072 1046 path_attr.pa_num_dgids = 1;
1073 1047 path_attr.pa_pkey = redirect_info->rdi_pkey;
1074 1048
1075 1049 if ((status = ibt_get_paths(ibcm_ibt_handle,
1076 1050 IBT_PATH_PKEY, &path_attr, 1, &path, NULL)) !=
1077 1051 IBT_SUCCESS)
1078 1052 return (status);
1079 1053
1080 1054 /* Initialize cm_adds */
1081 1055 cm_adds = &path.pi_prim_cep_path.cep_adds_vect;
1082 1056 *cm_pkt_lt = path.pi_prim_pkt_lt;
1083 1057 }
1084 1058
1085 1059 } else { /* cm_pkey initialized in ibt_open_rc_channel */
1086 1060 reply_addr->rcvd_addr.ia_q_key = IB_GSI_QKEY;
1087 1061 reply_addr->rcvd_addr.ia_remote_qno = 1;
1088 1062 *cm_pkt_lt = chan_args->oc_path->pi_prim_pkt_lt;
1089 1063 cm_adds = &(IBCM_PRIM_ADDS_VECT(chan_args));
1090 1064 }
1091 1065
1092 1066
1093 1067 cm_grh = cm_adds->av_send_grh;
1094 1068 reply_addr->grh_exists = cm_grh;
1095 1069
1096 1070 reply_addr->rcvd_addr.ia_remote_lid =
1097 1071 cm_adds->av_dlid;
1098 1072 reply_addr->grh_hdr.ig_recver_gid =
↓ open down ↓ |
144 lines elided |
↑ open up ↑ |
1099 1073 cm_adds->av_dgid;
1100 1074 reply_addr->grh_hdr.ig_flow_label =
1101 1075 cm_adds->av_flow & IB_GRH_FLOW_LABEL_MASK;
1102 1076 reply_addr->grh_hdr.ig_tclass =
1103 1077 (cm_grh == B_TRUE) ? cm_adds->av_tclass : 0;
1104 1078 reply_addr->grh_hdr.ig_hop_limit =
1105 1079 (cm_grh == B_TRUE) ? cm_adds->av_hop : 1;
1106 1080 reply_addr->rcvd_addr.ia_service_level =
1107 1081 cm_adds->av_srvl;
1108 1082
1109 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*reply_addr))
1110 -
1111 1083 return (IBT_SUCCESS);
1112 1084 }
1113 1085
1114 1086
1115 1087 /*
1116 1088 * ibt_prime_close_rc_channel()
1117 1089 * It allocates resources required for close channel operation, so
1118 1090 * ibt_close_rc_channel can be called from interrupt routine.
1119 1091 *
1120 1092 * INPUTS:
1121 1093 * channel The address of an ibt_channel_t struct that
1122 1094 * specifies the channel to open.
1123 1095 *
1124 1096 * RETURN VALUES:
1125 1097 * IBT_SUCCESS on success(or respective failure on error)
1126 1098 *
1127 1099 * Clients are typically expected to call this function in established state
1128 1100 */
1129 1101 ibt_status_t
1130 1102 ibt_prime_close_rc_channel(ibt_channel_hdl_t channel)
1131 1103 {
1132 1104 ibcm_state_data_t *statep;
1133 1105 ibt_status_t status = IBT_SUCCESS;
1134 1106
1135 1107 IBTF_DPRINTF_L3(cmlog, "ibt_prime_close_rc_channel(%p)", channel);
1136 1108
1137 1109 /* validate channel, first */
1138 1110 if (IBCM_INVALID_CHANNEL(channel)) {
1139 1111 IBTF_DPRINTF_L2(cmlog, "ibt_prime_close_rc_channel: chan 0x%p "
1140 1112 "invalid channel", channel);
1141 1113 return (IBT_CHAN_HDL_INVALID);
1142 1114 }
1143 1115
1144 1116 if (ibtl_cm_get_chan_type(channel) != IBT_RC_SRV) {
1145 1117 IBTF_DPRINTF_L2(cmlog, "ibt_prime_close_rc_channel: chan 0x%p "
1146 1118 "Invalid Channel type: Applicable only to RC Channel",
1147 1119 channel);
1148 1120 return (IBT_CHAN_SRV_TYPE_INVALID);
1149 1121 }
1150 1122
1151 1123 /* get the statep */
1152 1124 IBCM_GET_CHAN_PRIVATE(channel, statep);
1153 1125
1154 1126 /*
1155 1127 * This can happen, if the statep is already gone by a DREQ from
1156 1128 * the remote side
1157 1129 */
1158 1130
1159 1131 if (statep == NULL) {
1160 1132 IBTF_DPRINTF_L2(cmlog, "ibt_prime_close_rc_channel: chan 0x%p "
1161 1133 "statep NULL", channel);
1162 1134 return (IBT_SUCCESS);
1163 1135 }
1164 1136
1165 1137 mutex_enter(&statep->state_mutex);
1166 1138 IBCM_RELEASE_CHAN_PRIVATE(channel);
1167 1139 if (statep->state != IBCM_STATE_ESTABLISHED) {
1168 1140 mutex_exit(&statep->state_mutex);
1169 1141 return (IBT_CHAN_STATE_INVALID);
1170 1142 }
1171 1143 IBCM_REF_CNT_INCR(statep);
1172 1144 IBTF_DPRINTF_L4(cmlog, "ibt_prime_close_rc_channel: chan 0x%p statep %p"
1173 1145 " state %x", channel, statep, statep->state);
1174 1146 mutex_exit(&statep->state_mutex);
1175 1147
1176 1148 /* clients could pre-allocate dreq mad, even before connection est */
1177 1149 if (statep->dreq_msg == NULL)
1178 1150 status = ibcm_alloc_out_msg(statep->stored_reply_addr.ibmf_hdl,
1179 1151 &statep->dreq_msg, MAD_METHOD_SEND);
1180 1152
1181 1153 mutex_enter(&statep->state_mutex);
1182 1154 IBCM_REF_CNT_DECR(statep);
1183 1155 mutex_exit(&statep->state_mutex);
1184 1156
1185 1157 if (status != IBT_SUCCESS) {
1186 1158 IBTF_DPRINTF_L2(cmlog, "ibt_prime_close_rc_channel: chan 0x%p "
1187 1159 "ibcm_alloc_out_msg failed ", channel);
1188 1160 return (status);
1189 1161 }
1190 1162
1191 1163 /* If this message isn't seen then ibt_prime_close_rc_channel failed */
1192 1164 IBTF_DPRINTF_L5(cmlog, "ibt_prime_close_rc_channel: chan 0x%p done",
1193 1165 channel);
1194 1166
1195 1167 return (IBT_SUCCESS);
1196 1168 }
1197 1169
1198 1170 /*
1199 1171 * ibt_close_rc_channel()
1200 1172 * It closes an established channel.
1201 1173 *
1202 1174 * RETURN VALUES:
1203 1175 * IBT_SUCCESS on success(or respective failure on error)
1204 1176 */
1205 1177 ibt_status_t
1206 1178 ibt_close_rc_channel(ibt_channel_hdl_t channel, ibt_execution_mode_t mode,
1207 1179 void *priv_data, ibt_priv_data_len_t priv_data_len, uint8_t *ret_status,
1208 1180 void *ret_priv_data, ibt_priv_data_len_t *ret_priv_data_len_p)
1209 1181 {
1210 1182 ibcm_state_data_t *statep;
1211 1183
1212 1184 IBTF_DPRINTF_L3(cmlog, "ibt_close_rc_channel(%p, %x, %p, %d, %p)",
1213 1185 channel, mode, priv_data, priv_data_len,
1214 1186 (ret_priv_data_len_p == NULL) ? 0 : *ret_priv_data_len_p);
1215 1187
1216 1188 /* validate channel, first */
1217 1189 if (IBCM_INVALID_CHANNEL(channel)) {
1218 1190 IBTF_DPRINTF_L2(cmlog, "ibt_close_rc_channel: chan 0x%p "
1219 1191 "invalid channel", channel);
1220 1192 return (IBT_CHAN_HDL_INVALID);
1221 1193 }
1222 1194
1223 1195 if (ibtl_cm_get_chan_type(channel) != IBT_RC_SRV) {
1224 1196 IBTF_DPRINTF_L2(cmlog, "ibt_close_rc_channel: chan 0x%p "
1225 1197 "Invalid Channel type: Applicable only to RC Channel",
1226 1198 channel);
1227 1199 return (IBT_CHAN_SRV_TYPE_INVALID);
1228 1200 }
1229 1201
1230 1202 if (mode == IBT_BLOCKING) {
1231 1203 /* valid only for BLOCKING MODE */
1232 1204 if ((ret_priv_data_len_p != NULL) &&
1233 1205 (*ret_priv_data_len_p > IBT_DREP_PRIV_DATA_SZ)) {
1234 1206 IBTF_DPRINTF_L2(cmlog, "ibt_close_rc_channel: chan 0x%p"
1235 1207 " private data len %d is too large", channel,
1236 1208 *ret_priv_data_len_p);
1237 1209 return (IBT_INVALID_PARAM);
1238 1210 }
1239 1211 } else if ((mode != IBT_NONBLOCKING) && (mode != IBT_NOCALLBACKS)) {
1240 1212 IBTF_DPRINTF_L2(cmlog, "ibt_close_rc_channel: chan 0x%p "
1241 1213 "invalid mode %x specified", channel, mode);
1242 1214 return (IBT_INVALID_PARAM);
1243 1215 }
1244 1216
1245 1217 if (ibtl_cm_is_chan_closing(channel) ||
1246 1218 ibtl_cm_is_chan_closed(channel)) {
1247 1219 if (ret_status)
1248 1220 *ret_status = IBT_CM_CLOSED_ALREADY;
1249 1221
1250 1222 /* No private data to return to the client */
1251 1223 if (ret_priv_data_len_p != NULL)
1252 1224 *ret_priv_data_len_p = 0;
1253 1225
1254 1226 if ((mode == IBT_BLOCKING) ||
1255 1227 (mode == IBT_NOCALLBACKS)) {
1256 1228 IBCM_GET_CHAN_PRIVATE(channel, statep);
1257 1229 if (statep == NULL)
1258 1230 return (IBT_SUCCESS);
1259 1231 mutex_enter(&statep->state_mutex);
1260 1232 IBCM_RELEASE_CHAN_PRIVATE(channel);
1261 1233 IBCM_REF_CNT_INCR(statep);
1262 1234 while (statep->close_done != B_TRUE)
1263 1235 cv_wait(&statep->block_client_cv,
1264 1236 &statep->state_mutex);
1265 1237 IBCM_REF_CNT_DECR(statep);
1266 1238 mutex_exit(&statep->state_mutex);
1267 1239 }
1268 1240
1269 1241 IBTF_DPRINTF_L3(cmlog, "ibt_close_rc_channel: chan 0x%p "
1270 1242 "already marked for closing", channel);
1271 1243
1272 1244 return (IBT_SUCCESS);
1273 1245 }
1274 1246
1275 1247 /* get the statep */
1276 1248 IBCM_GET_CHAN_PRIVATE(channel, statep);
1277 1249 if (statep == NULL) {
1278 1250 IBTF_DPRINTF_L2(cmlog, "ibt_close_rc_channel: chan 0x%p "
1279 1251 "statep NULL", channel);
1280 1252 return (IBT_CHAN_STATE_INVALID);
1281 1253 }
1282 1254
1283 1255 mutex_enter(&statep->state_mutex);
1284 1256
1285 1257 if (statep->dreq_msg == NULL) {
1286 1258 IBTF_DPRINTF_L2(cmlog, "ibt_close_rc_channel: chan 0x%p "
1287 1259 "Fatal Error: dreq_msg is NULL", channel);
1288 1260 IBCM_RELEASE_CHAN_PRIVATE(channel);
1289 1261 mutex_exit(&statep->state_mutex);
1290 1262 return (IBT_CHAN_STATE_INVALID);
1291 1263 }
1292 1264
1293 1265 if ((ret_priv_data == NULL) || (ret_priv_data_len_p == NULL)) {
1294 1266 statep->close_ret_priv_data = NULL;
1295 1267 statep->close_ret_priv_data_len = NULL;
1296 1268 } else {
1297 1269 statep->close_ret_priv_data = ret_priv_data;
1298 1270 statep->close_ret_priv_data_len = ret_priv_data_len_p;
1299 1271 }
1300 1272
1301 1273 priv_data_len = min(priv_data_len, IBT_DREQ_PRIV_DATA_SZ);
1302 1274 if ((priv_data != NULL) && (priv_data_len > 0)) {
1303 1275 bcopy(priv_data, ((ibcm_dreq_msg_t *)
1304 1276 IBCM_OUT_MSGP(statep->dreq_msg))->dreq_private_data,
1305 1277 priv_data_len);
1306 1278 }
1307 1279 statep->close_ret_status = ret_status;
1308 1280
1309 1281 IBCM_RELEASE_CHAN_PRIVATE(channel);
1310 1282 IBCM_REF_CNT_INCR(statep);
1311 1283
1312 1284 if (mode != IBT_NONBLOCKING) {
1313 1285 return (ibcm_close_rc_channel(channel, statep, mode));
1314 1286 }
1315 1287
1316 1288 /* IBT_NONBLOCKING */
1317 1289 ibcm_close_enqueue(statep);
1318 1290 mutex_exit(&statep->state_mutex);
1319 1291
1320 1292 return (IBT_SUCCESS);
1321 1293 }
1322 1294
1323 1295 void
1324 1296 ibcm_close_start(ibcm_state_data_t *statep)
1325 1297 {
1326 1298 mutex_enter(&statep->state_mutex);
↓ open down ↓ |
206 lines elided |
↑ open up ↑ |
1327 1299 (void) ibcm_close_rc_channel(statep->channel, statep, IBT_NONBLOCKING);
1328 1300 }
1329 1301
1330 1302 static
1331 1303 ibt_status_t
1332 1304 ibcm_close_rc_channel(ibt_channel_hdl_t channel, ibcm_state_data_t *statep,
1333 1305 ibt_execution_mode_t mode)
1334 1306 {
1335 1307 ibcm_hca_info_t *hcap;
1336 1308
1337 - _NOTE(LOCK_RELEASED_AS_SIDE_EFFECT(&statep->state_mutex));
1338 1309 ASSERT(MUTEX_HELD(&statep->state_mutex));
1339 1310
1340 1311 IBTF_DPRINTF_L3(cmlog, "ibcm_close_rc_channel: chan 0x%p statep %p",
1341 1312 channel, statep);
1342 1313
1343 1314 hcap = statep->hcap;
1344 1315
1345 1316 /* HCA must have been in active state. If not, it's a client bug */
1346 1317 if (!IBCM_ACCESS_HCA_OK(hcap)) {
1347 1318 IBTF_DPRINTF_L2(cmlog, "ibcm_close_rc_channel: chan 0x%p "
1348 1319 "hcap 0x%p not active", channel, hcap);
1349 1320 IBCM_REF_CNT_DECR(statep);
1350 1321 mutex_exit(&statep->state_mutex);
1351 1322 return (IBT_CHAN_HDL_INVALID);
1352 1323 }
1353 1324
1354 1325 if (statep->state == IBCM_STATE_TRANSIENT_ESTABLISHED) {
1355 1326 while (statep->cep_in_rts == IBCM_BLOCK)
1356 1327 cv_wait(&statep->block_mad_cv, &statep->state_mutex);
1357 1328 }
1358 1329
1359 1330 /* Do TRANSIENT_DREQ check after TRANSIENT_ESTABLISHED check */
1360 1331 while (statep->state == IBCM_STATE_TRANSIENT_DREQ_SENT)
1361 1332 cv_wait(&statep->block_mad_cv, &statep->state_mutex);
1362 1333
1363 1334 IBTF_DPRINTF_L4(cmlog, "ibcm_close_rc_channel: chan 0x%p "
1364 1335 "connection state is %x", channel, statep->state);
1365 1336
1366 1337 /* If state is in pre-established states, abort the connection est */
1367 1338 if (statep->state != IBCM_STATE_ESTABLISHED) {
1368 1339 statep->cm_retries++; /* ensure connection trace is dumped */
1369 1340
1370 1341 /* No DREP private data possible */
1371 1342 if (statep->close_ret_priv_data_len != NULL)
1372 1343 *statep->close_ret_priv_data_len = 0;
1373 1344
1374 1345 /*
1375 1346 * If waiting for a response mad, then cancel the timer,
1376 1347 * and delete the connection
1377 1348 */
1378 1349 if (statep->state == IBCM_STATE_REQ_SENT ||
1379 1350 statep->state == IBCM_STATE_REP_SENT ||
1380 1351 statep->state == IBCM_STATE_REP_WAIT ||
1381 1352 statep->state == IBCM_STATE_MRA_REP_RCVD) {
1382 1353 timeout_id_t timer_val = statep->timerid;
1383 1354 ibcm_conn_state_t old_state;
1384 1355
1385 1356 IBTF_DPRINTF_L4(cmlog, "ibcm_close_rc_channel: "
1386 1357 "chan 0x%p connection aborted in state %x", channel,
1387 1358 statep->state);
1388 1359
1389 1360 old_state = statep->state;
1390 1361 statep->state = IBCM_STATE_DELETE;
1391 1362
1392 1363 if (mode == IBT_NONBLOCKING) {
1393 1364 if (taskq_dispatch(ibcm_taskq,
1394 1365 ibcm_process_abort_via_taskq, statep,
1395 1366 TQ_NOSLEEP) == 0) {
1396 1367
1397 1368 IBCM_REF_CNT_DECR(statep);
1398 1369 statep->state = old_state;
1399 1370 mutex_exit(&statep->state_mutex);
1400 1371 return (IBT_INSUFF_KERNEL_RESOURCE);
1401 1372 } /* if taskq_dispatch succeeds */
1402 1373 /* Cancel the timer */
1403 1374 statep->timerid = 0;
1404 1375 mutex_exit(&statep->state_mutex);
1405 1376 } else {
1406 1377 /* Cancel the timer */
1407 1378 statep->timerid = 0;
1408 1379 mutex_exit(&statep->state_mutex);
1409 1380 (void) taskq_dispatch(ibcm_taskq,
1410 1381 ibcm_process_abort_via_taskq, statep,
1411 1382 TQ_SLEEP);
1412 1383 }
1413 1384
1414 1385 /* cancel the currently running timer */
1415 1386 if (timer_val != 0)
1416 1387 (void) untimeout(timer_val);
1417 1388
1418 1389 /* wait until cm handler returns for BLOCKING cases */
1419 1390 mutex_enter(&statep->state_mutex);
1420 1391 if ((mode == IBT_BLOCKING) ||
1421 1392 (mode == IBT_NOCALLBACKS)) {
1422 1393 while (statep->close_done != B_TRUE)
1423 1394 cv_wait(&statep->block_client_cv,
1424 1395 &statep->state_mutex);
1425 1396 }
1426 1397
1427 1398 if (statep->close_ret_status)
1428 1399 *statep->close_ret_status = IBT_CM_CLOSED_ABORT;
1429 1400 mutex_exit(&statep->state_mutex);
1430 1401
1431 1402 /*
1432 1403 * It would ideal to post a REJ MAD, but that would
1433 1404 * be non-conformance to spec. Hence, delete the state
1434 1405 * data. Assuming that happens quickly, any retransmits
1435 1406 * from the remote are replied by CM with reject
1436 1407 * reason " no valid com id". That would stop remote
1437 1408 * sending any more MADs.
1438 1409 */
1439 1410 ibcm_delete_state_data(statep);
1440 1411 return (IBT_SUCCESS);
1441 1412
1442 1413 /* if CM busy in cm handler, wait until cm handler returns */
1443 1414 } else if (statep->state == IBCM_STATE_REQ_RCVD ||
1444 1415 statep->state == IBCM_STATE_REP_RCVD ||
1445 1416 statep->state == IBCM_STATE_MRA_SENT ||
1446 1417 statep->state == IBCM_STATE_MRA_REP_SENT) {
1447 1418
1448 1419 /* take control of statep */
1449 1420 statep->abort_flag |= IBCM_ABORT_CLIENT;
1450 1421
1451 1422 IBTF_DPRINTF_L4(cmlog, "ibcm_close_rc_channel: "
1452 1423 "chan 0x%p connection aborted in state = %x",
1453 1424 channel, statep->state);
1454 1425
1455 1426 /*
1456 1427 * wait until state machine modifies qp state to error,
1457 1428 * including disassociating statep and QP
1458 1429 */
1459 1430 if ((mode == IBT_BLOCKING) || (mode == IBT_NOCALLBACKS))
1460 1431 while (statep->close_done != B_TRUE)
1461 1432 cv_wait(&statep->block_client_cv,
1462 1433 &statep->state_mutex);
1463 1434
1464 1435 /* a sanity setting */
1465 1436 if (mode == IBT_NOCALLBACKS)
1466 1437 statep->cm_handler = NULL;
1467 1438 IBCM_REF_CNT_DECR(statep);
1468 1439
1469 1440 /*
1470 1441 * In rare situations, connection attempt could be
1471 1442 * terminated for some other reason, before abort is
1472 1443 * processed, but CM still returns ret_status as abort
1473 1444 */
1474 1445 if (statep->close_ret_status)
1475 1446 *statep->close_ret_status = IBT_CM_CLOSED_ABORT;
1476 1447 mutex_exit(&statep->state_mutex);
1477 1448
1478 1449 /*
1479 1450 * REJ MAD is posted by the CM state machine for this
1480 1451 * case, hence state structure is deleted in the
1481 1452 * state machine processing.
1482 1453 */
1483 1454 return (IBT_SUCCESS);
1484 1455
1485 1456 } else if ((statep->state == IBCM_STATE_TIMEWAIT) ||
1486 1457 (statep->state == IBCM_STATE_DELETE)) {
1487 1458
1488 1459 /* State already in timewait, so no return priv data */
1489 1460 IBCM_REF_CNT_DECR(statep);
1490 1461
1491 1462 /* The teardown has already been done */
1492 1463 if (statep->close_ret_status)
1493 1464 *statep->close_ret_status =
1494 1465 IBT_CM_CLOSED_ALREADY;
1495 1466 mutex_exit(&statep->state_mutex);
1496 1467
1497 1468 return (IBT_SUCCESS);
1498 1469
1499 1470 } else if ((statep->state == IBCM_STATE_DREQ_RCVD) ||
1500 1471 (statep->state == IBCM_STATE_DREQ_SENT) ||
1501 1472 (statep->state == IBCM_STATE_DREP_RCVD) ||
1502 1473 ((statep->state == IBCM_STATE_TIMED_OUT) &&
1503 1474 (statep->timedout_state == IBCM_STATE_DREQ_SENT))) {
1504 1475
1505 1476 /*
1506 1477 * Either the remote or local client has already
1507 1478 * initiated the teardown. IBCM_STATE_DREP_RCVD is
1508 1479 * possible, if CM initiated teardown without client's
1509 1480 * knowledge, for stale handling, etc.,
1510 1481 */
1511 1482 if (mode == IBT_NOCALLBACKS) {
1512 1483 if (statep->close_nocb_state == IBCM_UNBLOCK) {
1513 1484 statep->close_nocb_state = IBCM_FAIL;
1514 1485 /* enable free qp after return */
1515 1486 ibtl_cm_chan_is_closing(
1516 1487 statep->channel);
1517 1488 } else while (statep->close_nocb_state ==
1518 1489 IBCM_BLOCK)
1519 1490 cv_wait(&statep->block_client_cv,
1520 1491 &statep->state_mutex);
1521 1492 statep->cm_handler = NULL; /* sanity setting */
1522 1493 if (statep->close_ret_status)
1523 1494 *statep->close_ret_status =
1524 1495 IBT_CM_CLOSED_ALREADY;
1525 1496 } else if (mode == IBT_BLOCKING) {
1526 1497 /* wait until state is moved to timewait */
1527 1498 while (statep->close_done != B_TRUE)
1528 1499 cv_wait(&statep->block_client_cv,
1529 1500 &statep->state_mutex);
1530 1501 }
1531 1502
1532 1503 IBCM_REF_CNT_DECR(statep);
1533 1504 mutex_exit(&statep->state_mutex);
1534 1505
1535 1506 /* ret_status is set in state machine code */
1536 1507 return (IBT_SUCCESS);
1537 1508
1538 1509 } else if (statep->state == IBCM_STATE_TIMED_OUT) {
1539 1510
1540 1511 if ((mode == IBT_BLOCKING) ||
1541 1512 (mode == IBT_NOCALLBACKS)) {
1542 1513
1543 1514 /*
1544 1515 * wait until cm handler invocation and
1545 1516 * disassociation between statep and channel
1546 1517 * is complete
1547 1518 */
1548 1519 while (statep->close_done != B_TRUE)
1549 1520 cv_wait(&statep->block_client_cv,
1550 1521 &statep->state_mutex);
1551 1522 }
1552 1523
1553 1524 if (statep->close_ret_status)
1554 1525 *statep->close_ret_status = IBT_CM_CLOSED_ABORT;
1555 1526 IBCM_REF_CNT_DECR(statep);
1556 1527 mutex_exit(&statep->state_mutex);
1557 1528
1558 1529 return (IBT_SUCCESS);
1559 1530 } else {
1560 1531 IBCM_REF_CNT_DECR(statep);
1561 1532 mutex_exit(&statep->state_mutex);
1562 1533
1563 1534 return (IBT_CM_FAILURE);
1564 1535 }
1565 1536 }
1566 1537
1567 1538 ASSERT(statep->close_nocb_state != IBCM_BLOCK);
1568 1539
1569 1540 if (mode == IBT_NOCALLBACKS) {
1570 1541 statep->close_nocb_state = IBCM_FAIL;
1571 1542 statep->cm_handler = NULL;
1572 1543 ibtl_cm_chan_is_closing(statep->channel);
1573 1544 IBTF_DPRINTF_L4(cmlog, "ibcm_close_rc_channel: "
1574 1545 "NOCALLBACKS on in statep = %p", statep);
1575 1546 }
1576 1547
1577 1548 if (statep->state != IBCM_STATE_ESTABLISHED) {
1578 1549 goto lost_race;
1579 1550 }
1580 1551
1581 1552 /*
1582 1553 * Cancel/wait for any pending ibt_set_alt_path, and
1583 1554 * release state mutex
1584 1555 */
1585 1556 ibcm_sync_lapr_idle(statep);
1586 1557
1587 1558 ibcm_close_enter();
1588 1559
1589 1560 mutex_enter(&statep->state_mutex);
1590 1561 if (statep->state != IBCM_STATE_ESTABLISHED) {
1591 1562 ibcm_close_exit();
1592 1563 goto lost_race;
1593 1564 }
1594 1565
1595 1566 statep->state = IBCM_STATE_TRANSIENT_DREQ_SENT;
1596 1567 statep->timerid = 0;
1597 1568 statep->close_done = B_FALSE;
1598 1569 statep->close_flow = 1;
1599 1570 mutex_exit(&statep->state_mutex);
1600 1571
1601 1572 ibcm_post_dreq_mad(statep);
1602 1573
1603 1574 mutex_enter(&statep->state_mutex);
1604 1575
1605 1576 lost_race:
1606 1577 if (mode == IBT_BLOCKING) {
1607 1578
1608 1579 /* wait for DREP */
1609 1580 while (statep->close_done != B_TRUE)
1610 1581 cv_wait(&statep->block_client_cv,
1611 1582 &statep->state_mutex);
1612 1583
1613 1584 IBTF_DPRINTF_L4(cmlog, "ibcm_close_rc_channel: chan 0x%p "
1614 1585 "done blocking", channel);
1615 1586 }
1616 1587
1617 1588 IBCM_REF_CNT_DECR(statep);
1618 1589 mutex_exit(&statep->state_mutex);
1619 1590
1620 1591 /* If this message isn't seen then ibt_close_rc_channel failed */
1621 1592 IBTF_DPRINTF_L5(cmlog, "ibcm_close_rc_channel: chan 0x%p done",
1622 1593 channel);
1623 1594
1624 1595 return (IBT_SUCCESS);
1625 1596 }
1626 1597
1627 1598 ibt_status_t
1628 1599 ibt_recycle_rc(ibt_channel_hdl_t rc_chan, ibt_cep_flags_t control,
1629 1600 uint8_t hca_port_num, ibt_recycle_handler_t func, void *arg)
1630 1601 {
1631 1602 ibcm_state_data_t *statep;
1632 1603 ibcm_taskq_recycle_arg_t *ibcm_tq_recycle_arg;
1633 1604 ibt_qp_query_attr_t qp_attr;
1634 1605 ibt_status_t retval;
1635 1606
1636 1607 IBTF_DPRINTF_L3(cmlog, "ibt_recycle_rc (%p, 0x%X, %d, %p, %p)", rc_chan,
1637 1608 control, hca_port_num, func, arg);
1638 1609
1639 1610 if (IBCM_INVALID_CHANNEL(rc_chan)) {
1640 1611 IBTF_DPRINTF_L2(cmlog, "ibt_recycle_rc: invalid channel");
1641 1612 return (IBT_CHAN_HDL_INVALID);
1642 1613 }
1643 1614
1644 1615 /* check qp state */
1645 1616 retval = ibt_query_qp(rc_chan, &qp_attr);
↓ open down ↓ |
298 lines elided |
↑ open up ↑ |
1646 1617
1647 1618 if (retval != IBT_SUCCESS)
1648 1619 return (retval);
1649 1620
1650 1621 if (qp_attr.qp_info.qp_trans != IBT_RC_SRV)
1651 1622 return (IBT_CHAN_SRV_TYPE_INVALID);
1652 1623
1653 1624 if (qp_attr.qp_info.qp_state != IBT_STATE_ERROR)
1654 1625 return (IBT_CHAN_STATE_INVALID);
1655 1626
1656 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ibcm_tq_recycle_arg))
1657 -
1658 1627 ibcm_tq_recycle_arg = kmem_alloc(sizeof (ibcm_taskq_recycle_arg_t),
1659 1628 KM_SLEEP);
1660 1629
1661 1630 ibcm_tq_recycle_arg->rc_chan = rc_chan;
1662 1631 ibcm_tq_recycle_arg->control = control;
1663 1632 ibcm_tq_recycle_arg->hca_port_num = hca_port_num;
1664 1633 ibcm_tq_recycle_arg->func = func;
1665 1634 ibcm_tq_recycle_arg->arg = arg;
1666 1635
1667 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*ibcm_tq_recycle_arg))
1668 -
1669 1636 IBCM_GET_CHAN_PRIVATE(rc_chan, statep);
1670 1637
1671 1638 /*
1672 1639 * If non-blocking ie., func specified and channel has not yet completed
1673 1640 * the timewait, then schedule the work for later
1674 1641 */
1675 1642 if ((func != NULL) && (statep != NULL)) {
1676 1643 IBCM_RELEASE_CHAN_PRIVATE(rc_chan);
1677 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(statep->recycle_arg))
1678 1644 statep->recycle_arg = ibcm_tq_recycle_arg;
1679 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(statep->recycle_arg))
1680 1645 return (IBT_SUCCESS);
1681 1646 }
1682 1647
1683 1648 /*
1684 1649 * if blocking ie., func specified, and channel has not yet completed
1685 1650 * the timewait, then block until the channel completes the timewait
1686 1651 */
1687 1652 if (statep != NULL)
1688 1653 IBCM_RELEASE_CHAN_PRIVATE(rc_chan);
1689 1654 IBCM_WAIT_CHAN_PRIVATE(rc_chan);
1690 1655
1691 1656 if (func) { /* NON BLOCKING case. Taskq for QP state change */
1692 1657 (void) taskq_dispatch(ibcm_taskq, ibcm_process_rc_recycle,
1693 1658 ibcm_tq_recycle_arg, TQ_SLEEP);
1694 1659 return (IBT_SUCCESS);
1695 1660 } else /* BLOCKING case */
1696 1661 return (ibcm_process_rc_recycle_ret(ibcm_tq_recycle_arg));
1697 1662 }
1698 1663
1699 1664 void
1700 1665 ibcm_process_rc_recycle(void *recycle_arg)
1701 1666 {
1702 1667 (void) ibcm_process_rc_recycle_ret(recycle_arg);
1703 1668 }
1704 1669
1705 1670 static ibt_status_t
1706 1671 ibcm_process_rc_recycle_ret(void *recycle_arg)
1707 1672 {
1708 1673 ibt_qp_info_t qp_info;
1709 1674 ibt_status_t ibt_status = IBT_SUCCESS;
1710 1675 ibt_cep_modify_flags_t cep_flags;
1711 1676 ibt_qp_query_attr_t qp_attr;
1712 1677 ibcm_taskq_recycle_arg_t *ibcm_tq_recycle_arg =
1713 1678 (ibcm_taskq_recycle_arg_t *)recycle_arg;
1714 1679
1715 1680 /* QP must have been in error state */
1716 1681 ibt_status = ibt_query_qp(ibcm_tq_recycle_arg->rc_chan, &qp_attr);
1717 1682 if (ibt_status != IBT_SUCCESS)
1718 1683 IBTF_DPRINTF_L2(cmlog, "ibcm_process_rc_recycle_ret: "
1719 1684 "chanp %p ibt_query_qp() = %d",
1720 1685 ibcm_tq_recycle_arg->rc_chan, ibt_status);
1721 1686 else {
1722 1687 /* perform the QP state change from ERROR to RESET */
1723 1688 bzero(&qp_info, sizeof (qp_info));
1724 1689
1725 1690 qp_info.qp_trans = IBT_RC_SRV;
1726 1691 qp_info.qp_state = IBT_STATE_RESET;
1727 1692
1728 1693 /* Call modify_qp to move to RESET state */
1729 1694 ibt_status = ibt_modify_qp(ibcm_tq_recycle_arg->rc_chan,
1730 1695 IBT_CEP_SET_STATE, &qp_info, NULL);
1731 1696
1732 1697 if (ibt_status != IBT_SUCCESS)
1733 1698 IBTF_DPRINTF_L2(cmlog, "ibcm_process_rc_recycle_ret: "
1734 1699 "chanp %p ibt_modify_qp() = %d for ERROR to RESET",
1735 1700 ibcm_tq_recycle_arg->rc_chan, ibt_status);
1736 1701 }
1737 1702
1738 1703 if (ibt_status == IBT_SUCCESS) {
1739 1704
1740 1705 qp_info.qp_state = IBT_STATE_INIT;
1741 1706
1742 1707 /* set flags for all mandatory args from RESET to INIT */
1743 1708 cep_flags = IBT_CEP_SET_STATE | IBT_CEP_SET_PORT;
1744 1709 cep_flags |= IBT_CEP_SET_RDMA_R | IBT_CEP_SET_RDMA_W;
1745 1710 cep_flags |= IBT_CEP_SET_ATOMIC;
1746 1711
1747 1712 qp_info.qp_transport.rc.rc_path.cep_hca_port_num =
1748 1713 ibcm_tq_recycle_arg->hca_port_num;
1749 1714 qp_info.qp_flags |=
1750 1715 ibcm_tq_recycle_arg->control & IBT_CEP_RDMA_RD;
1751 1716 qp_info.qp_flags |=
1752 1717 ibcm_tq_recycle_arg->control & IBT_CEP_RDMA_WR;
1753 1718 qp_info.qp_flags |=
1754 1719 ibcm_tq_recycle_arg->control & IBT_CEP_ATOMIC;
1755 1720
1756 1721 /* Always use the existing pkey */
1757 1722 qp_info.qp_transport.rc.rc_path.cep_pkey_ix =
1758 1723 qp_attr. qp_info.qp_transport.rc.rc_path.cep_pkey_ix;
1759 1724
1760 1725 /* Call modify_qp to move to INIT state */
1761 1726 ibt_status = ibt_modify_qp(ibcm_tq_recycle_arg->rc_chan,
1762 1727 cep_flags, &qp_info, NULL);
1763 1728
1764 1729 if (ibt_status != IBT_SUCCESS)
1765 1730 IBTF_DPRINTF_L2(cmlog, "ibcm_process_rc_recycle_ret: "
1766 1731 "chanp %p ibt_modify_qp() = %d for RESET to INIT",
1767 1732 ibcm_tq_recycle_arg->rc_chan, ibt_status);
1768 1733 }
1769 1734
1770 1735 /* Change the QP CM state to indicate QP being re-used */
1771 1736 if (ibt_status == IBT_SUCCESS)
1772 1737 ibtl_cm_chan_is_reused(ibcm_tq_recycle_arg->rc_chan);
1773 1738
1774 1739 /* Call func, if defined */
1775 1740 if (ibcm_tq_recycle_arg->func)
1776 1741 (*(ibcm_tq_recycle_arg->func))(ibt_status,
1777 1742 ibcm_tq_recycle_arg->arg);
1778 1743
1779 1744 kmem_free(ibcm_tq_recycle_arg, sizeof (ibcm_taskq_recycle_arg_t));
1780 1745
1781 1746 return (ibt_status);
1782 1747 }
1783 1748
1784 1749 static void
1785 1750 ibcm_process_abort_via_taskq(void *args)
1786 1751 {
1787 1752 ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
1788 1753
1789 1754 ibcm_process_abort(statep);
1790 1755 mutex_enter(&statep->state_mutex);
1791 1756 IBCM_REF_CNT_DECR(statep);
1792 1757 mutex_exit(&statep->state_mutex);
1793 1758 }
1794 1759
↓ open down ↓ |
105 lines elided |
↑ open up ↑ |
1795 1760 /*
1796 1761 * Local UD CM Handler's private data, used during ibt_request_ud_dest() in
1797 1762 * Non-Blocking mode operations.
1798 1763 */
1799 1764 typedef struct ibcm_local_handler_s {
1800 1765 ibt_cm_ud_handler_t actual_cm_handler;
1801 1766 void *actual_cm_private;
1802 1767 ibt_ud_dest_t *dest_hdl;
1803 1768 } ibcm_local_handler_t;
1804 1769
1805 -_NOTE(READ_ONLY_DATA(ibcm_local_handler_s))
1806 -
1807 1770 /*
1808 1771 * Local UD CM Handler, used when ibt_alloc_ud_dest() is issued in
1809 1772 * NON-Blocking mode.
1810 1773 *
1811 1774 * Out here, we update the UD Destination handle with
1812 1775 * the obtained DQPN and QKey (from SIDR REP) and invokes actual client
1813 1776 * handler that was specified by the client.
1814 1777 */
1815 1778 static ibt_cm_status_t
1816 1779 ibcm_local_cm_handler(void *priv, ibt_cm_ud_event_t *event,
1817 1780 ibt_cm_ud_return_args_t *ret_args, void *priv_data, ibt_priv_data_len_t len)
1818 1781 {
1819 1782 ibcm_local_handler_t *handler_priv = (ibcm_local_handler_t *)priv;
1820 1783
1821 1784 IBTF_DPRINTF_L4(cmlog, "ibcm_local_cm_handler: event %d",
1822 1785 event->cm_type);
1823 1786
1824 1787 ASSERT(handler_priv != NULL);
1825 1788
1826 1789 switch (event->cm_type) {
1827 1790 case IBT_CM_UD_EVENT_SIDR_REP:
1828 1791 /* Update QPN & QKey from event into destination handle. */
1829 1792 if (handler_priv->dest_hdl != NULL) {
1830 1793 handler_priv->dest_hdl->ud_dst_qpn =
1831 1794 event->cm_event.sidr_rep.srep_remote_qpn;
1832 1795 handler_priv->dest_hdl->ud_qkey =
1833 1796 event->cm_event.sidr_rep.srep_remote_qkey;
1834 1797 }
1835 1798
1836 1799 /* Invoke the client handler - inform only, so ignore retval */
1837 1800 (void) handler_priv->actual_cm_handler(
1838 1801 handler_priv->actual_cm_private, event, ret_args, priv_data,
1839 1802 len);
1840 1803
1841 1804 /* Free memory allocated for local handler's private data. */
1842 1805 if (handler_priv != NULL)
1843 1806 kmem_free(handler_priv, sizeof (*handler_priv));
1844 1807
1845 1808 break;
1846 1809 default:
1847 1810 IBTF_DPRINTF_L2(cmlog, "ibcm_local_cm_handler: ERROR");
1848 1811 break;
1849 1812 }
1850 1813
1851 1814 return (IBT_CM_ACCEPT);
1852 1815 }
1853 1816
1854 1817
1855 1818 /* Validate the input UD destination attributes. */
1856 1819 static ibt_status_t
1857 1820 ibcm_validate_dqpn_data(ibt_ud_dest_attr_t *attr, ibt_execution_mode_t mode,
1858 1821 ibt_ud_returns_t *ret_args)
1859 1822 {
1860 1823 /* cm handler must always be specified */
1861 1824 if (mode == IBT_NONBLOCKING && attr->ud_cm_handler == NULL) {
1862 1825 IBTF_DPRINTF_L2(cmlog, "ibcm_validate_dqpn_data: "
1863 1826 "CM handler is not specified ");
1864 1827 return (IBT_INVALID_PARAM);
1865 1828 }
1866 1829
1867 1830 if (mode == IBT_NONBLOCKING) {
1868 1831 if (ret_args != NULL) {
1869 1832 IBTF_DPRINTF_L2(cmlog, "ibcm_validate_dqpn_data: "
1870 1833 "ret_args should be NULL when called in "
1871 1834 "non-blocking mode");
1872 1835 return (IBT_INVALID_PARAM);
1873 1836 }
1874 1837 } else if (mode == IBT_BLOCKING) {
1875 1838 if (ret_args == NULL) {
1876 1839 IBTF_DPRINTF_L2(cmlog, "ibcm_validate_dqpn_data: "
1877 1840 "ret_args should be Non-NULL when called in "
1878 1841 "blocking mode");
1879 1842 return (IBT_INVALID_PARAM);
1880 1843 }
1881 1844 } else {
1882 1845 IBTF_DPRINTF_L2(cmlog, "ibcm_validate_dqpn_data: "
1883 1846 "invalid mode %x specified ", mode);
1884 1847 return (IBT_INVALID_PARAM);
1885 1848 }
1886 1849
1887 1850 if (attr->ud_sid == 0) {
1888 1851 IBTF_DPRINTF_L2(cmlog, "ibcm_validate_dqpn_data: "
1889 1852 "ServiceID must be specified. ");
1890 1853 return (IBT_INVALID_PARAM);
1891 1854 }
1892 1855
1893 1856 if (attr->ud_addr == NULL) {
1894 1857 IBTF_DPRINTF_L2(cmlog, "ibcm_validate_dqpn_data: "
1895 1858 "Address Info NULL");
1896 1859 return (IBT_INVALID_PARAM);
1897 1860 }
1898 1861
1899 1862 /* Validate SGID */
1900 1863 if ((attr->ud_addr->av_sgid.gid_prefix == 0) ||
1901 1864 (attr->ud_addr->av_sgid.gid_guid == 0)) {
1902 1865 IBTF_DPRINTF_L2(cmlog, "ibcm_validate_dqpn_data: Invalid SGID");
1903 1866 return (IBT_INVALID_PARAM);
1904 1867 }
1905 1868 IBTF_DPRINTF_L3(cmlog, "ibcm_validate_dqpn_data: SGID<%llX:%llX>",
1906 1869 attr->ud_addr->av_sgid.gid_prefix,
1907 1870 attr->ud_addr->av_sgid.gid_guid);
1908 1871
1909 1872 /* Validate DGID */
1910 1873 if ((attr->ud_addr->av_dgid.gid_prefix == 0) ||
1911 1874 (attr->ud_addr->av_dgid.gid_guid == 0)) {
1912 1875 IBTF_DPRINTF_L2(cmlog, "ibcm_validate_dqpn_data: Invalid DGID");
1913 1876 return (IBT_INVALID_PARAM);
1914 1877 }
1915 1878 IBTF_DPRINTF_L3(cmlog, "ibcm_validate_dqpn_data: DGID<%llX:%llX>",
1916 1879 attr->ud_addr->av_dgid.gid_prefix,
1917 1880 attr->ud_addr->av_dgid.gid_guid);
1918 1881
1919 1882 return (IBT_SUCCESS);
1920 1883 }
1921 1884
1922 1885
1923 1886 /* Perform SIDR to retrieve DQPN and QKey. */
1924 1887 static ibt_status_t
1925 1888 ibcm_ud_get_dqpn(ibt_ud_dest_attr_t *attr, ibt_execution_mode_t mode,
1926 1889 ibt_ud_returns_t *ret_args)
1927 1890 {
1928 1891 ibt_status_t retval;
1929 1892 ib_pkey_t ud_pkey;
1930 1893 ibmf_handle_t ibmf_hdl;
1931 1894 ibmf_msg_t *ibmf_msg;
1932 1895 ibcm_hca_info_t *hcap;
1933 1896 ibcm_sidr_req_msg_t *sidr_req_msgp;
1934 1897 ibcm_ud_state_data_t *ud_statep;
1935 1898 ibtl_cm_hca_port_t port;
1936 1899 ibcm_sidr_srch_t sidr_entry;
1937 1900 ibcm_qp_list_t *cm_qp_entry;
1938 1901
1939 1902 /* Retrieve HCA GUID value from the available SGID info. */
1940 1903 retval = ibtl_cm_get_hca_port(attr->ud_addr->av_sgid, 0, &port);
1941 1904 if ((retval != IBT_SUCCESS) || (port.hp_port == 0)) {
1942 1905 IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: "
1943 1906 "ibtl_cm_get_hca_port failed: %d", retval);
1944 1907 return (retval);
1945 1908 }
1946 1909
1947 1910 IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: "
1948 1911 "HCA GUID:%llX, port_num:%d", port.hp_hca_guid, port.hp_port);
1949 1912
1950 1913 /* Lookup the HCA info for this GUID */
1951 1914 if ((hcap = ibcm_find_hca_entry(port.hp_hca_guid)) == NULL) {
1952 1915 IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: hcap is NULL");
1953 1916 return (IBT_HCA_INVALID);
1954 1917 }
1955 1918
1956 1919 /* Return failure if the HCA device or Port is not operational */
1957 1920
1958 1921 if ((retval = ibt_get_port_state_byguid(port.hp_hca_guid, port.hp_port,
1959 1922 NULL, NULL)) != IBT_SUCCESS) {
1960 1923 /* Device Port is not in good state, don't use it. */
1961 1924 IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: Invalid "
1962 1925 "port specified or port not active");
1963 1926 ibcm_dec_hca_acc_cnt(hcap);
1964 1927 return (retval);
1965 1928 }
↓ open down ↓ |
149 lines elided |
↑ open up ↑ |
1966 1929
1967 1930 retval = ibt_index2pkey_byguid(port.hp_hca_guid, port.hp_port,
1968 1931 attr->ud_pkey_ix, &ud_pkey);
1969 1932 if (retval != IBT_SUCCESS) {
1970 1933 IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: "
1971 1934 "Failed to convert index2pkey: %d", retval);
1972 1935 ibcm_dec_hca_acc_cnt(hcap);
1973 1936 return (retval);
1974 1937 }
1975 1938
1976 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(sidr_entry))
1977 -
1978 1939 /* Allocate a new request id */
1979 1940 if (ibcm_alloc_reqid(hcap, &sidr_entry.srch_req_id) == IBCM_FAILURE) {
1980 1941 IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: "
1981 1942 "no req id available");
1982 1943 ibcm_dec_hca_acc_cnt(hcap);
1983 1944 return (IBT_INSUFF_KERNEL_RESOURCE);
1984 1945 }
1985 1946
1986 1947 if ((hcap->hca_port_info[port.hp_port - 1].port_ibmf_hdl == NULL) &&
1987 1948 ((retval = ibcm_hca_reinit_port(hcap, port.hp_port - 1))
1988 1949 != IBT_SUCCESS)) {
1989 1950 IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: "
1990 1951 "ibmf reg or callback setup failed during re-initialize");
1991 1952 return (retval);
1992 1953 }
1993 1954
1994 1955 ibmf_hdl = hcap->hca_port_info[port.hp_port - 1].port_ibmf_hdl;
1995 1956
1996 1957 /* find the ibmf QP to post the SIDR REQ */
1997 1958 if ((cm_qp_entry = ibcm_find_qp(hcap, port.hp_port, ud_pkey)) ==
1998 1959 NULL) {
1999 1960 IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: IBMF QP allocation"
2000 1961 " failed");
2001 1962 ibcm_dec_hca_acc_cnt(hcap);
2002 1963 return (IBT_INSUFF_RESOURCE);
2003 1964 }
2004 1965
2005 1966 if ((retval = ibcm_alloc_out_msg(ibmf_hdl, &ibmf_msg, MAD_METHOD_SEND))
2006 1967 != IBT_SUCCESS) {
2007 1968 IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: IBMF MSG allocation"
2008 1969 " failed");
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
2009 1970 ibcm_release_qp(cm_qp_entry);
2010 1971 ibcm_dec_hca_acc_cnt(hcap);
2011 1972 return (retval);
2012 1973 }
2013 1974
2014 1975 sidr_entry.srch_lid = port.hp_base_lid;
2015 1976 sidr_entry.srch_gid = attr->ud_addr->av_sgid;
2016 1977 sidr_entry.srch_grh_exists = attr->ud_addr->av_send_grh;
2017 1978 sidr_entry.srch_mode = IBCM_ACTIVE_MODE;
2018 1979
2019 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(sidr_entry))
2020 -
2021 1980 /* do various allocations needed here */
2022 1981 rw_enter(&hcap->hca_sidr_list_lock, RW_WRITER);
2023 1982
2024 1983 (void) ibcm_find_sidr_entry(&sidr_entry, hcap, &ud_statep,
2025 1984 IBCM_FLAG_ADD);
2026 1985 rw_exit(&hcap->hca_sidr_list_lock);
2027 1986
2028 1987 /* Increment hca's resource count */
2029 1988 ibcm_inc_hca_res_cnt(hcap);
2030 1989
2031 1990 /* After a resource created on hca, no need to hold the acc cnt */
2032 1991 ibcm_dec_hca_acc_cnt(hcap);
2033 1992
2034 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ud_statep))
2035 -
2036 1993 /* Initialize some ud_statep fields */
2037 1994 ud_statep->ud_stored_msg = ibmf_msg;
2038 1995 ud_statep->ud_svc_id = attr->ud_sid;
2039 1996 ud_statep->ud_pkt_life_time =
2040 1997 ibt_ib2usec(attr->ud_pkt_lt);
2041 1998 ud_statep->ud_stored_reply_addr.cm_qp_entry = cm_qp_entry;
2042 1999
2043 2000 /* set remaining retry cnt */
2044 2001 ud_statep->ud_remaining_retry_cnt = ud_statep->ud_max_cm_retries;
2045 2002
2046 2003 /*
2047 2004 * Get UD handler and corresponding args which is pass it back
2048 2005 * as first argument for the handler.
2049 2006 */
2050 2007 ud_statep->ud_state_cm_private = attr->ud_cm_private;
2051 2008
2052 2009 if (mode == IBT_BLOCKING)
2053 2010 ud_statep->ud_return_data = ret_args;
2054 2011 else
2055 2012 ud_statep->ud_cm_handler = attr->ud_cm_handler;
2056 2013
2057 2014 /* Initialize the fields of ud_statep->ud_stored_reply_addr */
2058 2015 ud_statep->ud_stored_reply_addr.grh_exists = attr->ud_addr->av_send_grh;
2059 2016 ud_statep->ud_stored_reply_addr.ibmf_hdl = ibmf_hdl;
2060 2017 ud_statep->ud_stored_reply_addr.grh_hdr.ig_hop_limit =
2061 2018 attr->ud_addr->av_hop;
2062 2019 ud_statep->ud_stored_reply_addr.grh_hdr.ig_sender_gid =
2063 2020 attr->ud_addr->av_sgid;
2064 2021 ud_statep->ud_stored_reply_addr.grh_hdr.ig_recver_gid =
2065 2022 attr->ud_addr->av_dgid;
2066 2023 ud_statep->ud_stored_reply_addr.grh_hdr.ig_tclass =
2067 2024 attr->ud_addr->av_tclass;
2068 2025 ud_statep->ud_stored_reply_addr.grh_hdr.ig_flow_label =
2069 2026 attr->ud_addr->av_flow & IB_GRH_FLOW_LABEL_MASK;
2070 2027
2071 2028 /* needs to be derived based on the base LID and path bits */
2072 2029 ud_statep->ud_stored_reply_addr.rcvd_addr.ia_local_lid =
2073 2030 port.hp_base_lid;
2074 2031 ud_statep->ud_stored_reply_addr.rcvd_addr.ia_remote_lid =
2075 2032 attr->ud_addr->av_dlid;
2076 2033 ud_statep->ud_stored_reply_addr.rcvd_addr.ia_p_key = ud_pkey;
2077 2034 ud_statep->ud_stored_reply_addr.rcvd_addr.ia_q_key = IB_GSI_QKEY;
↓ open down ↓ |
32 lines elided |
↑ open up ↑ |
2078 2035 ud_statep->ud_stored_reply_addr.rcvd_addr.ia_service_level =
2079 2036 attr->ud_addr->av_srvl;
2080 2037
2081 2038 /*
2082 2039 * This may be enchanced later, to use a remote qno based on past
2083 2040 * redirect rej mad responses. This would be the place to specify
2084 2041 * appropriate remote qno
2085 2042 */
2086 2043 ud_statep->ud_stored_reply_addr.rcvd_addr.ia_remote_qno = 1;
2087 2044
2088 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sidr_req_msgp))
2089 -
2090 2045 /* Initialize the SIDR REQ message fields */
2091 2046 sidr_req_msgp =
2092 2047 (ibcm_sidr_req_msg_t *)IBCM_OUT_MSGP(ud_statep->ud_stored_msg);
2093 2048
2094 2049 sidr_req_msgp->sidr_req_request_id = h2b32(ud_statep->ud_req_id);
2095 2050 sidr_req_msgp->sidr_req_service_id = h2b64(attr->ud_sid);
2096 2051 sidr_req_msgp->sidr_req_pkey = h2b16(ud_pkey);
2097 2052 IBCM_OUT_HDRP(ud_statep->ud_stored_msg)->AttributeID =
2098 2053 h2b16(IBCM_INCOMING_SIDR_REQ + IBCM_ATTR_BASE_ID);
2099 2054
2100 2055 if ((attr->ud_priv_data != NULL) && (attr->ud_priv_data_len > 0)) {
2101 2056 bcopy(attr->ud_priv_data, sidr_req_msgp->sidr_req_private_data,
2102 2057 min(attr->ud_priv_data_len, IBT_SIDR_REQ_PRIV_DATA_SZ));
2103 2058 }
2104 2059
2105 2060 /* Send out the SIDR REQ message */
2106 2061 ud_statep->ud_state = IBCM_STATE_SIDR_REQ_SENT;
2107 2062 ud_statep->ud_timer_stored_state = IBCM_STATE_SIDR_REQ_SENT;
2108 2063 IBCM_UD_REF_CNT_INCR(ud_statep); /* for non-blocking SIDR REQ post */
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
2109 2064 ud_statep->ud_timer_value = ibt_ib2usec(ibcm_max_sidr_rep_proctime) +
2110 2065 (ud_statep->ud_pkt_life_time * 2);
2111 2066
2112 2067 IBCM_OUT_HDRP(ud_statep->ud_stored_msg)->TransactionID =
2113 2068 h2b64(ibcm_generate_tranid(IBCM_INCOMING_SIDR_REQ,
2114 2069 ud_statep->ud_req_id, 0));
2115 2070
2116 2071 IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: timer_value in HZ = %x",
2117 2072 ud_statep->ud_timer_value);
2118 2073
2119 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*ud_statep))
2120 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*sidr_req_msgp))
2121 -
2122 2074 ibcm_post_ud_mad(ud_statep, ud_statep->ud_stored_msg,
2123 2075 ibcm_post_sidr_req_complete, ud_statep);
2124 2076
2125 2077 mutex_enter(&ud_statep->ud_state_mutex);
2126 2078
2127 2079 /* Wait for SIDR_REP */
2128 2080 if (mode == IBT_BLOCKING) {
2129 2081 IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: blocking");
2130 2082
2131 2083 while (ud_statep->ud_blocking_done != B_TRUE) {
2132 2084 cv_wait(&ud_statep->ud_block_client_cv,
2133 2085 &ud_statep->ud_state_mutex);
2134 2086 }
2135 2087
2136 2088 IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: finished blocking");
2137 2089
2138 2090 if (ret_args->ud_status == IBT_CM_SREP_QPN_VALID) {
2139 2091 IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: DQPN = %x, "
2140 2092 "status = %x, QKey = %x", ret_args->ud_dqpn,
2141 2093 ret_args->ud_status, ret_args->ud_qkey);
2142 2094
2143 2095 } else {
2144 2096 IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: Status<%x>",
2145 2097 ret_args->ud_status);
2146 2098 retval = IBT_CM_FAILURE;
2147 2099 }
2148 2100 }
2149 2101
2150 2102 IBCM_UD_REF_CNT_DECR(ud_statep);
2151 2103 mutex_exit(&ud_statep->ud_state_mutex);
2152 2104
2153 2105 IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: done");
2154 2106
2155 2107 return (retval);
2156 2108 }
2157 2109
2158 2110
2159 2111 /*
2160 2112 * Function:
2161 2113 * ibt_request_ud_dest
2162 2114 * Input:
2163 2115 * ud_dest A previously allocated UD destination handle.
2164 2116 * mode This function can execute in blocking or non blocking
2165 2117 * modes.
2166 2118 * attr UD destination attributes to be modified.
2167 2119 * Output:
2168 2120 * ud_ret_args If the function is called in blocking mode, ud_ret_args
2169 2121 * should be a pointer to an ibt_ud_returns_t struct.
2170 2122 * Returns:
2171 2123 * IBT_SUCCESS
2172 2124 * Description:
2173 2125 * Modify a previously allocated UD destination handle based on the
2174 2126 * results of doing the SIDR protocol.
2175 2127 */
2176 2128 ibt_status_t
2177 2129 ibt_request_ud_dest(ibt_ud_dest_hdl_t ud_dest, ibt_execution_mode_t mode,
2178 2130 ibt_ud_dest_attr_t *attr, ibt_ud_returns_t *ud_ret_args)
2179 2131 {
2180 2132 ibt_status_t retval;
2181 2133 ibt_ud_dest_t *ud_destp;
2182 2134 ibcm_local_handler_t *local_handler_priv = NULL;
2183 2135
2184 2136 IBTF_DPRINTF_L3(cmlog, "ibt_request_ud_dest(%p, %x, %p, %p)",
2185 2137 ud_dest, mode, attr, ud_ret_args);
2186 2138
2187 2139 retval = ibcm_validate_dqpn_data(attr, mode, ud_ret_args);
2188 2140 if (retval != IBT_SUCCESS) {
2189 2141 return (retval);
2190 2142 }
2191 2143
2192 2144 ud_destp = ud_dest;
2193 2145
2194 2146 /* Allocate an Address handle. */
2195 2147 retval = ibt_modify_ah(ud_destp->ud_dest_hca, ud_destp->ud_ah,
2196 2148 attr->ud_addr);
2197 2149 if (retval != IBT_SUCCESS) {
2198 2150 IBTF_DPRINTF_L2(cmlog, "ibt_request_ud_dest: "
2199 2151 "Address Handle Modification failed: %d", retval);
2200 2152 return (retval);
2201 2153 }
2202 2154
2203 2155 if (mode == IBT_NONBLOCKING) {
2204 2156 /*
2205 2157 * In NON-BLOCKING mode, and we need to update the destination
↓ open down ↓ |
74 lines elided |
↑ open up ↑ |
2206 2158 * handle with the DQPN and QKey that are obtained from
2207 2159 * SIDR REP, hook-up our own handler, so that we can catch
2208 2160 * the event, and we ourselves call the actual client's
2209 2161 * ud_cm_handler, in our handler.
2210 2162 */
2211 2163
2212 2164 /* Allocate memory for local handler's private data. */
2213 2165 local_handler_priv =
2214 2166 kmem_alloc(sizeof (*local_handler_priv), KM_SLEEP);
2215 2167
2216 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*local_handler_priv))
2217 -
2218 2168 local_handler_priv->actual_cm_handler = attr->ud_cm_handler;
2219 2169 local_handler_priv->actual_cm_private = attr->ud_cm_private;
2220 2170 local_handler_priv->dest_hdl = ud_destp;
2221 2171
2222 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*local_handler_priv))
2223 -
2224 2172 attr->ud_cm_handler = ibcm_local_cm_handler;
2225 2173 attr->ud_cm_private = local_handler_priv;
2226 2174 }
2227 2175
2228 2176 /* In order to get DQPN and Destination QKey, perform SIDR */
2229 2177 retval = ibcm_ud_get_dqpn(attr, mode, ud_ret_args);
2230 2178 if (retval != IBT_SUCCESS) {
2231 2179 IBTF_DPRINTF_L2(cmlog, "ibt_request_ud_dest: "
2232 2180 "Failed to get DQPN: %d", retval);
2233 2181
2234 2182 /* Free memory allocated for local handler's private data. */
2235 2183 if (local_handler_priv != NULL)
2236 2184 kmem_free(local_handler_priv,
2237 2185 sizeof (*local_handler_priv));
2238 2186 return (retval);
2239 2187 }
2240 2188
2241 2189 /*
2242 2190 * Fill in the dqpn and dqkey as obtained from ud_ret_args,
2243 2191 * values will be valid only on BLOCKING mode.
2244 2192 */
2245 2193 if (mode == IBT_BLOCKING) {
2246 2194 ud_destp->ud_dst_qpn = ud_ret_args->ud_dqpn;
2247 2195 ud_destp->ud_qkey = ud_ret_args->ud_qkey;
2248 2196 }
2249 2197
2250 2198 return (retval);
2251 2199 }
2252 2200
2253 2201 /*
2254 2202 * Function:
2255 2203 * ibt_ud_get_dqpn
2256 2204 * Input:
2257 2205 * attr A pointer to an ibt_ud_dest_attr_t struct that are
2258 2206 * required for SIDR REQ message. Not specified attributes
2259 2207 * should be set to "NULL" or "0".
2260 2208 * ud_sid, ud_addr and ud_pkt_lt must be specified.
2261 2209 * mode This function can execute in blocking or non blocking
2262 2210 * modes.
2263 2211 * Output:
2264 2212 * returns If the function is called in blocking mode, returns
2265 2213 * should be a pointer to an ibt_ud_returns_t struct.
2266 2214 * Return:
2267 2215 * IBT_SUCCESS on success or respective failure on error.
2268 2216 * Description:
2269 2217 * Finds the destination QPN at the specified destination that the
2270 2218 * specified service can be reached on. The IBTF CM initiates the
2271 2219 * service ID resolution protocol (SIDR) to determine a destination QPN.
2272 2220 *
2273 2221 * NOTE: SIDR_REQ is initiated from active side.
2274 2222 */
2275 2223 ibt_status_t
2276 2224 ibt_ud_get_dqpn(ibt_ud_dest_attr_t *attr, ibt_execution_mode_t mode,
2277 2225 ibt_ud_returns_t *returns)
2278 2226 {
2279 2227 ibt_status_t retval;
2280 2228
2281 2229 IBTF_DPRINTF_L3(cmlog, "ibt_ud_get_dqpn(%p, %x, %p)",
2282 2230 attr, mode, returns);
2283 2231
2284 2232 retval = ibcm_validate_dqpn_data(attr, mode, returns);
2285 2233 if (retval != IBT_SUCCESS) {
2286 2234 return (retval);
2287 2235 }
2288 2236
2289 2237 return (ibcm_ud_get_dqpn(attr, mode, returns));
2290 2238 }
2291 2239
2292 2240
2293 2241 /*
2294 2242 * ibt_cm_delay:
2295 2243 * A client CM handler function can call this function
2296 2244 * to extend its response time to a CM event.
2297 2245 * INPUTS:
2298 2246 * flags Indicates what CM message processing is being delayed
2299 2247 * by the CM handler, valid values are:
2300 2248 * IBT_CM_DELAY_REQ
2301 2249 * IBT_CM_DELAY_REP
2302 2250 * IBT_CM_DELAY_LAP
2303 2251 * cm_session_id The session ID that was passed to client srv_handler
2304 2252 * by the CM
2305 2253 * service_time The extended service time
2306 2254 * priv_data Vendor specific data to be sent in the CM generated
2307 2255 * MRA message. Should be NULL if not specified.
2308 2256 * len The number of bytes of data specified by priv_data.
2309 2257 *
2310 2258 * RETURN VALUES:
2311 2259 * IBT_SUCCESS on success (or respective failure on error)
2312 2260 */
2313 2261 ibt_status_t
2314 2262 ibt_cm_delay(ibt_cmdelay_flags_t flags, void *cm_session_id,
2315 2263 clock_t service_time, void *priv_data, ibt_priv_data_len_t len)
2316 2264 {
2317 2265 uint8_t msg_typ = 0;
2318 2266 ibcm_mra_msg_t *mra_msgp;
2319 2267 ibcm_state_data_t *statep;
2320 2268 ibt_status_t status;
2321 2269
2322 2270 IBTF_DPRINTF_L3(cmlog, "ibt_cm_delay(0x%x, %p, 0x%x)",
2323 2271 flags, cm_session_id, service_time);
2324 2272
2325 2273 /*
2326 2274 * Make sure channel is associated with a statep
2327 2275 */
2328 2276 statep = (ibcm_state_data_t *)cm_session_id;
2329 2277
2330 2278 if (statep == NULL) {
2331 2279 IBTF_DPRINTF_L2(cmlog, "ibt_cm_delay: statep NULL");
2332 2280 return (IBT_INVALID_PARAM);
2333 2281 }
2334 2282
2335 2283 IBTF_DPRINTF_L4(cmlog, "ibt_cm_delay: statep %p", statep);
2336 2284
2337 2285 /* Allocate an ibmf msg for mra, if not allocated yet */
↓ open down ↓ |
104 lines elided |
↑ open up ↑ |
2338 2286 if (statep->mra_msg == NULL) {
2339 2287 if ((status = ibcm_alloc_out_msg(
2340 2288 statep->stored_reply_addr.ibmf_hdl, &statep->mra_msg,
2341 2289 MAD_METHOD_SEND)) != IBT_SUCCESS) {
2342 2290 IBTF_DPRINTF_L2(cmlog, "ibt_cm_delay: chan 0x%p"
2343 2291 "IBMF MSG allocation failed", statep->channel);
2344 2292 return (status);
2345 2293 }
2346 2294 }
2347 2295
2348 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*mra_msgp))
2349 -
2350 2296 mra_msgp = (ibcm_mra_msg_t *)IBCM_OUT_MSGP(statep->mra_msg);
2351 2297 mra_msgp->mra_local_comm_id = h2b32(statep->local_comid);
2352 2298 mra_msgp->mra_remote_comm_id = h2b32(statep->remote_comid);
2353 2299
2354 2300 /* fill in rest of MRA's fields - Message MRAed and Service Timeout */
2355 2301 if (flags == IBT_CM_DELAY_REQ) {
2356 2302 msg_typ = IBT_CM_MRA_TYPE_REQ;
2357 2303 } else if (flags == IBT_CM_DELAY_REP) {
2358 2304 msg_typ = IBT_CM_MRA_TYPE_REP;
2359 2305 } else if (flags == IBT_CM_DELAY_LAP) {
2360 2306 msg_typ = IBT_CM_MRA_TYPE_LAP;
2361 2307 }
2362 2308
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
2363 2309 mra_msgp->mra_message_type_plus = msg_typ << 6;
2364 2310 mra_msgp->mra_service_timeout_plus = ibt_usec2ib(service_time) << 3;
2365 2311
2366 2312 len = min(len, IBT_MRA_PRIV_DATA_SZ);
2367 2313 if (priv_data && (len > 0))
2368 2314 bcopy(priv_data, mra_msgp->mra_private_data, len);
2369 2315
2370 2316 IBCM_OUT_HDRP(statep->mra_msg)->AttributeID =
2371 2317 h2b16(IBCM_INCOMING_MRA + IBCM_ATTR_BASE_ID);
2372 2318
2373 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*mra_msgp))
2374 -
2375 2319 mutex_enter(&statep->state_mutex);
2376 2320
2377 2321 if ((statep->mode == IBCM_ACTIVE_MODE) &&
2378 2322 (statep->state == IBCM_STATE_REP_RCVD)) {
2379 2323 statep->state = IBCM_STATE_MRA_REP_SENT;
2380 2324 } else if (statep->mode == IBCM_PASSIVE_MODE) {
2381 2325 if (statep->state == IBCM_STATE_REQ_RCVD) {
2382 2326 statep->state = IBCM_STATE_MRA_SENT;
2383 2327 } else if (statep->ap_state == IBCM_AP_STATE_LAP_RCVD) {
2384 2328 statep->ap_state = IBCM_AP_STATE_MRA_LAP_RCVD;
2385 2329 } else {
2386 2330 IBTF_DPRINTF_L2(cmlog, "ibt_cm_delay: invalid state "
2387 2331 "/ap_state/mode %x, %x, %x", statep->state,
2388 2332 statep->ap_state, statep->mode);
2389 2333 mutex_exit(&statep->state_mutex);
2390 2334 return (IBT_CHAN_STATE_INVALID);
2391 2335 }
2392 2336 } else {
2393 2337 IBTF_DPRINTF_L2(cmlog, "ibt_cm_delay: invalid state "
2394 2338 "/ap_state/mode %x, %x, %x", statep->state,
2395 2339 statep->ap_state, statep->mode);
2396 2340 mutex_exit(&statep->state_mutex);
2397 2341
2398 2342 return (IBT_CHAN_STATE_INVALID);
2399 2343 }
2400 2344 /* service time is usecs, stale_clock is nsecs */
2401 2345 statep->stale_clock = gethrtime() +
2402 2346 (hrtime_t)ibt_ib2usec(ibt_usec2ib(service_time)) * (1000 *
2403 2347 statep->max_cm_retries);
2404 2348
2405 2349 statep->send_mad_flags |= IBCM_MRA_POST_BUSY;
2406 2350 IBCM_REF_CNT_INCR(statep); /* for ibcm_post_mra_complete */
2407 2351 mutex_exit(&statep->state_mutex);
2408 2352
2409 2353 IBCM_OUT_HDRP(statep->mra_msg)->TransactionID =
2410 2354 IBCM_OUT_HDRP(statep->stored_msg)->TransactionID;
2411 2355
2412 2356 /* post the MRA mad in blocking mode, as no timers involved */
2413 2357 ibcm_post_rc_mad(statep, statep->mra_msg, ibcm_post_mra_complete,
2414 2358 statep);
2415 2359 ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_MRA);
2416 2360 /* If this message isn't seen then ibt_cm_delay failed */
2417 2361 IBTF_DPRINTF_L3(cmlog, "ibt_cm_delay: done !!");
2418 2362
2419 2363 return (IBT_SUCCESS);
2420 2364 }
2421 2365
2422 2366
2423 2367 /*
2424 2368 * ibt_register_service()
2425 2369 * Register a service with the IBCM
2426 2370 *
2427 2371 * INPUTS:
2428 2372 * ibt_hdl The IBT client handle returned to the client
2429 2373 * on an ibt_attach() call.
2430 2374 *
2431 2375 * srv The address of a ibt_srv_desc_t that describes
2432 2376 * the service, containing the following:
2433 2377 *
2434 2378 * sd_ud_handler The Service CM UD event Handler.
2435 2379 * sd_handler The Service CM RC/UC/RD event Handler.
2436 2380 * sd_flags Service flags (peer-to-peer, or not).
2437 2381 *
2438 2382 * sid This tells CM if the service is local (sid is 0) or
2439 2383 * wellknown (sid is the starting service id of the range).
2440 2384 *
2441 2385 * num_sids The number of contiguous service-ids to reserve.
2442 2386 *
2443 2387 * srv_hdl The address of a service identification handle, used
2444 2388 * to deregister a service, and to bind GIDs to.
2445 2389 *
2446 2390 * ret_sid The address to store the Service ID return value.
2447 2391 * If num_sids > 1, ret_sid is the first Service ID
2448 2392 * in the range.
2449 2393 *
2450 2394 * ibt_register_service() returns:
2451 2395 * IBT_SUCCESS - added a service successfully.
2452 2396 * IBT_INVALID_PARAM - invalid input parameter.
2453 2397 * IBT_CM_FAILURE - failed to add the service.
2454 2398 * IBT_CM_SERVICE_EXISTS - service already exists.
2455 2399 * IBT_INSUFF_KERNEL_RESOURCE - ran out of local service ids (should
2456 2400 * never happen).
2457 2401 */
↓ open down ↓ |
73 lines elided |
↑ open up ↑ |
2458 2402 ibt_status_t
2459 2403 ibt_register_service(ibt_clnt_hdl_t ibt_hdl, ibt_srv_desc_t *srv,
2460 2404 ib_svc_id_t sid, int num_sids, ibt_srv_hdl_t *srv_hdl, ib_svc_id_t *ret_sid)
2461 2405 {
2462 2406 ibcm_svc_info_t *svcinfop;
2463 2407
2464 2408 IBTF_DPRINTF_L2(cmlog, "ibt_register_service(%p (%s), %p, 0x%llX, %d)",
2465 2409 ibt_hdl, ibtl_cm_get_clnt_name(ibt_hdl), srv, (longlong_t)sid,
2466 2410 num_sids);
2467 2411
2468 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*svcinfop))
2469 -
2470 2412 *srv_hdl = NULL;
2471 2413
2472 2414 if (num_sids <= 0) {
2473 2415 IBTF_DPRINTF_L2(cmlog, "ibt_register_service: "
2474 2416 "Invalid number of service-ids specified (%d)", num_sids);
2475 2417 return (IBT_INVALID_PARAM);
2476 2418 }
2477 2419
2478 2420 if (sid == 0) {
2479 2421 if (ret_sid == NULL)
2480 2422 return (IBT_INVALID_PARAM);
2481 2423 sid = ibcm_alloc_local_sids(num_sids);
2482 2424 if (sid == 0)
2483 2425 return (IBT_INSUFF_KERNEL_RESOURCE);
2484 2426
2485 2427 /* Make sure that the ServiceId specified is not of LOCAL AGN type. */
2486 2428 } else if ((sid & IB_SID_AGN_MASK) == IB_SID_AGN_LOCAL) {
2487 2429 IBTF_DPRINTF_L2(cmlog, "ibt_register_service: "
2488 2430 "Invalid non-LOCAL SID specified: 0x%llX",
2489 2431 (longlong_t)sid);
2490 2432 return (IBT_INVALID_PARAM);
2491 2433 }
2492 2434
2493 2435 svcinfop = ibcm_create_svc_entry(sid, num_sids);
2494 2436
2495 2437 if (svcinfop == NULL) {
2496 2438 IBTF_DPRINTF_L2(cmlog, "ibt_register_service: "
2497 2439 "Service-ID 0x%llx already registered", (longlong_t)sid);
2498 2440 return (IBT_CM_SERVICE_EXISTS);
2499 2441 }
2500 2442
2501 2443 /*
2502 2444 * 'sid' and 'num_sids' are filled in ibcm_create_svc_entry()
2503 2445 */
2504 2446 svcinfop->svc_flags = srv->sd_flags;
2505 2447 svcinfop->svc_rc_handler = srv->sd_handler;
2506 2448 svcinfop->svc_ud_handler = srv->sd_ud_handler;
2507 2449
2508 2450 if (ret_sid != NULL)
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
2509 2451 *ret_sid = sid;
2510 2452
2511 2453 *srv_hdl = svcinfop;
2512 2454
2513 2455 ibtl_cm_change_service_cnt(ibt_hdl, num_sids);
2514 2456
2515 2457 /* If this message isn't seen, then ibt_register_service failed. */
2516 2458 IBTF_DPRINTF_L2(cmlog, "ibt_register_service: done (%p, %llX)",
2517 2459 svcinfop, sid);
2518 2460
2519 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*svcinfop))
2520 -
2521 2461 return (IBT_SUCCESS);
2522 2462 }
2523 2463
2524 2464
2525 2465 static ibt_status_t
2526 2466 ibcm_write_service_record(ibmf_saa_handle_t saa_handle,
2527 2467 sa_service_record_t *srv_recp, ibmf_saa_access_type_t saa_type)
2528 2468 {
2529 2469 int rval;
2530 2470 int retry;
2531 2471
2532 2472 ibcm_sa_access_enter();
2533 2473 for (retry = 0; retry < ibcm_max_sa_retries; retry++) {
2534 2474 rval = ibmf_saa_update_service_record(
2535 2475 saa_handle, srv_recp, saa_type, 0);
2536 2476 if (rval != IBMF_TRANS_TIMEOUT) {
2537 2477 break;
2538 2478 }
2539 2479 IBTF_DPRINTF_L2(cmlog, "ibcm_write_service_record: "
2540 2480 "ibmf_saa_update_service_record timed out"
2541 2481 " SID = %llX, rval = %d, saa_type = %d",
2542 2482 (longlong_t)srv_recp->ServiceID, rval, saa_type);
2543 2483 delay(ibcm_sa_timeout_delay);
2544 2484 }
2545 2485 ibcm_sa_access_exit();
2546 2486
2547 2487 if (rval != IBMF_SUCCESS) {
2548 2488 IBTF_DPRINTF_L2(cmlog, "ibcm_write_service_record: "
2549 2489 "ibmf_saa_update_service_record() : Failed - %d", rval);
2550 2490 return (ibcm_ibmf_analyze_error(rval));
2551 2491 } else
2552 2492 return (IBT_SUCCESS);
2553 2493 }
2554 2494
2555 2495
2556 2496 static void
2557 2497 ibcm_rem_stale_srec(ibmf_saa_handle_t saa_handle, sa_service_record_t *srec)
2558 2498 {
2559 2499 ibt_status_t retval;
2560 2500 uint_t num_found;
2561 2501 size_t length;
2562 2502 sa_service_record_t *srv_resp;
2563 2503 void *results_p;
2564 2504 uint_t i;
2565 2505 uint64_t component_mask;
2566 2506 ibmf_saa_access_args_t access_args;
2567 2507
2568 2508 component_mask =
2569 2509 SA_SR_COMPMASK_PKEY | SA_SR_COMPMASK_NAME | SA_SR_COMPMASK_GID;
2570 2510
2571 2511 /* Call in SA Access retrieve routine to get Service Records. */
2572 2512 access_args.sq_attr_id = SA_SERVICERECORD_ATTRID;
2573 2513 access_args.sq_access_type = IBMF_SAA_RETRIEVE;
2574 2514 access_args.sq_component_mask = component_mask;
2575 2515 access_args.sq_template = srec;
2576 2516 access_args.sq_template_length = sizeof (sa_service_record_t);
2577 2517 access_args.sq_callback = NULL;
2578 2518 access_args.sq_callback_arg = NULL;
2579 2519
2580 2520 retval = ibcm_contact_sa_access(saa_handle, &access_args, &length,
2581 2521 &results_p);
2582 2522 if (retval != IBT_SUCCESS) {
2583 2523 IBTF_DPRINTF_L2(cmlog, "ibcm_rem_stale_srec: "
2584 2524 "SA Access Failure");
2585 2525 return;
2586 2526 }
2587 2527
2588 2528 num_found = length / sizeof (sa_service_record_t);
2589 2529
2590 2530 if (num_found)
2591 2531 IBTF_DPRINTF_L3(cmlog, "ibcm_rem_stale_srec: "
2592 2532 "Found %d matching Service Records.", num_found);
2593 2533
2594 2534 /* Validate the returned number of records. */
2595 2535 if ((results_p != NULL) && (num_found > 0)) {
2596 2536
2597 2537 /* Remove all the records. */
2598 2538 for (i = 0; i < num_found; i++) {
2599 2539
2600 2540 srv_resp = (sa_service_record_t *)
2601 2541 ((uchar_t *)results_p +
2602 2542 i * sizeof (sa_service_record_t));
2603 2543
2604 2544 /*
2605 2545 * Found some matching records, but check out whether
2606 2546 * this Record is really stale or just happens to match
2607 2547 * the current session records. If yes, don't remove it.
2608 2548 */
2609 2549 mutex_enter(&ibcm_svc_info_lock);
2610 2550 if (ibcm_find_svc_entry(srv_resp->ServiceID) != NULL) {
2611 2551 /* This record is NOT STALE. */
2612 2552 mutex_exit(&ibcm_svc_info_lock);
2613 2553 IBTF_DPRINTF_L3(cmlog, "ibcm_rem_stale_srec: "
2614 2554 "This is not Stale, it's an active record");
2615 2555 continue;
2616 2556 }
2617 2557 mutex_exit(&ibcm_svc_info_lock);
2618 2558
2619 2559 IBTF_DPRINTF_L2(cmlog, "ibcm_rem_stale_srec: "
2620 2560 "Removing Stale Rec: %s, %llX",
2621 2561 srv_resp->ServiceName, srv_resp->ServiceID);
↓ open down ↓ |
91 lines elided |
↑ open up ↑ |
2622 2562
2623 2563 IBCM_DUMP_SERVICE_REC(srv_resp);
2624 2564
2625 2565 /*
2626 2566 * Remove the Service Record Entry from SA.
2627 2567 *
2628 2568 * Get ServiceID info from Response Buf, other
2629 2569 * attributes are already filled-in.
2630 2570 */
2631 2571
2632 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(srec->ServiceID))
2633 -
2634 2572 srec->ServiceID = srv_resp->ServiceID;
2635 2573
2636 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(srec->ServiceID))
2637 -
2638 2574 (void) ibcm_write_service_record(saa_handle, srec,
2639 2575 IBMF_SAA_DELETE);
2640 2576 }
2641 2577
2642 2578 /* Deallocate the memory for results_p. */
2643 2579 kmem_free(results_p, length);
2644 2580 }
2645 2581 }
2646 2582
2647 2583
2648 2584
2649 2585 /*
2650 2586 * ibt_bind_service()
2651 2587 * Register a service with the IBCM
2652 2588 *
2653 2589 * INPUTS:
2654 2590 * srv_hdl The service id handle returned to the client
2655 2591 * on an ibt_service_register() call.
2656 2592 *
2657 2593 * gid The GID to which to bind the service.
2658 2594 *
2659 2595 * srv_bind The address of a ibt_srv_bind_t that describes
2660 2596 * the service record. This should be NULL if there
2661 2597 * is to be no service record. This contains:
2662 2598 *
2663 2599 * sb_lease Lease period
2664 2600 * sb_pkey Partition
2665 2601 * sb_name pointer to ASCII string Service Name,
2666 2602 * NULL terminated.
2667 2603 * sb_key[] Key to secure the service record.
2668 2604 * sb_data Service Data structure (64-byte)
2669 2605 *
2670 2606 * cm_private First argument of Service handler.
2671 2607 *
2672 2608 * sb_hdl_p The address of a service bind handle, used
2673 2609 * to undo the service binding.
2674 2610 *
2675 2611 * ibt_bind_service() returns:
2676 2612 * IBT_SUCCESS - added a service successfully.
2677 2613 * IBT_INVALID_PARAM - invalid input parameter.
2678 2614 * IBT_CM_FAILURE - failed to add the service.
2679 2615 * IBT_CM_SERVICE_EXISTS - service already exists.
2680 2616 */
2681 2617 ibt_status_t
2682 2618 ibt_bind_service(ibt_srv_hdl_t srv_hdl, ib_gid_t gid, ibt_srv_bind_t *srv_bind,
2683 2619 void *cm_private, ibt_sbind_hdl_t *sb_hdl_p)
2684 2620 {
2685 2621 ibt_status_t status;
2686 2622 ibtl_cm_hca_port_t port;
2687 2623 ibcm_svc_bind_t *sbindp, *sbp;
2688 2624 ibcm_hca_info_t *hcap;
2689 2625 ib_svc_id_t sid, start_sid, end_sid;
↓ open down ↓ |
42 lines elided |
↑ open up ↑ |
2690 2626 ibmf_saa_handle_t saa_handle;
2691 2627 sa_service_record_t srv_rec;
2692 2628 uint16_t pkey_ix;
2693 2629
2694 2630 if (sb_hdl_p != NULL)
2695 2631 *sb_hdl_p = NULL; /* return value for error cases */
2696 2632
2697 2633 IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: srv_hdl %p, gid (%llX:%llX)",
2698 2634 srv_hdl, (longlong_t)gid.gid_prefix, (longlong_t)gid.gid_guid);
2699 2635
2700 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sbindp))
2701 -
2702 2636 /* Call ibtl_cm_get_hca_port to get the port number and the HCA GUID. */
2703 2637 if ((status = ibtl_cm_get_hca_port(gid, 0, &port)) != IBT_SUCCESS) {
2704 2638 IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: "
2705 2639 "ibtl_cm_get_hca_port failed: %d", status);
2706 2640 return (status);
2707 2641 }
2708 2642 IBTF_DPRINTF_L4(cmlog, "ibt_bind_service: Port:%d HCA GUID:%llX",
2709 2643 port.hp_port, port.hp_hca_guid);
2710 2644
2711 2645 hcap = ibcm_find_hca_entry(port.hp_hca_guid);
2712 2646 if (hcap == NULL) {
2713 2647 IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: NO HCA found");
2714 2648 return (IBT_HCA_BUSY_DETACHING);
2715 2649 }
2716 2650 IBTF_DPRINTF_L4(cmlog, "ibt_bind_service: hcap = %p", hcap);
2717 2651
2718 2652 if (srv_bind != NULL) {
2719 2653 saa_handle = ibcm_get_saa_handle(hcap, port.hp_port);
2720 2654 if (saa_handle == NULL) {
2721 2655 IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: "
2722 2656 "saa_handle is NULL");
2723 2657 ibcm_dec_hca_acc_cnt(hcap);
2724 2658 return (IBT_HCA_PORT_NOT_ACTIVE);
2725 2659 }
2726 2660 if (srv_bind->sb_pkey == 0) {
2727 2661 IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: "
2728 2662 "P_Key must not be 0");
2729 2663 ibcm_dec_hca_acc_cnt(hcap);
2730 2664 return (IBT_INVALID_PARAM);
2731 2665 }
2732 2666 if (strlen(srv_bind->sb_name) >= IB_SVC_NAME_LEN) {
2733 2667 IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: "
2734 2668 "Service Name is too long");
2735 2669 ibcm_dec_hca_acc_cnt(hcap);
2736 2670 return (IBT_INVALID_PARAM);
2737 2671 } else
2738 2672 IBTF_DPRINTF_L3(cmlog, "ibt_bind_service: "
2739 2673 "Service Name='%s'", srv_bind->sb_name);
2740 2674 status = ibt_pkey2index_byguid(port.hp_hca_guid,
2741 2675 port.hp_port, srv_bind->sb_pkey, &pkey_ix);
2742 2676 if (status != IBT_SUCCESS) {
2743 2677 IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: "
2744 2678 "P_Key 0x%x not found in P_Key_Table",
2745 2679 srv_bind->sb_pkey);
2746 2680 ibcm_dec_hca_acc_cnt(hcap);
2747 2681 return (status);
2748 2682 }
2749 2683 }
2750 2684
2751 2685 /* assume success - allocate before locking */
2752 2686 sbindp = kmem_zalloc(sizeof (*sbindp), KM_SLEEP);
2753 2687 sbindp->sbind_cm_private = cm_private;
2754 2688 sbindp->sbind_gid = gid;
2755 2689 sbindp->sbind_hcaguid = port.hp_hca_guid;
2756 2690 sbindp->sbind_port = port.hp_port;
2757 2691
2758 2692 mutex_enter(&ibcm_svc_info_lock);
2759 2693
2760 2694 sbp = srv_hdl->svc_bind_list;
2761 2695 while (sbp != NULL) {
2762 2696 if (sbp->sbind_gid.gid_guid == gid.gid_guid &&
2763 2697 sbp->sbind_gid.gid_prefix == gid.gid_prefix) {
2764 2698 if (srv_bind == NULL ||
2765 2699 srv_bind->sb_pkey == sbp->sbind_pkey) {
2766 2700 IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: "
2767 2701 "failed: GID %llX:%llX and PKEY %x is "
2768 2702 "already bound", gid.gid_prefix,
2769 2703 gid.gid_guid, sbp->sbind_pkey);
2770 2704 mutex_exit(&ibcm_svc_info_lock);
2771 2705 ibcm_dec_hca_acc_cnt(hcap);
2772 2706 kmem_free(sbindp, sizeof (*sbindp));
2773 2707 return (IBT_CM_SERVICE_EXISTS);
2774 2708 }
2775 2709 }
2776 2710 sbp = sbp->sbind_link;
2777 2711 }
2778 2712 /* no entry found */
2779 2713
2780 2714 sbindp->sbind_link = srv_hdl->svc_bind_list;
2781 2715 srv_hdl->svc_bind_list = sbindp;
2782 2716
2783 2717 mutex_exit(&ibcm_svc_info_lock);
2784 2718
2785 2719 if (srv_bind != NULL) {
2786 2720 bzero(&srv_rec, sizeof (srv_rec));
2787 2721
2788 2722 srv_rec.ServiceLease =
2789 2723 sbindp->sbind_lease = srv_bind->sb_lease;
2790 2724 srv_rec.ServiceP_Key =
2791 2725 sbindp->sbind_pkey = srv_bind->sb_pkey;
2792 2726 srv_rec.ServiceKey_hi =
2793 2727 sbindp->sbind_key[0] = srv_bind->sb_key[0];
2794 2728 srv_rec.ServiceKey_lo =
2795 2729 sbindp->sbind_key[1] = srv_bind->sb_key[1];
2796 2730 (void) strcpy(sbindp->sbind_name, srv_bind->sb_name);
2797 2731 (void) strcpy((char *)srv_rec.ServiceName, srv_bind->sb_name);
2798 2732 srv_rec.ServiceGID = gid;
2799 2733
2800 2734 /*
2801 2735 * Find out whether we have any stale Local Service records
2802 2736 * matching the current attributes. If yes, we shall try to
2803 2737 * remove them from SA using the current request's ServiceKey.
2804 2738 *
2805 2739 * We will perform this operation only for Local Services, as
2806 2740 * it is handled by SA automatically for WellKnown Services.
2807 2741 *
2808 2742 * Ofcourse, clients can specify NOT to do this clean-up by
2809 2743 * setting IBT_SBIND_NO_CLEANUP flag (srv_bind->sb_flag).
2810 2744 */
2811 2745 if ((srv_hdl->svc_id & IB_SID_AGN_LOCAL) &&
2812 2746 (!(srv_bind->sb_flag & IBT_SBIND_NO_CLEANUP))) {
2813 2747 ibcm_rem_stale_srec(saa_handle, &srv_rec);
2814 2748 }
2815 2749
2816 2750 /* Handle endianess for service data. */
2817 2751 ibcm_swizzle_from_srv(&srv_bind->sb_data, sbindp->sbind_data);
2818 2752
2819 2753 bcopy(sbindp->sbind_data, srv_rec.ServiceData, IB_SVC_DATA_LEN);
2820 2754
2821 2755 /* insert srv record into the SA */
2822 2756 start_sid = srv_hdl->svc_id;
2823 2757 end_sid = start_sid + srv_hdl->svc_num_sids - 1;
2824 2758 for (sid = start_sid; sid <= end_sid; sid++) {
2825 2759
2826 2760 srv_rec.ServiceID = sid;
2827 2761
2828 2762 IBCM_DUMP_SERVICE_REC(&srv_rec);
2829 2763
2830 2764 IBTF_DPRINTF_L4(cmlog, "ibt_bind_service: "
2831 2765 "ibmf_saa_write_service_record, SvcId = %llX",
2832 2766 (longlong_t)sid);
2833 2767
2834 2768 status = ibcm_write_service_record(saa_handle, &srv_rec,
2835 2769 IBMF_SAA_UPDATE);
2836 2770 if (status != IBT_SUCCESS) {
2837 2771 IBTF_DPRINTF_L2(cmlog, "ibt_bind_service:"
2838 2772 " ibcm_write_service_record fails %d, "
2839 2773 "sid %llX", status, (longlong_t)sid);
2840 2774
2841 2775 if (sid != start_sid) {
2842 2776 /*
2843 2777 * Bind failed while bind SID other than
2844 2778 * first in the sid_range. So we need
2845 2779 * to unbind those, which are passed.
2846 2780 *
2847 2781 * Need to increment svc count to
2848 2782 * compensate for ibt_unbind_service().
2849 2783 */
2850 2784 ibcm_inc_hca_svc_cnt(hcap);
2851 2785 ibcm_dec_hca_acc_cnt(hcap);
2852 2786
2853 2787 (void) ibt_unbind_service(srv_hdl,
2854 2788 sbindp);
2855 2789 } else {
2856 2790 ibcm_svc_bind_t **sbpp;
2857 2791
2858 2792 /*
2859 2793 * Bind failed for the first SID or the
2860 2794 * only SID in question, then no need
2861 2795 * to unbind, just free memory and
2862 2796 * return error.
2863 2797 */
2864 2798 mutex_enter(&ibcm_svc_info_lock);
2865 2799
2866 2800 sbpp = &srv_hdl->svc_bind_list;
2867 2801 sbp = *sbpp;
2868 2802 while (sbp != NULL) {
2869 2803 if (sbp == sbindp) {
2870 2804 *sbpp = sbp->sbind_link;
2871 2805 break;
2872 2806 }
2873 2807 sbpp = &sbp->sbind_link;
2874 2808 sbp = *sbpp;
2875 2809 }
2876 2810 mutex_exit(&ibcm_svc_info_lock);
2877 2811 ibcm_dec_hca_acc_cnt(hcap);
2878 2812
2879 2813 kmem_free(sbindp, sizeof (*sbindp));
2880 2814 }
2881 2815 return (status);
2882 2816 }
2883 2817 }
2884 2818 }
↓ open down ↓ |
173 lines elided |
↑ open up ↑ |
2885 2819 ibcm_inc_hca_svc_cnt(hcap);
2886 2820 ibcm_dec_hca_acc_cnt(hcap);
2887 2821
2888 2822 /* If this message isn't seen then ibt_bind_service failed */
2889 2823 IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: DONE (%p, %llX:%llX)",
2890 2824 srv_hdl, gid.gid_prefix, gid.gid_guid);
2891 2825
2892 2826 if (sb_hdl_p != NULL)
2893 2827 *sb_hdl_p = sbindp;
2894 2828
2895 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*sbindp))
2896 -
2897 2829 return (IBT_SUCCESS);
2898 2830 }
2899 2831
2900 2832 ibt_status_t
2901 2833 ibt_unbind_service(ibt_srv_hdl_t srv_hdl, ibt_sbind_hdl_t sbindp)
2902 2834 {
2903 2835 ib_svc_id_t sid, end_sid;
2904 2836 ibt_status_t rval;
2905 2837 ibcm_hca_info_t *hcap;
2906 2838 ibcm_svc_bind_t *sbp, **sbpp;
2907 2839
2908 2840 IBTF_DPRINTF_L2(cmlog, "ibt_unbind_service(%p, %p)",
2909 2841 srv_hdl, sbindp);
2910 2842
2911 2843 hcap = ibcm_find_hca_entry(sbindp->sbind_hcaguid);
2912 2844
2913 2845 /* If there is a service on hca, respective hcap cannot go away */
2914 2846 ASSERT(hcap != NULL);
2915 2847
2916 2848 mutex_enter(&ibcm_svc_info_lock);
2917 2849
2918 2850 sbpp = &srv_hdl->svc_bind_list;
2919 2851 sbp = *sbpp;
2920 2852 while (sbp != NULL) {
2921 2853 if (sbp == sbindp) {
2922 2854 *sbpp = sbp->sbind_link;
2923 2855 break;
2924 2856 }
2925 2857 sbpp = &sbp->sbind_link;
2926 2858 sbp = *sbpp;
2927 2859 }
2928 2860 sid = srv_hdl->svc_id;
2929 2861 end_sid = srv_hdl->svc_id + srv_hdl->svc_num_sids - 1;
2930 2862 if (sbp != NULL)
2931 2863 while (sbp->sbind_rewrite_state == IBCM_REWRITE_BUSY)
2932 2864 cv_wait(&ibcm_svc_info_cv, &ibcm_svc_info_lock);
2933 2865 mutex_exit(&ibcm_svc_info_lock);
2934 2866
2935 2867 if (sbp == NULL) {
2936 2868 IBTF_DPRINTF_L2(cmlog, "ibt_unbind_service: "
2937 2869 "service binding not found: srv_hdl %p, srv_bind %p",
2938 2870 srv_hdl, sbindp);
2939 2871 ibcm_dec_hca_acc_cnt(hcap);
2940 2872 return (IBT_INVALID_PARAM);
2941 2873 }
2942 2874
2943 2875 if (sbindp->sbind_pkey != 0) { /* Are there service records? */
2944 2876 ibtl_cm_hca_port_t port;
2945 2877 sa_service_record_t srv_rec;
2946 2878 ibmf_saa_handle_t saa_handle;
2947 2879 ibt_status_t status;
2948 2880
2949 2881 /* get the default SGID of the port */
2950 2882 if ((status = ibtl_cm_get_hca_port(sbindp->sbind_gid, 0, &port))
2951 2883 != IBT_SUCCESS) {
2952 2884 IBTF_DPRINTF_L2(cmlog, "ibt_unbind_service: "
2953 2885 "ibtl_cm_get_hca_port failed: %d", status);
2954 2886 /* we're done, but there may be stale service records */
2955 2887 goto done;
2956 2888 }
2957 2889
2958 2890 saa_handle = ibcm_get_saa_handle(hcap, port.hp_port);
2959 2891 if (saa_handle == NULL) {
2960 2892 IBTF_DPRINTF_L2(cmlog, "ibt_unbind_service: "
2961 2893 "saa_handle is NULL");
2962 2894 /* we're done, but there may be stale service records */
2963 2895 goto done;
2964 2896 }
2965 2897
2966 2898 /* Fill in fields of srv_rec */
2967 2899 bzero(&srv_rec, sizeof (srv_rec));
2968 2900
2969 2901 srv_rec.ServiceP_Key = sbindp->sbind_pkey;
2970 2902 srv_rec.ServiceKey_hi = sbindp->sbind_key[0];
2971 2903 srv_rec.ServiceKey_lo = sbindp->sbind_key[1];
2972 2904 srv_rec.ServiceGID = sbindp->sbind_gid;
2973 2905 (void) strcpy((char *)srv_rec.ServiceName, sbindp->sbind_name);
2974 2906
2975 2907 while (sid <= end_sid) {
2976 2908
2977 2909 srv_rec.ServiceID = sid;
2978 2910 IBCM_DUMP_SERVICE_REC(&srv_rec);
2979 2911
2980 2912 rval = ibcm_write_service_record(saa_handle, &srv_rec,
2981 2913 IBMF_SAA_DELETE);
2982 2914
2983 2915 IBTF_DPRINTF_L4(cmlog, "ibt_unbind_service: "
2984 2916 "ibcm_write_service_record rval = %d, SID %llx",
2985 2917 rval, sid);
2986 2918 if (rval != IBT_SUCCESS) {
2987 2919 /* this is not considered a reason to fail */
2988 2920 IBTF_DPRINTF_L2(cmlog, "ibt_unbind_service: "
2989 2921 "ibcm_write_service_record fails %d, "
2990 2922 "sid %llx", rval, sid);
2991 2923 }
2992 2924 sid++;
2993 2925 }
2994 2926 }
2995 2927 done:
2996 2928 ibcm_dec_hca_svc_cnt(hcap);
2997 2929 ibcm_dec_hca_acc_cnt(hcap);
2998 2930 kmem_free(sbindp, sizeof (*sbindp));
2999 2931
3000 2932 /* If this message isn't seen then ibt_unbind_service failed */
3001 2933 IBTF_DPRINTF_L2(cmlog, "ibt_unbind_service: done !!");
3002 2934
3003 2935 return (IBT_SUCCESS);
3004 2936 }
3005 2937
3006 2938 /*
3007 2939 * Simply pull off each binding from the list and unbind it.
3008 2940 * If any of the unbind calls fail, we fail.
3009 2941 */
3010 2942 ibt_status_t
3011 2943 ibt_unbind_all_services(ibt_srv_hdl_t srv_hdl)
3012 2944 {
3013 2945 ibt_status_t status;
3014 2946 ibcm_svc_bind_t *sbp;
3015 2947
3016 2948 mutex_enter(&ibcm_svc_info_lock);
3017 2949 sbp = NULL;
3018 2950
3019 2951 /* this compare keeps the loop from being infinite */
3020 2952 while (sbp != srv_hdl->svc_bind_list) {
3021 2953 sbp = srv_hdl->svc_bind_list;
3022 2954 mutex_exit(&ibcm_svc_info_lock);
3023 2955 status = ibt_unbind_service(srv_hdl, sbp);
3024 2956 if (status != IBT_SUCCESS)
3025 2957 return (status);
3026 2958 mutex_enter(&ibcm_svc_info_lock);
3027 2959 if (srv_hdl->svc_bind_list == NULL)
3028 2960 break;
3029 2961 }
3030 2962 mutex_exit(&ibcm_svc_info_lock);
3031 2963 return (IBT_SUCCESS);
3032 2964 }
3033 2965
3034 2966 /*
3035 2967 * ibt_deregister_service()
3036 2968 * Deregister a service with the IBCM
3037 2969 *
3038 2970 * INPUTS:
3039 2971 * ibt_hdl The IBT client handle returned to the client
3040 2972 * on an ibt_attach() call.
3041 2973 *
3042 2974 * srv_hdl The address of a service identification handle, used
3043 2975 * to de-register a service.
3044 2976 * RETURN VALUES:
3045 2977 * IBT_SUCCESS on success (or respective failure on error)
3046 2978 */
3047 2979 ibt_status_t
3048 2980 ibt_deregister_service(ibt_clnt_hdl_t ibt_hdl, ibt_srv_hdl_t srv_hdl)
3049 2981 {
3050 2982 ibcm_svc_info_t *svcp;
3051 2983 ibcm_svc_lookup_t svc;
3052 2984
3053 2985 IBTF_DPRINTF_L2(cmlog, "ibt_deregister_service(%p (%s), %p)",
3054 2986 ibt_hdl, ibtl_cm_get_clnt_name(ibt_hdl), srv_hdl);
3055 2987
3056 2988 mutex_enter(&ibcm_svc_info_lock);
3057 2989
3058 2990 if (srv_hdl->svc_bind_list != NULL) {
↓ open down ↓ |
152 lines elided |
↑ open up ↑ |
3059 2991 IBTF_DPRINTF_L2(cmlog, "ibt_deregister_service:"
3060 2992 " srv_hdl %p still has bindings", srv_hdl);
3061 2993 mutex_exit(&ibcm_svc_info_lock);
3062 2994 return (IBT_CM_SERVICE_BUSY);
3063 2995 }
3064 2996 svc.sid = srv_hdl->svc_id;
3065 2997 svc.num_sids = 1;
3066 2998 IBTF_DPRINTF_L3(cmlog, "ibt_deregister_service: SID 0x%llX, numsids %d",
3067 2999 srv_hdl->svc_id, srv_hdl->svc_num_sids);
3068 3000
3069 -#ifdef __lock_lint
3070 - ibcm_svc_compare(NULL, NULL);
3071 -#endif
3072 3001 svcp = avl_find(&ibcm_svc_avl_tree, &svc, NULL);
3073 3002 if (svcp != srv_hdl) {
3074 3003 mutex_exit(&ibcm_svc_info_lock);
3075 3004 IBTF_DPRINTF_L2(cmlog, "ibt_deregister_service(): "
3076 3005 "srv_hdl %p not found", srv_hdl);
3077 3006 return (IBT_INVALID_PARAM);
3078 3007 }
3079 3008 avl_remove(&ibcm_svc_avl_tree, svcp);
3080 3009
3081 3010 /* wait for active REQ/SREQ handling to be done */
3082 3011 svcp->svc_to_delete = 1;
3083 3012 while (svcp->svc_ref_cnt != 0)
3084 3013 cv_wait(&ibcm_svc_info_cv, &ibcm_svc_info_lock);
3085 3014
3086 3015 mutex_exit(&ibcm_svc_info_lock);
3087 3016
3088 3017 if ((srv_hdl->svc_id & IB_SID_AGN_MASK) == IB_SID_AGN_LOCAL)
3089 3018 ibcm_free_local_sids(srv_hdl->svc_id, srv_hdl->svc_num_sids);
3090 3019
3091 3020 ibtl_cm_change_service_cnt(ibt_hdl, -srv_hdl->svc_num_sids);
3092 3021 kmem_free(srv_hdl, sizeof (*srv_hdl));
3093 3022
3094 3023 /* If this message isn't seen then ibt_deregister_service failed */
3095 3024 IBTF_DPRINTF_L2(cmlog, "ibt_deregister_service: done !!");
3096 3025
3097 3026 return (IBT_SUCCESS);
3098 3027 }
3099 3028
3100 3029 ibcm_status_t
3101 3030 ibcm_ar_init(void)
3102 3031 {
3103 3032 ib_svc_id_t sid = IBCM_DAPL_ATS_SID;
3104 3033 ibcm_svc_info_t *tmp_svcp;
3105 3034
3106 3035 IBTF_DPRINTF_L3(cmlog, "ibcm_ar_init()");
3107 3036
3108 3037 /* remove this special SID from the pool of available SIDs */
3109 3038 if ((tmp_svcp = ibcm_create_svc_entry(sid, 1)) == NULL) {
3110 3039 IBTF_DPRINTF_L3(cmlog, "ibcm_ar_init: "
3111 3040 "DAPL ATS SID 0x%llx already registered", (longlong_t)sid);
3112 3041 return (IBCM_FAILURE);
3113 3042 }
3114 3043 mutex_enter(&ibcm_svc_info_lock);
3115 3044 ibcm_ar_svcinfop = tmp_svcp;
3116 3045 ibcm_ar_list = NULL; /* no address records registered yet */
3117 3046 mutex_exit(&ibcm_svc_info_lock);
3118 3047 return (IBCM_SUCCESS);
3119 3048 }
3120 3049
3121 3050 ibcm_status_t
3122 3051 ibcm_ar_fini(void)
3123 3052 {
3124 3053 ibcm_ar_t *ar_list;
3125 3054 ibcm_svc_info_t *tmp_svcp;
3126 3055
3127 3056 mutex_enter(&ibcm_svc_info_lock);
3128 3057 ar_list = ibcm_ar_list;
3129 3058
3130 3059 if (ar_list == NULL &&
3131 3060 avl_numnodes(&ibcm_svc_avl_tree) == 1 &&
3132 3061 avl_first(&ibcm_svc_avl_tree) == ibcm_ar_svcinfop) {
3133 3062 avl_remove(&ibcm_svc_avl_tree, ibcm_ar_svcinfop);
3134 3063 tmp_svcp = ibcm_ar_svcinfop;
3135 3064 mutex_exit(&ibcm_svc_info_lock);
3136 3065 kmem_free(tmp_svcp, sizeof (*ibcm_ar_svcinfop));
3137 3066 return (IBCM_SUCCESS);
3138 3067 }
3139 3068 mutex_exit(&ibcm_svc_info_lock);
3140 3069 return (IBCM_FAILURE);
3141 3070 }
3142 3071
3143 3072
3144 3073 /*
3145 3074 * Return to the caller:
3146 3075 * IBT_SUCCESS Found a perfect match.
3147 3076 * *arpp is set to the record.
3148 3077 * IBT_INCONSISTENT_AR Found a record that's inconsistent.
3149 3078 * IBT_AR_NOT_REGISTERED Found no record with same GID/pkey and
3150 3079 * found no record with same data.
3151 3080 */
3152 3081 static ibt_status_t
3153 3082 ibcm_search_ar(ibt_ar_t *arp, ibcm_ar_t **arpp)
3154 3083 {
3155 3084 ibcm_ar_t *tmp;
3156 3085 int i;
3157 3086
3158 3087 ASSERT(MUTEX_HELD(&ibcm_svc_info_lock));
3159 3088 tmp = ibcm_ar_list;
3160 3089 while (tmp != NULL) {
3161 3090 if (tmp->ar.ar_gid.gid_prefix == arp->ar_gid.gid_prefix &&
3162 3091 tmp->ar.ar_gid.gid_guid == arp->ar_gid.gid_guid &&
3163 3092 tmp->ar.ar_pkey == arp->ar_pkey) {
3164 3093 for (i = 0; i < IBCM_DAPL_ATS_NBYTES; i++)
3165 3094 if (tmp->ar.ar_data[i] != arp->ar_data[i])
3166 3095 return (IBT_INCONSISTENT_AR);
3167 3096 *arpp = tmp;
3168 3097 return (IBT_SUCCESS);
3169 3098 } else {
3170 3099 /* if all the data bytes match, we have inconsistency */
3171 3100 for (i = 0; i < IBCM_DAPL_ATS_NBYTES; i++)
3172 3101 if (tmp->ar.ar_data[i] != arp->ar_data[i])
3173 3102 break;
3174 3103 if (i == IBCM_DAPL_ATS_NBYTES)
3175 3104 return (IBT_INCONSISTENT_AR);
3176 3105 /* try next address record */
3177 3106 }
3178 3107 tmp = tmp->ar_link;
3179 3108 }
3180 3109 return (IBT_AR_NOT_REGISTERED);
3181 3110 }
3182 3111
3183 3112 ibt_status_t
3184 3113 ibt_register_ar(ibt_clnt_hdl_t ibt_hdl, ibt_ar_t *arp)
3185 3114 {
3186 3115 ibcm_ar_t *found;
3187 3116 ibcm_ar_t *tmp;
3188 3117 ibt_status_t status;
3189 3118 ibt_status_t s1, s2;
3190 3119 char *s;
3191 3120 ibcm_ar_ref_t *hdlp;
3192 3121 ibcm_ar_t *new;
3193 3122 ibcm_ar_t **linkp;
3194 3123 ibtl_cm_hca_port_t cm_port;
3195 3124 uint16_t pkey_ix;
3196 3125 ibcm_hca_info_t *hcap;
3197 3126 ibmf_saa_handle_t saa_handle;
3198 3127 sa_service_record_t *srv_recp;
3199 3128 uint64_t gid_ored;
3200 3129
3201 3130 IBTF_DPRINTF_L3(cmlog, "ibt_register_ar: PKey 0x%X GID %llX:%llX",
3202 3131 arp->ar_pkey, (longlong_t)arp->ar_gid.gid_prefix,
3203 3132 (longlong_t)arp->ar_gid.gid_guid);
3204 3133
3205 3134 /*
3206 3135 * If P_Key is 0, but GID is not, this query is invalid.
3207 3136 * If GID is 0, but P_Key is not, this query is invalid.
3208 3137 */
3209 3138 gid_ored = arp->ar_gid.gid_guid | arp->ar_gid.gid_prefix;
3210 3139 if ((arp->ar_pkey == 0 && gid_ored != 0ULL) ||
3211 3140 (arp->ar_pkey != 0 && gid_ored == 0ULL)) {
3212 3141 IBTF_DPRINTF_L2(cmlog, "ibt_register_ar: "
3213 3142 "GID/P_Key is not valid");
3214 3143 return (IBT_INVALID_PARAM);
3215 3144 }
3216 3145
3217 3146 /* assume success, so these might be needed */
3218 3147 hdlp = kmem_alloc(sizeof (*hdlp), KM_SLEEP);
3219 3148 new = kmem_zalloc(sizeof (*new), KM_SLEEP);
3220 3149
3221 3150 mutex_enter(&ibcm_svc_info_lock);
3222 3151 /* search for existing GID/pkey (there can be at most 1) */
3223 3152 status = ibcm_search_ar(arp, &found);
3224 3153 if (status == IBT_INCONSISTENT_AR) {
3225 3154 mutex_exit(&ibcm_svc_info_lock);
3226 3155 kmem_free(new, sizeof (*new));
3227 3156 kmem_free(hdlp, sizeof (*hdlp));
3228 3157 IBTF_DPRINTF_L2(cmlog, "ibt_register_ar: "
3229 3158 "address record is inconsistent with a known one");
3230 3159 return (IBT_INCONSISTENT_AR);
3231 3160 } else if (status == IBT_SUCCESS) {
3232 3161 if (found->ar_flags == IBCM_AR_INITING) {
3233 3162 found->ar_waiters++;
3234 3163 cv_wait(&found->ar_cv, &ibcm_svc_info_lock);
3235 3164 found->ar_waiters--;
3236 3165 }
3237 3166 if (found->ar_flags == IBCM_AR_FAILED) {
3238 3167 if (found->ar_waiters == 0) {
3239 3168 cv_destroy(&found->ar_cv);
3240 3169 kmem_free(found, sizeof (*found));
3241 3170 }
3242 3171 mutex_exit(&ibcm_svc_info_lock);
3243 3172 kmem_free(new, sizeof (*new));
3244 3173 kmem_free(hdlp, sizeof (*hdlp));
3245 3174 return (ibt_get_module_failure(IBT_FAILURE_IBCM, 0));
3246 3175 }
3247 3176 hdlp->ar_ibt_hdl = ibt_hdl;
3248 3177 hdlp->ar_ref_link = found->ar_ibt_hdl_list;
3249 3178 found->ar_ibt_hdl_list = hdlp;
3250 3179 mutex_exit(&ibcm_svc_info_lock);
3251 3180 kmem_free(new, sizeof (*new));
3252 3181 ibtl_cm_change_service_cnt(ibt_hdl, 1);
3253 3182 return (IBT_SUCCESS);
3254 3183 } else {
3255 3184 ASSERT(status == IBT_AR_NOT_REGISTERED);
3256 3185 }
3257 3186 hdlp->ar_ref_link = NULL;
3258 3187 hdlp->ar_ibt_hdl = ibt_hdl;
3259 3188 new->ar_ibt_hdl_list = hdlp;
3260 3189 new->ar = *arp;
3261 3190 new->ar_flags = IBCM_AR_INITING;
3262 3191 new->ar_waiters = 0;
3263 3192 cv_init(&new->ar_cv, NULL, CV_DEFAULT, NULL);
3264 3193 new->ar_link = ibcm_ar_list;
3265 3194 ibcm_ar_list = new;
3266 3195
3267 3196 /* verify GID/pkey is valid for a local port, etc. */
3268 3197 hcap = NULL;
3269 3198 if ((s1 = ibtl_cm_get_hca_port(arp->ar_gid, 0, &cm_port))
3270 3199 != IBT_SUCCESS ||
3271 3200 (s2 = ibt_pkey2index_byguid(cm_port.hp_hca_guid, cm_port.hp_port,
3272 3201 arp->ar_pkey, &pkey_ix)) != IBT_SUCCESS ||
3273 3202 (hcap = ibcm_find_hca_entry(cm_port.hp_hca_guid)) == NULL) {
3274 3203 cv_destroy(&new->ar_cv);
3275 3204 ibcm_ar_list = new->ar_link;
3276 3205 mutex_exit(&ibcm_svc_info_lock);
3277 3206 kmem_free(new, sizeof (*new));
3278 3207 kmem_free(hdlp, sizeof (*hdlp));
3279 3208 status = IBT_INVALID_PARAM;
3280 3209 if (s1 == IBT_HCA_PORT_NOT_ACTIVE) {
3281 3210 s = "PORT DOWN";
3282 3211 status = IBT_HCA_PORT_NOT_ACTIVE;
3283 3212 } else if (s1 != IBT_SUCCESS)
3284 3213 s = "GID not found";
3285 3214 else if (s2 != IBT_SUCCESS)
3286 3215 s = "PKEY not found";
3287 3216 else
3288 3217 s = "CM could not find its HCA entry";
3289 3218 IBTF_DPRINTF_L2(cmlog, "ibt_register_ar: %s, status = %d",
3290 3219 s, status);
3291 3220 return (status);
3292 3221 }
3293 3222 mutex_exit(&ibcm_svc_info_lock);
3294 3223 saa_handle = ibcm_get_saa_handle(hcap, cm_port.hp_port);
3295 3224
3296 3225 /* create service record */
3297 3226 srv_recp = kmem_zalloc(sizeof (*srv_recp), KM_SLEEP);
3298 3227 srv_recp->ServiceLease = 0xFFFFFFFF; /* infinite */
3299 3228 srv_recp->ServiceP_Key = arp->ar_pkey;
3300 3229 srv_recp->ServiceKey_hi = 0xDA410000ULL; /* DAPL */
3301 3230 srv_recp->ServiceKey_lo = 0xA7500000ULL; /* ATS */
3302 3231 (void) strcpy((char *)srv_recp->ServiceName, IBCM_DAPL_ATS_NAME);
3303 3232 srv_recp->ServiceGID = arp->ar_gid;
3304 3233 bcopy(arp->ar_data, srv_recp->ServiceData, IBCM_DAPL_ATS_NBYTES);
3305 3234 srv_recp->ServiceID = IBCM_DAPL_ATS_SID;
3306 3235
3307 3236 /* insert service record into the SA */
3308 3237
3309 3238 IBCM_DUMP_SERVICE_REC(srv_recp);
3310 3239
3311 3240 if (saa_handle != NULL)
3312 3241 status = ibcm_write_service_record(saa_handle, srv_recp,
3313 3242 IBMF_SAA_UPDATE);
3314 3243 else
3315 3244 status = IBT_HCA_PORT_NOT_ACTIVE;
3316 3245
3317 3246 if (status != IBT_SUCCESS) {
3318 3247 IBTF_DPRINTF_L2(cmlog, "ibt_register_ar: sa access fails %d, "
3319 3248 "sid %llX", status, (longlong_t)srv_recp->ServiceID);
3320 3249 IBTF_DPRINTF_L2(cmlog, "ibt_register_ar: FAILED for gid "
3321 3250 "%llX:%llX pkey 0x%X", (longlong_t)arp->ar_gid.gid_prefix,
3322 3251 (longlong_t)arp->ar_gid.gid_guid, arp->ar_pkey);
3323 3252
3324 3253 kmem_free(srv_recp, sizeof (*srv_recp));
3325 3254 kmem_free(hdlp, sizeof (*hdlp));
3326 3255
3327 3256 mutex_enter(&ibcm_svc_info_lock);
3328 3257 linkp = &ibcm_ar_list;
3329 3258 tmp = *linkp;
3330 3259 while (tmp != NULL) {
3331 3260 if (tmp == new) {
3332 3261 *linkp = new->ar_link;
3333 3262 break;
3334 3263 }
3335 3264 linkp = &tmp->ar_link;
3336 3265 tmp = *linkp;
3337 3266 }
3338 3267 if (new->ar_waiters > 0) {
3339 3268 new->ar_flags = IBCM_AR_FAILED;
3340 3269 cv_broadcast(&new->ar_cv);
3341 3270 mutex_exit(&ibcm_svc_info_lock);
3342 3271 } else {
3343 3272 cv_destroy(&new->ar_cv);
3344 3273 mutex_exit(&ibcm_svc_info_lock);
3345 3274 kmem_free(new, sizeof (*new));
3346 3275 }
3347 3276 ibcm_dec_hca_acc_cnt(hcap);
3348 3277 IBTF_DPRINTF_L2(cmlog, "ibt_register_ar: "
3349 3278 "IBMF_SAA failed to write address record");
3350 3279 } else { /* SUCCESS */
3351 3280 uint8_t *b;
3352 3281
3353 3282 IBTF_DPRINTF_L3(cmlog, "ibt_register_ar: SUCCESS for gid "
3354 3283 "%llx:%llx pkey %x", (longlong_t)arp->ar_gid.gid_prefix,
3355 3284 (longlong_t)arp->ar_gid.gid_guid, arp->ar_pkey);
3356 3285 b = arp->ar_data;
3357 3286
3358 3287 IBTF_DPRINTF_L3(cmlog, "ibt_register_ar:"
3359 3288 " data %d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
3360 3289 b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9],
3361 3290 b[10], b[11], b[12], b[13], b[14], b[15]);
3362 3291 mutex_enter(&ibcm_svc_info_lock);
3363 3292 new->ar_srv_recp = srv_recp;
3364 3293 new->ar_saa_handle = saa_handle;
3365 3294 new->ar_port = cm_port.hp_port;
3366 3295 new->ar_hcap = hcap;
3367 3296 new->ar_flags = IBCM_AR_SUCCESS;
3368 3297 if (new->ar_waiters > 0)
3369 3298 cv_broadcast(&new->ar_cv);
3370 3299 mutex_exit(&ibcm_svc_info_lock);
3371 3300 ibtl_cm_change_service_cnt(ibt_hdl, 1);
3372 3301 /* do not call ibcm_dec_hca_acc_cnt(hcap) until deregister */
3373 3302 }
3374 3303 return (status);
3375 3304 }
3376 3305
3377 3306 ibt_status_t
3378 3307 ibt_deregister_ar(ibt_clnt_hdl_t ibt_hdl, ibt_ar_t *arp)
3379 3308 {
3380 3309 ibcm_ar_t *found;
3381 3310 ibcm_ar_t *tmp;
3382 3311 ibcm_ar_t **linkp;
3383 3312 ibcm_ar_ref_t *hdlp;
3384 3313 ibcm_ar_ref_t **hdlpp;
3385 3314 ibt_status_t status;
3386 3315 ibmf_saa_handle_t saa_handle;
3387 3316 sa_service_record_t *srv_recp;
3388 3317 uint64_t gid_ored;
3389 3318
3390 3319 IBTF_DPRINTF_L3(cmlog, "ibt_deregister_ar: pkey %x", arp->ar_pkey);
3391 3320 IBTF_DPRINTF_L3(cmlog, "ibt_deregister_ar: gid %llx:%llx",
3392 3321 (longlong_t)arp->ar_gid.gid_prefix,
3393 3322 (longlong_t)arp->ar_gid.gid_guid);
3394 3323
3395 3324 /*
3396 3325 * If P_Key is 0, but GID is not, this query is invalid.
3397 3326 * If GID is 0, but P_Key is not, this query is invalid.
3398 3327 */
3399 3328 gid_ored = arp->ar_gid.gid_guid | arp->ar_gid.gid_prefix;
3400 3329 if ((arp->ar_pkey == 0 && gid_ored != 0ULL) ||
3401 3330 (arp->ar_pkey != 0 && gid_ored == 0ULL)) {
3402 3331 IBTF_DPRINTF_L2(cmlog, "ibt_deregister_ar: "
3403 3332 "GID/P_Key is not valid");
3404 3333 return (IBT_INVALID_PARAM);
3405 3334 }
3406 3335
3407 3336 mutex_enter(&ibcm_svc_info_lock);
3408 3337 /* search for existing GID/pkey (there can be at most 1) */
3409 3338 status = ibcm_search_ar(arp, &found);
3410 3339 if (status == IBT_INCONSISTENT_AR || status == IBT_AR_NOT_REGISTERED) {
3411 3340 mutex_exit(&ibcm_svc_info_lock);
3412 3341 IBTF_DPRINTF_L2(cmlog, "ibt_deregister_ar: "
3413 3342 "address record not found");
3414 3343 return (IBT_AR_NOT_REGISTERED);
3415 3344 }
3416 3345 ASSERT(status == IBT_SUCCESS);
3417 3346
3418 3347 hdlpp = &found->ar_ibt_hdl_list;
3419 3348 hdlp = *hdlpp;
3420 3349 while (hdlp != NULL) {
3421 3350 if (hdlp->ar_ibt_hdl == ibt_hdl)
3422 3351 break;
3423 3352 hdlpp = &hdlp->ar_ref_link;
3424 3353 hdlp = *hdlpp;
3425 3354 }
3426 3355 if (hdlp == NULL) { /* could not find ibt_hdl on list */
3427 3356 mutex_exit(&ibcm_svc_info_lock);
3428 3357 IBTF_DPRINTF_L2(cmlog, "ibt_deregister_ar: "
3429 3358 "address record found, but not for this client");
3430 3359 return (IBT_AR_NOT_REGISTERED);
3431 3360 }
3432 3361 *hdlpp = hdlp->ar_ref_link; /* remove ref for this client */
3433 3362 if (found->ar_ibt_hdl_list == NULL && found->ar_waiters == 0) {
3434 3363 /* last entry was removed */
3435 3364 found->ar_flags = IBCM_AR_INITING; /* hold off register_ar */
3436 3365 saa_handle = found->ar_saa_handle;
3437 3366 srv_recp = found->ar_srv_recp;
3438 3367
3439 3368 /* wait if this service record is being rewritten */
3440 3369 while (found->ar_rewrite_state == IBCM_REWRITE_BUSY)
3441 3370 cv_wait(&ibcm_svc_info_cv, &ibcm_svc_info_lock);
3442 3371 mutex_exit(&ibcm_svc_info_lock);
3443 3372
3444 3373 /* remove service record */
3445 3374 status = ibcm_write_service_record(saa_handle, srv_recp,
3446 3375 IBMF_SAA_DELETE);
3447 3376 if (status != IBT_SUCCESS)
3448 3377 IBTF_DPRINTF_L2(cmlog, "ibt_deregister_ar: "
3449 3378 "IBMF_SAA failed to delete address record");
3450 3379 mutex_enter(&ibcm_svc_info_lock);
3451 3380 if (found->ar_waiters == 0) { /* still no waiters */
3452 3381 linkp = &ibcm_ar_list;
3453 3382 tmp = *linkp;
3454 3383 while (tmp != found) {
3455 3384 linkp = &tmp->ar_link;
3456 3385 tmp = *linkp;
3457 3386 }
3458 3387 *linkp = tmp->ar_link;
3459 3388 ibcm_dec_hca_acc_cnt(found->ar_hcap);
3460 3389 kmem_free(srv_recp, sizeof (*srv_recp));
3461 3390 cv_destroy(&found->ar_cv);
3462 3391 kmem_free(found, sizeof (*found));
3463 3392 } else {
3464 3393 /* add service record back in for the waiters */
3465 3394 mutex_exit(&ibcm_svc_info_lock);
3466 3395 status = ibcm_write_service_record(saa_handle, srv_recp,
3467 3396 IBMF_SAA_UPDATE);
3468 3397 mutex_enter(&ibcm_svc_info_lock);
3469 3398 if (status == IBT_SUCCESS)
3470 3399 found->ar_flags = IBCM_AR_SUCCESS;
3471 3400 else {
3472 3401 found->ar_flags = IBCM_AR_FAILED;
3473 3402 IBTF_DPRINTF_L2(cmlog, "ibt_deregister_ar: "
3474 3403 "IBMF_SAA failed to write address record");
3475 3404 }
3476 3405 cv_broadcast(&found->ar_cv);
3477 3406 }
3478 3407 }
3479 3408 mutex_exit(&ibcm_svc_info_lock);
3480 3409 kmem_free(hdlp, sizeof (*hdlp));
3481 3410 ibtl_cm_change_service_cnt(ibt_hdl, -1);
3482 3411 return (status);
3483 3412 }
3484 3413
3485 3414 ibt_status_t
3486 3415 ibt_query_ar(ib_gid_t *sgid, ibt_ar_t *queryp, ibt_ar_t *resultp)
3487 3416 {
3488 3417 sa_service_record_t svcrec_req;
3489 3418 sa_service_record_t *svcrec_resp;
3490 3419 void *results_p;
3491 3420 uint64_t component_mask = 0;
3492 3421 uint64_t gid_ored;
3493 3422 size_t length;
3494 3423 int num_rec;
3495 3424 int i;
3496 3425 ibmf_saa_access_args_t access_args;
3497 3426 ibt_status_t retval;
3498 3427 ibtl_cm_hca_port_t cm_port;
3499 3428 ibcm_hca_info_t *hcap;
3500 3429 ibmf_saa_handle_t saa_handle;
3501 3430
3502 3431 IBTF_DPRINTF_L3(cmlog, "ibt_query_ar(%p, %p)", queryp, resultp);
3503 3432 IBTF_DPRINTF_L3(cmlog, "ibt_query_ar: sgid %llx:%llx",
3504 3433 (longlong_t)sgid->gid_prefix, (longlong_t)sgid->gid_guid);
3505 3434 IBTF_DPRINTF_L3(cmlog, "ibt_query_ar: query_pkey %x", queryp->ar_pkey);
3506 3435 IBTF_DPRINTF_L3(cmlog, "ibt_query_ar: query_gid %llx:%llx",
3507 3436 (longlong_t)queryp->ar_gid.gid_prefix,
3508 3437 (longlong_t)queryp->ar_gid.gid_guid);
3509 3438
3510 3439 /*
3511 3440 * If P_Key is 0, but GID is not, this query is invalid.
3512 3441 * If GID is 0, but P_Key is not, this query is invalid.
3513 3442 */
3514 3443 gid_ored = queryp->ar_gid.gid_guid | queryp->ar_gid.gid_prefix;
3515 3444 if ((queryp->ar_pkey == 0 && gid_ored != 0ULL) ||
3516 3445 (queryp->ar_pkey != 0 && gid_ored == 0ULL)) {
3517 3446 IBTF_DPRINTF_L2(cmlog, "ibt_query_ar: GID/P_Key is not valid");
3518 3447 return (IBT_INVALID_PARAM);
3519 3448 }
3520 3449
3521 3450 hcap = NULL;
3522 3451 if (ibtl_cm_get_hca_port(*sgid, 0, &cm_port) != IBT_SUCCESS ||
3523 3452 (hcap = ibcm_find_hca_entry(cm_port.hp_hca_guid)) == NULL ||
3524 3453 (saa_handle = ibcm_get_saa_handle(hcap, cm_port.hp_port)) == NULL) {
3525 3454 if (hcap != NULL)
3526 3455 ibcm_dec_hca_acc_cnt(hcap);
3527 3456 IBTF_DPRINTF_L2(cmlog, "ibt_query_ar: sgid is not valid");
3528 3457 return (IBT_INVALID_PARAM);
3529 3458 }
3530 3459
3531 3460 bzero(&svcrec_req, sizeof (svcrec_req));
3532 3461
3533 3462 /* Is GID/P_Key Specified. */
3534 3463 if (queryp->ar_pkey != 0) { /* GID is non-zero from check above */
3535 3464 svcrec_req.ServiceP_Key = queryp->ar_pkey;
3536 3465 component_mask |= SA_SR_COMPMASK_PKEY;
3537 3466 IBTF_DPRINTF_L3(cmlog, "ibt_query_ar: P_Key %X",
3538 3467 queryp->ar_pkey);
3539 3468 svcrec_req.ServiceGID = queryp->ar_gid;
3540 3469 component_mask |= SA_SR_COMPMASK_GID;
3541 3470 IBTF_DPRINTF_L3(cmlog, "ibt_query_ar: GID %llX:%llX",
3542 3471 (longlong_t)queryp->ar_gid.gid_prefix,
3543 3472 (longlong_t)queryp->ar_gid.gid_guid);
3544 3473 }
3545 3474
3546 3475 /* Is ServiceData Specified. */
3547 3476 for (i = 0; i < IBCM_DAPL_ATS_NBYTES; i++) {
3548 3477 if (queryp->ar_data[i] != 0) {
3549 3478 bcopy(queryp->ar_data, svcrec_req.ServiceData,
3550 3479 IBCM_DAPL_ATS_NBYTES);
3551 3480 component_mask |= 0xFFFF << 7; /* all 16 Data8 */
3552 3481 /* components */
3553 3482 break;
3554 3483 }
3555 3484 }
3556 3485
3557 3486 /* Service Name */
3558 3487 (void) strcpy((char *)svcrec_req.ServiceName, IBCM_DAPL_ATS_NAME);
3559 3488 component_mask |= SA_SR_COMPMASK_NAME;
3560 3489
3561 3490 svcrec_req.ServiceID = IBCM_DAPL_ATS_SID;
3562 3491 component_mask |= SA_SR_COMPMASK_ID;
3563 3492
3564 3493 IBTF_DPRINTF_L3(cmlog, "ibt_query_ar: "
3565 3494 "Perform SA Access: Mask: 0x%X", component_mask);
3566 3495
3567 3496 /*
3568 3497 * Call in SA Access retrieve routine to get Service Records.
3569 3498 *
3570 3499 * SA Access framework allocated memory for the "results_p".
3571 3500 * Make sure to deallocate once we are done with the results_p.
3572 3501 * The size of the buffer allocated will be as returned in
3573 3502 * "length" field.
3574 3503 */
3575 3504 access_args.sq_attr_id = SA_SERVICERECORD_ATTRID;
3576 3505 access_args.sq_access_type = IBMF_SAA_RETRIEVE;
3577 3506 access_args.sq_component_mask = component_mask;
3578 3507 access_args.sq_template = &svcrec_req;
3579 3508 access_args.sq_template_length = sizeof (sa_service_record_t);
3580 3509 access_args.sq_callback = NULL;
3581 3510 access_args.sq_callback_arg = NULL;
3582 3511
3583 3512 retval = ibcm_contact_sa_access(saa_handle, &access_args, &length,
3584 3513 &results_p);
3585 3514
3586 3515 ibcm_dec_hca_acc_cnt(hcap);
3587 3516 if (retval != IBT_SUCCESS) {
3588 3517 IBTF_DPRINTF_L2(cmlog, "ibt_query_ar: SA Access Failed");
3589 3518 return (retval);
3590 3519 }
3591 3520
3592 3521 num_rec = length / sizeof (sa_service_record_t);
3593 3522
3594 3523 IBTF_DPRINTF_L3(cmlog, "ibt_query_ar: "
3595 3524 "Found %d Service Records.", num_rec);
3596 3525
3597 3526 /* Validate the returned number of records. */
3598 3527 if ((results_p != NULL) && (num_rec > 0)) {
3599 3528 uint8_t *b;
3600 3529
3601 3530 /* Just return info from the first service record. */
3602 3531 svcrec_resp = (sa_service_record_t *)results_p;
3603 3532
3604 3533 /* The Service GID and Service ID */
3605 3534 resultp->ar_gid = svcrec_resp->ServiceGID;
3606 3535 resultp->ar_pkey = svcrec_resp->ServiceP_Key;
3607 3536 bcopy(svcrec_resp->ServiceData,
3608 3537 resultp->ar_data, IBCM_DAPL_ATS_NBYTES);
3609 3538
3610 3539 IBTF_DPRINTF_L3(cmlog, "ibt_query_ar: "
3611 3540 "Found: pkey %x dgid %llX:%llX", resultp->ar_pkey,
3612 3541 (longlong_t)resultp->ar_gid.gid_prefix,
3613 3542 (longlong_t)resultp->ar_gid.gid_guid);
3614 3543 b = resultp->ar_data;
3615 3544 IBTF_DPRINTF_L3(cmlog, "ibt_query_ar:"
3616 3545 " data %d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
3617 3546 b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9],
3618 3547 b[10], b[11], b[12], b[13], b[14], b[15]);
3619 3548
3620 3549 /* Deallocate the memory for results_p. */
3621 3550 kmem_free(results_p, length);
3622 3551 if (num_rec > 1)
3623 3552 retval = IBT_MULTIPLE_AR;
3624 3553 else
3625 3554 retval = IBT_SUCCESS;
3626 3555 } else {
3627 3556 IBTF_DPRINTF_L2(cmlog, "ibt_query_ar: "
3628 3557 "ibmf_sa_access found 0 matching records");
3629 3558 retval = IBT_AR_NOT_REGISTERED;
3630 3559 }
3631 3560 return (retval);
3632 3561 }
3633 3562
3634 3563 /* mark all ATS service records associated with the port */
3635 3564 static void
3636 3565 ibcm_mark_ar(ib_guid_t hca_guid, uint8_t port)
3637 3566 {
3638 3567 ibcm_ar_t *tmp;
3639 3568
3640 3569 ASSERT(MUTEX_HELD(&ibcm_svc_info_lock));
3641 3570 for (tmp = ibcm_ar_list; tmp != NULL; tmp = tmp->ar_link) {
3642 3571 if (tmp->ar_hcap == NULL)
3643 3572 continue;
3644 3573 if (tmp->ar_hcap->hca_guid == hca_guid &&
3645 3574 tmp->ar_port == port) {
3646 3575 /* even if it's busy, we mark it for rewrite */
3647 3576 tmp->ar_rewrite_state = IBCM_REWRITE_NEEDED;
3648 3577 }
3649 3578 }
3650 3579 }
3651 3580
3652 3581 /* rewrite all ATS service records */
3653 3582 static int
3654 3583 ibcm_rewrite_ar(void)
3655 3584 {
3656 3585 ibcm_ar_t *tmp;
3657 3586 ibmf_saa_handle_t saa_handle;
3658 3587 sa_service_record_t *srv_recp;
3659 3588 ibt_status_t rval;
3660 3589 int did_something = 0;
3661 3590
3662 3591 ASSERT(MUTEX_HELD(&ibcm_svc_info_lock));
3663 3592 check_for_work:
3664 3593 for (tmp = ibcm_ar_list; tmp != NULL; tmp = tmp->ar_link) {
3665 3594 if (tmp->ar_rewrite_state == IBCM_REWRITE_NEEDED) {
3666 3595 tmp->ar_rewrite_state = IBCM_REWRITE_BUSY;
3667 3596 saa_handle = tmp->ar_saa_handle;
3668 3597 srv_recp = tmp->ar_srv_recp;
3669 3598 mutex_exit(&ibcm_svc_info_lock);
3670 3599 IBTF_DPRINTF_L3(cmlog, "ibcm_rewrite_ar: "
3671 3600 "rewriting ar @ %p", tmp);
3672 3601 did_something = 1;
3673 3602 rval = ibcm_write_service_record(saa_handle, srv_recp,
3674 3603 IBMF_SAA_UPDATE);
3675 3604 if (rval != IBT_SUCCESS)
3676 3605 IBTF_DPRINTF_L2(cmlog, "ibcm_rewrite_ar: "
3677 3606 "ibcm_write_service_record failed: "
3678 3607 "status = %d", rval);
3679 3608 mutex_enter(&ibcm_svc_info_lock);
3680 3609 /* if it got marked again, then we want to rewrite */
3681 3610 if (tmp->ar_rewrite_state == IBCM_REWRITE_BUSY)
3682 3611 tmp->ar_rewrite_state = IBCM_REWRITE_IDLE;
3683 3612 /* in case there was a waiter... */
3684 3613 cv_broadcast(&ibcm_svc_info_cv);
3685 3614 goto check_for_work;
3686 3615 }
3687 3616 }
3688 3617 return (did_something);
3689 3618 }
3690 3619
3691 3620 static void
3692 3621 ibcm_rewrite_svc_record(ibcm_svc_info_t *srv_hdl, ibcm_svc_bind_t *sbindp)
3693 3622 {
3694 3623 ibcm_hca_info_t *hcap;
3695 3624 ib_svc_id_t sid, start_sid, end_sid;
3696 3625 ibmf_saa_handle_t saa_handle;
3697 3626 sa_service_record_t srv_rec;
3698 3627 ibt_status_t rval;
3699 3628
3700 3629 hcap = ibcm_find_hca_entry(sbindp->sbind_hcaguid);
3701 3630 if (hcap == NULL) {
3702 3631 IBTF_DPRINTF_L2(cmlog, "ibcm_rewrite_svc_record: "
3703 3632 "NO HCA found for HCA GUID %llX", sbindp->sbind_hcaguid);
3704 3633 return;
3705 3634 }
3706 3635
3707 3636 saa_handle = ibcm_get_saa_handle(hcap, sbindp->sbind_port);
3708 3637 if (saa_handle == NULL) {
3709 3638 IBTF_DPRINTF_L2(cmlog, "ibcm_rewrite_svc_record: "
3710 3639 "saa_handle is NULL");
3711 3640 ibcm_dec_hca_acc_cnt(hcap);
3712 3641 return;
3713 3642 }
3714 3643
3715 3644 IBTF_DPRINTF_L3(cmlog, "ibcm_rewrite_svc_record: "
3716 3645 "rewriting svc '%s', port_guid = %llX", sbindp->sbind_name,
3717 3646 sbindp->sbind_gid.gid_guid);
3718 3647
3719 3648 bzero(&srv_rec, sizeof (srv_rec));
3720 3649
3721 3650 srv_rec.ServiceLease = sbindp->sbind_lease;
3722 3651 srv_rec.ServiceP_Key = sbindp->sbind_pkey;
3723 3652 srv_rec.ServiceKey_hi = sbindp->sbind_key[0];
3724 3653 srv_rec.ServiceKey_lo = sbindp->sbind_key[1];
3725 3654 (void) strcpy((char *)srv_rec.ServiceName, sbindp->sbind_name);
3726 3655 srv_rec.ServiceGID = sbindp->sbind_gid;
3727 3656
3728 3657 bcopy(sbindp->sbind_data, srv_rec.ServiceData, IB_SVC_DATA_LEN);
3729 3658
3730 3659 /* insert srv record into the SA */
3731 3660 start_sid = srv_hdl->svc_id;
3732 3661 end_sid = start_sid + srv_hdl->svc_num_sids - 1;
3733 3662 for (sid = start_sid; sid <= end_sid; sid++) {
3734 3663 srv_rec.ServiceID = sid;
3735 3664
3736 3665 rval = ibcm_write_service_record(saa_handle, &srv_rec,
3737 3666 IBMF_SAA_UPDATE);
3738 3667
3739 3668 IBTF_DPRINTF_L4(cmlog, "ibcm_rewrite_svc_record: "
3740 3669 "ibcm_write_service_record, SvcId = %llX, "
3741 3670 "rval = %d", (longlong_t)sid, rval);
3742 3671 if (rval != IBT_SUCCESS) {
3743 3672 IBTF_DPRINTF_L2(cmlog, "ibcm_rewrite_svc_record:"
3744 3673 " ibcm_write_service_record fails %d sid %llX",
3745 3674 rval, (longlong_t)sid);
3746 3675 }
3747 3676 }
3748 3677 ibcm_dec_hca_acc_cnt(hcap);
3749 3678 }
3750 3679
3751 3680 /*
3752 3681 * Task to mark all service records as needing to be rewritten to the SM/SA.
3753 3682 * This task does not return until all of them have been rewritten.
3754 3683 */
3755 3684 void
3756 3685 ibcm_service_record_rewrite_task(void *arg)
3757 3686 {
3758 3687 ibcm_port_up_t *pup = (ibcm_port_up_t *)arg;
3759 3688 ib_guid_t hca_guid = pup->pup_hca_guid;
3760 3689 uint8_t port = pup->pup_port;
3761 3690 ibcm_svc_info_t *svcp;
3762 3691 ibcm_svc_bind_t *sbp;
3763 3692 avl_tree_t *avl_tree = &ibcm_svc_avl_tree;
3764 3693 static int task_is_running = 0;
3765 3694
3766 3695 IBTF_DPRINTF_L3(cmlog, "ibcm_service_record_rewrite_task STARTED "
3767 3696 "for hca_guid %llX, port %d", hca_guid, port);
3768 3697
3769 3698 mutex_enter(&ibcm_svc_info_lock);
3770 3699 ibcm_mark_ar(hca_guid, port);
3771 3700 for (svcp = avl_first(avl_tree); svcp != NULL;
3772 3701 svcp = avl_walk(avl_tree, svcp, AVL_AFTER)) {
3773 3702 sbp = svcp->svc_bind_list;
3774 3703 while (sbp != NULL) {
3775 3704 if (sbp->sbind_pkey != 0 &&
3776 3705 sbp->sbind_port == port &&
3777 3706 sbp->sbind_hcaguid == hca_guid) {
3778 3707 /* even if it's busy, we mark it for rewrite */
3779 3708 sbp->sbind_rewrite_state = IBCM_REWRITE_NEEDED;
3780 3709 }
3781 3710 sbp = sbp->sbind_link;
3782 3711 }
3783 3712 }
3784 3713 if (task_is_running) {
3785 3714 /* let the other task thread finish the work */
3786 3715 mutex_exit(&ibcm_svc_info_lock);
3787 3716 return;
3788 3717 }
3789 3718 task_is_running = 1;
3790 3719
3791 3720 (void) ibcm_rewrite_ar();
3792 3721
3793 3722 check_for_work:
3794 3723 for (svcp = avl_first(avl_tree); svcp != NULL;
3795 3724 svcp = avl_walk(avl_tree, svcp, AVL_AFTER)) {
3796 3725 sbp = svcp->svc_bind_list;
3797 3726 while (sbp != NULL) {
3798 3727 if (sbp->sbind_rewrite_state == IBCM_REWRITE_NEEDED) {
3799 3728 sbp->sbind_rewrite_state = IBCM_REWRITE_BUSY;
3800 3729 mutex_exit(&ibcm_svc_info_lock);
3801 3730 ibcm_rewrite_svc_record(svcp, sbp);
3802 3731 mutex_enter(&ibcm_svc_info_lock);
3803 3732 /* if it got marked again, we want to rewrite */
3804 3733 if (sbp->sbind_rewrite_state ==
3805 3734 IBCM_REWRITE_BUSY)
3806 3735 sbp->sbind_rewrite_state =
3807 3736 IBCM_REWRITE_IDLE;
3808 3737 /* in case there was a waiter... */
3809 3738 cv_broadcast(&ibcm_svc_info_cv);
3810 3739 goto check_for_work;
3811 3740 }
3812 3741 sbp = sbp->sbind_link;
3813 3742 }
3814 3743 }
3815 3744 /*
3816 3745 * If there were no service records to write, and we failed to
3817 3746 * have to rewrite any more ATS service records, then we're done.
3818 3747 */
3819 3748 if (ibcm_rewrite_ar() != 0)
3820 3749 goto check_for_work;
3821 3750 task_is_running = 0;
3822 3751 mutex_exit(&ibcm_svc_info_lock);
3823 3752
3824 3753 IBTF_DPRINTF_L3(cmlog, "ibcm_service_record_rewrite_task DONE");
3825 3754 kmem_free(pup, sizeof (ibcm_port_up_t));
3826 3755 }
3827 3756
3828 3757 ibt_status_t
3829 3758 ibt_ofuvcm_get_req_data(void *session_id, ibt_ofuvcm_req_data_t *req_data)
3830 3759 {
3831 3760 ibcm_state_data_t *statep = (ibcm_state_data_t *)session_id;
3832 3761 ibcm_req_msg_t *req_msgp;
3833 3762
3834 3763 IBTF_DPRINTF_L3(cmlog, "ibt_get_ofuvcm_req_data: session_id %p",
3835 3764 session_id);
3836 3765 mutex_enter(&statep->state_mutex);
3837 3766 if ((statep->state != IBCM_STATE_REQ_RCVD) &&
3838 3767 (statep->state != IBCM_STATE_MRA_SENT)) {
3839 3768 IBTF_DPRINTF_L2(cmlog, "ibt_get_ofuvcm_req_data: Invalid "
3840 3769 "State %x", statep->state);
3841 3770 mutex_exit(&statep->state_mutex);
3842 3771 return (IBT_CHAN_STATE_INVALID);
3843 3772 }
3844 3773 if (statep->mode == IBCM_ACTIVE_MODE) {
3845 3774 IBTF_DPRINTF_L2(cmlog, "ibt_get_ofuvcm_req_data: Active mode "
3846 3775 "not supported");
3847 3776 mutex_exit(&statep->state_mutex);
3848 3777 return (IBT_INVALID_PARAM);
3849 3778 }
3850 3779 ASSERT(statep->req_msgp);
3851 3780
3852 3781 /*
3853 3782 * Fill in the additional req message values reqired for
3854 3783 * RTR transition.
3855 3784 * Should the PSN be same as the active side??
3856 3785 */
3857 3786 req_msgp = (ibcm_req_msg_t *)statep->req_msgp;
3858 3787 req_data->req_rnr_nak_time = ibcm_default_rnr_nak_time;
3859 3788 req_data->req_path_mtu = req_msgp->req_mtu_plus >> 4;
3860 3789 req_data->req_rq_psn = b2h32(req_msgp->req_starting_psn_plus) >> 8;
3861 3790 mutex_exit(&statep->state_mutex);
3862 3791 return (IBT_SUCCESS);
3863 3792 }
3864 3793
3865 3794 ibt_status_t
3866 3795 ibt_ofuvcm_proceed(ibt_cm_event_type_t event, void *session_id,
3867 3796 ibt_cm_status_t status, ibt_cm_proceed_reply_t *cm_event_data,
3868 3797 void *priv_data, ibt_priv_data_len_t priv_data_len)
3869 3798 {
3870 3799 ibcm_state_data_t *statep = (ibcm_state_data_t *)session_id;
3871 3800 ibt_status_t ret;
3872 3801
3873 3802 IBTF_DPRINTF_L3(cmlog, "ibt_ofuvcm_proceed chan 0x%p event %x "
3874 3803 "status %x session_id %p", statep->channel, event, status,
3875 3804 session_id);
3876 3805
3877 3806 IBTF_DPRINTF_L5(cmlog, "ibt_ofuvcm_proceed chan 0x%p "
3878 3807 "cm_event_data %p, priv_data %p priv_data_len %x",
3879 3808 statep->channel, cm_event_data, priv_data, priv_data_len);
3880 3809
3881 3810 /* validate session_id and status */
3882 3811 if ((statep == NULL) || (status == IBT_CM_DEFER)) {
3883 3812 IBTF_DPRINTF_L2(cmlog, "ibt_ofuvcm_proceed : Invalid Args");
3884 3813 return (IBT_INVALID_PARAM);
3885 3814 }
3886 3815
3887 3816 if (event != IBT_CM_EVENT_REQ_RCV) {
3888 3817 IBTF_DPRINTF_L2(cmlog, "ibt_ofuvcm_proceed : only for REQ_RCV");
3889 3818 return (IBT_INVALID_PARAM);
3890 3819 }
3891 3820 mutex_enter(&statep->state_mutex);
3892 3821 statep->is_this_ofuv_chan = B_TRUE;
3893 3822 mutex_exit(&statep->state_mutex);
3894 3823
3895 3824 ret = ibt_cm_proceed(event, session_id, status, cm_event_data,
3896 3825 priv_data, priv_data_len);
3897 3826 return (ret);
3898 3827 }
3899 3828
3900 3829 /*
3901 3830 * Function:
3902 3831 * ibt_cm_proceed
3903 3832 *
3904 3833 * Verifies the arguments and dispatches the cm state machine processing
3905 3834 * via taskq
3906 3835 */
3907 3836
3908 3837 ibt_status_t
3909 3838 ibt_cm_proceed(ibt_cm_event_type_t event, void *session_id,
3910 3839 ibt_cm_status_t status, ibt_cm_proceed_reply_t *cm_event_data,
3911 3840 void *priv_data, ibt_priv_data_len_t priv_data_len)
3912 3841 {
3913 3842 ibcm_state_data_t *statep = (ibcm_state_data_t *)session_id;
3914 3843 ibcm_proceed_targs_t *proceed_targs;
3915 3844 ibcm_proceed_error_t proceed_error;
3916 3845
3917 3846 IBTF_DPRINTF_L3(cmlog, "ibt_cm_proceed chan 0x%p event %x status %x "
3918 3847 "session_id %p", statep->channel, event, status, session_id);
3919 3848
3920 3849 IBTF_DPRINTF_L5(cmlog, "ibt_cm_proceed chan 0x%p cm_event_data %p, "
3921 3850 "priv_data %p priv_data_len %x", statep->channel, cm_event_data,
3922 3851 priv_data, priv_data_len);
3923 3852
3924 3853 /* validate session_id and status */
3925 3854 if ((statep == NULL) || (status == IBT_CM_DEFER)) {
3926 3855 IBTF_DPRINTF_L2(cmlog, "ibt_cm_proceed : Invalid Args");
3927 3856 return (IBT_INVALID_PARAM);
3928 3857 }
3929 3858
3930 3859 /* If priv data len specified, then priv_data cannot be NULL */
3931 3860 if ((priv_data_len > 0) && (priv_data == NULL))
3932 3861 return (IBT_INVALID_PARAM);
3933 3862
3934 3863 proceed_error = IBCM_PROCEED_INVALID_NONE;
3935 3864
3936 3865 mutex_enter(&statep->state_mutex);
3937 3866 if (event == IBT_CM_EVENT_REQ_RCV) {
3938 3867
3939 3868 if ((statep->state != IBCM_STATE_REQ_RCVD) &&
3940 3869 (statep->state != IBCM_STATE_MRA_SENT))
3941 3870 proceed_error = IBCM_PROCEED_INVALID_EVENT_STATE;
3942 3871 else if (priv_data_len > IBT_REP_PRIV_DATA_SZ)
3943 3872 proceed_error = IBCM_PROCEED_INVALID_PRIV_SZ;
3944 3873
3945 3874 } else if (event == IBT_CM_EVENT_REP_RCV) {
3946 3875 if ((statep->state != IBCM_STATE_REP_RCVD) &&
3947 3876 (statep->state != IBCM_STATE_MRA_REP_SENT))
3948 3877 proceed_error = IBCM_PROCEED_INVALID_EVENT_STATE;
3949 3878 else if (priv_data_len > IBT_RTU_PRIV_DATA_SZ)
3950 3879 proceed_error = IBCM_PROCEED_INVALID_PRIV_SZ;
3951 3880 } else if (event == IBT_CM_EVENT_LAP_RCV) {
3952 3881 if ((statep->ap_state != IBCM_AP_STATE_LAP_RCVD) &&
3953 3882 (statep->ap_state != IBCM_AP_STATE_MRA_LAP_SENT))
3954 3883 proceed_error = IBCM_PROCEED_INVALID_EVENT_STATE;
3955 3884 else if (priv_data_len > IBT_APR_PRIV_DATA_SZ)
3956 3885 proceed_error = IBCM_PROCEED_INVALID_PRIV_SZ;
3957 3886 } else if (event == IBT_CM_EVENT_CONN_CLOSED) {
3958 3887 if (statep->state != IBCM_STATE_DREQ_RCVD)
3959 3888 proceed_error = IBCM_PROCEED_INVALID_EVENT_STATE;
3960 3889 else if (priv_data_len > IBT_DREP_PRIV_DATA_SZ)
3961 3890 proceed_error = IBCM_PROCEED_INVALID_PRIV_SZ;
3962 3891 } else {
3963 3892 proceed_error = IBCM_PROCEED_INVALID_EVENT;
3964 3893 }
3965 3894
3966 3895 /* if there is an error, print an error message and return */
3967 3896 if (proceed_error != IBCM_PROCEED_INVALID_NONE) {
3968 3897 mutex_exit(&statep->state_mutex);
3969 3898 if (proceed_error == IBCM_PROCEED_INVALID_EVENT_STATE) {
3970 3899 IBTF_DPRINTF_L2(cmlog, "ibt_cm_proceed : chan 0x%p"
3971 3900 "Invalid Event/State combination specified",
3972 3901 statep->channel);
3973 3902 return (IBT_INVALID_PARAM);
3974 3903 } else if (proceed_error == IBCM_PROCEED_INVALID_PRIV_SZ) {
3975 3904 IBTF_DPRINTF_L2(cmlog, "ibt_cm_proceed : chan 0x%p"
3976 3905 "Invalid Event/priv len combination specified",
3977 3906 statep->channel);
3978 3907 return (IBT_INVALID_PARAM);
3979 3908 } else if (proceed_error == IBCM_PROCEED_INVALID_EVENT) {
3980 3909 IBTF_DPRINTF_L2(cmlog, "ibt_cm_proceed : chan 0x%p"
3981 3910 "Invalid Event specified", statep->channel);
3982 3911 return (IBT_INVALID_PARAM);
3983 3912 } else {
3984 3913 ASSERT(proceed_error == IBCM_PROCEED_INVALID_LAP);
3985 3914 IBTF_DPRINTF_L2(cmlog, "ibt_cm_proceed : chan 0x%p"
3986 3915 "IBT_CM_EVENT_LAP_RCV not supported",
3987 3916 statep->channel);
3988 3917 /* UNTIL HCA DRIVER ENABLES AP SUPPORT, FAIL THE CALL */
3989 3918 return (IBT_APM_NOT_SUPPORTED);
3990 3919 }
3991 3920 }
3992 3921
3993 3922
3994 3923 /* wait until client's CM handler returns DEFER status back to CM */
3995 3924
3996 3925 while (statep->clnt_proceed == IBCM_BLOCK) {
3997 3926 IBTF_DPRINTF_L5(cmlog, "ibt_cm_proceed : chan 0x%p blocked for "
3998 3927 "return of client's cm handler", statep->channel);
3999 3928 cv_wait(&statep->block_client_cv, &statep->state_mutex);
4000 3929 }
4001 3930
4002 3931 if (statep->clnt_proceed == IBCM_FAIL) {
4003 3932 mutex_exit(&statep->state_mutex);
↓ open down ↓ |
922 lines elided |
↑ open up ↑ |
4004 3933 IBTF_DPRINTF_L2(cmlog, "ibt_cm_proceed : chan 0x%p Failed as "
4005 3934 "client returned non-DEFER status from cm handler",
4006 3935 statep->channel);
4007 3936 return (IBT_CHAN_STATE_INVALID);
4008 3937 }
4009 3938
4010 3939 ASSERT(statep->clnt_proceed == IBCM_UNBLOCK);
4011 3940 statep->clnt_proceed = IBCM_FAIL;
4012 3941 mutex_exit(&statep->state_mutex);
4013 3942
4014 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*proceed_targs))
4015 -
4016 3943 /* the state machine processing is done in a separate thread */
4017 3944
4018 3945 /* proceed_targs is freed in ibcm_proceed_via_taskq */
4019 3946 proceed_targs = kmem_alloc(sizeof (ibcm_proceed_targs_t),
4020 3947 KM_SLEEP);
4021 3948
4022 3949 proceed_targs->event = event;
4023 3950 proceed_targs->status = status;
4024 3951 proceed_targs->priv_data_len = priv_data_len;
4025 3952
4026 3953 bcopy(priv_data, proceed_targs->priv_data, priv_data_len);
4027 3954
4028 3955 proceed_targs->tst.rc.statep = statep;
4029 3956 bcopy(cm_event_data, &proceed_targs->tst.rc.rc_cm_event_data,
4030 3957 sizeof (ibt_cm_proceed_reply_t));
4031 3958
4032 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*proceed_targs))
4033 -
4034 3959 (void) taskq_dispatch(ibcm_taskq, ibcm_proceed_via_taskq,
4035 3960 proceed_targs, TQ_SLEEP);
4036 3961
4037 3962 return (IBT_SUCCESS);
4038 3963 }
4039 3964
4040 3965 /*
4041 3966 * Function:
4042 3967 * ibcm_proceed_via_taskq
4043 3968 *
4044 3969 * Called from taskq, dispatched by ibt_cm_proceed
4045 3970 * Completes the cm state processing for ibt_cm_proceed
4046 3971 */
4047 3972 void
4048 3973 ibcm_proceed_via_taskq(void *targs)
4049 3974 {
4050 3975 ibcm_proceed_targs_t *proceed_targs = (ibcm_proceed_targs_t *)targs;
4051 3976 ibcm_state_data_t *statep = proceed_targs->tst.rc.statep;
4052 3977 ibt_cm_reason_t reject_reason;
4053 3978 uint8_t arej_len;
4054 3979 ibcm_status_t response;
4055 3980 ibcm_clnt_reply_info_t clnt_info;
4056 3981
4057 3982 clnt_info.reply_event = &proceed_targs->tst.rc.rc_cm_event_data;
4058 3983 clnt_info.priv_data = proceed_targs->priv_data;
4059 3984 clnt_info.priv_data_len = proceed_targs->priv_data_len;
4060 3985
4061 3986 IBTF_DPRINTF_L4(cmlog, "ibcm_proceed_via_taskq chan 0x%p targs %x",
4062 3987 statep->channel, targs);
4063 3988
4064 3989 if (proceed_targs->event == IBT_CM_EVENT_REQ_RCV) {
4065 3990 response =
4066 3991 ibcm_process_cep_req_cm_hdlr(statep, proceed_targs->status,
4067 3992 &clnt_info, &reject_reason, &arej_len,
4068 3993 (ibcm_req_msg_t *)statep->defer_cm_msg);
4069 3994
4070 3995 ibcm_handle_cep_req_response(statep, response, reject_reason,
4071 3996 arej_len);
4072 3997
4073 3998 } else if (proceed_targs->event == IBT_CM_EVENT_REP_RCV) {
4074 3999 response =
4075 4000 ibcm_process_cep_rep_cm_hdlr(statep, proceed_targs->status,
4076 4001 &clnt_info, &reject_reason, &arej_len,
4077 4002 (ibcm_rep_msg_t *)statep->defer_cm_msg);
4078 4003
4079 4004 ibcm_handle_cep_rep_response(statep, response, reject_reason,
4080 4005 arej_len, (ibcm_rep_msg_t *)statep->defer_cm_msg);
4081 4006
4082 4007 } else if (proceed_targs->event == IBT_CM_EVENT_LAP_RCV) {
4083 4008 ibcm_process_cep_lap_cm_hdlr(statep, proceed_targs->status,
4084 4009 &clnt_info, (ibcm_lap_msg_t *)statep->defer_cm_msg,
4085 4010 (ibcm_apr_msg_t *)IBCM_OUT_MSGP(statep->lapr_msg));
4086 4011
4087 4012 ibcm_post_apr_mad(statep);
4088 4013
4089 4014 } else {
4090 4015 ASSERT(proceed_targs->event == IBT_CM_EVENT_CONN_CLOSED);
4091 4016 ibcm_handle_cep_dreq_response(statep, proceed_targs->priv_data,
4092 4017 proceed_targs->priv_data_len);
4093 4018 }
4094 4019
4095 4020 kmem_free(targs, sizeof (ibcm_proceed_targs_t));
4096 4021 }
4097 4022
4098 4023 /*
4099 4024 * Function:
4100 4025 * ibt_cm_ud_proceed
4101 4026 *
4102 4027 * Verifies the arguments and dispatches the cm state machine processing
4103 4028 * via taskq
4104 4029 */
4105 4030 ibt_status_t
4106 4031 ibt_cm_ud_proceed(void *session_id, ibt_channel_hdl_t ud_channel,
4107 4032 ibt_cm_status_t status, ibt_redirect_info_t *redirect_infop,
4108 4033 void *priv_data, ibt_priv_data_len_t priv_data_len)
4109 4034 {
4110 4035 ibcm_ud_state_data_t *ud_statep = (ibcm_ud_state_data_t *)session_id;
4111 4036 ibcm_proceed_targs_t *proceed_targs;
4112 4037 ibt_qp_query_attr_t qp_attr;
4113 4038 ibt_status_t retval;
4114 4039
4115 4040 IBTF_DPRINTF_L3(cmlog, "ibt_cm_ud_proceed session_id %p "
4116 4041 "ud_channel %p ", session_id, ud_channel);
4117 4042
4118 4043 IBTF_DPRINTF_L4(cmlog, "ibt_cm_ud_proceed status %x priv_data %p "
4119 4044 "priv_data_len %x", status, priv_data, priv_data_len);
4120 4045
4121 4046 /* validate session_id and status */
4122 4047 if ((ud_statep == NULL) || (status == IBT_CM_DEFER)) {
4123 4048 IBTF_DPRINTF_L2(cmlog, "ibt_cm_ud_proceed : Invalid Args");
4124 4049 return (IBT_INVALID_PARAM);
4125 4050 }
4126 4051
4127 4052 /* If priv data len specified, then priv_data cannot be NULL */
4128 4053 if ((priv_data_len > 0) && (priv_data == NULL))
4129 4054 return (IBT_INVALID_PARAM);
4130 4055
4131 4056 if (priv_data_len > IBT_SIDR_REP_PRIV_DATA_SZ)
4132 4057 return (IBT_INVALID_PARAM);
4133 4058
4134 4059 /* retrieve qpn and qkey from ud channel */
4135 4060
4136 4061 /* validate event and statep's state */
4137 4062
4138 4063 if (status == IBT_CM_ACCEPT) {
4139 4064 retval = ibt_query_qp(ud_channel, &qp_attr);
4140 4065 if ((retval != IBT_SUCCESS) ||
4141 4066 (qp_attr.qp_info.qp_trans != IBT_UD_SRV)) {
4142 4067 IBTF_DPRINTF_L2(cmlog, "ibt_cm_ud_proceed: "
4143 4068 "Failed to retrieve QPN from the channel: %d",
4144 4069 retval);
4145 4070 return (IBT_INVALID_PARAM);
4146 4071 }
4147 4072 }
4148 4073
4149 4074
4150 4075 mutex_enter(&ud_statep->ud_state_mutex);
4151 4076
4152 4077 if (ud_statep->ud_state != IBCM_STATE_SIDR_REQ_RCVD) {
4153 4078 mutex_exit(&ud_statep->ud_state_mutex);
4154 4079 IBTF_DPRINTF_L2(cmlog, "ibt_cm_ud_proceed : Invalid State "
4155 4080 "specified");
4156 4081 return (IBT_INVALID_PARAM);
4157 4082 }
4158 4083
4159 4084 /* wait until client's CM handler returns DEFER status back to CM */
4160 4085
4161 4086 while (ud_statep->ud_clnt_proceed == IBCM_BLOCK) {
4162 4087 IBTF_DPRINTF_L5(cmlog, "ibt_cm_ud_proceed : Blocked for return"
4163 4088 " of client's ud cm handler");
4164 4089 cv_wait(&ud_statep->ud_block_client_cv,
4165 4090 &ud_statep->ud_state_mutex);
4166 4091 }
4167 4092
4168 4093 if (ud_statep->ud_clnt_proceed == IBCM_FAIL) {
↓ open down ↓ |
125 lines elided |
↑ open up ↑ |
4169 4094 mutex_exit(&ud_statep->ud_state_mutex);
4170 4095 IBTF_DPRINTF_L2(cmlog, "ibt_cm_ud_proceed : Failed as client "
4171 4096 "returned non-DEFER status from cm handler");
4172 4097 return (IBT_INVALID_PARAM);
4173 4098 }
4174 4099
4175 4100 ASSERT(ud_statep->ud_clnt_proceed == IBCM_UNBLOCK);
4176 4101 ud_statep->ud_clnt_proceed = IBCM_FAIL;
4177 4102 mutex_exit(&ud_statep->ud_state_mutex);
4178 4103
4179 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*proceed_targs))
4180 -
4181 4104 /* the state machine processing is done in a separate thread */
4182 4105
4183 4106 /* proceed_targs is freed in ibcm_proceed_via_taskq */
4184 4107 proceed_targs = kmem_zalloc(sizeof (ibcm_proceed_targs_t),
4185 4108 KM_SLEEP);
4186 4109
4187 4110 proceed_targs->status = status;
4188 4111 proceed_targs->priv_data_len = priv_data_len;
4189 4112
4190 4113 bcopy(priv_data, proceed_targs->priv_data, priv_data_len);
4191 4114
4192 4115 if (status == IBT_CM_ACCEPT) {
4193 4116 proceed_targs->tst.ud.ud_qkey =
4194 4117 qp_attr.qp_info.qp_transport.ud.ud_qkey;
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
4195 4118 proceed_targs->tst.ud.ud_qpn = qp_attr.qp_qpn;
4196 4119 }
4197 4120
4198 4121 proceed_targs->tst.ud.ud_statep = ud_statep;
4199 4122
4200 4123 /* copy redirect info based on status */
4201 4124 if (status == IBT_CM_REDIRECT)
4202 4125 bcopy(redirect_infop, &proceed_targs->tst.ud.ud_redirect_info,
4203 4126 sizeof (ibt_redirect_info_t));
4204 4127
4205 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*proceed_targs))
4206 -
4207 4128 (void) taskq_dispatch(ibcm_taskq, ibcm_ud_proceed_via_taskq,
4208 4129 proceed_targs, TQ_SLEEP);
4209 4130
4210 4131 return (IBT_SUCCESS);
4211 4132 }
4212 4133
4213 4134 /*
4214 4135 * Function:
4215 4136 * ibcm_ud_proceed_via_taskq
4216 4137 *
4217 4138 * Called from taskq, dispatched by ibt_cm_ud_proceed
4218 4139 * Completes the cm state processing for ibt_cm_ud_proceed
4219 4140 */
4220 4141 void
4221 4142 ibcm_ud_proceed_via_taskq(void *targs)
4222 4143 {
4223 4144 ibcm_proceed_targs_t *proceed_targs = (ibcm_proceed_targs_t *)targs;
4224 4145 ibcm_ud_state_data_t *ud_statep = proceed_targs->tst.ud.ud_statep;
4225 4146 ibcm_ud_clnt_reply_info_t ud_clnt_info;
4226 4147 ibt_sidr_status_t sidr_status;
4227 4148
4228 4149 IBTF_DPRINTF_L4(cmlog, "ibcm_ud_proceed_via_taskq(%p)", targs);
4229 4150
4230 4151 ud_clnt_info.ud_qpn = proceed_targs->tst.ud.ud_qpn;
4231 4152 ud_clnt_info.ud_qkey = proceed_targs->tst.ud.ud_qkey;
4232 4153 ud_clnt_info.priv_data = proceed_targs->priv_data;
4233 4154 ud_clnt_info.priv_data_len = proceed_targs->priv_data_len;
4234 4155 ud_clnt_info.redirect_infop = &proceed_targs->tst.ud.ud_redirect_info;
4235 4156
4236 4157 /* validate event and statep's state */
4237 4158 ibcm_process_sidr_req_cm_hdlr(ud_statep, proceed_targs->status,
4238 4159 &ud_clnt_info, &sidr_status,
4239 4160 (ibcm_sidr_rep_msg_t *)IBCM_OUT_MSGP(ud_statep->ud_stored_msg));
4240 4161
4241 4162 ibcm_post_sidr_rep_mad(ud_statep, sidr_status);
4242 4163
4243 4164 /* decr the statep ref cnt incremented in ibcm_process_sidr_req_msg */
4244 4165 mutex_enter(&ud_statep->ud_state_mutex);
4245 4166 IBCM_UD_REF_CNT_DECR(ud_statep);
4246 4167 mutex_exit(&ud_statep->ud_state_mutex);
4247 4168
4248 4169 kmem_free(targs, sizeof (ibcm_proceed_targs_t));
4249 4170 }
4250 4171
4251 4172 /*
4252 4173 * Function:
4253 4174 * ibt_set_alt_path
4254 4175 * Input:
4255 4176 * channel Channel handle returned from ibt_alloc_rc_channel(9F).
4256 4177 *
4257 4178 * mode Execute in blocking or non blocking mode.
4258 4179 *
4259 4180 * alt_path A pointer to an ibt_alt_path_info_t as returned from an
4260 4181 * ibt_get_alt_path(9F) call that specifies the new
4261 4182 * alternate path.
4262 4183 *
4263 4184 * priv_data A pointer to a buffer specified by caller for the
4264 4185 * private data in the outgoing CM Load Alternate Path
4265 4186 * (LAP) message sent to the remote host. This can be NULL
4266 4187 * if no private data is available to communicate to the
4267 4188 * remote node.
4268 4189 *
4269 4190 * priv_data_len Length of valid data in priv_data, this should be less
4270 4191 * than or equal to IBT_LAP_PRIV_DATA_SZ.
4271 4192 *
4272 4193 * Output:
4273 4194 * ret_args If called in blocking mode, points to a return argument
4274 4195 * structure of type ibt_ap_returns_t.
4275 4196 *
4276 4197 * Returns:
4277 4198 * IBT_SUCCESS on Success else appropriate error.
4278 4199 * Description:
4279 4200 * Load the specified alternate path. Causes the CM to send an LAP message
4280 4201 * to the remote node.
4281 4202 * Can only be called on a previously opened RC channel.
4282 4203 */
4283 4204 ibt_status_t
4284 4205 ibt_set_alt_path(ibt_channel_hdl_t channel, ibt_execution_mode_t mode,
4285 4206 ibt_alt_path_info_t *alt_path, void *priv_data,
4286 4207 ibt_priv_data_len_t priv_data_len, ibt_ap_returns_t *ret_args)
4287 4208 {
4288 4209 ibmf_handle_t ibmf_hdl;
4289 4210 ibt_status_t status = IBT_SUCCESS;
4290 4211 ibcm_lap_msg_t *lap_msgp;
4291 4212 ibcm_hca_info_t *hcap;
4292 4213 ibcm_state_data_t *statep;
4293 4214 uint8_t port_no;
4294 4215 ib_lid_t alternate_slid;
4295 4216 ibt_priv_data_len_t len;
4296 4217 ib_lid_t base_lid;
4297 4218 boolean_t alt_grh;
4298 4219
4299 4220 IBTF_DPRINTF_L3(cmlog, "ibt_set_alt_path(%p, %x, %p, %p, %x, %p)",
4300 4221 channel, mode, alt_path, priv_data, priv_data_len, ret_args);
4301 4222
4302 4223 /* validate channel */
4303 4224 if (IBCM_INVALID_CHANNEL(channel)) {
4304 4225 IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: invalid channel");
4305 4226 return (IBT_CHAN_HDL_INVALID);
4306 4227 }
4307 4228
4308 4229 if (ibtl_cm_get_chan_type(channel) != IBT_RC_SRV) {
4309 4230 IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: "
4310 4231 "Invalid Channel type: Applicable only to RC Channel");
4311 4232 return (IBT_CHAN_SRV_TYPE_INVALID);
4312 4233 }
4313 4234
4314 4235 if (mode == IBT_NONBLOCKING) {
4315 4236 if (ret_args != NULL) {
4316 4237 IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: "
4317 4238 "ret_args should be NULL when called in "
4318 4239 "non-blocking mode");
4319 4240 return (IBT_INVALID_PARAM);
4320 4241 }
4321 4242 } else if (mode == IBT_BLOCKING) {
4322 4243 if (ret_args == NULL) {
4323 4244 IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: "
4324 4245 "ret_args should be Non-NULL when called in "
4325 4246 "blocking mode");
4326 4247 return (IBT_INVALID_PARAM);
4327 4248 }
4328 4249 if (ret_args->ap_priv_data_len > IBT_APR_PRIV_DATA_SZ) {
4329 4250 IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: "
4330 4251 "expected private data length is too large");
4331 4252 return (IBT_INVALID_PARAM);
4332 4253 }
4333 4254 if ((ret_args->ap_priv_data_len > 0) &&
4334 4255 (ret_args->ap_priv_data == NULL)) {
4335 4256 IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: "
4336 4257 "apr_priv_data_len > 0, but apr_priv_data NULL");
4337 4258 return (IBT_INVALID_PARAM);
4338 4259 }
4339 4260 } else { /* any other mode is not valid for ibt_set_alt_path */
4340 4261 IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: "
4341 4262 "invalid mode %x specified", mode);
4342 4263 return (IBT_INVALID_PARAM);
4343 4264 }
4344 4265
4345 4266 if ((port_no = alt_path->ap_alt_cep_path.cep_hca_port_num) == 0)
4346 4267 return (IBT_INVALID_PARAM);
4347 4268
4348 4269 /* get the statep */
4349 4270 IBCM_GET_CHAN_PRIVATE(channel, statep);
4350 4271 if (statep == NULL) {
4351 4272 IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: statep NULL");
4352 4273 return (IBT_CM_FAILURE);
4353 4274 }
4354 4275
4355 4276 mutex_enter(&statep->state_mutex);
4356 4277 IBCM_RELEASE_CHAN_PRIVATE(channel);
4357 4278 IBCM_REF_CNT_INCR(statep);
4358 4279 mutex_exit(&statep->state_mutex);
4359 4280
4360 4281 IBTF_DPRINTF_L4(cmlog, "ibt_set_alt_path: statep %p", statep);
4361 4282
4362 4283 hcap = statep->hcap;
4363 4284
4364 4285 /* HCA must have been in active state. If not, it's a client bug */
4365 4286 if (!IBCM_ACCESS_HCA_OK(hcap))
4366 4287 IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: hca in error state");
4367 4288
4368 4289 ASSERT(statep->cm_handler != NULL);
4369 4290
4370 4291 /* Check Alternate port */
4371 4292 status = ibt_get_port_state_byguid(hcap->hca_guid, port_no, NULL,
4372 4293 &base_lid);
4373 4294 if (status != IBT_SUCCESS) {
4374 4295 IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: "
4375 4296 "ibt_get_port_state_byguid status %d ", status);
4376 4297 mutex_enter(&statep->state_mutex);
4377 4298 IBCM_REF_CNT_DECR(statep);
4378 4299 mutex_exit(&statep->state_mutex);
4379 4300 return (status);
4380 4301 }
4381 4302
4382 4303 if ((hcap->hca_port_info[port_no - 1].port_ibmf_hdl == NULL) &&
4383 4304 ((status = ibcm_hca_reinit_port(hcap, port_no - 1))
4384 4305 != IBT_SUCCESS)) {
4385 4306 IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: "
4386 4307 "ibmf reg or callback setup failed during re-initialize");
4387 4308 mutex_enter(&statep->state_mutex);
4388 4309 IBCM_REF_CNT_DECR(statep);
4389 4310 mutex_exit(&statep->state_mutex);
4390 4311 return (status);
4391 4312 }
4392 4313
4393 4314 ibmf_hdl = statep->stored_reply_addr.ibmf_hdl;
4394 4315
4395 4316 alternate_slid = base_lid +
4396 4317 alt_path->ap_alt_cep_path.cep_adds_vect.av_src_path;
4397 4318
4398 4319 IBTF_DPRINTF_L4(cmlog, "ibt_set_alt_path: alternate SLID = %x",
4399 4320 h2b16(alternate_slid));
4400 4321
4401 4322 ibcm_lapr_enter(); /* limit how many run simultaneously */
4402 4323
4403 4324 /* Allocate MAD for LAP */
4404 4325 if (statep->lapr_msg == NULL)
4405 4326 if ((status = ibcm_alloc_out_msg(ibmf_hdl, &statep->lapr_msg,
4406 4327 MAD_METHOD_SEND)) != IBT_SUCCESS) {
4407 4328 ibcm_lapr_exit();
4408 4329 IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: "
4409 4330 "chan 0x%p ibcm_alloc_out_msg failed", channel);
4410 4331 mutex_enter(&statep->state_mutex);
4411 4332 IBCM_REF_CNT_DECR(statep);
4412 4333 mutex_exit(&statep->state_mutex);
4413 4334 return (status);
4414 4335 }
4415 4336
4416 4337 mutex_enter(&statep->state_mutex);
4417 4338
4418 4339 IBTF_DPRINTF_L4(cmlog, "ibt_set_alt_path: connection state is"
4419 4340 " %x", statep->state);
4420 4341
4421 4342 /* Check state */
4422 4343 if ((statep->state != IBCM_STATE_ESTABLISHED) ||
4423 4344 (statep->ap_state != IBCM_AP_STATE_IDLE)) {
4424 4345 IBCM_REF_CNT_DECR(statep);
4425 4346 mutex_exit(&statep->state_mutex);
4426 4347 (void) ibcm_free_out_msg(ibmf_hdl, &statep->lapr_msg);
4427 4348 ibcm_lapr_exit();
4428 4349 return (IBT_CHAN_STATE_INVALID);
4429 4350 } else {
4430 4351 /* Set to LAP Sent state */
4431 4352 statep->ap_state = IBCM_AP_STATE_LAP_SENT;
4432 4353 statep->ap_done = B_FALSE;
4433 4354 statep->remaining_retry_cnt = statep->max_cm_retries;
4434 4355 statep->timer_stored_state = statep->state;
4435 4356 statep->timer_stored_ap_state = statep->ap_state;
4436 4357 IBCM_REF_CNT_INCR(statep); /* for ibcm_post_lap_complete */
↓ open down ↓ |
220 lines elided |
↑ open up ↑ |
4437 4358 }
4438 4359
4439 4360 mutex_exit(&statep->state_mutex);
4440 4361
4441 4362 /* No more failure returns below */
4442 4363
4443 4364 /* Allocate MAD for LAP */
4444 4365 IBTF_DPRINTF_L5(cmlog, "ibt_set_alt_path:"
4445 4366 " statep's mad addr = 0x%p", IBCM_OUT_HDRP(statep->lapr_msg));
4446 4367
4447 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lap_msgp))
4448 -
4449 4368 lap_msgp = (ibcm_lap_msg_t *)IBCM_OUT_MSGP(statep->lapr_msg);
4450 4369
4451 4370 lap_msgp->lap_alt_l_port_lid = h2b16(alternate_slid);
4452 4371 lap_msgp->lap_alt_r_port_lid =
4453 4372 h2b16(alt_path->ap_alt_cep_path.cep_adds_vect.av_dlid);
4454 4373
4455 4374 /* Fill in remote port gid */
4456 4375 lap_msgp->lap_alt_r_port_gid.gid_prefix =
4457 4376 h2b64(alt_path->ap_alt_cep_path.cep_adds_vect.av_dgid.gid_prefix);
4458 4377 lap_msgp->lap_alt_r_port_gid.gid_guid =
4459 4378 h2b64(alt_path->ap_alt_cep_path.cep_adds_vect.av_dgid.gid_guid);
4460 4379
4461 4380 /* Fill in local port gid */
4462 4381 lap_msgp->lap_alt_l_port_gid.gid_prefix =
4463 4382 h2b64(alt_path->ap_alt_cep_path.cep_adds_vect.av_sgid.gid_prefix);
4464 4383 lap_msgp->lap_alt_l_port_gid.gid_guid =
4465 4384 h2b64(alt_path->ap_alt_cep_path.cep_adds_vect.av_sgid.gid_guid);
4466 4385
4467 4386 alt_grh = alt_path->ap_alt_cep_path.cep_adds_vect.av_send_grh;
4468 4387
4469 4388 /* alternate_flow_label, and alternate srate, alternate traffic class */
4470 4389 lap_msgp->lap_alt_srate_plus =
4471 4390 alt_path->ap_alt_cep_path.cep_adds_vect.av_srate & 0x3f;
4472 4391 lap_msgp->lap_alt_flow_label_plus = h2b32(((alt_grh == B_TRUE) ?
4473 4392 (alt_path->ap_alt_cep_path.cep_adds_vect.av_flow << 12) : 0) |
4474 4393 alt_path->ap_alt_cep_path.cep_adds_vect.av_tclass);
4475 4394
4476 4395 /* Alternate hop limit, service level */
4477 4396 lap_msgp->lap_alt_hop_limit = (alt_grh == B_TRUE) ?
4478 4397 alt_path->ap_alt_cep_path.cep_adds_vect.av_hop : 1;
4479 4398 lap_msgp->lap_alt_sl_plus =
4480 4399 alt_path->ap_alt_cep_path.cep_adds_vect.av_srvl << 4 |
4481 4400 ((alt_grh == B_FALSE) ? 0x8 : 0);
4482 4401
4483 4402 lap_msgp->lap_alt_local_acktime_plus = ibt_usec2ib(
4484 4403 (2 * statep->rc_alt_pkt_lt) +
4485 4404 ibt_ib2usec(hcap->hca_ack_delay)) << 3;
4486 4405
4487 4406 lap_msgp->lap_local_comm_id = h2b32(statep->local_comid);
4488 4407 lap_msgp->lap_remote_comm_id = h2b32(statep->remote_comid);
4489 4408
↓ open down ↓ |
31 lines elided |
↑ open up ↑ |
4490 4409 lap_msgp->lap_remote_qpn_eecn_plus =
4491 4410 h2b32((statep->remote_qpn << 8) |
4492 4411 ibt_usec2ib(ibcm_remote_response_time) << 3);
4493 4412
4494 4413 len = min(priv_data_len, IBT_LAP_PRIV_DATA_SZ);
4495 4414 if ((len > 0) && priv_data) {
4496 4415 bcopy(priv_data, lap_msgp->lap_private_data, len);
4497 4416 }
4498 4417
4499 4418 /* only rc_alt_pkt_lt and ap_return_data fields are initialized */
4500 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
4501 -
4502 4419 statep->rc_alt_pkt_lt = ibt_ib2usec(alt_path->ap_alt_pkt_lt);
4503 4420
4504 4421 /* return_data is filled up in the state machine code */
4505 4422 statep->ap_return_data = ret_args;
4506 4423
4507 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*statep))
4508 -
4509 4424 IBCM_OUT_HDRP(statep->lapr_msg)->AttributeID =
4510 4425 h2b16(IBCM_INCOMING_LAP + IBCM_ATTR_BASE_ID);
4511 4426
4512 4427 IBCM_OUT_HDRP(statep->lapr_msg)->TransactionID =
4513 4428 h2b64(ibcm_generate_tranid(IBCM_INCOMING_LAP, statep->local_comid,
4514 4429 0));
4515 4430 IBTF_DPRINTF_L3(cmlog, "ibt_set_alt_path: statep %p, tid %llx",
4516 4431 statep, IBCM_OUT_HDRP(statep->lapr_msg)->TransactionID);
4517 4432
4518 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*lap_msgp))
4519 -
4520 4433 /* Send LAP */
4521 4434 ibcm_post_rc_mad(statep, statep->lapr_msg, ibcm_post_lap_complete,
4522 4435 statep);
4523 4436
4524 4437 mutex_enter(&statep->state_mutex);
4525 4438
4526 4439 if (mode == IBT_BLOCKING) {
4527 4440 IBTF_DPRINTF_L4(cmlog, "ibt_set_alt_path: blocking");
4528 4441
4529 4442 /* wait for APR */
4530 4443 while (statep->ap_done != B_TRUE) {
4531 4444 cv_wait(&statep->block_client_cv,
4532 4445 &statep->state_mutex);
4533 4446 }
4534 4447
4535 4448 IBTF_DPRINTF_L4(cmlog, "ibt_set_alt_path: done blocking");
4536 4449
4537 4450 /*
4538 4451 * In the case that ibt_set_alt_path fails,
4539 4452 * change retval to IBT_CM_FAILURE
4540 4453 */
4541 4454 if (statep->ap_return_data->ap_status != IBT_CM_AP_LOADED)
4542 4455 status = IBT_CM_FAILURE;
4543 4456
4544 4457 }
4545 4458
4546 4459 /* decrement the ref-count before leaving here */
4547 4460 IBCM_REF_CNT_DECR(statep);
4548 4461
4549 4462 mutex_exit(&statep->state_mutex);
4550 4463
4551 4464 ibcm_lapr_exit();
4552 4465
4553 4466 /* If this message isn't seen then ibt_set_alt_path failed */
4554 4467 IBTF_DPRINTF_L4(cmlog, "ibt_set_alt_path: done");
4555 4468
4556 4469 return (status);
4557 4470 }
4558 4471
4559 4472
4560 4473 #ifdef DEBUG
4561 4474
4562 4475 /*
4563 4476 * ibcm_query_classport_info:
4564 4477 * Query classportinfo
4565 4478 *
4566 4479 * INPUTS:
4567 4480 * channel - Channel that is associated with a statep
4568 4481 *
4569 4482 * RETURN VALUE: NONE
4570 4483 * This function is currently used to generate a valid get method classport
4571 4484 * info, and test CM functionality. There is no ibtl client interface to
4572 4485 * generate a classportinfo. It is possible that CM may use classportinfo
4573 4486 * from other nodes in the future, and most of the code below could be re-used.
4574 4487 */
4575 4488 void
4576 4489 ibcm_query_classport_info(ibt_channel_hdl_t channel)
4577 4490 {
4578 4491 ibcm_state_data_t *statep;
4579 4492 ibmf_msg_t *msgp;
4580 4493
4581 4494 IBTF_DPRINTF_L3(cmlog, "ibcm_query_classport_info(%p)", channel);
4582 4495
4583 4496 /* validate channel, first */
4584 4497 if (IBCM_INVALID_CHANNEL(channel)) {
4585 4498 IBTF_DPRINTF_L2(cmlog, "ibcm_query_classport_info: "
4586 4499 "invalid channel (%p)", channel);
4587 4500 return;
4588 4501 }
4589 4502
4590 4503 /* get the statep */
4591 4504 IBCM_GET_CHAN_PRIVATE(channel, statep);
4592 4505
4593 4506 /*
4594 4507 * This can happen, if the statep is already gone by a DREQ from
4595 4508 * the remote side
4596 4509 */
4597 4510 if (statep == NULL) {
4598 4511 IBTF_DPRINTF_L2(cmlog, "ibcm_query_classport_info: "
4599 4512 "statep NULL");
4600 4513 return;
4601 4514 }
4602 4515
4603 4516 mutex_enter(&statep->state_mutex);
4604 4517 IBCM_RELEASE_CHAN_PRIVATE(channel);
4605 4518 IBCM_REF_CNT_INCR(statep);
4606 4519 mutex_exit(&statep->state_mutex);
4607 4520
4608 4521 /* Debug/test code, so don't care about return status */
4609 4522 (void) ibcm_alloc_out_msg(statep->stored_reply_addr.ibmf_hdl, &msgp,
4610 4523 MAD_METHOD_GET);
4611 4524
4612 4525 IBCM_OUT_HDRP(msgp)->TransactionID = h2b64(ibcm_generate_tranid(
4613 4526 MAD_ATTR_ID_CLASSPORTINFO, statep->local_comid, 0));
4614 4527 IBCM_OUT_HDRP(msgp)->AttributeID = h2b16(MAD_ATTR_ID_CLASSPORTINFO);
4615 4528
4616 4529 (void) ibcm_post_mad(msgp, &statep->stored_reply_addr, NULL, NULL);
4617 4530
4618 4531 IBTF_DPRINTF_L3(cmlog, "ibcm_query_classport_info(%p) "
4619 4532 "Get method MAD posted ", channel);
4620 4533
4621 4534 (void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl, &msgp);
4622 4535
4623 4536 mutex_enter(&statep->state_mutex);
4624 4537 IBCM_REF_CNT_DECR(statep);
4625 4538 mutex_exit(&statep->state_mutex);
4626 4539 }
4627 4540
4628 4541 static void
4629 4542 ibcm_print_reply_addr(ibt_channel_hdl_t channel, ibcm_mad_addr_t *cm_reply_addr)
4630 4543 {
4631 4544 IBTF_DPRINTF_L4(cmlog, "ibcm_print_reply_addr: chan 0x%p, SLID %x, "
4632 4545 "DLID %x", channel, cm_reply_addr->rcvd_addr.ia_local_lid,
4633 4546 cm_reply_addr->rcvd_addr.ia_remote_lid);
4634 4547
4635 4548 IBTF_DPRINTF_L4(cmlog, "ibcm_print_reply_addr: QKEY %x, PKEY %x, "
4636 4549 "RQPN %x SL %x", cm_reply_addr->rcvd_addr.ia_q_key,
4637 4550 cm_reply_addr->rcvd_addr.ia_p_key,
4638 4551 cm_reply_addr->rcvd_addr.ia_remote_qno,
4639 4552 cm_reply_addr->rcvd_addr.ia_service_level);
4640 4553
4641 4554 IBTF_DPRINTF_L4(cmlog, "ibcm_print_reply_addr: CM SGID %llX:%llX ",
4642 4555 cm_reply_addr->grh_hdr.ig_sender_gid.gid_prefix,
4643 4556 cm_reply_addr->grh_hdr.ig_sender_gid.gid_guid);
4644 4557
4645 4558 IBTF_DPRINTF_L4(cmlog, "ibcm_print_reply_addr: CM DGID %llX:%llX",
4646 4559 cm_reply_addr->grh_hdr.ig_recver_gid.gid_prefix,
4647 4560 cm_reply_addr->grh_hdr.ig_recver_gid.gid_guid);
4648 4561
4649 4562 IBTF_DPRINTF_L4(cmlog, "ibcm_print_reply_addr: CM FL %x TC %x HL %x",
4650 4563 cm_reply_addr->grh_hdr.ig_flow_label,
4651 4564 cm_reply_addr->grh_hdr.ig_tclass,
4652 4565 cm_reply_addr->grh_hdr.ig_hop_limit);
4653 4566 }
4654 4567
4655 4568 #endif
4656 4569
4657 4570 /* For MCG List search */
4658 4571 typedef struct ibcm_mcg_list_s {
4659 4572 struct ibcm_mcg_list_s *ml_next;
↓ open down ↓ |
130 lines elided |
↑ open up ↑ |
4660 4573 ib_gid_t ml_sgid;
4661 4574 ib_gid_t ml_mgid;
4662 4575 ib_pkey_t ml_pkey;
4663 4576 ib_qkey_t ml_qkey;
4664 4577 uint_t ml_refcnt;
4665 4578 uint8_t ml_jstate;
4666 4579 } ibcm_mcg_list_t;
4667 4580
4668 4581 ibcm_mcg_list_t *ibcm_mcglist = NULL;
4669 4582
4670 -_NOTE(MUTEX_PROTECTS_DATA(ibcm_mcglist_lock, ibcm_mcg_list_s))
4671 -_NOTE(MUTEX_PROTECTS_DATA(ibcm_mcglist_lock, ibcm_mcglist))
4672 -
4673 4583 typedef struct ibcm_join_mcg_tqarg_s {
4674 4584 ib_gid_t rgid;
4675 4585 ibt_mcg_attr_t mcg_attr;
4676 4586 ibt_mcg_info_t *mcg_infop;
4677 4587 ibt_mcg_handler_t func;
4678 4588 void *arg;
4679 4589 } ibcm_join_mcg_tqarg_t;
4680 4590
4681 -_NOTE(READ_ONLY_DATA(ibcm_join_mcg_tqarg_s))
4682 -
4683 4591 void
4684 4592 ibcm_add_incr_mcg_entry(sa_mcmember_record_t *mcg_req,
4685 4593 sa_mcmember_record_t *mcg_resp)
4686 4594 {
4687 4595 ibcm_mcg_list_t *new = NULL;
4688 4596 ibcm_mcg_list_t *head = NULL;
4689 4597
4690 4598 IBTF_DPRINTF_L3(cmlog, "ibcm_add_incr_mcg_entry: MGID %llX:%llX"
4691 4599 "\n SGID %llX:%llX, JState %X)", mcg_req->MGID.gid_prefix,
4692 4600 mcg_req->MGID.gid_guid, mcg_req->PortGID.gid_prefix,
4693 4601 mcg_req->PortGID.gid_guid, mcg_req->JoinState);
4694 4602
4695 4603 mutex_enter(&ibcm_mcglist_lock);
4696 4604 head = ibcm_mcglist;
4697 4605
4698 4606 while (head != NULL) {
4699 4607 if ((head->ml_mgid.gid_guid == mcg_resp->MGID.gid_guid) &&
4700 4608 (head->ml_mgid.gid_prefix == mcg_resp->MGID.gid_prefix) &&
4701 4609 (head->ml_sgid.gid_guid == mcg_resp->PortGID.gid_guid)) {
4702 4610 /* Increment the count */
4703 4611 head->ml_refcnt++;
4704 4612 /* OR the join_state value, we need this during leave */
4705 4613 head->ml_jstate |= mcg_req->JoinState;
4706 4614
4707 4615 IBTF_DPRINTF_L3(cmlog, "ibcm_add_incr_mcg_entry: Entry "
4708 4616 "FOUND: refcnt %d JState %X", head->ml_refcnt,
4709 4617 head->ml_jstate);
4710 4618
4711 4619 mutex_exit(&ibcm_mcglist_lock);
4712 4620 return;
4713 4621 }
4714 4622 head = head->ml_next;
4715 4623 }
4716 4624 mutex_exit(&ibcm_mcglist_lock);
4717 4625
4718 4626 IBTF_DPRINTF_L3(cmlog, "ibcm_add_incr_mcg_entry: Create NEW Entry ");
4719 4627
4720 4628 /* If we are here, either list is empty or match couldn't be found */
4721 4629 new = kmem_zalloc(sizeof (ibcm_mcg_list_t), KM_SLEEP);
4722 4630
4723 4631 mutex_enter(&ibcm_mcglist_lock);
4724 4632 /* Initialize the fields */
4725 4633 new->ml_sgid = mcg_resp->PortGID;
4726 4634 new->ml_mgid = mcg_resp->MGID;
4727 4635 new->ml_qkey = mcg_req->Q_Key;
4728 4636 new->ml_pkey = mcg_req->P_Key;
4729 4637 new->ml_refcnt = 1; /* As this is the first entry */
4730 4638 new->ml_jstate = mcg_req->JoinState;
4731 4639 new->ml_next = NULL;
4732 4640
4733 4641 new->ml_next = ibcm_mcglist;
4734 4642 ibcm_mcglist = new;
4735 4643 mutex_exit(&ibcm_mcglist_lock);
4736 4644 }
4737 4645
4738 4646 /*
4739 4647 * ibcm_del_decr_mcg_entry
4740 4648 *
4741 4649 * Return value:
4742 4650 * IBCM_SUCCESS Entry found and ref_cnt is now zero. So go-ahead and
4743 4651 * leave the MCG group. The return arg *jstate will have
4744 4652 * a valid join_state value that needed to be used by
4745 4653 * xxx_leave_mcg().
4746 4654 * IBCM_LOOKUP_EXISTS Entry found and ref_cnt is decremented but is NOT zero.
4747 4655 * So do not leave the MCG group yet.
4748 4656 * IBCM_LOOKUP_FAIL Entry is NOT found.
4749 4657 */
4750 4658 ibcm_status_t
4751 4659 ibcm_del_decr_mcg_entry(sa_mcmember_record_t *mcg_req, uint8_t *jstate)
4752 4660 {
4753 4661 ibcm_mcg_list_t *head, *prev;
4754 4662
4755 4663 IBTF_DPRINTF_L3(cmlog, "ibcm_del_decr_mcg_entry: MGID %llX:%llX"
4756 4664 "\n SGID %llX:%llX, JState %X)", mcg_req->MGID.gid_prefix,
4757 4665 mcg_req->MGID.gid_guid, mcg_req->PortGID.gid_prefix,
4758 4666 mcg_req->PortGID.gid_guid, mcg_req->JoinState);
4759 4667
4760 4668 *jstate = 0;
4761 4669
4762 4670 mutex_enter(&ibcm_mcglist_lock);
4763 4671 head = ibcm_mcglist;
4764 4672 prev = NULL;
4765 4673
4766 4674 while (head != NULL) {
4767 4675 if ((head->ml_mgid.gid_guid == mcg_req->MGID.gid_guid) &&
4768 4676 (head->ml_mgid.gid_prefix == mcg_req->MGID.gid_prefix) &&
4769 4677 (head->ml_sgid.gid_guid == mcg_req->PortGID.gid_guid)) {
4770 4678 if (!(head->ml_jstate & mcg_req->JoinState)) {
4771 4679 IBTF_DPRINTF_L2(cmlog, "ibcm_del_decr_mcg_entry"
4772 4680 ": JoinState mismatch %X %X)",
4773 4681 head->ml_jstate, mcg_req->JoinState);
4774 4682 }
4775 4683 /* Decrement the count */
4776 4684 head->ml_refcnt--;
4777 4685
4778 4686 if (head->ml_refcnt == 0) {
4779 4687 *jstate = head->ml_jstate;
4780 4688
4781 4689 IBTF_DPRINTF_L3(cmlog, "ibcm_del_decr_mcg_entry"
4782 4690 ": refcnt is ZERO, so delete the entry ");
4783 4691 if ((head == ibcm_mcglist) || (prev == NULL)) {
4784 4692 ibcm_mcglist = head->ml_next;
4785 4693 } else if (prev != NULL) {
4786 4694 prev->ml_next = head->ml_next;
4787 4695 }
4788 4696 mutex_exit(&ibcm_mcglist_lock);
4789 4697
4790 4698 kmem_free(head, sizeof (ibcm_mcg_list_t));
4791 4699 return (IBCM_SUCCESS);
4792 4700 }
4793 4701 mutex_exit(&ibcm_mcglist_lock);
4794 4702 return (IBCM_LOOKUP_EXISTS);
4795 4703 }
4796 4704 prev = head;
4797 4705 head = head->ml_next;
4798 4706 }
4799 4707 mutex_exit(&ibcm_mcglist_lock);
4800 4708
4801 4709 /*
4802 4710 * If we are here, something went wrong, we don't have the entry
4803 4711 * for that MCG being joined.
4804 4712 */
4805 4713 IBTF_DPRINTF_L2(cmlog, "ibcm_del_decr_mcg_entry: Match NOT "
4806 4714 "Found ");
4807 4715
4808 4716 return (IBCM_LOOKUP_FAIL);
4809 4717 }
4810 4718
4811 4719
4812 4720 /*
4813 4721 * Function:
4814 4722 * ibt_join_mcg
4815 4723 * Input:
4816 4724 * rgid The request GID that defines the HCA port from which a
4817 4725 * contact to SA Access is performed to add the specified
4818 4726 * endport GID ((mcg_attr->mc_pgid) to a multicast group.
4819 4727 * If mcg_attr->mc_pgid is null, then this (rgid) will be
4820 4728 * treated as endport GID that is to be added to the
4821 4729 * multicast group.
4822 4730 *
4823 4731 * mcg_attr A pointer to an ibt_mcg_attr_t structure that defines
4824 4732 * the attributes of the desired multicast group to be
4825 4733 * created or joined.
4826 4734 *
4827 4735 * func NULL or a pointer to a function to call when
4828 4736 * ibt_join_mcg() completes. If 'func' is not NULL then
4829 4737 * ibt_join_mcg() will return as soon as possible after
4830 4738 * initiating the multicast group join/create process.
4831 4739 * 'func' is then called when the process completes.
4832 4740 *
4833 4741 * arg Argument to the 'func'.
4834 4742 *
4835 4743 * Output:
4836 4744 * mcg_info_p A pointer to the ibt_mcg_info_t structure, allocated
4837 4745 * by the caller, where the attributes of the created or
4838 4746 * joined multicast group are copied.
4839 4747 * Returns:
4840 4748 * IBT_SUCCESS
4841 4749 * IBT_INVALID_PARAM
4842 4750 * IBT_MCG_RECORDS_NOT_FOUND
4843 4751 * IBT_INSUFF_RESOURCE
4844 4752 * Description:
4845 4753 * Join a multicast group. The first full member "join" causes the MCG
4846 4754 * to be created.
4847 4755 */
4848 4756 ibt_status_t
4849 4757 ibt_join_mcg(ib_gid_t rgid, ibt_mcg_attr_t *mcg_attr,
4850 4758 ibt_mcg_info_t *mcg_info_p, ibt_mcg_handler_t func, void *arg)
4851 4759 {
4852 4760 ibcm_join_mcg_tqarg_t *mcg_tq;
4853 4761 int flag = ((func == NULL) ? KM_SLEEP : KM_NOSLEEP);
4854 4762
4855 4763 IBTF_DPRINTF_L3(cmlog, "ibt_join_mcg(%llX:%llX, %p)", rgid.gid_prefix,
4856 4764 rgid.gid_guid, mcg_attr);
4857 4765
4858 4766 if ((rgid.gid_prefix == 0) || (rgid.gid_guid == 0)) {
4859 4767 IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: Request GID is required");
4860 4768 return (IBT_INVALID_PARAM);
4861 4769 }
4862 4770
4863 4771 if ((mcg_attr->mc_pkey == IB_PKEY_INVALID_LIMITED) ||
4864 4772 (mcg_attr->mc_pkey == IB_PKEY_INVALID_FULL)) {
4865 4773 IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: Invalid P_Key specified");
4866 4774 return (IBT_INVALID_PARAM);
4867 4775 }
4868 4776
↓ open down ↓ |
176 lines elided |
↑ open up ↑ |
4869 4777 if (mcg_attr->mc_join_state == 0) {
4870 4778 IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: JoinState not specified");
4871 4779 return (IBT_INVALID_PARAM);
4872 4780 }
4873 4781
4874 4782 if (mcg_info_p == NULL) {
4875 4783 IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: mcg_info_p is NULL");
4876 4784 return (IBT_INVALID_PARAM);
4877 4785 }
4878 4786
4879 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*mcg_tq))
4880 -
4881 4787 mcg_tq = kmem_alloc(sizeof (ibcm_join_mcg_tqarg_t), flag);
4882 4788 if (mcg_tq == NULL) {
4883 4789 IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: "
4884 4790 "Unable to allocate memory for local usage.");
4885 4791 return (IBT_INSUFF_KERNEL_RESOURCE);
4886 4792 }
4887 4793
4888 4794 mcg_tq->rgid = rgid;
4889 4795 bcopy(mcg_attr, &mcg_tq->mcg_attr, sizeof (ibt_mcg_attr_t));
4890 4796 mcg_tq->mcg_infop = mcg_info_p;
4891 4797 mcg_tq->func = func;
4892 4798 mcg_tq->arg = arg;
4893 4799
4894 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*mcg_tq))
4895 -
4896 4800 if (func != NULL) { /* Non-Blocking */
4897 4801 IBTF_DPRINTF_L3(cmlog, "ibt_join_mcg: Non-Blocking Call");
4898 4802 if (taskq_dispatch(ibcm_taskq, ibcm_process_async_join_mcg,
4899 4803 mcg_tq, TQ_NOSLEEP) == 0) {
4900 4804 IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: Failed to "
4901 4805 "Dispatch the TaskQ");
4902 4806 kmem_free(mcg_tq, sizeof (ibcm_join_mcg_tqarg_t));
4903 4807 return (IBT_INSUFF_KERNEL_RESOURCE);
4904 4808 } else
4905 4809 return (IBT_SUCCESS);
4906 4810 } else { /* Blocking */
4907 4811 return (ibcm_process_join_mcg(mcg_tq));
4908 4812 }
4909 4813 }
4910 4814
4911 4815 static void
4912 4816 ibcm_process_async_join_mcg(void *tq_arg)
4913 4817 {
4914 4818 (void) ibcm_process_join_mcg(tq_arg);
4915 4819 }
4916 4820
4917 4821 static ibt_status_t
4918 4822 ibcm_process_join_mcg(void *taskq_arg)
4919 4823 {
4920 4824 sa_mcmember_record_t mcg_req;
4921 4825 sa_mcmember_record_t *mcg_resp;
4922 4826 ibmf_saa_access_args_t access_args;
4923 4827 ibmf_saa_handle_t saa_handle;
4924 4828 uint64_t component_mask = 0;
4925 4829 ibt_status_t retval;
4926 4830 ibtl_cm_hca_port_t hca_port;
4927 4831 uint_t num_records;
4928 4832 size_t length;
4929 4833 ibcm_hca_info_t *hcap;
4930 4834 ibcm_join_mcg_tqarg_t *mcg_arg = (ibcm_join_mcg_tqarg_t *)taskq_arg;
4931 4835 ibt_mcg_info_t *mcg_info_p = mcg_arg->mcg_infop;
4932 4836
4933 4837 IBTF_DPRINTF_L3(cmlog, "ibcm_process_join_mcg(%p)", mcg_arg);
4934 4838
4935 4839 retval = ibtl_cm_get_hca_port(mcg_arg->rgid, 0, &hca_port);
4936 4840 if (retval != IBT_SUCCESS) {
4937 4841 IBTF_DPRINTF_L2(cmlog, "ibcm_process_join_mcg: Failed to get "
4938 4842 "port info from specified RGID: status = %d", retval);
4939 4843 goto ibcm_join_mcg_exit1;
4940 4844 }
4941 4845
4942 4846 bzero(&mcg_req, sizeof (sa_mcmember_record_t));
4943 4847
4944 4848 if ((mcg_arg->mcg_attr.mc_pgid.gid_prefix == 0) ||
4945 4849 (mcg_arg->mcg_attr.mc_pgid.gid_guid == 0)) {
4946 4850 IBTF_DPRINTF_L3(cmlog, "ibcm_process_join_mcg: "
4947 4851 "Request GID is Port GID");
4948 4852 mcg_req.PortGID = mcg_arg->rgid;
4949 4853 } else {
4950 4854 mcg_req.PortGID = mcg_arg->mcg_attr.mc_pgid;
4951 4855 }
4952 4856 component_mask |= SA_MC_COMPMASK_PORTGID;
4953 4857
4954 4858 mcg_req.Q_Key = mcg_arg->mcg_attr.mc_qkey;
4955 4859 mcg_req.P_Key = mcg_arg->mcg_attr.mc_pkey;
4956 4860 mcg_req.JoinState = mcg_arg->mcg_attr.mc_join_state;
4957 4861 mcg_req.TClass = mcg_arg->mcg_attr.mc_tclass;
4958 4862 mcg_req.FlowLabel = mcg_arg->mcg_attr.mc_flow;
4959 4863 mcg_req.SL = mcg_arg->mcg_attr.mc_sl;
4960 4864
4961 4865 component_mask |= SA_MC_COMPMASK_QKEY | SA_MC_COMPMASK_PKEY |
4962 4866 SA_MC_COMPMASK_JOINSTATE | SA_MC_COMPMASK_TCLASS |
4963 4867 SA_MC_COMPMASK_FLOWLABEL | SA_MC_COMPMASK_SL;
4964 4868
4965 4869 /* If client has specified MGID, use it else SA will assign one. */
4966 4870 if ((mcg_arg->mcg_attr.mc_mgid.gid_prefix >> 56ULL & 0xFF) == 0xFF) {
4967 4871 mcg_req.MGID = mcg_arg->mcg_attr.mc_mgid;
4968 4872 component_mask |= SA_MC_COMPMASK_MGID;
4969 4873 }
4970 4874
4971 4875 IBTF_DPRINTF_L3(cmlog, "ibcm_process_join_mcg: ");
4972 4876 IBTF_DPRINTF_L3(cmlog, "PGID=%016llX:%016llX, ",
4973 4877 mcg_req.PortGID.gid_prefix, mcg_req.PortGID.gid_guid);
4974 4878 IBTF_DPRINTF_L3(cmlog, "MGID=%016llX:%016llX",
4975 4879 mcg_req.MGID.gid_prefix, mcg_req.MGID.gid_guid);
4976 4880 IBTF_DPRINTF_L3(cmlog, "JoinState = %X",
4977 4881 mcg_arg->mcg_attr.mc_join_state);
4978 4882 IBTF_DPRINTF_L5(cmlog, "QKey %lX, PKey %lX",
4979 4883 mcg_arg->mcg_attr.mc_qkey, mcg_arg->mcg_attr.mc_pkey);
4980 4884 IBTF_DPRINTF_L5(cmlog, "Scope %X, MLID %X",
4981 4885 mcg_arg->mcg_attr.mc_scope, mcg_arg->mcg_attr.mc_mlid);
4982 4886
4983 4887 /* Is MTU specified. */
4984 4888 if (mcg_arg->mcg_attr.mc_mtu_req.r_mtu) {
4985 4889 mcg_req.MTU = mcg_arg->mcg_attr.mc_mtu_req.r_mtu;
4986 4890 mcg_req.MTUSelector = mcg_arg->mcg_attr.mc_mtu_req.r_selector;
4987 4891
4988 4892 component_mask |= SA_MC_COMPMASK_MTUSELECTOR |
4989 4893 SA_MC_COMPMASK_MTU;
4990 4894 }
4991 4895
4992 4896 /* Is RATE specified. */
4993 4897 if (mcg_arg->mcg_attr.mc_rate_req.r_srate) {
4994 4898 mcg_req.Rate = mcg_arg->mcg_attr.mc_rate_req.r_srate;
4995 4899 mcg_req.RateSelector =
4996 4900 mcg_arg->mcg_attr.mc_rate_req.r_selector;
4997 4901
4998 4902 component_mask |= SA_MC_COMPMASK_RATESELECTOR |
4999 4903 SA_MC_COMPMASK_RATE;
5000 4904 }
5001 4905
5002 4906 /* Is Packet Life Time specified. */
5003 4907 if (mcg_arg->mcg_attr.mc_pkt_lt_req.p_pkt_lt) {
5004 4908 mcg_req.Rate = mcg_arg->mcg_attr.mc_pkt_lt_req.p_pkt_lt;
5005 4909 mcg_req.RateSelector =
5006 4910 mcg_arg->mcg_attr.mc_pkt_lt_req.p_selector;
5007 4911
5008 4912 component_mask |= SA_MC_COMPMASK_PKTLTSELECTOR |
5009 4913 SA_MC_COMPMASK_PKTLT;
5010 4914 }
5011 4915
5012 4916 if (mcg_arg->mcg_attr.mc_hop) {
5013 4917 mcg_req.HopLimit = mcg_arg->mcg_attr.mc_hop;
5014 4918 component_mask |= SA_MC_COMPMASK_HOPLIMIT;
5015 4919 }
5016 4920
5017 4921 if (mcg_arg->mcg_attr.mc_scope) {
5018 4922 mcg_req.Scope = mcg_arg->mcg_attr.mc_scope;
5019 4923 component_mask |= SA_MC_COMPMASK_SCOPE;
5020 4924 }
5021 4925
5022 4926 if (mcg_arg->mcg_attr.mc_mlid) {
5023 4927 mcg_req.MLID = mcg_arg->mcg_attr.mc_mlid;
5024 4928 component_mask |= SA_MC_COMPMASK_MLID;
5025 4929 }
5026 4930
5027 4931 /* Get SA Access Handle. */
5028 4932 hcap = ibcm_find_hca_entry(hca_port.hp_hca_guid);
5029 4933 if (hcap == NULL) {
5030 4934 IBTF_DPRINTF_L2(cmlog, "ibcm_process_join_mcg: NO HCA found");
5031 4935
5032 4936 retval = IBT_HCA_BUSY_DETACHING;
5033 4937 goto ibcm_join_mcg_exit1;
5034 4938 }
5035 4939
5036 4940 saa_handle = ibcm_get_saa_handle(hcap, hca_port.hp_port);
5037 4941 if (saa_handle == NULL) {
5038 4942 IBTF_DPRINTF_L2(cmlog, "ibcm_process_join_mcg: SA Handle NULL");
5039 4943
5040 4944 retval = IBT_HCA_PORT_NOT_ACTIVE;
5041 4945 goto ibcm_join_mcg_exit;
5042 4946 }
5043 4947
5044 4948 if ((mcg_arg->mcg_attr.mc_pgid.gid_prefix != 0) &&
5045 4949 (mcg_arg->mcg_attr.mc_pgid.gid_guid != 0)) {
5046 4950 retval = ibtl_cm_get_hca_port(mcg_arg->mcg_attr.mc_pgid, 0,
5047 4951 &hca_port);
5048 4952 if (retval != IBT_SUCCESS) {
5049 4953 IBTF_DPRINTF_L2(cmlog, "ibcm_process_join_mcg: Failed "
5050 4954 "to get PortInfo of specified PGID: status = %d",
5051 4955 retval);
5052 4956 goto ibcm_join_mcg_exit1;
5053 4957 }
5054 4958 }
5055 4959
5056 4960 /* Contact SA Access */
5057 4961 access_args.sq_attr_id = SA_MCMEMBERRECORD_ATTRID;
5058 4962 access_args.sq_access_type = IBMF_SAA_UPDATE;
5059 4963 access_args.sq_component_mask = component_mask;
5060 4964 access_args.sq_template = &mcg_req;
5061 4965 access_args.sq_template_length = sizeof (sa_mcmember_record_t);
5062 4966 access_args.sq_callback = NULL;
5063 4967 access_args.sq_callback_arg = NULL;
5064 4968
5065 4969 retval = ibcm_contact_sa_access(saa_handle, &access_args, &length,
5066 4970 (void **)&mcg_resp);
5067 4971 if (retval != IBT_SUCCESS) {
5068 4972 IBTF_DPRINTF_L2(cmlog, "ibcm_process_join_mcg: "
5069 4973 "SA Access Failed");
5070 4974 goto ibcm_join_mcg_exit;
5071 4975 }
5072 4976
5073 4977 num_records = length/sizeof (sa_mcmember_record_t);
5074 4978
5075 4979 IBTF_DPRINTF_L4(cmlog, "ibcm_process_join_mcg: "
5076 4980 "Found %d MCMember Records", num_records);
5077 4981
5078 4982 /* Validate the returned number of records. */
5079 4983 if ((mcg_resp != NULL) && (num_records > 0)) {
5080 4984 /* Update the return values. */
5081 4985 mcg_info_p->mc_adds_vect.av_dgid = mcg_resp->MGID;
5082 4986 mcg_info_p->mc_adds_vect.av_sgid = mcg_resp->PortGID;
5083 4987 mcg_info_p->mc_adds_vect.av_srate = mcg_resp->Rate;
5084 4988 mcg_info_p->mc_adds_vect.av_srvl = mcg_resp->SL;
5085 4989 mcg_info_p->mc_adds_vect.av_flow = mcg_resp->FlowLabel;
5086 4990 mcg_info_p->mc_adds_vect.av_tclass = mcg_resp->TClass;
5087 4991 mcg_info_p->mc_adds_vect.av_hop = mcg_resp->HopLimit;
5088 4992 mcg_info_p->mc_adds_vect.av_send_grh = B_TRUE;
5089 4993 mcg_info_p->mc_adds_vect.av_dlid = mcg_resp->MLID;
5090 4994 mcg_info_p->mc_mtu = mcg_resp->MTU;
5091 4995 mcg_info_p->mc_qkey = mcg_resp->Q_Key;
5092 4996
5093 4997 retval = ibt_pkey2index_byguid(hca_port.hp_hca_guid,
5094 4998 hca_port.hp_port, mcg_resp->P_Key, &mcg_info_p->mc_pkey_ix);
5095 4999 if (retval != IBT_SUCCESS) {
5096 5000 IBTF_DPRINTF_L3(cmlog, "ibcm_process_join_mcg: "
5097 5001 "Pkey2Index Conversion failed<%d>", retval);
5098 5002 mcg_info_p->mc_pkey_ix = 0;
5099 5003 }
5100 5004
5101 5005 mcg_info_p->mc_scope = mcg_resp->Scope;
5102 5006 mcg_info_p->mc_pkt_lt = mcg_resp->PacketLifeTime;
5103 5007
5104 5008 mcg_info_p->mc_adds_vect.av_port_num = hca_port.hp_port;
5105 5009 mcg_info_p->mc_adds_vect.av_sgid_ix = hca_port.hp_sgid_ix;
5106 5010 mcg_info_p->mc_adds_vect.av_src_path = 0;
5107 5011
5108 5012 /* Add or Incr the matching MCG entry. */
5109 5013 ibcm_add_incr_mcg_entry(&mcg_req, mcg_resp);
5110 5014 /* Deallocate the memory allocated by SA for mcg_resp. */
5111 5015 kmem_free(mcg_resp, length);
5112 5016
5113 5017 retval = IBT_SUCCESS;
5114 5018 } else {
5115 5019 retval = IBT_MCG_RECORDS_NOT_FOUND;
5116 5020 IBTF_DPRINTF_L3(cmlog, "ibcm_process_join_mcg: "
5117 5021 "MCG RECORDS NOT FOUND");
5118 5022 }
5119 5023
5120 5024 ibcm_join_mcg_exit:
5121 5025 ibcm_dec_hca_acc_cnt(hcap);
5122 5026
5123 5027 ibcm_join_mcg_exit1:
5124 5028 if (mcg_arg->func)
5125 5029 (*(mcg_arg->func))(mcg_arg->arg, retval, mcg_info_p);
5126 5030
5127 5031 kmem_free(mcg_arg, sizeof (ibcm_join_mcg_tqarg_t));
5128 5032
5129 5033 return (retval);
5130 5034 }
5131 5035
5132 5036
5133 5037 /*
5134 5038 * Function:
5135 5039 * ibt_leave_mcg
5136 5040 * Input:
5137 5041 * rgid The request GID that defines the HCA port upon which
5138 5042 * to send the request to the Subnet Administrator, to
5139 5043 * remove the specified port (port_gid) from the multicast
5140 5044 * group. If 'port_gid' is the Reserved GID (i.e.
5141 5045 * port_gid.gid_prefix = 0 and port_gid.gid_guid = 0),
5142 5046 * then the end-port associated with 'rgid' is removed
5143 5047 * from the multicast group.
5144 5048 *
5145 5049 * mc_gid A multicast group GID as returned from ibt_join_mcg()
5146 5050 * call. This is optional, if not specified (i.e.
5147 5051 * mc_gid.gid_prefix has 0xFF in its upper 8 bits to
5148 5052 * identify this as being a multicast GID), then the
5149 5053 * port is removed from all the multicast groups of
5150 5054 * which it is a member.
5151 5055 *
5152 5056 * port_gid This is optional, if not the Reserved GID (gid_prefix
5153 5057 * and gid_guid not equal to 0), then this specifies the
5154 5058 * endport GID of the multicast group member being deleted
5155 5059 * from the group. If it is the Reserved GID (gid_prefix
5156 5060 * and gid_guid equal to 0) then the member endport GID is
5157 5061 * determined from 'rgid'.
5158 5062 *
5159 5063 * mc_join_state The Join State attribute used when the group was joined
5160 5064 * using ibt_join_mcg(). This Join State component must
5161 5065 * contains at least one bit set to 1 in the same position
5162 5066 * as that used during ibt_join_mcg(). i.e. the logical
5163 5067 * AND of the two JoinState components is not all zeros.
5164 5068 * This Join State component must not have some bits set
5165 5069 * which are not set using ibt_join_mcg().
5166 5070 * Output:
5167 5071 * None.
5168 5072 * Returns:
5169 5073 * IBT_SUCCESS
5170 5074 * IBT_INVALID_PARAM
5171 5075 * IBT_MC_GROUP_INVALID
5172 5076 * IBT_INSUFF_RESOURCE
5173 5077 * Description:
5174 5078 * The port associated with the port GID shall be removed from the
5175 5079 * multicast group specified by MGID (mc_gid) or from all the multicast
5176 5080 * groups of which it is a member if the MGID (mc_gid) is not specified.
5177 5081 *
5178 5082 * The last full member to leave causes the destruction of the Multicast
5179 5083 * Group.
5180 5084 */
5181 5085 ibt_status_t
5182 5086 ibt_leave_mcg(ib_gid_t rgid, ib_gid_t mc_gid, ib_gid_t port_gid,
5183 5087 uint8_t mc_join_state)
5184 5088 {
5185 5089 sa_mcmember_record_t mcg_req;
5186 5090 ibmf_saa_access_args_t access_args;
5187 5091 ibmf_saa_handle_t saa_handle;
5188 5092 uint64_t component_mask = 0;
5189 5093 int sa_retval;
5190 5094 ibt_status_t retval;
5191 5095 ibcm_status_t ret;
5192 5096 ibtl_cm_hca_port_t hca_port;
5193 5097 size_t length;
5194 5098 void *results_p;
5195 5099 ibcm_hca_info_t *hcap;
5196 5100 uint8_t jstate = 0;
5197 5101
5198 5102 IBTF_DPRINTF_L3(cmlog, "ibt_leave_mcg(%llX:%llX, %llX:%llX)",
5199 5103 rgid.gid_prefix, rgid.gid_guid, mc_gid.gid_prefix, mc_gid.gid_guid);
5200 5104
5201 5105 IBTF_DPRINTF_L3(cmlog, "ibt_leave_mcg(%llX:%llX, 0x%X)",
5202 5106 port_gid.gid_prefix, port_gid.gid_guid, mc_join_state);
5203 5107
5204 5108 if ((rgid.gid_prefix == 0) || (rgid.gid_guid == 0)) {
5205 5109 IBTF_DPRINTF_L2(cmlog, "ibt_leave_mcg: RequestGID is required");
5206 5110 return (IBT_INVALID_PARAM);
5207 5111 }
5208 5112
5209 5113 bzero(&mcg_req, sizeof (sa_mcmember_record_t));
5210 5114
5211 5115 IBTF_DPRINTF_L3(cmlog, "ibt_leave_mcg: MGID: %llX%llX",
5212 5116 mc_gid.gid_prefix, mc_gid.gid_guid);
5213 5117
5214 5118 /* Validate MGID */
5215 5119 if ((mc_gid.gid_prefix >> 56ULL & 0xFF) == 0xFF) {
5216 5120 mcg_req.MGID = mc_gid;
5217 5121 component_mask |= SA_MC_COMPMASK_MGID;
5218 5122 } else if ((mc_gid.gid_prefix != 0) || (mc_gid.gid_guid != 0)) {
5219 5123 IBTF_DPRINTF_L3(cmlog, "ibt_leave_mcg: Invalid MGID specified");
5220 5124 return (IBT_MC_MGID_INVALID);
5221 5125 }
5222 5126
5223 5127 if ((port_gid.gid_prefix == 0) || (port_gid.gid_guid == 0)) {
5224 5128 mcg_req.PortGID = rgid;
5225 5129 } else {
5226 5130 IBTF_DPRINTF_L3(cmlog, "ibt_leave_mcg: Performing PROXY Leave");
5227 5131 mcg_req.PortGID = port_gid;
5228 5132 }
5229 5133 component_mask |= SA_MC_COMPMASK_PORTGID;
5230 5134
5231 5135 IBTF_DPRINTF_L3(cmlog, "ibt_leave_mcg: Port GID <%llX:%llX>",
5232 5136 mcg_req.PortGID.gid_prefix, mcg_req.PortGID.gid_guid);
5233 5137
5234 5138 /* Join State */
5235 5139 mcg_req.JoinState = mc_join_state;
5236 5140 component_mask |= SA_MC_COMPMASK_JOINSTATE;
5237 5141
5238 5142 ret = ibcm_del_decr_mcg_entry(&mcg_req, &jstate);
5239 5143 if (ret == IBCM_LOOKUP_EXISTS) {
5240 5144 IBTF_DPRINTF_L3(cmlog, "ibt_leave_mcg: Multiple JoinMCG record "
5241 5145 " still exists, we shall leave for last leave_mcg call");
5242 5146 return (IBT_SUCCESS);
5243 5147 } else if (ret == IBCM_LOOKUP_FAIL) {
5244 5148 IBTF_DPRINTF_L2(cmlog, "ibt_leave_mcg: No Record found, "
5245 5149 "continue with leave_mcg call");
5246 5150 } else if ((ret == IBCM_SUCCESS) && (jstate != 0)) {
5247 5151 /*
5248 5152 * Update with cached "jstate", as this will be OR'ed of
5249 5153 * all ibt_join_mcg() calls for this record.
5250 5154 */
5251 5155 mcg_req.JoinState = jstate;
5252 5156 }
5253 5157
5254 5158 retval = ibtl_cm_get_hca_port(rgid, 0, &hca_port);
5255 5159 if (retval != IBT_SUCCESS) {
5256 5160 IBTF_DPRINTF_L2(cmlog, "ibt_leave_mcg: Failed to get port info "
5257 5161 "from specified RGID : status = %d", retval);
5258 5162 return (retval);
5259 5163 }
5260 5164
5261 5165 /* Get SA Access Handle. */
5262 5166 hcap = ibcm_find_hca_entry(hca_port.hp_hca_guid);
5263 5167 if (hcap == NULL) {
5264 5168 IBTF_DPRINTF_L2(cmlog, "ibt_leave_mcg: "
5265 5169 "NO HCA found");
5266 5170 return (IBT_HCA_BUSY_DETACHING);
5267 5171 }
5268 5172
5269 5173 saa_handle = ibcm_get_saa_handle(hcap, hca_port.hp_port);
5270 5174 if (saa_handle == NULL) {
5271 5175 IBTF_DPRINTF_L2(cmlog, "ibt_leave_mcg: saa_handle is NULL");
5272 5176 ibcm_dec_hca_acc_cnt(hcap);
5273 5177 return (IBT_HCA_PORT_NOT_ACTIVE);
5274 5178 }
5275 5179
5276 5180 /* Contact SA Access */
5277 5181 access_args.sq_attr_id = SA_MCMEMBERRECORD_ATTRID;
5278 5182 access_args.sq_access_type = IBMF_SAA_DELETE;
5279 5183 access_args.sq_component_mask = component_mask;
5280 5184 access_args.sq_template = &mcg_req;
5281 5185 access_args.sq_template_length = sizeof (sa_mcmember_record_t);
5282 5186 access_args.sq_callback = NULL;
5283 5187 access_args.sq_callback_arg = NULL;
5284 5188
5285 5189 ibcm_sa_access_enter();
5286 5190
5287 5191 sa_retval = ibmf_sa_access(saa_handle, &access_args, 0, &length,
5288 5192 &results_p);
5289 5193 if (sa_retval != IBMF_SUCCESS) {
5290 5194 IBTF_DPRINTF_L2(cmlog, "ibt_leave_mcg: SA access Failed: %d",
5291 5195 sa_retval);
5292 5196 (void) ibcm_ibmf_analyze_error(sa_retval);
5293 5197 retval = IBT_MC_GROUP_INVALID;
5294 5198 }
5295 5199
5296 5200 ibcm_sa_access_exit();
5297 5201
5298 5202 ibcm_dec_hca_acc_cnt(hcap);
5299 5203
5300 5204 return (retval);
5301 5205 }
5302 5206
5303 5207
5304 5208 /*
5305 5209 * Function:
5306 5210 * ibt_query_mcg
5307 5211 * Input:
5308 5212 * rgid The request GID that defines the HCA port upon which
5309 5213 * to send the request to the Subnet Administrator, to
5310 5214 * retrieve Multicast Records matching attributes as
5311 5215 * specified through 'mcg_attr' argument.
5312 5216 *
5313 5217 * mcg_attr NULL or a pointer to an ibt_mcg_attr_t structure that
5314 5218 * specifies MCG attributes that are to be matched.
5315 5219 * Attributes that are not required can be wild carded
5316 5220 * by specifying as '0'.
5317 5221 *
5318 5222 * mcgs_max_num The maximum number of matching multicast groups to
5319 5223 * return. If zero, then all available matching multicast
5320 5224 * groups are returned.
5321 5225 * Output:
5322 5226 * mcgs_info_p The address of an ibt_mcg_info_t pointer, where
5323 5227 * multicast group information is returned. The actual
5324 5228 * number of entries filled in the array is returned in
5325 5229 * entries_p.
5326 5230 *
5327 5231 * entries_p The number of ibt_mcg_attr_t entries returned.
5328 5232 * Returns:
5329 5233 * IBT_SUCCESS
5330 5234 * IBT_INVALID_PARAM
5331 5235 * IBT_MCG_RECORDS_NOT_FOUND
5332 5236 * Description:
5333 5237 * Request information on multicast groups that match the parameters
5334 5238 * specified in mcg_attr. Information on each multicast group is returned
5335 5239 * to the caller in the form of an array of ibt_mcg_info_t.
5336 5240 * ibt_query_mcg() allocates the memory for this array and returns a
5337 5241 * pointer to the array (mcgs_p) and the number of entries in the array
5338 5242 * (entries_p). This memory should be freed by the client using
5339 5243 * ibt_free_mcg_info().
5340 5244 */
5341 5245 ibt_status_t
5342 5246 ibt_query_mcg(ib_gid_t rgid, ibt_mcg_attr_t *mcg_attr, uint_t mcgs_max_num,
5343 5247 ibt_mcg_info_t **mcgs_info_p, uint_t *entries_p)
5344 5248 {
5345 5249 sa_mcmember_record_t mcg_req;
5346 5250 sa_mcmember_record_t *mcg_resp;
5347 5251 ibt_mcg_info_t *mcg_infop;
5348 5252 ibmf_saa_access_args_t access_args;
5349 5253 ibmf_saa_handle_t saa_handle;
5350 5254 uint64_t component_mask = 0;
5351 5255 ibt_status_t retval;
5352 5256 ibtl_cm_hca_port_t hport;
5353 5257 uint_t num_records;
5354 5258 size_t length;
5355 5259 void *results_p;
5356 5260 ib_gid_t port_gid;
5357 5261 ibcm_hca_info_t *hcap;
5358 5262
5359 5263 IBTF_DPRINTF_L3(cmlog, "ibt_query_mcg(%p, %d)", mcg_attr, mcgs_max_num);
5360 5264
5361 5265 if ((entries_p == NULL) || (mcgs_info_p == NULL)) {
5362 5266 IBTF_DPRINTF_L2(cmlog, "ibt_query_mcg: "
5363 5267 "entries_p or mcgs_info_p is NULL");
5364 5268 return (IBT_INVALID_PARAM);
5365 5269 }
5366 5270
5367 5271 if ((rgid.gid_prefix == 0) || (rgid.gid_guid == 0)) {
5368 5272 IBTF_DPRINTF_L2(cmlog, "ibt_query_mcg: RequestGID is required");
5369 5273 return (IBT_INVALID_PARAM);
5370 5274 }
5371 5275 IBTF_DPRINTF_L4(cmlog, "ibt_query_mcg: Request GID <%llX:%llX>",
5372 5276 rgid.gid_prefix, rgid.gid_guid);
5373 5277
5374 5278 bzero(&mcg_req, sizeof (sa_mcmember_record_t));
5375 5279 port_gid.gid_prefix = port_gid.gid_guid = 0;
5376 5280
5377 5281 if (mcg_attr != NULL) {
5378 5282 port_gid = mcg_attr->mc_pgid;
5379 5283
5380 5284 if ((port_gid.gid_prefix != 0) && (port_gid.gid_guid != 0)) {
5381 5285 mcg_req.PortGID = mcg_attr->mc_pgid;
5382 5286 component_mask |= SA_MC_COMPMASK_PORTGID;
5383 5287
5384 5288 IBTF_DPRINTF_L4(cmlog, "ibt_query_mcg: PGID %llX:%llX",
5385 5289 port_gid.gid_prefix, port_gid.gid_guid);
5386 5290 }
5387 5291
5388 5292 /* Is Q_Key specified. */
5389 5293 if (mcg_attr->mc_qkey != 0) {
5390 5294 mcg_req.Q_Key = mcg_attr->mc_qkey;
5391 5295 component_mask |= SA_MC_COMPMASK_QKEY;
5392 5296 }
5393 5297
5394 5298 /* Is P_Key specified. */
5395 5299 if (mcg_attr->mc_pkey != 0) {
5396 5300 mcg_req.P_Key = mcg_attr->mc_pkey;
5397 5301 component_mask |= SA_MC_COMPMASK_PKEY;
5398 5302 }
5399 5303
5400 5304 /* Is MGID specified. */
5401 5305 if ((mcg_attr->mc_mgid.gid_prefix >> 56ULL & 0xFF) == 0xFF) {
5402 5306 mcg_req.MGID = mcg_attr->mc_mgid;
5403 5307 component_mask |= SA_MC_COMPMASK_MGID;
5404 5308 }
5405 5309
5406 5310 /* Is MTU specified. */
5407 5311 if (mcg_attr->mc_mtu_req.r_mtu) {
5408 5312 mcg_req.MTU = mcg_attr->mc_mtu_req.r_mtu;
5409 5313 mcg_req.MTUSelector = mcg_attr->mc_mtu_req.r_selector;
5410 5314
5411 5315 component_mask |= SA_MC_COMPMASK_MTUSELECTOR |
5412 5316 SA_MC_COMPMASK_MTU;
5413 5317 }
5414 5318
5415 5319 if (mcg_attr->mc_tclass) {
5416 5320 mcg_req.TClass = mcg_attr->mc_tclass;
5417 5321 component_mask |= SA_MC_COMPMASK_TCLASS;
5418 5322 }
5419 5323
5420 5324 /* Is RATE specified. */
5421 5325 if (mcg_attr->mc_rate_req.r_srate) {
5422 5326 mcg_req.Rate = mcg_attr->mc_rate_req.r_srate;
5423 5327 mcg_req.RateSelector = mcg_attr->mc_rate_req.r_selector;
5424 5328
5425 5329 component_mask |= SA_MC_COMPMASK_RATESELECTOR |
5426 5330 SA_MC_COMPMASK_RATE;
5427 5331 }
5428 5332
5429 5333 /* Is Packet Life Time specified. */
5430 5334 if (mcg_attr->mc_pkt_lt_req.p_pkt_lt) {
5431 5335 mcg_req.Rate = mcg_attr->mc_pkt_lt_req.p_pkt_lt;
5432 5336 mcg_req.RateSelector =
5433 5337 mcg_attr->mc_pkt_lt_req.p_selector;
5434 5338
5435 5339 component_mask |= SA_MC_COMPMASK_PKTLTSELECTOR |
5436 5340 SA_MC_COMPMASK_PKTLT;
5437 5341 }
5438 5342
5439 5343 if (mcg_attr->mc_hop) {
5440 5344 mcg_req.HopLimit = mcg_attr->mc_hop;
5441 5345 component_mask |= SA_MC_COMPMASK_HOPLIMIT;
5442 5346 }
5443 5347
5444 5348 if (mcg_attr->mc_flow) {
5445 5349 mcg_req.FlowLabel = mcg_attr->mc_flow;
5446 5350 component_mask |= SA_MC_COMPMASK_FLOWLABEL;
5447 5351 }
5448 5352
5449 5353 if (mcg_attr->mc_sl) {
5450 5354 mcg_req.SL = mcg_attr->mc_sl;
5451 5355 component_mask |= SA_MC_COMPMASK_SL;
5452 5356 }
5453 5357
5454 5358 if (mcg_attr->mc_scope) {
5455 5359 mcg_req.Scope = mcg_attr->mc_scope;
5456 5360 component_mask |= SA_MC_COMPMASK_SCOPE;
5457 5361 }
5458 5362
5459 5363 if (mcg_attr->mc_join_state) {
5460 5364 mcg_req.JoinState = mcg_attr->mc_join_state;
5461 5365 component_mask |= SA_MC_COMPMASK_JOINSTATE;
5462 5366 }
5463 5367
5464 5368 if (mcg_attr->mc_mlid) {
5465 5369 mcg_req.MLID = mcg_attr->mc_mlid;
5466 5370 component_mask |= SA_MC_COMPMASK_MLID;
5467 5371 }
5468 5372 }
5469 5373
5470 5374 retval = ibtl_cm_get_hca_port(rgid, 0, &hport);
5471 5375 if (retval != IBT_SUCCESS) {
5472 5376 IBTF_DPRINTF_L2(cmlog, "ibt_query_mcg: Failed to get port info "
5473 5377 "from specified RGID : status = %d", retval);
5474 5378 return (retval);
5475 5379 }
5476 5380
5477 5381 /* Get SA Access Handle. */
5478 5382 hcap = ibcm_find_hca_entry(hport.hp_hca_guid);
5479 5383 if (hcap == NULL) {
5480 5384 IBTF_DPRINTF_L2(cmlog, "ibt_query_mcg: NO HCA found");
5481 5385 return (IBT_HCA_BUSY_DETACHING);
5482 5386 }
5483 5387
5484 5388 saa_handle = ibcm_get_saa_handle(hcap, hport.hp_port);
5485 5389 if (saa_handle == NULL) {
5486 5390 IBTF_DPRINTF_L2(cmlog, "ibt_query_mcg: saa_handle is NULL");
5487 5391 ibcm_dec_hca_acc_cnt(hcap);
5488 5392 return (IBT_HCA_PORT_NOT_ACTIVE);
5489 5393 }
5490 5394
5491 5395 /* Contact SA Access */
5492 5396 access_args.sq_attr_id = SA_MCMEMBERRECORD_ATTRID;
5493 5397 access_args.sq_access_type = IBMF_SAA_RETRIEVE;
5494 5398 access_args.sq_component_mask = component_mask;
5495 5399 access_args.sq_template = &mcg_req;
5496 5400 access_args.sq_template_length = sizeof (sa_mcmember_record_t);
5497 5401 access_args.sq_callback = NULL;
5498 5402 access_args.sq_callback_arg = NULL;
5499 5403
5500 5404 retval = ibcm_contact_sa_access(saa_handle, &access_args, &length,
5501 5405 &results_p);
5502 5406 if (retval != IBT_SUCCESS) {
5503 5407 IBTF_DPRINTF_L2(cmlog, "ibt_query_mcg: SA access Failed");
5504 5408 ibcm_dec_hca_acc_cnt(hcap);
5505 5409 return (retval);
5506 5410 }
5507 5411
5508 5412 num_records = length/sizeof (sa_mcmember_record_t);
5509 5413
5510 5414 IBTF_DPRINTF_L4(cmlog, "ibt_query_mcg: Found %d MCMember Records",
5511 5415 num_records);
5512 5416
5513 5417 /* Validate the returned number of records. */
5514 5418 if ((results_p != NULL) && (num_records > 0)) {
5515 5419 uint_t i;
5516 5420
5517 5421 /*
5518 5422 * If mcgs_max_num is zero, then return all records else
5519 5423 * return only requested number of records
5520 5424 */
5521 5425 if ((mcgs_max_num != 0) && (num_records > mcgs_max_num)) {
5522 5426 /* we are interested in only mcgs_max_num records */
5523 5427 num_records = mcgs_max_num;
5524 5428 }
5525 5429
5526 5430 /*
5527 5431 * The SGID returned in "mcg_info_p" buffer should be PortGID,
5528 5432 * (mcg_attr->mc_pgid), if 'mcg_attr->mc_pgid' was specified,
5529 5433 * else RequestGID (rgid) should be returned.
5530 5434 */
5531 5435 if ((port_gid.gid_prefix != 0) && (port_gid.gid_guid != 0)) {
5532 5436
5533 5437 /* Get sgid_ix and port number of 'port_gid' */
5534 5438 retval = ibtl_cm_get_hca_port(port_gid, 0, &hport);
5535 5439 if (retval != IBT_SUCCESS) {
5536 5440 IBTF_DPRINTF_L2(cmlog, "ibt_query_mcg: "
5537 5441 "Failed to Get Portinfo for PortGID :"
5538 5442 "status = %d", retval);
5539 5443 return (retval);
5540 5444 }
5541 5445 } else {
5542 5446 /*
5543 5447 * The sgid_ix and port number related to RequestGID
5544 5448 * are already obtained at the beginning.
5545 5449 */
5546 5450 port_gid = rgid;
5547 5451 }
5548 5452
5549 5453 /*
5550 5454 * Allocate memory for return buffer, to be freed in
5551 5455 * ibt_free_mcg_info().
5552 5456 */
5553 5457 mcg_infop = kmem_alloc((num_records * sizeof (ibt_mcg_info_t)),
5554 5458 KM_SLEEP);
5555 5459
5556 5460 *mcgs_info_p = mcg_infop;
5557 5461 *entries_p = num_records;
5558 5462
5559 5463 /* Update the return values. */
5560 5464 for (i = 0; i < num_records; i++) {
5561 5465
5562 5466 mcg_resp = (sa_mcmember_record_t *)((uchar_t *)
5563 5467 results_p + i * sizeof (sa_mcmember_record_t));
5564 5468
5565 5469 mcg_infop[i].mc_adds_vect.av_dgid = mcg_resp->MGID;
5566 5470 mcg_infop[i].mc_adds_vect.av_sgid = port_gid;
5567 5471 mcg_infop[i].mc_adds_vect.av_srate = mcg_resp->Rate;
5568 5472 mcg_infop[i].mc_adds_vect.av_srvl = mcg_resp->SL;
5569 5473 mcg_infop[i].mc_adds_vect.av_flow = mcg_resp->FlowLabel;
5570 5474 mcg_infop[i].mc_adds_vect.av_tclass = mcg_resp->TClass;
5571 5475 mcg_infop[i].mc_adds_vect.av_hop = mcg_resp->HopLimit;
5572 5476 mcg_infop[i].mc_adds_vect.av_port_num = hport.hp_port;
5573 5477 mcg_infop[i].mc_adds_vect.av_send_grh = B_TRUE;
5574 5478 mcg_infop[i].mc_adds_vect.av_dlid = mcg_resp->MLID;
5575 5479 mcg_infop[i].mc_adds_vect.av_sgid_ix = hport.hp_sgid_ix;
5576 5480 mcg_infop[i].mc_adds_vect.av_src_path = 0;
5577 5481 mcg_infop[i].mc_mtu = mcg_resp->MTU;
5578 5482 mcg_infop[i].mc_qkey = mcg_resp->Q_Key;
5579 5483 mcg_infop[i].mc_scope = mcg_resp->Scope;
5580 5484 mcg_infop[i].mc_pkt_lt = mcg_resp->PacketLifeTime;
5581 5485
5582 5486 if (ibt_pkey2index_byguid(hport.hp_hca_guid,
5583 5487 hport.hp_port, mcg_resp->P_Key,
5584 5488 &mcg_infop[i].mc_pkey_ix) != IBT_SUCCESS) {
5585 5489 IBTF_DPRINTF_L3(cmlog, "ibt_query_mcg: "
5586 5490 "Pkey2Index Conversion failed");
5587 5491 mcg_infop[i].mc_pkey_ix = 0;
5588 5492 }
5589 5493 }
5590 5494
5591 5495 /*
5592 5496 * Deallocate the memory allocated by SA for results_p.
5593 5497 */
5594 5498 kmem_free(results_p, length);
5595 5499 retval = IBT_SUCCESS;
5596 5500
5597 5501 IBTF_DPRINTF_L3(cmlog, "ibt_query_mcg: returning %d MCGRecords",
5598 5502 num_records);
5599 5503
5600 5504 } else {
5601 5505 retval = IBT_MCG_RECORDS_NOT_FOUND;
5602 5506 *entries_p = 0;
5603 5507
5604 5508 IBTF_DPRINTF_L3(cmlog, "ibt_query_mcg: MCG RECORDS NOT FOUND");
5605 5509 }
5606 5510
5607 5511 ibcm_dec_hca_acc_cnt(hcap);
5608 5512
5609 5513 return (retval);
5610 5514 }
5611 5515
5612 5516
5613 5517 /*
5614 5518 * ibt_free_mcg_info()
5615 5519 * Free the memory allocated by successful ibt_query_mcg()
5616 5520 *
5617 5521 * mcgs_info Pointer returned by ibt_query_mcg().
5618 5522 *
5619 5523 * entries The number of ibt_mcg_info_t entries to free.
5620 5524 */
5621 5525 void
5622 5526 ibt_free_mcg_info(ibt_mcg_info_t *mcgs_info, uint_t entries)
5623 5527 {
5624 5528 IBTF_DPRINTF_L3(cmlog, "ibt_free_mcg_info: "
5625 5529 "Free <%d> entries from 0x%p", entries, mcgs_info);
5626 5530
5627 5531 if ((mcgs_info != NULL) && (entries > 0))
5628 5532 kmem_free(mcgs_info, entries * sizeof (ibt_mcg_info_t));
5629 5533 else
5630 5534 IBTF_DPRINTF_L2(cmlog, "ibt_free_mcg_info: "
5631 5535 "ERROR: NULL buf pointer or length specified.");
5632 5536 }
5633 5537
5634 5538
5635 5539 /*
5636 5540 * Function:
5637 5541 * ibt_gid_to_node_info()
5638 5542 * Input:
5639 5543 * gid Identifies the IB Node and port for which to obtain
5640 5544 * Node information.
5641 5545 * Output:
5642 5546 * node_info_p A pointer to an ibt_node_info_t structure (allocated
5643 5547 * by the caller) in which to return the node information.
5644 5548 * Returns:
5645 5549 * IBT_SUCCESS
5646 5550 * IBT_INVALID_PARAM
5647 5551 * IBT_NODE_RECORDS_NOT_FOUND
5648 5552 * IBT_NO_HCAS_AVAILABLE
5649 5553 * Description:
5650 5554 * Retrieve Node Information for the specified GID.
5651 5555 */
5652 5556 ibt_status_t
5653 5557 ibt_gid_to_node_info(ib_gid_t gid, ibt_node_info_t *node_info_p)
5654 5558 {
5655 5559 sa_node_record_t nr_req, *nr_resp;
5656 5560 ibmf_saa_handle_t saa_handle;
5657 5561 ibt_status_t retval;
5658 5562 ibcm_hca_info_t *hcap;
5659 5563 ibtl_cm_hca_port_t hport;
5660 5564 int i, j;
5661 5565 uint_t num_rec;
5662 5566 ib_guid_t *guid_array = NULL;
5663 5567 sa_path_record_t *path;
5664 5568 size_t len;
5665 5569 uint8_t npaths;
5666 5570 uint32_t num_hcas = 0;
5667 5571 ib_lid_t node_lid;
5668 5572 boolean_t local_node = B_FALSE;
5669 5573 void *res_p;
5670 5574 uint8_t num_ports = 0;
5671 5575
5672 5576
5673 5577 IBTF_DPRINTF_L4(cmlog, "ibt_gid_to_node_info(%llX:%llX, %p)",
5674 5578 gid.gid_prefix, gid.gid_guid, node_info_p);
5675 5579
5676 5580 if ((gid.gid_prefix == 0) || (gid.gid_guid == 0)) {
5677 5581 IBTF_DPRINTF_L2(cmlog, "ibt_gid_to_node_info: GID is required");
5678 5582 return (IBT_INVALID_PARAM);
5679 5583 }
5680 5584
5681 5585 if (node_info_p == NULL) {
5682 5586 IBTF_DPRINTF_L2(cmlog, "ibt_gid_to_node_info: "
5683 5587 "Return Buf (node_info_p) is NULL.");
5684 5588 return (IBT_INVALID_PARAM);
5685 5589 }
5686 5590
5687 5591 /*
5688 5592 * If 'gid' is on local node, then get node lid (i.e. base lid of the
5689 5593 * associated port) info via ibtl_cm_get_hca_port() call.
5690 5594 */
5691 5595 bzero(&hport, sizeof (ibtl_cm_hca_port_t));
5692 5596 if (ibtl_cm_get_hca_port(gid, 0, &hport) == IBT_SUCCESS) {
5693 5597
5694 5598 hcap = ibcm_find_hca_entry(hport.hp_hca_guid);
5695 5599 if (hcap == NULL) {
5696 5600 IBTF_DPRINTF_L3(cmlog, "ibt_gid_to_node_info: "
5697 5601 "HCA(%llX) info not found", hport.hp_hca_guid);
5698 5602 return (IBT_NO_HCAS_AVAILABLE);
5699 5603 }
5700 5604 num_ports = 1;
5701 5605 num_hcas = 1;
5702 5606 node_lid = hport.hp_base_lid;
5703 5607 local_node = B_TRUE;
5704 5608 IBTF_DPRINTF_L4(cmlog, "ibt_gid_to_node_info: Local Node: "
5705 5609 "LID = 0x%X", node_lid);
5706 5610 } else {
5707 5611 /* Get the number of HCAs and their GUIDs */
5708 5612 num_hcas = ibt_get_hca_list(&guid_array);
5709 5613 IBTF_DPRINTF_L4(cmlog, "ibt_gid_to_node_info: ibt_get_hca_list "
5710 5614 "returned %d hcas", num_hcas);
5711 5615
5712 5616 if (num_hcas == 0) {
5713 5617 IBTF_DPRINTF_L2(cmlog, "ibt_gid_to_node_info: "
5714 5618 "NO HCA's Found on this system");
5715 5619 return (IBT_NO_HCAS_AVAILABLE);
5716 5620 }
5717 5621 }
5718 5622
5719 5623 for (i = 0; i < num_hcas; i++) {
5720 5624 if (local_node == B_FALSE) {
5721 5625 hcap = ibcm_find_hca_entry(guid_array[i]);
5722 5626 if (hcap == NULL) {
5723 5627 IBTF_DPRINTF_L3(cmlog, "ibt_gid_to_node_info: "
5724 5628 "HCA(%llX) info not found", guid_array[i]);
5725 5629 retval = IBT_NO_HCAS_AVAILABLE;
5726 5630 continue;
5727 5631 }
5728 5632 num_ports = hcap->hca_num_ports;
5729 5633 }
5730 5634
5731 5635 for (j = 0; j < num_ports; j++) {
5732 5636 uint8_t port = 0;
5733 5637
5734 5638 if (local_node == B_TRUE)
5735 5639 port = hport.hp_port;
5736 5640 else
5737 5641 port = j + 1;
5738 5642
5739 5643 /* Get SA Access Handle. */
5740 5644 saa_handle = ibcm_get_saa_handle(hcap, port);
5741 5645 if (saa_handle == NULL) {
5742 5646 IBTF_DPRINTF_L3(cmlog, "ibt_gid_to_node_info: "
5743 5647 "Port %d of HCA (%llX) is NOT ACTIVE",
5744 5648 port, hport.hp_hca_guid);
5745 5649 retval = IBT_NODE_RECORDS_NOT_FOUND;
5746 5650 continue;
5747 5651 }
5748 5652
5749 5653 if (local_node == B_FALSE) {
5750 5654 ib_gid_t sgid;
5751 5655 int sa_ret;
5752 5656
5753 5657 /*
5754 5658 * Check whether 'gid' and this port has same
5755 5659 * subnet prefix. If not, then there is no use
5756 5660 * in searching from this port.
5757 5661 */
5758 5662 sgid = hcap->hca_port_info[j].port_sgid0;
5759 5663 if (gid.gid_prefix != sgid.gid_prefix) {
5760 5664 IBTF_DPRINTF_L3(cmlog,
5761 5665 "ibt_gid_to_node_info:Sn_Prefix of "
5762 5666 "GID(%llX) and Port's(%llX) differ",
5763 5667 gid.gid_prefix, sgid.gid_prefix);
5764 5668 retval = IBT_NODE_RECORDS_NOT_FOUND;
5765 5669 continue;
5766 5670 }
5767 5671
5768 5672 /*
5769 5673 * First Get Path Records for the specified DGID
5770 5674 * from this port (SGID). From Path Records,
5771 5675 * note down DLID, then use this DLID as Input
5772 5676 * attribute to get NodeRecords from SA Access.
5773 5677 */
5774 5678 npaths = 1;
5775 5679 path = NULL;
5776 5680
5777 5681 sa_ret = ibmf_saa_gid_to_pathrecords(saa_handle,
5778 5682 sgid, gid, 0, 0, B_TRUE, &npaths, 0, &len,
5779 5683 &path);
5780 5684 if (sa_ret != IBMF_SUCCESS) {
5781 5685 IBTF_DPRINTF_L2(cmlog,
5782 5686 "ibt_gid_to_node_info: "
5783 5687 "ibmf_saa_gid_to_pathrecords() "
5784 5688 "returned error: %d ", sa_ret);
5785 5689 retval =
5786 5690 ibcm_ibmf_analyze_error(sa_ret);
5787 5691 continue;
5788 5692 } else if ((npaths == 0) || (path == NULL)) {
5789 5693 IBTF_DPRINTF_L3(cmlog,
5790 5694 "ibt_gid_to_node_info: failed (%d) "
5791 5695 "to get path records for the DGID "
5792 5696 "0x%llX from SGID 0x%llX", sa_ret,
5793 5697 gid.gid_guid, sgid.gid_guid);
5794 5698 retval = IBT_NODE_RECORDS_NOT_FOUND;
5795 5699 continue;
5796 5700 }
5797 5701 node_lid = path->DLID; /* LID */
5798 5702
5799 5703 IBTF_DPRINTF_L3(cmlog, "ibt_gid_to_node_info: "
5800 5704 "Remote Node: LID = 0x%X", node_lid);
5801 5705
5802 5706 /* Free SA_Access memory for path record. */
5803 5707 kmem_free(path, len);
5804 5708 }
5805 5709
5806 5710 /* Retrieve Node Records from SA Access. */
5807 5711 bzero(&nr_req, sizeof (sa_node_record_t));
5808 5712
5809 5713 nr_req.LID = node_lid; /* LID */
5810 5714
5811 5715 retval = ibcm_get_node_rec(saa_handle, &nr_req,
5812 5716 SA_NODEINFO_COMPMASK_NODELID, &res_p, &len);
5813 5717 if (retval == IBT_NODE_RECORDS_NOT_FOUND) {
5814 5718 IBTF_DPRINTF_L2(cmlog, "ibt_gid_to_node_info: "
5815 5719 "failed (%d) to get Node records", retval);
5816 5720 continue;
5817 5721 } else if (retval != IBT_SUCCESS) {
5818 5722 IBTF_DPRINTF_L2(cmlog, "ibt_gid_to_node_info: "
5819 5723 "failed (%d) to get Node records", retval);
5820 5724 ibcm_dec_hca_acc_cnt(hcap);
5821 5725 goto gid_to_ni_exit;
↓ open down ↓ |
916 lines elided |
↑ open up ↑ |
5822 5726 }
5823 5727
5824 5728 num_rec = len/sizeof (sa_node_record_t);
5825 5729 nr_resp = (sa_node_record_t *)(uchar_t *)res_p;
5826 5730
5827 5731 /* Validate the returned number of records. */
5828 5732 if ((nr_resp != NULL) && (num_rec > 0)) {
5829 5733
5830 5734 IBCM_DUMP_NODE_REC(nr_resp);
5831 5735
5832 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(
5833 - *node_info_p))
5834 -
5835 5736 node_info_p->n_sys_img_guid =
5836 5737 nr_resp->NodeInfo.SystemImageGUID;
5837 5738 node_info_p->n_node_guid =
5838 5739 nr_resp->NodeInfo.NodeGUID;
5839 5740 node_info_p->n_port_guid =
5840 5741 nr_resp->NodeInfo.PortGUID;
5841 5742 node_info_p->n_dev_id =
5842 5743 nr_resp->NodeInfo.DeviceID;
5843 5744 node_info_p->n_revision =
5844 5745 nr_resp->NodeInfo.Revision;
5845 5746 node_info_p->n_vendor_id =
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
5846 5747 nr_resp->NodeInfo.VendorID;
5847 5748 node_info_p->n_num_ports =
5848 5749 nr_resp->NodeInfo.NumPorts;
5849 5750 node_info_p->n_port_num =
5850 5751 nr_resp->NodeInfo.LocalPortNum;
5851 5752 node_info_p->n_node_type =
5852 5753 nr_resp->NodeInfo.NodeType;
5853 5754 (void) strncpy(node_info_p->n_description,
5854 5755 (char *)&nr_resp->NodeDescription, 64);
5855 5756
5856 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(
5857 - *node_info_p))
5858 -
5859 5757 /*
5860 5758 * Deallocate the memory allocated by SA for
5861 5759 * 'nr_resp'.
5862 5760 */
5863 5761 ibcm_dec_hca_acc_cnt(hcap);
5864 5762 kmem_free(nr_resp, len);
5865 5763 retval = IBT_SUCCESS;
5866 5764
5867 5765 goto gid_to_ni_exit;
5868 5766 } else {
5869 5767 retval = IBT_NODE_RECORDS_NOT_FOUND;
5870 5768 IBTF_DPRINTF_L3(cmlog, "ibt_gid_to_node_info: "
5871 5769 "Node Records NOT found - PortGUID %016llX",
5872 5770 gid.gid_guid);
5873 5771 }
5874 5772 }
5875 5773 ibcm_dec_hca_acc_cnt(hcap);
5876 5774
5877 5775 if (local_node == B_TRUE)
5878 5776 break;
5879 5777 }
5880 5778
5881 5779 gid_to_ni_exit:
5882 5780 if (guid_array)
5883 5781 ibt_free_hca_list(guid_array, num_hcas);
5884 5782
5885 5783 IBTF_DPRINTF_L3(cmlog, "ibt_gid_to_node_info: done. Status %d", retval);
5886 5784
5887 5785 return (retval);
5888 5786 }
5889 5787
5890 5788
5891 5789 ibt_status_t
5892 5790 ibcm_get_node_rec(ibmf_saa_handle_t saa_handle, sa_node_record_t *nr_req,
5893 5791 uint64_t component_mask, void *result_p, size_t *len)
5894 5792 {
5895 5793 ibmf_saa_access_args_t args;
5896 5794 size_t length;
5897 5795 ibt_status_t retval;
5898 5796
5899 5797 args.sq_attr_id = SA_NODERECORD_ATTRID;
5900 5798 args.sq_template = nr_req;
5901 5799 args.sq_access_type = IBMF_SAA_RETRIEVE;
5902 5800 args.sq_template_length = sizeof (sa_node_record_t);
5903 5801 args.sq_component_mask = component_mask;
5904 5802 args.sq_callback = NULL;
5905 5803 args.sq_callback_arg = NULL;
5906 5804
5907 5805 retval = ibcm_contact_sa_access(saa_handle, &args, &length, result_p);
5908 5806 if (retval != IBT_SUCCESS) {
5909 5807 IBTF_DPRINTF_L2(cmlog, "ibcm_get_node_rec: SA Call Failed");
5910 5808 return (retval);
5911 5809 }
5912 5810
5913 5811 *len = length;
5914 5812
5915 5813 /* Validate the returned number of records. */
5916 5814 if ((result_p != NULL) && (length > 0)) {
5917 5815 IBTF_DPRINTF_L3(cmlog, "ibcm_get_node_rec: Node Records FOUND");
5918 5816
5919 5817 /* Got it, done!. */
5920 5818 return (IBT_SUCCESS);
5921 5819 } else {
5922 5820 IBTF_DPRINTF_L2(cmlog, "ibcm_get_node_rec: Node Rec NOT found");
5923 5821 return (IBT_NODE_RECORDS_NOT_FOUND);
5924 5822 }
5925 5823 }
5926 5824
5927 5825
5928 5826 /*
5929 5827 * Function:
5930 5828 * ibt_lid_to_node_info()
5931 5829 * Input:
5932 5830 * lid Identifies the IB Node and port for which to obtain
5933 5831 * Node information.
5934 5832 * Output:
5935 5833 * node_info_p A pointer to an ibt_node_info_t structure (allocated
5936 5834 * by the caller) in which to return the node information.
5937 5835 * Returns:
5938 5836 * IBT_SUCCESS
5939 5837 * IBT_INVALID_PARAM
5940 5838 * IBT_NODE_RECORDS_NOT_FOUND
5941 5839 * IBT_NO_HCAS_AVAILABLE
5942 5840 * Description:
5943 5841 * Retrieve Node Information for the specified LID.
5944 5842 */
5945 5843 ibt_status_t
5946 5844 ibt_lid_to_node_info(ib_lid_t lid, ibt_node_info_t *node_info_p)
5947 5845 {
5948 5846 ibt_status_t retval;
5949 5847 ibcm_hca_info_t *hcap;
5950 5848 uint8_t i, j;
5951 5849 ib_guid_t *guid_array = NULL;
5952 5850 uint_t num_hcas = 0;
5953 5851
5954 5852
5955 5853 IBTF_DPRINTF_L4(cmlog, "ibt_lid_to_node_info(0x%lX, %p)",
5956 5854 lid, node_info_p);
5957 5855
5958 5856 if ((lid == 0) || (node_info_p == NULL)) {
5959 5857 IBTF_DPRINTF_L2(cmlog, "ibt_lid_to_node_info: "
5960 5858 "Lid is zero, or node_info_p is NULL.");
5961 5859 return (IBT_INVALID_PARAM);
5962 5860 }
5963 5861
5964 5862 /* Get the number of HCAs and their GUIDs */
5965 5863 num_hcas = ibt_get_hca_list(&guid_array);
5966 5864 IBTF_DPRINTF_L4(cmlog, "ibt_lid_to_node_info: ibt_get_hca_list "
5967 5865 "returned %d hcas", num_hcas);
5968 5866
5969 5867 if (num_hcas == 0) {
5970 5868 IBTF_DPRINTF_L2(cmlog, "ibt_lid_to_node_info: "
5971 5869 "NO HCA's Found on this system");
5972 5870 return (IBT_NO_HCAS_AVAILABLE);
5973 5871 }
5974 5872
5975 5873 for (i = 0; i < num_hcas; i++) {
5976 5874 hcap = ibcm_find_hca_entry(guid_array[i]);
5977 5875 if (hcap == NULL) {
5978 5876 IBTF_DPRINTF_L3(cmlog, "ibt_lid_to_node_info: "
5979 5877 "HCA(%llX) info not found", guid_array[i]);
5980 5878 retval = IBT_NO_HCAS_AVAILABLE;
5981 5879 continue;
5982 5880 }
5983 5881
5984 5882 for (j = 0; j < hcap->hca_num_ports; j++) {
5985 5883 uint8_t port;
5986 5884 ibmf_saa_handle_t saa_handle;
5987 5885 uint_t num_rec;
5988 5886 size_t len;
5989 5887 void *res_p;
5990 5888 sa_node_record_t nr_req, *nr_resp;
5991 5889
5992 5890 port = j + 1;
5993 5891
5994 5892 /* Get SA Access Handle. */
5995 5893 saa_handle = ibcm_get_saa_handle(hcap, port);
5996 5894 if (saa_handle == NULL) {
5997 5895 IBTF_DPRINTF_L3(cmlog, "ibt_lid_to_node_info: "
5998 5896 "Port %d of HCA (%llX) is NOT ACTIVE",
5999 5897 port, guid_array[i]);
6000 5898 retval = IBT_NODE_RECORDS_NOT_FOUND;
6001 5899 continue;
6002 5900 }
6003 5901
6004 5902 /* Retrieve Node Records from SA Access. */
6005 5903 bzero(&nr_req, sizeof (sa_node_record_t));
6006 5904
6007 5905 nr_req.LID = lid; /* LID */
6008 5906
6009 5907 retval = ibcm_get_node_rec(saa_handle, &nr_req,
6010 5908 SA_NODEINFO_COMPMASK_NODELID, &res_p, &len);
6011 5909 if (retval == IBT_NODE_RECORDS_NOT_FOUND) {
6012 5910 IBTF_DPRINTF_L2(cmlog, "ibt_lid_to_node_info: "
6013 5911 "failed (%d) to get Node records", retval);
6014 5912 continue;
6015 5913 } else if (retval != IBT_SUCCESS) {
6016 5914 IBTF_DPRINTF_L2(cmlog, "ibt_lid_to_node_info: "
6017 5915 "failed (%d) to get Node records", retval);
6018 5916 ibcm_dec_hca_acc_cnt(hcap);
6019 5917 goto lid_to_ni_exit;
↓ open down ↓ |
151 lines elided |
↑ open up ↑ |
6020 5918 }
6021 5919
6022 5920 num_rec = len/sizeof (sa_node_record_t);
6023 5921 nr_resp = (sa_node_record_t *)(uchar_t *)res_p;
6024 5922
6025 5923 /* Validate the returned number of records. */
6026 5924 if ((nr_resp != NULL) && (num_rec > 0)) {
6027 5925
6028 5926 IBCM_DUMP_NODE_REC(nr_resp);
6029 5927
6030 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(
6031 - *node_info_p))
6032 -
6033 5928 node_info_p->n_sys_img_guid =
6034 5929 nr_resp->NodeInfo.SystemImageGUID;
6035 5930 node_info_p->n_node_guid =
6036 5931 nr_resp->NodeInfo.NodeGUID;
6037 5932 node_info_p->n_port_guid =
6038 5933 nr_resp->NodeInfo.PortGUID;
6039 5934 node_info_p->n_dev_id =
6040 5935 nr_resp->NodeInfo.DeviceID;
6041 5936 node_info_p->n_revision =
6042 5937 nr_resp->NodeInfo.Revision;
6043 5938 node_info_p->n_vendor_id =
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
6044 5939 nr_resp->NodeInfo.VendorID;
6045 5940 node_info_p->n_num_ports =
6046 5941 nr_resp->NodeInfo.NumPorts;
6047 5942 node_info_p->n_port_num =
6048 5943 nr_resp->NodeInfo.LocalPortNum;
6049 5944 node_info_p->n_node_type =
6050 5945 nr_resp->NodeInfo.NodeType;
6051 5946 (void) strncpy(node_info_p->n_description,
6052 5947 (char *)&nr_resp->NodeDescription, 64);
6053 5948
6054 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(
6055 - *node_info_p))
6056 -
6057 5949 /*
6058 5950 * Deallocate the memory allocated by SA for
6059 5951 * 'nr_resp'.
6060 5952 */
6061 5953 ibcm_dec_hca_acc_cnt(hcap);
6062 5954 kmem_free(nr_resp, len);
6063 5955 retval = IBT_SUCCESS;
6064 5956
6065 5957 goto lid_to_ni_exit;
6066 5958 } else {
6067 5959 retval = IBT_NODE_RECORDS_NOT_FOUND;
6068 5960 IBTF_DPRINTF_L3(cmlog, "ibt_lid_to_node_info: "
6069 5961 "Node Records NOT found - LID 0x%lX",
6070 5962 lid);
6071 5963 }
6072 5964 }
6073 5965 ibcm_dec_hca_acc_cnt(hcap);
6074 5966 }
6075 5967
6076 5968 lid_to_ni_exit:
6077 5969 if (guid_array)
6078 5970 ibt_free_hca_list(guid_array, num_hcas);
6079 5971
6080 5972 IBTF_DPRINTF_L3(cmlog, "ibt_lid_to_node_info: done. Status %d", retval);
6081 5973
6082 5974 return (retval);
6083 5975 }
6084 5976
6085 5977 /*
6086 5978 * Function:
6087 5979 * ibt_get_companion_port_gids()
6088 5980 * Description:
6089 5981 * Get list of GID's available on a companion port(s) of the specified
6090 5982 * GID or list of GIDs available on a specified Node GUID/SystemImage GUID.
6091 5983 */
6092 5984 ibt_status_t
6093 5985 ibt_get_companion_port_gids(ib_gid_t gid, ib_guid_t hca_guid,
6094 5986 ib_guid_t sysimg_guid, ib_gid_t **gids_p, uint_t *num_gids_p)
6095 5987 {
6096 5988 sa_node_record_t nr_req, *nr_resp;
6097 5989 void *res_p;
6098 5990 ibmf_saa_handle_t saa_handle;
6099 5991 int sa_ret;
6100 5992 ibt_status_t retval = IBT_SUCCESS;
6101 5993 ibcm_hca_info_t *hcap;
6102 5994 ibtl_cm_hca_port_t hport;
6103 5995 int i, j;
6104 5996 uint_t num_rec;
6105 5997 ib_guid_t *guid_array = NULL;
6106 5998 sa_path_record_t *path;
6107 5999 size_t len;
6108 6000 uint8_t npaths;
6109 6001 uint32_t num_hcas = 0;
6110 6002 boolean_t local_node = B_FALSE;
6111 6003 boolean_t local_hca = B_FALSE;
6112 6004 ib_guid_t h_guid = hca_guid;
6113 6005 ib_gid_t *gidp = NULL, *t_gidp = NULL;
6114 6006 int multi_hca_loop = 0;
6115 6007
6116 6008 IBTF_DPRINTF_L4(cmlog, "ibt_get_companion_port_gids(%llX:%llX, %llX, "
6117 6009 "%llX)", gid.gid_prefix, gid.gid_guid, hca_guid, sysimg_guid);
6118 6010
6119 6011 if (((gid.gid_prefix == 0) || (gid.gid_guid == 0)) && (hca_guid == 0) &&
6120 6012 (sysimg_guid == 0)) {
6121 6013 IBTF_DPRINTF_L2(cmlog, "ibt_get_companion_port_gids: "
6122 6014 "Null Input attribute specified.");
6123 6015 return (IBT_INVALID_PARAM);
6124 6016 }
6125 6017
6126 6018 if ((num_gids_p == NULL) || (gids_p == NULL)) {
6127 6019 IBTF_DPRINTF_L2(cmlog, "ibt_get_companion_port_gids: "
6128 6020 "num_gids_p or gids_p is NULL");
6129 6021 return (IBT_INVALID_PARAM);
6130 6022 }
6131 6023
6132 6024 *num_gids_p = 0;
6133 6025
6134 6026 /* Get the number of HCAs and their GUIDs */
6135 6027 if ((num_hcas = ibt_get_hca_list(&guid_array)) == 0) {
6136 6028 IBTF_DPRINTF_L2(cmlog, "ibt_get_companion_port_gids: "
6137 6029 "NO HCA's Found on this system");
6138 6030 return (IBT_NO_HCAS_AVAILABLE);
6139 6031 }
6140 6032
6141 6033 IBTF_DPRINTF_L4(cmlog, "ibt_get_companion_port_gids: "
6142 6034 "ibt_get_hca_list() returned %d hcas", num_hcas);
6143 6035
6144 6036 /*
6145 6037 * If 'gid' is on local node, then get node lid (i.e. base lid of the
6146 6038 * associated port) info via ibtl_cm_get_hca_port() call.
6147 6039 */
6148 6040 bzero(&hport, sizeof (ibtl_cm_hca_port_t));
6149 6041 if ((gid.gid_prefix != 0) && (gid.gid_guid != 0) &&
6150 6042 (ibtl_cm_get_hca_port(gid, 0, &hport) == IBT_SUCCESS)) {
6151 6043
6152 6044 if ((hca_guid != 0) && (hca_guid != hport.hp_hca_guid)) {
6153 6045 IBTF_DPRINTF_L2(cmlog, "ibt_get_companion_port_gids: "
6154 6046 "Invalid GID<->HCAGUID combination specified.");
6155 6047 retval = IBT_INVALID_PARAM;
6156 6048 goto get_comp_pgid_exit;
6157 6049 }
6158 6050 h_guid = hport.hp_hca_guid;
6159 6051 local_node = B_TRUE;
6160 6052
6161 6053 IBTF_DPRINTF_L4(cmlog, "ibt_get_companion_port_gids: "
6162 6054 "Local Node: HCA (0x%llX)", h_guid);
6163 6055 } else if (h_guid) { /* Is specified HCA GUID - local? */
6164 6056 for (i = 0; i < num_hcas; i++) {
6165 6057 if (h_guid == guid_array[i]) {
6166 6058 local_hca = B_TRUE;
6167 6059 break;
6168 6060 }
6169 6061 }
6170 6062 } else if (sysimg_guid) { /* Is specified SystemImage GUID - local? */
6171 6063 for (i = 0; i < num_hcas; i++) {
6172 6064 ibt_status_t ret;
6173 6065 ibt_hca_attr_t hca_attr;
6174 6066
6175 6067 ret = ibt_query_hca_byguid(guid_array[i], &hca_attr);
6176 6068 if (ret != IBT_SUCCESS) {
6177 6069 IBTF_DPRINTF_L2(cmlog,
6178 6070 "ibt_get_companion_port_gids: HCA(%llX) "
6179 6071 "info not found", guid_array[i]);
6180 6072 retval = IBT_NO_HCAS_AVAILABLE;
6181 6073 continue;
6182 6074 }
6183 6075 if (hca_attr.hca_si_guid == sysimg_guid) {
6184 6076 if ((hca_guid != 0) &&
6185 6077 (hca_guid != hca_attr.hca_node_guid)) {
6186 6078 IBTF_DPRINTF_L2(cmlog,
6187 6079 "ibt_get_companion_port_gids: "
6188 6080 "Invalid SysImg<->HCA GUID "
6189 6081 "combination specified.");
6190 6082 retval = IBT_INVALID_PARAM;
6191 6083 goto get_comp_pgid_exit;
6192 6084 }
6193 6085 local_hca = B_TRUE;
6194 6086 h_guid = hca_attr.hca_node_guid;
6195 6087 break;
6196 6088 }
6197 6089 }
6198 6090 }
6199 6091
6200 6092 if ((local_node == B_TRUE) || (local_hca == B_TRUE)) {
6201 6093 retval = ibtl_cm_get_local_comp_gids(h_guid, gid, gids_p,
6202 6094 num_gids_p);
6203 6095 goto get_comp_pgid_exit;
6204 6096 }
6205 6097
6206 6098 get_comp_for_multihca:
6207 6099 /* We will be here, if request is for remote node */
6208 6100 for (i = 0; i < num_hcas; i++) {
6209 6101 int multism;
6210 6102 uint_t count = 0;
6211 6103 int multi_sm_loop = 0;
6212 6104 uint_t k = 0, l;
6213 6105
6214 6106 hcap = ibcm_find_hca_entry(guid_array[i]);
6215 6107 if (hcap == NULL) {
6216 6108 IBTF_DPRINTF_L3(cmlog, "ibt_get_companion_port_gids: "
6217 6109 "HCA(%llX) info not found", guid_array[i]);
6218 6110 retval = IBT_NO_HCAS_AVAILABLE;
6219 6111 continue;
6220 6112 }
6221 6113
6222 6114 /* 1 - MultiSM, 0 - Single SM */
6223 6115 multism = ibtl_cm_is_multi_sm(guid_array[i]);
6224 6116
6225 6117 for (j = 0; j < hcap->hca_num_ports; j++) {
6226 6118 ib_gid_t sgid;
6227 6119 uint64_t c_mask = 0;
6228 6120 ib_guid_t pg;
6229 6121 uint_t port = j;
6230 6122
6231 6123 get_comp_for_multism:
6232 6124 IBTF_DPRINTF_L3(cmlog, "ibt_get_companion_port_gids: "
6233 6125 "Port %d, HCA %llX, MultiSM= %d, Loop=%d",
6234 6126 port + 1, h_guid, multism, multi_sm_loop);
6235 6127
6236 6128 /* Get SA Access Handle. */
6237 6129 saa_handle = ibcm_get_saa_handle(hcap, port + 1);
6238 6130 if (saa_handle == NULL) {
6239 6131 IBTF_DPRINTF_L2(cmlog,
6240 6132 "ibt_get_companion_port_gids: "
6241 6133 "Port (%d) - NOT ACTIVE", port + 1);
6242 6134 retval = IBT_GIDS_NOT_FOUND;
6243 6135 continue;
6244 6136 }
6245 6137
6246 6138 /*
6247 6139 * Check whether 'gid' and this port has same subnet
6248 6140 * prefix. If not, then there is no use in searching
6249 6141 * from this port.
6250 6142 */
6251 6143 sgid = hcap->hca_port_info[port].port_sgid0;
6252 6144 if ((h_guid == 0) && (gid.gid_prefix != 0) &&
6253 6145 (multi_sm_loop == 0) &&
6254 6146 (gid.gid_prefix != sgid.gid_prefix)) {
6255 6147 IBTF_DPRINTF_L2(cmlog,
6256 6148 "ibt_get_companion_port_gids: SnPrefix of "
6257 6149 "GID(%llX) and Port SN_Pfx(%llX) differ",
6258 6150 gid.gid_prefix, sgid.gid_prefix);
6259 6151 retval = IBT_GIDS_NOT_FOUND;
6260 6152 continue;
6261 6153 }
6262 6154
6263 6155 /*
6264 6156 * If HCA GUID or System Image GUID is specified, then
6265 6157 * we can achieve our goal sooner!.
6266 6158 */
6267 6159 if ((h_guid == 0) && (sysimg_guid == 0)) {
6268 6160 /* So only GID info is provided. */
6269 6161
6270 6162 /*
6271 6163 * First Get Path Records for the specified DGID
6272 6164 * from this port (SGID). From Path Records,
6273 6165 * note down DLID, then use this DLID as Input
6274 6166 * attribute to get NodeRecords.
6275 6167 */
6276 6168 npaths = 1;
6277 6169 path = NULL;
6278 6170
6279 6171 sa_ret = ibmf_saa_gid_to_pathrecords(saa_handle,
6280 6172 sgid, gid, 0, 0, B_TRUE, &npaths, 0, &len,
6281 6173 &path);
6282 6174 if (sa_ret != IBMF_SUCCESS) {
6283 6175 IBTF_DPRINTF_L2(cmlog,
6284 6176 "ibt_get_companion_port_gids: "
6285 6177 "ibmf_saa_gid_to_pathrecords() "
6286 6178 "returned error: %d ", sa_ret);
6287 6179 retval =
6288 6180 ibcm_ibmf_analyze_error(sa_ret);
6289 6181 ibcm_dec_hca_acc_cnt(hcap);
6290 6182 goto get_comp_pgid_exit;
6291 6183 } else if ((npaths == 0) || (path == NULL)) {
6292 6184 IBTF_DPRINTF_L2(cmlog,
6293 6185 "ibt_get_companion_port_gids: "
6294 6186 "failed (%d) to get path records "
6295 6187 "for the DGID (0x%llX) from SGID "
6296 6188 "(0x%llX)", sa_ret, gid.gid_guid,
6297 6189 sgid.gid_guid);
6298 6190 retval = IBT_GIDS_NOT_FOUND;
6299 6191 continue;
6300 6192 }
6301 6193
6302 6194 bzero(&nr_req, sizeof (sa_node_record_t));
6303 6195 nr_req.LID = path->DLID; /* LID */
6304 6196
6305 6197 IBTF_DPRINTF_L3(cmlog,
6306 6198 "ibt_get_companion_port_gids: "
6307 6199 "Remote Node: LID = 0x%X", nr_req.LID);
6308 6200
6309 6201 /* Free SA_Access memory for path record. */
6310 6202 kmem_free(path, len);
6311 6203
6312 6204 IBTF_DPRINTF_L3(cmlog,
6313 6205 "ibt_get_companion_port_gids: SAA Call: "
6314 6206 "based on LID ");
6315 6207
6316 6208 retval = ibcm_get_node_rec(saa_handle, &nr_req,
6317 6209 SA_NODEINFO_COMPMASK_NODELID, &res_p, &len);
6318 6210 if (retval == IBT_NODE_RECORDS_NOT_FOUND) {
6319 6211 IBTF_DPRINTF_L2(cmlog,
6320 6212 "ibt_get_companion_port_gids: "
6321 6213 "failed (%d) to get Node records",
6322 6214 retval);
6323 6215 continue;
6324 6216 } else if (retval != IBT_SUCCESS) {
6325 6217 IBTF_DPRINTF_L2(cmlog,
6326 6218 "ibt_get_companion_port_gids: "
6327 6219 "failed (%d) to get Node records",
6328 6220 retval);
6329 6221 ibcm_dec_hca_acc_cnt(hcap);
6330 6222 goto get_comp_pgid_exit;
6331 6223 }
6332 6224
6333 6225 nr_resp = (sa_node_record_t *)(uchar_t *)res_p;
6334 6226 /* Note down HCA GUID info. */
6335 6227 h_guid = nr_resp->NodeInfo.NodeGUID;
6336 6228
6337 6229 IBTF_DPRINTF_L3(cmlog,
6338 6230 "ibt_get_companion_port_gids: "
6339 6231 "Remote HCA GUID: 0x%llX", h_guid);
6340 6232
6341 6233 IBCM_DUMP_NODE_REC(nr_resp);
6342 6234
6343 6235 kmem_free(res_p, len);
6344 6236 }
6345 6237
6346 6238 bzero(&nr_req, sizeof (sa_node_record_t));
6347 6239 if (h_guid != 0) {
6348 6240 nr_req.NodeInfo.NodeGUID = h_guid;
6349 6241 c_mask = SA_NODEINFO_COMPMASK_NODEGUID;
6350 6242 }
6351 6243
6352 6244 if (sysimg_guid != 0) {
6353 6245 nr_req.NodeInfo.SystemImageGUID = sysimg_guid;
6354 6246 c_mask |= SA_NODEINFO_COMPMASK_SYSIMAGEGUID;
6355 6247 }
6356 6248
6357 6249 IBTF_DPRINTF_L3(cmlog, "ibt_get_companion_port_gids: "
6358 6250 "SAA Call: CMASK= 0x%llX", c_mask);
6359 6251
6360 6252 retval = ibcm_get_node_rec(saa_handle, &nr_req, c_mask,
6361 6253 &res_p, &len);
6362 6254 if (retval == IBT_NODE_RECORDS_NOT_FOUND) {
6363 6255 IBTF_DPRINTF_L3(cmlog,
6364 6256 "ibt_get_companion_port_gids: "
6365 6257 "failed (%d) to get Node records", retval);
6366 6258 continue;
6367 6259 } else if (retval != IBT_SUCCESS) {
6368 6260 IBTF_DPRINTF_L2(cmlog,
6369 6261 "ibt_get_companion_port_gids: Error: (%d) "
6370 6262 "while getting Node records", retval);
6371 6263 ibcm_dec_hca_acc_cnt(hcap);
6372 6264 goto get_comp_pgid_exit;
6373 6265 }
6374 6266
6375 6267 num_rec = len/sizeof (sa_node_record_t);
6376 6268
6377 6269 /* We will be here, only if we found some NodeRec */
6378 6270 if (gid.gid_prefix && gid.gid_guid) {
6379 6271 nr_resp = (sa_node_record_t *)res_p;
6380 6272 for (l = 0; l < num_rec; l++, nr_resp++) {
6381 6273 pg = nr_resp->NodeInfo.PortGUID;
6382 6274 if (gid.gid_guid != pg)
6383 6275 count++;
6384 6276 }
6385 6277 } else {
6386 6278 count = num_rec;
6387 6279 }
6388 6280
6389 6281 if (count != 0) {
6390 6282 if (multi_sm_loop == 1) {
6391 6283 count += k;
6392 6284 t_gidp = kmem_zalloc(count *
6393 6285 sizeof (ib_gid_t), KM_SLEEP);
6394 6286
6395 6287 if ((k != 0) && (gidp != NULL)) {
6396 6288 bcopy(gidp, t_gidp,
6397 6289 k * sizeof (ib_gid_t));
6398 6290 kmem_free(gidp,
6399 6291 k * sizeof (ib_gid_t));
6400 6292 }
6401 6293 gidp = t_gidp;
6402 6294 } else {
6403 6295 gidp = kmem_zalloc(count *
6404 6296 sizeof (ib_gid_t), KM_SLEEP);
6405 6297 }
6406 6298 *num_gids_p = count;
6407 6299 *gids_p = gidp;
6408 6300
6409 6301 nr_resp = (sa_node_record_t *)res_p;
6410 6302 for (l = 0; l < num_rec; l++, nr_resp++) {
6411 6303 IBCM_DUMP_NODE_REC(nr_resp);
6412 6304
6413 6305 pg = nr_resp->NodeInfo.PortGUID;
6414 6306 IBTF_DPRINTF_L4(cmlog,
6415 6307 "ibt_get_companion_port_gids: "
6416 6308 "PortGID %llX", pg);
6417 6309
6418 6310 if (pg != gid.gid_guid) {
6419 6311 gidp[k].gid_prefix =
6420 6312 sgid.gid_prefix;
6421 6313 gidp[k].gid_guid = pg;
6422 6314
6423 6315 IBTF_DPRINTF_L3(cmlog,
6424 6316 "ibt_get_companion_pgids: "
6425 6317 "GID[%d] = %llX:%llX", k,
6426 6318 gidp[k].gid_prefix,
6427 6319 gidp[k].gid_guid);
6428 6320
6429 6321 k++;
6430 6322 if (k == count)
6431 6323 break;
6432 6324 }
6433 6325 }
6434 6326 retval = IBT_SUCCESS; /* done!. */
6435 6327 kmem_free(res_p, len);
6436 6328 ibcm_dec_hca_acc_cnt(hcap);
6437 6329 goto get_comp_pgid_exit;
6438 6330 } else {
6439 6331 IBTF_DPRINTF_L2(cmlog,
6440 6332 "ibt_get_companion_port_gids: "
6441 6333 "Companion PortGIDs not available");
6442 6334 retval = IBT_GIDS_NOT_FOUND;
6443 6335 }
6444 6336 /* Deallocate the memory for 'res_p'. */
6445 6337 kmem_free(res_p, len);
6446 6338
6447 6339 /*
6448 6340 * If we are on MultiSM setup, then we need to lookout
6449 6341 * from that subnet port too.
6450 6342 */
6451 6343 if (multism) {
6452 6344 /* break if already searched both the subnet */
6453 6345 if (multi_sm_loop == 1)
6454 6346 break;
6455 6347
6456 6348 port = (j == 0) ? 1 : 0;
6457 6349 multi_sm_loop = 1;
6458 6350 goto get_comp_for_multism;
6459 6351 } else {
6460 6352 break;
6461 6353 }
6462 6354 }
6463 6355 ibcm_dec_hca_acc_cnt(hcap);
6464 6356
6465 6357 /*
6466 6358 * We may be on dual HCA with dual SM configured system. And
6467 6359 * the input attr GID was visible from second HCA. So in order
6468 6360 * to get the companion portgid we need to re-look from the
6469 6361 * first HCA ports.
6470 6362 */
6471 6363 if ((num_hcas > 1) && (i > 0) && (h_guid != 0) &&
6472 6364 (multi_hca_loop != 1)) {
6473 6365 multi_hca_loop = 1;
6474 6366 goto get_comp_for_multihca;
6475 6367 }
6476 6368 }
6477 6369 if (*num_gids_p == 0)
6478 6370 retval = IBT_GIDS_NOT_FOUND;
6479 6371
6480 6372 get_comp_pgid_exit:
6481 6373 if (guid_array)
6482 6374 ibt_free_hca_list(guid_array, num_hcas);
6483 6375
6484 6376 if ((retval != IBT_SUCCESS) && (*num_gids_p != 0)) {
6485 6377 retval = IBT_SUCCESS;
6486 6378 }
6487 6379
6488 6380 IBTF_DPRINTF_L3(cmlog, "ibt_get_companion_port_gids: done. Status %d, "
6489 6381 "Found %d GIDs", retval, *num_gids_p);
6490 6382
6491 6383 return (retval);
6492 6384 }
6493 6385
6494 6386 /* RDMA IP CM Support routines */
6495 6387 ibt_status_t
6496 6388 ibt_get_src_ip(ibt_srcip_attr_t *sattr, ibt_srcip_info_t **src_info_p,
6497 6389 uint_t *entries_p)
6498 6390 {
6499 6391 ibt_srcip_info_t *s_ip;
6500 6392 ibcm_arp_ip_t *ipp;
6501 6393 ibcm_arp_ibd_insts_t ibds;
6502 6394 uint8_t i, j;
6503 6395 uint_t count;
6504 6396 ibt_status_t retval = IBT_SUCCESS;
6505 6397
6506 6398 IBTF_DPRINTF_L4(cmlog, "ibt_get_src_ip(%p, %p, %p)",
6507 6399 sattr, src_info_p, entries_p);
6508 6400
6509 6401 if (sattr == NULL || entries_p == NULL) {
6510 6402 IBTF_DPRINTF_L3(cmlog, "ibt_get_src_ip: Invalid I/P Args.");
6511 6403 return (IBT_INVALID_PARAM);
6512 6404 }
6513 6405
6514 6406 if (sattr->sip_gid.gid_prefix == 0 || sattr->sip_gid.gid_guid == 0) {
6515 6407 IBTF_DPRINTF_L3(cmlog, "ibt_get_src_ip: Invalid GID.");
6516 6408 return (IBT_INVALID_PARAM);
6517 6409 }
6518 6410
6519 6411 /* TBD: Zoneid */
6520 6412 retval = ibcm_arp_get_ibds(&ibds, sattr->sip_family);
6521 6413 if (retval != IBT_SUCCESS) {
6522 6414 IBTF_DPRINTF_L2(cmlog, "ibt_get_src_ip: ibcm_arp_get_ibds "
6523 6415 "failed to get IBD Instances: ret 0x%x", retval);
6524 6416 goto get_src_ip_end;
6525 6417 }
6526 6418
6527 6419 count = 0;
6528 6420 for (i = 0, ipp = ibds.ibcm_arp_ip; i < ibds.ibcm_arp_ibd_cnt;
6529 6421 i++, ipp++) {
6530 6422 if (ipp->ip_inet_family == AF_UNSPEC)
6531 6423 continue;
6532 6424 if (ipp->ip_port_gid.gid_prefix == sattr->sip_gid.gid_prefix &&
6533 6425 ipp->ip_port_gid.gid_guid == sattr->sip_gid.gid_guid) {
6534 6426 if ((sattr->sip_pkey) &&
6535 6427 (ipp->ip_pkey != sattr->sip_pkey))
6536 6428 continue;
6537 6429
6538 6430 if ((sattr->sip_zoneid != ALL_ZONES) &&
6539 6431 (sattr->sip_zoneid != ipp->ip_zoneid))
6540 6432 continue;
6541 6433
6542 6434 count++;
6543 6435 break;
6544 6436 }
6545 6437 }
6546 6438
6547 6439 if (count) {
6548 6440 /*
6549 6441 * Allocate memory for return buffer, to be freed by
6550 6442 * ibt_free_srcip_info().
6551 6443 */
6552 6444 s_ip = kmem_alloc((count * sizeof (ibt_srcip_info_t)),
6553 6445 KM_SLEEP);
6554 6446
6555 6447 *src_info_p = s_ip;
6556 6448 *entries_p = count;
6557 6449
6558 6450 j = 0;
6559 6451 for (i = 0, ipp = ibds.ibcm_arp_ip; i < ibds.ibcm_arp_ibd_cnt;
6560 6452 i++, ipp++) {
6561 6453 if (ipp->ip_inet_family == AF_UNSPEC)
6562 6454 continue;
6563 6455 if ((ipp->ip_port_gid.gid_prefix ==
6564 6456 sattr->sip_gid.gid_prefix) &&
↓ open down ↓ |
498 lines elided |
↑ open up ↑ |
6565 6457 (ipp->ip_port_gid.gid_guid ==
6566 6458 sattr->sip_gid.gid_guid)) {
6567 6459 if ((sattr->sip_pkey) &&
6568 6460 (ipp->ip_pkey != sattr->sip_pkey))
6569 6461 continue;
6570 6462
6571 6463 if ((sattr->sip_zoneid != ALL_ZONES) &&
6572 6464 (sattr->sip_zoneid != ipp->ip_zoneid))
6573 6465 continue;
6574 6466
6575 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*s_ip))
6576 6467 s_ip[j].ip_addr.family = ipp->ip_inet_family;
6577 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*s_ip))
6578 6468 if (s_ip[j].ip_addr.family == AF_INET) {
6579 6469 bcopy(&ipp->ip_cm_sin.sin_addr,
6580 6470 &s_ip[j].ip_addr.un.ip4addr,
6581 6471 sizeof (in_addr_t));
6582 6472 } else if (s_ip[j].ip_addr.family == AF_INET6) {
6583 6473 bcopy(&ipp->ip_cm_sin6.sin6_addr,
6584 6474 &s_ip[j].ip_addr.un.ip6addr,
6585 6475 sizeof (in6_addr_t));
6586 6476 /* TBD: scope_id */
6587 6477 }
6588 6478 IBCM_PRINT_IP("ibt_get_src_ip",
6589 6479 &s_ip[j].ip_addr);
6590 6480 j++;
6591 6481 }
6592 6482 }
6593 6483 } else {
6594 6484 retval = IBT_SRC_IP_NOT_FOUND;
6595 6485 }
6596 6486
6597 6487 get_src_ip_end:
6598 6488 ibcm_arp_free_ibds(&ibds);
6599 6489 return (retval);
6600 6490 }
6601 6491
6602 6492 /*
6603 6493 * ibt_free_srcip_info()
6604 6494 * Free the memory allocated by successful ibt_get_src_ip()
6605 6495 *
6606 6496 * src_info Pointer returned by ibt_get_src_ip().
6607 6497 *
6608 6498 * entries The number of ibt_ip_addr_t entries to free.
6609 6499 */
6610 6500 void
6611 6501 ibt_free_srcip_info(ibt_srcip_info_t *src_info, uint_t entries)
6612 6502 {
6613 6503 IBTF_DPRINTF_L3(cmlog, "ibt_free_srcip_info: "
6614 6504 "Free <%d> entries from 0x%p", entries, src_info);
6615 6505
6616 6506 if ((src_info != NULL) && (entries > 0))
6617 6507 kmem_free(src_info, entries * sizeof (ibt_srcip_info_t));
6618 6508 else
6619 6509 IBTF_DPRINTF_L2(cmlog, "ibt_free_srcip_info: "
6620 6510 "ERROR: NULL buf pointer or ZERO length specified.");
6621 6511 }
6622 6512
6623 6513
6624 6514 ib_svc_id_t
6625 6515 ibt_get_ip_sid(uint8_t protocol_num, in_port_t dst_port)
6626 6516 {
6627 6517 ib_svc_id_t sid;
6628 6518
6629 6519 IBTF_DPRINTF_L4(cmlog, "ibt_get_ip_sid(%X, %lX)", protocol_num,
6630 6520 dst_port);
6631 6521
6632 6522 /*
6633 6523 * If protocol_num is non-zero, then formulate the SID and return it.
6634 6524 * If protocol_num is zero, then we need to assign a locally generated
6635 6525 * IP SID with IB_SID_IPADDR_PREFIX.
6636 6526 */
6637 6527 if (protocol_num) {
6638 6528 sid = IB_SID_IPADDR_PREFIX | protocol_num << 16 | dst_port;
6639 6529 } else {
6640 6530 sid = ibcm_alloc_ip_sid();
6641 6531 }
6642 6532
6643 6533 IBTF_DPRINTF_L3(cmlog, "ibt_get_ip_sid: SID: 0x%016llX", sid);
6644 6534 return (sid);
6645 6535 }
6646 6536
6647 6537 ibt_status_t
6648 6538 ibt_release_ip_sid(ib_svc_id_t ip_sid)
6649 6539 {
6650 6540 IBTF_DPRINTF_L4(cmlog, "ibt_release_ip_sid(%llX)", ip_sid);
6651 6541
6652 6542 if (((ip_sid & IB_SID_IPADDR_PREFIX_MASK) != 0) ||
6653 6543 (!(ip_sid & IB_SID_IPADDR_PREFIX))) {
6654 6544 IBTF_DPRINTF_L2(cmlog, "ibt_release_ip_sid(0x%016llX): ERROR: "
6655 6545 "Called for Non-RDMA IP SID", ip_sid);
6656 6546 return (IBT_INVALID_PARAM);
6657 6547 }
6658 6548
6659 6549 /*
6660 6550 * If protocol_num in ip_sid are all ZEROs, then this SID is allocated
6661 6551 * by IBTF. If not, then the specified ip_sid is invalid.
6662 6552 */
6663 6553 if (ip_sid & IB_SID_IPADDR_IPNUM_MASK) {
6664 6554 IBTF_DPRINTF_L2(cmlog, "ibt_release_ip_sid(0x%016llX): ERROR: "
6665 6555 "Called for Non-IBTF assigned RDMA IP SID", ip_sid);
6666 6556 return (IBT_INVALID_PARAM);
6667 6557 }
6668 6558
6669 6559 ibcm_free_ip_sid(ip_sid);
6670 6560
6671 6561 return (IBT_SUCCESS);
6672 6562 }
6673 6563
6674 6564
6675 6565 uint8_t
6676 6566 ibt_get_ip_protocol_num(ib_svc_id_t sid)
↓ open down ↓ |
89 lines elided |
↑ open up ↑ |
6677 6567 {
6678 6568 return ((sid & IB_SID_IPADDR_IPNUM_MASK) >> 16);
6679 6569 }
6680 6570
6681 6571 in_port_t
6682 6572 ibt_get_ip_dst_port(ib_svc_id_t sid)
6683 6573 {
6684 6574 return (sid & IB_SID_IPADDR_PORTNUM_MASK);
6685 6575 }
6686 6576
6687 -_NOTE(SCHEME_PROTECTS_DATA("Unshared data", ibt_ip_cm_info_t))
6688 -_NOTE(SCHEME_PROTECTS_DATA("Unshared data", ibcm_ip_pvtdata_t))
6689 -
6690 6577 ibt_status_t
6691 6578 ibt_format_ip_private_data(ibt_ip_cm_info_t *ip_cm_info,
6692 6579 ibt_priv_data_len_t priv_data_len, void *priv_data_p)
6693 6580 {
6694 6581 ibcm_ip_pvtdata_t ip_data;
6695 6582
6696 6583 IBTF_DPRINTF_L4(cmlog, "ibt_format_ip_private_data(%p, %d, %p)",
6697 6584 ip_cm_info, priv_data_len, priv_data_p);
6698 6585
6699 6586 if ((ip_cm_info == NULL) || (priv_data_p == NULL) ||
6700 6587 (priv_data_len < IBT_IP_HDR_PRIV_DATA_SZ)) {
6701 6588 IBTF_DPRINTF_L2(cmlog, "ibt_format_ip_private_data: ERROR "
6702 6589 "Invalid Inputs.");
6703 6590 return (IBT_INVALID_PARAM);
6704 6591 }
6705 6592
6706 6593 bzero(&ip_data, sizeof (ibcm_ip_pvtdata_t));
6707 6594 ip_data.ip_srcport = ip_cm_info->src_port; /* Source Port */
6708 6595
6709 6596 IBCM_PRINT_IP("format_ip_pvt: src", &ip_cm_info->src_addr);
6710 6597 IBCM_PRINT_IP("format_ip_pvt: dst", &ip_cm_info->dst_addr);
6711 6598 /* IPV = 0x4, if IP-Addr are IPv4 format, else 0x6 for IPv6 */
6712 6599 if (ip_cm_info->src_addr.family == AF_INET) {
6713 6600 ip_data.ip_ipv = IBT_CM_IP_IPV_V4;
6714 6601 ip_data.ip_srcv4 = ip_cm_info->src_addr.un.ip4addr;
6715 6602 ip_data.ip_dstv4 = ip_cm_info->dst_addr.un.ip4addr;
6716 6603 } else if (ip_cm_info->src_addr.family == AF_INET6) {
6717 6604 ip_data.ip_ipv = IBT_CM_IP_IPV_V6;
6718 6605 bcopy(&ip_cm_info->src_addr.un.ip6addr,
6719 6606 &ip_data.ip_srcv6, sizeof (in6_addr_t));
6720 6607 bcopy(&ip_cm_info->dst_addr.un.ip6addr,
6721 6608 &ip_data.ip_dstv6, sizeof (in6_addr_t));
6722 6609 } else {
6723 6610 IBTF_DPRINTF_L2(cmlog, "ibt_format_ip_private_data: ERROR "
6724 6611 "IP Addr needs to be either AF_INET or AF_INET6 family.");
6725 6612 return (IBT_INVALID_PARAM);
6726 6613 }
6727 6614
6728 6615 ip_data.ip_MajV = IBT_CM_IP_MAJ_VER;
6729 6616 ip_data.ip_MinV = IBT_CM_IP_MIN_VER;
6730 6617
6731 6618 bcopy(&ip_data, priv_data_p, IBT_IP_HDR_PRIV_DATA_SZ);
6732 6619
6733 6620 return (IBT_SUCCESS);
6734 6621 }
6735 6622
6736 6623
6737 6624 ibt_status_t
6738 6625 ibt_get_ip_data(ibt_priv_data_len_t priv_data_len, void *priv_data,
6739 6626 ibt_ip_cm_info_t *ip_cm_infop)
6740 6627 {
6741 6628 ibcm_ip_pvtdata_t ip_data;
6742 6629
6743 6630 IBTF_DPRINTF_L4(cmlog, "ibt_get_ip_data(%d, %p, %p)",
6744 6631 priv_data_len, priv_data, ip_cm_infop);
6745 6632
6746 6633 if ((ip_cm_infop == NULL) || (priv_data == NULL) ||
6747 6634 (priv_data_len < IBT_IP_HDR_PRIV_DATA_SZ)) {
6748 6635 IBTF_DPRINTF_L2(cmlog, "ibt_get_ip_data: ERROR Invalid Inputs");
6749 6636 return (IBT_INVALID_PARAM);
6750 6637 }
6751 6638
6752 6639 bcopy(priv_data, &ip_data, IBT_IP_HDR_PRIV_DATA_SZ);
6753 6640 ip_cm_infop->src_port = ip_data.ip_srcport; /* Source Port */
6754 6641
6755 6642 /* IPV = 0x4, if IP Address are IPv4 format, else 0x6 for IPv6 */
6756 6643 if (ip_data.ip_ipv == IBT_CM_IP_IPV_V4) {
6757 6644 /* Copy IPv4 Addr */
6758 6645 ip_cm_infop->src_addr.family = ip_cm_infop->dst_addr.family =
6759 6646 AF_INET;
6760 6647 ip_cm_infop->src_addr.un.ip4addr = ip_data.ip_srcv4;
6761 6648 ip_cm_infop->dst_addr.un.ip4addr = ip_data.ip_dstv4;
6762 6649 } else if (ip_data.ip_ipv == IBT_CM_IP_IPV_V6) {
6763 6650 /* Copy IPv6 Addr */
6764 6651 ip_cm_infop->src_addr.family = ip_cm_infop->dst_addr.family =
6765 6652 AF_INET6;
6766 6653 bcopy(&ip_data.ip_srcv6, &ip_cm_infop->src_addr.un.ip6addr,
6767 6654 sizeof (in6_addr_t));
6768 6655 bcopy(&ip_data.ip_dstv6, &ip_cm_infop->dst_addr.un.ip6addr,
↓ open down ↓ |
69 lines elided |
↑ open up ↑ |
6769 6656 sizeof (in6_addr_t));
6770 6657 } else {
6771 6658 IBTF_DPRINTF_L2(cmlog, "ibt_get_ip_data: ERROR: IP Addr needs"
6772 6659 " to be either AF_INET or AF_INET6 family.");
6773 6660 return (IBT_INVALID_PARAM);
6774 6661 }
6775 6662 IBCM_PRINT_IP("ibt_get_ip_data: src", &ip_cm_infop->src_addr);
6776 6663 IBCM_PRINT_IP("ibt_get_ip_data: dst", &ip_cm_infop->dst_addr);
6777 6664
6778 6665 return (IBT_SUCCESS);
6779 -}
6780 -
6781 -
6782 -/* Routines for warlock */
6783 -
6784 -/* ARGSUSED */
6785 -static void
6786 -ibcm_dummy_mcg_handler(void *arg, ibt_status_t retval, ibt_mcg_info_t *minfo)
6787 -{
6788 - ibcm_join_mcg_tqarg_t dummy_mcg;
6789 -
6790 - dummy_mcg.func = ibcm_dummy_mcg_handler;
6791 -
6792 - IBTF_DPRINTF_L5(cmlog, "ibcm_dummy_mcg_handler: "
6793 - "dummy_mcg.func %p", dummy_mcg.func);
6794 -}
6795 -
6796 -
6797 -/* ARGSUSED */
6798 -static void
6799 -ibcm_dummy_recycle_rc_handler(ibt_status_t retval, void *arg)
6800 -{
6801 - ibcm_taskq_recycle_arg_t dummy_rc_recycle;
6802 -
6803 - dummy_rc_recycle.func = ibcm_dummy_recycle_rc_handler;
6804 -
6805 - IBTF_DPRINTF_L5(cmlog, "ibcm_dummy_recycle_rc_handler: "
6806 - "dummy_rc_recycle.func %p", dummy_rc_recycle.func);
6807 -}
6808 -
6809 -
6810 -/* ARGSUSED */
6811 -static ibt_cm_status_t
6812 -ibcm_dummy_ud_handler(void *priv, ibt_cm_ud_event_t *event,
6813 - ibt_cm_ud_return_args_t *ret_args,
6814 - void *priv_data, ibt_priv_data_len_t len)
6815 -{
6816 - /*
6817 - * Let warlock see that ibcm_local_handler_s::actual_cm_handler
6818 - * points to this routine.
6819 - */
6820 - ibcm_local_handler_t p;
6821 - ibcm_ud_state_data_t dummy_ud;
6822 -
6823 - p.actual_cm_handler = ibcm_dummy_ud_handler;
6824 - dummy_ud.ud_cm_handler = ibcm_dummy_ud_handler;
6825 -
6826 - IBTF_DPRINTF_L5(cmlog, "ibcm_dummy_ud_handler: p.actual_cm_handler %p"
6827 - "dummy_ud.ud_cm_handler %p", p.actual_cm_handler,
6828 - dummy_ud.ud_cm_handler);
6829 - /*
6830 - * Call all routines that the client's callback routine could call.
6831 - */
6832 -
6833 - return (IBT_CM_ACCEPT);
6834 -}
6835 -
6836 -/* ARGSUSED */
6837 -static ibt_cm_status_t
6838 -ibcm_dummy_rc_handler(void *priv, ibt_cm_event_t *event,
6839 - ibt_cm_return_args_t *ret_args, void *priv_data, ibt_priv_data_len_t len)
6840 -{
6841 - ibcm_state_data_t dummy_rc;
6842 -
6843 - dummy_rc.cm_handler = ibcm_dummy_rc_handler;
6844 -
6845 - IBTF_DPRINTF_L5(cmlog, "ibcm_dummy_rc_handler: "
6846 - "dummy_ud.ud_cm_handler %p", dummy_rc.cm_handler);
6847 - /*
6848 - * Call all routines that the client's callback routine could call.
6849 - */
6850 -
6851 - return (IBT_CM_ACCEPT);
6852 6666 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX