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 (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /* Copyright 2015 QLogic Corporation */
  23 
  24 /*
  25  * ISP2xxx Solaris Fibre Channel Adapter (FCA) qlc mdb source file.
  26  *
  27  * ***********************************************************************
  28  * *                                                                    **
  29  * *                            NOTICE                                  **
  30  * *            COPYRIGHT (C) 1996-2015 QLOGIC CORPORATION              **
  31  * *                    ALL RIGHTS RESERVED                             **
  32  * *                                                                    **
  33  * ***********************************************************************
  34  *
  35  */
  36 
  37 #pragma ident   "Copyright 2015 QLogic Corporation; ql_mdb.c"
  38 
  39 #include <sys/mdb_modapi.h>
  40 #include <ql_apps.h>
  41 #include <ql_api.h>
  42 #include <ql_init.h>
  43 
  44 /*
  45  * local prototypes
  46  */
  47 static int32_t ql_doprint(uintptr_t, int8_t *);
  48 static void ql_dump_flags(uint64_t, int8_t **);
  49 static int qlclinks_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *);
  50 static int qlcstate_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *);
  51 static int qlc_osc_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *);
  52 static int qlc_wdog_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *);
  53 static int qlc_getdump_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *);
  54 static int qlc_gettrace_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *);
  55 #if 0
  56 static int qlc_triggerdump_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *);
  57 #endif
  58 static int qlcver_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *);
  59 static int qlstates_walk_init(mdb_walk_state_t *);
  60 static int qlstates_walk_step(mdb_walk_state_t *);
  61 static void qlstates_walk_fini(mdb_walk_state_t *);
  62 static int qlsrb_walk_init(mdb_walk_state_t *);
  63 static int qlsrb_walk_step(mdb_walk_state_t *);
  64 static void qlsrb_walk_fini(mdb_walk_state_t *);
  65 static int get_next_link(ql_link_t *);
  66 static int get_first_link(ql_head_t *, ql_link_t *);
  67 
  68 static int ql_24xx_dump_dcmd(ql_adapter_state_t *, uint_t, int,
  69     const mdb_arg_t *);
  70 static int ql_23xx_dump_dcmd(ql_adapter_state_t *, uint_t, int,
  71     const mdb_arg_t *);
  72 static int ql_25xx_dump_dcmd(ql_adapter_state_t *, uint_t, int,
  73     const mdb_arg_t *);
  74 static int ql_81xx_dump_dcmd(ql_adapter_state_t *, uint_t, int,
  75     const mdb_arg_t *);
  76 static int ql_8021_dump_dcmd(ql_adapter_state_t *, uint_t, int,
  77     const mdb_arg_t *);
  78 static int ql_8300_dump_dcmd(ql_adapter_state_t *, uint_t, int,
  79     const mdb_arg_t *);
  80 static void ql_elog_common(ql_adapter_state_t *, boolean_t);
  81 
  82 /*
  83  * local adapter state flags strings
  84  */
  85 int8_t *adapter_state_flags[] = {
  86         "FCA_BOUND",
  87         "QL_OPENED",
  88         "ONLINE",
  89         "INTERRUPTS_ENABLED",
  90         "ABORT_CMDS_LOOP_DOWN_TMO",
  91         "POINT_TO_POINT",
  92         "IP_ENABLED",
  93         "IP_INITIALIZED",
  94         "MENLO_LOGIN_OPERATIONAL",
  95         "ADAPTER_SUSPENDED",
  96         "FW_DUMP_NEEDED",
  97         "PARITY_ERROR",
  98         "FLASH_ERRLOG_MARKER",
  99         "VP_ENABLED",
 100         "FDISC_ENABLED",
 101         "MULTI_QUEUE",
 102         "MPI_RESET_NEEDED",
 103         "VP_ID_NOT_ACQUIRED",
 104         "IDC_STALL_NEEDED",
 105         "POLL_INTR",
 106         "IDC_RESTART_NEEDED",
 107         "IDC_ACK_NEEDED",
 108         "LOOPBACK_ACTIVE",
 109         "QUEUE_SHADOW_PTRS",
 110         "NO_INTR_HANDSHAKE",
 111         "COMP_THD_TERMINATE",
 112         "DISABLE_NIC_FW_DMP",
 113         "MULTI_CHIP_ADAPTER",
 114         NULL
 115 };
 116 
 117 int8_t *adapter_config_flags[] = {
 118         "CTRL_27XX",
 119         "ENABLE_64BIT_ADDRESSING",
 120         "ENABLE_LIP_RESET",
 121         "ENABLE_FULL_LIP_LOGIN",
 122         "ENABLE_TARGET_RESET",
 123         "ENABLE_LINK_DOWN_REPORTING",
 124         "DISABLE_EXTENDED_LOGGING_TRACE",
 125         "ENABLE_FCP_2_SUPPORT",
 126         "CTRL_83XX",
 127         "SBUS_CARD",
 128         "CTRL_23XX",
 129         "CTRL_63XX",
 130         "CTRL_22XX",
 131         "CTRL_24XX",
 132         "CTRL_25XX",
 133         "ENABLE_EXTENDED_LOGGING",
 134         "DISABLE_RISC_CODE_LOAD",
 135         "SET_CACHE_LINE_SIZE_1",
 136         "CTRL_MENLO",
 137         "EXT_FW_INTERFACE",
 138         "LOAD_FLASH_FW",
 139         "DUMP_MAILBOX_TIMEOUT",
 140         "DUMP_ISP_SYSTEM_ERROR",
 141         "DUMP_DRIVER_COMMAND_TIMEOUT",
 142         "DUMP_LOOP_OFFLINE_TIMEOUT",
 143         "ENABLE_FWEXTTRACE",
 144         "ENABLE_FWFCETRACE",
 145         "CTRL_80XX",
 146         "CTRL_81XX",
 147         "CTRL_82XX",
 148         "FAST_TIMEOUT",
 149         "LR_SUPPORT",
 150         NULL
 151 };
 152 
 153 /*
 154  * local task daemon flags strings
 155  */
 156 int8_t *task_daemon_flags[] = {
 157         "TASK_DAEMON_STOP_FLG",
 158         "TASK_DAEMON_SLEEPING_FLG",
 159         "TASK_DAEMON_ALIVE_FLG",
 160         "TASK_DAEMON_IDLE_CHK_FLG",
 161         "SUSPENDED_WAKEUP_FLG",
 162         "FC_STATE_CHANGE",
 163         "NEED_UNSOLICITED_BUFFERS",
 164         "MARKER_NEEDED",
 165         "MARKER_ACTIVE",
 166         "ISP_ABORT_NEEDED",
 167         "ABORT_ISP_ACTIVE",
 168         "LOOP_RESYNC_NEEDED",
 169         "LOOP_RESYNC_ACTIVE",
 170         "LOOP_DOWN",
 171         "DRIVER_STALL",
 172         "COMMAND_WAIT_NEEDED",
 173         "COMMAND_WAIT_ACTIVE",
 174         "STATE_ONLINE",
 175         "ABORT_QUEUES_NEEDED",
 176         "TASK_DAEMON_STALLED_FLG",
 177         "SEND_PLOGI",
 178         "FIRMWARE_UP",
 179         "IDC_POLL_NEEDED",
 180         "FIRMWARE_LOADED",
 181         "RSCN_UPDATE_NEEDED",
 182         "HANDLE_PORT_BYPASS_CHANGE",
 183         "PORT_RETRY_NEEDED",
 184         "TASK_DAEMON_POWERING_DOWN",
 185         "TD_IIDMA_NEEDED",
 186         "WATCHDOG_NEEDED",
 187         "LED_BLINK",
 188         NULL
 189 };
 190 
 191 /*
 192  * local interrupt aif flags
 193  */
 194 int8_t *aif_flags[] = {
 195         "IFLG_INTR_LEGACY",
 196         "IFLG_INTR_FIXED",
 197         "IFLG_INTR_MSI",
 198         "IFLG_INTR_MSIX",
 199         NULL
 200 };
 201 
 202 int8_t *qlsrb_flags[] = {
 203         "SRB_ISP_STARTED",
 204         "SRB_ISP_COMPLETED",
 205         "SRB_RETRY",
 206         "SRB_POLL",
 207         "SRB_WATCHDOG_ENABLED",
 208         "SRB_ABORT",
 209         "SRB_UB_IN_FCA",
 210         "SRB_UB_IN_ISP",
 211         "SRB_UB_CALLBACK",
 212         "SRB_UB_RSCN",
 213         "SRB_UB_FCP",
 214         "SRB_FCP_CMD_PKT",
 215         "SRB_FCP_DATA_PKT",
 216         "SRB_FCP_RSP_PKT",
 217         "SRB_IP_PKT",
 218         "SRB_GENERIC_SERVICES_PKT",
 219         "SRB_COMMAND_TIMEOUT",
 220         "SRB_ABORTING",
 221         "SRB_IN_DEVICE_QUEUE",
 222         "SRB_IN_TOKEN_ARRAY",
 223         "SRB_UB_FREE_REQUESTED",
 224         "SRB_UB_ACQUIRED",
 225         "SRB_MS_PKT",
 226         "SRB_ELS_PKT",
 227         NULL
 228 };
 229 
 230 int8_t *qllun_flags[] = {
 231         "LQF_UNTAGGED_PENDING",
 232         NULL
 233 };
 234 
 235 int8_t *qltgt_flags[] = {
 236         "TQF_TAPE_DEVICE",
 237         "TQF_QUEUE_SUSPENDED",
 238         "TQF_FABRIC_DEVICE",
 239         "TQF_INITIATOR_DEVICE",
 240         "TQF_RSCN_RCVD",
 241         "TQF_NEED_AUTHENTICATION",
 242         "TQF_PLOGI_PROGRS",
 243         "TQF_IIDMA_NEEDED",
 244         "TQF_LOGIN_NEEDED",
 245         NULL
 246 };
 247 
 248 int8_t *qldump_flags[] = {
 249         "QL_DUMPING",
 250         "QL_DUMP_VALID",
 251         "QL_DUMP_UPLOADED",
 252         NULL
 253 };
 254 
 255 /*
 256  * qlclinks_dcmd
 257  *      mdb dcmd which prints out the ql_hba pointers
 258  *
 259  * Input:
 260  *      addr  = User supplied address -- error if supplied.
 261  *      flags = mdb flags.
 262  *      argc  = Number of user supplied args -- error if non-zero.
 263  *      argv  = Arg array.
 264  *
 265  * Returns:
 266  *      DCMD_ERR, DCMD_USAGE, or DCMD_OK
 267  *
 268  * Context:
 269  *      User context.
 270  *
 271  */
 272 /*ARGSUSED*/
 273 static int
 274 qlclinks_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 275 {
 276         ql_head_t               ql_hba;
 277         ql_adapter_state_t      *qlstate;
 278         uintptr_t               hbaptr = NULL;
 279 
 280         if ((flags & DCMD_ADDRSPEC) || argc != 0) {
 281                 return (DCMD_USAGE);
 282         }
 283 
 284         if (mdb_readvar(&ql_hba, "ql_hba") == -1) {
 285                 mdb_warn("failed to read ql_hba structure");
 286                 return (DCMD_ERR);
 287         }
 288 
 289         if (ql_hba.first == NULL) {
 290                 mdb_warn("failed to read ql_hba structure -- is qlc loaded?");
 291                 return (DCMD_ERR);
 292         }
 293 
 294         mdb_printf("\nqlc adapter state linkages (f=0x%llx, l=0x%llx)\n\n",
 295             ql_hba.first, ql_hba.last);
 296 
 297         if ((qlstate = (ql_adapter_state_t *)mdb_alloc(
 298             sizeof (ql_adapter_state_t), UM_SLEEP)) == NULL) {
 299                 mdb_warn("Unable to allocate memory for ql_adapter_state\n");
 300                 return (DCMD_OK);
 301         }
 302 
 303         (void) mdb_inc_indent((ulong_t)4);
 304         mdb_printf("%<u>%-?s\t%-45s%</u>\n\n", "baseaddr", "instance");
 305 
 306         hbaptr = (uintptr_t)ql_hba.first;
 307         while (hbaptr != NULL) {
 308 
 309                 if (mdb_vread(qlstate, sizeof (ql_adapter_state_t),
 310                     hbaptr) == -1) {
 311                         mdb_free(qlstate, sizeof (ql_adapter_state_t));
 312                         mdb_warn("failed to read ql_adapter_state at %p",
 313                             hbaptr);
 314                         return (DCMD_OK);
 315                 }
 316 
 317                 mdb_printf("%<b>0x%016p%t%d%</b>\n",
 318                     qlstate->hba.base_address, qlstate->instance);
 319 
 320                 /*
 321                  * If vp exists, loop through those
 322                  */
 323 
 324                 if ((qlstate->flags & VP_ENABLED) &&
 325                     (qlstate->vp_next != NULL)) {
 326 
 327                         ql_adapter_state_t      *vqlstate;
 328                         uintptr_t               vhbaptr = NULL;
 329 
 330                         vhbaptr = (uintptr_t)qlstate->vp_next;
 331 
 332                         if ((vqlstate = (ql_adapter_state_t *)mdb_alloc(
 333                             sizeof (ql_adapter_state_t), UM_SLEEP)) == NULL) {
 334                                 mdb_warn("Unable to allocate memory for "
 335                                     "ql_adapter_state vp\n");
 336                                 mdb_free(qlstate, sizeof (ql_adapter_state_t));
 337                                 return (DCMD_OK);
 338                         }
 339 
 340                         (void) mdb_inc_indent((ulong_t)30);
 341 
 342                         mdb_printf("%<u>vp baseaddr\t\tvp index%</u>\n");
 343 
 344                         while (vhbaptr != NULL) {
 345 
 346                                 if (mdb_vread(vqlstate,
 347                                     sizeof (ql_adapter_state_t), vhbaptr) ==
 348                                     -1) {
 349                                         mdb_free(vqlstate,
 350                                             sizeof (ql_adapter_state_t));
 351                                         mdb_free(qlstate,
 352                                             sizeof (ql_adapter_state_t));
 353                                         mdb_warn("failed to read vp "
 354                                             "ql_adapter_state at %p", vhbaptr);
 355                                         return (DCMD_OK);
 356                                 }
 357 
 358                                 mdb_printf("%<b>0x%016p%t%d%</b>\n",
 359                                     vqlstate->hba.base_address,
 360                                     vqlstate->vp_index);
 361 
 362                                 vhbaptr = (uintptr_t)vqlstate->vp_next;
 363                         }
 364 
 365                         mdb_free(vqlstate, sizeof (ql_adapter_state_t));
 366 
 367                         (void) mdb_dec_indent((ulong_t)30);
 368 
 369                         mdb_printf("\n");
 370                 }
 371 
 372                 hbaptr = (uintptr_t)qlstate->hba.next;
 373         }
 374 
 375         (void) mdb_dec_indent((ulong_t)4);
 376 
 377         mdb_free(qlstate, sizeof (ql_adapter_state_t));
 378 
 379         return (DCMD_OK);
 380 }
 381 
 382 /*
 383  * qlcver_dcmd
 384  *      mdb dcmd which prints out the qlc driver version the mdb
 385  *      module was compiled with, and the verison of qlc which is
 386  *      currently loaded on the machine.
 387  *
 388  * Input:
 389  *      addr  = User supplied address -- error if supplied.
 390  *      flags = mdb flags.
 391  *      argc  = Number of user supplied args -- error if non-zero.
 392  *      argv  = Arg array.
 393  *
 394  * Returns:
 395  *      DCMD_USAGE, or DCMD_OK
 396  *
 397  * Context:
 398  *      User context.
 399  *
 400  */
 401 /*ARGSUSED*/
 402 static int
 403 qlcver_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 404 {
 405         int8_t          qlcversion[100];
 406         struct fw_table fw_table[10], *fwt = NULL;
 407         uint8_t         *fwverptr = NULL;
 408         ql_head_t       ql_hba;
 409         uint32_t        found = 0;
 410 
 411         if ((flags & DCMD_ADDRSPEC) || argc != 0) {
 412                 return (DCMD_USAGE);
 413         }
 414 
 415         if (mdb_readvar(&qlcversion, "qlc_driver_version") == -1) {
 416                 mdb_warn("unable to read qlc driver version\n");
 417         } else {
 418                 mdb_printf("\n%s version currently loaded is: %s\n",
 419                     QL_NAME, qlcversion);
 420         }
 421 
 422         mdb_printf("qlc mdb library compiled with %s version: %s\n",
 423             QL_NAME, QL_VERSION);
 424 
 425         if ((fwverptr = (uint8_t *)(mdb_alloc(50, UM_SLEEP))) == NULL) {
 426                 mdb_warn("unable to alloc fwverptr\n");
 427                 return (DCMD_OK);
 428         }
 429 
 430         if (mdb_readvar(&fw_table, "fw_table") == -1) {
 431                 mdb_warn("unable to read firmware table\n");
 432         } else {
 433                 ql_adapter_state_t      *qlstate;
 434                 uintptr_t               hbaptr = NULL;
 435 
 436                 if (mdb_readvar(&ql_hba, "ql_hba") == -1) {
 437                         mdb_warn("failed to read ql_hba structure");
 438                         return (DCMD_ERR);
 439                 }
 440 
 441                 if ((qlstate = (ql_adapter_state_t *)mdb_alloc(
 442                     sizeof (ql_adapter_state_t), UM_SLEEP)) == NULL) {
 443                         mdb_warn("Unable to allocate memory for "
 444                             "ql_adapter_state\n");
 445                         return (DCMD_OK);
 446                 }
 447 
 448                 mdb_printf("\n%-8s%-11s%s\n", "f/w", "compiled", "loaded");
 449                 mdb_printf("%<u>%-8s%-11s%-13s%s%</u>\n\n", "class", "version",
 450                     "version", "instance list");
 451 
 452                 for (fwt = &fw_table[0]; fwt->fw_class; fwt++) {
 453 
 454                         if (mdb_vread(fwverptr, sizeof (void *),
 455                             (uintptr_t)fwt->fw_version) == -1) {
 456                                 mdb_warn("unable to read fwverptr\n");
 457                                 mdb_free(fwverptr, sizeof (void *));
 458                                 mdb_free(qlstate, sizeof (ql_adapter_state_t));
 459                                 return (DCMD_OK);
 460                         }
 461 
 462                         mdb_printf("%x\t%-11s", fwt->fw_class, fwverptr);
 463 
 464                         if (ql_hba.first == NULL) {
 465                                 mdb_warn("failed to read ql_hba structure");
 466                                 hbaptr = NULL;
 467                         } else {
 468                                 hbaptr = (uintptr_t)ql_hba.first;
 469                         }
 470 
 471                         found = 0;
 472                         while (hbaptr != NULL) {
 473 
 474                                 if (mdb_vread(qlstate,
 475                                     sizeof (ql_adapter_state_t), hbaptr) ==
 476                                     -1) {
 477                                         mdb_warn("failed to read "
 478                                             "ql_adapter_state at %p", hbaptr);
 479                                         break;
 480                                 }
 481 
 482                                 if (qlstate->fw_class == fwt->fw_class) {
 483                                         if (found == 0) {
 484                                                 mdb_printf("%x.%02x.%02x\t",
 485                                                     qlstate->fw_major_version,
 486                                                     qlstate->fw_minor_version,
 487                                                     qlstate->
 488                                                     fw_subminor_version);
 489                                                 mdb_printf("%d",
 490                                                     qlstate->instance);
 491                                         } else {
 492                                                 mdb_printf(", %d",
 493                                                     qlstate->instance);
 494                                         }
 495                                         found = 1;
 496                                 }
 497 
 498                                 hbaptr = (uintptr_t)qlstate->hba.next;
 499                         }
 500 
 501                         if (found == 1) {
 502                                 mdb_printf("\n");
 503                         } else {
 504                                 mdb_printf("not loaded\n");
 505                         }
 506                 }
 507 
 508                 mdb_free(qlstate, sizeof (ql_adapter_state_t));
 509                 mdb_free(fwverptr, sizeof (void *));
 510         }
 511 
 512         return (DCMD_OK);
 513 }
 514 
 515 /*
 516  * qlc_el_dcmd
 517  *      mdb dcmd which turns the extended logging bit on or off
 518  *      for the specificed qlc instance(s).
 519  *
 520  * Input:
 521  *      addr  = User supplied address -- error if supplied.
 522  *      flags = mdb flags.
 523  *      argc  = Number of user supplied args -- error if non-zero.
 524  *      argv  = Arg array.
 525  *
 526  * Returns:
 527  *      DCMD_USAGE, or DCMD_OK
 528  *
 529  * Context:
 530  *      User context.
 531  *
 532  */
 533 /*ARGSUSED*/
 534 static int
 535 qlc_el_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 536 {
 537         int8_t                  qlcversion[100];
 538         boolean_t               elswitch;
 539         uint32_t                argcnt;
 540         int                     mdbs;
 541         uint32_t                instance;
 542         uint32_t                qlsize = sizeof (ql_adapter_state_t);
 543         ql_adapter_state_t      *qlstate;
 544         uintptr_t               hbaptr = NULL;
 545         ql_head_t               ql_hba;
 546 
 547         if ((mdbs = mdb_get_state()) == MDB_STATE_DEAD) {
 548                 mdb_warn("Cannot change core file data (state=%xh)\n", mdbs);
 549                 return (DCMD_OK);
 550         }
 551 
 552         if ((flags & DCMD_ADDRSPEC) || argc < 2) {
 553                 return (DCMD_USAGE);
 554         }
 555 
 556         /*
 557          * Check and make sure the driver version and the mdb versions
 558          * match so all the structures and flags line up
 559          */
 560 
 561         if (mdb_readvar(&qlcversion, "qlc_driver_version") == -1) {
 562                 mdb_warn("unable to read qlc driver version\n");
 563                 return (DCMD_OK);
 564         }
 565 
 566         if ((strcmp(QL_VERSION, (const char *)&qlcversion)) != 0) {
 567                 mdb_warn("Error: qlc driver/qlc mdb version mismatch\n");
 568                 mdb_printf("\tqlc mdb library compiled version is: %s\n",
 569                     QL_VERSION);
 570                 mdb_printf("\tqlc driver version is: %s\n", qlcversion);
 571 
 572                 return (DCMD_OK);
 573         }
 574 
 575         if ((strcasecmp(argv[0].a_un.a_str, "on")) == 0) {
 576                 elswitch = TRUE;
 577         } else if ((strcasecmp(argv[0].a_un.a_str, "off")) == 0) {
 578                 elswitch = FALSE;
 579         } else {
 580                 return (DCMD_USAGE);
 581         }
 582 
 583         if (mdb_readvar(&ql_hba, "ql_hba") == -1) {
 584                 mdb_warn("failed to read ql_hba structure");
 585                 return (DCMD_ERR);
 586         }
 587 
 588         if (ql_hba.first == NULL) {
 589                 mdb_warn("failed to read ql_hba structure - is qlc loaded?");
 590                 return (DCMD_ERR);
 591         }
 592 
 593         if ((qlstate = (ql_adapter_state_t *)mdb_alloc(qlsize,
 594             UM_SLEEP)) == NULL) {
 595                 mdb_warn("Unable to allocate memory for "
 596                     "ql_adapter_state\n");
 597                 return (DCMD_OK);
 598         }
 599 
 600         if ((strcasecmp(argv[1].a_un.a_str, "all")) == 0) {
 601 
 602                 if (argc != 2) {
 603                         mdb_free(qlstate, qlsize);
 604                         return (DCMD_USAGE);
 605                 }
 606 
 607                 hbaptr = (uintptr_t)ql_hba.first;
 608 
 609                 while (hbaptr != NULL) {
 610 
 611                         if (mdb_vread(qlstate, qlsize, hbaptr) == -1) {
 612                                 mdb_free(qlstate, qlsize);
 613                                 mdb_warn("failed to read ql_adapter_state "
 614                                     "at %p", hbaptr);
 615                                 return (DCMD_OK);
 616                         }
 617 
 618                         ql_elog_common(qlstate, elswitch);
 619 
 620                         hbaptr = (uintptr_t)qlstate->hba.next;
 621                 }
 622         } else {
 623                 for (argcnt = 1; argcnt < argc; argcnt++) {
 624 
 625                         instance = (uint32_t)mdb_strtoull(
 626                             argv[argcnt].a_un.a_str);
 627 
 628                         /* find the correct instance to change */
 629                         hbaptr = (uintptr_t)ql_hba.first;
 630                         while (hbaptr != NULL) {
 631 
 632                                 if (mdb_vread(qlstate, qlsize, hbaptr) == -1) {
 633                                         mdb_free(qlstate, qlsize);
 634                                         mdb_warn("failed to read "
 635                                             "ql_adapter_state at %p", hbaptr);
 636                                         return (DCMD_OK);
 637                                 }
 638 
 639                                 if (qlstate->instance == instance) {
 640                                         break;
 641                                 }
 642 
 643                                 hbaptr = (uintptr_t)qlstate->hba.next;
 644                         }
 645 
 646                         if (hbaptr == NULL) {
 647                                 mdb_printf("instance %d is not loaded",
 648                                     instance);
 649                                 continue;
 650                         }
 651 
 652                         ql_elog_common(qlstate, elswitch);
 653                 }
 654         }
 655 
 656         mdb_free(qlstate, qlsize);
 657 
 658         return (DCMD_OK);
 659 }
 660 
 661 /*
 662  * qlc_elog_common
 663  *      mdb helper function which set/resets the extended logging bit
 664  *
 665  * Input:
 666  *      qlstate  = adapter state structure
 667  *      elswitch = boolean which specifies to reset (0) or set (1) the
 668  *                 extended logging bit.
 669  *
 670  * Returns:
 671  *
 672  * Context:
 673  *      User context.
 674  *
 675  */
 676 static void
 677 ql_elog_common(ql_adapter_state_t *qlstate, boolean_t elswitch)
 678 {
 679         uintptr_t       hbaptr = (uintptr_t)qlstate->hba.base_address;
 680         size_t          qlsize = sizeof (ql_adapter_state_t);
 681 
 682         if (elswitch) {
 683                 if ((qlstate->cfg_flags & CFG_ENABLE_EXTENDED_LOGGING) == 0) {
 684 
 685                         qlstate->cfg_flags |= CFG_ENABLE_EXTENDED_LOGGING;
 686 
 687                         if ((mdb_vwrite((const void *)qlstate, qlsize,
 688                             hbaptr)) != (ssize_t)qlsize) {
 689                                 mdb_warn("instance %d - unable to update",
 690                                     qlstate->instance);
 691                         } else {
 692                                 mdb_printf("instance %d extended logging is "
 693                                     "now on\n", qlstate->instance);
 694                         }
 695                 } else {
 696                         mdb_printf("instance %d extended logging is "
 697                             "already on\n", qlstate->instance);
 698                 }
 699         } else {
 700                 if ((qlstate->cfg_flags & CFG_ENABLE_EXTENDED_LOGGING) != 0) {
 701 
 702                         qlstate->cfg_flags &= ~CFG_ENABLE_EXTENDED_LOGGING;
 703 
 704                         if ((mdb_vwrite((const void *)qlstate, qlsize,
 705                             hbaptr)) != (ssize_t)qlsize) {
 706                                 mdb_warn("instance %d - unable to update",
 707                                     qlstate->instance);
 708                         } else {
 709                                 mdb_printf("instance %d extended logging is "
 710                                     "now off\n", qlstate->instance);
 711                         }
 712                 } else {
 713                         mdb_printf("instance %d extended logging is "
 714                             "already off\n", qlstate->instance);
 715                 }
 716         }
 717 }
 718 
 719 /*
 720  * qlc_ocs_dcmd
 721  *      mdb dcmd which prints out the outstanding command array using
 722  *      caller supplied address (which sb the ha structure).
 723  *
 724  * Input:
 725  *      addr  = User supplied ha address.
 726  *      flags = mdb flags.
 727  *      argc  = Number of user supplied args.
 728  *      argv  = Arg array.
 729  *
 730  * Returns:
 731  *      DCMD_USAGE, or DCMD_OK
 732  *
 733  * Context:
 734  *      User context.
 735  *
 736  *
 737  */
 738 static int
 739 /*ARGSUSED*/
 740 qlc_osc_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 741 {
 742         ql_adapter_state_t      *qlstate;
 743         uintptr_t               qlosc, ptr1;
 744         uint32_t                indx, found = 0;
 745         ql_srb_t                *qlsrb;
 746 
 747         if (!(flags & DCMD_ADDRSPEC)) {
 748                 return (DCMD_USAGE);
 749         }
 750 
 751         if ((qlstate = (ql_adapter_state_t *)
 752             mdb_alloc(sizeof (ql_adapter_state_t), UM_SLEEP)) == NULL) {
 753                 mdb_warn("Unable to allocate memory for ql_adapter_state\n");
 754                 return (DCMD_OK);
 755         }
 756         if (mdb_vread(qlstate, sizeof (ql_adapter_state_t), addr) == -1) {
 757                 mdb_free(qlstate, sizeof (ql_adapter_state_t));
 758                 mdb_warn("failed to read ql_adapter_state at %p", addr);
 759                 return (DCMD_OK);
 760         }
 761 
 762         qlosc = (uintptr_t)qlstate->outstanding_cmds;
 763         mdb_printf("qlc instance: %d, base addr = %llx, osc base = %p\n",
 764             qlstate->instance, qlstate->hba.base_address, qlosc);
 765 
 766         if ((qlsrb = (ql_srb_t *)mdb_alloc(sizeof (ql_srb_t), UM_SLEEP)) ==
 767             NULL) {
 768                 mdb_free(qlstate, sizeof (ql_adapter_state_t));
 769                 mdb_warn("failed to allocate space for srb_t\n");
 770                 return (DCMD_OK);
 771         }
 772         for (indx = 0; indx < qlstate->osc_max_cnt; indx++, qlosc += 8) {
 773                 if (mdb_vread(&ptr1, 8, qlosc) == -1) {
 774                         mdb_warn("failed to read ptr1, indx=%d", indx);
 775                         break;
 776                 }
 777                 if (ptr1 == 0) {
 778                         continue;
 779                 }
 780 
 781                 mdb_printf("osc ptr = %p, indx = %xh\n", ptr1, indx);
 782 
 783                 if (mdb_vread(qlsrb, sizeof (ql_srb_t), ptr1) == -1) {
 784                         mdb_warn("failed to read ql_srb_t at %p", ptr1);
 785                         break;
 786                 }
 787                 (void) ql_doprint(ptr1, "struct ql_srb");
 788                 found++;
 789         }
 790 
 791         mdb_free(qlsrb, sizeof (ql_srb_t));
 792         mdb_free(qlstate, sizeof (ql_adapter_state_t));
 793 
 794         mdb_printf("number of outstanding command srb's is: %d\n", found);
 795 
 796         return (DCMD_OK);
 797 }
 798 
 799 /*
 800  * qlc_wdog_dcmd
 801  *      mdb dcmd which prints out the commands which are linked
 802  *      on the watchdog linked list. Caller supplied address (which
 803  *      sb the ha structure).
 804  *
 805  * Input:
 806  *      addr  = User supplied ha address.
 807  *      flags = mdb flags.
 808  *      argc  = Number of user supplied args.
 809  *      argv  = Arg array.
 810  *
 811  * Returns:
 812  *      DCMD_USAGE, or DCMD_OK
 813  *
 814  * Context:
 815  *      User context.
 816  *
 817  *
 818  */
 819 static int
 820 /*ARGSUSED*/
 821 qlc_wdog_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 822 {
 823         ql_adapter_state_t      *qlstate;
 824         uint16_t                index, count;
 825         ql_head_t               *dev;
 826         ql_srb_t                *srb;
 827         ql_tgt_t                *tq;
 828         ql_lun_t                *lq;
 829         ql_link_t               *tqlink, *srblink, *lqlink;
 830         int                     nextlink;
 831 
 832         if (!(flags & DCMD_ADDRSPEC)) {
 833                 mdb_warn("Address required\n", addr);
 834                 return (DCMD_USAGE);
 835         }
 836 
 837         if ((qlstate = (ql_adapter_state_t *)
 838             mdb_alloc(sizeof (ql_adapter_state_t), UM_SLEEP)) == NULL) {
 839                 mdb_warn("Unable to allocate memory for ql_adapter_state\n");
 840                 return (DCMD_OK);
 841         }
 842 
 843         if (mdb_vread(qlstate, sizeof (ql_adapter_state_t), addr) == -1) {
 844                 mdb_free(qlstate, sizeof (ql_adapter_state_t));
 845                 mdb_warn("failed to read ql_adapter_state at %p", addr);
 846                 return (DCMD_OK);
 847         }
 848 
 849         /*
 850          * Read in the device array
 851          */
 852         dev = (ql_head_t *)
 853             mdb_alloc(sizeof (ql_head_t) * DEVICE_HEAD_LIST_SIZE, UM_SLEEP);
 854 
 855         if (mdb_vread(dev, sizeof (ql_head_t) * DEVICE_HEAD_LIST_SIZE,
 856             (uintptr_t)qlstate->dev) == -1) {
 857                 mdb_warn("failed to read ql_head_t (dev) at %p", qlstate->dev);
 858                 mdb_free(qlstate, sizeof (ql_adapter_state_t));
 859                 mdb_free(dev, sizeof (ql_head_t) * DEVICE_HEAD_LIST_SIZE);
 860                 return (DCMD_OK);
 861         }
 862 
 863         tqlink = (ql_link_t *)mdb_alloc(sizeof (ql_link_t), UM_SLEEP);
 864         tq = (ql_tgt_t *)mdb_alloc(sizeof (ql_tgt_t), UM_SLEEP);
 865         lqlink = (ql_link_t *)mdb_alloc(sizeof (ql_link_t), UM_SLEEP);
 866         lq = (ql_lun_t *)mdb_alloc(sizeof (ql_lun_t), UM_SLEEP);
 867         srblink = (ql_link_t *)mdb_alloc(sizeof (ql_link_t), UM_SLEEP);
 868         srb = (ql_srb_t *)mdb_alloc(sizeof (ql_srb_t), UM_SLEEP);
 869 
 870         /*
 871          * Validate the devices watchdog queue
 872          */
 873         for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
 874 
 875                 /* Skip empty ones */
 876                 if (dev[index].first == NULL) {
 877                         continue;
 878                 }
 879 
 880                 mdb_printf("dev array index = %x\n", index);
 881 
 882                 /* Loop through targets on device linked list */
 883                 /* get the first link */
 884 
 885                 nextlink = get_first_link(&dev[index], tqlink);
 886 
 887                 /*
 888                  * traverse the targets linked list at this device array index.
 889                  */
 890                 while (nextlink == DCMD_OK) {
 891                         /* Get the target */
 892                         if (mdb_vread(tq, sizeof (ql_tgt_t),
 893                             (uintptr_t)(tqlink->base_address)) == -1) {
 894                                 mdb_warn("failed to read ql_tgt at %p",
 895                                     tqlink->base_address);
 896                                 break;
 897                         }
 898                         mdb_printf("tgt q base = %llx, ",
 899                             tqlink->base_address);
 900 
 901                         mdb_printf("flags: (%xh)", tq->flags);
 902 
 903                         if (tq->flags) {
 904                                 ql_dump_flags((uint64_t)tq->flags, qltgt_flags);
 905                         }
 906 
 907                         mdb_printf("tgt: %02x%02x%02x%02x%02x%02x%02x%02x ",
 908                             tq->node_name[0], tq->node_name[1],
 909                             tq->node_name[2], tq->node_name[3],
 910                             tq->node_name[4], tq->node_name[5],
 911                             tq->node_name[6], tq->node_name[7]);
 912 
 913                         /*
 914                          * Loop through commands on this targets watchdog queue.
 915                          */
 916 
 917                         /* Get the first link on the targets cmd wdg q. */
 918                         if (tq->wdg.first == NULL) {
 919                                 mdb_printf(" watchdog list empty ");
 920                                 break;
 921                         } else {
 922                                 if (mdb_vread(srblink, sizeof (ql_link_t),
 923                                     (uintptr_t)tq->wdg.first) == -1) {
 924                                         mdb_warn("failed to read ql_link_t"
 925                                             " at %p", tq->wdg.first);
 926                                         break;
 927                                 }
 928                                 /* There is aleast one. */
 929                                 count = 1;
 930                                 /*
 931                                  * Count the remaining items in the
 932                                  * cmd watchdog list.
 933                                  */
 934                                 while (srblink->next != NULL) {
 935                                         /* Read in the next ql_link_t header */
 936                                         if (mdb_vread(srblink,
 937                                             sizeof (ql_link_t),
 938                                             (uintptr_t)srblink->next) == -1) {
 939                                                 mdb_warn("failed to read"
 940                                                     " ql_link_t next at %p",
 941                                                     srblink->next);
 942                                                 break;
 943                                         }
 944                                         count = (uint16_t)(count + 1);
 945                                 }
 946                                 mdb_printf(" watchdog list: %d entries\n",
 947                                     count);
 948                                 /* get the first one again */
 949                                 if (mdb_vread(srblink, sizeof (ql_link_t),
 950                                     (uintptr_t)tq->wdg.first) == -1) {
 951                                         mdb_warn("failed to read ql_link_t"
 952                                             " at %p", tq->wdg.first);
 953                                         break;
 954                                 }
 955                         }
 956                         /*
 957                          * Traverse the targets cmd watchdog linked list
 958                          * verifying srb's from the list are on a lun cmd list.
 959                          */
 960                         while (nextlink == DCMD_OK) {
 961                                 int     found = 0;
 962                                 /* get the srb */
 963                                 if (mdb_vread(srb, sizeof (ql_srb_t),
 964                                     (uintptr_t)srblink->base_address) == -1) {
 965                                         mdb_warn("failed to read ql_srb_t"
 966                                         " at %p", srblink->base_address);
 967                                         break;
 968                                 }
 969                                 mdb_printf("ql_srb %llx ",
 970                                     srblink->base_address);
 971 
 972                                 /*
 973                                  * Get the lun q the srb is on
 974                                  */
 975                                 if (mdb_vread(lq, sizeof (ql_lun_t),
 976                                     (uintptr_t)srb->lun_queue) == -1) {
 977                                         mdb_warn("failed to read ql_srb_t"
 978                                             " at %p", srb->lun_queue);
 979                                         break;
 980                                 }
 981                                 nextlink = get_first_link(&lq->cmd, lqlink);
 982                                 /*
 983                                  * traverse the lun cmd linked list looking
 984                                  * for the srb from the targets watchdog list
 985                                  */
 986                                 while (nextlink == DCMD_OK) {
 987                                         if (srblink->base_address ==
 988                                             lqlink->base_address) {
 989                                                 mdb_printf("on lun %d cmd q\n",
 990                                                     lq->lun_no);
 991                                                 found = 1;
 992                                                 break;
 993                                         }
 994                                         /* get next item on lun cmd list */
 995                                         nextlink = get_next_link(lqlink);
 996                                 }
 997                                 if (!found) {
 998                                         mdb_printf("not found on lun cmd q\n");
 999                                 }
1000                                 /* get next item in the watchdog list */
1001                                 nextlink = get_next_link(srblink);
1002                         } /* End targets command watchdog list */
1003                         /* get next item in this target list */
1004                         nextlink = get_next_link(tqlink);
1005                 } /* End traverse the device targets linked list */
1006                 mdb_printf("\n");
1007         } /* End device array */
1008 
1009         mdb_free(tq, sizeof (ql_tgt_t));
1010         mdb_free(lq, sizeof (ql_lun_t));
1011         mdb_free(srb, sizeof (ql_srb_t));
1012         mdb_free(tqlink, sizeof (ql_link_t));
1013         mdb_free(srblink, sizeof (ql_link_t));
1014         mdb_free(lqlink, sizeof (ql_link_t));
1015         mdb_free(qlstate, sizeof (ql_adapter_state_t));
1016         mdb_free(dev, sizeof (ql_head_t)*DEVICE_HEAD_LIST_SIZE);
1017 
1018         return (DCMD_OK);
1019 }
1020 
1021 /*
1022  * get_first_link
1023  *      Gets the first ql_link_t header on ql_head.
1024  *
1025  * Input:
1026  *      ql_head  = pointer to a ql_head_t structure.
1027  *      ql_link  = pointer to a ql_link_t structure.
1028  *
1029  * Returns:
1030  *      DCMD_ABORT, or DCMD_OK
1031  *
1032  * Context:
1033  *      User context.
1034  *
1035  */
1036 static int
1037 get_first_link(ql_head_t *qlhead, ql_link_t *qllink)
1038 {
1039         int     rval = DCMD_ABORT;
1040 
1041         if (qlhead != NULL) {
1042                 if (qlhead->first != NULL) {
1043                         /* Read in the first ql_link_t header */
1044                         if (mdb_vread(qllink, sizeof (ql_link_t),
1045                             (uintptr_t)(qlhead->first)) == -1) {
1046                                 mdb_warn("failed to read ql_link_t "
1047                                     "next at %p", qlhead->first);
1048                         } else {
1049                                 rval = DCMD_OK;
1050                         }
1051                 }
1052         }
1053         return (rval);
1054 }
1055 
1056 /*
1057  * get_next_link
1058  *      Gets the next ql_link_t structure.
1059  *
1060  * Input:
1061  *      ql_link  = pointer to a ql_link_t structure.
1062  *
1063  * Returns:
1064  *      DCMD_ABORT, or DCMD_OK
1065  *
1066  * Context:
1067  *      User context.
1068  *
1069  */
1070 static int
1071 get_next_link(ql_link_t *qllink)
1072 {
1073         int     rval = DCMD_ABORT;
1074 
1075         if (qllink != NULL) {
1076                 if (qllink->next != NULL) {
1077                         /* Read in the next ql_link_t header */
1078                         if (mdb_vread(qllink, sizeof (ql_link_t),
1079                             (uintptr_t)(qllink->next)) == -1) {
1080                                 mdb_warn("failed to read ql_link_t "
1081                                     "next at %p", qllink->next);
1082                         } else {
1083                                 rval = DCMD_OK;
1084                         }
1085                 }
1086         }
1087         return (rval);
1088 }
1089 
1090 /*
1091  * qlcstate_dcmd
1092  *      mdb dcmd which prints out the ql_state info using
1093  *      caller supplied address.
1094  *
1095  * Input:
1096  *      addr  = User supplied address.
1097  *      flags = mdb flags.
1098  *      argc  = Number of user supplied args.
1099  *      argv  = Arg array.
1100  *
1101  * Returns:
1102  *      DCMD_USAGE, or DCMD_OK
1103  *
1104  * Context:
1105  *      User context.
1106  *
1107  */
1108 static int
1109 qlcstate_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1110 {
1111         ql_adapter_state_t      *qlstate;
1112         int                     verbose = 0;
1113 
1114         if (!(flags & DCMD_ADDRSPEC)) {
1115                 return (DCMD_USAGE);
1116         }
1117 
1118         if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose) !=
1119             argc) {
1120                 return (DCMD_USAGE);
1121         }
1122 
1123         if ((qlstate = (ql_adapter_state_t *)
1124             mdb_alloc(sizeof (ql_adapter_state_t), UM_SLEEP)) == NULL) {
1125                 mdb_warn("failed to allocate memory for ql_adapter_state\n");
1126                 return (DCMD_OK);
1127         }
1128         if (mdb_vread(qlstate, sizeof (ql_adapter_state_t), addr) == -1) {
1129                 mdb_free(qlstate, sizeof (ql_adapter_state_t));
1130                 mdb_warn("failed to read ql_adapter_state at %p", addr);
1131                 return (DCMD_OK);
1132         }
1133 
1134         mdb_printf("qlc instance: %d, base addr = %llx\n", qlstate->instance,
1135             addr);
1136 
1137         mdb_printf("\nadapter state flags:\n");
1138         ql_dump_flags((uint64_t)qlstate->flags, adapter_state_flags);
1139         mdb_printf("\nadapter cfg flags:\n");
1140         ql_dump_flags((uint64_t)qlstate->cfg_flags, adapter_config_flags);
1141         mdb_printf("\ntask daemon state flags:\n");
1142         ql_dump_flags((uint64_t)qlstate->task_daemon_flags,
1143             task_daemon_flags);
1144 
1145         if (verbose) {
1146                 (void) ql_doprint(addr, "struct ql_adapter_state");
1147         }
1148 
1149         mdb_free(qlstate, sizeof (ql_adapter_state_t));
1150 
1151         return (DCMD_OK);
1152 }
1153 
1154 /*
1155  * qlcstates_walk_init
1156  *      mdb walker init which prints out all qlc states info.
1157  *
1158  * Input:
1159  *      wsp - Pointer to walker state struct
1160  *
1161  * Returns:
1162  *      WALK_ERR, or WALK_NEXT
1163  *
1164  * Context:
1165  *      User context.
1166  *
1167  */
1168 static int
1169 qlstates_walk_init(mdb_walk_state_t *wsp)
1170 {
1171         ql_head_t       ql_hba;
1172 
1173         if (wsp->walk_addr == NULL) {
1174                 if ((mdb_readvar(&ql_hba, "ql_hba") == -1) ||
1175                     (&ql_hba == NULL)) {
1176                         mdb_warn("failed to read ql_hba structure");
1177                         return (WALK_ERR);
1178                 }
1179 
1180                 wsp->walk_addr = (uintptr_t)ql_hba.first;
1181                 wsp->walk_data = mdb_alloc(sizeof (ql_adapter_state_t),
1182                     UM_SLEEP);
1183                 return (WALK_NEXT);
1184         } else {
1185                 return (ql_doprint(wsp->walk_addr, "struct ql_adapter_state"));
1186         }
1187 }
1188 
1189 /*
1190  * qlstates_walk_step
1191  *      mdb walker step which prints out all qlc states info.
1192  *
1193  * Input:
1194  *      wsp - Pointer to walker state struct
1195  *
1196  * Returns:
1197  *      WALK_DONE, or WALK_NEXT
1198  *
1199  * Context:
1200  *      User context.
1201  *
1202  */
1203 static int
1204 qlstates_walk_step(mdb_walk_state_t *wsp)
1205 {
1206         ql_adapter_state_t      *qlstate;
1207 
1208         if (wsp->walk_addr == NULL) {
1209                 return (WALK_DONE);
1210         }
1211 
1212         if (mdb_vread(wsp->walk_data, sizeof (ql_adapter_state_t),
1213             wsp->walk_addr) == -1) {
1214                 mdb_warn("failed to read ql_adapter_state at %p",
1215                     wsp->walk_addr);
1216                 return (WALK_DONE);
1217         }
1218 
1219         qlstate = (ql_adapter_state_t *)(wsp->walk_data);
1220         mdb_printf("qlc instance: %d, base addr = %llx\n",
1221             qlstate->instance, wsp->walk_addr);
1222 
1223         mdb_printf("\nadapter state flags:\n");
1224         ql_dump_flags((uint64_t)qlstate->flags, adapter_state_flags);
1225         mdb_printf("\nadapter cfg flags:\n");
1226         ql_dump_flags((uint64_t)qlstate->cfg_flags, adapter_config_flags);
1227         mdb_printf("\ntask daemon state flags:\n");
1228         ql_dump_flags((uint64_t)qlstate->task_daemon_flags,
1229             task_daemon_flags);
1230 
1231         mdb_printf("\nadapter state:\n");
1232         (void) ql_doprint(wsp->walk_addr, "struct ql_adapter_state");
1233 
1234         mdb_printf("\n");
1235 
1236         wsp->walk_addr = (uintptr_t)
1237             (((ql_adapter_state_t *)wsp->walk_data)->hba.next);
1238 
1239         return (WALK_NEXT);
1240 }
1241 
1242 /*
1243  * qlstates_walk_fini
1244  *      mdb walker fini which wraps up the walker
1245  *
1246  * Input:
1247  *      wsp - Pointer to walker state struct
1248  *
1249  * Returns:
1250  *
1251  * Context:
1252  *      User context.
1253  *
1254  */
1255 static void
1256 qlstates_walk_fini(mdb_walk_state_t *wsp)
1257 {
1258         mdb_free(wsp->walk_data, sizeof (ql_adapter_state_t));
1259 }
1260 
1261 /*
1262  * qlsrb_walk_init
1263  *      mdb walker init which prints out linked srb's
1264  *
1265  * Input:
1266  *      wsp - Pointer to walker ql_srb struct
1267  *
1268  * Returns:
1269  *      WALK_ERR, or WALK_NEXT
1270  *
1271  * Context:
1272  *      User context.
1273  *
1274  */
1275 static int
1276 qlsrb_walk_init(mdb_walk_state_t *wsp)
1277 {
1278         if (wsp->walk_addr == NULL) {
1279                 mdb_warn("failed to read ql_srb addr at %p",
1280                     wsp->walk_addr);
1281                 return (WALK_ERR);
1282         }
1283 
1284         wsp->walk_data = mdb_alloc(sizeof (ql_srb_t), UM_SLEEP);
1285 
1286         return (WALK_NEXT);
1287 }
1288 
1289 /*
1290  * qlcsrb_walk_step
1291  *      mdb walker step which prints out linked ql_srb structures
1292  *
1293  * Input:
1294  *      wsp - Pointer to walker srb struct
1295  *
1296  * Returns:
1297  *      WALK_DONE, or WALK_NEXT
1298  *
1299  * Context:
1300  *      User context.
1301  *
1302  */
1303 static int
1304 qlsrb_walk_step(mdb_walk_state_t *wsp)
1305 {
1306         ql_srb_t        *qlsrb;
1307 
1308         if (wsp->walk_addr == NULL)
1309                 return (WALK_DONE);
1310 
1311         if (mdb_vread(wsp->walk_data, sizeof (ql_srb_t),
1312             wsp->walk_addr) == -1) {
1313                 mdb_warn("failed to read ql_srb at %p", wsp->walk_addr);
1314                 return (WALK_DONE);
1315         }
1316 
1317         qlsrb = (ql_srb_t *)(wsp->walk_data);
1318         mdb_printf("ql_srb base addr = %llx\n", wsp->walk_addr);
1319 
1320         mdb_printf("\nql_srb flags:\n");
1321         ql_dump_flags((uint64_t)qlsrb->flags, qlsrb_flags);
1322 
1323         mdb_printf("\nql_srb:\n");
1324         (void) ql_doprint(wsp->walk_addr, "struct ql_srb");
1325 
1326         mdb_printf("\n");
1327 
1328         wsp->walk_addr = (uintptr_t)
1329             (((ql_srb_t *)wsp->walk_data)->cmd.next);
1330 
1331         return (WALK_NEXT);
1332 }
1333 
1334 /*
1335  * qlsrb_walk_fini
1336  *      mdb walker fini which wraps up the walker
1337  *
1338  * Input:
1339  *      wsp - Pointer to walker state struct
1340  *
1341  * Returns:
1342  *
1343  * Context:
1344  *      User context.
1345  *
1346  */
1347 static void
1348 qlsrb_walk_fini(mdb_walk_state_t *wsp)
1349 {
1350         mdb_free(wsp->walk_data, sizeof (ql_srb_t));
1351 }
1352 
1353 /*
1354  * qllunq_dcmd
1355  *      mdb walker which prints out lun q's
1356  *
1357  * Input:
1358  *      wsp - Pointer to walker ql_lun struct
1359  *
1360  * Returns:
1361  *      WALK_ERR, or WALK_NEXT
1362  *
1363  * Context:
1364  *      User context.
1365  *
1366  */
1367 static int
1368 qllunq_walk_init(mdb_walk_state_t *wsp)
1369 {
1370         if (wsp->walk_addr == NULL) {
1371                 mdb_warn("failed to read ql_lun addr at %p",
1372                     wsp->walk_addr);
1373                 return (WALK_ERR);
1374         }
1375 
1376         wsp->walk_data = mdb_alloc(sizeof (ql_lun_t), UM_SLEEP);
1377 
1378         return (WALK_NEXT);
1379 }
1380 
1381 /*
1382  * qlclunq_walk_step
1383  *      mdb walker step which prints out linked ql_lun structures
1384  *
1385  * Input:
1386  *      wsp - Pointer to walker srb struct
1387  *
1388  * Returns:
1389  *      WALK_DONE, or WALK_NEXT
1390  *
1391  * Context:
1392  *      User context.
1393  *
1394  */
1395 static int
1396 qllunq_walk_step(mdb_walk_state_t *wsp)
1397 {
1398         ql_lun_t        *qllun;
1399         ql_link_t       ql_link;
1400         ql_link_t       *qllink;
1401 
1402         if (wsp->walk_addr == NULL)
1403                 return (WALK_DONE);
1404 
1405         if (mdb_vread(wsp->walk_data, sizeof (ql_lun_t),
1406             wsp->walk_addr) == -1) {
1407                 mdb_warn("failed to read ql_lun at %p", wsp->walk_addr);
1408                 return (WALK_DONE);
1409         }
1410 
1411         qllun = (ql_lun_t *)(wsp->walk_data);
1412         mdb_printf("ql_lun base addr = %llx\n", wsp->walk_addr);
1413 
1414         mdb_printf("\nql_lun flags:\n");
1415         ql_dump_flags((uint64_t)qllun->flags, qllun_flags);
1416 
1417         mdb_printf("\nql_lun:\n");
1418         (void) ql_doprint(wsp->walk_addr, "struct ql_lun");
1419 
1420         mdb_printf("\n");
1421 
1422         qllink = (ql_link_t *)
1423             (((ql_lun_t *)wsp->walk_data)->link.next);
1424 
1425         if (qllink == NULL) {
1426                 return (WALK_DONE);
1427         } else {
1428                 /*
1429                  * Read in the next link_t header
1430                  */
1431                 if (mdb_vread(&ql_link, sizeof (ql_link_t),
1432                     (uintptr_t)qllink) == -1) {
1433                         mdb_warn("failed to read ql_link_t "
1434                             "next at %p", qllink->next);
1435                         return (WALK_DONE);
1436                 }
1437                 qllink = &ql_link;
1438         }
1439 
1440         wsp->walk_addr = (uintptr_t)qllink->base_address;
1441 
1442         return (WALK_NEXT);
1443 }
1444 
1445 /*
1446  * qllunq_walk_fini
1447  *      mdb walker fini which wraps up the walker
1448  *
1449  * Input:
1450  *      wsp - Pointer to walker state struct
1451  *
1452  * Returns:
1453  *
1454  * Context:
1455  *      User context.
1456  *
1457  */
1458 static void
1459 qllunq_walk_fini(mdb_walk_state_t *wsp)
1460 {
1461         mdb_free(wsp->walk_data, sizeof (ql_lun_t));
1462 }
1463 
1464 /*
1465  * qltgtq_dcmd
1466  *      mdb dcmd which prints out an hs's tq struct info.
1467  *
1468  * Input:
1469  *      addr  = User supplied address. (NB: nust be an ha)
1470  *      flags = mdb flags.
1471  *      argc  = Number of user supplied args.
1472  *      argv  = Arg array.
1473  *
1474  * Returns:
1475  *      DCMD_USAGE, or DCMD_OK
1476  *
1477  * Context:
1478  *      User context.
1479  *
1480  */
1481 /*ARGSUSED*/
1482 static int
1483 qltgtq_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1484 {
1485         ql_adapter_state_t      *ha;
1486         ql_link_t               *link;
1487         ql_tgt_t                *tq;
1488         uint32_t                index;
1489         ql_head_t               *dev;
1490 
1491         if ((!(flags & DCMD_ADDRSPEC)) || addr == NULL) {
1492                 mdb_warn("ql_hba structure addr is required");
1493                 return (DCMD_USAGE);
1494         }
1495 
1496         /*
1497          * Get the adapter state struct which was passed
1498          */
1499 
1500         ha = (ql_adapter_state_t *)mdb_alloc(sizeof (ql_adapter_state_t),
1501             UM_SLEEP);
1502 
1503         if (mdb_vread(ha, sizeof (ql_adapter_state_t), addr) == -1) {
1504                 mdb_warn("failed to read ql_adapter_state at %p", addr);
1505                 mdb_free(ha, sizeof (ql_adapter_state_t));
1506                 return (DCMD_OK);
1507         }
1508 
1509         if (ha->dev == NULL) {
1510                 mdb_warn("dev ptr is NULL for ha: %p", addr);
1511                 mdb_free(ha, sizeof (ql_adapter_state_t));
1512                 return (DCMD_OK);
1513         }
1514 
1515         /*
1516          * Read in the device array
1517          */
1518         dev = (ql_head_t *)
1519             mdb_alloc(sizeof (ql_head_t) * DEVICE_HEAD_LIST_SIZE, UM_SLEEP);
1520 
1521         if (mdb_vread(dev, sizeof (ql_head_t) * DEVICE_HEAD_LIST_SIZE,
1522             (uintptr_t)ha->dev) == -1) {
1523                 mdb_warn("failed to read ql_head_t (dev) at %p", ha->dev);
1524                 mdb_free(ha, sizeof (ql_adapter_state_t));
1525                 mdb_free(dev, sizeof (ql_head_t) * DEVICE_HEAD_LIST_SIZE);
1526         }
1527 
1528         tq = (ql_tgt_t *)mdb_alloc(sizeof (ql_tgt_t), UM_SLEEP);
1529         link = (ql_link_t *)mdb_alloc(sizeof (ql_link_t), UM_SLEEP);
1530 
1531         for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
1532 
1533                 if (dev[index].first == NULL) {
1534                         continue;
1535                 }
1536 
1537                 if (mdb_vread(link, sizeof (ql_link_t),
1538                     (uintptr_t)dev[index].first) == -1) {
1539                         mdb_warn("failed to read ql_link_t at %p",
1540                             dev[index].first);
1541                         break;
1542                 }
1543 
1544                 while (link != NULL) {
1545                         if (mdb_vread(tq, sizeof (ql_tgt_t),
1546                             (uintptr_t)(link->base_address)) == -1) {
1547                                 mdb_warn("failed to read ql_tgt at %p",
1548                                     link->base_address);
1549                                 break;
1550                         }
1551 
1552                         mdb_printf("tgt queue base addr = %llx\n",
1553                             link->base_address);
1554 
1555                         mdb_printf("\ntgt queue flags: (%xh)\n", tq->flags);
1556                         ql_dump_flags((uint64_t)tq->flags, qltgt_flags);
1557 
1558                         mdb_printf("\ntgt queue:\n");
1559 
1560                         (void) ql_doprint((uintptr_t)link->base_address,
1561                             "struct ql_target");
1562 
1563                         mdb_printf("\n");
1564 
1565                         if (get_next_link(link) != DCMD_OK) {
1566                                 break;
1567                         }
1568                 }
1569         }
1570 
1571         mdb_free(ha, sizeof (ql_adapter_state_t));
1572         mdb_free(tq, sizeof (ql_tgt_t));
1573         mdb_free(link, sizeof (ql_link_t));
1574         mdb_free(dev, sizeof (ql_head_t)*DEVICE_HEAD_LIST_SIZE);
1575 
1576         return (DCMD_OK);
1577 }
1578 
1579 /*
1580  * ql_triggerdump_dcmd
1581  *      Triggers the driver to take a firmware dump
1582  *
1583  * Input:
1584  *      addr  = User supplied address (optional)
1585  *      flags = mdb flags.
1586  *      argc  = Number of user supplied args.
1587  *      argv  = Arg array (instance #, optional).
1588  *
1589  * Returns:
1590  *      DCMD_OK or DCMD_ERR
1591  *
1592  * Context:
1593  *      User context.
1594  *
1595  */
1596 
1597 #if 0
1598 
1599 /*ARGSUSED*/
1600 static int
1601 qlc_triggerdump_dcmd(uintptr_t addr, uint_t flags, int argc,
1602     const mdb_arg_t *argv)
1603 {
1604         ql_adapter_state_t      *qlstate;
1605         uintptr_t               hbaptr = NULL;
1606         ql_head_t               ql_hba;
1607         uint32_t                qlsize = sizeof (ql_adapter_state_t);
1608         int                     mdbs;
1609 
1610         if ((mdbs = mdb_get_state()) == MDB_STATE_DEAD) {
1611                 mdb_warn("Cannot change core file data (state=%xh)\n", mdbs);
1612                 return (DCMD_OK);
1613         }
1614 
1615         if ((qlstate = (ql_adapter_state_t *)mdb_alloc(qlsize,
1616             UM_SLEEP)) == NULL) {
1617                 mdb_warn("Unable to allocate memory for ql_adapter_state\n");
1618                 return (DCMD_OK);
1619         }
1620 
1621         if (addr == NULL) {
1622                 uint32_t        instance;
1623 
1624                 if (argc == 0) {
1625                         mdb_warn("must specify either the ha addr or "
1626                             "the instance number\n");
1627                         mdb_free(qlstate, qlsize);
1628                         return (DCMD_OK);
1629                 }
1630 
1631                 /*
1632                  * find the specified instance in the ha list
1633                  */
1634 
1635                 instance = (uint32_t)mdb_strtoull(argv[1].a_un.a_str);
1636 
1637                 if (mdb_readvar(&ql_hba, "ql_hba") == -1) {
1638                         mdb_warn("failed to read ql_hba structure");
1639                         mdb_free(qlstate, qlsize);
1640                         return (DCMD_ERR);
1641                 }
1642 
1643                 if (&ql_hba == NULL) {
1644                         mdb_warn("failed to read ql_hba structure - "
1645                             "is qlc loaded?");
1646                         mdb_free(qlstate, qlsize);
1647                         return (DCMD_ERR);
1648                 }
1649 
1650                 hbaptr = (uintptr_t)ql_hba.first;
1651                 while (hbaptr != NULL) {
1652 
1653                         if (mdb_vread(qlstate, qlsize, hbaptr) == -1) {
1654                                 mdb_free(qlstate, qlsize);
1655                                 mdb_warn("failed to read "
1656                                     "ql_adapter_state at %p", hbaptr);
1657                                 return (DCMD_OK);
1658                         }
1659 
1660                         if (qlstate->instance == instance) {
1661                                 break;
1662                         }
1663 
1664                         hbaptr = (uintptr_t)qlstate->hba.next;
1665                 }
1666         } else {
1667 
1668                 /*
1669                  * verify the addr specified
1670                  */
1671 
1672                 if (mdb_readvar(&ql_hba, "ql_hba") == -1) {
1673                         mdb_warn("failed to read ql_hba structure");
1674                         mdb_free(qlstate, qlsize);
1675                         return (DCMD_ERR);
1676                 }
1677 
1678                 if (&ql_hba == NULL) {
1679                         mdb_warn("failed to read ql_hba structure - "
1680                             "is qlc loaded?");
1681                         mdb_free(qlstate, qlsize);
1682                         return (DCMD_ERR);
1683                 }
1684 
1685                 hbaptr = (uintptr_t)ql_hba.first;
1686                 while (hbaptr != NULL) {
1687 
1688                         if (mdb_vread(qlstate, qlsize, hbaptr) == -1) {
1689                                 mdb_free(qlstate, qlsize);
1690                                 mdb_warn("failed to read "
1691                                     "ql_adapter_state at %p", hbaptr);
1692                                 return (DCMD_OK);
1693                         }
1694 
1695                         if (hbaptr == addr) {
1696                                 break;
1697                         }
1698 
1699                         hbaptr = (uintptr_t)qlstate->hba.next;
1700                 }
1701         }
1702 
1703         if (hbaptr == NULL) {
1704                 mdb_free(qlstate, qlsize);
1705                 if (argc == 0) {
1706                         mdb_warn("addr specified is not in the hba list\n");
1707                 } else {
1708                         mdb_warn("instance specified does not exist\n");
1709                 }
1710                 return (DCMD_OK);
1711         }
1712 
1713         if (((qlstate->ql_dump_state & QL_DUMP_VALID) != 0) ||
1714             (qlstate->ql_dump_ptr != NULL)) {
1715                 mdb_warn("instance %d already has a valid dump\n",
1716                     qlstate->instance);
1717                 mdb_free(qlstate, qlsize);
1718                 return (DCMD_OK);
1719         }
1720 }
1721 #endif
1722 
1723 /*
1724  * ql_getdump_dcmd
1725  *      prints out the firmware dump buffer
1726  *
1727  * Input:
1728  *      addr  = User supplied address. (NB: must be an ha)
1729  *      flags = mdb flags.
1730  *      argc  = Number of user supplied args.
1731  *      argv  = Arg array.
1732  *
1733  * Returns:
1734  *      DCMD_OK or DCMD_ERR
1735  *
1736  * Context:
1737  *      User context.
1738  *
1739  */
1740 static int
1741 qlc_getdump_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1742 {
1743         ql_adapter_state_t      *ha;
1744         ql_head_t               ql_hba;
1745         uintptr_t               hbaptr = NULL;
1746         int                     verbose = 0;
1747 
1748         if ((!(flags & DCMD_ADDRSPEC)) || addr == NULL) {
1749                 mdb_warn("ql_adapter_state structure addr is required");
1750                 return (DCMD_USAGE);
1751         }
1752 
1753         if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose) !=
1754             argc) {
1755                 return (DCMD_USAGE);
1756         }
1757 
1758         /*
1759          * Get the adapter state struct which was passed
1760          */
1761         if ((ha = (ql_adapter_state_t *)mdb_alloc(sizeof (ql_adapter_state_t),
1762             UM_SLEEP)) == NULL) {
1763                 mdb_warn("failed to allocate memory for ql_adapter_state\n");
1764                 return (DCMD_OK);
1765         }
1766 
1767         /*
1768          * show user which instances have valid f/w dumps available if
1769          * user has specified verbose option
1770          */
1771         if (mdb_readvar(&ql_hba, "ql_hba") == -1) {
1772                 mdb_warn("failed to read ql_hba structure");
1773         } else if (ql_hba.first == NULL) {
1774                 mdb_warn("failed to read ql_hba structure -- is qlc loaded?");
1775         } else if (verbose) {
1776                 hbaptr = (uintptr_t)ql_hba.first;
1777                 while (hbaptr != NULL) {
1778 
1779                         if (mdb_vread(ha, sizeof (ql_adapter_state_t),
1780                             hbaptr) == -1) {
1781                                 mdb_free(ha, sizeof (ql_adapter_state_t));
1782                                 mdb_warn("failed read ql_adapter_state at %p",
1783                                     hbaptr);
1784                                 return (DCMD_OK);
1785                         }
1786 
1787                         mdb_printf("instance %d:\n", ha->instance);
1788                         (void) mdb_inc_indent((ulong_t)4);
1789 
1790                         if (ha->ql_dump_state == 0) {
1791                                 mdb_printf("no dump flags\n");
1792                         } else {
1793                                 ql_dump_flags((uint64_t)ha->ql_dump_state,
1794                                     qldump_flags);
1795                         }
1796 
1797                         if (ha->ql_dump_ptr == NULL) {
1798                                 mdb_printf("no dump address\n");
1799                         } else {
1800                                 mdb_printf("dump address is: %p\n",
1801                                     ha->ql_dump_ptr);
1802                         }
1803 
1804                         (void) mdb_dec_indent((ulong_t)4);
1805 
1806                         hbaptr = (uintptr_t)ha->hba.next;
1807                 }
1808                 mdb_printf("\n");
1809         }
1810 
1811         if (mdb_vread(ha, sizeof (ql_adapter_state_t), addr) == -1) {
1812                 mdb_warn("failed to read ql_adapter_state at %p", addr);
1813                 mdb_free(ha, sizeof (ql_adapter_state_t));
1814                 return (DCMD_OK);
1815         }
1816 
1817         /*
1818          * If its not a valid dump or there's not a f/w dump binary (???)
1819          * then bail out
1820          */
1821         if (((ha->ql_dump_state & QL_DUMP_VALID) == 0) ||
1822             (ha->ql_dump_ptr == NULL)) {
1823                 mdb_warn("dump does not exist for instance %d (%x, %p)\n",
1824                     ha->instance, ha->ql_dump_state, ha->ql_dump_ptr);
1825                 mdb_free(ha, sizeof (ql_adapter_state_t));
1826                 return (DCMD_OK);
1827         }
1828 
1829         if (CFG_IST(ha, CFG_CTRL_24XX)) {
1830                 (void) ql_24xx_dump_dcmd(ha, flags, argc, argv);
1831         } else if (CFG_IST(ha, CFG_CTRL_25XX)) {
1832                 (void) ql_25xx_dump_dcmd(ha, flags, argc, argv);
1833         } else if (CFG_IST(ha, CFG_CTRL_81XX)) {
1834                 (void) ql_81xx_dump_dcmd(ha, flags, argc, argv);
1835         } else if (CFG_IST(ha, CFG_CTRL_82XX | CFG_CTRL_27XX)) {
1836                 (void) ql_8021_dump_dcmd(ha, flags, argc, argv);
1837         } else if (CFG_IST(ha, CFG_CTRL_83XX)) {
1838                 (void) ql_8300_dump_dcmd(ha, flags, argc, argv);
1839         } else {
1840                 (void) ql_23xx_dump_dcmd(ha, flags, argc, argv);
1841         }
1842 
1843         mdb_free(ha, sizeof (ql_adapter_state_t));
1844 
1845         return (DCMD_OK);
1846 }
1847 
1848 /*
1849  * ql_8021_dump_dcmd
1850  *      prints out a firmware dump buffer
1851  *
1852  * Input:
1853  *      addr  = User supplied address. (NB: nust be an ha)
1854  *      flags = mdb flags.
1855  *      argc  = Number of user supplied args.
1856  *      argv  = Arg array.
1857  *
1858  * Returns:
1859  *      DCMD_OK or DCMD_ERR
1860  *
1861  * Context:
1862  *      User context.
1863  *
1864  */
1865 /*ARGSUSED*/
1866 static int
1867 ql_8021_dump_dcmd(ql_adapter_state_t *ha, uint_t flags, int argc,
1868     const mdb_arg_t *argv)
1869 {
1870         uint8_t         *fw, *bp;
1871         uint32_t        cnt = 0;
1872 
1873         bp = fw = (uint8_t *)mdb_alloc(ha->ql_dump_size, UM_SLEEP);
1874 
1875         if (mdb_vread(fw, ha->ql_dump_size,
1876             (uintptr_t)ha->ql_dump_ptr) == -1) {
1877                 mdb_warn("failed to read ql_dump_ptr (no f/w dump active?)");
1878                 mdb_free(fw, ha->ql_dump_size);
1879                 return (DCMD_OK);
1880         }
1881 
1882         while (cnt < ha->ql_dump_size) {
1883                 mdb_printf("%02x ", *bp++);
1884                 if (++cnt % 16 == 0) {
1885                         mdb_printf("\n");
1886                 }
1887         }
1888         if (cnt % 16 != 0) {
1889                 mdb_printf("\n");
1890         }
1891 
1892         mdb_free(fw, ha->ql_dump_size);
1893 
1894         return (DCMD_OK);
1895 }
1896 
1897 /*
1898  * ql_83xx_dump_dcmd
1899  *      prints out a firmware dump buffer
1900  *
1901  * Input:
1902  *      addr  = User supplied address. (NB: must be an ha)
1903  *      flags = mdb flags.
1904  *      argc  = Number of user supplied args.
1905  *      argv  = Arg array.
1906  *
1907  * Returns:
1908  *      DCMD_OK or DCMD_ERR
1909  *
1910  * Context:
1911  *      User context.
1912  *
1913  */
1914 /*ARGSUSED*/
1915 static int
1916 ql_8300_dump_dcmd(ql_adapter_state_t *ha, uint_t flags, int argc,
1917     const mdb_arg_t *argv)
1918 {
1919         ql_83xx_fw_dump_t       *fw;
1920         ql_response_q_t         **rsp_queues, *rsp_q;
1921         uint32_t                cnt, cnt1, *dp, *dp2;
1922 
1923         fw = mdb_alloc(ha->ql_dump_size, UM_SLEEP);
1924         rsp_queues = mdb_alloc(ha->rsp_queues_cnt *
1925             sizeof (ql_response_q_t *), UM_SLEEP);
1926         rsp_q = mdb_alloc(sizeof (ql_response_q_t), UM_SLEEP);
1927 
1928         if (mdb_vread(fw, ha->ql_dump_size,
1929             (uintptr_t)ha->ql_dump_ptr) == -1 ||
1930             mdb_vread(rsp_queues, ha->rsp_queues_cnt *
1931             sizeof (ql_response_q_t *), (uintptr_t)ha->rsp_queues) == -1) {
1932                 mdb_warn("failed to read fw_dump_buffer (no f/w dump active?)");
1933                 mdb_free(rsp_q, sizeof (ql_response_q_t));
1934                 mdb_free(rsp_queues, ha->rsp_queues_cnt *
1935                     sizeof (ql_response_q_t *));
1936                 mdb_free(fw, ha->ql_dump_size);
1937                 return (DCMD_OK);
1938         }
1939 
1940         mdb_printf("\nISP FW Version %d.%02d.%02d Attributes %X\n",
1941             ha->fw_major_version, ha->fw_minor_version,
1942             ha->fw_subminor_version, ha->fw_attributes);
1943 
1944         mdb_printf("\nHCCR Register\n%08x\n", fw->hccr);
1945 
1946         mdb_printf("\nR2H Status Register\n%08x\n", fw->r2h_status);
1947 
1948         mdb_printf("\nAER Uncorrectable Error Status Register\n%08x\n",
1949             fw->aer_ues);
1950 
1951         mdb_printf("\nHostRisc Registers");
1952         for (cnt = 0; cnt < sizeof (fw->hostrisc_reg) / 4; cnt++) {
1953                 if (cnt % 8 == 0) {
1954                         mdb_printf("\n");
1955                 }
1956                 mdb_printf("%08x ", fw->hostrisc_reg[cnt]);
1957         }
1958 
1959         mdb_printf("\n\nPCIe Registers");
1960         for (cnt = 0; cnt < sizeof (fw->pcie_reg) / 4; cnt++) {
1961                 if (cnt % 8 == 0) {
1962                         mdb_printf("\n");
1963                 }
1964                 mdb_printf("%08x ", fw->pcie_reg[cnt]);
1965         }
1966 
1967         dp = fw->req_rsp_ext_mem;
1968         for (cnt = 0; cnt < ha->rsp_queues_cnt; cnt++) {
1969                 mdb_printf("\n\nQueue Pointers #%d:\n", cnt);
1970                 for (cnt1 = 0; cnt1 < 4; cnt1++) {
1971                         mdb_printf("%08x ", *dp++);
1972                 }
1973         }
1974 
1975         mdb_printf("\n\nHost Interface Registers");
1976         for (cnt = 0; cnt < sizeof (fw->host_reg) / 4; cnt++) {
1977                 if (cnt % 8 == 0) {
1978                         mdb_printf("\n");
1979                 }
1980                 mdb_printf("%08x ", fw->host_reg[cnt]);
1981         }
1982 
1983         mdb_printf("\n\nShadow Registers");
1984         for (cnt = 0; cnt < sizeof (fw->shadow_reg) / 4; cnt++) {
1985                 if (cnt % 8 == 0) {
1986                         mdb_printf("\n");
1987                 }
1988                 mdb_printf("%08x ", fw->shadow_reg[cnt]);
1989         }
1990 
1991         mdb_printf("\n\nRISC IO Register\n%08x", fw->risc_io);
1992 
1993         mdb_printf("\n\nMailbox Registers");
1994         for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) {
1995                 if (cnt % 16 == 0) {
1996                         mdb_printf("\n");
1997                 }
1998                 mdb_printf("%04x ", fw->mailbox_reg[cnt]);
1999         }
2000 
2001         mdb_printf("\n\nXSEQ GP Registers");
2002         for (cnt = 0; cnt < sizeof (fw->xseq_gp_reg) / 4; cnt++) {
2003                 if (cnt % 8 == 0) {
2004                         mdb_printf("\n");
2005                 }
2006                 mdb_printf("%08x ", fw->xseq_gp_reg[cnt]);
2007         }
2008 
2009         mdb_printf("\n\nXSEQ-0 Registers");
2010         for (cnt = 0; cnt < sizeof (fw->xseq_0_reg) / 4; cnt++) {
2011                 if (cnt % 8 == 0) {
2012                         mdb_printf("\n");
2013                 }
2014                 mdb_printf("%08x ", fw->xseq_0_reg[cnt]);
2015         }
2016 
2017         mdb_printf("\n\nXSEQ-1 Registers");
2018         for (cnt = 0; cnt < sizeof (fw->xseq_1_reg) / 4; cnt++) {
2019                 if (cnt % 8 == 0) {
2020                         mdb_printf("\n");
2021                 }
2022                 mdb_printf("%08x ", fw->xseq_1_reg[cnt]);
2023         }
2024 
2025         mdb_printf("\n\nXSEQ-2 Registers");
2026         for (cnt = 0; cnt < sizeof (fw->xseq_2_reg) / 4; cnt++) {
2027                 if (cnt % 8 == 0) {
2028                         mdb_printf("\n");
2029                 }
2030                 mdb_printf("%08x ", fw->xseq_2_reg[cnt]);
2031         }
2032 
2033         mdb_printf("\n\nRSEQ GP Registers");
2034         for (cnt = 0; cnt < sizeof (fw->rseq_gp_reg) / 4; cnt++) {
2035                 if (cnt % 8 == 0) {
2036                         mdb_printf("\n");
2037                 }
2038                 mdb_printf("%08x ", fw->rseq_gp_reg[cnt]);
2039         }
2040 
2041         mdb_printf("\n\nRSEQ-0 Registers");
2042         for (cnt = 0; cnt < sizeof (fw->rseq_0_reg) / 4; cnt++) {
2043                 if (cnt % 8 == 0) {
2044                         mdb_printf("\n");
2045                 }
2046                 mdb_printf("%08x ", fw->rseq_0_reg[cnt]);
2047         }
2048 
2049         mdb_printf("\n\nRSEQ-1 Registers");
2050         for (cnt = 0; cnt < sizeof (fw->rseq_1_reg) / 4; cnt++) {
2051                 if (cnt % 8 == 0) {
2052                         mdb_printf("\n");
2053                 }
2054                 mdb_printf("%08x ", fw->rseq_1_reg[cnt]);
2055         }
2056 
2057         mdb_printf("\n\nRSEQ-2 Registers");
2058         for (cnt = 0; cnt < sizeof (fw->rseq_2_reg) / 4; cnt++) {
2059                 if (cnt % 8 == 0) {
2060                         mdb_printf("\n");
2061                 }
2062                 mdb_printf("%08x ", fw->rseq_2_reg[cnt]);
2063         }
2064 
2065         mdb_printf("\n\nRSEQ-3 Registers");
2066         for (cnt = 0; cnt < sizeof (fw->rseq_3_reg) / 4; cnt++) {
2067                 if (cnt % 8 == 0) {
2068                         mdb_printf("\n");
2069                 }
2070                 mdb_printf("%08x ", fw->rseq_3_reg[cnt]);
2071         }
2072 
2073         mdb_printf("\n\nASEQ GP Registers");
2074         for (cnt = 0; cnt < sizeof (fw->aseq_gp_reg) / 4; cnt++) {
2075                 if (cnt % 8 == 0) {
2076                         mdb_printf("\n");
2077                 }
2078                 mdb_printf("%08x ", fw->aseq_gp_reg[cnt]);
2079         }
2080 
2081         mdb_printf("\n\nASEQ-0 Registers");
2082         for (cnt = 0; cnt < sizeof (fw->aseq_0_reg) / 4; cnt++) {
2083                 if (cnt % 8 == 0) {
2084                         mdb_printf("\n");
2085                 }
2086                 mdb_printf("%08x ", fw->aseq_0_reg[cnt]);
2087         }
2088 
2089         mdb_printf("\n\nASEQ-1 Registers");
2090         for (cnt = 0; cnt < sizeof (fw->aseq_1_reg) / 4; cnt++) {
2091                 if (cnt % 8 == 0) {
2092                         mdb_printf("\n");
2093                 }
2094                 mdb_printf("%08x ", fw->aseq_1_reg[cnt]);
2095         }
2096 
2097         mdb_printf("\n\nASEQ-2 Registers");
2098         for (cnt = 0; cnt < sizeof (fw->aseq_2_reg) / 4; cnt++) {
2099                 if (cnt % 8 == 0) {
2100                         mdb_printf("\n");
2101                 }
2102                 mdb_printf("%08x ", fw->aseq_2_reg[cnt]);
2103         }
2104 
2105         mdb_printf("\n\nASEQ-3 Registers");
2106         for (cnt = 0; cnt < sizeof (fw->aseq_3_reg) / 4; cnt++) {
2107                 if (cnt % 8 == 0) {
2108                         mdb_printf("\n");
2109                 }
2110                 mdb_printf("%08x ", fw->aseq_3_reg[cnt]);
2111         }
2112 
2113         mdb_printf("\n\nCommand DMA Registers");
2114         for (cnt = 0; cnt < sizeof (fw->cmd_dma_reg) / 4; cnt++) {
2115                 if (cnt % 8 == 0) {
2116                         mdb_printf("\n");
2117                 }
2118                 mdb_printf("%08x ", fw->cmd_dma_reg[cnt]);
2119         }
2120 
2121         mdb_printf("\n\nRequest0 Queue DMA Channel Registers");
2122         for (cnt = 0; cnt < sizeof (fw->req0_dma_reg) / 4; cnt++) {
2123                 if (cnt % 8 == 0) {
2124                         mdb_printf("\n");
2125                 }
2126                 mdb_printf("%08x ", fw->req0_dma_reg[cnt]);
2127         }
2128 
2129         mdb_printf("\n\nResponse0 Queue DMA Channel Registers");
2130         for (cnt = 0; cnt < sizeof (fw->resp0_dma_reg) / 4; cnt++) {
2131                 if (cnt % 8 == 0) {
2132                         mdb_printf("\n");
2133                 }
2134                 mdb_printf("%08x ", fw->resp0_dma_reg[cnt]);
2135         }
2136 
2137         mdb_printf("\n\nRequest1 Queue DMA Channel Registers");
2138         for (cnt = 0; cnt < sizeof (fw->req1_dma_reg) / 4; cnt++) {
2139                 if (cnt % 8 == 0) {
2140                         mdb_printf("\n");
2141                 }
2142                 mdb_printf("%08x ", fw->req1_dma_reg[cnt]);
2143         }
2144 
2145         mdb_printf("\n\nXMT0 Data DMA Registers");
2146         for (cnt = 0; cnt < sizeof (fw->xmt0_dma_reg) / 4; cnt++) {
2147                 if (cnt % 8 == 0) {
2148                         mdb_printf("\n");
2149                 }
2150                 mdb_printf("%08x ", fw->xmt0_dma_reg[cnt]);
2151         }
2152 
2153         mdb_printf("\n\nXMT1 Data DMA Registers");
2154         for (cnt = 0; cnt < sizeof (fw->xmt1_dma_reg) / 4; cnt++) {
2155                 if (cnt % 8 == 0) {
2156                         mdb_printf("\n");
2157                 }
2158                 mdb_printf("%08x ", fw->xmt1_dma_reg[cnt]);
2159         }
2160 
2161         mdb_printf("\n\nXMT2 Data DMA Registers");
2162         for (cnt = 0; cnt < sizeof (fw->xmt2_dma_reg) / 4; cnt++) {
2163                 if (cnt % 8 == 0) {
2164                         mdb_printf("\n");
2165                 }
2166                 mdb_printf("%08x ", fw->xmt2_dma_reg[cnt]);
2167         }
2168 
2169         mdb_printf("\n\nXMT3 Data DMA Registers");
2170         for (cnt = 0; cnt < sizeof (fw->xmt3_dma_reg) / 4; cnt++) {
2171                 if (cnt % 8 == 0) {
2172                         mdb_printf("\n");
2173                 }
2174                 mdb_printf("%08x ", fw->xmt3_dma_reg[cnt]);
2175         }
2176 
2177         mdb_printf("\n\nXMT4 Data DMA Registers");
2178         for (cnt = 0; cnt < sizeof (fw->xmt4_dma_reg) / 4; cnt++) {
2179                 if (cnt % 8 == 0) {
2180                         mdb_printf("\n");
2181                 }
2182                 mdb_printf("%08x ", fw->xmt4_dma_reg[cnt]);
2183         }
2184 
2185         mdb_printf("\n\nXMT Data DMA Common Registers");
2186         for (cnt = 0; cnt < sizeof (fw->xmt_data_dma_reg) / 4; cnt++) {
2187                 if (cnt % 8 == 0) {
2188                         mdb_printf("\n");
2189                 }
2190                 mdb_printf("%08x ", fw->xmt_data_dma_reg[cnt]);
2191         }
2192 
2193         mdb_printf("\n\nRCV Thread 0 Data DMA Registers");
2194         for (cnt = 0; cnt < sizeof (fw->rcvt0_data_dma_reg) / 4; cnt++) {
2195                 if (cnt % 8 == 0) {
2196                         mdb_printf("\n");
2197                 }
2198                 mdb_printf("%08x ", fw->rcvt0_data_dma_reg[cnt]);
2199         }
2200 
2201         mdb_printf("\n\nRCV Thread 1 Data DMA Registers");
2202         for (cnt = 0; cnt < sizeof (fw->rcvt1_data_dma_reg) / 4; cnt++) {
2203                 if (cnt % 8 == 0) {
2204                         mdb_printf("\n");
2205                 }
2206                 mdb_printf("%08x ", fw->rcvt1_data_dma_reg[cnt]);
2207         }
2208 
2209         mdb_printf("\n\nRISC GP Registers");
2210         for (cnt = 0; cnt < sizeof (fw->risc_gp_reg) / 4; cnt++) {
2211                 if (cnt % 8 == 0) {
2212                         mdb_printf("\n");
2213                 }
2214                 mdb_printf("%08x ", fw->risc_gp_reg[cnt]);
2215         }
2216 
2217         mdb_printf("\n\nLMC Registers");
2218         for (cnt = 0; cnt < sizeof (fw->lmc_reg) / 4; cnt++) {
2219                 if (cnt % 8 == 0) {
2220                         mdb_printf("\n");
2221                 }
2222                 mdb_printf("%08x ", fw->lmc_reg[cnt]);
2223         }
2224 
2225         mdb_printf("\n\nFPM Hardware Registers");
2226         for (cnt = 0; cnt < sizeof (fw->fpm_hdw_reg) / 4; cnt++) {
2227                 if (cnt % 8 == 0) {
2228                         mdb_printf("\n");
2229                 }
2230                 mdb_printf("%08x ", fw->fpm_hdw_reg[cnt]);
2231         }
2232 
2233         mdb_printf("\n\nRQ0 Array Registers");
2234         for (cnt = 0; cnt < sizeof (fw->rq0_array_reg) / 4; cnt++) {
2235                 if (cnt % 8 == 0) {
2236                         mdb_printf("\n");
2237                 }
2238                 mdb_printf("%08x ", fw->rq0_array_reg[cnt]);
2239         }
2240 
2241         mdb_printf("\n\nRQ1 Array Registers");
2242         for (cnt = 0; cnt < sizeof (fw->rq1_array_reg) / 4; cnt++) {
2243                 if (cnt % 8 == 0) {
2244                         mdb_printf("\n");
2245                 }
2246                 mdb_printf("%08x ", fw->rq1_array_reg[cnt]);
2247         }
2248 
2249         mdb_printf("\n\nRP0 Array Registers");
2250         for (cnt = 0; cnt < sizeof (fw->rp0_array_reg) / 4; cnt++) {
2251                 if (cnt % 8 == 0) {
2252                         mdb_printf("\n");
2253                 }
2254                 mdb_printf("%08x ", fw->rp0_array_reg[cnt]);
2255         }
2256 
2257         mdb_printf("\n\nRP1 Array Registers");
2258         for (cnt = 0; cnt < sizeof (fw->rp1_array_reg) / 4; cnt++) {
2259                 if (cnt % 8 == 0) {
2260                         mdb_printf("\n");
2261                 }
2262                 mdb_printf("%08x ", fw->rp1_array_reg[cnt]);
2263         }
2264 
2265         mdb_printf("\n\nAT0 Array Registers");
2266         for (cnt = 0; cnt < sizeof (fw->ato_array_reg) / 4; cnt++) {
2267                 if (cnt % 8 == 0) {
2268                         mdb_printf("\n");
2269                 }
2270                 mdb_printf("%08x ", fw->ato_array_reg[cnt]);
2271         }
2272 
2273         mdb_printf("\n\nQueue Control Registers");
2274         for (cnt = 0; cnt < sizeof (fw->queue_control_reg) / 4; cnt++) {
2275                 if (cnt % 8 == 0) {
2276                         mdb_printf("\n");
2277                 }
2278                 mdb_printf("%08x ", fw->queue_control_reg[cnt]);
2279         }
2280 
2281         mdb_printf("\n\nFB Hardware Registers");
2282         for (cnt = 0; cnt < sizeof (fw->fb_hdw_reg) / 4; cnt++) {
2283                 if (cnt % 8 == 0) {
2284                         mdb_printf("\n");
2285                 }
2286                 mdb_printf("%08x ", fw->fb_hdw_reg[cnt]);
2287         }
2288 
2289         mdb_printf("\n\nCode RAM");
2290         for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) {
2291                 if (cnt % 8 == 0) {
2292                         mdb_printf("\n%08x: ", cnt + 0x20000);
2293                 }
2294                 mdb_printf("%08x ", fw->code_ram[cnt]);
2295         }
2296 
2297         mdb_printf("\n\nExternal Memory");
2298         dp = (uint32_t *)(void *)((caddr_t)fw->req_rsp_ext_mem +
2299             fw->req_q_size[0] + fw->req_q_size[1] + fw->rsp_q_size +
2300             (ha->rsp_queues_cnt * 16));
2301         for (cnt = 0; cnt < ha->fw_ext_memory_size / 4; cnt++) {
2302                 if (cnt % 8 == 0) {
2303                         mdb_printf("\n%08x: ", cnt + 0x100000);
2304                 }
2305                 mdb_printf("%08x ", *dp++);
2306         }
2307 
2308         mdb_printf("\n\n[<==END] ISP Debug Dump");
2309 
2310         dp = fw->req_rsp_ext_mem + (ha->rsp_queues_cnt * 4);
2311         for (cnt = 0; cnt < 2 && fw->req_q_size[cnt]; cnt++) {
2312                 dp2 = dp;
2313                 for (cnt1 = 0; cnt1 < fw->req_q_size[cnt] / 4; cnt1++) {
2314                         if (*dp2++) {
2315                                 break;
2316                         }
2317                 }
2318                 if (cnt1 == fw->req_q_size[cnt] / 4) {
2319                         dp = dp2;
2320                         continue;
2321                 }
2322                 mdb_printf("\n\nRequest Queue\nQueue 0%d:", cnt);
2323                 for (cnt1 = 0; cnt1 < fw->req_q_size[cnt] / 4; cnt1++) {
2324                         if (cnt1 % 8 == 0) {
2325                                 mdb_printf("\n%08x: ", cnt1);
2326                         }
2327                         mdb_printf("%08x ", *dp++);
2328                 }
2329         }
2330 
2331         for (cnt = 0; cnt < ha->rsp_queues_cnt; cnt++) {
2332                 if (mdb_vread(rsp_q, sizeof (ql_response_q_t),
2333                     (uintptr_t)rsp_queues[cnt]) == -1) {
2334                         mdb_warn("failed to read ha->rsp_queues[%d]", cnt);
2335                         break;
2336                 }
2337                 dp2 = dp;
2338                 for (cnt1 = 0; cnt1 < rsp_q->rsp_ring.size / 4; cnt1++) {
2339                         if (*dp2++) {
2340                                 break;
2341                         }
2342                 }
2343                 if (cnt1 == rsp_q->rsp_ring.size / 4) {
2344                         dp = dp2;
2345                         continue;
2346                 }
2347                 mdb_printf("\n\nResponse Queue\nQueue 0%d:", cnt);
2348 
2349                 for (cnt1 = 0; cnt1 < rsp_q->rsp_ring.size / 4; cnt1++) {
2350                         if (cnt1 % 8 == 0) {
2351                                 mdb_printf("\n%08x: ", cnt1);
2352                         }
2353                         mdb_printf("%08x ", *dp++);
2354                 }
2355         }
2356 
2357         if (ha->fwexttracebuf.dma_handle != NULL) {
2358                 uint32_t        cnt_b;
2359                 uint32_t        *w32 = ha->fwexttracebuf.bp;
2360 
2361                 mdb_printf("\n\nExtended Trace Buffer Memory");
2362                 /* show data address as a byte address, data as long words */
2363                 for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
2364                         cnt_b = cnt * 4;
2365                         if (cnt_b % 32 == 0) {
2366                                 mdb_printf("\n%08x: ", w32 + cnt_b);
2367                         }
2368                         mdb_printf("%08x ", fw->ext_trace_buf[cnt]);
2369                 }
2370         }
2371 
2372         if (ha->fwfcetracebuf.dma_handle != NULL) {
2373                 uint32_t        cnt_b;
2374                 uint32_t        *w32 = ha->fwfcetracebuf.bp;
2375 
2376                 mdb_printf("\n\nFC Event Trace Buffer Memory");
2377                 /* show data address as a byte address, data as long words */
2378                 for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
2379                         cnt_b = cnt * 4;
2380                         if (cnt_b % 32 == 0) {
2381                                 mdb_printf("\n%08x: ", w32 + cnt_b);
2382                         }
2383                         mdb_printf("%08x ", fw->fce_trace_buf[cnt]);
2384                 }
2385         }
2386 
2387         mdb_free(rsp_q, sizeof (ql_response_q_t));
2388         mdb_free(rsp_queues, ha->rsp_queues_cnt * sizeof (ql_response_q_t *));
2389         mdb_free(fw, ha->ql_dump_size);
2390 
2391         mdb_printf("\n\nreturn exit\n");
2392 
2393         return (DCMD_OK);
2394 }
2395 
2396 /*
2397  * ql_23xx_dump_dcmd
2398  *      prints out a firmware dump buffer
2399  *
2400  * Input:
2401  *      addr  = User supplied address. (NB: nust be an ha)
2402  *      flags = mdb flags.
2403  *      argc  = Number of user supplied args.
2404  *      argv  = Arg array.
2405  *
2406  * Returns:
2407  *      DCMD_OK or DCMD_ERR
2408  *
2409  * Context:
2410  *      User context.
2411  *
2412  */
2413 /*ARGSUSED*/
2414 static int
2415 ql_23xx_dump_dcmd(ql_adapter_state_t *ha, uint_t flags, int argc,
2416     const mdb_arg_t *argv)
2417 {
2418         ql_fw_dump_t    *fw;
2419         uint32_t        cnt = 0;
2420         int             mbox_cnt;
2421 
2422         fw = (ql_fw_dump_t *)mdb_alloc(ha->ql_dump_size, UM_SLEEP);
2423 
2424         if (mdb_vread(fw, ha->ql_dump_size,
2425             (uintptr_t)ha->ql_dump_ptr) == -1) {
2426                 mdb_warn("failed to read ql_dump_ptr (no f/w dump active?)");
2427                 mdb_free(fw, ha->ql_dump_size);
2428                 return (DCMD_OK);
2429         }
2430 
2431         if (ha->cfg_flags & CFG_CTRL_23XX) {
2432                 mdb_printf("\nISP 2300IP ");
2433         } else if (ha->cfg_flags & CFG_CTRL_63XX) {
2434                 mdb_printf("\nISP 2322/6322FLX ");
2435         } else {
2436                 mdb_printf("\nISP 2200IP ");
2437         }
2438 
2439         mdb_printf("Firmware Version %d.%d.%d\n",
2440             ha->fw_major_version, ha->fw_minor_version,
2441             ha->fw_subminor_version);
2442 
2443         mdb_printf("\nPBIU Registers:");
2444         for (cnt = 0; cnt < sizeof (fw->pbiu_reg) / 2; cnt++) {
2445                 if (cnt % 8 == 0) {
2446                         mdb_printf("\n");
2447                 }
2448                 mdb_printf("%04x  ", fw->pbiu_reg[cnt]);
2449         }
2450 
2451         if (ha->cfg_flags & CFG_CTRL_2363) {
2452                 mdb_printf("\n\nReqQ-RspQ-Risc2Host Status registers:");
2453                 for (cnt = 0; cnt < sizeof (fw->risc_host_reg) / 2; cnt++) {
2454                         if (cnt % 8 == 0) {
2455                                 mdb_printf("\n");
2456                         }
2457                         mdb_printf("%04x  ", fw->risc_host_reg[cnt]);
2458                 }
2459         }
2460 
2461         mdb_printf("\n\nMailbox Registers:");
2462         mbox_cnt = ha->cfg_flags & CFG_CTRL_2363 ? 16 : 8;
2463         for (cnt = 0; cnt < mbox_cnt; cnt++) {
2464                 if (cnt % 8 == 0) {
2465                         mdb_printf("\n");
2466                 }
2467                 mdb_printf("%04x  ", fw->mailbox_reg[cnt]);
2468         }
2469 
2470         if (ha->cfg_flags & CFG_CTRL_2363) {
2471                 mdb_printf("\n\nAuto Request Response DMA Registers:");
2472                 for (cnt = 0; cnt < sizeof (fw->resp_dma_reg) / 2; cnt++) {
2473                         if (cnt % 8 == 0) {
2474                                 mdb_printf("\n");
2475                         }
2476                         mdb_printf("%04x  ", fw->resp_dma_reg[cnt]);
2477                 }
2478         }
2479 
2480         mdb_printf("\n\nDMA Registers:");
2481         for (cnt = 0; cnt < sizeof (fw->dma_reg) / 2; cnt++) {
2482                 if (cnt % 8 == 0) {
2483                         mdb_printf("\n");
2484                 }
2485                 mdb_printf("%04x  ", fw->dma_reg[cnt]);
2486         }
2487 
2488         mdb_printf("\n\nRISC Hardware Registers:");
2489         for (cnt = 0; cnt < sizeof (fw->risc_hdw_reg) / 2; cnt++) {
2490                 if (cnt % 8 == 0) {
2491                         mdb_printf("\n");
2492                 }
2493                 mdb_printf("%04x  ", fw->risc_hdw_reg[cnt]);
2494         }
2495 
2496         mdb_printf("\n\nRISC GP0 Registers:");
2497         for (cnt = 0; cnt < sizeof (fw->risc_gp0_reg) / 2; cnt++) {
2498                 if (cnt % 8 == 0) {
2499                         mdb_printf("\n");
2500                 }
2501                 mdb_printf("%04x  ", fw->risc_gp0_reg[cnt]);
2502         }
2503 
2504         mdb_printf("\n\nRISC GP1 Registers:");
2505         for (cnt = 0; cnt < sizeof (fw->risc_gp1_reg) / 2; cnt++) {
2506                 if (cnt % 8 == 0) {
2507                         mdb_printf("\n");
2508                 }
2509                 mdb_printf("%04x  ", fw->risc_gp1_reg[cnt]);
2510         }
2511 
2512         mdb_printf("\n\nRISC GP2 Registers:");
2513         for (cnt = 0; cnt < sizeof (fw->risc_gp2_reg) / 2; cnt++) {
2514                 if (cnt % 8 == 0) {
2515                         mdb_printf("\n");
2516                 }
2517                 mdb_printf("%04x  ", fw->risc_gp2_reg[cnt]);
2518         }
2519 
2520         mdb_printf("\n\nRISC GP3 Registers:");
2521         for (cnt = 0; cnt < sizeof (fw->risc_gp3_reg) / 2; cnt++) {
2522                 if (cnt % 8 == 0) {
2523                         mdb_printf("\n");
2524                 }
2525                 mdb_printf("%04x  ", fw->risc_gp3_reg[cnt]);
2526         }
2527 
2528         mdb_printf("\n\nRISC GP4 Registers:");
2529         for (cnt = 0; cnt < sizeof (fw->risc_gp4_reg) / 2; cnt++) {
2530                 if (cnt % 8 == 0) {
2531                         mdb_printf("\n");
2532                 }
2533                 mdb_printf("%04x  ", fw->risc_gp4_reg[cnt]);
2534         }
2535 
2536         mdb_printf("\n\nRISC GP5 Registers:");
2537         for (cnt = 0; cnt < sizeof (fw->risc_gp5_reg) / 2; cnt++) {
2538                 if (cnt % 8 == 0) {
2539                         mdb_printf("\n");
2540                 }
2541                 mdb_printf("%04x  ", fw->risc_gp5_reg[cnt]);
2542         }
2543 
2544         mdb_printf("\n\nRISC GP6 Registers:");
2545         for (cnt = 0; cnt < sizeof (fw->risc_gp6_reg) / 2; cnt++) {
2546                 if (cnt % 8 == 0) {
2547                         mdb_printf("\n");
2548                 }
2549                 mdb_printf("%04x  ", fw->risc_gp6_reg[cnt]);
2550         }
2551 
2552         mdb_printf("\n\nRISC GP7 Registers:");
2553         for (cnt = 0; cnt < sizeof (fw->risc_gp7_reg) / 2; cnt++) {
2554                 if (cnt % 8 == 0) {
2555                         mdb_printf("\n");
2556                 }
2557                 mdb_printf("%04x  ", fw->risc_gp7_reg[cnt]);
2558         }
2559 
2560         mdb_printf("\n\nFrame Buffer Hardware Registers:");
2561         for (cnt = 0; cnt < sizeof (fw->frame_buf_hdw_reg) / 2; cnt++) {
2562                 if ((cnt == 16) &&
2563                     ((ha->cfg_flags & CFG_CTRL_2363) == 0)) {
2564                         break;
2565                 }
2566                 if (cnt % 8 == 0) {
2567                         mdb_printf("\n");
2568                 }
2569                 mdb_printf("%04x  ", fw->frame_buf_hdw_reg[cnt]);
2570         }
2571 
2572         mdb_printf("\n\nFPM B0 Registers:");
2573         for (cnt = 0; cnt < sizeof (fw->fpm_b0_reg) / 2; cnt++) {
2574                 if (cnt % 8 == 0) {
2575                         mdb_printf("\n");
2576                 }
2577                 mdb_printf("%04x  ", fw->fpm_b0_reg[cnt]);
2578         }
2579 
2580         mdb_printf("\n\nFPM B1 Registers:");
2581         for (cnt = 0; cnt < sizeof (fw->fpm_b1_reg) / 2; cnt++) {
2582                 if (cnt % 8 == 0) {
2583                         mdb_printf("\n");
2584                 }
2585                 mdb_printf("%04x  ", fw->fpm_b1_reg[cnt]);
2586         }
2587 
2588         if (ha->cfg_flags & CFG_CTRL_2363) {
2589                 mdb_printf("\n\nCode RAM Dump:");
2590                 for (cnt = 0; cnt < sizeof (fw->risc_ram) / 2; cnt++) {
2591                         if (cnt % 8 == 0) {
2592                                 mdb_printf("\n%05x: ", cnt + 0x0800);
2593                         }
2594                         mdb_printf("%04x  ", fw->risc_ram[cnt]);
2595                 }
2596 
2597                 mdb_printf("\n\nStack RAM Dump:");
2598                 for (cnt = 0; cnt < sizeof (fw->stack_ram) / 2; cnt++) {
2599                         if (cnt % 8 == 0) {
2600                                 mdb_printf("\n%05x: ", cnt + 0x010000);
2601                         }
2602                         mdb_printf("%04x  ", fw->stack_ram[cnt]);
2603                 }
2604 
2605                 mdb_printf("\n\nData RAM Dump:");
2606                 for (cnt = 0; cnt < sizeof (fw->data_ram) / 2; cnt++) {
2607                         if (cnt % 8 == 0) {
2608                                 mdb_printf("\n%05x: ", cnt + 0x010800);
2609                         }
2610                         mdb_printf("%04x  ", fw->data_ram[cnt]);
2611                 }
2612 
2613                 mdb_printf("\n\n[<==END] ISP Debug Dump.\n");
2614 
2615                 mdb_printf("\n\nRequest Queue");
2616 
2617                 for (cnt = 0; cnt < REQUEST_QUEUE_SIZE / 4; cnt++) {
2618                         if (cnt % 8 == 0) {
2619                                 mdb_printf("\n%08x: ", cnt);
2620                         }
2621                         mdb_printf("%08x ", fw->req_q[cnt]);
2622                 }
2623 
2624                 mdb_printf("\n\nResponse Queue");
2625 
2626                 for (cnt = 0; cnt < RESPONSE_QUEUE_SIZE / 4; cnt++) {
2627                         if (cnt % 8 == 0) {
2628                                 mdb_printf("\n%08x: ", cnt);
2629                         }
2630                         mdb_printf("%08x ", fw->rsp_q[cnt]);
2631                 }
2632 
2633                 mdb_printf("\n");
2634 
2635         } else {
2636                 mdb_printf("\n\nRISC SRAM:");
2637                 for (cnt = 0; cnt < 0xf000; cnt++) {
2638                         if (cnt % 8 == 0) {
2639                                 mdb_printf("\n%04x: ", cnt + 0x1000);
2640                         }
2641                         mdb_printf("%04x  ", fw->risc_ram[cnt]);
2642                 }
2643         }
2644 
2645         mdb_free(fw, ha->ql_dump_size);
2646 
2647         return (DCMD_OK);
2648 }
2649 
2650 /*
2651  * ql_24xx_dump_dcmd
2652  *      prints out a firmware dump buffer
2653  *
2654  * Input:
2655  *      addr  = User supplied address. (NB: nust be an ha)
2656  *      flags = mdb flags.
2657  *      argc  = Number of user supplied args.
2658  *      argv  = Arg array.
2659  *
2660  * Returns:
2661  *      DCMD_OK or DCMD_ERR
2662  *
2663  * Context:
2664  *      User context.
2665  *
2666  */
2667 /*ARGSUSED*/
2668 static int
2669 ql_24xx_dump_dcmd(ql_adapter_state_t *ha, uint_t flags, int argc,
2670     const mdb_arg_t *argv)
2671 {
2672         ql_24xx_fw_dump_t       *fw;
2673         uint32_t                cnt = 0;
2674 
2675         fw = (ql_24xx_fw_dump_t *)mdb_alloc(ha->ql_dump_size, UM_SLEEP);
2676 
2677         if (mdb_vread(fw, ha->ql_dump_size,
2678             (uintptr_t)ha->ql_dump_ptr) == -1) {
2679                 mdb_warn("failed to read ql_dump_ptr (no f/w dump active?)");
2680                 mdb_free(fw, ha->ql_dump_size);
2681                 return (DCMD_OK);
2682         }
2683 
2684         mdb_printf("ISP FW Version %d.%02d.%02d Attributes %X\n",
2685             ha->fw_major_version, ha->fw_minor_version,
2686             ha->fw_subminor_version, ha->fw_attributes);
2687 
2688         mdb_printf("\nHCCR Register\n%08x\n", fw->hccr);
2689 
2690         mdb_printf("\nHost Interface Registers");
2691         for (cnt = 0; cnt < sizeof (fw->host_reg) / 4; cnt++) {
2692                 if (cnt % 8 == 0) {
2693                         mdb_printf("\n");
2694                 }
2695                 mdb_printf("%08x ", fw->host_reg[cnt]);
2696         }
2697 
2698         mdb_printf("\n\nMailbox Registers");
2699         for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) {
2700                 if (cnt % 16 == 0) {
2701                         mdb_printf("\n");
2702                 }
2703                 mdb_printf("%04x ", fw->mailbox_reg[cnt]);
2704         }
2705 
2706         mdb_printf("\n\nXSEQ GP Registers");
2707         for (cnt = 0; cnt < sizeof (fw->xseq_gp_reg) / 4; cnt++) {
2708                 if (cnt % 8 == 0) {
2709                         mdb_printf("\n");
2710                 }
2711                 mdb_printf("%08x ", fw->xseq_gp_reg[cnt]);
2712         }
2713 
2714         mdb_printf("\n\nXSEQ-0 Registers");
2715         for (cnt = 0; cnt < sizeof (fw->xseq_0_reg) / 4; cnt++) {
2716                 if (cnt % 8 == 0) {
2717                         mdb_printf("\n");
2718                 }
2719                 mdb_printf("%08x ", fw->xseq_0_reg[cnt]);
2720         }
2721 
2722         mdb_printf("\n\nXSEQ-1 Registers");
2723         for (cnt = 0; cnt < sizeof (fw->xseq_1_reg) / 4; cnt++) {
2724                 if (cnt % 8 == 0) {
2725                         mdb_printf("\n");
2726                 }
2727                 mdb_printf("%08x ", fw->xseq_1_reg[cnt]);
2728         }
2729 
2730         mdb_printf("\n\nRSEQ GP Registers");
2731         for (cnt = 0; cnt < sizeof (fw->rseq_gp_reg) / 4; cnt++) {
2732                 if (cnt % 8 == 0) {
2733                         mdb_printf("\n");
2734                 }
2735                 mdb_printf("%08x ", fw->rseq_gp_reg[cnt]);
2736         }
2737 
2738         mdb_printf("\n\nRSEQ-0 Registers");
2739         for (cnt = 0; cnt < sizeof (fw->rseq_0_reg) / 4; cnt++) {
2740                 if (cnt % 8 == 0) {
2741                         mdb_printf("\n");
2742                 }
2743                 mdb_printf("%08x ", fw->rseq_0_reg[cnt]);
2744         }
2745 
2746         mdb_printf("\n\nRSEQ-1 Registers");
2747         for (cnt = 0; cnt < sizeof (fw->rseq_1_reg) / 4; cnt++) {
2748                 if (cnt % 8 == 0) {
2749                         mdb_printf("\n");
2750                 }
2751                 mdb_printf("%08x ", fw->rseq_1_reg[cnt]);
2752         }
2753 
2754         mdb_printf("\n\nRSEQ-2 Registers");
2755         for (cnt = 0; cnt < sizeof (fw->rseq_2_reg) / 4; cnt++) {
2756                 if (cnt % 8 == 0) {
2757                         mdb_printf("\n");
2758                 }
2759                 mdb_printf("%08x ", fw->rseq_2_reg[cnt]);
2760         }
2761 
2762         mdb_printf("\n\nCommand DMA Registers");
2763         for (cnt = 0; cnt < sizeof (fw->cmd_dma_reg) / 4; cnt++) {
2764                 if (cnt % 8 == 0) {
2765                         mdb_printf("\n");
2766                 }
2767                 mdb_printf("%08x ", fw->cmd_dma_reg[cnt]);
2768         }
2769 
2770         mdb_printf("\n\nRequest0 Queue DMA Channel Registers");
2771         for (cnt = 0; cnt < sizeof (fw->req0_dma_reg) / 4; cnt++) {
2772                 if (cnt % 8 == 0) {
2773                         mdb_printf("\n");
2774                 }
2775                 mdb_printf("%08x ", fw->req0_dma_reg[cnt]);
2776         }
2777 
2778         mdb_printf("\n\nResponse0 Queue DMA Channel Registers");
2779         for (cnt = 0; cnt < sizeof (fw->resp0_dma_reg) / 4; cnt++) {
2780                 if (cnt % 8 == 0) {
2781                         mdb_printf("\n");
2782                 }
2783                 mdb_printf("%08x ", fw->resp0_dma_reg[cnt]);
2784         }
2785 
2786         mdb_printf("\n\nRequest1 Queue DMA Channel Registers");
2787         for (cnt = 0; cnt < sizeof (fw->req1_dma_reg) / 4; cnt++) {
2788                 if (cnt % 8 == 0) {
2789                         mdb_printf("\n");
2790                 }
2791                 mdb_printf("%08x ", fw->req1_dma_reg[cnt]);
2792         }
2793 
2794         mdb_printf("\n\nXMT0 Data DMA Registers");
2795         for (cnt = 0; cnt < sizeof (fw->xmt0_dma_reg) / 4; cnt++) {
2796                 if (cnt % 8 == 0) {
2797                         mdb_printf("\n");
2798                 }
2799                 mdb_printf("%08x ", fw->xmt0_dma_reg[cnt]);
2800         }
2801 
2802         mdb_printf("\n\nXMT1 Data DMA Registers");
2803         for (cnt = 0; cnt < sizeof (fw->xmt1_dma_reg) / 4; cnt++) {
2804                 if (cnt % 8 == 0) {
2805                         mdb_printf("\n");
2806                 }
2807                 mdb_printf("%08x ", fw->xmt1_dma_reg[cnt]);
2808         }
2809 
2810         mdb_printf("\n\nXMT2 Data DMA Registers");
2811         for (cnt = 0; cnt < sizeof (fw->xmt2_dma_reg) / 4; cnt++) {
2812                 if (cnt % 8 == 0) {
2813                         mdb_printf("\n");
2814                 }
2815                 mdb_printf("%08x ", fw->xmt2_dma_reg[cnt]);
2816         }
2817 
2818         mdb_printf("\n\nXMT3 Data DMA Registers");
2819         for (cnt = 0; cnt < sizeof (fw->xmt3_dma_reg) / 4; cnt++) {
2820                 if (cnt % 8 == 0) {
2821                         mdb_printf("\n");
2822                 }
2823                 mdb_printf("%08x ", fw->xmt3_dma_reg[cnt]);
2824         }
2825 
2826         mdb_printf("\n\nXMT4 Data DMA Registers");
2827         for (cnt = 0; cnt < sizeof (fw->xmt4_dma_reg) / 4; cnt++) {
2828                 if (cnt % 8 == 0) {
2829                         mdb_printf("\n");
2830                 }
2831                 mdb_printf("%08x ", fw->xmt4_dma_reg[cnt]);
2832         }
2833 
2834         mdb_printf("\n\nXMT Data DMA Common Registers");
2835         for (cnt = 0; cnt < sizeof (fw->xmt_data_dma_reg) / 4; cnt++) {
2836                 if (cnt % 8 == 0) {
2837                         mdb_printf("\n");
2838                 }
2839                 mdb_printf("%08x ", fw->xmt_data_dma_reg[cnt]);
2840         }
2841 
2842         mdb_printf("\n\nRCV Thread 0 Data DMA Registers");
2843         for (cnt = 0; cnt < sizeof (fw->rcvt0_data_dma_reg) / 4; cnt++) {
2844                 if (cnt % 8 == 0) {
2845                         mdb_printf("\n");
2846                 }
2847                 mdb_printf("%08x ", fw->rcvt0_data_dma_reg[cnt]);
2848         }
2849 
2850         mdb_printf("\n\nRCV Thread 1 Data DMA Registers");
2851         for (cnt = 0; cnt < sizeof (fw->rcvt1_data_dma_reg) / 4; cnt++) {
2852                 if (cnt % 8 == 0) {
2853                         mdb_printf("\n");
2854                 }
2855                 mdb_printf("%08x ", fw->rcvt1_data_dma_reg[cnt]);
2856         }
2857 
2858         mdb_printf("\n\nRISC GP Registers");
2859         for (cnt = 0; cnt < sizeof (fw->risc_gp_reg) / 4; cnt++) {
2860                 if (cnt % 8 == 0) {
2861                         mdb_printf("\n");
2862                 }
2863                 mdb_printf("%08x ", fw->risc_gp_reg[cnt]);
2864         }
2865 
2866         mdb_printf("\n\nShadow Registers");
2867         for (cnt = 0; cnt < sizeof (fw->shadow_reg) / 4; cnt++) {
2868                 if (cnt % 8 == 0) {
2869                         mdb_printf("\n");
2870                 }
2871                 mdb_printf("%08x ", fw->shadow_reg[cnt]);
2872         }
2873 
2874         mdb_printf("\n\nLMC Registers");
2875         for (cnt = 0; cnt < sizeof (fw->lmc_reg) / 4; cnt++) {
2876                 if (cnt % 8 == 0) {
2877                         mdb_printf("\n");
2878                 }
2879                 mdb_printf("%08x ", fw->lmc_reg[cnt]);
2880         }
2881 
2882         mdb_printf("\n\nFPM Hardware Registers");
2883         for (cnt = 0; cnt < sizeof (fw->fpm_hdw_reg) / 4; cnt++) {
2884                 if (cnt % 8 == 0) {
2885                         mdb_printf("\n");
2886                 }
2887                 mdb_printf("%08x ", fw->fpm_hdw_reg[cnt]);
2888         }
2889 
2890         mdb_printf("\n\nFB Hardware Registers");
2891         for (cnt = 0; cnt < sizeof (fw->fb_hdw_reg) / 4; cnt++) {
2892                 if (cnt % 8 == 0) {
2893                         mdb_printf("\n");
2894                 }
2895                 mdb_printf("%08x ", fw->fb_hdw_reg[cnt]);
2896         }
2897 
2898         mdb_printf("\n\nCode RAM");
2899         for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) {
2900                 if (cnt % 8 == 0) {
2901                         mdb_printf("\n%08x: ", cnt + 0x20000);
2902                 }
2903                 mdb_printf("%08x ", fw->code_ram[cnt]);
2904         }
2905 
2906         mdb_printf("\n\nExternal Memory");
2907         for (cnt = 0; cnt < ha->fw_ext_memory_size / 4; cnt++) {
2908                 if (cnt % 8 == 0) {
2909                         mdb_printf("\n%08x: ", cnt + 0x100000);
2910                 }
2911                 mdb_printf("%08x ", fw->ext_mem[cnt]);
2912         }
2913 
2914         mdb_printf("\n[<==END] ISP Debug Dump");
2915 
2916         mdb_printf("\n\nRequest Queue");
2917 
2918         for (cnt = 0; cnt < REQUEST_QUEUE_SIZE / 4; cnt++) {
2919                 if (cnt % 8 == 0) {
2920                         mdb_printf("\n%08x: ", cnt);
2921                 }
2922                 mdb_printf("%08x ", fw->req_q[cnt]);
2923         }
2924 
2925         mdb_printf("\n\nResponse Queue");
2926 
2927         for (cnt = 0; cnt < RESPONSE_QUEUE_SIZE / 4; cnt++) {
2928                 if (cnt % 8 == 0) {
2929                         mdb_printf("\n%08x: ", cnt);
2930                 }
2931                 mdb_printf("%08x ", fw->rsp_q[cnt]);
2932         }
2933 
2934         if ((ha->cfg_flags & CFG_ENABLE_FWEXTTRACE) &&
2935             (ha->fwexttracebuf.bp != NULL)) {
2936                 uint32_t cnt_b = 0;
2937                 uint32_t *w32 = ha->fwexttracebuf.bp;
2938 
2939                 mdb_printf("\n\nExtended Trace Buffer Memory");
2940                 /* show data address as a byte address, data as long words */
2941                 for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
2942                         cnt_b = cnt * 4;
2943                         if (cnt_b % 32 == 0) {
2944                                 mdb_printf("\n%08x: ", w32 + cnt_b);
2945                         }
2946                         mdb_printf("%08x ", fw->ext_trace_buf[cnt]);
2947                 }
2948         }
2949 
2950         if ((ha->cfg_flags & CFG_ENABLE_FWFCETRACE) &&
2951             (ha->fwfcetracebuf.bp != NULL)) {
2952                 uint32_t cnt_b = 0;
2953                 uint32_t *w32 = ha->fwfcetracebuf.bp;
2954 
2955                 mdb_printf("\n\nFC Event Trace Buffer Memory");
2956                 /* show data address as a byte address, data as long words */
2957                 for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
2958                         cnt_b = cnt * 4;
2959                         if (cnt_b % 32 == 0) {
2960                                 mdb_printf("\n%08x: ", w32 + cnt_b);
2961                         }
2962                         mdb_printf("%08x ", fw->fce_trace_buf[cnt]);
2963                 }
2964         }
2965         mdb_free(fw, ha->ql_dump_size);
2966 
2967         return (DCMD_OK);
2968 }
2969 
2970 /*
2971  * ql_25xx_dump_dcmd
2972  *      prints out a firmware dump buffer
2973  *
2974  * Input:
2975  *      addr  = User supplied address. (NB: nust be an ha)
2976  *      flags = mdb flags.
2977  *      argc  = Number of user supplied args.
2978  *      argv  = Arg array.
2979  *
2980  * Returns:
2981  *      DCMD_OK or DCMD_ERR
2982  *
2983  * Context:
2984  *      User context.
2985  *
2986  */
2987 /*ARGSUSED*/
2988 static int
2989 ql_25xx_dump_dcmd(ql_adapter_state_t *ha, uint_t flags, int argc,
2990     const mdb_arg_t *argv)
2991 {
2992         ql_25xx_fw_dump_t       *fw;
2993         ql_response_q_t         **rsp_queues, *rsp_q;
2994         uint32_t                cnt, cnt1, *dp, *dp2;
2995 
2996         fw = (ql_25xx_fw_dump_t *)mdb_alloc(ha->ql_dump_size, UM_SLEEP);
2997         rsp_queues = mdb_alloc(ha->rsp_queues_cnt *
2998             sizeof (ql_response_q_t *), UM_SLEEP);
2999         rsp_q = mdb_alloc(sizeof (ql_response_q_t), UM_SLEEP);
3000 
3001         if (mdb_vread(fw, ha->ql_dump_size,
3002             (uintptr_t)ha->ql_dump_ptr) == -1 ||
3003             mdb_vread(rsp_queues, ha->rsp_queues_cnt *
3004             sizeof (ql_response_q_t *), (uintptr_t)ha->rsp_queues) == -1) {
3005                 mdb_warn("failed to read ql_dump_ptr (no f/w dump active?)");
3006                 mdb_free(rsp_q, sizeof (ql_response_q_t));
3007                 mdb_free(rsp_queues, ha->rsp_queues_cnt *
3008                     sizeof (ql_response_q_t *));
3009                 mdb_free(fw, ha->ql_dump_size);
3010                 return (DCMD_OK);
3011         }
3012 
3013         mdb_printf("\nISP FW Version %d.%02d.%02d Attributes %X\n",
3014             ha->fw_major_version, ha->fw_minor_version,
3015             ha->fw_subminor_version, ha->fw_attributes);
3016 
3017         mdb_printf("\nHCCR Register\n%08x\n", fw->hccr);
3018         mdb_printf("\nR2H Register\n%08x\n", fw->r2h_status);
3019         mdb_printf("\nAER Uncorrectable Error Status Register\n%08x\n",
3020             fw->aer_ues);
3021 
3022         mdb_printf("\n\nHostRisc Registers");
3023         for (cnt = 0; cnt < sizeof (fw->hostrisc_reg) / 4; cnt++) {
3024                 if (cnt % 8 == 0) {
3025                         mdb_printf("\n");
3026                 }
3027                 mdb_printf("%08x ", fw->hostrisc_reg[cnt]);
3028         }
3029 
3030         mdb_printf("\n\nPCIe Registers");
3031         for (cnt = 0; cnt < sizeof (fw->pcie_reg) / 4; cnt++) {
3032                 if (cnt % 8 == 0) {
3033                         mdb_printf("\n");
3034                 }
3035                 mdb_printf("%08x ", fw->pcie_reg[cnt]);
3036         }
3037 
3038         mdb_printf("\n\nHost Interface Registers");
3039         for (cnt = 0; cnt < sizeof (fw->host_reg) / 4; cnt++) {
3040                 if (cnt % 8 == 0) {
3041                         mdb_printf("\n");
3042                 }
3043                 mdb_printf("%08x ", fw->host_reg[cnt]);
3044         }
3045 
3046         mdb_printf("\n\nShadow Registers");
3047         for (cnt = 0; cnt < sizeof (fw->shadow_reg) / 4; cnt++) {
3048                 if (cnt % 8 == 0) {
3049                         mdb_printf("\n");
3050                 }
3051 
3052                 mdb_printf("%08x ", fw->shadow_reg[cnt]);
3053         }
3054 
3055         mdb_printf("\n\nMailbox Registers");
3056         for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) {
3057                 if (cnt % 16 == 0) {
3058                         mdb_printf("\n");
3059                 }
3060                 mdb_printf("%04x ", fw->mailbox_reg[cnt]);
3061         }
3062 
3063         mdb_printf("\n\nXSEQ GP Registers");
3064         for (cnt = 0; cnt < sizeof (fw->xseq_gp_reg) / 4; cnt++) {
3065                 if (cnt % 8 == 0) {
3066                         mdb_printf("\n");
3067                 }
3068                 mdb_printf("%08x ", fw->xseq_gp_reg[cnt]);
3069         }
3070 
3071         mdb_printf("\n\nXSEQ-0 Registers");
3072         for (cnt = 0; cnt < sizeof (fw->xseq_0_reg) / 4; cnt++) {
3073                 if (cnt % 8 == 0) {
3074                         mdb_printf("\n");
3075                 }
3076                 mdb_printf("%08x ", fw->xseq_0_reg[cnt]);
3077         }
3078 
3079         mdb_printf("\n\nXSEQ-1 Registers");
3080         for (cnt = 0; cnt < sizeof (fw->xseq_1_reg) / 4; cnt++) {
3081                 if (cnt % 8 == 0) {
3082                         mdb_printf("\n");
3083                 }
3084                 mdb_printf("%08x ", fw->xseq_1_reg[cnt]);
3085         }
3086 
3087         mdb_printf("\n\nRSEQ GP Registers");
3088         for (cnt = 0; cnt < sizeof (fw->rseq_gp_reg) / 4; cnt++) {
3089                 if (cnt % 8 == 0) {
3090                         mdb_printf("\n");
3091                 }
3092                 mdb_printf("%08x ", fw->rseq_gp_reg[cnt]);
3093         }
3094 
3095         mdb_printf("\n\nRSEQ-0 Registers");
3096         for (cnt = 0; cnt < sizeof (fw->rseq_0_reg) / 4; cnt++) {
3097                 if (cnt % 8 == 0) {
3098                         mdb_printf("\n");
3099                 }
3100                 mdb_printf("%08x ", fw->rseq_0_reg[cnt]);
3101         }
3102 
3103         mdb_printf("\n\nRSEQ-1 Registers");
3104         for (cnt = 0; cnt < sizeof (fw->rseq_1_reg) / 4; cnt++) {
3105                 if (cnt % 8 == 0) {
3106                         mdb_printf("\n");
3107                 }
3108                 mdb_printf("%08x ", fw->rseq_1_reg[cnt]);
3109         }
3110 
3111         mdb_printf("\n\nRSEQ-2 Registers");
3112         for (cnt = 0; cnt < sizeof (fw->rseq_2_reg) / 4; cnt++) {
3113                 if (cnt % 8 == 0) {
3114                         mdb_printf("\n");
3115                 }
3116                 mdb_printf("%08x ", fw->rseq_2_reg[cnt]);
3117         }
3118 
3119         mdb_printf("\n\nASEQ GP Registers");
3120         for (cnt = 0; cnt < sizeof (fw->aseq_gp_reg) / 4; cnt++) {
3121                 if (cnt % 8 == 0) {
3122                         mdb_printf("\n");
3123                 }
3124                 mdb_printf("%08x ", fw->aseq_gp_reg[cnt]);
3125         }
3126 
3127         mdb_printf("\n\nASEQ-0 GP Registers");
3128         for (cnt = 0; cnt < sizeof (fw->aseq_0_reg) / 4; cnt++) {
3129                 if (cnt % 8 == 0) {
3130                         mdb_printf("\n");
3131                 }
3132 
3133                 mdb_printf("%08x ", fw->aseq_0_reg[cnt]);
3134         }
3135 
3136         mdb_printf("\n\nASEQ-1 GP Registers");
3137         for (cnt = 0; cnt < sizeof (fw->aseq_1_reg) / 4; cnt++) {
3138                 if (cnt % 8 == 0) {
3139                         mdb_printf("\n");
3140                 }
3141 
3142                 mdb_printf("%08x ", fw->aseq_1_reg[cnt]);
3143         }
3144 
3145         mdb_printf("\n\nASEQ-2 GP Registers");
3146         for (cnt = 0; cnt < sizeof (fw->aseq_2_reg) / 4; cnt++) {
3147                 if (cnt % 8 == 0) {
3148                         mdb_printf("\n");
3149                 }
3150                 mdb_printf("%08x ", fw->aseq_2_reg[cnt]);
3151         }
3152 
3153         mdb_printf("\n\nCommand DMA Registers");
3154         for (cnt = 0; cnt < sizeof (fw->cmd_dma_reg) / 4; cnt++) {
3155                 if (cnt % 8 == 0) {
3156                         mdb_printf("\n");
3157                 }
3158                 mdb_printf("%08x ", fw->cmd_dma_reg[cnt]);
3159         }
3160 
3161         mdb_printf("\n\nRequest0 Queue DMA Channel Registers");
3162         for (cnt = 0; cnt < sizeof (fw->req0_dma_reg) / 4; cnt++) {
3163                 if (cnt % 8 == 0) {
3164                         mdb_printf("\n");
3165                 }
3166                 mdb_printf("%08x ", fw->req0_dma_reg[cnt]);
3167         }
3168 
3169         mdb_printf("\n\nResponse0 Queue DMA Channel Registers");
3170         for (cnt = 0; cnt < sizeof (fw->resp0_dma_reg) / 4; cnt++) {
3171                 if (cnt % 8 == 0) {
3172                         mdb_printf("\n");
3173                 }
3174                 mdb_printf("%08x ", fw->resp0_dma_reg[cnt]);
3175         }
3176 
3177         mdb_printf("\n\nRequest1 Queue DMA Channel Registers");
3178         for (cnt = 0; cnt < sizeof (fw->req1_dma_reg) / 4; cnt++) {
3179                 if (cnt % 8 == 0) {
3180                         mdb_printf("\n");
3181                 }
3182                 mdb_printf("%08x ", fw->req1_dma_reg[cnt]);
3183         }
3184 
3185         mdb_printf("\n\nXMT0 Data DMA Registers");
3186         for (cnt = 0; cnt < sizeof (fw->xmt0_dma_reg) / 4; cnt++) {
3187                 if (cnt % 8 == 0) {
3188                         mdb_printf("\n");
3189                 }
3190                 mdb_printf("%08x ", fw->xmt0_dma_reg[cnt]);
3191         }
3192 
3193         mdb_printf("\n\nXMT1 Data DMA Registers");
3194         for (cnt = 0; cnt < sizeof (fw->xmt1_dma_reg) / 4; cnt++) {
3195                 if (cnt % 8 == 0) {
3196                         mdb_printf("\n");
3197                 }
3198                 mdb_printf("%08x ", fw->xmt1_dma_reg[cnt]);
3199         }
3200 
3201         mdb_printf("\n\nXMT2 Data DMA Registers");
3202         for (cnt = 0; cnt < sizeof (fw->xmt2_dma_reg) / 4; cnt++) {
3203                 if (cnt % 8 == 0) {
3204                         mdb_printf("\n");
3205                 }
3206                 mdb_printf("%08x ", fw->xmt2_dma_reg[cnt]);
3207         }
3208 
3209         mdb_printf("\n\nXMT3 Data DMA Registers");
3210         for (cnt = 0; cnt < sizeof (fw->xmt3_dma_reg) / 4; cnt++) {
3211                 if (cnt % 8 == 0) {
3212                         mdb_printf("\n");
3213                 }
3214                 mdb_printf("%08x ", fw->xmt3_dma_reg[cnt]);
3215         }
3216 
3217         mdb_printf("\n\nXMT4 Data DMA Registers");
3218         for (cnt = 0; cnt < sizeof (fw->xmt4_dma_reg) / 4; cnt++) {
3219                 if (cnt % 8 == 0) {
3220                         mdb_printf("\n");
3221                 }
3222                 mdb_printf("%08x ", fw->xmt4_dma_reg[cnt]);
3223         }
3224 
3225         mdb_printf("\n\nXMT Data DMA Common Registers");
3226         for (cnt = 0; cnt < sizeof (fw->xmt_data_dma_reg) / 4; cnt++) {
3227                 if (cnt % 8 == 0) {
3228                         mdb_printf("\n");
3229                 }
3230                 mdb_printf("%08x ", fw->xmt_data_dma_reg[cnt]);
3231         }
3232 
3233         mdb_printf("\n\nRCV Thread 0 Data DMA Registers");
3234         for (cnt = 0; cnt < sizeof (fw->rcvt0_data_dma_reg) / 4; cnt++) {
3235                 if (cnt % 8 == 0) {
3236                         mdb_printf("\n");
3237                 }
3238                 mdb_printf("%08x ", fw->rcvt0_data_dma_reg[cnt]);
3239         }
3240 
3241         mdb_printf("\n\nRCV Thread 1 Data DMA Registers");
3242         for (cnt = 0; cnt < sizeof (fw->rcvt1_data_dma_reg) / 4; cnt++) {
3243                 if (cnt % 8 == 0) {
3244                         mdb_printf("\n");
3245                 }
3246                 mdb_printf("%08x ", fw->rcvt1_data_dma_reg[cnt]);
3247         }
3248 
3249         mdb_printf("\n\nRISC GP Registers");
3250         for (cnt = 0; cnt < sizeof (fw->risc_gp_reg) / 4; cnt++) {
3251                 if (cnt % 8 == 0) {
3252                         mdb_printf("\n");
3253                 }
3254                 mdb_printf("%08x ", fw->risc_gp_reg[cnt]);
3255         }
3256 
3257         mdb_printf("\n\nRISC IO Register\n%08x", fw->risc_io);
3258 
3259         mdb_printf("\n\nLMC Registers");
3260         for (cnt = 0; cnt < sizeof (fw->lmc_reg) / 4; cnt++) {
3261                 if (cnt % 8 == 0) {
3262                         mdb_printf("\n");
3263                 }
3264                 mdb_printf("%08x ", fw->lmc_reg[cnt]);
3265         }
3266 
3267         mdb_printf("\n\nFPM Hardware Registers");
3268         for (cnt = 0; cnt < sizeof (fw->fpm_hdw_reg) / 4; cnt++) {
3269                 if (cnt % 8 == 0) {
3270                         mdb_printf("\n");
3271                 }
3272                 mdb_printf("%08x ", fw->fpm_hdw_reg[cnt]);
3273         }
3274 
3275         mdb_printf("\n\nFB Hardware Registers");
3276         for (cnt = 0; cnt < sizeof (fw->fb_hdw_reg) / 4; cnt++) {
3277                 if (cnt % 8 == 0) {
3278                         mdb_printf("\n");
3279                 }
3280                 mdb_printf("%08x ", fw->fb_hdw_reg[cnt]);
3281         }
3282 
3283         mdb_printf("\n\nCode RAM");
3284         for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) {
3285                 if (cnt % 8 == 0) {
3286                         mdb_printf("\n%08x: ", cnt + 0x20000);
3287                 }
3288                 mdb_printf("%08x ", fw->code_ram[cnt]);
3289         }
3290 
3291         mdb_printf("\n\nExternal Memory");
3292         dp = (uint32_t *)(void *)((caddr_t)fw->req_rsp_ext_mem +
3293             fw->req_q_size[0] + fw->req_q_size[1] + fw->rsp_q_size +
3294             (ha->rsp_queues_cnt * 16));
3295         for (cnt = 0; cnt < ha->fw_ext_memory_size / 4; cnt++) {
3296                 if (cnt % 8 == 0) {
3297                         mdb_printf("\n%08x: ", cnt + 0x100000);
3298                 }
3299                 mdb_printf("%08x ", *dp++);
3300         }
3301 
3302         mdb_printf("\n[<==END] ISP Debug Dump");
3303 
3304         mdb_printf("\n\nRequest Queue");
3305 
3306         dp = fw->req_rsp_ext_mem + (ha->rsp_queues_cnt * 4);
3307         for (cnt = 0; cnt < 2 && fw->req_q_size[cnt]; cnt++) {
3308                 dp2 = dp;
3309                 for (cnt1 = 0; cnt1 < fw->req_q_size[cnt] / 4; cnt1++) {
3310                         if (*dp2++) {
3311                                 break;
3312                         }
3313                 }
3314                 if (cnt1 == fw->req_q_size[cnt] / 4) {
3315                         dp = dp2;
3316                         continue;
3317                 }
3318                 mdb_printf("\n\nRequest Queue\nQueue 0%d:", cnt);
3319                 for (cnt1 = 0; cnt1 < fw->req_q_size[cnt] / 4; cnt1++) {
3320                         if (cnt1 % 8 == 0) {
3321                                 mdb_printf("\n%08x: ", cnt1);
3322                         }
3323                         mdb_printf("%08x ", *dp++);
3324                 }
3325         }
3326 
3327         for (cnt = 0; cnt < ha->rsp_queues_cnt; cnt++) {
3328                 if (mdb_vread(rsp_q, sizeof (ql_response_q_t),
3329                     (uintptr_t)rsp_queues[cnt]) == -1) {
3330                         mdb_warn("failed to read ha->rsp_queues[%d]", cnt);
3331                         break;
3332                 }
3333                 dp2 = dp;
3334                 for (cnt1 = 0; cnt1 < rsp_q->rsp_ring.size / 4; cnt1++) {
3335                         if (*dp2++) {
3336                                 break;
3337                         }
3338                 }
3339                 if (cnt1 == rsp_q->rsp_ring.size / 4) {
3340                         dp = dp2;
3341                         continue;
3342                 }
3343                 mdb_printf("\n\nResponse Queue\nQueue 0%d:", cnt);
3344 
3345                 for (cnt1 = 0; cnt1 < rsp_q->rsp_ring.size / 4; cnt1++) {
3346                         if (cnt1 % 8 == 0) {
3347                                 mdb_printf("\n%08x: ", cnt1);
3348                         }
3349                         mdb_printf("%08x ", *dp++);
3350                 }
3351         }
3352 
3353         if ((ha->cfg_flags & CFG_ENABLE_FWEXTTRACE) &&
3354             (ha->fwexttracebuf.bp != NULL)) {
3355                 uint32_t cnt_b = 0;
3356                 uint32_t *w32 = ha->fwexttracebuf.bp;
3357 
3358                 mdb_printf("\n\nExtended Trace Buffer Memory");
3359                 /* show data address as a byte address, data as long words */
3360                 for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
3361                         cnt_b = cnt * 4;
3362                         if (cnt_b % 32 == 0) {
3363                                 mdb_printf("\n%08x: ", w32 + cnt_b);
3364                         }
3365                         mdb_printf("%08x ", fw->ext_trace_buf[cnt]);
3366                 }
3367         }
3368 
3369         if ((ha->cfg_flags & CFG_ENABLE_FWFCETRACE) &&
3370             (ha->fwfcetracebuf.bp != NULL)) {
3371                 uint32_t cnt_b = 0;
3372                 uint32_t *w32 = ha->fwfcetracebuf.bp;
3373 
3374                 mdb_printf("\n\nFC Event Trace Buffer Memory");
3375                 /* show data address as a byte address, data as long words */
3376                 for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
3377                         cnt_b = cnt * 4;
3378                         if (cnt_b % 32 == 0) {
3379                                 mdb_printf("\n%08x: ", w32 + cnt_b);
3380                         }
3381                         mdb_printf("%08x ", fw->fce_trace_buf[cnt]);
3382                 }
3383         }
3384 
3385         mdb_free(rsp_q, sizeof (ql_response_q_t));
3386         mdb_free(rsp_queues, ha->rsp_queues_cnt * sizeof (ql_response_q_t *));
3387         mdb_free(fw, ha->ql_dump_size);
3388 
3389         mdb_printf("\n\nreturn exit\n");
3390 
3391         return (DCMD_OK);
3392 }
3393 
3394 /*
3395  * ql_81xx_dump_dcmd
3396  *      prints out a firmware dump buffer
3397  *
3398  * Input:
3399  *      addr  = User supplied address. (NB: nust be an ha)
3400  *      flags = mdb flags.
3401  *      argc  = Number of user supplied args.
3402  *      argv  = Arg array.
3403  *
3404  * Returns:
3405  *      DCMD_OK or DCMD_ERR
3406  *
3407  * Context:
3408  *      User context.
3409  *
3410  */
3411 /*ARGSUSED*/
3412 static int
3413 ql_81xx_dump_dcmd(ql_adapter_state_t *ha, uint_t flags, int argc,
3414     const mdb_arg_t *argv)
3415 {
3416         ql_81xx_fw_dump_t       *fw;
3417         ql_response_q_t         **rsp_queues, *rsp_q;
3418         uint32_t                cnt, cnt1, *dp, *dp2;
3419 
3420         fw = (ql_81xx_fw_dump_t *)mdb_alloc(ha->ql_dump_size, UM_SLEEP);
3421         rsp_queues = mdb_alloc(ha->rsp_queues_cnt *
3422             sizeof (ql_response_q_t *), UM_SLEEP);
3423         rsp_q = mdb_alloc(sizeof (ql_response_q_t), UM_SLEEP);
3424 
3425         if (mdb_vread(fw, ha->ql_dump_size,
3426             (uintptr_t)ha->ql_dump_ptr) == -1 ||
3427             mdb_vread(rsp_queues, ha->rsp_queues_cnt *
3428             sizeof (ql_response_q_t *), (uintptr_t)ha->rsp_queues) == -1) {
3429                 mdb_warn("failed to read ql_dump_ptr (no f/w dump active?)");
3430                 mdb_free(rsp_q, sizeof (ql_response_q_t));
3431                 mdb_free(rsp_queues, ha->rsp_queues_cnt *
3432                     sizeof (ql_response_q_t *));
3433                 mdb_free(fw, ha->ql_dump_size);
3434                 return (DCMD_OK);
3435         }
3436 
3437         mdb_printf("\nISP FW Version %d.%02d.%02d Attributes %X\n",
3438             ha->fw_major_version, ha->fw_minor_version,
3439             ha->fw_subminor_version, ha->fw_attributes);
3440 
3441         mdb_printf("\nHCCR Register\n%08x\n", fw->hccr);
3442 
3443         mdb_printf("\nR2H Register\n%08x\n", fw->r2h_status);
3444 
3445         mdb_printf("\nAER Uncorrectable Error Status Register\n%08x\n",
3446             fw->aer_ues);
3447 
3448         mdb_printf("\n\nHostRisc Registers");
3449         for (cnt = 0; cnt < sizeof (fw->hostrisc_reg) / 4; cnt++) {
3450                 if (cnt % 8 == 0) {
3451                         mdb_printf("\n");
3452                 }
3453                 mdb_printf("%08x ", fw->hostrisc_reg[cnt]);
3454         }
3455 
3456         mdb_printf("\n\nPCIe Registers");
3457         for (cnt = 0; cnt < sizeof (fw->pcie_reg) / 4; cnt++) {
3458                 if (cnt % 8 == 0) {
3459                         mdb_printf("\n");
3460                 }
3461                 mdb_printf("%08x ", fw->pcie_reg[cnt]);
3462         }
3463 
3464         mdb_printf("\n\nHost Interface Registers");
3465         for (cnt = 0; cnt < sizeof (fw->host_reg) / 4; cnt++) {
3466                 if (cnt % 8 == 0) {
3467                         mdb_printf("\n");
3468                 }
3469                 mdb_printf("%08x ", fw->host_reg[cnt]);
3470         }
3471 
3472         mdb_printf("\n\nShadow Registers");
3473         for (cnt = 0; cnt < sizeof (fw->shadow_reg) / 4; cnt++) {
3474                 if (cnt % 8 == 0) {
3475                         mdb_printf("\n");
3476                 }
3477 
3478                 mdb_printf("%08x ", fw->shadow_reg[cnt]);
3479         }
3480 
3481         mdb_printf("\n\nMailbox Registers");
3482         for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) {
3483                 if (cnt % 16 == 0) {
3484                         mdb_printf("\n");
3485                 }
3486                 mdb_printf("%04x ", fw->mailbox_reg[cnt]);
3487         }
3488 
3489         mdb_printf("\n\nXSEQ GP Registers");
3490         for (cnt = 0; cnt < sizeof (fw->xseq_gp_reg) / 4; cnt++) {
3491                 if (cnt % 8 == 0) {
3492                         mdb_printf("\n");
3493                 }
3494                 mdb_printf("%08x ", fw->xseq_gp_reg[cnt]);
3495         }
3496 
3497         mdb_printf("\n\nXSEQ-0 Registers");
3498         for (cnt = 0; cnt < sizeof (fw->xseq_0_reg) / 4; cnt++) {
3499                 if (cnt % 8 == 0) {
3500                         mdb_printf("\n");
3501                 }
3502                 mdb_printf("%08x ", fw->xseq_0_reg[cnt]);
3503         }
3504 
3505         mdb_printf("\n\nXSEQ-1 Registers");
3506         for (cnt = 0; cnt < sizeof (fw->xseq_1_reg) / 4; cnt++) {
3507                 if (cnt % 8 == 0) {
3508                         mdb_printf("\n");
3509                 }
3510                 mdb_printf("%08x ", fw->xseq_1_reg[cnt]);
3511         }
3512 
3513         mdb_printf("\n\nRSEQ GP Registers");
3514         for (cnt = 0; cnt < sizeof (fw->rseq_gp_reg) / 4; cnt++) {
3515                 if (cnt % 8 == 0) {
3516                         mdb_printf("\n");
3517                 }
3518                 mdb_printf("%08x ", fw->rseq_gp_reg[cnt]);
3519         }
3520 
3521         mdb_printf("\n\nRSEQ-0 Registers");
3522         for (cnt = 0; cnt < sizeof (fw->rseq_0_reg) / 4; cnt++) {
3523                 if (cnt % 8 == 0) {
3524                         mdb_printf("\n");
3525                 }
3526                 mdb_printf("%08x ", fw->rseq_0_reg[cnt]);
3527         }
3528 
3529         mdb_printf("\n\nRSEQ-1 Registers");
3530         for (cnt = 0; cnt < sizeof (fw->rseq_1_reg) / 4; cnt++) {
3531                 if (cnt % 8 == 0) {
3532                         mdb_printf("\n");
3533                 }
3534                 mdb_printf("%08x ", fw->rseq_1_reg[cnt]);
3535         }
3536 
3537         mdb_printf("\n\nRSEQ-2 Registers");
3538         for (cnt = 0; cnt < sizeof (fw->rseq_2_reg) / 4; cnt++) {
3539                 if (cnt % 8 == 0) {
3540                         mdb_printf("\n");
3541                 }
3542                 mdb_printf("%08x ", fw->rseq_2_reg[cnt]);
3543         }
3544 
3545         mdb_printf("\n\nASEQ GP Registers");
3546         for (cnt = 0; cnt < sizeof (fw->aseq_gp_reg) / 4; cnt++) {
3547                 if (cnt % 8 == 0) {
3548                         mdb_printf("\n");
3549                 }
3550                 mdb_printf("%08x ", fw->aseq_gp_reg[cnt]);
3551         }
3552 
3553         mdb_printf("\n\nASEQ-0 GP Registers");
3554         for (cnt = 0; cnt < sizeof (fw->aseq_0_reg) / 4; cnt++) {
3555                 if (cnt % 8 == 0) {
3556                         mdb_printf("\n");
3557                 }
3558 
3559                 mdb_printf("%08x ", fw->aseq_0_reg[cnt]);
3560         }
3561 
3562         mdb_printf("\n\nASEQ-1 GP Registers");
3563         for (cnt = 0; cnt < sizeof (fw->aseq_1_reg) / 4; cnt++) {
3564                 if (cnt % 8 == 0) {
3565                         mdb_printf("\n");
3566                 }
3567 
3568                 mdb_printf("%08x ", fw->aseq_1_reg[cnt]);
3569         }
3570 
3571         mdb_printf("\n\nASEQ-2 GP Registers");
3572         for (cnt = 0; cnt < sizeof (fw->aseq_2_reg) / 4; cnt++) {
3573                 if (cnt % 8 == 0) {
3574                         mdb_printf("\n");
3575                 }
3576                 mdb_printf("%08x ", fw->aseq_2_reg[cnt]);
3577         }
3578 
3579         mdb_printf("\n\nCommand DMA Registers");
3580         for (cnt = 0; cnt < sizeof (fw->cmd_dma_reg) / 4; cnt++) {
3581                 if (cnt % 8 == 0) {
3582                         mdb_printf("\n");
3583                 }
3584                 mdb_printf("%08x ", fw->cmd_dma_reg[cnt]);
3585         }
3586 
3587         mdb_printf("\n\nRequest0 Queue DMA Channel Registers");
3588         for (cnt = 0; cnt < sizeof (fw->req0_dma_reg) / 4; cnt++) {
3589                 if (cnt % 8 == 0) {
3590                         mdb_printf("\n");
3591                 }
3592                 mdb_printf("%08x ", fw->req0_dma_reg[cnt]);
3593         }
3594 
3595         mdb_printf("\n\nResponse0 Queue DMA Channel Registers");
3596         for (cnt = 0; cnt < sizeof (fw->resp0_dma_reg) / 4; cnt++) {
3597                 if (cnt % 8 == 0) {
3598                         mdb_printf("\n");
3599                 }
3600                 mdb_printf("%08x ", fw->resp0_dma_reg[cnt]);
3601         }
3602 
3603         mdb_printf("\n\nRequest1 Queue DMA Channel Registers");
3604         for (cnt = 0; cnt < sizeof (fw->req1_dma_reg) / 4; cnt++) {
3605                 if (cnt % 8 == 0) {
3606                         mdb_printf("\n");
3607                 }
3608                 mdb_printf("%08x ", fw->req1_dma_reg[cnt]);
3609         }
3610 
3611         mdb_printf("\n\nXMT0 Data DMA Registers");
3612         for (cnt = 0; cnt < sizeof (fw->xmt0_dma_reg) / 4; cnt++) {
3613                 if (cnt % 8 == 0) {
3614                         mdb_printf("\n");
3615                 }
3616                 mdb_printf("%08x ", fw->xmt0_dma_reg[cnt]);
3617         }
3618 
3619         mdb_printf("\n\nXMT1 Data DMA Registers");
3620         for (cnt = 0; cnt < sizeof (fw->xmt1_dma_reg) / 4; cnt++) {
3621                 if (cnt % 8 == 0) {
3622                         mdb_printf("\n");
3623                 }
3624                 mdb_printf("%08x ", fw->xmt1_dma_reg[cnt]);
3625         }
3626 
3627         mdb_printf("\n\nXMT2 Data DMA Registers");
3628         for (cnt = 0; cnt < sizeof (fw->xmt2_dma_reg) / 4; cnt++) {
3629                 if (cnt % 8 == 0) {
3630                         mdb_printf("\n");
3631                 }
3632                 mdb_printf("%08x ", fw->xmt2_dma_reg[cnt]);
3633         }
3634 
3635         mdb_printf("\n\nXMT3 Data DMA Registers");
3636         for (cnt = 0; cnt < sizeof (fw->xmt3_dma_reg) / 4; cnt++) {
3637                 if (cnt % 8 == 0) {
3638                         mdb_printf("\n");
3639                 }
3640                 mdb_printf("%08x ", fw->xmt3_dma_reg[cnt]);
3641         }
3642 
3643         mdb_printf("\n\nXMT4 Data DMA Registers");
3644         for (cnt = 0; cnt < sizeof (fw->xmt4_dma_reg) / 4; cnt++) {
3645                 if (cnt % 8 == 0) {
3646                         mdb_printf("\n");
3647                 }
3648                 mdb_printf("%08x ", fw->xmt4_dma_reg[cnt]);
3649         }
3650 
3651         mdb_printf("\n\nXMT Data DMA Common Registers");
3652         for (cnt = 0; cnt < sizeof (fw->xmt_data_dma_reg) / 4; cnt++) {
3653                 if (cnt % 8 == 0) {
3654                         mdb_printf("\n");
3655                 }
3656                 mdb_printf("%08x ", fw->xmt_data_dma_reg[cnt]);
3657         }
3658 
3659         mdb_printf("\n\nRCV Thread 0 Data DMA Registers");
3660         for (cnt = 0; cnt < sizeof (fw->rcvt0_data_dma_reg) / 4; cnt++) {
3661                 if (cnt % 8 == 0) {
3662                         mdb_printf("\n");
3663                 }
3664                 mdb_printf("%08x ", fw->rcvt0_data_dma_reg[cnt]);
3665         }
3666 
3667         mdb_printf("\n\nRCV Thread 1 Data DMA Registers");
3668         for (cnt = 0; cnt < sizeof (fw->rcvt1_data_dma_reg) / 4; cnt++) {
3669                 if (cnt % 8 == 0) {
3670                         mdb_printf("\n");
3671                 }
3672                 mdb_printf("%08x ", fw->rcvt1_data_dma_reg[cnt]);
3673         }
3674 
3675         mdb_printf("\n\nRISC GP Registers");
3676         for (cnt = 0; cnt < sizeof (fw->risc_gp_reg) / 4; cnt++) {
3677                 if (cnt % 8 == 0) {
3678                         mdb_printf("\n");
3679                 }
3680                 mdb_printf("%08x ", fw->risc_gp_reg[cnt]);
3681         }
3682 
3683         mdb_printf("\n\nRISC IO Register\n%08x", fw->risc_io);
3684 
3685         mdb_printf("\n\nLMC Registers");
3686         for (cnt = 0; cnt < sizeof (fw->lmc_reg) / 4; cnt++) {
3687                 if (cnt % 8 == 0) {
3688                         mdb_printf("\n");
3689                 }
3690                 mdb_printf("%08x ", fw->lmc_reg[cnt]);
3691         }
3692 
3693         mdb_printf("\n\nFPM Hardware Registers");
3694         for (cnt = 0; cnt < sizeof (fw->fpm_hdw_reg) / 4; cnt++) {
3695                 if (cnt % 8 == 0) {
3696                         mdb_printf("\n");
3697                 }
3698                 mdb_printf("%08x ", fw->fpm_hdw_reg[cnt]);
3699         }
3700 
3701         mdb_printf("\n\nFB Hardware Registers");
3702         for (cnt = 0; cnt < sizeof (fw->fb_hdw_reg) / 4; cnt++) {
3703                 if (cnt % 8 == 0) {
3704                         mdb_printf("\n");
3705                 }
3706                 mdb_printf("%08x ", fw->fb_hdw_reg[cnt]);
3707         }
3708 
3709         mdb_printf("\n\nCode RAM");
3710         for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) {
3711                 if (cnt % 8 == 0) {
3712                         mdb_printf("\n%08x: ", cnt + 0x20000);
3713                 }
3714                 mdb_printf("%08x ", fw->code_ram[cnt]);
3715         }
3716 
3717         mdb_printf("\n\nExternal Memory");
3718         dp = (uint32_t *)(void *)((caddr_t)fw->req_rsp_ext_mem +
3719             fw->req_q_size[0] + fw->req_q_size[1] + fw->rsp_q_size +
3720             (ha->rsp_queues_cnt * 16));
3721         for (cnt = 0; cnt < ha->fw_ext_memory_size / 4; cnt++) {
3722                 if (cnt % 8 == 0) {
3723                         mdb_printf("\n%08x: ", cnt + 0x100000);
3724                 }
3725                 mdb_printf("%08x ", *dp++);
3726         }
3727 
3728         mdb_printf("\n[<==END] ISP Debug Dump");
3729 
3730         mdb_printf("\n\nRequest Queue");
3731 
3732         dp = fw->req_rsp_ext_mem + (ha->rsp_queues_cnt * 4);
3733         for (cnt = 0; cnt < 2 && fw->req_q_size[cnt]; cnt++) {
3734                 dp2 = dp;
3735                 for (cnt1 = 0; cnt1 < fw->req_q_size[cnt] / 4; cnt1++) {
3736                         if (*dp2++) {
3737                                 break;
3738                         }
3739                 }
3740                 if (cnt1 == fw->req_q_size[cnt] / 4) {
3741                         dp = dp2;
3742                         continue;
3743                 }
3744                 mdb_printf("\n\nRequest Queue\nQueue 0%d:", cnt);
3745                 for (cnt1 = 0; cnt1 < fw->req_q_size[cnt] / 4; cnt1++) {
3746                         if (cnt1 % 8 == 0) {
3747                                 mdb_printf("\n%08x: ", cnt1);
3748                         }
3749                         mdb_printf("%08x ", *dp++);
3750                 }
3751         }
3752 
3753         for (cnt = 0; cnt < ha->rsp_queues_cnt; cnt++) {
3754                 if (mdb_vread(rsp_q, sizeof (ql_response_q_t),
3755                     (uintptr_t)rsp_queues[cnt]) == -1) {
3756                         mdb_warn("failed to read ha->rsp_queues[%d]", cnt);
3757                         break;
3758                 }
3759                 dp2 = dp;
3760                 for (cnt1 = 0; cnt1 < rsp_q->rsp_ring.size / 4; cnt1++) {
3761                         if (*dp2++) {
3762                                 break;
3763                         }
3764                 }
3765                 if (cnt1 == rsp_q->rsp_ring.size / 4) {
3766                         dp = dp2;
3767                         continue;
3768                 }
3769                 mdb_printf("\n\nResponse Queue\nQueue 0%d:", cnt);
3770 
3771                 for (cnt1 = 0; cnt1 < rsp_q->rsp_ring.size / 4; cnt1++) {
3772                         if (cnt1 % 8 == 0) {
3773                                 mdb_printf("\n%08x: ", cnt1);
3774                         }
3775                         mdb_printf("%08x ", *dp++);
3776                 }
3777         }
3778 
3779         if ((ha->cfg_flags & CFG_ENABLE_FWEXTTRACE) &&
3780             (ha->fwexttracebuf.bp != NULL)) {
3781                 uint32_t cnt_b = 0;
3782                 uint32_t *w32 = ha->fwexttracebuf.bp;
3783 
3784                 mdb_printf("\n\nExtended Trace Buffer Memory");
3785                 /* show data address as a byte address, data as long words */
3786                 for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
3787                         cnt_b = cnt * 4;
3788                         if (cnt_b % 32 == 0) {
3789                                 mdb_printf("\n%08x: ", w32 + cnt_b);
3790                         }
3791                         mdb_printf("%08x ", fw->ext_trace_buf[cnt]);
3792                 }
3793         }
3794 
3795         if ((ha->cfg_flags & CFG_ENABLE_FWFCETRACE) &&
3796             (ha->fwfcetracebuf.bp != NULL)) {
3797                 uint32_t cnt_b = 0;
3798                 uint32_t *w32 = ha->fwfcetracebuf.bp;
3799 
3800                 mdb_printf("\n\nFC Event Trace Buffer Memory");
3801                 /* show data address as a byte address, data as long words */
3802                 for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
3803                         cnt_b = cnt * 4;
3804                         if (cnt_b % 32 == 0) {
3805                                 mdb_printf("\n%08x: ", w32 + cnt_b);
3806                         }
3807                         mdb_printf("%08x ", fw->fce_trace_buf[cnt]);
3808                 }
3809         }
3810 
3811         mdb_free(rsp_q, sizeof (ql_response_q_t));
3812         mdb_free(rsp_queues, ha->rsp_queues_cnt * sizeof (ql_response_q_t *));
3813         mdb_free(fw, ha->ql_dump_size);
3814 
3815         mdb_printf("\n\nreturn exit\n");
3816 
3817         return (DCMD_OK);
3818 }
3819 
3820 /*
3821  * ql_gettrace_dcmd
3822  *      prints out the Extended Logging trace buffer
3823  *
3824  * Input:
3825  *      addr  = User supplied address. (NB: must be an ha)
3826  *      flags = mdb flags.
3827  *      argc  = Number of user supplied args.
3828  *      argv  = Arg array.
3829  *
3830  * Returns:
3831  *      DCMD_OK or DCMD_ERR
3832  *
3833  * Context:
3834  *      User context.
3835  *
3836  */
3837 static int
3838 qlc_gettrace_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3839 {
3840         ql_adapter_state_t      *ha;
3841         ql_trace_desc_t         *trace_desc;
3842         ql_trace_entry_t        entry;
3843         uint32_t                i = 0;
3844         char                    merge[1024];
3845 
3846         if ((!(flags & DCMD_ADDRSPEC)) || addr == NULL) {
3847                 mdb_warn("ql_adapter_state structure addr is required");
3848                 return (DCMD_USAGE);
3849         }
3850 
3851         if (argc != 0) {
3852                 return (DCMD_USAGE);
3853         }
3854 
3855         if (mdb_getopts(argc, argv) != argc) {
3856                 return (DCMD_USAGE);
3857         }
3858 
3859         /*
3860          * Get the adapter state struct which was passed
3861          */
3862         if ((ha = (ql_adapter_state_t *)mdb_alloc(sizeof (ql_adapter_state_t),
3863             UM_SLEEP)) == NULL) {
3864                 mdb_warn("failed to allocate memory for ql_adapter_state\n");
3865                 return (DCMD_OK);
3866         }
3867 
3868         if (mdb_vread(ha, sizeof (ql_adapter_state_t), addr) == -1) {
3869                 mdb_warn("failed to read ql_adapter_state at %p", addr);
3870                 mdb_free(ha, sizeof (ql_adapter_state_t));
3871                 return (DCMD_OK);
3872         }
3873 
3874         if (ha->ql_trace_desc == NULL) {
3875                 mdb_warn("trace descriptor does not exist for instance %d\n",
3876                     ha->instance);
3877                 mdb_free(ha, sizeof (ql_adapter_state_t));
3878                 return (DCMD_OK);
3879 
3880         } else {
3881                 trace_desc = (ql_trace_desc_t *)
3882                     mdb_alloc(sizeof (ql_trace_desc_t), UM_SLEEP);
3883 
3884                 if (mdb_vread(trace_desc, sizeof (ql_trace_desc_t),
3885                     (uintptr_t)ha->ql_trace_desc) == -1) {
3886                         mdb_warn("failed to read ql_adapter_state at %p",
3887                             addr);
3888                         mdb_free(trace_desc, sizeof (ql_trace_desc_t));
3889                         mdb_free(ha, sizeof (ql_adapter_state_t));
3890                         return (DCMD_OK);
3891                 }
3892 
3893                 if (trace_desc->trace_buffer == NULL) {
3894                         mdb_warn("trace buffer does not exist for "
3895                             "instance %d\n", ha->instance);
3896 
3897                         mdb_free(trace_desc, sizeof (ql_trace_desc_t));
3898                         mdb_free(ha, sizeof (ql_adapter_state_t));
3899                         return (DCMD_OK);
3900                 }
3901         }
3902 
3903         /* Check if anything logged or not */
3904         if (trace_desc->csize == 0) {
3905                 mdb_warn("Extended log buffer is empty.\n");
3906                 mdb_free(trace_desc, sizeof (ql_trace_desc_t));
3907                 mdb_free(ha, sizeof (ql_adapter_state_t));
3908                 return (DCMD_OK);
3909         }
3910 
3911         /*
3912          * Locate the start and end point. If ever wrapped, then
3913          * always print from start to end in the circular buffer
3914          */
3915 
3916         /* always print from start to end */
3917         for (i = trace_desc->start; i < trace_desc->csize; i++) {
3918                 if (mdb_vread(&entry, sizeof (ql_trace_entry_t),
3919                     (uintptr_t)&trace_desc->trace_buffer[i]) !=
3920                     sizeof (ql_trace_entry_t)) {
3921                         mdb_warn("Cannot read trace entry. %xh", i);
3922                         mdb_free(trace_desc, sizeof (ql_trace_desc_t));
3923                         mdb_free(ha, sizeof (ql_adapter_state_t));
3924                         return (DCMD_ERR);
3925                 }
3926                 if (entry.buf[0] != 0) {
3927                         (void) mdb_snprintf(merge, sizeof (merge),
3928                             "[%Y:%03d:%03d:%03d] "
3929                             "%s",
3930                             entry.hs_time.tv_sec,
3931                             (int)entry.hs_time.tv_nsec / 1000000,
3932                             (int)(entry.hs_time.tv_nsec / 1000) % 1000,
3933                             (int)entry.hs_time.tv_nsec % 1000,
3934                             entry.buf + 1);
3935                 }
3936                 mdb_printf("%s", merge);
3937         }
3938 
3939         if (trace_desc->start != 0) {
3940                 for (i = 0; i < trace_desc->start; i++) {
3941                         if (mdb_vread(&entry, sizeof (ql_trace_entry_t),
3942                             (uintptr_t)&trace_desc->trace_buffer[i]) !=
3943                             sizeof (ql_trace_entry_t)) {
3944                                 mdb_warn("Cannot read trace entry. %xh", i);
3945                                 mdb_free(trace_desc, sizeof (ql_trace_desc_t));
3946                                 mdb_free(ha, sizeof (ql_adapter_state_t));
3947                                 return (DCMD_ERR);
3948                         }
3949                         if (entry.buf[0] != 0) {
3950                                 (void) mdb_snprintf(merge, sizeof (merge),
3951                                     "[%Y:%03d:%03d:%03d] "
3952                                     "%s",
3953                                     entry.hs_time.tv_sec,
3954                                     (int)entry.hs_time.tv_nsec / 1000000,
3955                                     (int)(entry.hs_time.tv_nsec / 1000) % 1000,
3956                                     (int)entry.hs_time.tv_nsec % 1000,
3957                                     entry.buf + 1);
3958                         }
3959                         mdb_printf("%s", merge);
3960                 }
3961         }
3962 
3963         mdb_printf("\n");
3964         mdb_free(trace_desc, sizeof (ql_trace_desc_t));
3965         mdb_free(ha, sizeof (ql_adapter_state_t));
3966         return (DCMD_OK);
3967 }
3968 
3969 /*
3970  * ql_doprint
3971  *      ql generic function to call the print dcmd
3972  *
3973  * Input:
3974  *      addr - address to struct
3975  *      prtsting - address to string
3976  *
3977  * Returns:
3978  *      WALK_DONE
3979  *
3980  * Context:
3981  *      User context.
3982  *
3983  */
3984 static int32_t
3985 ql_doprint(uintptr_t addr, int8_t *prtstring)
3986 {
3987         struct  mdb_arg         printarg;
3988 
3989         printarg.a_un.a_str = (int8_t *)(mdb_zalloc(strlen(prtstring),
3990             UM_SLEEP));
3991         printarg.a_type = MDB_TYPE_STRING;
3992         (void) strcpy((int8_t *)(printarg.a_un.a_str), prtstring);
3993 
3994         if ((mdb_call_dcmd("print", addr, DCMD_ADDRSPEC, 1,
3995             &printarg)) == -1) {
3996                 mdb_warn("ql_doprint: failed print dcmd: %s"
3997                     "at addr: %llxh", prtstring, addr);
3998         }
3999 
4000         mdb_free((void *)(printarg.a_un.a_str), strlen(prtstring));
4001         return (WALK_DONE);
4002 }
4003 
4004 /*
4005  * ql_dump_flags
4006  *      mdb utility to print the flag string
4007  *
4008  * Input:
4009  *      flags - flags to print
4010  *      strings - text to print when flag is set
4011  *
4012  * Returns:
4013  *
4014  *
4015  * Context:
4016  *      User context.
4017  *
4018  */
4019 static void
4020 ql_dump_flags(uint64_t flags, int8_t **strings)
4021 {
4022         int             i, linel, first = 1;
4023         uint64_t        mask = 1;
4024 
4025         linel = 8;
4026         mdb_printf("\t");
4027         for (i = 0; i < 64; i++) {
4028                 if (strings[i] == NULL)
4029                         break;
4030                 if (flags & mask) {
4031                         if (!first) {
4032                                 mdb_printf(" | ");
4033                         } else {
4034                                 first = 0;
4035                         }
4036                         linel += (int32_t)strlen(strings[i]) + 3;
4037                         if (linel > 80) {
4038                                 mdb_printf("\n\t");
4039                                 linel = (int32_t)strlen(strings[i]) + 1 + 8;
4040                         }
4041                         mdb_printf("%s", strings[i]);
4042                 }
4043                 mask <<= 1;
4044         }
4045         mdb_printf("\n");
4046 }
4047 
4048 /*
4049  * MDB module linkage information
4050  *
4051  *
4052  * dcmd structures for the _mdb_init function
4053  */
4054 static const mdb_dcmd_t dcmds[] = {
4055         { "qlclinks", NULL, "Prints qlc link information", qlclinks_dcmd },
4056         { "qlcosc", NULL, "Prints outstanding cmd info", qlc_osc_dcmd },
4057         { "qlcver", NULL, "Prints driver/mdb version", qlcver_dcmd },
4058         { "qlc_elog", "[on|off] [<inst #>|all]", "Turns qlc extended logging "
4059             "on / off", qlc_el_dcmd },
4060         { "qlcstate", ":[-v]", "Prints qlc adapter state information",
4061             qlcstate_dcmd },
4062         { "qlctgtq", NULL, "Prints qlc target queues", qltgtq_dcmd },
4063         { "qlcwdog", NULL, "Prints out watchdog linked list", qlc_wdog_dcmd},
4064         { "qlcgetdump", ":[-v]", "Retrieves the ASCII f/w dump",
4065             qlc_getdump_dcmd },
4066         { "qlcgettrace", ":", "Retrieves the ASCII Extended Logging trace",
4067             qlc_gettrace_dcmd },
4068         { NULL }
4069 };
4070 
4071 /*
4072  * walker structures for the _mdb_init function
4073  */
4074 static const mdb_walker_t walkers[] = {
4075         { "qlcstates", "walk list of qlc ql_state_t structures",
4076             qlstates_walk_init, qlstates_walk_step, qlstates_walk_fini },
4077         { "qlcsrbs", "walk list of qlc ql_srb_t strctures",
4078             qlsrb_walk_init, qlsrb_walk_step, qlsrb_walk_fini },
4079         { "qlclunq", "walk list of qlc ql_lun_t strctures",
4080             qllunq_walk_init, qllunq_walk_step, qllunq_walk_fini },
4081         { NULL }
4082 };
4083 
4084 static const mdb_modinfo_t ql_mdb_modinfo = {
4085         MDB_API_VERSION, dcmds, walkers
4086 };
4087 
4088 /*
4089  * Registration function which lists the dcmds and walker structures
4090  */
4091 const mdb_modinfo_t *
4092 _mdb_init(void)
4093 {
4094         return (&ql_mdb_modinfo);
4095 }