1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdlib.h> 30 #include <stdio.h> 31 #include <sys/mdb_modapi.h> 32 #include <sys/modctl.h> 33 #include <sys/types.h> 34 #include <sys/crypto/api.h> 35 #include <sys/crypto/common.h> 36 #include <sys/crypto/api.h> 37 #include <sys/crypto/sched_impl.h> 38 #include "crypto_cmds.h" 39 40 static void 41 prt_an_state(int state) 42 { 43 switch (state) { 44 case REQ_ALLOCATED: 45 mdb_printf("REQ_ALLOCATED "); 46 break; 47 case REQ_WAITING: 48 mdb_printf("REQ_WAITING "); 49 break; 50 case REQ_INPROGRESS: 51 mdb_printf("REQ_INPROGRESS "); 52 break; 53 case REQ_DONE: 54 mdb_printf("REQ_DONE "); 55 break; 56 case REQ_CANCELED: 57 mdb_printf("REQ_CANCELED "); 58 break; 59 default: 60 mdb_printf("? %d ?? ", state); 61 break; 62 } 63 } 64 65 66 static const mdb_bitmask_t call_flags[] = { 67 { "CRYPTO_ALWAYS_QUEUE", CRYPTO_ALWAYS_QUEUE, CRYPTO_ALWAYS_QUEUE }, 68 { "CRYPTO_NOTIFY_OPDONE", CRYPTO_NOTIFY_OPDONE, CRYPTO_NOTIFY_OPDONE }, 69 { "CRYPTO_SKIP_REQID", CRYPTO_SKIP_REQID, CRYPTO_SKIP_REQID }, 70 { "CRYPTO_RESTRICTED", CRYPTO_RESTRICTED, CRYPTO_RESTRICTED }, 71 { NULL, 0, 0 } 72 }; 73 74 /*ARGSUSED*/ 75 static int 76 kcf_areq_node_simple(kcf_areq_node_t *areqn) 77 { 78 mdb_printf("\nan_type: "); 79 if (areqn->an_type != CRYPTO_ASYNCH) 80 mdb_printf("%-8d ", areqn->an_type); 81 else 82 mdb_printf("CRYPTO_ASYNCH"); 83 84 mdb_printf("\nan_state: "); 85 prt_an_state(areqn->an_state); 86 87 mdb_printf("\nan_context: %-16p\t", areqn->an_context); 88 mdb_printf("an_is_my_turn: %s\t ", areqn->an_is_my_turn == B_FALSE ? 89 "B_FALSE" : "B_TRUE"); 90 91 mdb_printf("\ncr_reqid: %lx\n", areqn->an_reqarg.cr_reqid); 92 return (DCMD_OK); 93 } 94 /* 95 * Verbose print of kcf_areq_node_t 96 */ 97 static int 98 v_kcf_areq_node(kcf_areq_node_t *areqn) 99 { 100 101 /* contents only -- the address is printed elsewhere */ 102 /* First column */ 103 104 mdb_printf("\n%16s: ", "an_type"); 105 if (areqn->an_type != CRYPTO_ASYNCH) 106 mdb_printf("%-8d ", areqn->an_type); 107 else 108 mdb_printf("CRYPTO_ASYNCH"); 109 110 /* Second column */ 111 mdb_printf("\t\t%16s: %p\n", "an_lock", areqn->an_lock); 112 113 /* First column */ 114 mdb_printf("%16s: ", "an_state"); 115 prt_an_state(areqn->an_state); 116 117 /* Second column */ 118 mdb_printf("%14s: next 4 items\n", "an_reqarg"); 119 120 /* First column again */ 121 mdb_printf("%16s: '%16b'", "cr_flag", areqn->an_reqarg.cr_flag, 122 call_flags); 123 124 /* Second column */ 125 mdb_printf("\t%16s: %p\n", "cr_callback_func", 126 areqn->an_reqarg.cr_callback_func); 127 128 /* First column again */ 129 mdb_printf("%16s: %-16p", "cr_callback_arg", 130 areqn->an_reqarg.cr_callback_arg); 131 132 /* Second column */ 133 mdb_printf("\t%16s: %lx\n", "cr_reqid", 134 (ulong_t)areqn->an_reqarg.cr_reqid); 135 136 /* First column again */ 137 mdb_printf("%16s: %d", "an_params.rp_opgrp", 138 areqn->an_params.rp_opgrp); 139 140 /* Second column */ 141 mdb_printf("\t%16s: %d\n", "an_params.rp_optype", 142 areqn->an_params.rp_optype); 143 144 /* First column again */ 145 mdb_printf("%16s: %-16p", "an_context", 146 areqn->an_context); 147 148 /* Second column */ 149 mdb_printf("\t%16s: %p\n", "an_ctxchain_next", 150 areqn->an_ctxchain_next); 151 152 /* First column again */ 153 mdb_printf("%16s: %s", "an_is_my_turn", 154 areqn->an_is_my_turn == B_FALSE ? "B_FALSE" : "B_TRUE"); 155 156 /* Second column */ 157 mdb_printf("\t\t%16s: %s\n", "an_isdual", 158 areqn->an_isdual == B_FALSE ? "B_FALSE" : "B_TRUE"); 159 160 /* First column again */ 161 mdb_printf("%16s: %p", "an_next", 162 areqn->an_next); 163 164 /* Second column */ 165 mdb_printf("\t\t%16s: %p\n", "an_prev", areqn->an_prev); 166 167 /* First column again */ 168 mdb_printf("%16s: %p", "an_provider", 169 areqn->an_provider); 170 171 /* Second column */ 172 mdb_printf("\t\t%16s: %p\n", "an_idnext", areqn->an_idnext); 173 174 /* First column again */ 175 mdb_printf("%16s: %p", "an_idprev", 176 areqn->an_idprev); 177 178 /* Second column */ 179 mdb_printf("\t\t%16s: %hx\n", "an_done", areqn->an_done); 180 181 /* First column again */ 182 mdb_printf("%16s: %d\n", "an_refcnt", 183 areqn->an_refcnt); 184 185 return (DCMD_OK); 186 } 187 /*ARGSUSED*/ 188 int 189 kcf_areq_node(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 190 { 191 kcf_areq_node_t areqn; 192 uint_t opt_v = FALSE; 193 194 195 if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &opt_v, 196 NULL) != argc) 197 return (DCMD_USAGE); 198 199 /* 200 * read even if we're looping, because the cbdata design does not 201 * apply to mdb_pwalk_dcmd 202 */ 203 if (mdb_vread(&areqn, sizeof (kcf_areq_node_t), addr) == -1) { 204 mdb_warn("cannot read %p", addr); 205 return (DCMD_ERR); 206 } 207 if (opt_v) /* verbose */ 208 return (v_kcf_areq_node(&areqn)); 209 else 210 return (kcf_areq_node_simple(&areqn)); 211 } 212 213 /*ARGSUSED*/ 214 int 215 kcf_global_swq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 216 { 217 kcf_global_swq_t swq; 218 kcf_global_swq_t *ptr; 219 220 if (!flags && DCMD_ADDRSPEC) { 221 if (mdb_readsym(&ptr, sizeof (uintptr_t), "gswq") 222 == -1) { 223 mdb_warn("cannot read gswq"); 224 return (DCMD_ERR); 225 } 226 } 227 else 228 ptr = (kcf_global_swq_t *)addr; 229 230 if (mdb_vread(&swq, sizeof (kcf_global_swq_t), (uintptr_t)ptr) == -1) { 231 mdb_warn("cannot read %p", ptr); 232 return (DCMD_ERR); 233 } 234 mdb_printf("gs_lock (mutex):\t%p\n", swq.gs_lock); 235 mdb_printf("gs_cv:\t%hx\n", swq.gs_cv._opaque); 236 mdb_printf("gs_njobs:\t%u\n", swq.gs_njobs); 237 mdb_printf("gs_maxjobs:\t%u\n", swq.gs_maxjobs); 238 mdb_printf("gs_first:\t%p\n", swq.gs_first); 239 mdb_printf("gs_last:\t%p\n", swq.gs_last); 240 return (mdb_pwalk_dcmd("an_next", "kcf_areq_node", argc, 241 argv, (uintptr_t)swq.gs_first)); 242 } 243 244 static int 245 areq_walk_init_common(mdb_walk_state_t *wsp, boolean_t use_first) 246 { 247 kcf_global_swq_t gswq_copy; 248 uintptr_t gswq_ptr; 249 250 if (mdb_readsym(&gswq_ptr, sizeof (gswq_ptr), "gswq") == -1) { 251 mdb_warn("failed to read 'gswq'"); 252 return (WALK_ERR); 253 } 254 if (mdb_vread(&gswq_copy, sizeof (gswq_copy), gswq_ptr) == -1) { 255 mdb_warn("cannot read %p", gswq_ptr); 256 return (WALK_ERR); 257 } 258 if ((wsp->walk_addr = (use_first ? (uintptr_t)gswq_copy.gs_first : 259 (uintptr_t)gswq_copy.gs_last)) == NULL) { 260 mdb_printf("Global swq is empty\n"); 261 return (WALK_DONE); 262 } 263 wsp->walk_data = mdb_alloc(sizeof (kcf_areq_node_t), UM_SLEEP); 264 return (WALK_NEXT); 265 } 266 267 int 268 areq_first_walk_init(mdb_walk_state_t *wsp) 269 { 270 return (areq_walk_init_common(wsp, B_TRUE)); 271 } 272 273 int 274 areq_last_walk_init(mdb_walk_state_t *wsp) 275 { 276 return (areq_walk_init_common(wsp, B_FALSE)); 277 } 278 279 typedef enum idwalk_type { 280 IDNEXT, /* an_idnext */ 281 IDPREV, /* an_idprev */ 282 CTXCHAIN /* an_ctxchain_next */ 283 } idwalk_type_t; 284 285 static int 286 an_id_walk_init(mdb_walk_state_t *wsp, idwalk_type_t type) 287 { 288 kcf_areq_node_t *adn; 289 290 if (wsp->walk_addr == NULL) { 291 mdb_warn("must give kcf_areq_node address\n"); 292 return (WALK_ERR); 293 } 294 adn = wsp->walk_data = mdb_alloc(sizeof (kcf_areq_node_t), UM_SLEEP); 295 296 if (mdb_vread(adn, sizeof (kcf_areq_node_t), wsp->walk_addr) == -1) { 297 mdb_warn("cannot read %p", wsp->walk_addr); 298 return (WALK_ERR); 299 } 300 301 switch (type) { 302 case IDNEXT: 303 wsp->walk_addr = (uintptr_t)adn->an_idnext; 304 break; 305 case IDPREV: 306 wsp->walk_addr = (uintptr_t)adn->an_idprev; 307 break; 308 case CTXCHAIN: 309 wsp->walk_addr = (uintptr_t)adn->an_ctxchain_next; 310 break; 311 default: 312 mdb_warn("Bad structure member in walk_init\n"); 313 return (WALK_ERR); 314 } 315 return (WALK_NEXT); 316 } 317 int 318 an_idnext_walk_init(mdb_walk_state_t *wsp) 319 { 320 return (an_id_walk_init(wsp, IDNEXT)); 321 } 322 int 323 an_idprev_walk_init(mdb_walk_state_t *wsp) 324 { 325 return (an_id_walk_init(wsp, IDPREV)); 326 } 327 int 328 an_ctxchain_walk_init(mdb_walk_state_t *wsp) 329 { 330 return (an_id_walk_init(wsp, CTXCHAIN)); 331 } 332 /* 333 * At each step, read a kcf_areq_node_t into our private storage, then invoke 334 * the callback function. We terminate when we reach a NULL type pointer. 335 */ 336 static int 337 an_id_walk_step(mdb_walk_state_t *wsp, idwalk_type_t type) 338 { 339 int status; 340 kcf_areq_node_t *ptr; 341 342 if (wsp->walk_addr == NULL) /* then we're done */ 343 return (WALK_DONE); 344 345 ptr = wsp->walk_data; 346 347 if (mdb_vread(wsp->walk_data, sizeof (kcf_areq_node_t), 348 wsp->walk_addr) == -1) { 349 mdb_warn("cannot read %p", wsp->walk_addr); 350 return (WALK_ERR); 351 } 352 353 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 354 wsp->walk_cbdata); 355 356 switch (type) { 357 case IDNEXT: 358 if ((wsp->walk_addr = 359 (uintptr_t)ptr->an_idnext) == NULL) 360 return (WALK_DONE); 361 break; 362 363 case IDPREV: 364 if ((wsp->walk_addr = 365 (uintptr_t)ptr->an_idprev) == NULL) 366 return (WALK_DONE); 367 break; 368 369 case CTXCHAIN: 370 if ((wsp->walk_addr = 371 (uintptr_t)ptr->an_ctxchain_next) == NULL) 372 return (WALK_DONE); 373 break; 374 375 default: 376 mdb_warn("Bad structure member in walk_step\n"); 377 return (WALK_ERR); 378 } 379 return (status); 380 } 381 int 382 an_idnext_walk_step(mdb_walk_state_t *wsp) 383 { 384 return (an_id_walk_step(wsp, IDNEXT)); 385 } 386 int 387 an_idprev_walk_step(mdb_walk_state_t *wsp) 388 { 389 return (an_id_walk_step(wsp, IDPREV)); 390 } 391 int 392 an_ctxchain_walk_step(mdb_walk_state_t *wsp) 393 { 394 return (an_id_walk_step(wsp, CTXCHAIN)); 395 } 396 397 /* 398 * The walker's fini function is invoked at the end of each walk. Since we 399 * dynamically allocated a kcf_areq_node_t in areq_walk_init, 400 * we must free it now. 401 */ 402 void 403 areq_walk_fini(mdb_walk_state_t *wsp) 404 { 405 #ifdef DEBUG 406 mdb_printf("...end of kcf_areq_node walk\n"); 407 #endif 408 mdb_free(wsp->walk_data, sizeof (kcf_areq_node_t)); 409 } 410 411 /* 412 * At each step, read a kcf_areq_node_t into our private storage, then invoke 413 * the callback function. We terminate when we reach a NULL an_next pointer 414 * or a NULL an_prev pointer. use_next flag indicates which one to check. 415 */ 416 static int 417 an_walk_step_common(mdb_walk_state_t *wsp, boolean_t use_next) 418 { 419 int status; 420 kcf_areq_node_t *ptr; 421 422 ptr = (kcf_areq_node_t *)wsp->walk_data; 423 424 if (mdb_vread(wsp->walk_data, sizeof (kcf_areq_node_t), 425 wsp->walk_addr) == -1) { 426 mdb_warn("failed to read kcf_areq_node at %p", wsp->walk_addr); 427 return (WALK_DONE); 428 } 429 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 430 wsp->walk_cbdata); 431 432 if ((wsp->walk_addr = (use_next ? (uintptr_t)ptr->an_next : 433 (uintptr_t)ptr->an_prev)) == NULL) 434 return (WALK_DONE); 435 436 return (status); 437 } 438 439 int 440 an_next_walk_step(mdb_walk_state_t *wsp) 441 { 442 return (an_walk_step_common(wsp, B_TRUE)); 443 } 444 445 int 446 an_prev_walk_step(mdb_walk_state_t *wsp) 447 { 448 return (an_walk_step_common(wsp, B_FALSE)); 449 } 450 451 /* 452 * Walker data for reqid_table walking 453 */ 454 typedef struct reqid_data { 455 kcf_reqid_table_t rd_table; 456 kcf_reqid_table_t *rd_tbl_ptrs[REQID_TABLES]; 457 int rd_cur_index; 458 } reqid_data_t; 459 460 typedef struct reqid_cb_data { 461 crypto_req_id_t cb_reqid; 462 int verbose; 463 int found; 464 } reqid_cb_data_t; 465 466 extern int crypto_pr_reqid(uintptr_t, reqid_data_t *, reqid_cb_data_t *); 467 468 469 int 470 reqid_table_walk_init(mdb_walk_state_t *wsp) 471 { 472 reqid_data_t *wdata; 473 reqid_cb_data_t *cbdata; 474 475 wsp->walk_callback = (mdb_walk_cb_t)crypto_pr_reqid; 476 477 wsp->walk_data = mdb_alloc(sizeof (reqid_data_t), UM_SLEEP); 478 479 /* see if the walker was called from the command line or mdb_pwalk */ 480 if (wsp->walk_cbdata == NULL) { /* command line */ 481 if ((wsp->walk_cbdata = mdb_zalloc(sizeof (reqid_cb_data_t), 482 UM_SLEEP)) == NULL) { 483 mdb_warn("couldn't get cb memory for reqid_table_walker"); 484 return (WALK_ERR); 485 } 486 /* initialize for a simple walk, as opposed to a reqid search */ 487 cbdata = wsp->walk_cbdata; 488 cbdata->verbose = TRUE; 489 cbdata->cb_reqid = 0; 490 } 491 492 wdata = (reqid_data_t *)wsp->walk_data; 493 494 if (mdb_readsym(wdata->rd_tbl_ptrs, sizeof (wdata->rd_tbl_ptrs), 495 "kcf_reqid_table") == -1) { 496 mdb_warn("failed to read 'kcf_reqid_table'"); 497 return (WALK_ERR); 498 499 } 500 wdata->rd_cur_index = 0; 501 wsp->walk_addr = (uintptr_t)wdata->rd_tbl_ptrs[wdata->rd_cur_index]; 502 503 504 return (WALK_NEXT); 505 } 506 507 /* 508 * At each step, read a kcf_reqid_table_t into our private storage, then invoke 509 * the callback function. We terminate when we reach a 510 */ 511 int 512 reqid_table_walk_step(mdb_walk_state_t *wsp) 513 { 514 int status; 515 reqid_data_t *wdata; 516 517 518 wdata = wsp->walk_data; 519 wsp->walk_addr = (uintptr_t)wdata->rd_tbl_ptrs[wdata->rd_cur_index]; 520 521 #ifdef DEBUG 522 mdb_printf( 523 "DEBUG: kcf_reqid_table at %p, sizeof kcf_reqid_table_t = %d\n", 524 wsp->walk_addr, sizeof (kcf_reqid_table_t)); 525 #endif 526 527 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 528 wsp->walk_cbdata); 529 530 /* get ready for next call */ 531 wdata->rd_cur_index++; 532 if (wdata->rd_cur_index >= REQID_TABLES) 533 return (WALK_DONE); 534 return (status); 535 } 536 537 /* 538 * The walker's fini function is invoked at the end of each walk. Since we 539 * dynamically allocated a reqid_data_t in areq_walk_init, 540 * we must free it now. 541 */ 542 void 543 reqid_table_walk_fini(mdb_walk_state_t *wsp) 544 { 545 #ifdef DEBUG 546 mdb_printf("...end of kcf_reqid walk\n"); 547 #endif 548 mdb_free(wsp->walk_data, sizeof (reqid_data_t)); 549 } 550 551 /* 552 * If there's an argument beyond -v, then we're looking for a specific 553 * reqid, otherwise, print any non-null kcf_areq things we run across. 554 */ 555 556 int 557 crypto_pr_reqid(uintptr_t addr, reqid_data_t *data, reqid_cb_data_t *cbdata) 558 { 559 kcf_areq_node_t node; 560 int i; 561 int needhdr = TRUE; 562 563 if (addr == NULL) { 564 mdb_printf("kcf_reqid_table[%d] = NULL\n", data->rd_cur_index); 565 return (WALK_NEXT); 566 } 567 568 if (mdb_vread(&(data->rd_table), sizeof (kcf_reqid_table_t), 569 addr) == -1) { 570 mdb_warn("failed to read kcf_reqid_table at %p", 571 addr); 572 return (WALK_ERR); 573 } 574 575 /* Loop over all rt_idhash's */ 576 for (i = 0; i < REQID_BUCKETS; i++) { 577 uint_t number_in_chain = 0; 578 uintptr_t node_addr; 579 580 /* follow the an_idnext chains for each bucket */ 581 do { 582 /* read kcf_areq_node */ 583 if (number_in_chain == 0) 584 node_addr = (uintptr_t)data->rd_table.rt_idhash[i]; 585 else 586 /*LINTED*/ 587 node_addr = (uintptr_t)node.an_idnext; 588 #ifdef DEBUG 589 mdb_printf("DEBUG: node_addr = %p\n", node_addr); 590 #endif 591 592 if (node_addr == NULL) 593 break; /* skip */ 594 595 if (mdb_vread(&node, sizeof (kcf_areq_node_t), node_addr) 596 == -1) { 597 if (cbdata->verbose == TRUE) 598 mdb_printf( 599 "cannot read rt_idhash %d an_idnext %d\n", 600 i, number_in_chain); 601 break; 602 } 603 /* see if we want to print it */ 604 if ((cbdata->cb_reqid == 0) || 605 (node.an_reqarg.cr_reqid == cbdata->cb_reqid)) { 606 cbdata->found = TRUE; /* printed if false || reqid */ 607 /* is this the first rd_idhash found for this table? */ 608 if (needhdr == TRUE) { 609 /* print both indices in bold */ 610 mdb_printf("%<b>kcf_reqid_table[%lu] at %p:%</b>\n", 611 data->rd_cur_index, addr); 612 mdb_printf("\trt_lock: %p\trt_curid: %llx\n", 613 data->rd_table.rt_lock, 614 data->rd_table.rt_curid); 615 needhdr = FALSE; 616 } 617 /* print kcf_areq_node */ 618 if (number_in_chain < 1) 619 mdb_printf( 620 " %<b>rt_idhash[%lu%]%</b> = %<b>%p:%</b>\n", 621 i, node_addr); 622 else 623 mdb_printf( 624 " rt_idhash[%lu%]" 625 " an_idnext %d = %<b>%p:%</b>\n", 626 i, number_in_chain, node_addr); 627 mdb_inc_indent(8); 628 629 /* if we're looking for one and only one reqid */ 630 /* do it REALLY verbose */ 631 if ((node.an_reqarg.cr_reqid == cbdata->cb_reqid) && 632 (cbdata->cb_reqid != 0)) 633 v_kcf_areq_node(&node); 634 else if (cbdata->verbose == TRUE) 635 /* 636 * verbose for this walker means non-verbose for 637 * the kcf_areq_node details 638 */ 639 kcf_areq_node_simple(&node); 640 mdb_dec_indent(8); 641 } 642 /* if we only wanted one reqid, quit now */ 643 if (node.an_reqarg.cr_reqid == cbdata->cb_reqid) { 644 return (WALK_DONE); 645 } 646 647 number_in_chain++; 648 649 } while (node.an_idnext != NULL); /* follow chain in same bucket */ 650 651 } /* for each REQID_BUCKETS */ 652 653 if ((needhdr == TRUE) && (cbdata->cb_reqid == 0)) { 654 mdb_printf("%kcf_reqid_table[%lu]: %p\n", 655 data->rd_cur_index, addr); 656 } 657 return (WALK_NEXT); 658 } 659 660 /*ARGSUSED*/ 661 int 662 crypto_find_reqid(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 663 { 664 const mdb_arg_t *argp = NULL; 665 reqid_cb_data_t cbdata; 666 int i, status; 667 668 cbdata.cb_reqid = 0L; 669 cbdata.verbose = FALSE; 670 cbdata.found = FALSE; 671 672 if (flags & DCMD_ADDRSPEC) { 673 mdb_printf("use addr ::kcf_reqid_table\n"); 674 return (DCMD_USAGE); 675 } 676 if ((i = mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, 677 &cbdata.verbose, NULL)) != argc) { 678 if (argc - i > 1) 679 return (DCMD_USAGE); 680 } 681 682 if (argc > i) 683 argp = &argv[i]; 684 685 if ((argp != NULL)) { 686 if (argp->a_type == MDB_TYPE_IMMEDIATE) 687 cbdata.cb_reqid = argp->a_un.a_val; 688 else 689 cbdata.cb_reqid = (crypto_req_id_t) 690 mdb_strtoull(argp->a_un.a_str); 691 } 692 status = mdb_pwalk("kcf_reqid_table", (mdb_walk_cb_t)crypto_pr_reqid, 693 &cbdata, addr); 694 695 if ((cbdata.cb_reqid != 0L) && (cbdata.found == FALSE)) 696 mdb_printf("ID 0x%lx not found\n", cbdata.cb_reqid); 697 #ifdef DEBUG 698 else 699 mdb_printf("DEBUG: cbdata.db_reqid = %lx, cbdata.found = %d\n", 700 cbdata.cb_reqid, cbdata.found); 701 #endif 702 703 return (status); 704 } 705 706 int 707 kcf_reqid_table_dcmd(uintptr_t addr, uint_t flags, int argc, 708 const mdb_arg_t *argv) 709 { 710 reqid_data_t wdata; 711 reqid_cb_data_t cbdata; 712 713 if (!(flags & DCMD_ADDRSPEC)) 714 return (DCMD_USAGE); 715 716 memset(&wdata, 0, sizeof (wdata)); 717 memset(&cbdata, 0, sizeof (cbdata)); 718 719 if ((mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, 720 &cbdata.verbose, NULL)) != argc) { 721 return (DCMD_USAGE); 722 } 723 crypto_pr_reqid(addr, &wdata, &cbdata); 724 return (DCMD_OK); 725 } 726