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_impl.c
+++ new/usr/src/uts/common/io/ib/ibtl/ibtl_impl.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_impl.c
27 27 *
28 28 * This file contains the IBTF module's initialization and
29 29 * IBTF Clients/Modules registration routines.
30 30 */
31 31
32 32 #include <sys/modctl.h>
33 33 #include <sys/sunndi.h>
34 34 #include <sys/ib/ibtl/impl/ibtl.h>
35 35 #include <sys/ib/ibtl/impl/ibtl_ibnex.h>
36 36
37 37 /*
38 38 * Globals.
39 39 */
40 40 static char ibtf[] = "ibtl_impl";
41 41
42 42 extern ibtl_ibnex_callback_t ibtl_ibnex_callback_routine;
43 43
44 44 /*
45 45 * ibtl_clnt_list:
46 46 *
47 47 * Head of the list of IBT Client Instances. The IBT Client List
48 48 * is modified by IBTF on an IBT client's ibt_attach/ibt_detach call.
49 49 *
50 50 * ibtl_hca_list:
51 51 *
52 52 * Head of the list of HCA devices. The HCA List is modified by IBTF on
53 53 * a CI's ibc_attach/ibc_detach call.
54 54 * The datap of the list elements points to an ibtl_hca_devinfo_s
55 55 * structure.
56 56 *
57 57 * (ibc_attach)
58 58 * ibtl_hca_list -> ibtl_hca_devinfo_t--> ... -->ibtl_hca_devinfo_t
59 59 * [per-hca_dev] | ^ {nth HCA Dev}
60 60 * | |
61 61 * | ibtl_hca_t (ibt_open_hca)
62 62 * | ^ |
63 63 * | | |
64 64 * v | V
65 65 * ibtl_clnt_list -> ibtl_clnt_t--> ...--> {n'th Module}
66 66 * [per-client_instance] (ibt_attach)
67 67 *
68 68 */
69 69
70 70 /* Global List of IBT Client Instances, and associated mutex. */
71 71 struct ibtl_clnt_s *ibtl_clnt_list = NULL;
72 72 kmutex_t ibtl_clnt_list_mutex;
73 73
74 74 /* Lock for the race between the client and CM to free QPs. */
75 75 kmutex_t ibtl_free_qp_mutex;
76 76
77 77 /* Lock for the race between the client closing the HCA and QPN being freed. */
78 78 kcondvar_t ibtl_close_hca_cv;
79 79
80 80 /* Global List of HCA Devices, and associated mutex. */
81 81 struct ibtl_hca_devinfo_s *ibtl_hca_list = NULL;
↓ open down ↓ |
81 lines elided |
↑ open up ↑ |
82 82
83 83 /* Well-known async handlers and associated client private. */
84 84 ibt_async_handler_t ibtl_cm_async_handler;
85 85 ibt_async_handler_t ibtl_dm_async_handler;
86 86 ibt_async_handler_t ibtl_ibma_async_handler;
87 87 void *ibtl_cm_clnt_private;
88 88 void *ibtl_dm_clnt_private;
89 89 void *ibtl_ibma_clnt_private;
90 90
91 91 extern int ib_hw_status;
92 -_NOTE(SCHEME_PROTECTS_DATA("Scheme protects data", ib_hw_status))
93 92
94 93 /*
95 94 * Misc Module Declarations.
96 95 */
97 96 extern struct mod_ops mod_miscops;
98 97 static struct modlmisc modlmisc = {
99 98 &mod_miscops, /* Type of module - misc. */
100 99 "IB Transport Layer" /* Name of the Module. */
101 100 };
102 101
103 102 static struct modlinkage modlinkage = {
104 103 MODREV_1, (void *)&modlmisc, NULL
105 104 };
106 105
107 106 static void ibtl_kstat_init(ibtl_hca_devinfo_t *);
108 107 static void ibtl_kstat_fini(ibtl_hca_devinfo_t *);
109 108 static void ibtl_kstat_stats_create(ibtl_hca_devinfo_t *, uint_t);
110 109 static void ibtl_kstat_pkeys_create(ibtl_hca_devinfo_t *, uint_t);
111 110
112 111 extern kmutex_t ibtl_part_attr_mutex;
113 112
114 113 /*
115 114 * IBTF Loadable Module Routines.
116 115 */
117 116
118 117 int
119 118 _init(void)
120 119 {
121 120 int rval;
122 121
123 122 if ((rval = mod_install(&modlinkage)) != 0)
124 123 return (rval);
125 124
126 125 /*
127 126 * initialize IBTL ib2usec table
128 127 */
129 128 ibtl_ib2usec_init();
130 129
131 130 /*
132 131 * Initialize Logging
133 132 */
134 133 ibtl_logging_initialization();
135 134
136 135 /*
137 136 * Initialize the Alloc QP States.
138 137 */
139 138 ibtl_init_cep_states();
140 139
141 140 /*
142 141 * Initialize all Global Link Lists.
143 142 */
144 143 mutex_init(&ibtl_clnt_list_mutex, NULL, MUTEX_DEFAULT, NULL);
145 144 mutex_init(&ibtl_free_qp_mutex, NULL, MUTEX_DEFAULT, NULL);
146 145 cv_init(&ibtl_close_hca_cv, NULL, CV_DEFAULT, NULL);
147 146
148 147 mutex_init(&ibtl_qp_mutex, NULL, MUTEX_DEFAULT, NULL);
149 148 cv_init(&ibtl_qp_cv, NULL, CV_DEFAULT, NULL);
150 149
151 150 mutex_init(&ibtl_part_attr_mutex, NULL, MUTEX_DEFAULT, NULL);
152 151
153 152 ibtl_thread_init();
154 153
155 154 return (rval);
156 155 }
157 156
158 157
159 158 int
160 159 _fini(void)
161 160 {
162 161 int rval;
163 162
164 163 if ((rval = mod_remove(&modlinkage)) != 0) {
165 164 return (rval);
166 165 }
167 166
168 167 ibtl_thread_fini();
169 168
170 169 mutex_destroy(&ibtl_clnt_list_mutex);
171 170 mutex_destroy(&ibtl_free_qp_mutex);
172 171 cv_destroy(&ibtl_close_hca_cv);
173 172 mutex_destroy(&ibtl_qp_mutex);
174 173 cv_destroy(&ibtl_qp_cv);
175 174 mutex_destroy(&ibtl_part_attr_mutex);
176 175
177 176 /*
178 177 * Stop Logging
179 178 */
180 179 ibtl_logging_destroy();
181 180
182 181 return (rval);
183 182 }
184 183
185 184
186 185 int
187 186 _info(struct modinfo *modinfop)
188 187 {
189 188 /* Return the Module Information. */
190 189 return (mod_info(&modlinkage, modinfop));
191 190 }
192 191
193 192
194 193 /*
195 194 * IBTF Client Registration Routines.
196 195 */
197 196
198 197 /*
199 198 * Function:
200 199 * ibt_attach
201 200 * Input:
202 201 * modinfop - Client Module info structure.
203 202 * arg - usually client's dip
204 203 * clnt_private - client's private data pointer.
205 204 * Output:
206 205 * ibt_hdl_p - pointer to client's specific IBT handle,
207 206 * which is opaque to clients.
208 207 * Returns:
209 208 * IBT_SUCCESS
210 209 * IBT_INVALID_PARAM
211 210 * Called by:
212 211 * IBTF Client module during its attach() to register its instance
213 212 * to IBTF.
214 213 * Description:
215 214 * Registers the IBTF client module instance and returns an opaque
216 215 * handler to the client to be used for future calls to IBTF.
217 216 * Adds this client module instance to ibtl_clnt_list list.
218 217 * Records well-known async handlers.
219 218 */
220 219 ibt_status_t
221 220 ibt_attach(ibt_clnt_modinfo_t *mod_infop, dev_info_t *arg, void *clnt_private,
222 221 ibt_clnt_hdl_t *ibt_hdl_p)
223 222 {
224 223 dev_info_t *pdip;
225 224 ibtl_clnt_t *clntp;
226 225
227 226 IBTF_DPRINTF_L3(ibtf, "ibt_attach(%p, %p, %p)",
228 227 mod_infop, arg, clnt_private);
229 228
230 229 if (mod_infop->mi_clnt_name == NULL) {
231 230 IBTF_DPRINTF_L1(ibtf, "ibt_attach: "
232 231 "IB client needs to specify its name");
233 232 return (IBT_INVALID_PARAM);
234 233 }
235 234
236 235 /*
237 236 * Validate the Transport API version.
238 237 */
239 238 if (mod_infop->mi_ibt_version != IBTI_V_CURR) {
240 239 IBTF_DPRINTF_L1(ibtf, "ibt_attach: IB client '%s' has an "
241 240 "invalid IB TI Version '%d'", mod_infop->mi_clnt_name,
242 241 mod_infop->mi_ibt_version);
243 242 return (IBT_NOT_SUPPORTED);
244 243 }
245 244
246 245 if (mod_infop->mi_async_handler == NULL) {
247 246 IBTF_DPRINTF_L2(ibtf, "ibt_attach: Client '%s' has not\n"
248 247 " provided an Asynchronous Event Handler.\n"
249 248 " This will be required soon.",
250 249 mod_infop->mi_clnt_name);
251 250 }
252 251
253 252 /*
254 253 * Check out Client's Class information. If it is not of mgmt class,
255 254 * we expect 'arg' to be Not NULL and point to client driver's
256 255 * device info struct.
257 256 */
258 257 if ((!IBT_MISCMOD_CLIENTS(mod_infop->mi_clnt_class)) &&
259 258 (arg == NULL)) {
260 259 IBTF_DPRINTF_L1(ibtf, "ibt_attach: "
261 260 "arg not set with driver's dip.");
262 261 return (IBT_INVALID_PARAM);
263 262 }
264 263
265 264 if (!IBT_MISCMOD_CLIENTS(mod_infop->mi_clnt_class)) {
266 265 pdip = ddi_get_parent(arg);
267 266 if (pdip == NULL ||
268 267 ibtl_ibnex_valid_hca_parent(pdip) != IBT_SUCCESS) {
269 268 IBTF_DPRINTF_L2(ibtf, "ibt_attach: "
270 269 "client %s is not a child of IB nexus driver.",
271 270 ddi_driver_name(arg));
272 271 return (IBT_INVALID_PARAM);
273 272 }
274 273 }
275 274
276 275 mutex_enter(&ibtl_clnt_list_mutex);
277 276 if (mod_infop->mi_clnt_class == IBT_CM) {
278 277 if (ibtl_cm_async_handler != NULL) {
279 278 IBTF_DPRINTF_L1(ibtf, "ibt_attach: "
280 279 "CM is already attached.");
281 280 mutex_exit(&ibtl_clnt_list_mutex);
282 281 return (IBT_INVALID_PARAM);
283 282 }
284 283 ibtl_cm_async_handler = mod_infop->mi_async_handler;
285 284 ibtl_cm_clnt_private = clnt_private;
286 285 } else if (mod_infop->mi_clnt_class == IBT_DM) {
287 286 if (ibtl_dm_async_handler != NULL) {
288 287 IBTF_DPRINTF_L1(ibtf, "ibt_attach: "
289 288 "DM is already attached.");
290 289 mutex_exit(&ibtl_clnt_list_mutex);
291 290 return (IBT_INVALID_PARAM);
292 291 }
293 292 ibtl_dm_async_handler = mod_infop->mi_async_handler;
294 293 ibtl_dm_clnt_private = clnt_private;
295 294 } else if (mod_infop->mi_clnt_class == IBT_IBMA) {
296 295 if (ibtl_ibma_async_handler != NULL) {
297 296 IBTF_DPRINTF_L1(ibtf, "ibt_attach: "
298 297 "IBMF is already attached.");
↓ open down ↓ |
196 lines elided |
↑ open up ↑ |
299 298 mutex_exit(&ibtl_clnt_list_mutex);
300 299 return (IBT_INVALID_PARAM);
301 300 }
302 301 ibtl_ibma_async_handler = mod_infop->mi_async_handler;
303 302 ibtl_ibma_clnt_private = clnt_private;
304 303 }
305 304
306 305 /* Allocate the memory for per-client-device info structure */
307 306 clntp = kmem_zalloc(sizeof (ibtl_clnt_t), KM_SLEEP);
308 307
309 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(clntp->clnt_modinfop,
310 - clntp->clnt_dip, clntp->clnt_name, clntp->clnt_async_cnt,
311 - clntp->clnt_private))
312 308 /* Update the Client info structure */
313 309 clntp->clnt_modinfop = mod_infop; /* IBT Client's Mod Info */
314 310 clntp->clnt_private = clnt_private; /* IBT Client's private */
315 311 clntp->clnt_dip = arg; /* IBT Client's dip */
316 312 clntp->clnt_async_cnt = 0;
317 313 /* using a count of 7 below guarantees it is NULL terminated */
318 314 (void) strncpy(clntp->clnt_name, mod_infop->mi_clnt_name, 7);
319 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(clntp->clnt_modinfop,
320 - clntp->clnt_dip, clntp->clnt_name, clntp->clnt_async_cnt,
321 - clntp->clnt_private))
322 315
323 316 /*
324 317 * Update Client Device Instance List.
325 318 */
326 319 clntp->clnt_list_link = ibtl_clnt_list;
327 320 ibtl_clnt_list = clntp;
328 321 mutex_exit(&ibtl_clnt_list_mutex);
329 322
330 323 /*
331 324 * The ibt_hdl_p is a opaque handle which is the address of
332 325 * ibt_clnt_t structure passed back to the clients.
333 326 * The client will pass on this handle in its future calls to IBTF.
334 327 */
335 328 *ibt_hdl_p = clntp;
336 329
337 330 return (IBT_SUCCESS);
338 331 }
339 332
340 333
341 334 /*
342 335 * Function:
343 336 * ibt_detach
344 337 * Input:
345 338 * ibt_hdl - IBT Handle as returned during ibt_attach call.
346 339 * Output:
347 340 * none
348 341 * Returns:
349 342 * IBT_SUCCESS
350 343 * IBT_INVALID_PARAM.
351 344 * Called by:
352 345 * IBTF Client module during its detach() to de-register its instance
353 346 * from IBTF.
354 347 * Description:
355 348 * Deregisters the IBTF client module instance from the IBTF.
356 349 * All resources and any reference to this ibt_hdl will be removed.
357 350 */
358 351 ibt_status_t
359 352 ibt_detach(ibt_clnt_hdl_t ibt_hdl)
360 353 {
361 354 ibtl_clnt_t **clntpp;
362 355
363 356 IBTF_DPRINTF_L3(ibtf, "ibt_detach(%p)", ibt_hdl);
364 357
365 358 mutex_enter(&ibtl_clnt_list_mutex);
366 359 clntpp = &ibtl_clnt_list;
367 360 for (; *clntpp != NULL; clntpp = &(*clntpp)->clnt_list_link)
368 361 if (*clntpp == ibt_hdl)
369 362 break;
370 363 if (*clntpp == NULL) {
371 364 IBTF_DPRINTF_L1(ibtf, "ibt_detach: Client @ %p Not Found",
372 365 ibt_hdl);
373 366 mutex_exit(&ibtl_clnt_list_mutex);
374 367 return (IBT_INVALID_PARAM);
375 368 }
376 369
377 370 /*
378 371 * Check out whether the client has freed all its resources.
379 372 * If not done, then fail the detach.
380 373 *
381 374 * viz. A client has to close all the HCA they have opened,
382 375 * i.e. the HCA List maintained for clients has to be empty.
383 376 * If this list is not empty, then the client has not performed
384 377 * complete clean-up, so fail the detach.
385 378 */
386 379 if (ibt_hdl->clnt_hca_list != NULL) {
387 380 mutex_exit(&ibtl_clnt_list_mutex);
388 381
389 382 IBTF_DPRINTF_L2(ibtf, "ibt_detach: "
390 383 "ERROR: Client '%s' has not closed all of its HCAs",
391 384 ibt_hdl->clnt_modinfop->mi_clnt_name);
392 385 cmn_err(CE_CONT, "IBT DETACH failed: resources not yet "
393 386 "freed by client '%s'\n",
394 387 ibt_hdl->clnt_modinfop->mi_clnt_name);
395 388 return (IBT_HCA_RESOURCES_NOT_FREED);
396 389 }
397 390
398 391 if (ibt_hdl->clnt_srv_cnt != 0) {
399 392 mutex_exit(&ibtl_clnt_list_mutex);
400 393 IBTF_DPRINTF_L2(ibtf, "ibt_detach: client '%s' still has "
401 394 "services or subnet_notices registered",
402 395 ibt_hdl->clnt_modinfop->mi_clnt_name);
403 396 cmn_err(CE_CONT, "IBT DETACH failed: resources not yet "
404 397 "freed by client '%s'\n",
405 398 ibt_hdl->clnt_modinfop->mi_clnt_name);
406 399 return (IBT_HCA_RESOURCES_NOT_FREED);
407 400 }
408 401
409 402 /*
410 403 * Delete the entry of this module from the ibtl_clnt_list List.
411 404 */
412 405 *clntpp = ibt_hdl->clnt_list_link; /* remove us */
413 406
414 407 /* make sure asyncs complete before freeing */
415 408 ibtl_free_clnt_async_check(ibt_hdl);
416 409
417 410 if (ibt_hdl->clnt_modinfop->mi_clnt_class == IBT_CM) {
418 411 ibtl_cm_async_handler = NULL;
419 412 ibtl_cm_clnt_private = NULL;
420 413 } else if (ibt_hdl->clnt_modinfop->mi_clnt_class == IBT_DM) {
421 414 ibtl_dm_async_handler = NULL;
422 415 ibtl_dm_clnt_private = NULL;
423 416 } else if (ibt_hdl->clnt_modinfop->mi_clnt_class == IBT_IBMA) {
424 417 ibtl_ibma_async_handler = NULL;
425 418 ibtl_ibma_clnt_private = NULL;
426 419 }
427 420 mutex_exit(&ibtl_clnt_list_mutex);
428 421
429 422 /* Free up the memory of per-client info struct. */
430 423 kmem_free(ibt_hdl, sizeof (ibtl_clnt_t));
431 424
432 425 return (IBT_SUCCESS);
433 426 }
434 427
435 428 static void
436 429 ibtl_set_ibhw_status()
437 430 {
438 431 ib_hw_status++;
439 432 }
440 433
441 434 static void
442 435 ibtl_clear_ibhw_status()
443 436 {
444 437 ib_hw_status--;
445 438 }
446 439
447 440 /*
448 441 * Function:
449 442 * ibc_init
450 443 * Input:
451 444 * modlp - Pointer to IBC client module linkage structure
452 445 * Output:
453 446 * None
454 447 * Returns:
455 448 * 0 always for now
456 449 * Called by:
457 450 * CI client calls IBTF during its _init() to register HCA with
458 451 * Solaris I/O framework.
459 452 * Description:
460 453 * Initializes the CI clients module linkage structure with
461 454 * default bus_ops structure
462 455 */
463 456 int
464 457 ibc_init(struct modlinkage *modlp)
465 458 {
466 459 ibtl_ibnex_cb_args_t cb_args;
467 460
468 461 mutex_enter(&ibtl_clnt_list_mutex);
469 462 cb_args.cb_flag = IBTL_IBNEX_IBC_INIT;
470 463 cb_args.cb_modlp = modlp;
471 464 if (ibtl_ibnex_callback_routine) {
472 465 (void) ((*ibtl_ibnex_callback_routine)(&cb_args));
473 466 }
474 467 mutex_exit(&ibtl_clnt_list_mutex);
475 468 return (0);
476 469 }
477 470
478 471
479 472 /*
480 473 * Function:
481 474 * ibc_fini
482 475 * Input:
483 476 * modlp - Pointer to IBC client module linkage structure
484 477 * Output:
485 478 * None
486 479 * Returns:
487 480 * None
488 481 * Called by:
489 482 * CI client calls IBTF during its _fini() to remove HCA with
490 483 * Solaris I/O framework.
491 484 * Description:
492 485 * Undo what is done during ibc_init
493 486 */
494 487 void
495 488 ibc_fini(struct modlinkage *modlp)
496 489 {
497 490 ibtl_ibnex_cb_args_t cb_args;
498 491
499 492 mutex_enter(&ibtl_clnt_list_mutex);
500 493 cb_args.cb_flag = IBTL_IBNEX_IBC_FINI;
501 494 cb_args.cb_modlp = modlp;
502 495 if (ibtl_ibnex_callback_routine) {
503 496 (void) ((*ibtl_ibnex_callback_routine)(&cb_args));
504 497 }
505 498 mutex_exit(&ibtl_clnt_list_mutex);
506 499 }
507 500
508 501 /*
509 502 * Function:
510 503 * ibc_attach
511 504 * Input:
512 505 * info_p - IBC HCA Info.
513 506 * Output:
514 507 * ibc_hdl_p - IBC Client's HCA Handle.
515 508 * Returns:
516 509 * IBC_SUCCESS
517 510 * IBC_FAILURE
518 511 * Called by:
519 512 * CI calls IBTF during its attach() to register HCA Device with IBTF.
520 513 * Description:
521 514 * Registers the presence of HCA device by providing the HCA device info
522 515 * structure and provides an opaque HCA handler for future calls to this
523 516 * HCA device.
524 517 */
525 518 ibc_status_t
526 519 ibc_attach(ibc_clnt_hdl_t *ibc_hdl_p, ibc_hca_info_t *info_p)
527 520 {
528 521 ibtl_hca_devinfo_t *hca_devp;
529 522 uint_t nports;
530 523 ibt_status_t status;
531 524
532 525 IBTF_DPRINTF_L2(ibtf, "ibc_attach(%p, %p)", ibc_hdl_p, info_p);
533 526
534 527 /* Validate the Transport API version */
535 528 if (info_p->hca_ci_vers != IBCI_V4) {
536 529 IBTF_DPRINTF_L1(ibtf, "ibc_attach: Invalid IB CI Version '%d'",
537 530 info_p->hca_ci_vers);
538 531 return (IBC_FAILURE);
539 532 }
540 533
541 534 if (info_p->hca_attr == NULL) {
542 535 IBTF_DPRINTF_L1(ibtf, "ibc_attach: "
543 536 "HCA Attributes must be specified.");
544 537 return (IBC_FAILURE);
545 538 }
546 539
547 540 nports = info_p->hca_attr->hca_nports;
548 541 if (nports == 0) {
549 542 IBTF_DPRINTF_L1(ibtf, "ibc_attach: "
550 543 "Number of ports must be valid");
551 544 return (IBC_FAILURE);
552 545 }
553 546
554 547 if (info_p->hca_attr->hca_max_port_pkey_tbl_sz == 0) {
555 548 IBTF_DPRINTF_L1(ibtf, "ibc_attach: "
556 549 "Number of Partitions must be at least 1");
557 550 return (IBC_FAILURE);
558 551 }
559 552
560 553 if ((info_p->hca_attr->hca_flags & IBT_HCA_CURRENT_QP_STATE) == 0) {
561 554 IBTF_DPRINTF_L1(ibtf, "ibc_attach: "
562 555 "HCA driver must support QP current state checking");
563 556 return (IBC_FAILURE);
564 557 }
565 558
566 559 if ((info_p->hca_attr->hca_flags & IBT_HCA_PORT_UP) == 0) {
567 560 IBTF_DPRINTF_L1(ibtf, "ibc_attach: "
568 561 "HCA driver must support PORT_UP async events");
569 562 return (IBC_FAILURE);
570 563 }
571 564
572 565 /*
573 566 * Install IB nexus driver (if not installed already)
574 567 */
575 568 ibtl_set_ibhw_status();
576 569 if (ndi_devi_config_vhci("ib", 0) == NULL) {
577 570 IBTF_DPRINTF_L2(ibtf, "ibc_attach: IB nexus attach failed");
578 571 ibtl_clear_ibhw_status();
579 572 return (IBC_FAILURE);
580 573 }
581 574
582 575 ibtl_thread_init2();
583 576
584 577 /* Allocate the memory for per-client info structure */
585 578 hca_devp = kmem_zalloc(sizeof (ibtl_hca_devinfo_t) +
586 579 (nports - 1) * sizeof (ibtl_async_port_event_t), KM_SLEEP);
587 580
588 581 mutex_enter(&ibtl_clnt_list_mutex);
589 582
590 583 /* Update HCA dev info structure */
591 584 hca_devp->hd_ibc_hca_hdl = info_p->hca_handle;
592 585 hca_devp->hd_ibc_ops = info_p->hca_ops;
593 586 hca_devp->hd_hca_attr = info_p->hca_attr;
594 587 hca_devp->hd_hca_dip = info_p->hca_attr->hca_dip;
595 588
596 589 status = ibtl_init_hca_portinfo(hca_devp);
597 590 if (status != IBT_SUCCESS) {
598 591 mutex_exit(&ibtl_clnt_list_mutex);
599 592 IBTF_DPRINTF_L1(ibtf, "ibc_attach: call to ibc_query_hca_ports "
600 593 "failed: status = %d", status);
601 594 kmem_free(hca_devp, sizeof (ibtl_hca_devinfo_t) +
602 595 (nports - 1) * sizeof (ibtl_async_port_event_t));
603 596 return (IBC_FAILURE);
604 597 }
605 598
606 599 /* Register the with MPxIO as PHCI */
607 600 if (ibtl_ibnex_phci_register(hca_devp->hd_hca_dip) != IBT_SUCCESS) {
608 601 mutex_exit(&ibtl_clnt_list_mutex);
609 602 IBTF_DPRINTF_L1(ibtf, "ibc_attach: MPxIO register failed");
610 603 kmem_free(hca_devp, sizeof (ibtl_hca_devinfo_t) +
611 604 (nports - 1) * sizeof (ibtl_async_port_event_t));
612 605 return (IBC_FAILURE);
613 606 }
614 607
615 608 /* Initialize the Client List for this HCA. */
616 609 hca_devp->hd_state = IBTL_HCA_DEV_ATTACHED;
617 610
618 611 /* lock out asyncs until after we announce the new HCA */
619 612 hca_devp->hd_async_busy = 1;
620 613
621 614 cv_init(&hca_devp->hd_async_task_cv, NULL, CV_DEFAULT, NULL);
622 615 cv_init(&hca_devp->hd_async_busy_cv, NULL, CV_DEFAULT, NULL);
623 616
624 617 /* init portinfo locking variables */
625 618 hca_devp->hd_portinfo_locked_port = 0;
626 619 cv_init(&hca_devp->hd_portinfo_cv, NULL, CV_DEFAULT, NULL);
627 620
628 621 ibtl_kstat_init(hca_devp);
629 622
630 623 mutex_exit(&ibtl_clnt_list_mutex);
631 624
632 625 /*
633 626 * The ibc_hdl_p points to an opaque handle which is the address
634 627 * of ibt_hca_devinfo_t structure passed back to the CI.
635 628 * The CI will pass on this handle in its future upcalls to IBTF.
636 629 */
637 630 *ibc_hdl_p = hca_devp;
638 631
639 632 return (IBC_SUCCESS);
640 633 }
641 634
642 635
643 636 /*
644 637 * Function:
645 638 * ibc_post_attach
646 639 * Input:
647 640 * ibc_hdl - IBC Client's HCA Handle.
648 641 * Returns:
649 642 * none
650 643 * Called by:
651 644 * CI calls IBTF during its attach() after a successful ibc_attach().
652 645 * Description:
653 646 * Announces to all known clients the existence of this HCA (by GUID).
654 647 */
655 648 void
656 649 ibc_post_attach(ibc_clnt_hdl_t ibc_hdl)
657 650 {
658 651 IBTF_DPRINTF_L2(ibtf, "ibc_post_attach(%p)", ibc_hdl);
659 652
660 653 /*
661 654 * Update the HCA Device List.
662 655 */
663 656 mutex_enter(&ibtl_clnt_list_mutex);
664 657 ibc_hdl->hd_hca_dev_link = ibtl_hca_list;
665 658 ibtl_hca_list = ibc_hdl;
666 659 mutex_exit(&ibtl_clnt_list_mutex);
667 660
668 661 /* notify all IBT Client Device Instances of the new HCA Device */
669 662 ibtl_announce_new_hca(ibc_hdl);
670 663 }
671 664
672 665
673 666 /*
674 667 * Function:
675 668 * ibc_pre_detach
676 669 * Input:
677 670 * ibc_clnt_hdl - IBC HCA Handle as returned during ibc_attach call.
678 671 * cmd - DDI_DETACH/DDI_SUSPEND command.
679 672 * Output:
680 673 * none
681 674 * Returns:
682 675 * IBC_SUCCESS
683 676 * IBC_FAILURE.
684 677 * Called by:
685 678 * CI to try to get all IBTF clients to close the HCA device.
686 679 * Description:
687 680 * Attempts to deregister the HCA device entry from the IBTF.
688 681 * If all resources are freed by the IBTF clients and this HCA
689 682 * is closed, then IBC_SUCCESS is returned.
690 683 */
691 684 ibc_status_t
692 685 ibc_pre_detach(ibc_clnt_hdl_t hca_devp, ddi_detach_cmd_t cmd)
693 686 {
694 687 ibtl_hca_devinfo_t **hcapp, *hcap;
695 688
696 689 IBTF_DPRINTF_L2(ibtf, "ibc_pre_detach(%p, 0x%x)", hca_devp, cmd);
697 690
698 691 /*
699 692 * Return failure, if command is not DDI_DETACH
700 693 */
701 694 switch (cmd) {
702 695 case DDI_DETACH:
703 696 break;
704 697 default:
705 698 return (IBC_FAILURE); /* TBD: DDI_FAILURE */
706 699 }
707 700
708 701 /* Make sure this HCA is on the HCA Device List. */
709 702 mutex_enter(&ibtl_clnt_list_mutex);
710 703 hcap = ibtl_hca_list;
711 704 while (hcap != NULL) {
712 705 if (hcap == hca_devp)
713 706 break;
714 707 hcap = hcap->hd_hca_dev_link;
715 708 }
716 709 if (hcap == NULL) {
717 710 mutex_exit(&ibtl_clnt_list_mutex);
718 711 return (IBC_FAILURE);
719 712 }
720 713
721 714 /*
722 715 * Initially set the state to "Detaching".
723 716 */
724 717 hca_devp->hd_state = IBTL_HCA_DEV_DETACHING;
725 718
726 719 /*
727 720 * Try to detach all IBTI clients, and continue only if all
728 721 * of the detaches succeed.
729 722 */
730 723 if (ibtl_detach_all_clients(hca_devp)) {
731 724 hca_devp->hd_state = IBTL_HCA_DEV_ATTACHED; /* fix hd_state */
732 725 mutex_exit(&ibtl_clnt_list_mutex);
733 726
734 727 return (IBC_FAILURE);
735 728 }
736 729
737 730 /*
738 731 * Check to see if all clients closed this HCA, or not.
739 732 * We only succeed if all clients cooperated.
740 733 */
741 734 if (hca_devp->hd_clnt_list != NULL) {
742 735 hca_devp->hd_state = IBTL_HCA_DEV_ATTACHED;
743 736 mutex_exit(&ibtl_clnt_list_mutex);
744 737 IBTF_DPRINTF_L2(ibtf, "ibc_pre_detach: HCA still has attached "
745 738 "clients");
746 739 return (IBC_FAILURE);
747 740 }
748 741
749 742 /*
750 743 * mark this device as detached
751 744 */
752 745 hca_devp->hd_state = IBTL_HCA_DEV_DETACHED;
753 746
754 747 /* Delete the entry for this hca_devp from hca_head_list */
755 748 hcapp = &ibtl_hca_list;
756 749 while (*hcapp != NULL) {
757 750 if (*hcapp == hca_devp)
758 751 break;
759 752 hcapp = &(*hcapp)->hd_hca_dev_link;
760 753 }
761 754
762 755 if (ibtl_ibnex_phci_unregister(hca_devp->hd_hca_dip) != IBT_SUCCESS) {
763 756 hca_devp->hd_state = IBTL_HCA_DEV_ATTACHED; /* fix hd_state */
764 757 mutex_exit(&ibtl_clnt_list_mutex);
765 758 IBTF_DPRINTF_L1(ibtf, "ibc_pre_detach: PHCI unregister failed");
766 759 return (IBC_FAILURE);
767 760 }
768 761
769 762 if (*hcapp == NULL) {
770 763 hca_devp->hd_state = IBTL_HCA_DEV_ATTACHED; /* fix hd_state */
771 764 mutex_exit(&ibtl_clnt_list_mutex);
772 765 IBTF_DPRINTF_L1(ibtf, "ibc_pre_detach: HCA not attached");
773 766 return (IBC_FAILURE);
774 767 }
775 768 *hcapp = hca_devp->hd_hca_dev_link;
776 769 ibtl_fast_gid_cache_valid = B_FALSE; /* invalidate fast_gid_cache */
777 770 mutex_exit(&ibtl_clnt_list_mutex);
778 771
779 772 return (IBC_SUCCESS);
780 773 }
781 774
782 775 /*
783 776 * Function:
784 777 * ibc_detach
785 778 * Input:
786 779 * ibc_clnt_hdl - IBC HCA Handle as returned during ibc_attach call.
787 780 * Output:
788 781 * none
789 782 * Returns:
790 783 * None
791 784 * Called by:
792 785 * CI to detach the HCA device from IBTF.
793 786 * Description:
794 787 * Do the second step of detaching the HCA, which is required
795 788 * after a successful ibc_pre_detach.
796 789 */
797 790 void
798 791 ibc_detach(ibc_clnt_hdl_t hca_devp)
799 792 {
800 793 IBTF_DPRINTF_L2(ibtf, "ibc_detach(%p)", hca_devp);
801 794
802 795 mutex_enter(&ibtl_clnt_list_mutex);
803 796 if (hca_devp->hd_state != IBTL_HCA_DEV_DETACHED) {
804 797 mutex_exit(&ibtl_clnt_list_mutex);
805 798 IBTF_DPRINTF_L0(ibtf, "ibc_detach: HCA has not successfully "
806 799 "pre-detached");
807 800 return;
808 801 }
809 802
810 803 cv_destroy(&hca_devp->hd_async_task_cv);
811 804 cv_destroy(&hca_devp->hd_async_busy_cv);
812 805 cv_destroy(&hca_devp->hd_portinfo_cv);
813 806
814 807 kmem_free(hca_devp->hd_portinfop, hca_devp->hd_portinfo_len);
815 808 mutex_exit(&ibtl_clnt_list_mutex);
816 809
817 810 ibtl_kstat_fini(hca_devp);
818 811
819 812 /* Free up the memory of per-client info struct */
820 813 kmem_free(hca_devp, sizeof (ibtl_hca_devinfo_t) +
821 814 (hca_devp->hd_hca_attr->hca_nports - 1) *
822 815 sizeof (ibtl_async_port_event_t));
823 816 ibtl_clear_ibhw_status();
824 817 }
825 818
826 819 /*
827 820 * Function:
828 821 * ibt_ci_data_in()
829 822 *
830 823 * Input:
831 824 * hca_hdl HCA Handle.
832 825 * flags IBT_COMPLETE_ALLOC - Finish a deferred alloc.
833 826 * object Identifies the type object pointed to by
834 827 * ibt_object_handle.
835 828 *
836 829 * ibt_object_handle The handle of the object to be associated with
837 830 * the data in/out
838 831 *
839 832 * data_p Pointer data passed in to the CI. The buffer
840 833 * should be allocated by the caller.
841 834 *
842 835 * data_sz The size of the buffer pointed to by
843 836 * data_p.
844 837 * Output:
845 838 *
846 839 * Returns:
847 840 * IBT_SUCCESS
848 841 * IBT_NOT_SUPPORTED Feature not supported.
849 842 * IBT_INVALID_PARAM Invalid object type specified.
850 843 * IBT_HCA_HDL_INVALID
851 844 * IBT_AH_HDL_INVALID/IBT_UD_DEST_HDL_INVALID
852 845 * IBT_CHAN_HDL_INVALID/IBT_QP_HDL_INVALID
853 846 * IBT_CQ_HDL_INVALID
854 847 * IBT_EEC_HDL_INVALID
855 848 * IBT_RDD_HDL_INVALID
856 849 * IBT_MW_HDL_INVALID
857 850 * IBT_PD_HDL_INVALID
858 851 * IBT_SRQ_HDL_INVALID
859 852 *
860 853 * Description:
861 854 * Exchange CI private data for the specified CI object.
862 855 */
863 856 ibt_status_t
864 857 ibt_ci_data_in(ibt_hca_hdl_t hca, ibt_ci_data_flags_t flags,
865 858 ibt_object_type_t object, void *ibt_object_handle, void *data_p,
866 859 size_t data_sz)
867 860 {
868 861 ibt_status_t retval;
869 862 void *ci_obj_hdl;
870 863
871 864 IBTF_DPRINTF_L3(ibtf, "ibt_ci_data_in(%p, %x, %d, %p, %p, %d)",
872 865 hca, flags, object, ibt_object_handle, data_p, data_sz);
873 866
874 867 switch (object) {
875 868 case IBT_HDL_HCA:
876 869 ci_obj_hdl = (void *)
877 870 (IBTL_HCA2CIHCA(((ibt_hca_hdl_t)ibt_object_handle)));
878 871 break;
879 872
880 873 case IBT_HDL_CHANNEL:
881 874 ci_obj_hdl = (void *)
882 875 (IBTL_CHAN2CIQP(((ibt_channel_hdl_t)ibt_object_handle)));
883 876 break;
884 877
885 878 case IBT_HDL_CQ:
886 879 ci_obj_hdl = (void *)
887 880 (((ibt_cq_hdl_t)(ibt_object_handle))->cq_ibc_cq_hdl);
888 881 break;
889 882
890 883 case IBT_HDL_EEC:
891 884 ci_obj_hdl = (void *)
892 885 (((ibt_eec_hdl_t)(ibt_object_handle))->eec_ibc_eec_hdl);
893 886 break;
894 887
895 888 case IBT_HDL_UD_DEST:
896 889 ci_obj_hdl = (void *)
897 890 (((ibt_ud_dest_hdl_t)(ibt_object_handle))->ud_ah);
898 891 break;
899 892
900 893 case IBT_HDL_SRQ:
901 894 ci_obj_hdl = (void *)
902 895 (((ibt_srq_hdl_t)(ibt_object_handle))->srq_ibc_srq_hdl);
903 896 break;
904 897
905 898 default:
906 899 ci_obj_hdl = ibt_object_handle;
907 900 break;
908 901 }
909 902
910 903 retval = (IBTL_HCA2CIHCAOPS_P(hca)->ibc_ci_data_in)(IBTL_HCA2CIHCA(hca),
911 904 flags, object, ci_obj_hdl, data_p, data_sz);
912 905
913 906 if (retval != IBT_SUCCESS) {
914 907 IBTF_DPRINTF_L2(ibtf, "ibt_ci_data_in: Failed : %d", retval);
915 908 }
916 909 return (retval);
917 910 }
918 911
919 912 /*
920 913 * Function:
921 914 * ibt_ci_data_out()
922 915 *
923 916 * Input:
924 917 * hca_hdl HCA Handle.
925 918 * flags IBT_COMPLETE_ALLOC - Finish a deferred alloc.
926 919 * object Identifies the type object pointed to by
927 920 * ibt_object_handle.
928 921 *
929 922 * ibt_object_handle The handle of the object to be associated with
930 923 * the data in/out
931 924 *
932 925 * data_p Pointer to a buffer in which to return the CI
933 926 * private data. The buffer should be allocated
934 927 * by the caller.
935 928 *
936 929 * data_sz The size of the buffer pointed to by
937 930 * data_p.
938 931 * Output:
939 932 *
940 933 * Returns:
941 934 * IBT_SUCCESS
942 935 * IBT_NOT_SUPPORTED Feature not supported.
943 936 * IBT_INSUFF_RESOURCE The buffer pointed to by data_p was too
944 937 * small to hold the data.
945 938 * IBT_INVALID_PARAM Invalid object type specified.
946 939 * IBT_HCA_HDL_INVALID
947 940 * IBT_AH_HDL_INVALID/IBT_UD_DEST_HDL_INVALID
948 941 * IBT_CHAN_HDL_INVALID/IBT_QP_HDL_INVALID
949 942 * IBT_CQ_HDL_INVALID
950 943 * IBT_EEC_HDL_INVALID
951 944 * IBT_RDD_HDL_INVALID
952 945 * IBT_MW_HDL_INVALID
953 946 * IBT_PD_HDL_INVALID
954 947 * IBT_SRQ_HDL_INVALID
955 948 *
956 949 * Description:
957 950 * Exchange CI private data for the specified CI object.
958 951 */
959 952 ibt_status_t
960 953 ibt_ci_data_out(ibt_hca_hdl_t hca, ibt_ci_data_flags_t flags,
961 954 ibt_object_type_t object, void *ibt_object_handle, void *data_p,
962 955 size_t data_sz)
963 956 {
964 957 ibt_status_t retval;
965 958 void *ci_obj_hdl;
966 959
967 960 IBTF_DPRINTF_L3(ibtf, "ibt_ci_data_out(%p, %x, %d, %p, %p, %d)",
968 961 hca, flags, object, ibt_object_handle, data_p, data_sz);
969 962
970 963 switch (object) {
971 964 case IBT_HDL_HCA:
972 965 ci_obj_hdl = (void *)
973 966 (IBTL_HCA2CIHCA(((ibt_hca_hdl_t)ibt_object_handle)));
974 967 break;
975 968
976 969 case IBT_HDL_CHANNEL:
977 970 ci_obj_hdl = (void *)
978 971 (IBTL_CHAN2CIQP(((ibt_channel_hdl_t)ibt_object_handle)));
979 972 break;
980 973
981 974 case IBT_HDL_CQ:
982 975 ci_obj_hdl = (void *)
983 976 (((ibt_cq_hdl_t)(ibt_object_handle))->cq_ibc_cq_hdl);
984 977 break;
985 978
986 979 case IBT_HDL_EEC:
987 980 ci_obj_hdl = (void *)
988 981 (((ibt_eec_hdl_t)(ibt_object_handle))->eec_ibc_eec_hdl);
989 982 break;
990 983
991 984 case IBT_HDL_UD_DEST:
992 985 ci_obj_hdl = (void *)
993 986 (((ibt_ud_dest_hdl_t)(ibt_object_handle))->ud_ah);
994 987 break;
995 988
996 989 case IBT_HDL_SRQ:
997 990 ci_obj_hdl = (void *)
998 991 (((ibt_srq_hdl_t)(ibt_object_handle))->srq_ibc_srq_hdl);
999 992 break;
1000 993
1001 994 default:
1002 995 ci_obj_hdl = ibt_object_handle;
1003 996 break;
1004 997 }
1005 998
1006 999 retval = (IBTL_HCA2CIHCAOPS_P(hca)->ibc_ci_data_out)
1007 1000 (IBTL_HCA2CIHCA(hca), flags, object, ci_obj_hdl, data_p, data_sz);
1008 1001
1009 1002 if (retval != IBT_SUCCESS) {
1010 1003 IBTF_DPRINTF_L2(ibtf, "ibt_ci_data_out: Failed : %d", retval);
1011 1004 }
1012 1005 return (retval);
1013 1006 }
1014 1007
1015 1008
1016 1009 /*
1017 1010 * FMA Support functions.
1018 1011 */
1019 1012
1020 1013 #define IBTL_ENA_MASK 0xC0000000
1021 1014 #define IBTL_ENA_POSSIBLE 0x80000000
1022 1015 #define IBTL_TYPE_SHIFT 27
1023 1016
1024 1017 /*
1025 1018 * Function:
1026 1019 * ibt_get_module_failure()
1027 1020 *
1028 1021 * Input:
1029 1022 * type Identifies the failing IB module.
1030 1023 * ena '0' or the data for Fault Management
1031 1024 * Architecture (ENA).
1032 1025 *
1033 1026 * Returns:
1034 1027 * status Special IB failure status.
1035 1028 *
1036 1029 * Description:
1037 1030 * XXX Just stubbed out to return failures with no data for Fault
1038 1031 * Management Architecture (ENAs) at the moment XXX
1039 1032 */
1040 1033 ibt_status_t
1041 1034 ibt_get_module_failure(ibt_failure_type_t type, uint64_t ena)
1042 1035 {
1043 1036 ibt_status_t ret;
1044 1037
1045 1038 IBTF_DPRINTF_L3(ibtf, "ibt_get_module_failure(%d, 0x%llX)", type, ena);
1046 1039
1047 1040 switch (type) {
1048 1041 case IBT_FAILURE_CI:
1049 1042 case IBT_FAILURE_IBMF:
1050 1043 case IBT_FAILURE_IBCM:
1051 1044 case IBT_FAILURE_IBDM:
1052 1045 case IBT_FAILURE_IBTL:
1053 1046 case IBT_FAILURE_IBSM:
1054 1047 ret = IBTL_ENA_POSSIBLE | (type << IBTL_TYPE_SHIFT);
1055 1048 break;
1056 1049 default:
1057 1050 ret = IBT_FAILURE;
1058 1051 }
1059 1052 IBTF_DPRINTF_L3(ibtf, "ibt_get_module_failure: ret = 0x%lX", ret);
1060 1053 return (ret);
1061 1054 }
1062 1055
1063 1056
1064 1057 /*
1065 1058 * Function:
1066 1059 * ibc_get_ci_failure()
1067 1060 *
1068 1061 * Input:
1069 1062 * ena '0' or the data for Fault Management
1070 1063 * Architecture (ENA).
1071 1064 *
1072 1065 * Returns:
1073 1066 * status Special CI failure status.
1074 1067 *
1075 1068 * Description:
1076 1069 * Just use the function above to do the job.
1077 1070 */
1078 1071 ibt_status_t
1079 1072 ibc_get_ci_failure(uint64_t ena)
1080 1073 {
1081 1074 return (ibt_get_module_failure(IBT_FAILURE_CI, ena));
1082 1075 }
1083 1076
1084 1077
1085 1078 /*
1086 1079 * ibt_check_failure()
1087 1080 * Function to test for special case failures.
1088 1081 *
1089 1082 * status An ibt_status_t returned from an IBTF function call.
1090 1083 *
1091 1084 * reserved_p NULL, or a pointer to where we store the data for
1092 1085 * Fault Management Architecture (ENA).
1093 1086 *
1094 1087 * Description:
1095 1088 * XXX Still need to determine the data for Fault Management Architecture
1096 1089 * (ENA), using 0 for now XXX
1097 1090 */
1098 1091 ibt_failure_type_t
1099 1092 ibt_check_failure(ibt_status_t status, uint64_t *reserved_p)
1100 1093 {
1101 1094 ibt_failure_type_t type;
1102 1095
1103 1096 IBTF_DPRINTF_L3(ibtf, "ibt_check_failure(%X)", status);
1104 1097
1105 1098 if ((status & IBTL_ENA_MASK) == IBTL_ENA_POSSIBLE) {
1106 1099 type = status & ~IBTL_ENA_POSSIBLE >> IBTL_TYPE_SHIFT;
1107 1100
1108 1101 /* XXX Need more work here... */
1109 1102 if (reserved_p != NULL)
1110 1103 *reserved_p = 0;
1111 1104 } else {
1112 1105 type = IBT_FAILURE_STANDARD;
1113 1106 if (reserved_p != NULL)
1114 1107 *reserved_p = 0; /* No FMA Data Available. */
1115 1108 }
1116 1109 IBTF_DPRINTF_L3(ibtf, "ibt_check_failure: type = 0x%X", type);
1117 1110 return (type);
1118 1111 }
1119 1112
1120 1113 /*
1121 1114 * Initialize and create kstats.
1122 1115 *
1123 1116 * We create the following kstats on all ports of the HCA:
1124 1117 * <hca_driver_name><instance_number>/port<port_num>/stats
1125 1118 * <hca_driver_name><instance_number>/port<port_num>/pkeys
1126 1119 */
1127 1120 static void
1128 1121 ibtl_kstat_init(ibtl_hca_devinfo_t *hca_devp)
1129 1122 {
1130 1123 uint_t nports = hca_devp->hd_hca_attr->hca_nports;
1131 1124 ibtl_hca_port_kstat_t *pks;
1132 1125 int i;
1133 1126
1134 1127 IBTF_DPRINTF_L3(ibtf, "ibtl_kstat_init(hca_devp = 0x%p)", hca_devp);
1135 1128
1136 1129 hca_devp->hd_hca_port_ks_info_len =
1137 1130 sizeof (ibtl_hca_port_kstat_t) * nports;
1138 1131 pks = kmem_zalloc(hca_devp->hd_hca_port_ks_info_len, KM_SLEEP);
1139 1132 hca_devp->hd_hca_port_ks_info = pks;
1140 1133
1141 1134 for (i = 0; i < nports; i++, pks++) {
1142 1135 pks->pks_hca_devp = hca_devp;
1143 1136 pks->pks_port_num = i + 1;
1144 1137 ibtl_kstat_stats_create(hca_devp, i + 1);
1145 1138 ibtl_kstat_pkeys_create(hca_devp, i + 1);
1146 1139 }
1147 1140 }
1148 1141
1149 1142 /*
↓ open down ↓ |
818 lines elided |
↑ open up ↑ |
1150 1143 * Delete kstats on all ports of the HCA.
1151 1144 */
1152 1145 static void
1153 1146 ibtl_kstat_fini(ibtl_hca_devinfo_t *hca_devp)
1154 1147 {
1155 1148 ibtl_hca_port_kstat_t *pks;
1156 1149 int i;
1157 1150
1158 1151 IBTF_DPRINTF_L3(ibtf, "ibtl_kstat_fini(hca_devp = 0x%p)", hca_devp);
1159 1152
1160 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*hca_devp))
1161 -
1162 1153 pks = hca_devp->hd_hca_port_ks_info;
1163 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*pks))
1164 1154
1165 1155 if (pks == NULL)
1166 1156 return;
1167 1157
1168 1158 for (i = 0; i < hca_devp->hd_hca_attr->hca_nports; i++, pks++) {
1169 1159 if (pks->pks_stats_ksp)
1170 1160 kstat_delete(pks->pks_stats_ksp);
1171 1161
1172 1162 if (pks->pks_pkeys_ksp) {
1173 1163 ASSERT(!MUTEX_HELD(&ibtl_clnt_list_mutex));
1174 1164 kstat_delete(pks->pks_pkeys_ksp);
1175 1165 }
1176 1166 }
1177 1167
1178 1168 kmem_free(hca_devp->hd_hca_port_ks_info,
1179 1169 hca_devp->hd_hca_port_ks_info_len);
1180 1170 }
1181 1171
1182 1172 /*
1183 1173 * Update "stats" kstat.
1184 1174 * Called by kstat framework.
1185 1175 */
1186 1176 static int
1187 1177 ibtl_kstat_stats_update(kstat_t *ksp, int rw)
1188 1178 {
1189 1179 ibtl_hca_port_kstat_t *pks;
1190 1180 ibtl_hca_devinfo_t *hca_devp;
1191 1181 ibt_hca_portinfo_t *p;
1192 1182 struct kstat_named *data;
1193 1183
1194 1184 IBTF_DPRINTF_L4(ibtf, "ibtl_kstat_stats_update(ksp = 0x%p, rw = %d)",
1195 1185 ksp, rw);
1196 1186
1197 1187 if (rw == KSTAT_WRITE)
1198 1188 return (EACCES);
1199 1189
1200 1190 mutex_enter(&ibtl_clnt_list_mutex);
1201 1191
1202 1192 /*
1203 1193 * Update the link_state kstat using the value from portinfo cache.
1204 1194 */
1205 1195 pks = ksp->ks_private;
1206 1196 hca_devp = pks->pks_hca_devp;
1207 1197 data = (struct kstat_named *)(ksp->ks_data);
1208 1198 p = hca_devp->hd_portinfop + pks->pks_port_num - 1;
1209 1199 data[0].value.ui32 = (uint32_t)p->p_linkstate;
1210 1200
1211 1201 mutex_exit(&ibtl_clnt_list_mutex);
1212 1202
1213 1203 return (0);
1214 1204 }
1215 1205
1216 1206 /*
1217 1207 * Create "stats" kstat for the specified HCA port in the form:
1218 1208 * <hca_driver_name><instance_number>/port<port_num>/stats
1219 1209 * At preset it contains only one named data of "link_state"
1220 1210 */
1221 1211 static void
1222 1212 ibtl_kstat_stats_create(ibtl_hca_devinfo_t *hca_devp, uint_t port_num)
1223 1213 {
1224 1214 struct kstat *ksp;
1225 1215 struct kstat_named *named_data;
1226 1216 char *drv_name;
1227 1217 int drv_instance;
1228 1218 ibtl_hca_port_kstat_t *pks;
1229 1219 char kname[40];
1230 1220
1231 1221 IBTF_DPRINTF_L3(ibtf, "ibtl_kstat_stats_create(hca_devp = 0x%p, "
1232 1222 "port_num = 0x%u)", hca_devp, port_num);
1233 1223
1234 1224 drv_name = (char *)ddi_driver_name(hca_devp->hd_hca_dip);
1235 1225 drv_instance = ddi_get_instance(hca_devp->hd_hca_dip);
1236 1226 (void) snprintf(kname, sizeof (kname), "%s%d/port%d/stats",
1237 1227 drv_name, drv_instance, port_num);
1238 1228
1239 1229 ksp = kstat_create("ibtf", 0, kname, "ib", KSTAT_TYPE_NAMED, 1, 0);
1240 1230 if (ksp == NULL) {
1241 1231 IBTF_DPRINTF_L2(ibtf,
1242 1232 "ibtl_kstat_stats_create: kstat_create() failed");
1243 1233 return;
1244 1234 }
1245 1235
1246 1236 named_data = (struct kstat_named *)(ksp->ks_data);
1247 1237 kstat_named_init(&named_data[0], "link_state", KSTAT_DATA_UINT32);
1248 1238
1249 1239 pks = hca_devp->hd_hca_port_ks_info + port_num - 1;
1250 1240 pks->pks_stats_ksp = ksp;
1251 1241
1252 1242 ksp->ks_private = pks;
1253 1243 ksp->ks_update = ibtl_kstat_stats_update;
1254 1244
1255 1245 /* Install the kstat */
1256 1246 kstat_install(ksp);
1257 1247 }
1258 1248
1259 1249 /*
1260 1250 * Update "pkeys" kstat.
1261 1251 *
1262 1252 * Called by kstat framework. Since ks_lock was set to ibtl_clnt_list_mutex
1263 1253 * at the time of the kstat creation, kstat framework will hold this lock
1264 1254 * while calling this function.
1265 1255 */
↓ open down ↓ |
92 lines elided |
↑ open up ↑ |
1266 1256 static int
1267 1257 ibtl_kstat_pkeys_update(kstat_t *ksp, int rw)
1268 1258 {
1269 1259 ibtl_hca_port_kstat_t *pks;
1270 1260 ibtl_hca_devinfo_t *hca_devp;
1271 1261 ibt_hca_portinfo_t *p;
1272 1262
1273 1263 IBTF_DPRINTF_L4(ibtf, "ibtl_kstat_pkeys_update(ksp = 0x%p, rw = %d)",
1274 1264 ksp, rw);
1275 1265
1276 -#ifndef __lock_lint
1277 1266 ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
1278 -#endif
1279 1267
1280 1268 if (rw == KSTAT_WRITE)
1281 1269 return (EACCES);
1282 1270
1283 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ksp))
1284 -
1285 1271 pks = ksp->ks_private;
1286 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*pks))
1287 -
1288 1272 hca_devp = pks->pks_hca_devp;
1289 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*hca_devp))
1290 1273
1291 1274 /*
1292 1275 * Point kstat data to the pkey table in the portinfo cache.
1293 1276 */
1294 1277
1295 1278 p = hca_devp->hd_portinfop + pks->pks_port_num - 1;
1296 1279
1297 1280 ksp->ks_data = p->p_pkey_tbl;
1298 1281 ksp->ks_ndata = p->p_pkey_tbl_sz;
1299 1282 ksp->ks_data_size = p->p_pkey_tbl_sz * sizeof (ib_pkey_t);
1300 1283
1301 1284 return (0);
1302 1285 }
1303 1286
1304 1287 /*
1305 1288 * Create "pkeys" kstat for the specified HCA port in the form:
1306 1289 * <hca_driver_name><instance_number>/port<port_num>/pkeys
1307 1290 *
1308 1291 * Currently kstat framework allows only some fixed data types as named
1309 1292 * data components under a named kstat. Due to this limitation it is not
1310 1293 * possible to add "pkeys" as a named data under the "stats" kstat.
1311 1294 */
1312 1295 static void
1313 1296 ibtl_kstat_pkeys_create(ibtl_hca_devinfo_t *hca_devp, uint_t port_num)
1314 1297 {
1315 1298 struct kstat *ksp;
1316 1299 char *drv_name;
1317 1300 int drv_instance;
1318 1301 char kname[40];
1319 1302 ibtl_hca_port_kstat_t *pks;
1320 1303
1321 1304 IBTF_DPRINTF_L3(ibtf, "ibtl_kstat_stats_create(hca_devp = 0x%p, "
1322 1305 "port_num = 0x%u)", hca_devp, port_num);
1323 1306
1324 1307 drv_name = (char *)ddi_driver_name(hca_devp->hd_hca_dip);
1325 1308 drv_instance = ddi_get_instance(hca_devp->hd_hca_dip);
1326 1309 (void) snprintf(kname, sizeof (kname), "%s%d/port%d/pkeys",
1327 1310 drv_name, drv_instance, port_num);
1328 1311
1329 1312 ksp = kstat_create("ibtf", 0, kname, "ib", KSTAT_TYPE_RAW, 0,
1330 1313 KSTAT_FLAG_VAR_SIZE | KSTAT_FLAG_VIRTUAL);
1331 1314 if (ksp == NULL) {
1332 1315 IBTF_DPRINTF_L2(ibtf,
1333 1316 "ibtl_kstat_pkeys_create: kstat_create() failed");
1334 1317 return;
1335 1318 }
1336 1319
1337 1320 pks = hca_devp->hd_hca_port_ks_info + port_num - 1;
1338 1321 pks->pks_pkeys_ksp = ksp;
1339 1322
1340 1323 ksp->ks_private = pks;
1341 1324 ksp->ks_update = ibtl_kstat_pkeys_update;
1342 1325 ksp->ks_lock = &ibtl_clnt_list_mutex;
1343 1326
1344 1327 /*
1345 1328 * We just go with the default_kstat_snapshot().
1346 1329 * So there is no need to set ks_snapshot field.
1347 1330 */
1348 1331
1349 1332 /* Install the kstat */
1350 1333 kstat_install(ksp);
1351 1334 }
↓ open down ↓ |
52 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX