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