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