Print this page
8368 remove warlock leftovers from usr/src/uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/ib/ibtl/ibtl_hca.c
+++ new/usr/src/uts/common/io/ib/ibtl/ibtl_hca.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 /*
26 26 * ibtl_hca.c
27 27 *
28 28 * This file contains Transport API functions related to
29 29 * Host Channel Adapter (HCA) Verbs.
30 30 */
31 31
32 32 #include <sys/ib/ibtl/impl/ibtl.h>
33 33
34 34 static char ibtf_hca[] = "ibtl_hca";
35 35
36 36 /* Prototype declarations. */
37 37 static ibt_status_t ibtl_query_hca_ports(ibtl_hca_devinfo_t *hca_devp,
38 38 uint8_t port, ibt_hca_portinfo_t **port_info_p, uint_t *ports_p,
39 39 uint_t *size_p, int use_cache);
40 40
41 41 /*
42 42 * Function:
43 43 * ibt_open_hca
44 44 * Input:
45 45 * ibt_hdl - IBT Client Handle
46 46 * hca_guid - HCA's node GUID.
47 47 * Output:
48 48 * hca_hdl_p - IBT HCA Handle.
49 49 * Returns:
50 50 * IBT_SUCCESS
51 51 * IBT_HCA_IN_USE
52 52 * IBT_HCA_INVALID
53 53 * Description:
54 54 * Open a HCA. HCA can only be opened/closed once. This routine allocates
55 55 * and returns a unique IBT Client HCA handle. Clients passes this
56 56 * handle on its subsequent references to this device. Once opened by a
57 57 * client, a specific HCA cannot be opened again until after it is closed.
58 58 * The IBT_HCA_IN_USE error is returned if client tries to open multiple
59 59 * times. In this case, previously allocated IBT HCA handle is returned to
60 60 * the client. Opening the HCA prepares the HCA for use by the client.
61 61 */
62 62 ibt_status_t
63 63 ibt_open_hca(ibt_clnt_hdl_t ibt_hdl, ib_guid_t hca_guid,
64 64 ibt_hca_hdl_t *hca_hdl_p)
65 65 {
66 66 ibtl_hca_t *hca_infop;
67 67 ibtl_hca_devinfo_t *hca_devp; /* HCA Dev Info */
68 68
69 69 IBTF_DPRINTF_L3(ibtf_hca, "ibt_open_hca(%p, %llX)", ibt_hdl, hca_guid);
70 70
71 71
72 72 /*
73 73 * Get HCA Device Info Structure, referenced by HCA GUID.
74 74 */
75 75 mutex_enter(&ibtl_clnt_list_mutex);
76 76 hca_devp = ibtl_get_hcadevinfo(hca_guid);
77 77 if (hca_devp == NULL) {
78 78 /*
79 79 * If we are here, then the requested HCA device is not present.
80 80 * Return the status as Invalid HCA GUID.
81 81 */
82 82 mutex_exit(&ibtl_clnt_list_mutex);
83 83
84 84 IBTF_DPRINTF_L2(ibtf_hca, "ibt_open_hca: "
85 85 "HCA Device Not Found: Invalid HCA GUID");
86 86
87 87 *hca_hdl_p = NULL;
88 88 return (IBT_HCA_INVALID);
89 89 }
90 90
91 91 /*
92 92 * Check whether open is allowed for this dip
93 93 */
94 94 if (ibt_hdl->clnt_dip) {
95 95 if (ddi_get_parent(ibt_hdl->clnt_dip) == hca_devp->hd_hca_dip) {
96 96 if (hca_guid != hca_devp->hd_hca_attr->hca_node_guid) {
97 97 mutex_exit(&ibtl_clnt_list_mutex);
98 98 return (IBT_FAILURE);
99 99 }
100 100 }
101 101 }
102 102
103 103 if (hca_devp->hd_state != IBTL_HCA_DEV_ATTACHED) {
104 104 /*
105 105 * If we are here, then the requested HCA device has detached,
106 106 * or is in the process of detaching.
107 107 */
108 108 mutex_exit(&ibtl_clnt_list_mutex);
109 109
110 110 IBTF_DPRINTF_L2(ibtf_hca, "ibt_open_hca: "
111 111 "HCA is busy trying to detach");
112 112
113 113 *hca_hdl_p = NULL;
114 114 return (IBT_HCA_BUSY_DETACHING);
115 115 }
116 116
117 117 /*
118 118 * Yes, we found a HCA Device registered with IBTF, which matches with
119 119 * the requested HCA_GUID.
120 120 *
121 121 * Check out whether this client has already opened this HCA device,
122 122 * if yes return the status as IBT_HCA_IN_USE.
123 123 */
124 124 hca_infop = hca_devp->hd_clnt_list;
125 125
126 126 while (hca_infop != NULL) {
127 127 if (ibt_hdl == hca_infop->ha_clnt_devp) {
128 128 IBTF_DPRINTF_L3(ibtf_hca,
129 129 "ibt_open_hca: Already Open");
130 130
131 131 if (hca_infop->ha_flags & IBTL_HA_CLOSING) {
132 132 mutex_exit(&ibtl_clnt_list_mutex);
133 133 *hca_hdl_p = NULL;
134 134 return (IBT_HCA_BUSY_CLOSING);
135 135 }
136 136 mutex_exit(&ibtl_clnt_list_mutex);
137 137
138 138 /* Already Opened. Return back old HCA Handle. */
139 139 *hca_hdl_p = hca_infop;
140 140
141 141 return (IBT_HCA_IN_USE);
142 142 }
143 143 hca_infop = hca_infop->ha_clnt_link;
144 144 }
145 145
146 146 /* Create a new HCA Info entity. */
147 147 hca_infop = kmem_zalloc(sizeof (ibtl_hca_t), KM_SLEEP);
148 148
149 149 /* Update the HCA Info entity */
150 150 hca_infop->ha_hca_devp = hca_devp; /* HCA Device Info */
151 151 hca_infop->ha_clnt_devp = ibt_hdl; /* Client Info */
152 152
153 153 /* Update the HCA List, to keep track about the clients using it. */
154 154 hca_infop->ha_clnt_link = hca_devp->hd_clnt_list;
155 155 hca_devp->hd_clnt_list = hca_infop;
156 156
157 157
158 158 /* Update the client's list to depict that it uses this HCA device. */
159 159 hca_infop->ha_hca_link = ibt_hdl->clnt_hca_list;
160 160 ibt_hdl->clnt_hca_list = hca_infop;
161 161
162 162 mutex_exit(&ibtl_clnt_list_mutex);
163 163
164 164 /*
165 165 * Return back the address of ibtl_hca_t structure as an opaque
166 166 * IBT HCA handle for the clients, to be used in future calls.
167 167 */
168 168 *hca_hdl_p = hca_infop;
169 169
170 170 return (IBT_SUCCESS);
171 171 }
172 172
173 173 static char *ibtl_close_error_fmt = "IBT CLOSE HCA failed: %d '%s' "
174 174 "resources not yet freed by client '%s'\n";
175 175
176 176 #define IBTL_CLOSE_RESOURCE_CHECK(counter, resource_type) \
177 177 if ((cntr = atomic_add_32_nv(&(counter), 0)) != 0) { \
178 178 cmn_err(CE_CONT, ibtl_close_error_fmt, \
179 179 cntr, resource_type, \
180 180 hca_hdl->ha_clnt_devp->clnt_modinfop->mi_clnt_name); \
181 181 } \
182 182 error |= cntr
183 183
184 184 /*
185 185 * Function:
186 186 * ibt_close_hca
187 187 * Input:
188 188 * hca_hdl - The HCA handle as returned during its open.
189 189 * Output:
190 190 * none
191 191 * Returns:
192 192 * IBT_SUCCESS
193 193 * IBT_HCA_HDL_INVALID
194 194 * IBT_HCA_RESOURCES_NOT_FREED
195 195 * Description:
196 196 * Close a HCA.
197 197 */
198 198 ibt_status_t
199 199 ibt_close_hca(ibt_hca_hdl_t hca_hdl)
200 200 {
201 201 ibtl_hca_devinfo_t *hca_devp, *tmp_devp;
202 202 ibtl_hca_t **hcapp;
203 203 ibtl_clnt_t *clntp = hca_hdl->ha_clnt_devp;
204 204 uint32_t cntr, error;
205 205
206 206 IBTF_DPRINTF_L3(ibtf_hca, "ibt_close_hca(%p)", hca_hdl);
207 207
208 208 /*
209 209 * Verify the Input HCA Handle, if fake return error as
210 210 * invalid HCA Handle.
211 211 */
212 212 mutex_enter(&ibtl_clnt_list_mutex);
213 213 hca_devp = hca_hdl->ha_hca_devp;
214 214 tmp_devp = ibtl_hca_list;
215 215
216 216 for (; tmp_devp != NULL; tmp_devp = tmp_devp->hd_hca_dev_link)
217 217 if (tmp_devp == hca_devp)
218 218 break;
219 219
220 220 if (tmp_devp == NULL) {
221 221 mutex_exit(&ibtl_clnt_list_mutex);
222 222 IBTF_DPRINTF_L2(ibtf_hca, "ibt_close_hca: "
223 223 "Unable to find this on global HCA list");
224 224 return (IBT_HCA_HDL_INVALID);
225 225 }
226 226
227 227 /* Make sure resources have been freed. */
228 228 error = 0;
229 229 IBTL_CLOSE_RESOURCE_CHECK(hca_hdl->ha_qp_cnt, "QP/Channel");
230 230 IBTL_CLOSE_RESOURCE_CHECK(hca_hdl->ha_eec_cnt, "EEC");
231 231 IBTL_CLOSE_RESOURCE_CHECK(hca_hdl->ha_cq_cnt, "CQ");
232 232 IBTL_CLOSE_RESOURCE_CHECK(hca_hdl->ha_pd_cnt, "Protection Domain");
233 233 IBTL_CLOSE_RESOURCE_CHECK(hca_hdl->ha_ah_cnt, "AH");
234 234 IBTL_CLOSE_RESOURCE_CHECK(hca_hdl->ha_mr_cnt, "Memory Region");
235 235 IBTL_CLOSE_RESOURCE_CHECK(hca_hdl->ha_mw_cnt, "Memory Window");
236 236 IBTL_CLOSE_RESOURCE_CHECK(hca_hdl->ha_qpn_cnt, "QPN");
237 237 IBTL_CLOSE_RESOURCE_CHECK(hca_hdl->ha_srq_cnt, "SRQ");
238 238 IBTL_CLOSE_RESOURCE_CHECK(hca_hdl->ha_fmr_pool_cnt, "FMR Pool");
239 239 if (error) {
240 240 mutex_exit(&ibtl_clnt_list_mutex);
241 241 return (IBT_HCA_RESOURCES_NOT_FREED);
242 242 }
243 243
244 244 /* we are now committed to closing the HCA */
245 245 hca_hdl->ha_flags |= IBTL_HA_CLOSING;
246 246 while (hca_hdl->ha_qpn_cnt > 0)
247 247 cv_wait(&ibtl_close_hca_cv, &ibtl_clnt_list_mutex);
248 248
249 249 /*
250 250 * Remove this HCA Device entry form Client's current list of HCA
251 251 * Device Instances being used by it.
252 252 */
253 253 hcapp = &clntp->clnt_hca_list;
254 254
255 255 for (; *hcapp != NULL; hcapp = &(*hcapp)->ha_hca_link)
256 256 if (*hcapp == hca_hdl)
257 257 break;
258 258
259 259 if (*hcapp == NULL) {
260 260 IBTF_DPRINTF_L2(ibtf_hca, "ibt_close_hca: "
261 261 "Unable to find this HCA on client list");
262 262 mutex_exit(&ibtl_clnt_list_mutex);
263 263 return (IBT_HCA_HDL_INVALID);
264 264 }
265 265
266 266 /* hcapp now points to a link that points to us */
267 267 *hcapp = hca_hdl->ha_hca_link; /* remove us */
268 268
269 269 /*
270 270 * Remove this Client's entry from this HCA Device's Clients list.
271 271 */
272 272 hcapp = &hca_devp->hd_clnt_list;
273 273
274 274 for (; *hcapp != NULL; hcapp = &(*hcapp)->ha_clnt_link)
275 275 if (*hcapp == hca_hdl)
276 276 break;
277 277
278 278 if (*hcapp == NULL) {
279 279 mutex_exit(&ibtl_clnt_list_mutex);
280 280 IBTF_DPRINTF_L2(ibtf_hca, "ibt_close_hca: "
281 281 "Unable to find this HCA on the client's HCA list");
282 282 return (IBT_HCA_HDL_INVALID);
283 283 }
284 284
285 285 /* hcapp now points to a link that points to us */
286 286 *hcapp = hca_hdl->ha_clnt_link; /* remove us */
287 287 mutex_exit(&ibtl_clnt_list_mutex);
288 288
289 289 /* Free memory for this HCA Handle */
290 290 ibtl_free_hca_async_check(hca_hdl);
291 291
292 292 return (IBT_SUCCESS);
293 293 }
294 294
295 295 void
296 296 ibtl_close_hca_check(ibt_hca_hdl_t hca_hdl)
297 297 {
298 298 IBTF_DPRINTF_L3(ibtf_hca, "ibtl_close_hca_check(%p)", hca_hdl);
299 299
300 300 mutex_enter(&ibtl_clnt_list_mutex);
301 301 if ((--hca_hdl->ha_qpn_cnt == 0) &&
302 302 (hca_hdl->ha_flags & IBTL_HA_CLOSING)) {
303 303 cv_signal(&ibtl_close_hca_cv);
304 304 }
305 305 mutex_exit(&ibtl_clnt_list_mutex);
306 306 }
307 307
308 308 /*
309 309 * Function:
310 310 * ibt_get_hca_list
311 311 * Input:
312 312 * hca_list_p - Address of pointer updated here.
313 313 * Output:
314 314 * hca_list_p - Points to an array of ib_guid_t's allocated here.
315 315 * Returns:
316 316 * The actual number of valid ib_guid_t's returned.
317 317 * Description:
318 318 * If hca_list_p is not NULL then the memory for the array of GUIDs is
319 319 * allocated here and should be freed by the caller using
320 320 * ibt_free_hca_list(). If hca_list_p is NULL then no memory is allocated
321 321 * by ibt_get_hca_list and only the number of HCAs in a system is returned.
322 322 */
323 323 uint_t
324 324 ibt_get_hca_list(ib_guid_t **hca_list_p)
325 325 {
326 326 uint_t hca_count = 0;
327 327 ibtl_hca_devinfo_t *hca_devp;
328 328 ib_guid_t *hca_listp;
329 329
330 330 IBTF_DPRINTF_L3(ibtf_hca, "ibt_get_hca_list(%p)", hca_list_p);
331 331
332 332 mutex_enter(&ibtl_clnt_list_mutex);
333 333
334 334 hca_devp = ibtl_hca_list;
335 335 while (hca_devp != NULL) {
336 336 hca_count++;
337 337 hca_devp = hca_devp->hd_hca_dev_link;
338 338 }
339 339
340 340 if (hca_count == 0)
341 341 IBTF_DPRINTF_L2(ibtf_hca, "ibt_get_hca_list: "
342 342 "HCA device not found");
343 343
344 344 if ((hca_count == 0) || (hca_list_p == NULL)) {
345 345 mutex_exit(&ibtl_clnt_list_mutex);
346 346 return (hca_count);
347 347 }
348 348
349 349 hca_listp = kmem_alloc(hca_count * sizeof (ib_guid_t), KM_SLEEP);
350 350 *hca_list_p = hca_listp;
351 351
352 352 hca_devp = ibtl_hca_list;
353 353 while (hca_devp != NULL) {
354 354 /* Traverse Global HCA List & retrieve HCA Node GUIDs. */
355 355 *hca_listp++ = hca_devp->hd_hca_attr->hca_node_guid;
356 356 hca_devp = hca_devp->hd_hca_dev_link;
357 357 }
358 358 mutex_exit(&ibtl_clnt_list_mutex);
359 359
360 360 IBTF_DPRINTF_L3(ibtf_hca, "ibt_get_hca_list: "
361 361 "Returned <%d> entries @0x%p", hca_count, *hca_list_p);
362 362
363 363 return (hca_count);
364 364 }
365 365
366 366 /*
367 367 * Function:
368 368 * ibt_free_hca_list
369 369 * Input:
370 370 * hca_list - The address of an ib_guid_t pointer.
371 371 * entries - The number of ib_guid_t entries to be freed.
372 372 * Output:
373 373 * none.
374 374 * Returns:
375 375 * none.
376 376 * Description:
377 377 * The memory allocated in ibt_get_hca_list() is freed in this function.
378 378 */
379 379 void
380 380 ibt_free_hca_list(ib_guid_t *hca_list, uint_t entries)
381 381 {
382 382 IBTF_DPRINTF_L3(ibtf_hca, "ibt_free_hca_list: "
383 383 "Free <%d> entries from 0x%p", entries, hca_list);
384 384
385 385 if ((hca_list != NULL) && (entries > 0))
386 386 kmem_free(hca_list, entries * sizeof (ib_guid_t));
387 387 }
388 388
389 389 /*
390 390 * ibtl_portinfo_locked() is called when the portinfo cache is being
391 391 * updated. If this port's info update is in progress, we return 0
392 392 * immediately and have the c
393 393 * unless it's already in progress (distinguished by return value).
394 394 * When done updating the portinfo, they call ibtl_portinfo_unlock().
395 395 */
396 396
397 397 static int
398 398 ibtl_portinfo_locked(ibtl_hca_devinfo_t *hca_devp, uint8_t port)
399 399 {
400 400 ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
401 401
402 402 for (;;) {
403 403 if (hca_devp->hd_portinfo_locked_port == 0) {
404 404 hca_devp->hd_portinfo_locked_port = port;
405 405 return (1); /* not busy, so OK to initiate update */
406 406 } else if (hca_devp->hd_portinfo_locked_port == port) {
407 407 IBTF_DPRINTF_L3(ibtf_hca, "ibtl_portinfo_locked: "
408 408 "HCA %p port %d is already locked",
409 409 hca_devp, port);
410 410 hca_devp->hd_portinfo_waiters = 1;
411 411 cv_wait(&hca_devp->hd_portinfo_cv,
412 412 &ibtl_clnt_list_mutex);
413 413 return (0); /* it's now done, so no need to initiate */
414 414 } else {
415 415 /* need to wait for other port before we try again */
416 416 hca_devp->hd_portinfo_waiters = 1;
417 417 cv_wait(&hca_devp->hd_portinfo_cv,
418 418 &ibtl_clnt_list_mutex);
419 419 }
420 420 }
421 421 }
422 422
423 423 static void
424 424 ibtl_portinfo_unlock(ibtl_hca_devinfo_t *hca_devp, uint8_t port)
425 425 {
426 426 ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
427 427 ASSERT(hca_devp->hd_portinfo_locked_port == port);
428 428 hca_devp->hd_portinfo_locked_port = 0;
429 429 if (hca_devp->hd_portinfo_waiters) {
430 430 hca_devp->hd_portinfo_waiters = 0;
431 431 cv_broadcast(&hca_devp->hd_portinfo_cv);
432 432 IBTF_DPRINTF_L3(ibtf_hca, "ibtl_portinfo_unlock: "
433 433 "waking up waiters for port %d info on HCA %p",
434 434 port, hca_devp);
435 435 }
436 436 }
437 437
438 438 /*
439 439 * Function:
440 440 * ibt_get_port_state
441 441 * Input:
442 442 * hca_devp - The HCA Dev Info pointer.
443 443 * port - Port number to query.
444 444 * Output:
445 445 * sgid_p - Returned sgid[0], NULL implies no return value.
446 446 * base_lid_p - Returned base_lid, NULL implies no return value.
447 447 * Returns:
448 448 * IBT_SUCCESS
449 449 * IBT_HCA_PORT_INVALID
450 450 * Description:
451 451 * Returns HCA port attributes for one of the HCA ports.
452 452 */
453 453 static ibt_status_t
454 454 ibtl_get_port_state(ibtl_hca_devinfo_t *hca_devp, uint8_t port,
455 455 ib_gid_t *sgid_p, ib_lid_t *base_lid_p)
456 456 {
457 457 ibt_hca_portinfo_t *portinfop;
458 458
459 459 ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
460 460
461 461 if ((port < 1) || (port > hca_devp->hd_hca_attr->hca_nports)) {
462 462 IBTF_DPRINTF_L2(ibtf_hca, "ibtl_get_port_state: "
463 463 "invalid port %d, nports = %d", port,
464 464 hca_devp->hd_hca_attr->hca_nports);
465 465 return (IBT_HCA_PORT_INVALID);
466 466 }
467 467 portinfop = hca_devp->hd_portinfop + port - 1;
468 468 if (portinfop->p_linkstate != IBT_PORT_ACTIVE)
469 469 ibtl_reinit_hca_portinfo(hca_devp, port);
470 470
471 471 if (sgid_p)
472 472 *sgid_p = portinfop->p_sgid_tbl[0];
473 473 if (base_lid_p)
474 474 *base_lid_p = portinfop->p_base_lid;
475 475 if (portinfop->p_linkstate != IBT_PORT_ACTIVE) {
476 476 IBTF_DPRINTF_L2(ibtf_hca, "ibtl_get_port_state: "
477 477 "port %d, port_state %d, base_lid %d",
478 478 port, portinfop->p_linkstate, portinfop->p_base_lid);
479 479 return (IBT_HCA_PORT_NOT_ACTIVE);
480 480 }
481 481 IBTF_DPRINTF_L3(ibtf_hca, "ibtl_get_port_state: "
482 482 "port %d, port_state %d, base_lid %d",
483 483 port, portinfop->p_linkstate, portinfop->p_base_lid);
484 484 return (IBT_SUCCESS);
485 485 }
486 486
487 487 /*
488 488 * Function:
489 489 * ibt_get_port_state
490 490 * Input:
491 491 * hca_hdl - The HCA handle.
492 492 * port - Port number to query.
493 493 * Output:
494 494 * sgid_p - Returned sgid[0], NULL implies no return value.
495 495 * base_lid_p - Returned base_lid, NULL implies no return value.
496 496 * Returns:
497 497 * IBT_SUCCESS
498 498 * IBT_HCA_PORT_INVALID
499 499 * Description:
500 500 * Returns HCA port attributes for one of the HCA ports.
501 501 */
502 502 ibt_status_t
503 503 ibt_get_port_state(ibt_hca_hdl_t hca_hdl, uint8_t port,
504 504 ib_gid_t *sgid_p, ib_lid_t *base_lid_p)
505 505 {
506 506 ibt_status_t retval;
507 507
508 508 IBTF_DPRINTF_L3(ibtf_hca, "ibt_get_port_state(%p, %d, %p, %p)",
509 509 hca_hdl, port, sgid_p, base_lid_p);
510 510 mutex_enter(&ibtl_clnt_list_mutex);
511 511 retval = ibtl_get_port_state(hca_hdl->ha_hca_devp, port, sgid_p,
512 512 base_lid_p);
513 513 mutex_exit(&ibtl_clnt_list_mutex);
514 514 return (retval);
515 515 }
516 516
517 517
518 518 /*
519 519 * Function:
520 520 * ibt_get_port_state_byguid
521 521 * Input:
522 522 * hca_guid - The HCA node GUID.
523 523 * port - Port number to query.
524 524 * Output:
525 525 * sgid_p - Returned sgid[0], NULL implies no return value.
526 526 * base_lid_p - Returned base_lid, NULL implies no return value.
527 527 * Returns:
528 528 * IBT_SUCCESS
529 529 * IBT_HCA_PORT_INVALID
530 530 * IBT_HCA_INVALID
531 531 * Description:
532 532 * Returns HCA port attributes for one of the HCA ports.
533 533 */
534 534 ibt_status_t
535 535 ibt_get_port_state_byguid(ib_guid_t hca_guid, uint8_t port,
536 536 ib_gid_t *sgid_p, ib_lid_t *base_lid_p)
537 537 {
538 538 ibtl_hca_devinfo_t *hca_devp; /* HCA Dev Info */
539 539 ibt_status_t retval;
540 540
541 541 IBTF_DPRINTF_L3(ibtf_hca, "ibt_get_port_state_byguid(%llx, %d, %p, "
542 542 "%p)", (longlong_t)hca_guid, port, sgid_p, base_lid_p);
543 543 mutex_enter(&ibtl_clnt_list_mutex);
544 544 hca_devp = ibtl_get_hcadevinfo(hca_guid);
545 545 if (hca_devp == NULL)
546 546 retval = IBT_HCA_INVALID;
547 547 else
548 548 retval = ibtl_get_port_state(hca_devp, port, sgid_p,
549 549 base_lid_p);
550 550 mutex_exit(&ibtl_clnt_list_mutex);
551 551 return (retval);
552 552 }
553 553
554 554
555 555 /*
556 556 * Function:
557 557 * ibt_query_hca_byguid
558 558 * Input:
559 559 * hca_guid - The HCA node GUID.
560 560 * Output:
561 561 * hca_attrs - A pointer to a ibt_hca_attr_t allocated by the caller,
562 562 * into which the HCA Attributes are copied.
563 563 * Returns:
564 564 * IBT_SUCCESS
565 565 * IBT_INVALID_PARAM
566 566 * IBT_HCA_INVALID
567 567 * Description:
568 568 * Returns the static attributes of the specified HCA.
569 569 */
570 570 ibt_status_t
571 571 ibt_query_hca_byguid(ib_guid_t hca_guid, ibt_hca_attr_t *hca_attrs)
572 572 {
573 573 ibtl_hca_devinfo_t *hca_devp; /* HCA Dev Info. */
574 574
575 575 IBTF_DPRINTF_L3(ibtf_hca, "ibt_query_hca_byguid(%llX)", hca_guid);
576 576
577 577 mutex_enter(&ibtl_clnt_list_mutex);
578 578 /* Get HCA Dev Info Structure, referenced by HCA GUID. */
579 579 hca_devp = ibtl_get_hcadevinfo(hca_guid);
580 580 if (hca_devp == NULL) {
581 581 /*
582 582 * If we are here, then the requested HCA device is not present.
583 583 */
584 584 mutex_exit(&ibtl_clnt_list_mutex);
585 585 IBTF_DPRINTF_L2(ibtf_hca, "ibt_query_hca_byguid: "
586 586 "Device Not Found");
587 587 return (IBT_HCA_INVALID);
588 588 }
589 589
590 590 /* Return back the static HCA attributes */
591 591 bcopy(hca_devp->hd_hca_attr, hca_attrs, sizeof (ibt_hca_attr_t));
592 592
593 593 mutex_exit(&ibtl_clnt_list_mutex);
594 594
595 595 return (IBT_SUCCESS);
596 596 }
597 597
598 598
599 599 /*
600 600 * Function:
601 601 * ibt_query_hca
602 602 * Input:
603 603 * hca_hdl - The HCA handle.
604 604 * Output:
605 605 * hca_attrs - A pointer to a ibt_hca_attr_t allocated by the caller,
606 606 * into which the HCA Attributes are copied.
607 607 * Returns:
608 608 * IBT_SUCCESS
609 609 *
610 610 * Description:
611 611 * Returns the static attributes of the specified HCA.
612 612 */
613 613 ibt_status_t
614 614 ibt_query_hca(ibt_hca_hdl_t hca_hdl, ibt_hca_attr_t *hca_attrs)
615 615 {
616 616 IBTF_DPRINTF_L3(ibtf_hca, "ibt_query_hca(%p)", hca_hdl);
617 617
618 618 /* Return back the static HCA attributes */
619 619 bcopy(hca_hdl->ha_hca_devp->hd_hca_attr, hca_attrs,
620 620 sizeof (ibt_hca_attr_t));
621 621
622 622 return (IBT_SUCCESS);
623 623 }
624 624
625 625 #define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
626 626
627 627 /*
628 628 * Function:
629 629 * ibt_query_hca_ports
630 630 * Input:
631 631 * hca_hdl - The HCA handle.
632 632 * port - Port number. If "0", then query ALL Ports.
633 633 * Output:
634 634 * port_info_p - The address of a pointer to a ibt_hca_portinfo_t struct.
635 635 * ports_p - The number of hca ports on the specified HCA.
636 636 * size_p - Size of the memory allocated by IBTL to get portinfo,
637 637 * to be freed by calling ibt_free_portinfo().
638 638 * Returns:
639 639 * IBT_SUCCESS
640 640 * IBT_HCA_HDL_INVALID
641 641 * IBT_HCA_INVALID
642 642 * Description:
643 643 * Returns HCA port attributes for either "one", or "all" of the HCA ports.
644 644 */
645 645 ibt_status_t
646 646 ibt_query_hca_ports(ibt_hca_hdl_t hca_hdl, uint8_t port,
647 647 ibt_hca_portinfo_t **port_info_p, uint_t *ports_p, uint_t *size_p)
648 648 {
649 649 ibt_status_t retval;
650 650
651 651 IBTF_DPRINTF_L3(ibtf_hca, "ibt_query_hca_ports(%p, %d)",
652 652 hca_hdl, port);
653 653
654 654 mutex_enter(&ibtl_clnt_list_mutex);
655 655
656 656 retval = ibtl_query_hca_ports(hca_hdl->ha_hca_devp, port, port_info_p,
657 657 ports_p, size_p, 0);
658 658
659 659 mutex_exit(&ibtl_clnt_list_mutex);
660 660
661 661 return (retval);
662 662 }
663 663
664 664 /*
665 665 * Function:
666 666 * ibt_query_hca_ports_byguid
667 667 * Input:
668 668 * hca_guid - The HCA node GUID.
669 669 * port - Port number. If "0", then query ALL Ports.
670 670 * Output:
671 671 * port_info_p - The address of a pointer to a ibt_hca_portinfo_t struct.
672 672 * ports_p - The number of hca ports on the specified HCA.
673 673 * size_p - Size of the memory allocated by IBTL to get portinfo,
674 674 * to be freed by calling ibt_free_portinfo().
675 675 * Returns:
676 676 * IBT_SUCCESS
677 677 * IBT_HCA_HDL_INVALID
678 678 * IBT_HCA_INVALID
679 679 * Description:
680 680 * Returns HCA port attributes for either "one", or "all" of the HCA ports.
681 681 */
682 682 ibt_status_t
683 683 ibt_query_hca_ports_byguid(ib_guid_t hca_guid, uint8_t port,
684 684 ibt_hca_portinfo_t **port_info_p, uint_t *ports_p, uint_t *size_p)
685 685 {
686 686 ibtl_hca_devinfo_t *hca_devp; /* HCA Dev Info */
687 687 ibt_status_t retval;
688 688
689 689 mutex_enter(&ibtl_clnt_list_mutex);
690 690 hca_devp = ibtl_get_hcadevinfo(hca_guid);
691 691 if (hca_devp == NULL) {
692 692 /*
693 693 * If we are here, then the requested HCA device is not present.
694 694 * Return the status as Invalid HCA GUID.
695 695 */
696 696 *ports_p = *size_p = 0;
697 697 *port_info_p = NULL;
698 698 mutex_exit(&ibtl_clnt_list_mutex);
699 699 IBTF_DPRINTF_L2(ibtf_hca, "ibt_query_hca_ports_byguid: "
700 700 "HCA Device Not Found. ");
701 701 return (IBT_HCA_INVALID);
702 702 }
703 703
704 704 retval = ibtl_query_hca_ports(hca_devp, port, port_info_p, ports_p,
705 705 size_p, 0);
706 706
707 707 mutex_exit(&ibtl_clnt_list_mutex);
708 708
709 709 return (retval);
710 710 }
711 711
712 712 /*
713 713 * Define the above function for CM's use that uses the cached copy.
714 714 */
715 715 ibt_status_t
716 716 ibtl_cm_query_hca_ports_byguid(ib_guid_t hca_guid, uint8_t port,
717 717 ibt_hca_portinfo_t **port_info_p, uint_t *ports_p, uint_t *size_p)
718 718 {
719 719 ibtl_hca_devinfo_t *hca_devp; /* HCA Dev Info */
720 720 ibt_status_t retval;
721 721
722 722 mutex_enter(&ibtl_clnt_list_mutex);
723 723 hca_devp = ibtl_get_hcadevinfo(hca_guid);
724 724 if (hca_devp == NULL) {
725 725 /*
726 726 * If we are here, then the requested HCA device is not present.
727 727 * Return the status as Invalid HCA GUID.
728 728 */
729 729 *ports_p = *size_p = 0;
730 730 *port_info_p = NULL;
731 731 mutex_exit(&ibtl_clnt_list_mutex);
732 732 IBTF_DPRINTF_L2(ibtf_hca, "ibt_query_hca_ports_byguid: "
733 733 "HCA Device Not Found. ");
734 734 return (IBT_HCA_INVALID);
735 735 }
736 736
737 737 retval = ibtl_query_hca_ports(hca_devp, port, port_info_p, ports_p,
738 738 size_p, 1);
739 739
740 740 mutex_exit(&ibtl_clnt_list_mutex);
741 741
742 742 return (retval);
743 743 }
744 744
745 745
746 746 /*
747 747 * ibtl_query_one_port - fill in portinfo for one port.
748 748 */
749 749 static ibt_status_t
750 750 ibtl_query_one_port(ibtl_hca_devinfo_t *hca_devp, uint8_t port,
751 751 ibt_hca_portinfo_t **port_info_p, uint_t *ports_p, uint_t *size_p,
752 752 int use_cache)
753 753 {
754 754 ibt_hca_portinfo_t *sp1; /* src */
755 755 ibt_hca_portinfo_t *p1; /* dst */
756 756 caddr_t p2;
757 757 uint_t len;
758 758 uint_t sgid_tbl_len, pkey_tbl_len;
759 759
760 760 ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
761 761
762 762 IBTF_DPRINTF_L3(ibtf_hca, "ibtl_query_one_port(%p, %d)",
763 763 hca_devp, port);
764 764
765 765 if (port > hca_devp->hd_hca_attr->hca_nports) {
766 766 IBTF_DPRINTF_L2(ibtf_hca, "ibtl_query_one_port: "
767 767 "invalid port %d", port);
768 768 return (IBT_HCA_PORT_INVALID);
769 769 }
770 770
771 771 /* If the PORT_UP event is not supported, we need to query */
772 772 sp1 = hca_devp->hd_portinfop + port - 1;
773 773 if (use_cache == 0)
774 774 ibtl_reinit_hca_portinfo(hca_devp, port);
775 775
776 776 *ports_p = 1;
777 777
778 778 /*
779 779 * Calculate how much memory we need for one port, and allocate it.
780 780 */
781 781 sgid_tbl_len = ROUNDUP(sp1->p_sgid_tbl_sz * sizeof (ib_gid_t),
782 782 _LONG_LONG_ALIGNMENT);
783 783 pkey_tbl_len = ROUNDUP(sp1->p_pkey_tbl_sz * sizeof (ib_pkey_t),
784 784 _LONG_LONG_ALIGNMENT);
785 785
786 786 len = sizeof (ibt_hca_portinfo_t) + sgid_tbl_len + pkey_tbl_len;
787 787 *size_p = len;
788 788
789 789 p1 = kmem_zalloc(len, KM_SLEEP);
790 790 *port_info_p = p1;
791 791 bcopy(sp1, p1, sizeof (ibt_hca_portinfo_t));
792 792
793 793 /* initialize the p_pkey_tbl & p_sgid_tbl pointers. */
794 794 p2 = (caddr_t)(p1 + 1); /* pkeys follow the struct ibt_hca_portinfo_s */
795 795 bcopy(sp1->p_pkey_tbl, p2, pkey_tbl_len);
796 796 p1->p_pkey_tbl = (ib_pkey_t *)p2;
797 797
798 798 p2 += pkey_tbl_len; /* sgids follow the pkeys */
799 799 bcopy(sp1->p_sgid_tbl, p2, sgid_tbl_len);
800 800 p1->p_sgid_tbl = (ib_gid_t *)p2;
801 801
802 802 return (IBT_SUCCESS);
803 803 }
804 804
805 805 /*
806 806 * ibtl_query_hca_ports - worker routine to get port_info for clients.
807 807 */
808 808 static ibt_status_t
809 809 ibtl_query_hca_ports(ibtl_hca_devinfo_t *hca_devp, uint8_t port,
810 810 ibt_hca_portinfo_t **port_info_p, uint_t *ports_p, uint_t *size_p,
811 811 int use_cache)
812 812 {
813 813 ibt_hca_portinfo_t *sp1; /* src */
814 814 ibt_hca_portinfo_t *p1; /* dst */
815 815 uint_t i, nports;
816 816 caddr_t p2;
817 817 uint_t len;
818 818 uint_t sgid_tbl_len, pkey_tbl_len;
819 819
820 820 ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
821 821
822 822 /*
823 823 * If user has specified the port num, then query only that port,
824 824 * else query all ports.
825 825 */
826 826 if (port)
827 827 return (ibtl_query_one_port(hca_devp, port, port_info_p,
828 828 ports_p, size_p, use_cache));
829 829
830 830 IBTF_DPRINTF_L3(ibtf_hca, "ibtl_query_hca_ports(%p, ALL)", hca_devp);
831 831
832 832 nports = hca_devp->hd_hca_attr->hca_nports;
833 833 *ports_p = nports;
834 834
835 835 /* If the PORT_UP event is not supported, we need to query */
836 836 if (use_cache == 0)
837 837 for (i = 0; i < nports; i++)
838 838 ibtl_reinit_hca_portinfo(hca_devp, i + 1);
839 839
840 840 sp1 = hca_devp->hd_portinfop;
841 841
842 842 /*
843 843 * Calculate how much memory we need for all ports, and allocate it.
844 844 */
845 845 sgid_tbl_len = ROUNDUP(sp1->p_sgid_tbl_sz * sizeof (ib_gid_t),
846 846 _LONG_LONG_ALIGNMENT);
847 847 pkey_tbl_len = ROUNDUP(sp1->p_pkey_tbl_sz * sizeof (ib_pkey_t),
848 848 _LONG_LONG_ALIGNMENT);
849 849
850 850 len = (sizeof (ibt_hca_portinfo_t) + sgid_tbl_len + pkey_tbl_len) *
851 851 nports;
852 852 *size_p = len;
853 853
854 854 ASSERT(len == hca_devp->hd_portinfo_len);
855 855
856 856 p1 = kmem_zalloc(len, KM_SLEEP);
857 857 *port_info_p = p1;
858 858 bcopy(sp1, p1, len); /* start with an exact copy of our cache */
859 859
860 860 p2 = (caddr_t)(p1 + nports);
861 861
862 862 /* For each port, update the p_pkey_tbl & p_sgid_tbl ptrs. */
863 863 for (i = 0; i < nports; i++) {
864 864 p1->p_pkey_tbl = (ib_pkey_t *)p2;
865 865 p2 += pkey_tbl_len;
866 866 p1->p_sgid_tbl = (ib_gid_t *)p2;
867 867 p2 += sgid_tbl_len;
868 868 p1++;
869 869 }
870 870 return (IBT_SUCCESS);
871 871 }
872 872
873 873 /*
874 874 * Search for a Full pkey. Use the pkey at index 0 if not found.
875 875 */
876 876 static void
877 877 ibtl_set_default_pkey_ix(ibt_hca_portinfo_t *p1)
878 878 {
879 879 uint16_t pkey_ix;
880 880
881 881 for (pkey_ix = 0; pkey_ix < p1->p_pkey_tbl_sz; pkey_ix++) {
882 882 if ((p1->p_pkey_tbl[pkey_ix] & 0x8000) &&
883 883 (p1->p_pkey_tbl[pkey_ix] != IB_PKEY_INVALID_FULL)) {
884 884 p1->p_def_pkey_ix = pkey_ix;
885 885 IBTF_DPRINTF_L3(ibtf_hca,
886 886 "ibtl_set_default_pkey_ix: portinfop %p, "
887 887 "FULL PKEY 0x%x found, pkey_ix is %d",
888 888 p1, p1->p_pkey_tbl[pkey_ix], pkey_ix);
889 889 return;
890 890 }
891 891 }
892 892 IBTF_DPRINTF_L2(ibtf_hca,
893 893 "ibtl_set_default_pkey_ix: portinfop %p: failed "
894 894 "to find a default PKEY in the table, using PKey 0x%x",
895 895 p1, p1->p_pkey_tbl[0]);
896 896 p1->p_def_pkey_ix = 0;
897 897 }
898 898
899 899 /*
900 900 * ibtl_reinit_hca_portinfo - update the portinfo cache for use by IBTL.
901 901 *
902 902 * We have the HCA driver fill in a temporary portinfo, then we bcopy
903 903 * it into our cache while holding the appropriate lock.
904 904 */
905 905 void
906 906 ibtl_reinit_hca_portinfo(ibtl_hca_devinfo_t *hca_devp, uint8_t port)
907 907 {
908 908 ibt_status_t status;
909 909 ibt_hca_portinfo_t *p1, *sp1;
910 910 ibt_port_state_t old_linkstate;
911 911 uint_t len, sgid_tbl_len, pkey_tbl_len;
912 912 ib_pkey_t *saved_pkey_tbl;
913 913 ib_gid_t *saved_sgid_tbl;
914 914 ib_sn_prefix_t sn_pfx = 0;
915 915 uint_t multiSM;
916 916 int i;
917 917
918 918 IBTF_DPRINTF_L3(ibtf_hca, "ibtl_reinit_hca_portinfo(%p, %d)",
919 919 hca_devp, port);
920 920
921 921 ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
922 922 ASSERT(port != 0);
923 923
924 924 if (ibtl_portinfo_locked(hca_devp, port)) {
925 925 /* we got the lock, so we need to do the portinfo update */
926 926
927 927 /* invalidate fast_gid_cache */
928 928 ibtl_fast_gid_cache_valid = B_FALSE;
929 929
930 930 p1 = hca_devp->hd_portinfop + port - 1;
931 931 sgid_tbl_len = ROUNDUP(p1->p_sgid_tbl_sz * sizeof (ib_gid_t),
932 932 _LONG_LONG_ALIGNMENT);
933 933 pkey_tbl_len = ROUNDUP(p1->p_pkey_tbl_sz * sizeof (ib_pkey_t),
934 934 _LONG_LONG_ALIGNMENT);
935 935 len = sizeof (ibt_hca_portinfo_t) + sgid_tbl_len + pkey_tbl_len;
936 936
937 937 /* update was NOT in progress, so we do it here */
938 938 mutex_exit(&ibtl_clnt_list_mutex);
939 939
940 940 IBTF_DPRINTF_L3(ibtf_hca, "ibtl_reinit_hca_portinfo(%p, %d): "
941 941 "calling ibc_query_hca_ports", hca_devp, port);
942 942
943 943 sp1 = kmem_zalloc(len, KM_SLEEP);
944 944 sp1->p_pkey_tbl = (ib_pkey_t *)(sp1 + 1);
945 945 sp1->p_sgid_tbl =
946 946 (ib_gid_t *)((caddr_t)sp1->p_pkey_tbl + pkey_tbl_len);
947 947 status = IBTL_HDIP2CIHCAOPS_P(hca_devp)->ibc_query_hca_ports(
948 948 IBTL_HDIP2CIHCA(hca_devp), port, sp1);
949 949
950 950 mutex_enter(&ibtl_clnt_list_mutex);
951 951 if (status != IBT_SUCCESS) {
952 952 IBTF_DPRINTF_L2(ibtf_hca,
953 953 "ibtl_reinit_hca_portinfo(%p, %d): "
954 954 "ibc_query_hca_ports() failed: status = %d",
955 955 hca_devp, port, status);
956 956 } else {
957 957 old_linkstate = p1->p_linkstate;
958 958 bcopy(sp1->p_pkey_tbl, p1->p_pkey_tbl, pkey_tbl_len);
959 959 bcopy(sp1->p_sgid_tbl, p1->p_sgid_tbl, sgid_tbl_len);
960 960 saved_pkey_tbl = p1->p_pkey_tbl;
961 961 saved_sgid_tbl = p1->p_sgid_tbl;
962 962 bcopy(sp1, p1, sizeof (ibt_hca_portinfo_t));
963 963 p1->p_pkey_tbl = saved_pkey_tbl;
964 964 p1->p_sgid_tbl = saved_sgid_tbl;
965 965 if (p1->p_linkstate == IBT_PORT_ACTIVE) {
966 966 ibtl_set_default_pkey_ix(p1);
967 967 if (p1->p_linkstate != old_linkstate)
968 968 IBTF_DPRINTF_L2(ibtf_hca,
969 969 "ibtl_reinit_hca_portinfo(%p, %d): "
970 970 "PORT UP", hca_devp, port);
971 971 } else {
972 972 if (p1->p_linkstate != IBT_PORT_ARM)
973 973 p1->p_base_lid = 0;
974 974 if (p1->p_linkstate != old_linkstate)
975 975 IBTF_DPRINTF_L2(ibtf_hca,
976 976 "ibtl_reinit_hca_portinfo(%p, %d): "
977 977 "PORT DOWN", hca_devp, port);
978 978 }
979 979 }
980 980 kmem_free(sp1, len);
981 981
982 982 /* Set multism bit accordingly. */
983 983 multiSM = 0;
984 984 p1 = hca_devp->hd_portinfop;
985 985 for (i = 0; i < hca_devp->hd_hca_attr->hca_nports; i++) {
986 986 if (p1->p_linkstate == IBT_PORT_ACTIVE) {
987 987 if (sn_pfx == 0) {
988 988 sn_pfx = p1->p_sgid_tbl[0].gid_prefix;
989 989 } else if (sn_pfx !=
990 990 p1->p_sgid_tbl[0].gid_prefix) {
991 991 multiSM = 1;
992 992 IBTF_DPRINTF_L3(ibtf_hca,
993 993 "ibtl_reinit_hca_portinfo: "
994 994 "MULTI SM, Port1 SnPfx=0x%llX, "
995 995 "Port2 SnPfx=0x%llX", sn_pfx,
996 996 p1->p_sgid_tbl[0].gid_prefix);
997 997 }
998 998 }
999 999 p1++;
1000 1000 }
1001 1001 hca_devp->hd_multism = multiSM;
1002 1002
1003 1003 ibtl_portinfo_unlock(hca_devp, port);
1004 1004 }
1005 1005 }
1006 1006
1007 1007 /*
1008 1008 * ibtl_init_hca_portinfo - fill in the portinfo cache for use by IBTL.
1009 1009 */
1010 1010 ibt_status_t
1011 1011 ibtl_init_hca_portinfo(ibtl_hca_devinfo_t *hca_devp)
1012 1012 {
1013 1013 ibt_hca_portinfo_t *p1;
1014 1014 ibt_status_t retval;
1015 1015 uint_t i, nports;
1016 1016 caddr_t p2;
1017 1017 uint_t len;
1018 1018 uint_t sgid_tbl_len, pkey_tbl_len;
1019 1019 uint_t sgid_tbl_sz, pkey_tbl_sz;
1020 1020 ib_sn_prefix_t sn_pfx = 0;
1021 1021 uint_t multiSM;
1022 1022
1023 1023 IBTF_DPRINTF_L2(ibtf_hca, "ibtl_init_hca_portinfo(%p)", hca_devp);
1024 1024
1025 1025 ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
1026 1026
1027 1027 nports = hca_devp->hd_hca_attr->hca_nports;
1028 1028
1029 1029 /*
1030 1030 * Calculate how much memory we need for all ports, and allocate it.
1031 1031 */
1032 1032 pkey_tbl_sz = IBTL_HDIP2PKEYTBLSZ(hca_devp);
1033 1033 sgid_tbl_sz = IBTL_HDIP2SGIDTBLSZ(hca_devp);
1034 1034 pkey_tbl_len = ROUNDUP(pkey_tbl_sz * sizeof (ib_pkey_t),
1035 1035 _LONG_LONG_ALIGNMENT);
1036 1036 sgid_tbl_len = ROUNDUP(sgid_tbl_sz * sizeof (ib_gid_t),
1037 1037 _LONG_LONG_ALIGNMENT);
1038 1038
1039 1039 len = (sizeof (ibt_hca_portinfo_t) + sgid_tbl_len + pkey_tbl_len) *
1040 1040 nports;
1041 1041
1042 1042 p1 = kmem_zalloc(len, KM_SLEEP);
1043 1043 p2 = (caddr_t)(p1 + nports);
1044 1044
1045 1045 hca_devp->hd_portinfop = p1;
1046 1046 hca_devp->hd_portinfo_len = len;
1047 1047
1048 1048 /* For each port initialize the p_pkey_tbl & p_sgid_tbl ptrs. */
1049 1049 for (i = 0; i < nports; i++) {
1050 1050 p1->p_pkey_tbl_sz = pkey_tbl_sz;
1051 1051 p1->p_sgid_tbl_sz = sgid_tbl_sz;
1052 1052 p1->p_pkey_tbl = (ib_pkey_t *)p2;
1053 1053 p2 += pkey_tbl_len;
1054 1054 p1->p_sgid_tbl = (ib_gid_t *)p2;
1055 1055 p2 += sgid_tbl_len;
1056 1056 p1++;
1057 1057 }
1058 1058 p1 = hca_devp->hd_portinfop;
1059 1059 mutex_exit(&ibtl_clnt_list_mutex);
1060 1060
1061 1061 /* re-direct the call to CI's call */
1062 1062 retval = IBTL_HDIP2CIHCAOPS_P(hca_devp)->ibc_query_hca_ports(
1063 1063 IBTL_HDIP2CIHCA(hca_devp), 0, p1);
1064 1064
1065 1065 mutex_enter(&ibtl_clnt_list_mutex);
1066 1066 if (retval != IBT_SUCCESS) {
1067 1067 IBTF_DPRINTF_L2(ibtf_hca, "ibtl_init_hca_portinfo(%p): "
1068 1068 "ibc_query_hca_ports() failed: status = %d",
1069 1069 hca_devp, retval);
1070 1070 kmem_free(hca_devp->hd_portinfop, len);
1071 1071 hca_devp->hd_portinfop = NULL;
1072 1072 hca_devp->hd_portinfo_len = 0;
1073 1073 return (retval);
1074 1074 }
1075 1075
1076 1076 p1 = hca_devp->hd_portinfop;
1077 1077 multiSM = 0;
1078 1078 for (i = 0; i < nports; i++) {
1079 1079 if (p1->p_linkstate == IBT_PORT_ACTIVE) {
1080 1080 ibtl_set_default_pkey_ix(p1);
1081 1081 if (sn_pfx == 0) {
1082 1082 sn_pfx = p1->p_sgid_tbl[0].gid_prefix;
1083 1083 } else if (p1->p_sgid_tbl[0].gid_prefix != sn_pfx) {
1084 1084 multiSM = 1;
1085 1085 IBTF_DPRINTF_L3(ibtf_hca,
1086 1086 "ibtl_init_hca_portinfo: MULTI SM, "
1087 1087 "Port1 SnPfx=0x%llX, Port2 SnPfx=0x%llX",
1088 1088 sn_pfx, p1->p_sgid_tbl[0].gid_prefix);
1089 1089 }
1090 1090 } else {
1091 1091 if (p1->p_linkstate != IBT_PORT_ARM)
1092 1092 p1->p_base_lid = 0;
1093 1093 }
1094 1094 p1++;
1095 1095 }
1096 1096 hca_devp->hd_multism = multiSM;
1097 1097
1098 1098 return (IBT_SUCCESS);
1099 1099 }
1100 1100
1101 1101 /*
1102 1102 * Function:
1103 1103 * ibt_modify_system_image
1104 1104 * Input:
1105 1105 * hca_hdl - The HCA handle.
1106 1106 * sys_guid - The New system image GUID.
1107 1107 * Description:
1108 1108 * Modify specified HCA's system image GUID.
1109 1109 */
1110 1110 ibt_status_t
1111 1111 ibt_modify_system_image(ibt_hca_hdl_t hca_hdl, ib_guid_t sys_guid)
1112 1112 {
1113 1113 ibt_status_t retval;
1114 1114
1115 1115 IBTF_DPRINTF_L3(ibtf_hca, "ibt_modify_system_image(%p, %llX)",
1116 1116 hca_hdl, sys_guid);
1117 1117
1118 1118 mutex_enter(&ibtl_clnt_list_mutex);
1119 1119 /* Get HCA Dev Info Structure, referenced by HCA GUID. */
1120 1120
1121 1121 /* re-direct the call to CI's call */
1122 1122 retval = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_modify_system_image(
1123 1123 IBTL_HCA2CIHCA(hca_hdl), sys_guid);
1124 1124
1125 1125 mutex_exit(&ibtl_clnt_list_mutex);
1126 1126 return (retval);
1127 1127 }
1128 1128
1129 1129 /*
1130 1130 * Function:
1131 1131 * ibt_modify_system_image_byguid
1132 1132 *
1133 1133 * Input:
1134 1134 * hca_guid - The HCA Node GUID.
1135 1135 * sys_guid - The New system image GUID.
1136 1136 * Description:
1137 1137 * Modify specified HCA's system image GUID.
1138 1138 */
1139 1139 ibt_status_t
1140 1140 ibt_modify_system_image_byguid(ib_guid_t hca_guid, ib_guid_t sys_guid)
1141 1141 {
1142 1142 ibtl_hca_devinfo_t *hca_devp; /* HCA Dev Info. */
1143 1143 ibt_status_t retval;
1144 1144
1145 1145 IBTF_DPRINTF_L3(ibtf_hca, "ibt_modify_system_image_byguid(%llX, %llX)",
1146 1146 hca_guid, sys_guid);
1147 1147
1148 1148 mutex_enter(&ibtl_clnt_list_mutex);
1149 1149 /* Get HCA Dev Info Structure, referenced by HCA GUID. */
1150 1150 hca_devp = ibtl_get_hcadevinfo(hca_guid);
1151 1151 if (hca_devp == NULL) {
1152 1152 /*
1153 1153 * If we are here, then the requested HCA device is not present.
1154 1154 */
1155 1155 mutex_exit(&ibtl_clnt_list_mutex);
1156 1156 return (IBT_HCA_INVALID);
1157 1157 }
1158 1158
1159 1159 /* re-direct the call to CI's call */
1160 1160 retval = IBTL_HDIP2CIHCAOPS_P(hca_devp)->ibc_modify_system_image(
1161 1161 IBTL_HDIP2CIHCA(hca_devp), sys_guid);
1162 1162
1163 1163 mutex_exit(&ibtl_clnt_list_mutex);
1164 1164 return (retval);
1165 1165 }
1166 1166
1167 1167 /*
1168 1168 * Function:
1169 1169 * ibt_modify_port_byguid
1170 1170 * Input:
1171 1171 * hca_guid - The HCA Guid.
1172 1172 * cmds - A pointer to an array of ibt_port_modify_t cmds. The
1173 1173 * pmod_port field specifies the port to modify (all ports if 0)
1174 1174 * and the pmod_flags field specifies which attribute to reset.
1175 1175 * num_cmds - The number of commands in the cmds array.
1176 1176 * Output:
1177 1177 * none.
1178 1178 * Returns:
1179 1179 * IBT_SUCCESS
1180 1180 * IBT_HCA_HDL_INVALID
1181 1181 * IBT_HCA_CNTR_INVALID
1182 1182 * IBT_HCA_CNTR_VAL_INVALID
1183 1183 * Description:
1184 1184 * Reset the specified port, or all ports attribute(s).
1185 1185 */
1186 1186 ibt_status_t
1187 1187 ibt_modify_port_byguid(ib_guid_t hca_guid, uint8_t port,
1188 1188 ibt_port_modify_flags_t flags, uint8_t init_type)
1189 1189 {
1190 1190 ibtl_hca_devinfo_t *hca_devp; /* HCA Dev Info. */
1191 1191 ibt_status_t retval;
1192 1192
1193 1193 IBTF_DPRINTF_L3(ibtf_hca, "ibt_modify_port_byguid(%llX, %d, %X, %X)",
1194 1194 hca_guid, port, flags, init_type);
1195 1195
1196 1196 mutex_enter(&ibtl_clnt_list_mutex);
1197 1197 /* Get HCA Dev Info Structure, referenced by HCA GUID. */
1198 1198 hca_devp = ibtl_get_hcadevinfo(hca_guid);
1199 1199 if (hca_devp == NULL) {
1200 1200 /*
1201 1201 * If we are here, then the requested HCA device is not present.
1202 1202 */
1203 1203 mutex_exit(&ibtl_clnt_list_mutex);
1204 1204 return (IBT_HCA_INVALID);
1205 1205 }
1206 1206
1207 1207 /* re-direct the call to CI's call */
1208 1208 retval = IBTL_HDIP2CIHCAOPS_P(hca_devp)->ibc_modify_ports(
1209 1209 IBTL_HDIP2CIHCA(hca_devp), port, flags, init_type);
1210 1210
1211 1211 mutex_exit(&ibtl_clnt_list_mutex);
1212 1212 return (retval);
1213 1213 }
1214 1214
1215 1215 /*
1216 1216 * Function:
1217 1217 * ibt_modify_port
1218 1218 * Input:
1219 1219 * hca_hdl - The HCA handle.
1220 1220 * cmds - A pointer to an array of ibt_port_modify_t cmds. The
1221 1221 * pmod_port field specifies the port to modify (all ports if 0)
1222 1222 * and the pmod_flags field specifies which attribute to reset.
1223 1223 * num_cmds - The number of commands in the cmds array.
1224 1224 * Output:
1225 1225 * none.
1226 1226 * Returns:
1227 1227 * IBT_SUCCESS
1228 1228 * IBT_HCA_HDL_INVALID
1229 1229 * IBT_HCA_CNTR_INVALID
1230 1230 * IBT_HCA_CNTR_VAL_INVALID
1231 1231 * Description:
1232 1232 * Reset the specified port, or all ports attribute(s).
1233 1233 */
1234 1234 ibt_status_t
1235 1235 ibt_modify_port(ibt_hca_hdl_t hca_hdl, uint8_t port,
1236 1236 ibt_port_modify_flags_t flags, uint8_t init_type)
1237 1237
1238 1238 {
1239 1239 ibt_status_t retval;
1240 1240
1241 1241 IBTF_DPRINTF_L3(ibtf_hca, "ibt_modify_port(%p, %d, %X, %X)",
1242 1242 hca_hdl, port, flags, init_type);
1243 1243
1244 1244 mutex_enter(&ibtl_clnt_list_mutex);
1245 1245
1246 1246 /* re-direct the call to CI's call */
1247 1247 retval = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_modify_ports(
1248 1248 IBTL_HCA2CIHCA(hca_hdl), port, flags, init_type);
1249 1249
1250 1250 mutex_exit(&ibtl_clnt_list_mutex);
1251 1251 return (retval);
1252 1252 }
1253 1253
1254 1254 /*
1255 1255 * Function:
1256 1256 * ibt_free_portinfo
1257 1257 * Input:
1258 1258 * port_info - The address of an array to a ibt_hca_portinfo_t struct.
1259 1259 * size - Memory Size as returned from ibt_query_hca_ports().
1260 1260 * Output:
1261 1261 * none
1262 1262 * Returns:
1263 1263 * none
1264 1264 * Description:
1265 1265 * Frees the memory allocated for a specified ibt_hca_portinfo_t struct.
1266 1266 */
1267 1267 void
1268 1268 ibt_free_portinfo(ibt_hca_portinfo_t *port_info, uint_t size)
1269 1269 {
1270 1270 IBTF_DPRINTF_L3(ibtf_hca, "ibt_free_portinfo(%p, %d)",
1271 1271 port_info, size);
1272 1272
1273 1273 if ((port_info == NULL) || (size == 0)) {
1274 1274 IBTF_DPRINTF_L2(ibtf_hca, "ibt_free_portinfo: NULL Pointer");
1275 1275 } else {
1276 1276 kmem_free(port_info, size);
1277 1277 }
1278 1278 }
1279 1279
1280 1280
1281 1281 /*
1282 1282 * Function:
1283 1283 * ibt_get_hcadevinfo
1284 1284 * Input:
1285 1285 * hca_guid - The HCA's node GUID.
1286 1286 * Output:
1287 1287 * none.
1288 1288 * Returns:
1289 1289 * Pointer to HCA Device Info structure whose HCA GUID is requested or NULL
1290 1290 * Description:
1291 1291 * Get a pointer to HCA Device Info Structure for the requested HCA GUID.
1292 1292 * If no matching HCA GUID Device info is found, NULL is returned.
1293 1293 */
1294 1294 ibtl_hca_devinfo_t *
1295 1295 ibtl_get_hcadevinfo(ib_guid_t hca_guid)
1296 1296 {
1297 1297 ibtl_hca_devinfo_t *hca_devp; /* HCA Dev Info */
1298 1298
1299 1299 IBTF_DPRINTF_L3(ibtf_hca, "ibtl_get_hcadevinfo(%llX)", hca_guid);
1300 1300
1301 1301 ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
1302 1302
1303 1303 hca_devp = ibtl_hca_list;
1304 1304
1305 1305 /*
1306 1306 * Check whether a HCA device with requested Node GUID is available.
1307 1307 * This is done, by searching the global HCA devinfo list and
1308 1308 * comparing the Node GUID from the device attribute info.
1309 1309 */
1310 1310 while (hca_devp != NULL) {
1311 1311 if (hca_devp->hd_hca_attr->hca_node_guid == hca_guid) {
1312 1312 /* Match Found. */
1313 1313 break;
1314 1314 }
1315 1315 hca_devp = hca_devp->hd_hca_dev_link;
1316 1316 }
1317 1317 return (hca_devp);
1318 1318 }
1319 1319
1320 1320
1321 1321 /*
1322 1322 * Function:
1323 1323 * ibtl_pkey2index
1324 1324 * Input:
1325 1325 * hca_devp - The IBTL HCA Device Info.
1326 1326 * port_num - The HCA port number.
1327 1327 * pkey - The input PKey value, whose index we are interested in.
1328 1328 * Output:
1329 1329 * pkey_ix - The PKey index returned for the specified PKey.
1330 1330 * Returns:
1331 1331 * IBT_SUCCESS/IBT_HCA_PORT_INVALID/IBT_INVALID_PARAM
1332 1332 * Description:
1333 1333 * Returns the PKey Index for the specified PKey, the device as specified
1334 1334 * by IBT HCA Handle.
1335 1335 */
1336 1336 static ibt_status_t
1337 1337 ibtl_pkey2index(ibtl_hca_devinfo_t *hca_devp, uint8_t port_num,
1338 1338 ib_pkey_t pkey, uint16_t *pkey_ix)
1339 1339 {
1340 1340 ibt_hca_portinfo_t *port_infop;
1341 1341 uint_t ports;
1342 1342 uint_t i;
1343 1343
1344 1344 IBTF_DPRINTF_L3(ibtf_hca, "ibtl_pkey2index(%p, %d, %d)",
1345 1345 hca_devp, port_num, pkey);
1346 1346
1347 1347 ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
1348 1348
1349 1349 if ((pkey == IB_PKEY_INVALID_FULL) ||
1350 1350 (pkey == IB_PKEY_INVALID_LIMITED))
1351 1351 return (IBT_INVALID_PARAM);
1352 1352
1353 1353 ports = hca_devp->hd_hca_attr->hca_nports;
1354 1354 if ((port_num == 0) || (port_num > ports)) {
1355 1355 IBTF_DPRINTF_L2(ibtf_hca, "ibtl_pkey2index: "
1356 1356 "Invalid port_num %d, range is (1 to %d)", port_num, ports);
1357 1357 return (IBT_HCA_PORT_INVALID);
1358 1358 }
1359 1359
1360 1360 port_infop = hca_devp->hd_portinfop + port_num - 1;
1361 1361 for (i = 0; i < port_infop->p_pkey_tbl_sz; i++) {
1362 1362 if (pkey == port_infop->p_pkey_tbl[i]) {
1363 1363 *pkey_ix = i;
1364 1364 return (IBT_SUCCESS);
1365 1365 }
1366 1366 }
1367 1367 return (IBT_INVALID_PARAM);
1368 1368 }
1369 1369
1370 1370 /*
1371 1371 * Function:
1372 1372 * ibtl_index2pkey
1373 1373 * Input:
1374 1374 * hca_devp - The IBTL HCA Device Info.
1375 1375 * port_num - The HCA port
1376 1376 * pkey_ix - The input PKey index, whose PKey we are interested in.
1377 1377 * Output:
1378 1378 * pkey - The returned PKey value.
1379 1379 * Returns:
1380 1380 * IBT_SUCCESS/IBT_PKEY_IX_ILLEGAL/IBT_PKEY_IX_INVALID/IBT_HCA_PORT_INVALID
1381 1381 * Description:
1382 1382 * Returns the PKey value for the specified PKey index, the device as
1383 1383 * specified by IBT HCA Handle.
1384 1384 */
1385 1385 static ibt_status_t
1386 1386 ibtl_index2pkey(ibtl_hca_devinfo_t *hca_devp, uint8_t port_num,
1387 1387 uint16_t pkey_ix, ib_pkey_t *pkey)
1388 1388 {
1389 1389 ibt_hca_portinfo_t *port_infop;
1390 1390 uint_t ports;
1391 1391
1392 1392 IBTF_DPRINTF_L3(ibtf_hca, "ibtl_index2pkey(%p, %d, %d)",
1393 1393 hca_devp, port_num, pkey_ix);
1394 1394
1395 1395 ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
1396 1396
1397 1397 ports = hca_devp->hd_hca_attr->hca_nports;
1398 1398 if ((port_num == 0) || (port_num > ports)) {
1399 1399 IBTF_DPRINTF_L2(ibtf_hca, "ibtl_index2pkey: "
1400 1400 "Invalid port_num %d, range is (1 to %d)", port_num, ports);
1401 1401 return (IBT_HCA_PORT_INVALID);
1402 1402 }
1403 1403
1404 1404 port_infop = hca_devp->hd_portinfop + port_num - 1;
1405 1405 if (pkey_ix >= port_infop->p_pkey_tbl_sz) {
1406 1406 IBTF_DPRINTF_L2(ibtf_hca, "ibtl_index2pkey: "
1407 1407 "pkey index %d out of range (0, %d)",
1408 1408 pkey_ix, port_infop->p_pkey_tbl_sz - 1);
1409 1409 return (IBT_PKEY_IX_ILLEGAL);
1410 1410 }
1411 1411
1412 1412 *pkey = port_infop->p_pkey_tbl[pkey_ix];
1413 1413 if ((*pkey == IB_PKEY_INVALID_FULL) ||
1414 1414 (*pkey == IB_PKEY_INVALID_LIMITED))
1415 1415 return (IBT_PKEY_IX_INVALID);
1416 1416 return (IBT_SUCCESS);
1417 1417 }
1418 1418
1419 1419 /*
1420 1420 * Function:
1421 1421 * ibt_pkey2index
1422 1422 * Input:
1423 1423 * hca_hdl - The IBT HCA handle.
1424 1424 * port_num - The HCA port number.
1425 1425 * pkey - The input PKey value, whose index we are interested in.
1426 1426 * Output:
1427 1427 * pkey_ix - The PKey index returned for the specified PKey.
1428 1428 * Returns:
1429 1429 * IBT_SUCCESS/IBT_HCA_PORT_INVALID/IBT_INVALID_PARAM
1430 1430 * Description:
1431 1431 * Returns the PKey Index for the specified PKey, the device as specified
1432 1432 * by IBT HCA Handle.
1433 1433 */
1434 1434 ibt_status_t
1435 1435 ibt_pkey2index(ibt_hca_hdl_t hca_hdl, uint8_t port_num, ib_pkey_t pkey,
1436 1436 uint16_t *pkey_ix)
1437 1437 {
1438 1438 ibt_status_t retval;
1439 1439
1440 1440 IBTF_DPRINTF_L3(ibtf_hca, "ibt_pkey2index(%p, %d, %d)",
1441 1441 hca_hdl, port_num, pkey);
1442 1442
1443 1443 mutex_enter(&ibtl_clnt_list_mutex);
1444 1444 retval = ibtl_pkey2index(hca_hdl->ha_hca_devp, port_num, pkey, pkey_ix);
1445 1445 mutex_exit(&ibtl_clnt_list_mutex);
1446 1446
1447 1447 return (retval);
1448 1448 }
1449 1449
1450 1450 /*
1451 1451 * Function:
1452 1452 * ibt_pkey2index_byguid
1453 1453 * Input:
1454 1454 * hca_guid - The HCA's node GUID.
1455 1455 * port_num - The HCA port number.
1456 1456 * pkey - The input PKey value, whose index we are interested in.
1457 1457 * Output:
1458 1458 * pkey_ix - The PKey Index returned for the specified PKey.
1459 1459 * Returns:
1460 1460 * IBT_SUCCESS/IBT_HCA_PORT_INVALID/IBT_INVALID_PARAM/IBT_HCA_INVALID
1461 1461 * Description:
1462 1462 * Returns the PKey Index for the specified PKey, the device as specified
1463 1463 * by HCA GUID Info.
1464 1464 */
1465 1465 ibt_status_t
1466 1466 ibt_pkey2index_byguid(ib_guid_t hca_guid, uint8_t port_num, ib_pkey_t pkey,
1467 1467 uint16_t *pkey_ix)
1468 1468 {
1469 1469 ibt_status_t retval;
1470 1470 ibtl_hca_devinfo_t *hca_devp; /* HCA Dev Info */
1471 1471
1472 1472 IBTF_DPRINTF_L3(ibtf_hca, "ibt_pkey2index_byguid(%llX, %d, %d)",
1473 1473 hca_guid, port_num, pkey);
1474 1474
1475 1475 mutex_enter(&ibtl_clnt_list_mutex);
1476 1476 hca_devp = ibtl_get_hcadevinfo(hca_guid);
1477 1477 if (hca_devp == NULL) {
1478 1478 IBTF_DPRINTF_L2(ibtf_hca, "ibt_pkey2index_byguid: "
1479 1479 "Invalid HCA GUID 0x%llx", hca_guid);
1480 1480 mutex_exit(&ibtl_clnt_list_mutex);
1481 1481 return (IBT_HCA_INVALID);
1482 1482 }
1483 1483 retval = ibtl_pkey2index(hca_devp, port_num, pkey, pkey_ix);
1484 1484 mutex_exit(&ibtl_clnt_list_mutex);
1485 1485
1486 1486 return (retval);
1487 1487 }
1488 1488
1489 1489
1490 1490 /*
1491 1491 * Function:
1492 1492 * ibt_index2pkey
1493 1493 * Input:
1494 1494 * hca_hdl - The IBT HCA handle.
1495 1495 * port_num - The HCA port
1496 1496 * pkey_ix - The input PKey index, whose PKey we are interested in.
1497 1497 * Output:
1498 1498 * pkey - The returned PKey value.
1499 1499 * Returns:
1500 1500 * IBT_SUCCESS/IBT_PKEY_IX_ILLEGAL/IBT_PKEY_IX_INVALID/IBT_HCA_PORT_INVALID
1501 1501 * Description:
1502 1502 * Returns the PKey value for the specified PKey index, the device as
1503 1503 * specified by IBT HCA Handle.
1504 1504 */
1505 1505 ibt_status_t
1506 1506 ibt_index2pkey(ibt_hca_hdl_t hca_hdl, uint8_t port_num, uint16_t pkey_ix,
1507 1507 ib_pkey_t *pkey)
1508 1508 {
1509 1509 ibt_status_t retval;
1510 1510
1511 1511 IBTF_DPRINTF_L3(ibtf_hca, "ibt_index2pkey(%p, %d, %d)",
1512 1512 hca_hdl, port_num, pkey_ix);
1513 1513
1514 1514 mutex_enter(&ibtl_clnt_list_mutex);
1515 1515 retval = ibtl_index2pkey(hca_hdl->ha_hca_devp, port_num, pkey_ix, pkey);
1516 1516 mutex_exit(&ibtl_clnt_list_mutex);
1517 1517
1518 1518 return (retval);
1519 1519 }
1520 1520
1521 1521 /*
1522 1522 * Function:
1523 1523 * ibt_index2pkey_byguid
1524 1524 * Input:
1525 1525 * hca_guid - The HCA's node GUID.
1526 1526 * port_num - The HCA port
1527 1527 * pkey_ix - The input PKey index, whose PKey we are interested in.
1528 1528 * Output:
1529 1529 * pkey - The returned PKey value, for the specified index.
1530 1530 * Returns:
1531 1531 * IBT_SUCCESS/IBT_PKEY_IX_ILLEGAL/IBT_PKEY_IX_INVALID/
1532 1532 * IBT_HCA_PORT_INVALID/IBT_HCA_INVALID
1533 1533 * Description:
1534 1534 * Returns the PKey Index for the specified PKey, the device as specified
1535 1535 * by HCA GUID Info.
1536 1536 */
1537 1537 ibt_status_t
1538 1538 ibt_index2pkey_byguid(ib_guid_t hca_guid, uint8_t port_num, uint16_t pkey_ix,
1539 1539 ib_pkey_t *pkey)
1540 1540 {
1541 1541 ibt_status_t retval;
1542 1542 ibtl_hca_devinfo_t *hca_devp; /* HCA Dev Info */
1543 1543
1544 1544 IBTF_DPRINTF_L3(ibtf_hca, "ibt_index2pkey_byguid(%llX, %d, %d)",
1545 1545 hca_guid, port_num, pkey_ix);
1546 1546
1547 1547 mutex_enter(&ibtl_clnt_list_mutex);
1548 1548 hca_devp = ibtl_get_hcadevinfo(hca_guid);
1549 1549 if (hca_devp == NULL) {
1550 1550 IBTF_DPRINTF_L2(ibtf_hca, "ibt_index2pkey_byguid: "
1551 1551 "Invalid HCA GUID 0x%llx", hca_guid);
↓ open down ↓ |
1551 lines elided |
↑ open up ↑ |
1552 1552 mutex_exit(&ibtl_clnt_list_mutex);
1553 1553 return (IBT_HCA_INVALID);
1554 1554 }
1555 1555 retval = ibtl_index2pkey(hca_devp, port_num, pkey_ix, pkey);
1556 1556 mutex_exit(&ibtl_clnt_list_mutex);
1557 1557
1558 1558 return (retval);
1559 1559 }
1560 1560
1561 1561
1562 -_NOTE(SCHEME_PROTECTS_DATA("client managed", ibtl_hca_s::ha_clnt_private))
1563 -
1564 1562 /*
1565 1563 * Function:
1566 1564 * ibt_set_hca_private
1567 1565 * Input:
1568 1566 * hca_hdl The ibt_hca_hdl_t of the opened HCA.
1569 1567 * clnt_private The client private data.
1570 1568 * Output:
1571 1569 * none.
1572 1570 * Returns:
1573 1571 * none
1574 1572 * Description:
1575 1573 * Sets the client private data.
1576 1574 */
1577 1575 void
1578 1576 ibt_set_hca_private(ibt_hca_hdl_t hca_hdl, void *clnt_private)
1579 1577 {
1580 1578 hca_hdl->ha_clnt_private = clnt_private;
1581 1579 }
1582 1580
1583 1581
1584 1582 /*
1585 1583 * Function:
1586 1584 * ibt_get_hca_private
1587 1585 * Input:
1588 1586 * hca_hdl The ibt_hca_hdl_t of the opened HCA.
1589 1587 * Output:
1590 1588 * none
1591 1589 * Returns:
1592 1590 * The client private data.
1593 1591 * Description:
1594 1592 * Retrieves the private data from a specified HCA.
1595 1593 */
1596 1594 void *
1597 1595 ibt_get_hca_private(ibt_hca_hdl_t hca_hdl)
1598 1596 {
1599 1597 return (hca_hdl->ha_clnt_private);
1600 1598 }
1601 1599
1602 1600 /*
1603 1601 * Function:
1604 1602 * ibt_hca_handle_to_guid
1605 1603 * Input:
1606 1604 * hca HCA Handle.
1607 1605 * Output:
1608 1606 * none.
1609 1607 * Returns:
1610 1608 * hca_guid Returned HCA GUID on which the specified Channel is
1611 1609 * allocated. Valid if it is non-NULL on return.
1612 1610 * Description:
1613 1611 * A helper function to retrieve HCA GUID for the specified handle.
1614 1612 */
1615 1613 ib_guid_t
1616 1614 ibt_hca_handle_to_guid(ibt_hca_hdl_t hca)
1617 1615 {
1618 1616 IBTF_DPRINTF_L3(ibtf_hca, "ibt_hca_handle_to_guid(%p)", hca);
1619 1617 return (IBTL_HCA2HCAGUID(hca));
1620 1618 }
1621 1619
1622 1620 /*
1623 1621 * Function:
1624 1622 * ibt_hca_guid_to_handle
1625 1623 * Input:
1626 1624 * ibt_hdl The handle returned to the client by the IBTF from
1627 1625 * an ibt_attach() call.
1628 1626 * hca_guid HCA GUID
1629 1627 * Output:
1630 1628 * hca_hdl Returned ibt_hca_hdl_t.
1631 1629 * Returns:
1632 1630 * IBT_SUCCESS
1633 1631 * IBT_HCA_INVALID
1634 1632 * Description:
1635 1633 * A helper function to retrieve a hca handle from a HCA GUID.
1636 1634 */
1637 1635 ibt_status_t
1638 1636 ibt_hca_guid_to_handle(ibt_clnt_hdl_t ibt_hdl, ib_guid_t hca_guid,
1639 1637 ibt_hca_hdl_t *hca_hdl)
1640 1638 {
1641 1639 ibtl_hca_t *hca_infop;
1642 1640 ibtl_hca_devinfo_t *hca_devp; /* HCA Dev Info */
1643 1641 ibt_status_t rval = IBT_HCA_INVALID;
1644 1642
1645 1643 IBTF_DPRINTF_L3(ibtf_hca, "ibt_hca_guid_to_handle(%p, %llX)",
1646 1644 ibt_hdl, hca_guid);
1647 1645
1648 1646 mutex_enter(&ibtl_clnt_list_mutex);
1649 1647
1650 1648 /*
1651 1649 * Get HCA Device Info Structure, referenced by HCA GUID.
1652 1650 */
1653 1651 hca_devp = ibtl_get_hcadevinfo(hca_guid);
1654 1652 if (hca_devp == NULL) {
1655 1653 /*
1656 1654 * If we are here, then the requested HCA device is not present.
1657 1655 * Return the status as Invalid HCA GUID.
1658 1656 */
1659 1657 mutex_exit(&ibtl_clnt_list_mutex);
1660 1658
1661 1659 IBTF_DPRINTF_L2(ibtf_hca, "ibt_hca_guid_to_handle: "
1662 1660 "HCA Device Not Found: Invalid HCA GUID");
1663 1661
1664 1662 *hca_hdl = NULL;
1665 1663 return (rval);
1666 1664 }
1667 1665
1668 1666 /*
1669 1667 * Yes, we found a HCA Device registered with IBTF, which matches with
1670 1668 * the requested HCA_GUID.
1671 1669 */
1672 1670 hca_infop = hca_devp->hd_clnt_list;
1673 1671
1674 1672 while (hca_infop != NULL) {
1675 1673 if (ibt_hdl == hca_infop->ha_clnt_devp) {
1676 1674 rval = IBT_SUCCESS;
1677 1675 break;
1678 1676 }
1679 1677 hca_infop = hca_infop->ha_clnt_link;
1680 1678 }
1681 1679
1682 1680 mutex_exit(&ibtl_clnt_list_mutex);
1683 1681 *hca_hdl = hca_infop;
1684 1682 return (rval);
1685 1683 }
↓ open down ↓ |
112 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX