Print this page
NEX-5733 cleanup qlt/qlc
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
NEX-5717 import QLogic 16G FC drivers
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-4957 Panic in qlc with QLE2460 in PCI passthrough mode on ESXi
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>

@@ -17,29 +17,29 @@
  * information: Portions Copyright [yyyy] [name of copyright owner]
  *
  * CDDL HEADER END
  */
 
-/* Copyright 2010 QLogic Corporation */
+/* Copyright 2015 QLogic Corporation */
 
 /*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  * Copyright (c) 2016 by Delphix. All rights reserved.
  */
 
-#pragma ident   "Copyright 2010 QLogic Corporation; ql_api.c"
+#pragma ident   "Copyright 2015 QLogic Corporation; ql_api.c"
 
 /*
  * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
  *
  * ***********************************************************************
  * *                                                                    **
  * *                            NOTICE                                  **
- * *            COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION              **
+ * *            COPYRIGHT (C) 1996-2015 QLOGIC CORPORATION              **
  * *                    ALL RIGHTS RESERVED                             **
  * *                                                                    **
  * ***********************************************************************
  *
  */

@@ -52,10 +52,11 @@
 #include <ql_ioctl.h>
 #include <ql_isr.h>
 #include <ql_mbx.h>
 #include <ql_nx.h>
 #include <ql_xioctl.h>
+#include <ql_fm.h>
 
 /*
  * Solaris external defines.
  */
 extern pri_t minclsyspri;

@@ -92,24 +93,13 @@
 static opaque_t ql_get_device(opaque_t, fc_portid_t);
 
 /*
  * FCA Driver Support Function Prototypes.
  */
-static uint16_t ql_wait_outstanding(ql_adapter_state_t *);
-static void ql_task_mgmt(ql_adapter_state_t *, ql_tgt_t *, fc_packet_t *,
-    ql_srb_t *);
-static void ql_task_daemon(void *);
-static void ql_task_thread(ql_adapter_state_t *);
-static void ql_unsol_callback(ql_srb_t *);
-static void ql_free_unsolicited_buffer(ql_adapter_state_t *,
-    fc_unsol_buf_t *);
-static void ql_timer(void *);
-static void ql_watchdog(ql_adapter_state_t *, uint32_t *, uint32_t *);
-static void ql_cmd_timeout(ql_adapter_state_t *, ql_tgt_t *q, ql_srb_t *,
-    uint32_t *, uint32_t *);
-static void ql_halt(ql_adapter_state_t *, int);
+static ql_adapter_state_t *ql_cmd_setup(opaque_t, fc_packet_t *, int *);
 static int ql_els_plogi(ql_adapter_state_t *, fc_packet_t *);
+static int ql_p2p_plogi(ql_adapter_state_t *, fc_packet_t *);
 static int ql_els_flogi(ql_adapter_state_t *, fc_packet_t *);
 static int ql_els_logo(ql_adapter_state_t *, fc_packet_t *);
 static int ql_els_prli(ql_adapter_state_t *, fc_packet_t *);
 static int ql_els_prlo(ql_adapter_state_t *, fc_packet_t *);
 static int ql_els_adisc(ql_adapter_state_t *, fc_packet_t *);

@@ -118,90 +108,156 @@
 static int ql_els_lsts(ql_adapter_state_t *, fc_packet_t *);
 static int ql_els_scr(ql_adapter_state_t *, fc_packet_t *);
 static int ql_els_rscn(ql_adapter_state_t *, fc_packet_t *);
 static int ql_els_farp_req(ql_adapter_state_t *, fc_packet_t *);
 static int ql_els_farp_reply(ql_adapter_state_t *, fc_packet_t *);
-static int ql_els_rls(ql_adapter_state_t *, fc_packet_t *);
 static int ql_els_rnid(ql_adapter_state_t *, fc_packet_t *);
+static int ql_els_rls(ql_adapter_state_t *, fc_packet_t *);
+static int ql_busy_plogi(ql_adapter_state_t *, fc_packet_t *, ql_tgt_t *);
 static int ql_login_port(ql_adapter_state_t *, port_id_t);
 static int ql_login_fabric_port(ql_adapter_state_t *, ql_tgt_t *, uint16_t);
 static int ql_logout_port(ql_adapter_state_t *, port_id_t);
-static ql_lun_t *ql_lun_queue(ql_adapter_state_t *, ql_tgt_t *, uint16_t);
+static ql_lun_t *ql_lun_queue(ql_adapter_state_t *, ql_tgt_t *, uint64_t);
 static int ql_fcp_scsi_cmd(ql_adapter_state_t *, fc_packet_t *, ql_srb_t *);
+static void ql_task_mgmt(ql_adapter_state_t *, ql_tgt_t *, fc_packet_t *,
+    ql_srb_t *);
 static int ql_fcp_ip_cmd(ql_adapter_state_t *, fc_packet_t *, ql_srb_t *);
 static int ql_fc_services(ql_adapter_state_t *, fc_packet_t *);
-static int ql_poll_cmd(ql_adapter_state_t *, ql_srb_t *, time_t);
 static int ql_start_cmd(ql_adapter_state_t *, ql_tgt_t *, fc_packet_t *,
     ql_srb_t *);
-static int ql_kstat_update(kstat_t *, int);
-static ql_adapter_state_t *ql_fca_handle_to_state(opaque_t);
-static ql_adapter_state_t *ql_cmd_setup(opaque_t, fc_packet_t *, int *);
-static int ql_program_flash_address(ql_adapter_state_t *, uint32_t, uint8_t);
-static void ql_rst_aen(ql_adapter_state_t *);
-static void ql_restart_queues(ql_adapter_state_t *);
-static void ql_abort_queues(ql_adapter_state_t *);
-static void ql_abort_device_queues(ql_adapter_state_t *ha, ql_tgt_t *tq);
+static int ql_poll_cmd(ql_adapter_state_t *, ql_srb_t *, time_t);
+static void ql_task_daemon(void *);
+static void ql_task_thread(ql_adapter_state_t *);
 static void ql_idle_check(ql_adapter_state_t *);
-static int ql_loop_resync(ql_adapter_state_t *);
-static size_t ql_24xx_ascii_fw_dump(ql_adapter_state_t *, caddr_t);
-static size_t ql_2581_ascii_fw_dump(ql_adapter_state_t *, caddr_t);
-static int ql_save_config_regs(dev_info_t *);
-static int ql_restore_config_regs(dev_info_t *);
-static int ql_process_rscn(ql_adapter_state_t *, fc_affected_id_t *);
-static int ql_handle_rscn_update(ql_adapter_state_t *);
+static void ql_unsol_callback(ql_srb_t *);
+static int ql_process_logo_for_device(ql_adapter_state_t *, ql_tgt_t *);
 static int ql_send_plogi(ql_adapter_state_t *, ql_tgt_t *, ql_head_t *);
+static void ql_update_rscn(ql_adapter_state_t *, fc_affected_id_t *);
+static int ql_process_rscn(ql_adapter_state_t *, fc_affected_id_t *);
 static int ql_process_rscn_for_device(ql_adapter_state_t *, ql_tgt_t *);
-static int ql_dump_firmware(ql_adapter_state_t *);
-static int ql_process_logo_for_device(ql_adapter_state_t *, ql_tgt_t *);
+static int ql_handle_rscn_update(ql_adapter_state_t *);
+static void ql_free_unsolicited_buffer(ql_adapter_state_t *,
+    fc_unsol_buf_t *);
+static void ql_timer(void *);
+static void ql_timeout_insert(ql_adapter_state_t *, ql_tgt_t *, ql_srb_t *);
+static void ql_watchdog(ql_adapter_state_t *);
+static void ql_wdg_tq_list(ql_adapter_state_t *, ql_tgt_t *);
+static void ql_cmd_timeout(ql_adapter_state_t *, ql_tgt_t *q, ql_srb_t *);
+static uint16_t ql_wait_outstanding(ql_adapter_state_t *);
+static void ql_iidma(ql_adapter_state_t *);
+static void ql_abort_device_queues(ql_adapter_state_t *ha, ql_tgt_t *tq);
+static void ql_loop_resync(ql_adapter_state_t *);
+static ql_adapter_state_t *ql_fca_handle_to_state(opaque_t);
+static int ql_kstat_update(kstat_t *, int);
+static int ql_program_flash_address(ql_adapter_state_t *, uint32_t, uint8_t);
+static size_t ql_24xx_ascii_fw_dump(ql_adapter_state_t *, caddr_t);
+static size_t ql_25xx_ascii_fw_dump(ql_adapter_state_t *, caddr_t);
+static size_t ql_81xx_ascii_fw_dump(ql_adapter_state_t *, caddr_t);
+static size_t ql_8021_ascii_fw_dump(ql_adapter_state_t *, caddr_t);
 static int ql_2200_binary_fw_dump(ql_adapter_state_t *, ql_fw_dump_t *);
 static int ql_2300_binary_fw_dump(ql_adapter_state_t *, ql_fw_dump_t *);
 static int ql_24xx_binary_fw_dump(ql_adapter_state_t *, ql_24xx_fw_dump_t *);
 static int ql_25xx_binary_fw_dump(ql_adapter_state_t *, ql_25xx_fw_dump_t *);
 static int ql_81xx_binary_fw_dump(ql_adapter_state_t *, ql_81xx_fw_dump_t *);
 static int ql_read_risc_ram(ql_adapter_state_t *, uint32_t, uint32_t,
     void *);
 static void *ql_read_regs(ql_adapter_state_t *, void *, void *, uint32_t,
     uint8_t);
-static int ql_busy_plogi(ql_adapter_state_t *, fc_packet_t *, ql_tgt_t *);
-static int ql_suspend_adapter(ql_adapter_state_t *);
-static int ql_bstr_to_dec(char *, uint32_t *, uint32_t);
-static void ql_update_rscn(ql_adapter_state_t *, fc_affected_id_t *);
-int ql_alloc_dma_resouce(ql_adapter_state_t *, dma_mem_t *, int);
+static int ql_save_config_regs(dev_info_t *);
+static int ql_restore_config_regs(dev_info_t *);
+static void ql_halt(ql_adapter_state_t *, int);
 static int ql_bind_dma_buffer(ql_adapter_state_t *, dma_mem_t *, int);
 static void ql_unbind_dma_buffer(ql_adapter_state_t *, dma_mem_t *);
-static void ql_timeout_insert(ql_adapter_state_t *, ql_tgt_t *, ql_srb_t *);
+static int ql_suspend_adapter(ql_adapter_state_t *);
+static int ql_bstr_to_dec(char *, uint32_t *, uint32_t);
 static int ql_setup_interrupts(ql_adapter_state_t *);
 static int ql_setup_msi(ql_adapter_state_t *);
 static int ql_setup_msix(ql_adapter_state_t *);
 static int ql_setup_fixed(ql_adapter_state_t *);
 static void ql_release_intr(ql_adapter_state_t *);
-static void ql_disable_intr(ql_adapter_state_t *);
 static int ql_legacy_intr(ql_adapter_state_t *);
 static int ql_init_mutex(ql_adapter_state_t *);
 static void ql_destroy_mutex(ql_adapter_state_t *);
-static void ql_iidma(ql_adapter_state_t *);
-
-static int ql_n_port_plogi(ql_adapter_state_t *);
-static void ql_fca_isp_els_request(ql_adapter_state_t *, fc_packet_t *,
-    els_descriptor_t *);
+static void ql_fca_isp_els_request(ql_adapter_state_t *, ql_request_q_t *,
+    fc_packet_t *, els_descriptor_t *);
 static void ql_isp_els_request_ctor(els_descriptor_t *,
     els_passthru_entry_t *);
-static int ql_p2p_plogi(ql_adapter_state_t *, fc_packet_t *);
-static int ql_wait_for_td_stop(ql_adapter_state_t *);
-static void ql_process_idc_event(ql_adapter_state_t *);
+static int ql_n_port_plogi(ql_adapter_state_t *);
+static int ql_create_queues(ql_adapter_state_t *);
+static int ql_create_rsp_queue(ql_adapter_state_t *, uint16_t);
+static void ql_delete_queues(ql_adapter_state_t *);
+static int ql_multi_queue_support(ql_adapter_state_t *);
+static int ql_map_mem_bar(ql_adapter_state_t *, ddi_acc_handle_t *, caddr_t *,
+    uint32_t, uint32_t);
+static void ql_completion_thread(void *);
+static void ql_process_comp_queue(void *);
+static int ql_abort_io(ql_adapter_state_t *vha, ql_srb_t *);
+static void ql_idc(ql_adapter_state_t *);
+static int ql_83xx_binary_fw_dump(ql_adapter_state_t *, ql_83xx_fw_dump_t *);
+static size_t ql_83xx_ascii_fw_dump(ql_adapter_state_t *, caddr_t);
+static caddr_t ql_str_ptr(ql_adapter_state_t *, caddr_t, uint32_t *);
+static int ql_27xx_binary_fw_dump(ql_adapter_state_t *);
+static size_t ql_27xx_ascii_fw_dump(ql_adapter_state_t *, caddr_t);
+static uint32_t ql_2700_dmp_parse_template(ql_adapter_state_t *, ql_dt_hdr_t *,
+    uint8_t *, uint32_t);
+static int ql_2700_dt_riob1(ql_adapter_state_t *, ql_dt_riob1_t *, uint8_t *,
+    uint8_t *);
+static void ql_2700_dt_wiob1(ql_adapter_state_t *, ql_dt_wiob1_t *, uint8_t *,
+    uint8_t *);
+static int ql_2700_dt_riob2(ql_adapter_state_t *, ql_dt_riob2_t *, uint8_t *,
+    uint8_t *);
+static void ql_2700_dt_wiob2(ql_adapter_state_t *, ql_dt_wiob2_t *, uint8_t *,
+    uint8_t *);
+static int ql_2700_dt_rpci(ql_adapter_state_t *, ql_dt_rpci_t *, uint8_t *,
+    uint8_t *);
+static void ql_2700_dt_wpci(ql_adapter_state_t *, ql_dt_wpci_t *, uint8_t *,
+    uint8_t *);
+static int ql_2700_dt_rram(ql_adapter_state_t *, ql_dt_rram_t *, uint8_t *,
+    uint8_t *);
+static int ql_2700_dt_gque(ql_adapter_state_t *, ql_dt_gque_t *, uint8_t *,
+    uint8_t *);
+static int ql_2700_dt_gfce(ql_adapter_state_t *, ql_dt_gfce_t *, uint8_t *,
+    uint8_t *);
+static void ql_2700_dt_prisc(ql_adapter_state_t *, ql_dt_prisc_t *, uint8_t *,
+    uint8_t *);
+static void ql_2700_dt_rrisc(ql_adapter_state_t *, ql_dt_rrisc_t *, uint8_t *,
+    uint8_t *);
+static void ql_2700_dt_dint(ql_adapter_state_t *, ql_dt_dint_t *, uint8_t *,
+    uint8_t *);
+static int ql_2700_dt_ghbd(ql_adapter_state_t *, ql_dt_ghbd_t *, uint8_t *,
+    uint8_t *);
+static int ql_2700_dt_scra(ql_adapter_state_t *, ql_dt_scra_t *, uint8_t *,
+    uint8_t *);
+static int ql_2700_dt_rrreg(ql_adapter_state_t *, ql_dt_rrreg_t *, uint8_t *,
+    uint8_t *);
+static void ql_2700_dt_wrreg(ql_adapter_state_t *, ql_dt_wrreg_t *, uint8_t *,
+    uint8_t *);
+static int ql_2700_dt_rrram(ql_adapter_state_t *, ql_dt_rrram_t *, uint8_t *,
+    uint8_t *);
+static int ql_2700_dt_rpcic(ql_adapter_state_t *, ql_dt_rpcic_t *, uint8_t *,
+    uint8_t *);
+static int ql_2700_dt_gques(ql_adapter_state_t *, ql_dt_gques_t *, uint8_t *,
+    uint8_t *);
+static int ql_2700_dt_wdmp(ql_adapter_state_t *, ql_dt_wdmp_t *, uint8_t *,
+    uint8_t *);
+static int ql_2700_dump_ram(ql_adapter_state_t *, uint16_t, uint32_t, uint32_t,
+    uint8_t *);
 
 /*
  * Global data
  */
 static uint8_t  ql_enable_pm = 1;
 static int      ql_flash_sbus_fpga = 0;
 uint32_t        ql_os_release_level;
 uint32_t        ql_disable_aif = 0;
+uint32_t        ql_disable_intx = 0;
 uint32_t        ql_disable_msi = 0;
 uint32_t        ql_disable_msix = 0;
 uint32_t        ql_enable_ets = 0;
 uint16_t        ql_osc_wait_count = 1000;
+uint32_t        ql_task_cb_dly = 64;
+uint32_t        qlc_disable_load = 0;
 
 /* Timer routine variables. */
 static timeout_id_t     ql_timer_timeout_id = NULL;
 static clock_t          ql_timer_ticks;
 

@@ -452,24 +508,70 @@
         0x54,   /* io_base_addr */
         0x380,  /* nx_host_int */
         0x504   /* nx_risc_int */
 };
 
+/* 2700/8300 register offsets */
+static reg_off_t reg_off_2700_8300 = {
+        0x00,   /* flash_address */
+        0x04,   /* flash_data */
+        0x08,   /* ctrl_status */
+        0x0c,   /* ictrl */
+        0x10,   /* istatus */
+        0xff,   /* semaphore - n/a */
+        0xff,   /* nvram - n/a */
+        0xff,   /* req_in - n/a */
+        0xff,   /* req_out - n/a */
+        0xff,   /* resp_in - n/a */
+        0xff,   /* resp_out - n/a */
+        0x44,   /* risc2host */
+        32,     /* Number of mailboxes */
+
+        /* Mailbox in register offsets 0 - 31 */
+        0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e,
+        0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
+        0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae,
+        0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
+
+        /* Mailbox out register offsets 0 - 31 */
+        0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e,
+        0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
+        0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae,
+        0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
+
+        0xff,   /* fpm_diag_config - n/a */
+        0xff,   /* pcr - n/a */
+        0xff,   /* mctr - n/a */
+        0xff,   /* fb_cmd - n/a */
+        0x48,   /* hccr */
+        0x4c,   /* gpiod */
+        0x50,   /* gpioe */
+        0x58,   /* host_to_host_sema - n/a */
+        0xff,   /* pri_req_in - n/a */
+        0xff,   /* pri_req_out - n/a */
+        0xff,   /* atio_req_in - n/a */
+        0xff,   /* atio_req_out - n/a */
+        0x54,   /* io_base_addr */
+        0xff,   /* nx_host_int - n/a */
+        0xff    /* nx_risc_int - n/a */
+};
+
 /* mutex for protecting variables shared by all instances of the driver */
 kmutex_t ql_global_mutex;
 kmutex_t ql_global_hw_mutex;
 kmutex_t ql_global_el_mutex;
+kmutex_t ql_global_timer_mutex;
 
 /* DMA access attribute structure. */
-static ddi_device_acc_attr_t ql_dev_acc_attr = {
+ddi_device_acc_attr_t ql_dev_acc_attr = {
         DDI_DEVICE_ATTR_V0,
         DDI_STRUCTURE_LE_ACC,
         DDI_STRICTORDER_ACC
 };
 
 /* I/O DMA attributes structures. */
-static ddi_dma_attr_t ql_64bit_io_dma_attr = {
+ddi_dma_attr_t ql_64bit_io_dma_attr = {
         DMA_ATTR_V0,                    /* dma_attr_version */
         QL_DMA_LOW_ADDRESS,             /* low DMA address range */
         QL_DMA_HIGH_64BIT_ADDRESS,      /* high DMA address range */
         QL_DMA_XFER_COUNTER,            /* DMA counter register */
         QL_DMA_ADDRESS_ALIGNMENT,       /* DMA address alignment */

@@ -480,11 +582,11 @@
         QL_DMA_SG_LIST_LENGTH,          /* s/g list length */
         QL_DMA_GRANULARITY,             /* granularity of device */
         QL_DMA_XFER_FLAGS               /* DMA transfer flags */
 };
 
-static ddi_dma_attr_t ql_32bit_io_dma_attr = {
+ddi_dma_attr_t ql_32bit_io_dma_attr = {
         DMA_ATTR_V0,                    /* dma_attr_version */
         QL_DMA_LOW_ADDRESS,             /* low DMA address range */
         QL_DMA_HIGH_32BIT_ADDRESS,      /* high DMA address range */
         QL_DMA_XFER_COUNTER,            /* DMA counter register */
         QL_DMA_ADDRESS_ALIGNMENT,       /* DMA address alignment */

@@ -495,26 +597,10 @@
         QL_DMA_SG_LIST_LENGTH,          /* s/g list length */
         QL_DMA_GRANULARITY,             /* granularity of device */
         QL_DMA_XFER_FLAGS               /* DMA transfer flags */
 };
 
-/* Load the default dma attributes */
-static  ddi_dma_attr_t  ql_32fcsm_cmd_dma_attr;
-static  ddi_dma_attr_t  ql_64fcsm_cmd_dma_attr;
-static  ddi_dma_attr_t  ql_32fcsm_rsp_dma_attr;
-static  ddi_dma_attr_t  ql_64fcsm_rsp_dma_attr;
-static  ddi_dma_attr_t  ql_32fcip_cmd_dma_attr;
-static  ddi_dma_attr_t  ql_64fcip_cmd_dma_attr;
-static  ddi_dma_attr_t  ql_32fcip_rsp_dma_attr;
-static  ddi_dma_attr_t  ql_64fcip_rsp_dma_attr;
-static  ddi_dma_attr_t  ql_32fcp_cmd_dma_attr;
-static  ddi_dma_attr_t  ql_64fcp_cmd_dma_attr;
-static  ddi_dma_attr_t  ql_32fcp_rsp_dma_attr;
-static  ddi_dma_attr_t  ql_64fcp_rsp_dma_attr;
-static  ddi_dma_attr_t  ql_32fcp_data_dma_attr;
-static  ddi_dma_attr_t  ql_64fcp_data_dma_attr;
-
 /* Static declarations of cb_ops entry point functions... */
 static struct cb_ops ql_cb_ops = {
         ql_open,                        /* b/c open */
         ql_close,                       /* b/c close */
         nodev,                          /* b strategy */

@@ -554,12 +640,14 @@
 /* ELS command code to text converter */
 cmd_table_t els_cmd_tbl[] = ELS_CMD_TABLE();
 /* Mailbox command code to text converter */
 cmd_table_t mbox_cmd_tbl[] = MBOX_CMD_TABLE();
 
-char qlc_driver_version[] = QL_VERSION;
+char ql_driver_version[] = QL_VERSION;
 
+uint32_t ql_log_entries = QL_LOG_ENTRIES;
+
 /*
  * Loadable Driver Interface Structures.
  * Declare and initialize the module configuration section...
  */
 static struct modldrv modldrv = {

@@ -593,10 +681,15 @@
 _init(void)
 {
         uint16_t        w16;
         int             rval = 0;
 
+        if (qlc_disable_load) {
+                cmn_err(CE_WARN, "%s load disabled", QL_NAME);
+                return (EINVAL);
+        }
+
         /* Get OS major release level. */
         for (w16 = 0; w16 < sizeof (utsname.release); w16++) {
                 if (utsname.release[w16] == '.') {
                         w16++;
                         break;

@@ -627,50 +720,18 @@
                 fc_fca_init(&ql_devops);
 
                 mutex_init(&ql_global_mutex, NULL, MUTEX_DRIVER, NULL);
                 mutex_init(&ql_global_hw_mutex, NULL, MUTEX_DRIVER, NULL);
                 mutex_init(&ql_global_el_mutex, NULL, MUTEX_DRIVER, NULL);
+                mutex_init(&ql_global_timer_mutex, NULL, MUTEX_DRIVER, NULL);
                 rval = mod_install(&modlinkage);
                 if (rval != 0) {
+                        mutex_destroy(&ql_global_timer_mutex);
+                        mutex_destroy(&ql_global_el_mutex);
                         mutex_destroy(&ql_global_hw_mutex);
                         mutex_destroy(&ql_global_mutex);
-                        mutex_destroy(&ql_global_el_mutex);
                         ddi_soft_state_fini(&ql_state);
-                } else {
-                        /*EMPTY*/
-                        ql_32fcsm_cmd_dma_attr = ql_32bit_io_dma_attr;
-                        ql_64fcsm_cmd_dma_attr = ql_64bit_io_dma_attr;
-                        ql_32fcsm_rsp_dma_attr = ql_32bit_io_dma_attr;
-                        ql_64fcsm_rsp_dma_attr = ql_64bit_io_dma_attr;
-                        ql_32fcip_cmd_dma_attr = ql_32bit_io_dma_attr;
-                        ql_64fcip_cmd_dma_attr = ql_64bit_io_dma_attr;
-                        ql_32fcip_rsp_dma_attr = ql_32bit_io_dma_attr;
-                        ql_64fcip_rsp_dma_attr = ql_64bit_io_dma_attr;
-                        ql_32fcp_cmd_dma_attr = ql_32bit_io_dma_attr;
-                        ql_64fcp_cmd_dma_attr = ql_64bit_io_dma_attr;
-                        ql_32fcp_rsp_dma_attr = ql_32bit_io_dma_attr;
-                        ql_64fcp_rsp_dma_attr = ql_64bit_io_dma_attr;
-                        ql_32fcp_data_dma_attr = ql_32bit_io_dma_attr;
-                        ql_64fcp_data_dma_attr = ql_64bit_io_dma_attr;
-                        ql_32fcsm_cmd_dma_attr.dma_attr_sgllen =
-                            ql_64fcsm_cmd_dma_attr.dma_attr_sgllen =
-                            QL_FCSM_CMD_SGLLEN;
-                        ql_32fcsm_rsp_dma_attr.dma_attr_sgllen =
-                            ql_64fcsm_rsp_dma_attr.dma_attr_sgllen =
-                            QL_FCSM_RSP_SGLLEN;
-                        ql_32fcip_cmd_dma_attr.dma_attr_sgllen =
-                            ql_64fcip_cmd_dma_attr.dma_attr_sgllen =
-                            QL_FCIP_CMD_SGLLEN;
-                        ql_32fcip_rsp_dma_attr.dma_attr_sgllen =
-                            ql_64fcip_rsp_dma_attr.dma_attr_sgllen =
-                            QL_FCIP_RSP_SGLLEN;
-                        ql_32fcp_cmd_dma_attr.dma_attr_sgllen =
-                            ql_64fcp_cmd_dma_attr.dma_attr_sgllen =
-                            QL_FCP_CMD_SGLLEN;
-                        ql_32fcp_rsp_dma_attr.dma_attr_sgllen =
-                            ql_64fcp_rsp_dma_attr.dma_attr_sgllen =
-                            QL_FCP_RSP_SGLLEN;
                 }
         }
 
         if (rval != 0) {
                 cmn_err(CE_CONT, "?Unable to install/attach driver '%s'",

@@ -699,13 +760,14 @@
 {
         int     rval;
 
         rval = mod_remove(&modlinkage);
         if (rval == 0) {
+                mutex_destroy(&ql_global_timer_mutex);
+                mutex_destroy(&ql_global_el_mutex);
                 mutex_destroy(&ql_global_hw_mutex);
                 mutex_destroy(&ql_global_mutex);
-                mutex_destroy(&ql_global_el_mutex);
                 ddi_soft_state_fini(&ql_state);
         }
 
         return (rval);
 }

@@ -761,17 +823,17 @@
         int                     rval = DDI_FAILURE;
 
         minor = (int)(getminor((dev_t)arg));
         ha = ddi_get_soft_state(ql_state, minor);
         if (ha == NULL) {
-                QL_PRINT_2(CE_CONT, "failed, unknown minor=%d\n",
+                QL_PRINT_2(ha, "failed, unknown minor=%d\n",
                     getminor((dev_t)arg));
                 *resultp = NULL;
                 return (rval);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         switch (cmd) {
         case DDI_INFO_DEVT2DEVINFO:
                 *resultp = ha->dip;
                 rval = DDI_SUCCESS;

@@ -784,11 +846,11 @@
                 EL(ha, "failed, unsupported cmd=%d\n", cmd);
                 rval = DDI_FAILURE;
                 break;
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (rval);
 }
 
 /*

@@ -810,33 +872,30 @@
 ql_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
 {
         off_t                   regsize;
         uint32_t                size;
         int                     rval, *ptr;
-        int                     instance;
         uint_t                  progress = 0;
-        char                    *buf;
+        char                    *buf, taskq_name[32];
         ushort_t                caps_ptr, cap;
         fc_fca_tran_t           *tran;
         ql_adapter_state_t      *ha = NULL;
+        int                     instance = ddi_get_instance(dip);
 
         static char *pmcomps[] = {
                 NULL,
                 PM_LEVEL_D3_STR,                /* Device OFF */
                 PM_LEVEL_D0_STR,                /* Device ON */
         };
 
-        QL_PRINT_3(CE_CONT, "(%d): started, cmd=%xh\n",
+        QL_PRINT_3(NULL, "started, instance=%d, cmd=%xh\n",
             ddi_get_instance(dip), cmd);
 
         buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP));
 
         switch (cmd) {
         case DDI_ATTACH:
-                /* first get the instance */
-                instance = ddi_get_instance(dip);
-
                 cmn_err(CE_CONT, "!Qlogic %s(%d) FCA Driver v%s\n",
                     QL_NAME, instance, QL_VERSION);
 
                 /* Correct OS version? */
                 if (ql_os_release_level != 11) {

@@ -850,25 +909,17 @@
                         cmn_err(CE_WARN, "%s(%d): slave only", QL_NAME,
                             instance);
                         goto attach_failed;
                 }
 
-                /* No support for high-level interrupts */
-                if (ddi_intr_hilevel(dip, 0) != 0) {
-                        cmn_err(CE_WARN, "%s(%d): High level interrupt"
-                            " not supported", QL_NAME, instance);
-                        goto attach_failed;
-                }
-
                 /* Allocate our per-device-instance structure */
                 if (ddi_soft_state_zalloc(ql_state,
                     instance) != DDI_SUCCESS) {
                         cmn_err(CE_WARN, "%s(%d): soft state alloc failed",
                             QL_NAME, instance);
                         goto attach_failed;
                 }
-                progress |= QL_SOFT_STATE_ALLOCED;
 
                 ha = ddi_get_soft_state(ql_state, instance);
                 if (ha == NULL) {
                         cmn_err(CE_WARN, "%s(%d): can't get soft state",
                             QL_NAME, instance);

@@ -877,40 +928,42 @@
                 ha->dip = dip;
                 ha->instance = instance;
                 ha->hba.base_address = ha;
                 ha->pha = ha;
 
-                if (ql_el_trace_desc_ctor(ha) != DDI_SUCCESS) {
-                        cmn_err(CE_WARN, "%s(%d): can't setup el tracing",
-                            QL_NAME, instance);
-                        goto attach_failed;
-                }
+                ha->bit32_io_dma_attr = ql_32bit_io_dma_attr;
+                ha->bit64_io_dma_attr = ql_64bit_io_dma_attr;
 
+                (void) ql_el_trace_alloc(ha);
+
+                progress |= QL_SOFT_STATE_ALLOCED;
+
                 /* Get extended logging and dump flags. */
                 ql_common_properties(ha);
 
+                qlc_fm_init(ha);
+                progress |= QL_FCA_INIT_FM;
+
+                ha->io_dma_attr = ha->bit32_io_dma_attr;
+
                 if (strcmp(ddi_driver_name(ddi_get_parent(dip)),
                     "sbus") == 0) {
-                        EL(ha, "%s SBUS card detected", QL_NAME);
+                        EL(ha, "%s SBUS card detected\n", QL_NAME);
                         ha->cfg_flags |= CFG_SBUS_CARD;
                 }
 
                 ha->dev = kmem_zalloc(sizeof (*ha->dev) *
                     DEVICE_HEAD_LIST_SIZE, KM_SLEEP);
 
-                ha->outstanding_cmds = kmem_zalloc(
-                    sizeof (*ha->outstanding_cmds) * MAX_OUTSTANDING_COMMANDS,
-                    KM_SLEEP);
-
                 ha->ub_array = kmem_zalloc(sizeof (*ha->ub_array) *
                     QL_UB_LIMIT, KM_SLEEP);
 
                 ha->adapter_stats = kmem_zalloc(sizeof (*ha->adapter_stats),
                     KM_SLEEP);
 
                 (void) ddi_pathname(dip, buf);
-                ha->devpath = kmem_zalloc(strlen(buf)+1, KM_SLEEP);
+                ha->devpath = kmem_zalloc(strlen(buf) + 1, KM_SLEEP);
                 if (ha->devpath == NULL) {
                         EL(ha, "devpath mem alloc failed\n");
                 } else {
                         (void) strcpy(ha->devpath, buf);
                         EL(ha, "devpath is: %s\n", ha->devpath);

@@ -966,11 +1019,11 @@
                                 cmn_err(CE_WARN, "%s(%d): Unable to get PCI "
                                     "address registers", QL_NAME, instance);
                                 goto attach_failed;
                         } else {
                                 ha->pci_bus_addr = ptr[0];
-                                ha->function_number = (uint8_t)
+                                ha->pci_function_number = (uint8_t)
                                     (ha->pci_bus_addr >> 8 & 7);
                                 ddi_prop_free(ptr);
                         }
 
                         /*

@@ -995,10 +1048,18 @@
                          * 0x2   32-bit Memory Space address
                          * 0x3   64-bit Memory Space address
                          */
                         size = ql_pci_config_get32(ha, PCI_CONF_BASE0) & BIT_0 ?
                             2 : 1;
+
+                        if (qlc_fm_check_acc_handle(ha, ha->pci_handle)
+                            != DDI_FM_OK) {
+                                qlc_fm_report_err_impact(ha,
+                                    QL_FM_EREPORT_ACC_HANDLE_CHECK);
+                                goto attach_failed;
+                        }
+
                         if (ddi_dev_regsize(dip, size, &regsize) !=
                             DDI_SUCCESS ||
                             ddi_regs_map_setup(dip, size, &ha->iobase,
                             0, regsize, &ql_dev_acc_attr, &ha->dev_handle) !=
                             DDI_SUCCESS) {

@@ -1006,10 +1067,17 @@
                                     "failed", QL_NAME, instance);
                                 goto attach_failed;
                         }
                         progress |= QL_REGS_MAPPED;
 
+                        if (qlc_fm_check_acc_handle(ha, ha->dev_handle)
+                            != DDI_FM_OK) {
+                                qlc_fm_report_err_impact(ha,
+                                    QL_FM_EREPORT_ACC_HANDLE_CHECK);
+                                goto attach_failed;
+                        }
+
                         /*
                          * We need I/O space mappings for 23xx HBAs for
                          * loading flash (FCode). The chip has a bug due to
                          * which loading flash fails through mem space
                          * mappings in PCI-X mode.

@@ -1028,12 +1096,19 @@
                                             "setup(I/O) failed", QL_NAME,
                                             instance);
                                         goto attach_failed;
                                 }
                                 progress |= QL_IOMAP_IOBASE_MAPPED;
+
+                                if (qlc_fm_check_acc_handle(ha,
+                                    ha->iomap_dev_handle) != DDI_FM_OK) {
+                                        qlc_fm_report_err_impact(ha,
+                                            QL_FM_EREPORT_ACC_HANDLE_CHECK);
+                                        goto attach_failed;
                         }
                 }
+                }
 
                 ha->subsys_id = (uint16_t)ql_pci_config_get16(ha,
                     PCI_CONF_SUBSYSID);
                 ha->subven_id = (uint16_t)ql_pci_config_get16(ha,
                     PCI_CONF_SUBVENID);

@@ -1053,23 +1128,25 @@
                 case 0x2312:
                 case 0x2322:
                 case 0x6312:
                 case 0x6322:
                         if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 2) {
-                                ha->flags |= FUNCTION_1;
+                                ha->function_number = 1;
                         }
-                        if ((ha->device_id == 0x6322) ||
-                            (ha->device_id == 0x2322)) {
-                                ha->cfg_flags |= CFG_CTRL_6322;
+                        if (ha->device_id == 0x2322 ||
+                            ha->device_id == 0x6322) {
+                                ha->cfg_flags |= CFG_CTRL_63XX;
                                 ha->fw_class = 0x6322;
                                 ha->risc_dump_size = QL_6322_FW_DUMP_SIZE;
                         } else {
-                                ha->cfg_flags |= CFG_CTRL_2300;
+                                ha->cfg_flags |= CFG_CTRL_23XX;
                                 ha->fw_class = 0x2300;
                                 ha->risc_dump_size = QL_2300_FW_DUMP_SIZE;
                         }
                         ha->reg_off = &reg_off_2300;
+                        ha->interrupt_count = 1;
+                        ha->osc_max_cnt = 1024;
                         if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
                                 goto attach_failed;
                         }
                         ha->fcp_cmd = ql_command_iocb;
                         ha->ip_cmd = ql_ip_iocb;

@@ -1082,12 +1159,14 @@
                                 ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
                         }
                         break;
 
                 case 0x2200:
-                        ha->cfg_flags |= CFG_CTRL_2200;
+                        ha->cfg_flags |= CFG_CTRL_22XX;
                         ha->reg_off = &reg_off_2200;
+                        ha->interrupt_count = 1;
+                        ha->osc_max_cnt = 1024;
                         ha->fw_class = 0x2200;
                         if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
                                 goto attach_failed;
                         }
                         ha->risc_dump_size = QL_2200_FW_DUMP_SIZE;

@@ -1107,20 +1186,23 @@
                 case 0x2432:
                 case 0x5422:
                 case 0x5432:
                 case 0x8432:
                         if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 2) {
-                                ha->flags |= FUNCTION_1;
+                                ha->function_number = 1;
                         }
-                        ha->cfg_flags |= CFG_CTRL_2422;
+                        ha->cfg_flags |= CFG_CTRL_24XX;
                         if (ha->device_id == 0x8432) {
                                 ha->cfg_flags |= CFG_CTRL_MENLO;
                         } else {
                                 ha->flags |= VP_ENABLED;
+                                ha->max_vports = MAX_24_VIRTUAL_PORTS;
                         }
 
                         ha->reg_off = &reg_off_2400_2500;
+                        ha->interrupt_count = 2;
+                        ha->osc_max_cnt = 2048;
                         ha->fw_class = 0x2400;
                         if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
                                 goto attach_failed;
                         }
                         ha->risc_dump_size = QL_24XX_FW_DUMP_SIZE;

@@ -1133,79 +1215,175 @@
                         break;
 
                 case 0x2522:
                 case 0x2532:
                         if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 2) {
-                                ha->flags |= FUNCTION_1;
+                                ha->function_number = 1;
                         }
                         ha->cfg_flags |= CFG_CTRL_25XX;
                         ha->flags |= VP_ENABLED;
-                        ha->fw_class = 0x2500;
+                        ha->max_vports = MAX_25_VIRTUAL_PORTS;
                         ha->reg_off = &reg_off_2400_2500;
+                        ha->mbar_queue_offset = MBAR2_REG_OFFSET;
+                        ha->interrupt_count = 2;
+                        ha->osc_max_cnt = 2048;
+                        ha->fw_class = 0x2500;
                         if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
                                 goto attach_failed;
                         }
                         ha->risc_dump_size = QL_25XX_FW_DUMP_SIZE;
                         ha->fcp_cmd = ql_command_24xx_iocb;
-                        ha->ip_cmd = ql_ip_24xx_iocb;
                         ha->ms_cmd = ql_ms_24xx_iocb;
                         ha->els_cmd = ql_els_24xx_iocb;
                         ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS;
                         ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
+                        if (ql_multi_queue_support(ha) == QL_SUCCESS) {
+                                ha->flags |= MULTI_QUEUE;
+                        }
                         break;
 
+                case 0x2031:
+                        /* Get queue pointer memory mapped registers */
+                        if (ddi_dev_regsize(dip, 3, &regsize) != DDI_SUCCESS ||
+                            ddi_regs_map_setup(dip, 3, &ha->mbar,
+                            0, regsize, &ql_dev_acc_attr,
+                            &ha->mbar_dev_handle) != DDI_SUCCESS) {
+                                cmn_err(CE_WARN, "%s(%d): regs_map_setup"
+                                    "(mbar) failed", QL_NAME, instance);
+                                goto attach_failed;
+                        }
+                        ha->mbar_size = (uint32_t)regsize;
+
+                        if (ha->pci_function_number != 0 &&
+                            ha->pci_function_number != 2) {
+                                ha->function_number = 1;
+                        }
+                        ha->cfg_flags |= CFG_CTRL_83XX;
+                        ha->flags |= VP_ENABLED | MULTI_QUEUE;
+                        ha->max_vports = MAX_83_VIRTUAL_PORTS;
+                        ha->reg_off = &reg_off_2700_8300;
+                        ha->mbar_queue_offset = MBAR2_REG_OFFSET;
+                        ha->interrupt_count = 2;
+                        ha->osc_max_cnt = 2048;
+                        ha->fw_class = 0x8301fc;
+                        if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
+                                goto attach_failed;
+                        }
+                        ha->risc_dump_size = QL_83XX_FW_DUMP_SIZE;
+                        ha->fcp_cmd = ql_command_24xx_iocb;
+                        ha->ms_cmd = ql_ms_24xx_iocb;
+                        ha->els_cmd = ql_els_24xx_iocb;
+                        ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS;
+                        ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
+                        break;
+
+                case 0x2071:
+                case 0x2261:
+                case 0x2271:
+                        /* Get queue pointer memory mapped registers */
+                        if (ddi_dev_regsize(dip, 3, &regsize) != DDI_SUCCESS ||
+                            ddi_regs_map_setup(dip, 3, &ha->mbar,
+                            0, regsize, &ql_dev_acc_attr,
+                            &ha->mbar_dev_handle) != DDI_SUCCESS) {
+                                cmn_err(CE_WARN, "%s(%d): regs_map_setup"
+                                    "(mbar) failed", QL_NAME, instance);
+                                goto attach_failed;
+                        }
+                        ha->mbar_size = (uint32_t)regsize;
+
+                        ha->function_number = ha->pci_function_number;
+                        ha->cfg_flags |= CFG_CTRL_27XX;
+                        ha->flags |= VP_ENABLED | MULTI_QUEUE |
+                            QUEUE_SHADOW_PTRS;
+                        ha->max_vports = MAX_27_VIRTUAL_PORTS;
+                        ha->reg_off = &reg_off_2700_8300;
+                        ha->mbar_queue_offset = MBAR2_REG_OFFSET;
+                        ha->interrupt_count = 2;
+                        ha->osc_max_cnt = 2048;
+                        ha->fw_class = 0x2700;
+                        if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
+                                goto attach_failed;
+                        }
+                        ha->risc_dump_size = QL_27XX_FW_DUMP_SIZE;
+                        ha->fcp_cmd = ql_command_24xx_iocb;
+                        ha->ms_cmd = ql_ms_24xx_iocb;
+                        ha->els_cmd = ql_els_24xx_iocb;
+                        ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS;
+                        ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
+                        break;
+
                 case 0x8001:
                         if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 4) {
-                                ha->flags |= FUNCTION_1;
+                                ha->function_number = 1;
                         }
                         ha->cfg_flags |= CFG_CTRL_81XX;
                         ha->flags |= VP_ENABLED;
-                        ha->fw_class = 0x8100;
+                        ha->max_vports = MAX_81XX_VIRTUAL_PORTS;
                         ha->reg_off = &reg_off_2400_2500;
+                        ha->mbar_queue_offset = MBAR2_REG_OFFSET;
+                        ha->interrupt_count = 2;
+                        ha->osc_max_cnt = 2048;
+                        ha->fw_class = 0x8100;
                         if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
                                 goto attach_failed;
                         }
-                        ha->risc_dump_size = QL_25XX_FW_DUMP_SIZE;
+                        ha->risc_dump_size = QL_81XX_FW_DUMP_SIZE;
                         ha->fcp_cmd = ql_command_24xx_iocb;
-                        ha->ip_cmd = ql_ip_24xx_iocb;
                         ha->ms_cmd = ql_ms_24xx_iocb;
                         ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS;
                         ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
+                        if (ql_multi_queue_support(ha) == QL_SUCCESS) {
+                                ha->flags |= MULTI_QUEUE;
+                        }
                         break;
 
                 case 0x8021:
-                        if (ha->function_number & BIT_0) {
-                                ha->flags |= FUNCTION_1;
+                        if (ha->pci_function_number & BIT_0) {
+                                ha->function_number = 1;
                         }
-                        ha->cfg_flags |= CFG_CTRL_8021;
+                        ha->cfg_flags |= CFG_CTRL_82XX;
+                        ha->flags |= VP_ENABLED;
+                        ha->max_vports = MAX_8021_VIRTUAL_PORTS;
                         ha->reg_off = &reg_off_8021;
+                        ha->interrupt_count = 2;
+                        ha->osc_max_cnt = 2048;
                         ha->risc_dump_size = QL_25XX_FW_DUMP_SIZE;
                         ha->fcp_cmd = ql_command_24xx_iocb;
                         ha->ms_cmd = ql_ms_24xx_iocb;
                         ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS;
                         ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
+                        ha->io_dma_attr.dma_attr_flags |=
+                            DDI_DMA_RELAXED_ORDERING;
 
                         ha->nx_pcibase = ha->iobase;
-                        ha->iobase += 0xBC000 + (ha->function_number << 11);
+                        ha->iobase += 0xBC000 + (ha->pci_function_number << 11);
                         ha->iomap_iobase += 0xBC000 +
-                            (ha->function_number << 11);
+                            (ha->pci_function_number << 11);
 
                         /* map doorbell */
                         if (ddi_dev_regsize(dip, 2, &regsize) != DDI_SUCCESS ||
                             ddi_regs_map_setup(dip, 2, &ha->db_iobase,
-                            0, regsize, &ql_dev_acc_attr, &ha->db_dev_handle) !=
+                            0, regsize, &ql_dev_acc_attr,
+                            &ha->db_dev_handle) !=
                             DDI_SUCCESS) {
                                 cmn_err(CE_WARN, "%s(%d): regs_map_setup"
                                     "(doorbell) failed", QL_NAME, instance);
                                 goto attach_failed;
                         }
                         progress |= QL_DB_IOBASE_MAPPED;
 
+                        if (qlc_fm_check_acc_handle(ha, ha->db_dev_handle)
+                            != DDI_FM_OK) {
+                                qlc_fm_report_err_impact(ha,
+                                    QL_FM_EREPORT_ACC_HANDLE_CHECK);
+                                goto attach_failed;
+                        }
+
                         ha->nx_req_in = (uint32_t *)(ha->db_iobase +
-                            (ha->function_number << 12));
+                            (ha->pci_function_number << 12));
                         ha->db_read = ha->nx_pcibase + (512 * 1024) +
-                            (ha->function_number * 8);
+                            (ha->pci_function_number * 8);
 
                         ql_8021_update_crb_int_ptr(ha);
                         ql_8021_set_drv_active(ha);
                         break;
 

@@ -1213,59 +1391,51 @@
                         cmn_err(CE_WARN, "%s(%d): Unsupported device id: %x",
                             QL_NAME, instance, ha->device_id);
                         goto attach_failed;
                 }
 
-                /* Setup hba buffer. */
+                ha->outstanding_cmds = kmem_zalloc(
+                    sizeof (*ha->outstanding_cmds) * ha->osc_max_cnt,
+                    KM_SLEEP);
 
-                size = CFG_IST(ha, CFG_CTRL_24258081) ?
-                    (REQUEST_QUEUE_SIZE + RESPONSE_QUEUE_SIZE) :
-                    (REQUEST_QUEUE_SIZE + RESPONSE_QUEUE_SIZE +
-                    RCVBUF_QUEUE_SIZE);
+                /* Setup interrupts */
+                if ((rval = ql_setup_interrupts(ha)) != DDI_SUCCESS) {
+                        cmn_err(CE_WARN, "%s(%d): Failed to add interrupt, "
+                            "rval=%xh", QL_NAME, instance, rval);
+                        goto attach_failed;
+                }
 
-                if (ql_get_dma_mem(ha, &ha->hba_buf, size, LITTLE_ENDIAN_DMA,
-                    QL_DMA_RING_ALIGN) != QL_SUCCESS) {
+                progress |= (QL_INTR_ADDED | QL_MUTEX_CV_INITED);
+
+                /* Setup hba buffer. */
+                if (ql_create_queues(ha) != QL_SUCCESS) {
                         cmn_err(CE_WARN, "%s(%d): request queue DMA memory "
                             "alloc failed", QL_NAME, instance);
                         goto attach_failed;
                 }
                 progress |= QL_HBA_BUFFER_SETUP;
 
-                /* Setup buffer pointers. */
-                ha->request_dvma = ha->hba_buf.cookie.dmac_laddress +
-                    REQUEST_Q_BUFFER_OFFSET;
-                ha->request_ring_bp = (struct cmd_entry *)
-                    ((caddr_t)ha->hba_buf.bp + REQUEST_Q_BUFFER_OFFSET);
-
-                ha->response_dvma = ha->hba_buf.cookie.dmac_laddress +
-                    RESPONSE_Q_BUFFER_OFFSET;
-                ha->response_ring_bp = (struct sts_entry *)
-                    ((caddr_t)ha->hba_buf.bp + RESPONSE_Q_BUFFER_OFFSET);
-
-                ha->rcvbuf_dvma = ha->hba_buf.cookie.dmac_laddress +
-                    RCVBUF_Q_BUFFER_OFFSET;
-                ha->rcvbuf_ring_bp = (struct rcvbuf *)
-                    ((caddr_t)ha->hba_buf.bp + RCVBUF_Q_BUFFER_OFFSET);
-
                 /* Allocate resource for QLogic IOCTL */
                 (void) ql_alloc_xioctl_resource(ha);
 
-                /* Setup interrupts */
-                if ((rval = ql_setup_interrupts(ha)) != DDI_SUCCESS) {
-                        cmn_err(CE_WARN, "%s(%d): Failed to add interrupt, "
-                            "rval=%xh", QL_NAME, instance, rval);
+
+                if (ql_nvram_cache_desc_ctor(ha) != DDI_SUCCESS) {
+                        cmn_err(CE_WARN, "%s(%d): can't setup nvram cache",
+                            QL_NAME, instance);
                         goto attach_failed;
                 }
 
-                progress |= (QL_INTR_ADDED | QL_MUTEX_CV_INITED);
+                progress |= QL_NVRAM_CACHE_CREATED;
 
-                if (ql_nvram_cache_desc_ctor(ha) != DDI_SUCCESS) {
-                        cmn_err(CE_WARN, "%s(%d): can't setup nvram cache",
+                if (ql_plogi_params_desc_ctor(ha) != DDI_SUCCESS) {
+                        cmn_err(CE_WARN, "%s(%d): can't setup plogi params",
                             QL_NAME, instance);
                         goto attach_failed;
                 }
 
+                progress |= QL_PLOGI_PARAMS_CREATED;
+
                 /*
                  * Allocate an N Port information structure
                  * for use when in P2P topology.
                  */
                 ha->n_port = (ql_n_port_info_t *)

@@ -1352,28 +1522,28 @@
                 if (ha->fw_major_version == 0 && ha->fw_minor_version == 0 &&
                     ha->fw_subminor_version == 0) {
                         cmn_err(CE_NOTE, "!%s(%d): Firmware not loaded",
                             QL_NAME, ha->instance);
                 } else {
-                        int     rval;
+                        int     rval, rval1;
                         char    ver_fmt[256];
 
-                        rval = (int)snprintf(ver_fmt, (size_t)sizeof (ver_fmt),
+                        rval1 = (int)snprintf(ver_fmt, (size_t)sizeof (ver_fmt),
                             "Firmware version %d.%d.%d", ha->fw_major_version,
                             ha->fw_minor_version, ha->fw_subminor_version);
 
                         if (CFG_IST(ha, CFG_CTRL_81XX)) {
-                                rval = (int)snprintf(ver_fmt + rval,
+                                rval = (int)snprintf(ver_fmt + rval1,
                                     (size_t)sizeof (ver_fmt),
                                     ", MPI fw version %d.%d.%d",
                                     ha->mpi_fw_major_version,
                                     ha->mpi_fw_minor_version,
                                     ha->mpi_fw_subminor_version);
 
                                 if (ha->subsys_id == 0x17B ||
                                     ha->subsys_id == 0x17D) {
-                                        (void) snprintf(ver_fmt + rval,
+                                        (void) snprintf(ver_fmt + rval1 + rval,
                                             (size_t)sizeof (ver_fmt),
                                             ", PHY fw version %d.%d.%d",
                                             ha->phy_fw_major_version,
                                             ha->phy_fw_minor_version,
                                             ha->phy_fw_subminor_version);

@@ -1420,47 +1590,74 @@
                 progress |= QL_FCA_TRAN_ALLOCED;
 
                 /* fill in the structure */
                 tran->fca_numports = 1;
                 tran->fca_version = FCTL_FCA_MODREV_5;
-                if (CFG_IST(ha, CFG_CTRL_2422)) {
-                        tran->fca_num_npivports = MAX_24_VIRTUAL_PORTS;
-                } else if (CFG_IST(ha, CFG_CTRL_2581)) {
-                        tran->fca_num_npivports = MAX_25_VIRTUAL_PORTS;
-                }
+                tran->fca_num_npivports = ha->max_vports ?
+                    ha->max_vports - 1 : 0;
                 bcopy(ha->loginparams.node_ww_name.raw_wwn,
                     tran->fca_perm_pwwn.raw_wwn, 8);
 
-                EL(ha, "FCA version %d\n", tran->fca_version);
+                if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
+                        ha->io_dma_attr = ha->bit64_io_dma_attr;
+                        ha->fcsm_cmd_dma_attr = ha->bit64_io_dma_attr;
+                        ha->fcsm_rsp_dma_attr = ha->bit64_io_dma_attr;
+                        ha->fcip_cmd_dma_attr = ha->bit64_io_dma_attr;
+                        ha->fcip_rsp_dma_attr = ha->bit64_io_dma_attr;
+                        ha->fcp_cmd_dma_attr = ha->bit64_io_dma_attr;
+                        ha->fcp_rsp_dma_attr = ha->bit64_io_dma_attr;
+                        ha->fcp_data_dma_attr = ha->bit64_io_dma_attr;
+                } else {
+                        ha->io_dma_attr = ha->bit32_io_dma_attr;
+                        ha->fcsm_cmd_dma_attr = ha->bit32_io_dma_attr;
+                        ha->fcsm_rsp_dma_attr = ha->bit32_io_dma_attr;
+                        ha->fcip_cmd_dma_attr = ha->bit32_io_dma_attr;
+                        ha->fcip_rsp_dma_attr = ha->bit32_io_dma_attr;
+                        ha->fcp_cmd_dma_attr = ha->bit32_io_dma_attr;
+                        ha->fcp_rsp_dma_attr = ha->bit32_io_dma_attr;
+                        ha->fcp_data_dma_attr = ha->bit32_io_dma_attr;
+                }
+                ha->fcsm_cmd_dma_attr.dma_attr_sgllen = QL_FCSM_CMD_SGLLEN;
+                ha->fcsm_rsp_dma_attr.dma_attr_sgllen = QL_FCSM_RSP_SGLLEN;
+                ha->fcip_cmd_dma_attr.dma_attr_sgllen = QL_FCIP_CMD_SGLLEN;
+                ha->fcip_rsp_dma_attr.dma_attr_sgllen = QL_FCIP_RSP_SGLLEN;
+                ha->fcp_cmd_dma_attr.dma_attr_sgllen = QL_FCP_CMD_SGLLEN;
+                ha->fcp_rsp_dma_attr.dma_attr_sgllen = QL_FCP_RSP_SGLLEN;
+                if (CFG_IST(ha, CFG_CTRL_82XX)) {
+                        ha->io_dma_attr.dma_attr_flags |=
+                            DDI_DMA_RELAXED_ORDERING;
+                        ha->fcsm_cmd_dma_attr.dma_attr_flags |=
+                            DDI_DMA_RELAXED_ORDERING;
+                        ha->fcsm_rsp_dma_attr.dma_attr_flags |=
+                            DDI_DMA_RELAXED_ORDERING;
+                        ha->fcip_cmd_dma_attr.dma_attr_flags |=
+                            DDI_DMA_RELAXED_ORDERING;
+                        ha->fcip_rsp_dma_attr.dma_attr_flags |=
+                            DDI_DMA_RELAXED_ORDERING;
+                        ha->fcp_cmd_dma_attr.dma_attr_flags |=
+                            DDI_DMA_RELAXED_ORDERING;
+                        ha->fcp_rsp_dma_attr.dma_attr_flags |=
+                            DDI_DMA_RELAXED_ORDERING;
+                        ha->fcp_data_dma_attr.dma_attr_flags |=
+                            DDI_DMA_RELAXED_ORDERING;
+                }
 
                 /* Specify the amount of space needed in each packet */
                 tran->fca_pkt_size = sizeof (ql_srb_t);
 
                 /* command limits are usually dictated by hardware */
-                tran->fca_cmd_max = MAX_OUTSTANDING_COMMANDS;
+                tran->fca_cmd_max = ha->osc_max_cnt;
 
                 /* dmaattr are static, set elsewhere. */
-                if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
-                        tran->fca_dma_attr = &ql_64bit_io_dma_attr;
-                        tran->fca_dma_fcp_cmd_attr = &ql_64fcp_cmd_dma_attr;
-                        tran->fca_dma_fcp_rsp_attr = &ql_64fcp_rsp_dma_attr;
-                        tran->fca_dma_fcp_data_attr = &ql_64fcp_data_dma_attr;
-                        tran->fca_dma_fcsm_cmd_attr = &ql_64fcsm_cmd_dma_attr;
-                        tran->fca_dma_fcsm_rsp_attr = &ql_64fcsm_rsp_dma_attr;
-                        tran->fca_dma_fcip_cmd_attr = &ql_64fcip_cmd_dma_attr;
-                        tran->fca_dma_fcip_rsp_attr = &ql_64fcip_rsp_dma_attr;
-                } else {
-                        tran->fca_dma_attr = &ql_32bit_io_dma_attr;
-                        tran->fca_dma_fcp_cmd_attr = &ql_32fcp_cmd_dma_attr;
-                        tran->fca_dma_fcp_rsp_attr = &ql_32fcp_rsp_dma_attr;
-                        tran->fca_dma_fcp_data_attr = &ql_32fcp_data_dma_attr;
-                        tran->fca_dma_fcsm_cmd_attr = &ql_32fcsm_cmd_dma_attr;
-                        tran->fca_dma_fcsm_rsp_attr = &ql_32fcsm_rsp_dma_attr;
-                        tran->fca_dma_fcip_cmd_attr = &ql_32fcip_cmd_dma_attr;
-                        tran->fca_dma_fcip_rsp_attr = &ql_32fcip_rsp_dma_attr;
-                }
-
+                tran->fca_dma_attr = &ha->io_dma_attr;
+                tran->fca_dma_fcp_cmd_attr = &ha->fcp_cmd_dma_attr;
+                tran->fca_dma_fcp_rsp_attr = &ha->fcp_rsp_dma_attr;
+                tran->fca_dma_fcp_data_attr = &ha->fcp_data_dma_attr;
+                tran->fca_dma_fcsm_cmd_attr = &ha->fcsm_cmd_dma_attr;
+                tran->fca_dma_fcsm_rsp_attr = &ha->fcsm_rsp_dma_attr;
+                tran->fca_dma_fcip_cmd_attr = &ha->fcip_cmd_dma_attr;
+                tran->fca_dma_fcip_rsp_attr = &ha->fcip_rsp_dma_attr;
                 tran->fca_acc_attr = &ql_dev_acc_attr;
                 tran->fca_iblock = &(ha->iblock_cookie);
 
                 /* the remaining values are simply function vectors */
                 tran->fca_bind_port = ql_bind_port;

@@ -1478,10 +1675,13 @@
                 tran->fca_abort = ql_abort;
                 tran->fca_reset = ql_reset;
                 tran->fca_port_manage = ql_port_manage;
                 tran->fca_get_device = ql_get_device;
 
+                EL(ha, "Transport interface setup. FCA version %d\n",
+                    tran->fca_version);
+
                 /* give it to the FC transport */
                 if (fc_fca_attach(dip, tran) != DDI_SUCCESS) {
                         cmn_err(CE_WARN, "%s(%d): FCA attach failed", QL_NAME,
                             instance);
                         goto attach_failed;

@@ -1495,27 +1695,43 @@
                 GLOBAL_STATE_LOCK();
 
                 /* Add adapter structure to link list. */
                 ql_add_link_b(&ql_hba, &ha->hba);
 
+                /* Determine and populate HBA fru info */
+                ql_setup_fruinfo(ha);
+
+                /* Release global state lock. */
+                GLOBAL_STATE_UNLOCK();
+
                 /* Start one second driver timer. */
+                GLOBAL_TIMER_LOCK();
                 if (ql_timer_timeout_id == NULL) {
                         ql_timer_ticks = drv_usectohz(1000000);
                         ql_timer_timeout_id = timeout(ql_timer, (void *)0,
                             ql_timer_ticks);
                 }
+                GLOBAL_TIMER_UNLOCK();
 
-                /* Release global state lock. */
-                GLOBAL_STATE_UNLOCK();
-
-                /* Determine and populate HBA fru info */
-                ql_setup_fruinfo(ha);
-
                 /* Setup task_daemon thread. */
-                (void) thread_create(NULL, 0, (void (*)())ql_task_daemon, ha,
-                    0, &p0, TS_RUN, minclsyspri);
+                (void) snprintf(taskq_name, sizeof (taskq_name),
+                    "qlc_%d_driver_thread", instance);
+                ha->driver_thread_taskq = ddi_taskq_create(NULL, taskq_name, 1,
+                    TASKQ_DEFAULTPRI, 0);
+                (void) ddi_taskq_dispatch(ha->driver_thread_taskq,
+                    ql_task_daemon, ha, DDI_SLEEP);
+                ha->task_daemon_flags |= TASK_DAEMON_ALIVE_FLG;
 
+                (void) snprintf(taskq_name, sizeof (taskq_name),
+                    "qlc_%d_comp_thd", instance);
+                ha->completion_taskq = ddi_taskq_create(0, taskq_name,
+                    ha->completion_thds, maxclsyspri, 0);
+                for (size = 0; size < ha->completion_thds; size++) {
+                        (void) ddi_taskq_dispatch(ha->completion_taskq,
+                            ql_completion_thread, ha, DDI_SLEEP);
+                }
+
                 progress |= QL_TASK_DAEMON_STARTED;
 
                 ddi_report_dev(dip);
 
                 /* Disable link reset in panic path */

@@ -1523,10 +1739,15 @@
 
                 rval = DDI_SUCCESS;
                 break;
 
 attach_failed:
+                if (progress & QL_FCA_INIT_FM) {
+                        qlc_fm_fini(ha);
+                        progress &= ~QL_FCA_INIT_FM;
+                }
+
                 if (progress & QL_FCA_ATTACH_DONE) {
                         (void) fc_fca_detach(dip);
                         progress &= ~QL_FCA_ATTACH_DONE;
                 }
 

@@ -1548,23 +1769,48 @@
                 if (progress & QL_N_PORT_INFO_CREATED) {
                         kmem_free(ha->n_port, sizeof (ql_n_port_info_t));
                         progress &= ~QL_N_PORT_INFO_CREATED;
                 }
 
-                if (progress & QL_TASK_DAEMON_STARTED) {
-                        TASK_DAEMON_LOCK(ha);
+                if (progress & QL_PLOGI_PARAMS_CREATED) {
+                        (void) ql_plogi_params_desc_dtor(ha);
+                        progress &= ~QL_PLOGI_PARAMS_CREATED;
+                }
 
-                        ha->task_daemon_flags |= TASK_DAEMON_STOP_FLG;
+                if (progress & QL_NVRAM_CACHE_CREATED) {
+                        (void) ql_nvram_cache_desc_dtor(ha);
+                        progress &= ~QL_NVRAM_CACHE_CREATED;
+                }
 
-                        cv_signal(&ha->cv_task_daemon);
+                if (progress & QL_TASK_DAEMON_STARTED) {
+                        if (ha->driver_thread_taskq) {
+                                while (ha->task_daemon_flags &
+                                    TASK_DAEMON_ALIVE_FLG) {
+                                        /* Delay for 1 tick (10 ms). */
+                                        ql_awaken_task_daemon(ha, NULL,
+                                            TASK_DAEMON_STOP_FLG, 0);
+                                        delay(1);
+                                }
+                                ha->task_daemon_flags &= ~TASK_DAEMON_STOP_FLG;
 
-                        /* Release task daemon lock. */
-                        TASK_DAEMON_UNLOCK(ha);
+                                ddi_taskq_destroy(ha->driver_thread_taskq);
+                                ha->driver_thread_taskq = NULL;
+                        }
+                        if (ha->completion_taskq) {
+                                ADAPTER_STATE_LOCK(ha);
+                                ha->flags |= COMP_THD_TERMINATE;
+                                ADAPTER_STATE_UNLOCK(ha);
 
-                        /* Wait for for task daemon to stop running. */
-                        while (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) {
+                                do {
+                                        COMP_Q_LOCK(ha);
+                                        cv_broadcast(&ha->cv_comp_thread);
+                                        COMP_Q_UNLOCK(ha);
                                 ql_delay(ha, 10000);
+                                } while (ha->comp_thds_active != 0);
+
+                                ddi_taskq_destroy(ha->completion_taskq);
+                                ha->completion_taskq = NULL;
                         }
                         progress &= ~QL_TASK_DAEMON_STARTED;
                 }
 
                 if (progress & QL_DB_IOBASE_MAPPED) {

@@ -1574,10 +1820,16 @@
                 }
                 if (progress & QL_IOMAP_IOBASE_MAPPED) {
                         ddi_regs_map_free(&ha->iomap_dev_handle);
                         progress &= ~QL_IOMAP_IOBASE_MAPPED;
                 }
+                if (progress & QL_REGS_MAPPED) {
+                        if (ha->mbar_dev_handle) {
+                                ddi_regs_map_free(&ha->mbar_dev_handle);
+                                ha->mbar_dev_handle = 0;
+                        }
+                }
 
                 if (progress & QL_CONFIG_SPACE_SETUP) {
                         if (CFG_IST(ha, CFG_SBUS_CARD)) {
                                 ddi_regs_map_free(&ha->sbus_config_handle);
                         } else {

@@ -1596,11 +1848,11 @@
                         ql_destroy_mutex(ha);
                         progress &= ~QL_MUTEX_CV_INITED;
                 }
 
                 if (progress & QL_HBA_BUFFER_SETUP) {
-                        ql_free_phys(ha, &ha->hba_buf);
+                        ql_delete_queues(ha);
                         progress &= ~QL_HBA_BUFFER_SETUP;
                 }
 
                 if (progress & QL_REGS_MAPPED) {
                         ddi_regs_map_free(&ha->dev_handle);

@@ -1618,13 +1870,15 @@
                             sizeof (*ha->adapter_stats));
 
                         kmem_free(ha->ub_array, sizeof (*ha->ub_array) *
                             QL_UB_LIMIT);
 
+                        if (ha->outstanding_cmds != NULL) {
                         kmem_free(ha->outstanding_cmds,
                             sizeof (*ha->outstanding_cmds) *
-                            MAX_OUTSTANDING_COMMANDS);
+                                    ha->osc_max_cnt);
+                        }
 
                         if (ha->devpath != NULL) {
                                 kmem_free(ha->devpath,
                                     strlen(ha->devpath) + 1);
                         }

@@ -1637,12 +1891,11 @@
                         }
 
                         if (ha->fw_module != NULL) {
                                 (void) ddi_modclose(ha->fw_module);
                         }
-                        (void) ql_el_trace_desc_dtor(ha);
-                        (void) ql_nvram_cache_desc_dtor(ha);
+                        (void) ql_el_trace_dealloc(ha);
 
                         ddi_soft_state_free(ql_state, instance);
                         progress &= ~QL_SOFT_STATE_ALLOCED;
                 }
 

@@ -1687,34 +1940,23 @@
                         /* Wake up task_daemon. */
                         ql_awaken_task_daemon(ha, NULL, TASK_DAEMON_ALIVE_FLG,
                             0);
                 }
 
-                /* Acquire global state lock. */
-                GLOBAL_STATE_LOCK();
-
                 /* Restart driver timer. */
+                GLOBAL_TIMER_LOCK();
                 if (ql_timer_timeout_id == NULL) {
                         ql_timer_timeout_id = timeout(ql_timer, (void *)0,
                             ql_timer_ticks);
                 }
+                GLOBAL_TIMER_LOCK();
 
-                /* Release global state lock. */
-                GLOBAL_STATE_UNLOCK();
-
                 /* Wake up command start routine. */
                 ADAPTER_STATE_LOCK(ha);
                 ha->flags &= ~ADAPTER_SUSPENDED;
                 ADAPTER_STATE_UNLOCK(ha);
 
-                /*
-                 * Transport doesn't make FC discovery in polled
-                 * mode; So we need the daemon thread's services
-                 * right here.
-                 */
-                (void) callb_generic_cpr(&ha->cprinfo, CB_CODE_CPR_RESUME);
-
                 rval = DDI_SUCCESS;
 
                 /* Restart IP if it was running. */
                 if (ha->flags & IP_ENABLED && !(ha->flags & IP_INITIALIZED)) {
                         (void) ql_initialize_ip(ha);

@@ -1731,15 +1973,15 @@
 
         kmem_free(buf, MAXPATHLEN);
 
         if (rval != DDI_SUCCESS) {
                 /*EMPTY*/
-                QL_PRINT_2(CE_CONT, "(%d): failed, rval = %xh\n",
+                QL_PRINT_2(ha, "failed instance=%d, rval = %xh\n",
                     ddi_get_instance(dip), rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ddi_get_instance(dip));
+                QL_PRINT_3(ha, "done\n");
         }
 
         return (rval);
 }
 

@@ -1762,68 +2004,87 @@
 static int
 ql_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
 {
         ql_adapter_state_t      *ha, *vha;
         ql_tgt_t                *tq;
-        int                     delay_cnt;
         uint16_t                index;
         ql_link_t               *link;
         char                    *buf;
         timeout_id_t            timer_id = NULL;
         int                     suspend, rval = DDI_SUCCESS;
 
         ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
         if (ha == NULL) {
-                QL_PRINT_2(CE_CONT, "(%d): no adapter\n",
+                QL_PRINT_2(NULL, "no adapter, instance=%d\n",
                     ddi_get_instance(dip));
                 return (DDI_FAILURE);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): started, cmd=%xh\n", ha->instance, cmd);
+        QL_PRINT_3(ha, "started, cmd=%xh\n", cmd);
 
         buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP));
 
         switch (cmd) {
         case DDI_DETACH:
                 ADAPTER_STATE_LOCK(ha);
                 ha->flags |= (ADAPTER_SUSPENDED | ABORT_CMDS_LOOP_DOWN_TMO);
                 ADAPTER_STATE_UNLOCK(ha);
 
-                TASK_DAEMON_LOCK(ha);
+                /* Wait for task thread to see suspend flag. */
+                while (!(ha->task_daemon_flags & TASK_DAEMON_STALLED_FLG) &&
+                    ha->task_daemon_flags & TASK_DAEMON_ALIVE_FLG) {
+                        ql_awaken_task_daemon(ha, NULL, 0, 0);
+                        /* Delay for 1 tick (10 milliseconds). */
+                        delay(1);
+                }
 
-                if (ha->task_daemon_flags & TASK_DAEMON_ALIVE_FLG) {
-                        ha->task_daemon_flags |= TASK_DAEMON_STOP_FLG;
-                        cv_signal(&ha->cv_task_daemon);
+                if (ha->driver_thread_taskq) {
+                        while (ha->task_daemon_flags & TASK_DAEMON_ALIVE_FLG) {
+                                /* Delay for 1 tick (10 milliseconds). */
+                                ql_awaken_task_daemon(ha, NULL,
+                                    TASK_DAEMON_STOP_FLG, 0);
+                                delay(1);
+                        }
+                        ha->task_daemon_flags &= ~TASK_DAEMON_STOP_FLG;
 
-                        TASK_DAEMON_UNLOCK(ha);
+                        ddi_taskq_destroy(ha->driver_thread_taskq);
+                        ha->driver_thread_taskq = NULL;
+                }
 
-                        (void) ql_wait_for_td_stop(ha);
+                if (ha->completion_taskq) {
+                        ADAPTER_STATE_LOCK(ha);
+                        ha->flags |= COMP_THD_TERMINATE;
+                        ADAPTER_STATE_UNLOCK(ha);
 
-                        TASK_DAEMON_LOCK(ha);
-                        if (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) {
-                                ha->task_daemon_flags &= ~TASK_DAEMON_STOP_FLG;
-                                EL(ha, "failed, could not stop task daemon\n");
+                        do {
+                                COMP_Q_LOCK(ha);
+                                cv_broadcast(&ha->cv_comp_thread);
+                                COMP_Q_UNLOCK(ha);
+                                ql_delay(ha, 10000);
+                        } while (ha->comp_thds_active != 0);
+
+                        ddi_taskq_destroy(ha->completion_taskq);
+                        ha->completion_taskq = NULL;
                         }
-                }
-                TASK_DAEMON_UNLOCK(ha);
 
-                GLOBAL_STATE_LOCK();
-
                 /* Disable driver timer if no adapters. */
+                GLOBAL_TIMER_LOCK();
                 if (ql_timer_timeout_id && ql_hba.first == &ha->hba &&
                     ql_hba.last == &ha->hba) {
                         timer_id = ql_timer_timeout_id;
                         ql_timer_timeout_id = NULL;
                 }
-                ql_remove_link(&ql_hba, &ha->hba);
+                GLOBAL_TIMER_UNLOCK();
 
-                GLOBAL_STATE_UNLOCK();
-
                 if (timer_id) {
                         (void) untimeout(timer_id);
                 }
 
+                GLOBAL_STATE_LOCK();
+                ql_remove_link(&ql_hba, &ha->hba);
+                GLOBAL_STATE_UNLOCK();
+
                 if (ha->pm_capable) {
                         if (pm_lower_power(dip, QL_POWER_COMPONENT,
                             PM_LEVEL_D3) != DDI_SUCCESS) {
                                 cmn_err(CE_WARN, "%s(%d): failed to lower the"
                                     " power", QL_NAME, ha->instance);

@@ -1907,11 +2168,11 @@
                 }
 
                 if (CFG_IST(ha, CFG_SBUS_CARD)) {
                         ddi_regs_map_free(&ha->sbus_config_handle);
                 } else {
-                        if (CFG_IST(ha, CFG_CTRL_8021)) {
+                        if (CFG_IST(ha, CFG_CTRL_82XX)) {
                                 ql_8021_clr_drv_active(ha);
                                 ddi_regs_map_free(&ha->db_dev_handle);
                         }
                         if (ha->iomap_dev_handle != ha->dev_handle) {
                                 ddi_regs_map_free(&ha->iomap_dev_handle);

@@ -1924,18 +2185,21 @@
 
                 ql_free_xioctl_resource(ha);
 
                 ql_destroy_mutex(ha);
 
-                ql_free_phys(ha, &ha->hba_buf);
+                ql_delete_queues(ha);
                 ql_free_phys(ha, &ha->fwexttracebuf);
                 ql_free_phys(ha, &ha->fwfcetracebuf);
 
                 ddi_regs_map_free(&ha->dev_handle);
                 if (ha->sbus_fpga_iobase != NULL) {
                         ddi_regs_map_free(&ha->sbus_fpga_dev_handle);
                 }
+                if (ha->mbar_dev_handle != NULL) {
+                        ddi_regs_map_free(&ha->mbar_dev_handle);
+                }
 
                 ql_fcache_rel(ha->fcache);
                 if (ha->vcache != NULL) {
                         kmem_free(ha->vcache, QL_24XX_VPD_SIZE);
                 }

@@ -1947,11 +2211,11 @@
                 kmem_free(ha->adapter_stats, sizeof (*ha->adapter_stats));
 
                 kmem_free(ha->ub_array, sizeof (*ha->ub_array) * QL_UB_LIMIT);
 
                 kmem_free(ha->outstanding_cmds,
-                    sizeof (*ha->outstanding_cmds) * MAX_OUTSTANDING_COMMANDS);
+                    sizeof (*ha->outstanding_cmds) * ha->osc_max_cnt);
 
                 if (ha->n_port != NULL) {
                         kmem_free(ha->n_port, sizeof (ql_n_port_info_t));
                 }
 

@@ -1959,38 +2223,44 @@
                         kmem_free(ha->devpath, strlen(ha->devpath) + 1);
                 }
 
                 kmem_free(ha->dev, sizeof (*ha->dev) * DEVICE_HEAD_LIST_SIZE);
 
+                (void) ql_plogi_params_desc_dtor(ha);
+
+                (void) ql_nvram_cache_desc_dtor(ha);
+
+                (void) qlc_fm_fini(ha);
+
                 EL(ha, "detached\n");
 
+                (void) ql_el_trace_dealloc(ha);
+
                 ddi_soft_state_free(ql_state, (int)ha->instance);
 
+                rval = DDI_SUCCESS;
+
                 break;
 
         case DDI_SUSPEND:
                 ADAPTER_STATE_LOCK(ha);
-
-                delay_cnt = 0;
                 ha->flags |= ADAPTER_SUSPENDED;
-                while (ha->flags & ADAPTER_TIMER_BUSY && delay_cnt++ < 10) {
                         ADAPTER_STATE_UNLOCK(ha);
-                        delay(drv_usectohz(1000000));
-                        ADAPTER_STATE_LOCK(ha);
+
+                /* Disable driver timer if last adapter. */
+                GLOBAL_TIMER_LOCK();
+                if (ql_timer_timeout_id && ql_hba.first == &ha->hba &&
+                    ql_hba.last == &ha->hba) {
+                        timer_id = ql_timer_timeout_id;
+                        ql_timer_timeout_id = NULL;
                 }
-                if (ha->busy || ha->flags & ADAPTER_TIMER_BUSY) {
-                        ha->flags &= ~ADAPTER_SUSPENDED;
-                        ADAPTER_STATE_UNLOCK(ha);
-                        rval = DDI_FAILURE;
-                        cmn_err(CE_WARN, "!%s(%d): Fail suspend"
-                            " busy %xh flags %xh", QL_NAME, ha->instance,
-                            ha->busy, ha->flags);
-                        break;
+                GLOBAL_TIMER_UNLOCK();
+
+                if (timer_id) {
+                        (void) untimeout(timer_id);
                 }
 
-                ADAPTER_STATE_UNLOCK(ha);
-
                 if (ha->flags & IP_INITIALIZED) {
                         (void) ql_shutdown_ip(ha);
                 }
 
                 if ((suspend = ql_suspend_adapter(ha)) != QL_SUCCESS) {

@@ -2008,25 +2278,10 @@
                         }
                         rval = DDI_FAILURE;
                         break;
                 }
 
-                /* Acquire global state lock. */
-                GLOBAL_STATE_LOCK();
-
-                /* Disable driver timer if last adapter. */
-                if (ql_timer_timeout_id && ql_hba.first == &ha->hba &&
-                    ql_hba.last == &ha->hba) {
-                        timer_id = ql_timer_timeout_id;
-                        ql_timer_timeout_id = NULL;
-                }
-                GLOBAL_STATE_UNLOCK();
-
-                if (timer_id) {
-                        (void) untimeout(timer_id);
-                }
-
                 EL(ha, "suspended\n");
 
                 break;
 
         default:

@@ -2035,26 +2290,19 @@
         }
 
         kmem_free(buf, MAXPATHLEN);
 
         if (rval != DDI_SUCCESS) {
-                if (ha != NULL) {
                         EL(ha, "failed, rval = %xh\n", rval);
                 } else {
                         /*EMPTY*/
-                        QL_PRINT_2(CE_CONT, "(%d): failed, rval = %xh\n",
-                            ddi_get_instance(dip), rval);
+                QL_PRINT_3(ha, "done\n");
                 }
-        } else {
-                /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ddi_get_instance(dip));
-        }
 
         return (rval);
 }
 
-
 /*
  * ql_power
  *      Power a device attached to the system.
  *
  * Input:

@@ -2079,16 +2327,15 @@
         char                    *buf;
         char                    *path;
 
         ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
         if (ha == NULL || ha->pm_capable == 0) {
-                QL_PRINT_2(CE_CONT, "(%d): no hba or PM not supported\n",
-                    ddi_get_instance(dip));
+                QL_PRINT_2(ha, "no hba or PM not supported\n");
                 return (rval);
         }
 
-        QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
+        QL_PRINT_10(ha, "started\n");
 
         buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP));
         path = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP));
 
         if (component != QL_POWER_COMPONENT || (level != PM_LEVEL_D0 &&

@@ -2100,11 +2347,11 @@
 
         GLOBAL_HW_LOCK();
         csr = (uint8_t)ql_pci_config_get8(ha, PCI_CONF_CAP_PTR) + PCI_PMCSR;
         GLOBAL_HW_UNLOCK();
 
-        (void) snprintf(buf, sizeof (buf),
+        (void) snprintf(buf, MAXPATHLEN,
             "Qlogic %s(%d): %s\n\t", QL_NAME, ddi_get_instance(dip),
             ddi_pathname(dip, path));
 
         switch (level) {
         case PM_LEVEL_D0:       /* power up to D0 state - fully on */

@@ -2170,11 +2417,11 @@
 
         case PM_LEVEL_D3:       /* power down to D3 state - off */
 
                 QL_PM_LOCK(ha);
 
-                if (ha->busy || ((ha->task_daemon_flags &
+                if (ha->pm_busy || ((ha->task_daemon_flags &
                     TASK_DAEMON_SLEEPING_FLG) == 0)) {
                         QL_PM_UNLOCK(ha);
                         break;
                 }
 

@@ -2227,11 +2474,11 @@
         }
 
         kmem_free(buf, MAXPATHLEN);
         kmem_free(path, MAXPATHLEN);
 
-        QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
+        QL_PRINT_10(ha, "done\n");
 
         return (rval);
 }
 
 /*

@@ -2255,22 +2502,62 @@
         uint32_t                stat;
 
         ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
         if (ha == NULL) {
                 /* Oh well.... */
-                QL_PRINT_2(CE_CONT, "(%d): no adapter\n",
+                QL_PRINT_2(NULL, "no adapter, instance=%d\n",
                     ddi_get_instance(dip));
                 return (DDI_SUCCESS);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
-        if (CFG_IST(ha, CFG_CTRL_8021)) {
-                (void) ql_stop_firmware(ha);
-        } else if (CFG_IST(ha, CFG_CTRL_242581)) {
+        if (CFG_IST(ha, CFG_CTRL_82XX)) {
+                ql_8021_clr_hw_intr(ha);
+                ql_8021_clr_fw_intr(ha);
+                WRT16_IO_REG(ha, mailbox_in[0], MBC_TOGGLE_INTERRUPT);
+                WRT16_IO_REG(ha, mailbox_in[1], 0);
+                WRT32_IO_REG(ha, nx_host_int, NX_MBX_CMD);
+                for (timer = 0; timer < 20000; timer++) {
+                        stat = RD32_IO_REG(ha, risc2host);
+                        if (stat & BIT_15) {
+                                ql_8021_clr_hw_intr(ha);
+                                if ((stat & 0xff) < 0x12) {
+                                        ql_8021_clr_fw_intr(ha);
+                                        break;
+                                }
+                                ql_8021_clr_fw_intr(ha);
+                        }
+                        drv_usecwait(100);
+                }
+                ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0x0400);
+                WRT16_IO_REG(ha, mailbox_in[0], MBC_STOP_FIRMWARE);
+                WRT16_IO_REG(ha, mailbox_in[1], 0);
+                WRT32_IO_REG(ha, nx_host_int, NX_MBX_CMD);
+                for (timer = 0; timer < 20000; timer++) {
+                        stat = RD32_IO_REG(ha, risc2host);
+                        if (stat & BIT_15) {
+                                ql_8021_clr_hw_intr(ha);
+                                if ((stat & 0xff) < 0x12) {
+                                        ql_8021_clr_fw_intr(ha);
+                                        break;
+                                }
+                                ql_8021_clr_fw_intr(ha);
+                        }
+                        drv_usecwait(100);
+                }
+        } else if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
                 WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
                 WRT16_IO_REG(ha, mailbox_in[0], MBC_STOP_FIRMWARE);
+                WRT16_IO_REG(ha, mailbox_in[1], 0);
+                WRT16_IO_REG(ha, mailbox_in[2], 0);
+                WRT16_IO_REG(ha, mailbox_in[3], 0);
+                WRT16_IO_REG(ha, mailbox_in[4], 0);
+                WRT16_IO_REG(ha, mailbox_in[5], 0);
+                WRT16_IO_REG(ha, mailbox_in[6], 0);
+                WRT16_IO_REG(ha, mailbox_in[7], 0);
+                WRT16_IO_REG(ha, mailbox_in[8], 0);
                 WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT);
                 for (timer = 0; timer < 30000; timer++) {
                         stat = RD32_IO_REG(ha, risc2host);
                         if (stat & BIT_15) {
                                 if ((stat & 0xff) < 0x12) {

@@ -2281,12 +2568,16 @@
                                 WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
                         }
                         drv_usecwait(100);
                 }
                 /* Reset the chip. */
+                if (CFG_IST(ha, CFG_MWB_4096_SUPPORT)) {
                 WRT32_IO_REG(ha, ctrl_status, ISP_RESET | DMA_SHUTDOWN |
                     MWB_4096_BYTES);
+                } else {
+                        WRT32_IO_REG(ha, ctrl_status, ISP_RESET | DMA_SHUTDOWN);
+                }
                 drv_usecwait(100);
 
         } else {
                 /* Disable ISP interrupts. */
                 WRT16_IO_REG(ha, ictrl, 0);

@@ -2298,14 +2589,12 @@
                 WRT16_IO_REG(ha, hccr, HC_RESET_RISC);
                 /* Release RISC module. */
                 WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
         }
 
-        ql_disable_intr(ha);
+        QL_PRINT_3(ha, "done\n");
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
-
         return (DDI_SUCCESS);
 }
 
 /* ************************************************************************ */
 /*              Fibre Channel Adapter (FCA) Transport Functions.            */

@@ -2342,46 +2631,43 @@
         uchar_t                 *port_pwwn = bind_info->port_pwwn.raw_wwn;
 
         /* get state info based on the dip */
         ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
         if (ha == NULL) {
-                QL_PRINT_2(CE_CONT, "(%d): no adapter\n",
+                QL_PRINT_2(ha, "no adapter, instance=%d\n",
                     ddi_get_instance(dip));
                 return (NULL);
         }
-        QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
+        QL_PRINT_10(ha, "started\n");
 
         /* Verify port number is supported. */
         if (port_npiv != 0) {
                 if (!(ha->flags & VP_ENABLED)) {
-                        QL_PRINT_2(CE_CONT, "(%d): FC_NPIV_NOT_SUPPORTED\n",
-                            ha->instance);
+                        QL_PRINT_2(ha, "FC_NPIV_NOT_SUPPORTED\n");
                         port_info->pi_error = FC_NPIV_NOT_SUPPORTED;
                         return (NULL);
                 }
                 if (!(ha->flags & POINT_TO_POINT)) {
-                        QL_PRINT_2(CE_CONT, "(%d): FC_NPIV_WRONG_TOPOLOGY\n",
-                            ha->instance);
+                        QL_PRINT_2(ha, "FC_NPIV_WRONG_TOPOLOGY\n");
                         port_info->pi_error = FC_NPIV_WRONG_TOPOLOGY;
                         return (NULL);
                 }
                 if (!(ha->flags & FDISC_ENABLED)) {
-                        QL_PRINT_2(CE_CONT, "(%d): switch does not support "
-                            "FDISC\n", ha->instance);
+                        QL_PRINT_2(ha, "switch does not support "
+                            "FDISC\n");
                         port_info->pi_error = FC_NPIV_FDISC_FAILED;
                         return (NULL);
                 }
-                if (bind_info->port_num > (CFG_IST(ha, CFG_CTRL_2422) ?
-                    MAX_24_VIRTUAL_PORTS : MAX_25_VIRTUAL_PORTS)) {
-                        QL_PRINT_2(CE_CONT, "(%d): port number=%d "
-                            "FC_OUTOFBOUNDS\n", ha->instance);
+                if (bind_info->port_num >= ha->max_vports) {
+                        QL_PRINT_2(ha, "port number=%d "
+                            "FC_OUTOFBOUNDS\n", bind_info->port_num);
                         port_info->pi_error = FC_OUTOFBOUNDS;
                         return (NULL);
                 }
         } else if (bind_info->port_num != 0) {
-                QL_PRINT_2(CE_CONT, "(%d): failed, port number=%d is not "
-                    "supported\n", ha->instance, bind_info->port_num);
+                QL_PRINT_2(ha, "failed, port number=%d is not "
+                    "supported\n", bind_info->port_num);
                 port_info->pi_error = FC_OUTOFBOUNDS;
                 return (NULL);
         }
 
         /* Locate port context. */

@@ -2406,12 +2692,12 @@
                         bcopy(port_pwwn,
                             vha->loginparams.nport_ww_name.raw_wwn, 8);
                 }
                 if (vha->vp_index != 0 && !(vha->flags & VP_ENABLED)) {
                         if (ql_vport_enable(vha) != QL_SUCCESS) {
-                                QL_PRINT_2(CE_CONT, "(%d): failed to enable "
-                                    "virtual port=%d\n", ha->instance,
+                                QL_PRINT_2(ha, "failed to enable "
+                                    "virtual port=%d\n",
                                     vha->vp_index);
                                 port_info->pi_error = FC_NPIV_FDISC_FAILED;
                                 return (NULL);
                         }
                         cmn_err(CE_CONT, "!Qlogic %s(%d) NPIV(%d) "

@@ -2426,12 +2712,11 @@
                             port_nwwn[6], port_nwwn[7]);
                 }
 
                 /* stash the bind_info supplied by the FC Transport */
                 vha->bind_info.port_handle = bind_info->port_handle;
-                vha->bind_info.port_statec_cb =
-                    bind_info->port_statec_cb;
+                vha->bind_info.port_statec_cb = bind_info->port_statec_cb;
                 vha->bind_info.port_unsol_cb = bind_info->port_unsol_cb;
 
                 /* Set port's source ID. */
                 port_info->pi_s_id.port_id = vha->d_id.b24;
 

@@ -2442,11 +2727,11 @@
 
                 /* Set port's hard address if enabled. */
                 port_info->pi_hard_addr.hard_addr = 0;
                 if (bind_info->port_num == 0) {
                         d_id.b24 = ha->d_id.b24;
-                        if (CFG_IST(ha, CFG_CTRL_24258081)) {
+                        if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
                                 if (ha->init_ctrl_blk.cb24.
                                     firmware_options_1[0] & BIT_0) {
                                         d_id.b.al_pa = ql_index_to_alpa[ha->
                                             init_ctrl_blk.cb24.
                                             hard_address[0]];

@@ -2494,12 +2779,12 @@
                 ADAPTER_STATE_UNLOCK(ha);
                 /* Set port's current state. */
                 port_info->pi_port_state = vha->state;
         }
 
-        QL_PRINT_10(CE_CONT, "(%d,%d): done, pi_port_state=%xh, "
-            "pi_s_id.port_id=%xh\n", ha->instance, ha->vp_index,
+        QL_PRINT_10(ha, "done, pi_port_state=%xh, "
+            "pi_s_id.port_id=%xh\n",
             port_info->pi_port_state, port_info->pi_s_id.port_id);
 
         return (fca_handle);
 }
 

@@ -2521,40 +2806,37 @@
         uint32_t                flgs;
 
         ha = ql_fca_handle_to_state(fca_handle);
         if (ha == NULL) {
                 /*EMPTY*/
-                QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
+                QL_PRINT_2(NULL, "failed, no adapter=%ph\n",
                     (void *)fca_handle);
         } else {
-                QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance,
-                    ha->vp_index);
+                QL_PRINT_10(ha, "started\n");
 
                 if (!(ha->flags & FCA_BOUND)) {
                         /*EMPTY*/
-                        QL_PRINT_2(CE_CONT, "(%d): port=%d already unbound\n",
-                            ha->instance, ha->vp_index);
+                        QL_PRINT_2(ha, "port already unbound\n");
                 } else {
                         if (ha->vp_index != 0 && ha->flags & VP_ENABLED) {
+                                (void) ql_vport_control(ha, (uint8_t)
+                                    (CFG_IST(ha, CFG_FC_TYPE) ?
+                                    VPC_DISABLE_INIT : VPC_DISABLE_LOGOUT));
                                 if ((tq = ql_loop_id_to_queue(ha,
                                     FL_PORT_24XX_HDL)) != NULL) {
                                         (void) ql_logout_fabric_port(ha, tq);
                                 }
-                                (void) ql_vport_control(ha, (uint8_t)
-                                    (CFG_IST(ha, CFG_CTRL_2425) ?
-                                    VPC_DISABLE_INIT : VPC_DISABLE_LOGOUT));
                                 flgs = FCA_BOUND | VP_ENABLED;
                         } else {
                                 flgs = FCA_BOUND;
                         }
                         ADAPTER_STATE_LOCK(ha);
                         ha->flags &= ~flgs;
                         ADAPTER_STATE_UNLOCK(ha);
                 }
 
-                QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance,
-                    ha->vp_index);
+                QL_PRINT_10(ha, "done\n");
         }
 }
 
 /*
  * ql_init_pkt

@@ -2581,18 +2863,19 @@
         ql_srb_t                *sp;
         int                     rval = FC_SUCCESS;
 
         ha = ql_fca_handle_to_state(fca_handle);
         if (ha == NULL) {
-                QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
+                QL_PRINT_2(NULL, "failed, no adapter=%ph\n",
                     (void *)fca_handle);
                 return (FC_UNBOUND);
         }
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         sp = (ql_srb_t *)pkt->pkt_fca_private;
         sp->flags = 0;
+        sp->handle = 0;
 
         /* init cmd links */
         sp->cmd.base_address = sp;
         sp->cmd.prev = NULL;
         sp->cmd.next = NULL;

@@ -2606,23 +2889,23 @@
         sp->pkt = pkt;
         sp->ha = ha;
         sp->magic_number = QL_FCA_BRAND;
         sp->sg_dma.dma_handle = NULL;
 #ifndef __sparc
-        if (CFG_IST(ha, CFG_CTRL_8021)) {
+        if (CFG_IST(ha, CFG_CTRL_82XX)) {
                 /* Setup DMA for scatter gather list. */
                 sp->sg_dma.size = sizeof (cmd6_2400_dma_t);
                 sp->sg_dma.type = LITTLE_ENDIAN_DMA;
-                sp->sg_dma.cookie_count = 1;
+                sp->sg_dma.max_cookie_count = 1;
                 sp->sg_dma.alignment = 64;
                 if (ql_alloc_phys(ha, &sp->sg_dma, KM_SLEEP) != QL_SUCCESS) {
                         rval = FC_NOMEM;
                 }
         }
 #endif  /* __sparc */
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (rval);
 }
 
 /*

@@ -2649,15 +2932,15 @@
         int rval;
         ql_srb_t *sp;
 
         ha = ql_fca_handle_to_state(fca_handle);
         if (ha == NULL) {
-                QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
+                QL_PRINT_2(NULL, "failed, no adapter=%ph\n",
                     (void *)fca_handle);
                 return (FC_UNBOUND);
         }
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         sp = (ql_srb_t *)pkt->pkt_fca_private;
 
         if (sp->magic_number != QL_FCA_BRAND) {
                 EL(ha, "failed, FC_BADPACKET\n");

@@ -2666,11 +2949,11 @@
                 sp->magic_number = NULL;
                 ql_free_phys(ha, &sp->sg_dma);
                 rval = FC_SUCCESS;
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (rval);
 }
 
 /*

@@ -2703,19 +2986,19 @@
         ql_srb_t                *sp = (ql_srb_t *)pkt->pkt_fca_private;
 
         /* Verify proper command. */
         ha = ql_cmd_setup(fca_handle, pkt, &rval);
         if (ha == NULL) {
-                QL_PRINT_2(CE_CONT, "failed, ql_cmd_setup=%xh, fcah=%ph\n",
+                QL_PRINT_2(NULL, "failed, ql_cmd_setup=%xh, fcah=%ph\n",
                     rval, fca_handle);
                 return (FC_INVALID_REQUEST);
         }
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         /* Wait for suspension to end. */
         TASK_DAEMON_LOCK(ha);
-        while (ha->task_daemon_flags & QL_SUSPENDED) {
+        while (DRIVER_SUSPENDED(ha)) {
                 ha->task_daemon_flags |= SUSPENDED_WAKEUP_FLG;
 
                 /* 30 seconds from now */
                 if (cv_reltimedwait(&ha->pha->cv_dr_suspended,
                     &ha->pha->task_daemon_mutex, timer, TR_CLOCK_TICK) == -1) {

@@ -2761,25 +3044,19 @@
 
         /* map the type of ELS to a function */
         ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
             (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
 
-#if 0
-        QL_PRINT_3(CE_CONT, "(%d): command fhdr:\n", ha->instance);
-        QL_DUMP_3((uint8_t *)&pkt->pkt_cmd_fhdr, 32,
-            sizeof (fc_frame_hdr_t) / 4);
-        QL_PRINT_3(CE_CONT, "(%d): command:\n", ha->instance);
-        QL_DUMP_3((uint8_t *)&els, 32, sizeof (els) / 4);
-#endif
+        QL_PRINT_10(ha, "els.ls_code=%xh, d_id=%xh\n", els.ls_code,
+            pkt->pkt_cmd_fhdr.d_id);
 
         sp->iocb = ha->els_cmd;
         sp->req_cnt = 1;
 
         switch (els.ls_code) {
         case LA_ELS_RJT:
         case LA_ELS_ACC:
-                EL(ha, "LA_ELS_RJT\n");
                 pkt->pkt_state = FC_PKT_SUCCESS;
                 rval = FC_SUCCESS;
                 break;
         case LA_ELS_PLOGI:
         case LA_ELS_PDISC:

@@ -2843,32 +3120,28 @@
                 pkt->pkt_reason = FC_REASON_UNSUPPORTED;
                 rval = FC_SUCCESS;
                 break;
         }
 
-#if 0
-        QL_PRINT_3(CE_CONT, "(%d): response fhdr:\n", ha->instance);
-        QL_DUMP_3((uint8_t *)&pkt->pkt_resp_fhdr, 32,
-            sizeof (fc_frame_hdr_t) / 4);
-#endif
         /*
          * Return success if the srb was consumed by an iocb. The packet
          * completion callback will be invoked by the response handler.
          */
         if (rval == QL_CONSUMED) {
                 rval = FC_SUCCESS;
         } else if (rval == FC_SUCCESS &&
             !(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) {
                 /* Do command callback only if no error */
-                ql_awaken_task_daemon(ha, sp, 0, 0);
+                ql_io_comp(sp);
         }
 
         if (rval != FC_SUCCESS) {
-                EL(ha, "failed, rval = %xh\n", rval);
+                EL(ha, "rval=%x, ls_code=%xh sent to d_id=%xh, sp=%ph\n",
+                    rval, els.ls_code, pkt->pkt_cmd_fhdr.d_id, sp);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_10(ha, "done\n");
         }
         return (rval);
 }
 
 /*

@@ -2896,15 +3169,15 @@
         int                     rval;
         uint32_t                *rptr = (uint32_t *)ptr;
 
         ha = ql_fca_handle_to_state(fca_handle);
         if (ha == NULL) {
-                QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
+                QL_PRINT_2(NULL, "failed, no adapter=%ph\n",
                     (void *)fca_handle);
                 return (FC_UNBOUND);
         }
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         if (strcmp(cap, FC_NODE_WWN) == 0) {
                 bcopy((void *)&ha->loginparams.node_ww_name.raw_wwn[0],
                     ptr, 8);
                 rval = FC_CAP_FOUND;

@@ -2921,12 +3194,12 @@
 #ifdef __sparc
                 /*
                  * Disable streaming for certain 2 chip adapters
                  * below Psycho to handle Psycho byte hole issue.
                  */
-                if ((CFG_IST(ha, CFG_MULTI_CHIP_ADAPTER)) &&
-                    (!CFG_IST(ha, CFG_SBUS_CARD))) {
+                if (ha->flags & MULTI_CHIP_ADAPTER &&
+                    !CFG_IST(ha, CFG_SBUS_CARD)) {
                         for (psydip = ddi_get_parent(ha->dip); psydip;
                             psydip = ddi_get_parent(psydip)) {
                                 if (strcmp(ddi_driver_name(psydip),
                                     "pcipsy") == 0) {
                                         break;

@@ -2942,19 +3215,11 @@
                         *rptr = (uint32_t)FC_ALLOW_STREAMING;
                         EL(ha, "Allow Streaming\n");
                 }
                 rval = FC_CAP_FOUND;
         } else if (strcmp(cap, FC_CAP_PAYLOAD_SIZE) == 0) {
-                if (CFG_IST(ha, CFG_CTRL_24258081)) {
-                        *rptr = (uint32_t)CHAR_TO_SHORT(
-                            ha->init_ctrl_blk.cb24.max_frame_length[0],
-                            ha->init_ctrl_blk.cb24.max_frame_length[1]);
-                } else {
-                        *rptr = (uint32_t)CHAR_TO_SHORT(
-                            ha->init_ctrl_blk.cb.max_frame_length[0],
-                            ha->init_ctrl_blk.cb.max_frame_length[1]);
-                }
+                *rptr = ha->loginparams.common_service.rx_bufsize;
                 rval = FC_CAP_FOUND;
         } else if (strcmp(cap, FC_CAP_POST_RESET_BEHAVIOR) == 0) {
                 *rptr = FC_RESET_RETURN_ALL;
                 rval = FC_CAP_FOUND;
         } else if (strcmp(cap, FC_CAP_FCP_DMA) == 0) {

@@ -2963,11 +3228,11 @@
         } else {
                 EL(ha, "unknown=%s, FC_CAP_ERROR\n", cap);
                 rval = FC_CAP_ERROR;
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (rval);
 }
 
 /*

@@ -2995,15 +3260,15 @@
         ql_adapter_state_t      *ha;
         int                     rval;
 
         ha = ql_fca_handle_to_state(fca_handle);
         if (ha == NULL) {
-                QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
+                QL_PRINT_2(NULL, "failed, no adapter=%ph\n",
                     (void *)fca_handle);
                 return (FC_UNBOUND);
         }
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         if (strcmp(cap, FC_NODE_WWN) == 0) {
                 rval = FC_CAP_FOUND;
         } else if (strcmp(cap, FC_LOGIN_PARAMS) == 0) {
                 rval = FC_CAP_FOUND;

@@ -3016,11 +3281,11 @@
         } else {
                 EL(ha, "unknown=%s, FC_CAP_ERROR\n", cap);
                 rval = FC_CAP_ERROR;
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (rval);
 }
 
 /*

@@ -3048,22 +3313,22 @@
         clock_t                 timer = drv_usectohz(30000000);
         int                     rval = FC_SUCCESS;
 
         ha = ql_fca_handle_to_state(fca_handle);
         if (ha == NULL) {
-                QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
+                QL_PRINT_2(NULL, "failed, no adapter=%ph\n",
                     (void *)fca_handle);
                 return (FC_UNBOUND);
         }
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         mapbuf->lilp_magic = (uint16_t)MAGIC_LIRP;
         mapbuf->lilp_myalpa = ha->d_id.b.al_pa;
 
         /* Wait for suspension to end. */
         TASK_DAEMON_LOCK(ha);
-        while (ha->task_daemon_flags & QL_SUSPENDED) {
+        while (DRIVER_SUSPENDED(ha)) {
                 ha->task_daemon_flags |= SUSPENDED_WAKEUP_FLG;
 
                 /* 30 seconds from now */
                 if (cv_reltimedwait(&ha->pha->cv_dr_suspended,
                     &ha->pha->task_daemon_mutex, timer, TR_CLOCK_TICK) == -1) {

@@ -3090,22 +3355,22 @@
                  * offline condition, let's wait for few seconds
                  * for any loop transitions before we reset the.
                  * chip and restart all over again.
                  */
                 ql_delay(ha, 2000000);
-                EL(ha, "failed, FC_NOMAP\n");
-                rval = FC_NOMAP;
+                EL(ha, "failed, FC_NO_MAP\n");
+                rval = FC_NO_MAP;
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): my_alpa %xh len %xh "
-                    "data %xh %xh %xh %xh\n", ha->instance,
+                QL_PRINT_3(ha, "my_alpa %xh len %xh "
+                    "data %xh %xh %xh %xh\n",
                     mapbuf->lilp_myalpa, mapbuf->lilp_length,
                     mapbuf->lilp_alpalist[0], mapbuf->lilp_alpalist[1],
                     mapbuf->lilp_alpalist[2], mapbuf->lilp_alpalist[3]);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 #if 0
         QL_DUMP_3((uint8_t *)mapbuf, 8, sizeof (fc_lilpmap_t));
 #endif
         return (rval);
 }

@@ -3136,25 +3401,19 @@
         ql_srb_t                *sp = (ql_srb_t *)pkt->pkt_fca_private;
 
         /* Verify proper command. */
         ha = ql_cmd_setup(fca_handle, pkt, &rval);
         if (ha == NULL) {
-                QL_PRINT_2(CE_CONT, "failed, ql_cmd_setup=%xh, fcah=%ph\n",
+                QL_PRINT_2(NULL, "failed, ql_cmd_setup=%xh, fcah=%ph\n",
                     rval, fca_handle);
                 return (rval);
         }
-        QL_PRINT_3(CE_CONT, "(%d): started command:\n", ha->instance);
-#if 0
-        QL_DUMP_3((uint8_t *)&pkt->pkt_cmd_fhdr, 32,
-            sizeof (fc_frame_hdr_t) / 4);
-        QL_PRINT_3(CE_CONT, "(%d): command:\n", ha->instance);
-        QL_DUMP_3((uint8_t *)pkt->pkt_cmd, 8, pkt->pkt_cmdlen);
-#endif
+        QL_PRINT_3(ha, "started, d_id=%xh\n", pkt->pkt_cmd_fhdr.d_id);
 
         /* Reset SRB flags. */
         sp->flags &= ~(SRB_ISP_STARTED | SRB_ISP_COMPLETED | SRB_RETRY |
-            SRB_POLL | SRB_WATCHDOG_ENABLED | SRB_ABORT | SRB_UB_CALLBACK |
+            SRB_POLL | SRB_WATCHDOG_ENABLED | SRB_UB_CALLBACK |
             SRB_UB_RSCN | SRB_UB_FCP | SRB_FCP_CMD_PKT | SRB_FCP_DATA_PKT |
             SRB_FCP_RSP_PKT | SRB_IP_PKT | SRB_GENERIC_SERVICES_PKT |
             SRB_COMMAND_TIMEOUT | SRB_ABORTING | SRB_IN_DEVICE_QUEUE |
             SRB_IN_TOKEN_ARRAY | SRB_UB_FREE_REQUESTED | SRB_UB_ACQUIRED |
             SRB_MS_PKT | SRB_ELS_PKT);

@@ -3168,10 +3427,14 @@
         switch (pkt->pkt_cmd_fhdr.r_ctl) {
         case R_CTL_COMMAND:
                 if (pkt->pkt_cmd_fhdr.type == FC_TYPE_SCSI_FCP) {
                         sp->flags |= SRB_FCP_CMD_PKT;
                         rval = ql_fcp_scsi_cmd(ha, pkt, sp);
+                } else {
+                        pkt->pkt_state = FC_PKT_LOCAL_RJT;
+                        pkt->pkt_reason = FC_REASON_UNSUPPORTED;
+                        rval = FC_TRANSPORT_ERROR;
                 }
                 break;
 
         default:
                 /* Setup response header and buffer. */

@@ -3180,19 +3443,33 @@
                 }
 
                 switch (pkt->pkt_cmd_fhdr.r_ctl) {
                 case R_CTL_UNSOL_DATA:
                         if (pkt->pkt_cmd_fhdr.type == FC_TYPE_IS8802_SNAP) {
+                                if (CFG_IST(ha, CFG_FCIP_SUPPORT) &&
+                                    ha->vp_index == 0) {
                                 sp->flags |= SRB_IP_PKT;
                                 rval = ql_fcp_ip_cmd(ha, pkt, sp);
+                                } else {
+                                        cmn_err(CE_NOTE, "%s(%d) FC-IP is not "
+                                            "supported on this adapter\n",
+                                            QL_NAME, ha->instance);
+                                        pkt->pkt_state = FC_PKT_LOCAL_RJT;
+                                        pkt->pkt_reason = FC_REASON_UNSUPPORTED;
+                                        rval = FC_TRANSPORT_ERROR;
                         }
+                        }
                         break;
 
                 case R_CTL_UNSOL_CONTROL:
                         if (pkt->pkt_cmd_fhdr.type == FC_TYPE_FC_SERVICES) {
                                 sp->flags |= SRB_GENERIC_SERVICES_PKT;
                                 rval = ql_fc_services(ha, pkt);
+                        } else {
+                                pkt->pkt_state = FC_PKT_LOCAL_RJT;
+                                pkt->pkt_reason = FC_REASON_UNSUPPORTED;
+                                rval = FC_TRANSPORT_ERROR;
                         }
                         break;
 
                 case R_CTL_SOLICITED_DATA:
                 case R_CTL_STATUS:

@@ -3208,11 +3485,11 @@
 
         if (rval != FC_SUCCESS) {
                 EL(ha, "failed, rval = %xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
 
         return (rval);
 }
 

@@ -3253,29 +3530,24 @@
         int                     ub_updated = FALSE;
 
         /* Check handle. */
         ha = ql_fca_handle_to_state(fca_handle);
         if (ha == NULL) {
-                QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
+                QL_PRINT_2(NULL, "failed, no adapter=%ph\n",
                     (void *)fca_handle);
                 return (FC_UNBOUND);
         }
-        QL_PRINT_3(CE_CONT, "(%d,%d): started, count = %xh\n",
-            ha->instance, ha->vp_index, *count);
+        QL_PRINT_3(ha, "started, count = %xh\n", *count);
 
         QL_PM_LOCK(ha);
         if (ha->power_level != PM_LEVEL_D0) {
                 QL_PM_UNLOCK(ha);
-                QL_PRINT_3(CE_CONT, "(%d,%d): down done\n", ha->instance,
-                    ha->vp_index);
+                QL_PRINT_3(ha, "down done\n");
                 return (FC_FAILURE);
         }
         QL_PM_UNLOCK(ha);
 
-        /* Acquire adapter state lock. */
-        ADAPTER_STATE_LOCK(ha);
-
         /* Check the count. */
         if ((*count + ha->ub_allocated) > QL_UB_LIMIT) {
                 *count = 0;
                 EL(ha, "failed, FC_TOOMANY\n");
                 rval = FC_TOOMANY;

@@ -3387,24 +3659,22 @@
                         ub_updated = TRUE;
                         QL_UB_UNLOCK(ha);
                 }
         }
 
-        /* Release adapter state lock. */
-        ADAPTER_STATE_UNLOCK(ha);
-
         /* IP buffer. */
         if (ub_updated) {
-                if ((type == FC_TYPE_IS8802_SNAP) &&
-                    (!(CFG_IST(ha, (CFG_CTRL_6322 | CFG_CTRL_2581))))) {
+                if (type == FC_TYPE_IS8802_SNAP &&
+                    CFG_IST(ha, CFG_FCIP_SUPPORT) &&
+                    ha->vp_index == 0) {
 
                         ADAPTER_STATE_LOCK(ha);
                         ha->flags |= IP_ENABLED;
                         ADAPTER_STATE_UNLOCK(ha);
 
                         if (!(ha->flags & IP_INITIALIZED)) {
-                                if (CFG_IST(ha, CFG_CTRL_2422)) {
+                                if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
                                         ha->ip_init_ctrl_blk.cb24.mtu_size[0] =
                                             LSB(ql_ip_mtu);
                                         ha->ip_init_ctrl_blk.cb24.mtu_size[1] =
                                             MSB(ql_ip_mtu);
                                         ha->ip_init_ctrl_blk.cb24.buf_size[0] =

@@ -3452,12 +3722,11 @@
 
         if (rval != FC_SUCCESS) {
                 EL(ha, "failed=%xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d,%d): done\n", ha->instance,
-                    ha->vp_index);
+                QL_PRINT_3(ha, "done\n");
         }
         return (rval);
 }
 
 /*

@@ -3488,19 +3757,16 @@
         int                     rval = FC_SUCCESS;
 
         /* Check handle. */
         ha = ql_fca_handle_to_state(fca_handle);
         if (ha == NULL) {
-                QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
+                QL_PRINT_2(NULL, "failed, no adapter=%ph\n",
                     (void *)fca_handle);
                 return (FC_UNBOUND);
         }
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
-        /* Acquire adapter state lock. */
-        ADAPTER_STATE_LOCK(ha);
-
         /* Check all returned tokens. */
         for (index = 0; index < count; index++) {
                 fc_unsol_buf_t  *ubp;
 
                 /* Check the token range. */

@@ -3526,13 +3792,11 @@
                 sp->flags |= SRB_UB_FREE_REQUESTED;
 
                 while (!(sp->flags & SRB_UB_IN_FCA) ||
                     (sp->flags & (SRB_UB_CALLBACK | SRB_UB_ACQUIRED))) {
                         QL_UB_UNLOCK(ha);
-                        ADAPTER_STATE_UNLOCK(ha);
                         delay(drv_usectohz(100000));
-                        ADAPTER_STATE_LOCK(ha);
                         QL_UB_LOCK(ha);
                 }
                 ha->ub_array[ub_array_index] = NULL;
                 QL_UB_UNLOCK(ha);
                 ql_free_unsolicited_buffer(ha, ubp);

@@ -3542,22 +3806,21 @@
                 /*
                  * Signal any pending hardware reset when there are
                  * no more unsolicited buffers in use.
                  */
                 if (ha->ub_allocated == 0) {
+                        QL_UB_LOCK(ha);
                         cv_broadcast(&ha->pha->cv_ub);
+                        QL_UB_UNLOCK(ha);
                 }
         }
 
-        /* Release adapter state lock. */
-        ADAPTER_STATE_UNLOCK(ha);
-
         if (rval != FC_SUCCESS) {
                 EL(ha, "failed=%xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
         return (rval);
 }
 
 /*

@@ -3590,18 +3853,17 @@
         int                     ub_ip_updated = FALSE;
 
         /* Check handle. */
         ha = ql_fca_handle_to_state(fca_handle);
         if (ha == NULL) {
-                QL_PRINT_2(CE_CONT, ": failed, no adapter=%ph\n",
+                QL_PRINT_2(NULL, ": failed, no adapter=%ph\n",
                     (void *)fca_handle);
                 return (FC_UNBOUND);
         }
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         /* Acquire adapter state lock. */
-        ADAPTER_STATE_LOCK(ha);
         QL_UB_LOCK(ha);
 
         /* Check all returned tokens. */
         for (index = 0; index < count; index++) {
                 /* Check the token range. */

@@ -3647,12 +3909,10 @@
                         }
                 }
         }
 
         QL_UB_UNLOCK(ha);
-        /* Release adapter state lock. */
-        ADAPTER_STATE_UNLOCK(ha);
 
         /*
          * XXX: We should call ql_isp_rcvbuf() to return a
          * buffer to ISP only if the number of buffers fall below
          * the low water mark.

@@ -3663,11 +3923,11 @@
 
         if (rval != FC_SUCCESS) {
                 EL(ha, "failed, rval = %xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
         return (rval);
 }
 
 /*

@@ -3690,55 +3950,49 @@
  *      FC_UNBOUND - the fca_handle specified is not bound.
  *
  * Context:
  *      Kernel context.
  */
+/*ARGSUSED*/
 static int
 ql_abort(opaque_t fca_handle, fc_packet_t *pkt, int flags)
 {
         port_id_t               d_id;
         ql_link_t               *link;
         ql_adapter_state_t      *ha, *pha;
-        ql_srb_t                *sp;
         ql_tgt_t                *tq;
         ql_lun_t                *lq;
         int                     rval = FC_ABORTED;
+        ql_srb_t                *sp = (ql_srb_t *)pkt->pkt_fca_private;
 
         ha = ql_fca_handle_to_state(fca_handle);
         if (ha == NULL) {
-                QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
+                QL_PRINT_2(NULL, "failed, no adapter=%ph\n",
                     (void *)fca_handle);
                 return (FC_UNBOUND);
         }
 
         pha = ha->pha;
 
-        QL_PRINT_3(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
+        QL_PRINT_3(ha, "started\n");
 
         /* Get target queue pointer. */
         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
         tq = ql_d_id_to_queue(ha, d_id);
 
-        if ((tq == NULL) || (pha->task_daemon_flags & LOOP_DOWN)) {
-                if (tq == NULL) {
+        if ((tq == NULL) || (lq = sp->lun_queue) == NULL ||
+            (pha->task_daemon_flags & LOOP_DOWN)) {
+                if (tq == NULL || lq == NULL) {
                         EL(ha, "failed, FC_TRANSPORT_ERROR\n");
                         rval = FC_TRANSPORT_ERROR;
                 } else {
                         EL(ha, "failed, FC_OFFLINE\n");
                         rval = FC_OFFLINE;
                 }
                 return (rval);
         }
 
-        sp = (ql_srb_t *)pkt->pkt_fca_private;
-        lq = sp->lun_queue;
-
-        /* Set poll flag if sleep wanted. */
-        if (flags == KM_SLEEP) {
-                sp->flags |= SRB_POLL;
-        }
-
         /* Acquire target queue lock. */
         DEVICE_QUEUE_LOCK(tq);
         REQUEST_RING_LOCK(ha);
 
         /* If command not already started. */

@@ -3781,11 +4035,11 @@
 
                         /* Set return status */
                         pkt->pkt_reason = CS_ABORTED;
 
                         sp->cmd.next = NULL;
-                        ql_done(&sp->cmd);
+                        ql_done(&sp->cmd, B_TRUE);
                         rval = FC_ABORTED;
                 } else {
                         EL(ha, "failed, FC_BADEXCHANGE\n");
                         rval = FC_BADEXCHANGE;
                 }

@@ -3807,35 +4061,78 @@
                  */
                 REQUEST_RING_UNLOCK(ha);
                 DEVICE_QUEUE_UNLOCK(tq);
                 rval = FC_ABORTED;
         } else {
-                request_t       *ep = pha->request_ring_bp;
-                uint16_t        cnt;
+                ql_request_q_t  *req_q;
+                request_t       *pio;
+                uint32_t        index;
 
+                REQUEST_RING_UNLOCK(ha);
+                DEVICE_QUEUE_UNLOCK(tq);
+
+                INTR_LOCK(ha);
+                sp->flags |= SRB_ABORTING;
                 if (sp->handle != 0) {
-                        for (cnt = 0; cnt < REQUEST_ENTRY_CNT; cnt++) {
-                                if (sp->handle == ddi_get32(
-                                    pha->hba_buf.acc_handle, &ep->handle)) {
-                                        ep->entry_type = INVALID_ENTRY_TYPE;
-                                        break;
+                        index = sp->handle & OSC_INDEX_MASK;
+                        if (ha->outstanding_cmds[index] == sp) {
+                                ha->outstanding_cmds[index] =
+                                    QL_ABORTED_SRB(ha);
                                 }
-                                ep++;
+                        if (ha->req_q[1] != NULL && sp->rsp_q_number != 0) {
+                                req_q = ha->req_q[1];
+                        } else {
+                                req_q = ha->req_q[0];
                         }
+                        pio = sp->request_ring_ptr;
+                        if (sp->handle ==
+                            ddi_get32(req_q->req_ring.acc_handle,
+                            &pio->handle)) {
+                                EL(ha, "inflight sp=%ph, handle=%xh, "
+                                    "invalidated\n", (void *)sp, sp->handle);
+                                for (index = 0; index < sp->req_cnt; index++) {
+                                        ddi_put8(req_q->req_ring.acc_handle,
+                                            &pio->entry_type,
+                                            ABORTED_ENTRY_TYPE);
+                                        pio++;
+                                        if (pio == (request_t *)
+                                            ((uintptr_t)req_q->req_ring.bp +
+                                            req_q->req_ring.size)) {
+                                                pio = req_q->req_ring.bp;
                 }
-
+                                }
+                        }
+                        /* Decrement outstanding commands on device. */
+                        if (tq->outcnt != 0) {
+                                tq->outcnt--;
+                        }
+                        if (sp->flags & SRB_FCP_CMD_PKT &&
+                            lq->lun_outcnt != 0) {
+                                lq->lun_outcnt--;
+                        }
+                        /* Remove command from watchdog queue. */
+                        if (sp->flags & SRB_WATCHDOG_ENABLED) {
+                                ql_remove_link(&tq->wdg, &sp->wdg);
+                                sp->flags &= ~SRB_WATCHDOG_ENABLED;
+                        }
                 /* Release device queue lock. */
-                REQUEST_RING_UNLOCK(ha);
-                DEVICE_QUEUE_UNLOCK(tq);
+                        INTR_UNLOCK(ha);
 
-                sp->flags |= SRB_ABORTING;
                 (void) ql_abort_command(ha, sp);
+                        sp->handle = 0;
+                } else {
+                        /* Release device queue lock. */
+                        INTR_UNLOCK(ha);
+                }
+
+                sp->flags &= ~SRB_IN_TOKEN_ARRAY;
+                sp->flags |= SRB_ISP_COMPLETED;
                 pkt->pkt_reason = CS_ABORTED;
                 rval = FC_ABORTED;
         }
 
-        QL_PRINT_3(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
+        QL_PRINT_3(ha, "done\n");
 
         return (rval);
 }
 
 /*

@@ -3860,18 +4157,24 @@
         ql_adapter_state_t      *ha;
         int                     rval = FC_SUCCESS, rval2;
 
         ha = ql_fca_handle_to_state(fca_handle);
         if (ha == NULL) {
-                QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
+                QL_PRINT_2(NULL, "failed, no adapter=%ph\n",
                     (void *)fca_handle);
                 return (FC_UNBOUND);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d,%d): started, cmd=%d\n", ha->instance,
-            ha->vp_index, cmd);
+        QL_PRINT_3(ha, "started, cmd=%d\n", cmd);
 
+        if (ha->task_daemon_flags & (ABORT_ISP_ACTIVE | LOOP_RESYNC_ACTIVE |
+            DRIVER_STALL | ISP_ABORT_NEEDED | LOOP_RESYNC_NEEDED)) {
+                EL(ha, "driver stalled, FC_TRAN_BUSY, dtf=%xh\n",
+                    ha->task_daemon_flags);
+                return (FC_TRAN_BUSY);
+        }
+
         switch (cmd) {
         case FC_FCA_CORE:
                 /* dump firmware core if specified. */
                 if (ha->vp_index == 0) {
                         if (ql_dump_firmware(ha) != QL_SUCCESS) {

@@ -3958,12 +4261,11 @@
 
         if (rval != FC_SUCCESS) {
                 EL(ha, "cmd=%xh, failed=%xh\n", cmd, rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d,%d): done\n", ha->instance,
-                    ha->vp_index);
+                QL_PRINT_3(ha, "done\n");
         }
 
         return (rval);
 }
 

@@ -4003,33 +4305,30 @@
         int                     i0;
         uint8_t                 *bptr;
         int                     rval2, rval = FC_SUCCESS;
         uint32_t                opcode;
         uint32_t                set_flags = 0;
+        fc_fca_p2p_info_t       *p2p_info;
 
         ha = ql_fca_handle_to_state(fca_handle);
         if (ha == NULL) {
-                QL_PRINT_2(CE_CONT, ": failed, no adapter=%ph\n",
+                QL_PRINT_2(NULL, ": failed, no adapter=%ph\n",
                     (void *)fca_handle);
                 return (FC_UNBOUND);
         }
         pha = ha->pha;
 
-        QL_PRINT_3(CE_CONT, "(%d): started=%xh\n", ha->instance,
-            cmd->pm_cmd_code);
+#ifdef  QL_DEBUG_LEVEL_10
+        if (cmd->pm_cmd_code != FC_PORT_GET_FW_REV) {
+                QL_PRINT_10(ha, "started=%xh\n", cmd->pm_cmd_code);
+        }
+#endif
 
-        ql_awaken_task_daemon(ha, NULL, DRIVER_STALL, 0);
-
-        /*
-         * Wait for all outstanding commands to complete
-         */
-        index = (uint16_t)ql_wait_outstanding(ha);
-
-        if (index != MAX_OUTSTANDING_COMMANDS) {
-                ql_awaken_task_daemon(ha, NULL, 0, DRIVER_STALL);
-                ql_restart_queues(ha);
-                EL(ha, "failed, FC_TRAN_BUSY\n");
+        if (ha->task_daemon_flags & (ABORT_ISP_ACTIVE | LOOP_RESYNC_ACTIVE |
+            DRIVER_STALL | ISP_ABORT_NEEDED | LOOP_RESYNC_NEEDED)) {
+                EL(ha, "driver stalled, FC_TRAN_BUSY, dtf=%xh\n",
+                    ha->task_daemon_flags);
                 return (FC_TRAN_BUSY);
         }
 
         switch (cmd->pm_cmd_code) {
         case FC_PORT_BYPASS:

@@ -4115,70 +4414,21 @@
                         rval = FC_FAILURE;
                 }
                 QL_DUMP_UNLOCK(pha);
                 break;
         case FC_PORT_FORCE_DUMP:
-                PORTMANAGE_LOCK(ha);
                 if (ql_dump_firmware(ha) != QL_SUCCESS) {
                         EL(ha, "failed, FC_PORT_FORCE_DUMP FC_FAILURE\n");
                         rval = FC_FAILURE;
                 }
-                PORTMANAGE_UNLOCK(ha);
                 break;
-        case FC_PORT_DOWNLOAD_FW:
-                PORTMANAGE_LOCK(ha);
-                if (CFG_IST(ha, CFG_CTRL_24258081)) {
-                        if (ql_24xx_load_flash(ha, (uint8_t *)cmd->pm_data_buf,
-                            (uint32_t)cmd->pm_data_len,
-                            ha->flash_fw_addr << 2) != QL_SUCCESS) {
-                                EL(ha, "failed, FC_PORT_DOWNLOAD_FW\n");
-                                rval = FC_FAILURE;
-                        }
-                        ql_reset_chip(ha);
-                        set_flags |= ISP_ABORT_NEEDED;
-                } else {
-                        /* Save copy of the firmware. */
-                        if (pha->risc_code != NULL) {
-                                kmem_free(pha->risc_code, pha->risc_code_size);
-                                pha->risc_code = NULL;
-                                pha->risc_code_size = 0;
-                        }
-
-                        pha->risc_code = kmem_alloc(cmd->pm_data_len,
-                            KM_SLEEP);
-                        if (pha->risc_code != NULL) {
-                                pha->risc_code_size =
-                                    (uint32_t)cmd->pm_data_len;
-                                bcopy(cmd->pm_data_buf, pha->risc_code,
-                                    cmd->pm_data_len);
-
-                                /* Do abort to force reload. */
-                                ql_reset_chip(ha);
-                                if (ql_abort_isp(ha) != QL_SUCCESS) {
-                                        kmem_free(pha->risc_code,
-                                            pha->risc_code_size);
-                                        pha->risc_code = NULL;
-                                        pha->risc_code_size = 0;
-                                        ql_reset_chip(ha);
-                                        (void) ql_abort_isp(ha);
-                                        EL(ha, "failed, FC_PORT_DOWNLOAD_FW"
-                                            " FC_FAILURE\n");
-                                        rval = FC_FAILURE;
-                                }
-                        }
-                }
-                PORTMANAGE_UNLOCK(ha);
-                break;
         case FC_PORT_GET_DUMP_SIZE:
                 bp = (uint32_t *)cmd->pm_data_buf;
                 *bp = pha->risc_dump_size;
                 break;
         case FC_PORT_DIAG:
-                /*
-                 * Prevents concurrent diags
-                 */
-                PORTMANAGE_LOCK(ha);
+                EL(ha, "diag cmd=%xh\n", cmd->pm_cmd_flags);
 
                 /* Wait for suspension to end. */
                 for (timer = 0; timer < 3000 &&
                     pha->task_daemon_flags & QL_LOOP_TRANSITION; timer++) {
                         ql_delay(ha, 10000);

@@ -4185,23 +4435,30 @@
                 }
 
                 if (pha->task_daemon_flags & QL_LOOP_TRANSITION) {
                         EL(ha, "failed, FC_TRAN_BUSY-2\n");
                         rval = FC_TRAN_BUSY;
-                        PORTMANAGE_UNLOCK(ha);
                         break;
                 }
 
+                if ((rval2 = ql_stall_driver(ha, 0)) != QL_SUCCESS) {
+                        EL(ha, "stall_driver status=%xh, FC_TRAN_BUSY\n",
+                            rval2);
+                        ql_restart_driver(ha);
+                        rval = FC_TRAN_BUSY;
+                        break;
+                }
+
                 switch (cmd->pm_cmd_flags) {
                 case QL_DIAG_EXEFMW:
                         if (ql_start_firmware(ha) != QL_SUCCESS) {
                                 EL(ha, "failed, QL_DIAG_EXEFMW FC_FAILURE\n");
                                 rval = FC_FAILURE;
                         }
                         break;
                 case QL_DIAG_CHKCMDQUE:
-                        for (i0 = 1, cnt = 0; i0 < MAX_OUTSTANDING_COMMANDS;
+                        for (i0 = 1, cnt = 0; i0 < pha->osc_max_cnt;
                             i0++) {
                                 cnt += (pha->outstanding_cmds[i0] != NULL);
                         }
                         if (cnt != 0) {
                                 EL(ha, "failed, QL_DIAG_CHKCMDQUE "

@@ -4252,11 +4509,11 @@
                         }
                         /*
                          * Don't do the wrap test on a 2200 when the
                          * firmware is running.
                          */
-                        if (!CFG_IST(ha, CFG_CTRL_2200)) {
+                        if (!CFG_IST(ha, CFG_CTRL_22XX)) {
                                 mcp = (app_mbx_cmd_t *)cmd->pm_data_buf;
                                 mr.mb[1] = mcp->mb[1];
                                 mr.mb[2] = mcp->mb[2];
                                 mr.mb[3] = mcp->mb[3];
                                 mr.mb[4] = mcp->mb[4];

@@ -4330,11 +4587,11 @@
                             (uint8_t *)cmd->pm_data_buf,
                             (uint8_t *)buffer_xmt.bp,
                             cmd->pm_data_len, DDI_DEV_AUTOINCR);
 
                         /* 22xx's adapter must be in loop mode for test. */
-                        if (CFG_IST(ha, CFG_CTRL_2200)) {
+                        if (CFG_IST(ha, CFG_CTRL_22XX)) {
                                 bptr = &ha->init_ctrl_blk.cb.add_fw_opt[0];
                                 if (ha->flags & POINT_TO_POINT ||
                                     (ha->task_daemon_flags & LOOP_DOWN &&
                                     *bptr & (BIT_6 | BIT_5 | BIT_4))) {
                                         cnt = *bptr;

@@ -4358,10 +4615,14 @@
                         lb->transfer_data_address =
                             buffer_xmt.cookie.dmac_address;
                         lb->receive_data_address =
                             buffer_rcv.cookie.dmac_address;
 
+                        if (CFG_IST(ha, CFG_LOOP_POINT_SUPPORT)) {
+                                (void) ql_set_loop_point(ha, lb->options);
+                        }
+
                         if (ql_loop_back(ha, 0, lb,
                             buffer_xmt.cookie.dmac_notused,
                             buffer_rcv.cookie.dmac_notused) == QL_SUCCESS) {
                                 bzero((void *)cmd->pm_stat_buf,
                                     cmd->pm_stat_len);

@@ -4373,10 +4634,14 @@
                         } else {
                                 EL(ha, "failed, QL_DIAG_LPBDTA FC_FAILURE\n");
                                 rval = FC_FAILURE;
                         }
 
+                        if (CFG_IST(ha, CFG_LOOP_POINT_SUPPORT)) {
+                                (void) ql_set_loop_point(ha, 0);
+                        }
+
                         ql_free_phys(ha, &buffer_xmt);
                         ql_free_phys(ha, &buffer_rcv);
 
                         /* Needed to recover the f/w */
                         set_flags |= ISP_ABORT_NEEDED;

@@ -4442,11 +4707,11 @@
                          * while we are at it lets ask for
                          * real echo (bit 15)
                          */
                         echo.options = BIT_15;
                         if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING) &&
-                            !(CFG_IST(ha, CFG_CTRL_8081))) {
+                            !(CFG_IST(ha, CFG_FCOE_SUPPORT))) {
                                 echo.options = (uint16_t)
                                     (echo.options | BIT_6);
                         }
 
                         /*

@@ -4531,11 +4796,11 @@
                         EL(ha, "unknown=%xh, FC_PORT_DIAG "
                             "FC_INVALID_REQUEST\n", cmd->pm_cmd_flags);
                         rval = FC_INVALID_REQUEST;
                         break;
                 }
-                PORTMANAGE_UNLOCK(ha);
+                ql_restart_driver(ha);
                 break;
         case FC_PORT_LINK_STATE:
                 /* Check for name equal to null. */
                 for (index = 0; index < 8 && index < cmd->pm_cmd_len;
                     index++) {

@@ -4576,10 +4841,17 @@
                         cmd->pm_stat_buf[0] = (int8_t)LSB(ha->state);
                         cmd->pm_stat_buf[1] = (int8_t)MSB(ha->state);
                 }
                 break;
         case FC_PORT_INITIALIZE:
+                if ((rval2 = ql_stall_driver(ha, 0)) != QL_SUCCESS) {
+                        EL(ha, "stall_driver status=%xh, FC_TRAN_BUSY\n",
+                            rval2);
+                        ql_restart_driver(ha);
+                        rval = FC_TRAN_BUSY;
+                        break;
+                }
                 if (cmd->pm_cmd_len >= 8) {
                         tq = NULL;
                         for (index = 0; index < DEVICE_HEAD_LIST_SIZE &&
                             tq == NULL; index++) {
                                 for (link = ha->dev[index].first; link != NULL;

@@ -4609,10 +4881,11 @@
                         EL(ha, "failed, FC_PORT_INITIALIZE FC_FAILURE-2, "
                             "clen=%lxh\n", cmd->pm_cmd_len);
 
                         rval = FC_FAILURE;
                 }
+                ql_restart_driver(ha);
                 break;
         case FC_PORT_RLS:
                 if (cmd->pm_data_len < sizeof (fc_rls_acc_t)) {
                         EL(ha, "failed, buffer size passed: %lxh, "
                             "req: %lxh\n", cmd->pm_data_len,

@@ -4631,10 +4904,12 @@
 
                         rls = (fc_rls_acc_t *)cmd->pm_data_buf;
                         LITTLE_ENDIAN_32(&rls->rls_link_fail);
                         LITTLE_ENDIAN_32(&rls->rls_sync_loss);
                         LITTLE_ENDIAN_32(&rls->rls_sig_loss);
+                        LITTLE_ENDIAN_32(&rls->rls_prim_seq_err);
+                        LITTLE_ENDIAN_32(&rls->rls_invalid_word);
                         LITTLE_ENDIAN_32(&rls->rls_invalid_crc);
 #endif /* _BIG_ENDIAN */
                 }
                 break;
         case FC_PORT_GET_NODE_ID:

@@ -4650,12 +4925,18 @@
                         EL(ha, "failed, FC_PORT_SET_NODE_ID FC_FAILURE\n");
                         rval = FC_FAILURE;
                 }
                 break;
         case FC_PORT_DOWNLOAD_FCODE:
-                PORTMANAGE_LOCK(ha);
-                if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) {
+                if ((rval2 = ql_stall_driver(ha, 0)) != QL_SUCCESS) {
+                        EL(ha, "stall_driver status=%xh, FC_TRAN_BUSY\n",
+                            rval2);
+                        ql_restart_driver(ha);
+                        rval = FC_TRAN_BUSY;
+                        break;
+                }
+                if (CFG_IST(ha, CFG_ISP_FW_TYPE_1)) {
                         rval = ql_load_flash(ha, (uint8_t *)cmd->pm_data_buf,
                             (uint32_t)cmd->pm_data_len);
                 } else {
                         if (cmd->pm_data_buf[0] == 4 &&
                             cmd->pm_data_buf[8] == 0 &&

@@ -4679,12 +4960,59 @@
                 } else {
                         rval = FC_SUCCESS;
                 }
                 ql_reset_chip(ha);
                 set_flags |= ISP_ABORT_NEEDED;
-                PORTMANAGE_UNLOCK(ha);
+                ql_restart_driver(ha);
                 break;
+
+        case FC_PORT_GET_P2P_INFO:
+
+                bzero(cmd->pm_data_buf, cmd->pm_data_len);
+                if (cmd->pm_data_len < sizeof (fc_fca_p2p_info_t)) {
+                        EL(ha, "inadequate data length")
+                        rval = FC_NOMEM;
+                        break;
+                }
+
+                p2p_info = (fc_fca_p2p_info_t *)cmd->pm_data_buf;
+
+                if ((ha->topology & QL_N_PORT) &&
+                    (ha->flags & POINT_TO_POINT)) {
+                        p2p_info->fca_d_id = ha->d_id.b24;
+                        p2p_info->d_id = ha->n_port->d_id.b24;
+
+                        bcopy((void *) &ha->n_port->port_name[0],
+                            (caddr_t)&p2p_info->pwwn, 8);
+                        bcopy((void *) &ha->n_port->node_name[0],
+                            (caddr_t)&p2p_info->nwwn, 8);
+                        rval = FC_SUCCESS;
+
+                        EL(ha, "P2P HID=%xh, d_id=%xh, WWPN=%02x%02x%02x%02x"
+                            "%02x%02x%02x%02x : "
+                            "WWNN=%02x%02x%02x%02x%02x%02x%02x%02x\n",
+                            p2p_info->fca_d_id, p2p_info->d_id,
+                            ha->n_port->port_name[0],
+                            ha->n_port->port_name[1], ha->n_port->port_name[2],
+                            ha->n_port->port_name[3], ha->n_port->port_name[4],
+                            ha->n_port->port_name[5], ha->n_port->port_name[6],
+                            ha->n_port->port_name[7], ha->n_port->node_name[0],
+                            ha->n_port->node_name[1], ha->n_port->node_name[2],
+                            ha->n_port->node_name[3], ha->n_port->node_name[4],
+                            ha->n_port->node_name[5], ha->n_port->node_name[6],
+                            ha->n_port->node_name[7]);
+                        break;
+                } else {
+                        EL(ha, "No p2p info reported in non n2n topology\n");
+                        rval = FC_BADCMD;
+                }
+                break;
+
+        case FC_PORT_DOWNLOAD_FW:
+                EL(ha, "unsupported=%xh, FC_BADCMD\n", cmd->pm_cmd_code);
+                rval = FC_BADCMD;
+                break;
         default:
                 EL(ha, "unknown=%xh, FC_BADCMD\n", cmd->pm_cmd_code);
                 rval = FC_BADCMD;
                 break;
         }

@@ -4696,17 +5024,15 @@
         while (timer++ < 3000 &&
             ha->task_daemon_flags & (QL_LOOP_TRANSITION | DRIVER_STALL)) {
                 ql_delay(ha, 10000);
         }
 
-        ql_restart_queues(ha);
-
         if (rval != FC_SUCCESS) {
                 EL(ha, "failed, rval = %xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
 
         return (rval);
 }
 

@@ -4720,23 +5046,23 @@
         id.r.rsvd_1 = 0;
         id.b24 = d_id.port_id;
 
         ha = ql_fca_handle_to_state(fca_handle);
         if (ha == NULL) {
-                QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
+                QL_PRINT_2(NULL, "failed, no adapter=%ph\n",
                     (void *)fca_handle);
                 return (NULL);
         }
-        QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance, id.b24);
+        QL_PRINT_3(ha, "started, d_id=%xh\n", id.b24);
 
         tq = ql_d_id_to_queue(ha, id);
 
-        if (tq == NULL) {
-                EL(ha, "failed, tq=NULL\n");
+        if (tq == NULL && id.b24 != 0 && id.b24 != FS_BROADCAST) {
+                EL(ha, "failed, no tq available for d_id: %xh\n", id.b24);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
         return (tq);
 }
 
 /* ************************************************************************ */

@@ -4771,17 +5097,17 @@
 
         /* check that the handle is assigned by this FCA */
         ha = ql_fca_handle_to_state(fca_handle);
         if (ha == NULL) {
                 *rval = FC_UNBOUND;
-                QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
+                QL_PRINT_2(NULL, "failed, no adapter=%ph\n",
                     (void *)fca_handle);
                 return (NULL);
         }
         pha = ha->pha;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         if (ddi_in_panic() || pkt->pkt_tran_flags & FC_TRAN_DUMPING) {
                 return (ha);
         }
 

@@ -4827,50 +5153,78 @@
                         }
                         DEVICE_QUEUE_UNLOCK(tq);
                 }
         }
 
+        /* Check for packet already running. */
+        if (sp->handle != 0) {
+                *rval = FC_DEVICE_BUSY;
+                cmn_err(CE_WARN, "%s(%d) already running pkt=%p, sp=%p, "
+                    "sp->pkt=%p, sp->hdl=%x, spf=%x, cq=%p\n", QL_NAME,
+                    ha->instance, (void *)pkt, (void *)sp, (void *)sp->pkt,
+                    sp->handle, sp->flags, (void *)sp->cmd.head);
+                return (NULL);
+        }
+        if (ha->rsp_queues_cnt > 1) {
+                ADAPTER_STATE_LOCK(ha);
+                sp->rsp_q_number = ha->rsp_q_number++;
+                if (ha->rsp_q_number == ha->rsp_queues_cnt) {
+                        ha->rsp_q_number = 0;
+                }
+                ADAPTER_STATE_UNLOCK(ha);
+        } else {
+                sp->rsp_q_number = 0;
+        }
+
         /*
          * Check DMA pointers.
          */
         *rval = DDI_SUCCESS;
         if (pkt->pkt_cmd_acc != NULL && pkt->pkt_cmdlen) {
                 QL_CLEAR_DMA_HANDLE(pkt->pkt_cmd_dma);
-                *rval = ddi_check_dma_handle(pkt->pkt_cmd_dma);
-                if (*rval == DDI_SUCCESS) {
-                        *rval = ddi_check_acc_handle(pkt->pkt_cmd_acc);
+
+                *rval = qlc_fm_check_dma_handle(ha, pkt->pkt_cmd_dma);
+                if (*rval == DDI_FM_OK) {
+                        *rval = qlc_fm_check_acc_handle(ha,
+                            pkt->pkt_cmd_acc);
                 }
         }
 
         if (pkt->pkt_resp_acc != NULL && *rval == DDI_SUCCESS &&
             pkt->pkt_rsplen != 0) {
                 QL_CLEAR_DMA_HANDLE(pkt->pkt_resp_dma);
-                *rval = ddi_check_dma_handle(pkt->pkt_resp_dma);
-                if (*rval == DDI_SUCCESS) {
-                        *rval = ddi_check_acc_handle(pkt->pkt_resp_acc);
+
+                *rval = qlc_fm_check_dma_handle(ha, pkt->pkt_resp_dma);
+                if (*rval == DDI_FM_OK) {
+                        *rval = qlc_fm_check_acc_handle(ha,
+                            pkt->pkt_resp_acc);
                 }
         }
 
         /*
          * Minimum branch conditional; Change it with care.
          */
         if (((pkt->pkt_data_acc != NULL) & (*rval == DDI_SUCCESS) &
             (pkt->pkt_datalen != 0)) != 0) {
                 QL_CLEAR_DMA_HANDLE(pkt->pkt_data_dma);
-                *rval = ddi_check_dma_handle(pkt->pkt_data_dma);
-                if (*rval == DDI_SUCCESS) {
-                        *rval = ddi_check_acc_handle(pkt->pkt_data_acc);
+
+                *rval = qlc_fm_check_dma_handle(ha, pkt->pkt_data_dma);
+                if (*rval == DDI_FM_OK) {
+                        *rval = qlc_fm_check_acc_handle(ha,
+                            pkt->pkt_data_acc);
                 }
         }
 
-        if (*rval != DDI_SUCCESS) {
+        if (*rval != DDI_FM_OK) {
                 pkt->pkt_state = FC_PKT_TRAN_ERROR;
                 pkt->pkt_reason = FC_REASON_DMA_ERROR;
+                pkt->pkt_expln = FC_EXPLN_NONE;
+                pkt->pkt_action = FC_ACTION_RETRYABLE;
 
                 /* Do command callback. */
                 if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) {
-                        ql_awaken_task_daemon(ha, sp, 0, 0);
+                        ql_io_comp(sp);
                 }
                 *rval = FC_BADPACKET;
                 EL(ha, "failed, bad DMA pointers\n");
                 return (NULL);
         }

@@ -4880,11 +5234,11 @@
                 EL(ha, "failed, magic number=%xh\n", sp->magic_number);
                 return (NULL);
         }
         *rval = FC_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (ha);
 }
 
 /*

@@ -4910,27 +5264,26 @@
         la_els_logi_t           acc;
         class_svc_param_t       *class3_param;
         int                     ret;
         int                     rval = FC_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
-            pkt->pkt_cmd_fhdr.d_id);
+        QL_PRINT_3(ha, "started, d_id=%xh\n", pkt->pkt_cmd_fhdr.d_id);
 
         TASK_DAEMON_LOCK(ha);
         if (!(ha->task_daemon_flags & STATE_ONLINE)) {
                 TASK_DAEMON_UNLOCK(ha);
-                QL_PRINT_3(CE_CONT, "(%d): offline done\n", ha->instance);
+                QL_PRINT_3(ha, "offline done\n");
                 return (FC_OFFLINE);
         }
         TASK_DAEMON_UNLOCK(ha);
 
         bzero(&acc, sizeof (acc));
         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
 
         ret = QL_SUCCESS;
 
-        if (CFG_IST(ha, CFG_CTRL_2425) && ha->topology & QL_N_PORT) {
+        if (CFG_IST(ha, CFG_N2N_SUPPORT) && ha->topology & QL_N_PORT) {
                 /*
                  * In p2p topology it sends a PLOGI after determining
                  * it has the N_Port login initiative.
                  */
                 ret = ql_p2p_plogi(ha, pkt);

@@ -4972,11 +5325,12 @@
 
                 /* Build ACC. */
                 acc.ls_code.ls_code = LA_ELS_ACC;
                 acc.common_service.fcph_version = 0x2006;
                 acc.common_service.cmn_features = 0x8800;
-                acc.common_service.rx_bufsize = QL_MAX_FRAME_SIZE(ha);
+                acc.common_service.rx_bufsize =
+                    ha->loginparams.common_service.rx_bufsize;
                 acc.common_service.conc_sequences = 0xff;
                 acc.common_service.relative_offset = 0x03;
                 acc.common_service.e_d_tov = 0x7d0;
 
                 bcopy((void *)&tq->port_name[0],

@@ -5000,16 +5354,16 @@
                         rval = FC_TRAN_BUSY;
                 } else {
                         DEVICE_QUEUE_LOCK(tq);
                         tq->logout_sent = 0;
                         tq->flags &= ~TQF_NEED_AUTHENTICATION;
-                        if (CFG_IST(ha, CFG_CTRL_242581)) {
+                        if (CFG_IST(ha, CFG_IIDMA_SUPPORT)) {
                                 tq->flags |= TQF_IIDMA_NEEDED;
                         }
                         DEVICE_QUEUE_UNLOCK(tq);
 
-                        if (CFG_IST(ha, CFG_CTRL_242581)) {
+                        if (CFG_IST(ha, CFG_IIDMA_SUPPORT)) {
                                 TASK_DAEMON_LOCK(ha);
                                 ha->task_daemon_flags |= TD_IIDMA_NEEDED;
                                 TASK_DAEMON_UNLOCK(ha);
                         }
 

@@ -5064,11 +5418,11 @@
 
         if (rval != FC_SUCCESS) {
                 EL(ha, "failed, rval = %xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
         return (rval);
 }
 
 /*

@@ -5093,10 +5447,11 @@
         ql_tgt_t        tmp;
         ql_tgt_t        *tq = &tmp;
         int             rval;
         port_id_t       d_id;
         ql_srb_t        *sp = (ql_srb_t *)pkt->pkt_fca_private;
+        uint16_t        loop_id;
 
         tq->d_id.b.al_pa = 0;
         tq->d_id.b.area = 0;
         tq->d_id.b.domain = 0;
 

@@ -5106,16 +5461,16 @@
          * less unplesant than the error recovery if the wrong one is used.
          */
         for (id = 0; id <= LAST_LOCAL_LOOP_ID; id++) {
                 tq->loop_id = id;
                 rval = ql_get_port_database(ha, tq, PDF_NONE);
-                EL(ha, "rval=%xh\n", rval);
+                EL(ha, "rval=%xh, id=%x\n", rval, id);
                 /* check all the ones not logged in for possible use */
                 if (rval == QL_NOT_LOGGED_IN) {
                         if (tq->master_state == PD_STATE_PLOGI_PENDING) {
                                 ha->n_port->n_port_handle = tq->loop_id;
-                                EL(ha, "n_port_handle =%xh, master state=%x\n",
+                                EL(ha, "loop_id=%xh, master state=%x\n",
                                     tq->loop_id, tq->master_state);
                                 break;
                         }
                         /*
                          * Use a 'port unavailable' entry only

@@ -5122,27 +5477,27 @@
                          * if we used it before.
                          */
                         if (tq->master_state == PD_STATE_PORT_UNAVAILABLE) {
                                 /* if the port_id matches, reuse it */
                                 if (pkt->pkt_cmd_fhdr.d_id == tq->d_id.b24) {
-                                        EL(ha, "n_port_handle =%xh,"
+                                        EL(ha, "n_port_handle loop_id=%xh, "
                                             "master state=%xh\n",
                                             tq->loop_id, tq->master_state);
                                         break;
                                 } else if (tq->loop_id ==
                                     ha->n_port->n_port_handle) {
-                                    // avoid a lint error
+                                    /* avoid a lint error */
                                         uint16_t *hndl;
                                         uint16_t val;
 
                                         hndl = &ha->n_port->n_port_handle;
                                         val = *hndl;
                                         val++;
                                         val++;
                                         *hndl = val;
                                 }
-                        EL(ha, "rval=%xh, id=%d, n_port_handle =%xh, "
+                        EL(ha, "rval=%xh, id=%d, n_port_handle loop_id=%xh, "
                             "master state=%x\n", rval, id, tq->loop_id,
                             tq->master_state);
                         }
 
                 }

@@ -5151,20 +5506,62 @@
                                 ha->n_port->n_port_handle = tq->loop_id;
                                 EL(ha, "n_port_handle =%xh, master state=%x\n",
                                     tq->loop_id, tq->master_state);
                                 break;
                         }
-                        EL(ha, "rval=%xh, id=%d, n_port_handle =%xh, "
+                        EL(ha, "rval=%xh, id=%d, n_port_handle loop_id=%xh, "
                             "master state=%x\n", rval, id, tq->loop_id,
                             tq->master_state);
                 }
         }
         (void) ddi_dma_sync(pkt->pkt_cmd_dma, 0, 0, DDI_DMA_SYNC_FORDEV);
 
         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
+
+        /*
+         * In case fw does not have the loop id ready, driver assume 0 is
+         * used since this is p2p and there is only one remote port.
+         */
+        if (id == LAST_LOCAL_LOOP_ID + 1) {
+                EL(ha, "out of range loop id; rval=%xh, id=%xh, d_id=%xh\n",
+                    rval, id, d_id.b24);
+        } else {
+                EL(ha, "remote port loop_id '%x' has been logged in, d_id=%x\n",
+                    id, d_id.b24);
+        }
+
         tq = ql_d_id_to_queue(ha, d_id);
+
+        /*
+         * LV could use any d_id it likes.
+         * tq may not be available yet.
+         */
+        if (tq == NULL) {
+                if (id != LAST_LOCAL_LOOP_ID + 1) {
+                        loop_id = id;
+                } else {
+                        loop_id = 0;
+                }
+                /* Acquire adapter state lock. */
+                ADAPTER_STATE_LOCK(ha);
+
+                tq = ql_dev_init(ha, d_id, loop_id);
+
+                ADAPTER_STATE_UNLOCK(ha);
+        }
+
+        /*
+         * Lun0 should always allocated since tq is
+         * derived from lun queue in ql_els_passthru_entry
+         * in the interrupt handler.
+         */
+        sp->lun_queue = ql_lun_queue(ha, tq, 0);
+
+        DEVICE_QUEUE_LOCK(tq);
         ql_timeout_insert(ha, tq, sp);
+        DEVICE_QUEUE_UNLOCK(tq);
+
         ql_start_iocb(ha, sp);
 
         return (QL_CONSUMED);
 }
 

@@ -5192,17 +5589,16 @@
         la_els_logi_t           acc;
         class_svc_param_t       *class3_param;
         int                     rval = FC_SUCCESS;
         int                     accept = 0;
 
-        QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
-            pkt->pkt_cmd_fhdr.d_id);
+        QL_PRINT_3(ha, "started, d_id=%xh\n", pkt->pkt_cmd_fhdr.d_id);
 
         bzero(&acc, sizeof (acc));
         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
 
-        if (CFG_IST(ha, CFG_CTRL_2425) && ha->topology & QL_N_PORT) {
+        if (CFG_IST(ha, CFG_N2N_SUPPORT) && ha->topology & QL_N_PORT) {
                 /*
                  * d_id of zero in a FLOGI accept response in a point to point
                  * topology triggers evaluation of N Port login initiative.
                  */
                 pkt->pkt_resp_fhdr.d_id = 0;

@@ -5217,14 +5613,13 @@
                 if (tq != NULL) {
                         /*
                          * If the target port has initiative send
                          * up a PLOGI about the new device.
                          */
-                        if ((ql_wwn_cmp(ha, (la_wwn_t *)&tq->port_name[0],
-                            (la_wwn_t *)(CFG_IST(ha, CFG_CTRL_2425) ?
-                            &ha->init_ctrl_blk.cb24.port_name[0] :
-                            &ha->init_ctrl_blk.cb.port_name[0])) == 1)) {
+                        if (ql_wwn_cmp(ha, (la_wwn_t *)tq->port_name,
+                            (la_wwn_t *)ha->loginparams.nport_ww_name.raw_wwn)
+                            == 1) {
                                 ha->send_plogi_timer = 3;
                         } else {
                                 ha->send_plogi_timer = 0;
                         }
                         pkt->pkt_resp_fhdr.s_id = tq->d_id.b24;

@@ -5251,17 +5646,12 @@
                         /* clear F_Port indicator */
                         acc.common_service.cmn_features = 0x0800;
                 } else {
                         acc.common_service.cmn_features = 0x1b00;
                 }
-                CFG_IST(ha, CFG_CTRL_24258081) ?
-                    (acc.common_service.rx_bufsize = CHAR_TO_SHORT(
-                    ha->init_ctrl_blk.cb24.max_frame_length[0],
-                    ha->init_ctrl_blk.cb24.max_frame_length[1])) :
-                    (acc.common_service.rx_bufsize = CHAR_TO_SHORT(
-                    ha->init_ctrl_blk.cb.max_frame_length[0],
-                    ha->init_ctrl_blk.cb.max_frame_length[1]));
+                acc.common_service.rx_bufsize =
+                    ha->loginparams.common_service.rx_bufsize;
                 acc.common_service.conc_sequences = 0xff;
                 acc.common_service.relative_offset = 0x03;
                 acc.common_service.e_d_tov = 0x7d0;
                 if (accept) {
                         /* Use the saved N_Port WWNN and WWPN */

@@ -5309,11 +5699,11 @@
 
         if (rval != FC_SUCCESS) {
                 EL(ha, "failed, rval = %xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
         return (rval);
 }
 
 /*

@@ -5335,14 +5725,12 @@
 ql_els_logo(ql_adapter_state_t *ha, fc_packet_t *pkt)
 {
         port_id_t       d_id;
         ql_tgt_t        *tq;
         la_els_logo_t   acc;
-        int             rval = FC_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
-            pkt->pkt_cmd_fhdr.d_id);
+        QL_PRINT_3(ha, "started, d_id=%xh\n", pkt->pkt_cmd_fhdr.d_id);
 
         bzero(&acc, sizeof (acc));
         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
 
         tq = ql_d_id_to_queue(ha, d_id);

@@ -5386,17 +5774,13 @@
         }
 
         ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
             (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
 
-        if (rval != FC_SUCCESS) {
-                EL(ha, "failed, rval = %xh\n", rval);
-        } else {
-                /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
-        }
-        return (rval);
+        QL_PRINT_3(ha, "done\n");
+
+        return (FC_SUCCESS);
 }
 
 /*
  * ql_els_prli
  *      Issue a extended link service process login request.

@@ -5420,22 +5804,27 @@
         la_els_prli_t           acc;
         prli_svc_param_t        *param;
         ql_srb_t                *sp = (ql_srb_t *)pkt->pkt_fca_private;
         int                     rval = FC_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
-            pkt->pkt_cmd_fhdr.d_id);
+        QL_PRINT_3(ha, "started, d_id=%xh\n", pkt->pkt_cmd_fhdr.d_id);
 
         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
 
         tq = ql_d_id_to_queue(ha, d_id);
         if (tq != NULL) {
                 (void) ql_get_port_database(ha, tq, PDF_NONE);
 
                 if ((ha->topology & QL_N_PORT) &&
                     (tq->master_state == PD_STATE_PLOGI_COMPLETED)) {
+
+                        /* always set lun_queue */
+                        sp->lun_queue = ql_lun_queue(ha, tq, 0);
+
+                        DEVICE_QUEUE_LOCK(tq);
                         ql_timeout_insert(ha, tq, sp);
+                        DEVICE_QUEUE_UNLOCK(tq);
                         ql_start_iocb(ha, sp);
                         rval = QL_CONSUMED;
                 } else {
                         /* Build ACC. */
                         bzero(&acc, sizeof (acc));

@@ -5454,29 +5843,55 @@
                             DDI_DEV_AUTOINCR);
 
                         pkt->pkt_state = FC_PKT_SUCCESS;
                 }
         } else {
+                /* in case of P2P, tq might not have been created yet */
+                if (ha->topology & QL_N_PORT) {
+
+                        /* Acquire adapter state lock. */
+                        ADAPTER_STATE_LOCK(ha);
+                        tq = ql_dev_init(ha, d_id, ha->n_port->n_port_handle);
+                        ADAPTER_STATE_UNLOCK(ha);
+
+                        /* always alloc lun #0 */
+                        sp->lun_queue = ql_lun_queue(ha, tq, 0);
+                        bcopy((void *)&ha->n_port->port_name[0],
+                            (void *) &tq->port_name[0], 8);
+                        bcopy((void *)&ha->n_port->node_name[0],
+                            (void *) &tq->node_name[0], 8);
+
+                        DEVICE_QUEUE_LOCK(tq);
+                        ql_timeout_insert(ha, tq, sp);
+                        DEVICE_QUEUE_UNLOCK(tq);
+
+                        ql_start_iocb(ha, sp);
+                        rval = QL_CONSUMED;
+
+                } else {
+
                 la_els_rjt_t rjt;
 
                 /* Build RJT. */
                 bzero(&rjt, sizeof (rjt));
                 rjt.ls_code.ls_code = LA_ELS_RJT;
 
                 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt,
-                    (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR);
+                            (uint8_t *)pkt->pkt_resp, sizeof (rjt),
+                            DDI_DEV_AUTOINCR);
 
                 pkt->pkt_state = FC_PKT_TRAN_ERROR;
                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
                 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
         }
+        }
 
         if ((rval != FC_SUCCESS) && (rval != QL_CONSUMED)) {
                 EL(ha, "failed, rval = %xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
         return (rval);
 }
 
 /*

@@ -5497,14 +5912,12 @@
 /* ARGSUSED */
 static int
 ql_els_prlo(ql_adapter_state_t *ha, fc_packet_t *pkt)
 {
         la_els_prli_t   acc;
-        int             rval = FC_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
-            pkt->pkt_cmd_fhdr.d_id);
+        QL_PRINT_3(ha, "started, d_id=%xh\n", pkt->pkt_cmd_fhdr.d_id);
 
         /* Build ACC. */
         ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&acc,
             (uint8_t *)pkt->pkt_cmd, sizeof (acc), DDI_DEV_AUTOINCR);
 

@@ -5514,17 +5927,13 @@
         ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
             (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
 
         pkt->pkt_state = FC_PKT_SUCCESS;
 
-        if (rval != FC_SUCCESS) {
-                EL(ha, "failed, rval = %xh\n", rval);
-        } else {
-                /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
-        }
-        return (rval);
+        QL_PRINT_3(ha, "done\n");
+
+        return (FC_SUCCESS);
 }
 
 /*
  * ql_els_adisc
  *      Issue a extended link service address discovery request.

@@ -5550,13 +5959,12 @@
         ql_lun_t                *lq;
         port_id_t               d_id;
         la_els_adisc_t          acc;
         uint16_t                index, loop_id;
         ql_mbx_data_t           mr;
-        int                     rval = FC_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         bzero(&acc, sizeof (acc));
         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
 
         /*

@@ -5647,17 +6055,13 @@
         }
 
         ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
             (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
 
-        if (rval != FC_SUCCESS) {
-                EL(ha, "failed, rval = %xh\n", rval);
-        } else {
-                /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
-        }
-        return (rval);
+        QL_PRINT_3(ha, "done\n");
+
+        return (FC_SUCCESS);
 }
 
 /*
  * ql_els_linit
  *      Issue a extended link service loop initialize request.

@@ -5678,16 +6082,15 @@
 {
         ddi_dma_cookie_t        *cp;
         uint32_t                cnt;
         conv_num_t              n;
         port_id_t               d_id;
-        int                     rval = FC_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
-        if (ha->topology & QL_SNS_CONNECTION) {
+        if (ha->topology & QL_FABRIC_CONNECTION) {
                 fc_linit_req_t els;
                 lfa_cmd_t lfa;
 
                 ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
                     (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);

@@ -5742,17 +6145,13 @@
                 pkt->pkt_state = FC_PKT_TRAN_ERROR;
                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
                 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
         }
 
-        if (rval != FC_SUCCESS) {
-                EL(ha, "failed, rval = %xh\n", rval);
-        } else {
-                /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
-        }
-        return (rval);
+        QL_PRINT_3(ha, "done\n");
+
+        return (FC_SUCCESS);
 }
 
 /*
  * ql_els_lpc
  *      Issue a extended link service loop control request.

@@ -5773,16 +6172,15 @@
 {
         ddi_dma_cookie_t        *cp;
         uint32_t                cnt;
         conv_num_t              n;
         port_id_t               d_id;
-        int                     rval = FC_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
-        if (ha->topology & QL_SNS_CONNECTION) {
+        if (ha->topology & QL_FABRIC_CONNECTION) {
                 ql_lpc_t els;
                 lfa_cmd_t lfa;
 
                 ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
                     (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);

@@ -5813,11 +6211,11 @@
                 lfa.addr[0] = n.size8[0];
                 lfa.addr[1] = n.size8[1];
                 lfa.addr[2] = n.size8[2];
                 lfa.subcommand[1] = 0x71;
                 lfa.payload[4] = els.port_control;
-                bcopy((void *)&els.lpb[0], (void *)&lfa.payload[6], 32);
+                bcopy((void *)&els.lpb[0], (void *)&lfa.payload[6], 16);
 
                 if (ql_send_lfa(ha, &lfa) != QL_SUCCESS) {
                         pkt->pkt_state = FC_PKT_TRAN_ERROR;
                 } else {
                         pkt->pkt_state = FC_PKT_SUCCESS;

@@ -5835,17 +6233,13 @@
                 pkt->pkt_state = FC_PKT_TRAN_ERROR;
                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
                 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
         }
 
-        if (rval != FC_SUCCESS) {
-                EL(ha, "failed, rval = %xh\n", rval);
-        } else {
-                /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
-        }
-        return (rval);
+        QL_PRINT_3(ha, "done\n");
+
+        return (FC_SUCCESS);
 }
 
 /*
  * ql_els_lsts
  *      Issue a extended link service loop status request.

@@ -5866,16 +6260,15 @@
 {
         ddi_dma_cookie_t        *cp;
         uint32_t                cnt;
         conv_num_t              n;
         port_id_t               d_id;
-        int                     rval = FC_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
-        if (ha->topology & QL_SNS_CONNECTION) {
+        if (ha->topology & QL_FABRIC_CONNECTION) {
                 fc_lsts_req_t els;
                 lfa_cmd_t lfa;
 
                 ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
                     (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);

@@ -5926,17 +6319,13 @@
                 pkt->pkt_state = FC_PKT_TRAN_ERROR;
                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
                 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
         }
 
-        if (rval != FC_SUCCESS) {
-                EL(ha, "failed=%xh\n", rval);
-        } else {
-                /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
-        }
-        return (rval);
+        QL_PRINT_3(ha, "done\n");
+
+        return (FC_SUCCESS);
 }
 
 /*
  * ql_els_scr
  *      Issue a extended link service state change registration request.

@@ -5954,16 +6343,15 @@
  */
 static int
 ql_els_scr(ql_adapter_state_t *ha, fc_packet_t *pkt)
 {
         fc_scr_resp_t   acc;
-        int             rval = FC_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         bzero(&acc, sizeof (acc));
-        if (ha->topology & QL_SNS_CONNECTION) {
+        if (ha->topology & QL_FABRIC_CONNECTION) {
                 fc_scr_req_t els;
 
                 ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
                     (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
 

@@ -5991,17 +6379,13 @@
         }
 
         ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
             (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
 
-        if (rval != FC_SUCCESS) {
-                EL(ha, "failed, rval = %xh\n", rval);
-        } else {
-                /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
-        }
-        return (rval);
+        QL_PRINT_3(ha, "done\n");
+
+        return (FC_SUCCESS);
 }
 
 /*
  * ql_els_rscn
  *      Issue a extended link service register state

@@ -6020,16 +6404,15 @@
  */
 static int
 ql_els_rscn(ql_adapter_state_t *ha, fc_packet_t *pkt)
 {
         ql_rscn_resp_t  acc;
-        int             rval = FC_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         bzero(&acc, sizeof (acc));
-        if (ha->topology & QL_SNS_CONNECTION) {
+        if (ha->topology & QL_FABRIC_CONNECTION) {
                 /* Build ACC. */
                 acc.scr_acc = LA_ELS_ACC;
 
                 pkt->pkt_state = FC_PKT_SUCCESS;
         } else {

@@ -6042,17 +6425,13 @@
         }
 
         ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
             (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
 
-        if (rval != FC_SUCCESS) {
-                EL(ha, "failed, rval = %xh\n", rval);
-        } else {
-                /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
-        }
-        return (rval);
+        QL_PRINT_3(ha, "done\n");
+
+        return (FC_SUCCESS);
 }
 
 /*
  * ql_els_farp_req
  *      Issue FC Address Resolution Protocol (FARP)

@@ -6069,17 +6448,17 @@
  *      FC_TRANSPORT_ERROR - a transport error occurred.
  *
  * Context:
  *      Kernel context.
  */
+/* ARGSUSED */
 static int
 ql_els_farp_req(ql_adapter_state_t *ha, fc_packet_t *pkt)
 {
         ql_acc_rjt_t    acc;
-        int             rval = FC_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         bzero(&acc, sizeof (acc));
 
         /* Build ACC. */
         acc.ls_code.ls_code = LA_ELS_ACC;

@@ -6087,17 +6466,13 @@
         pkt->pkt_state = FC_PKT_SUCCESS;
 
         ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
             (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
 
-        if (rval != FC_SUCCESS) {
-                EL(ha, "failed, rval = %xh\n", rval);
-        } else {
-                /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
-        }
-        return (rval);
+        QL_PRINT_3(ha, "done\n");
+
+        return (FC_SUCCESS);
 }
 
 /*
  * ql_els_farp_reply
  *      Issue FC Address Resolution Protocol (FARP)

@@ -6119,13 +6494,12 @@
 /* ARGSUSED */
 static int
 ql_els_farp_reply(ql_adapter_state_t *ha, fc_packet_t *pkt)
 {
         ql_acc_rjt_t    acc;
-        int             rval = FC_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         bzero(&acc, sizeof (acc));
 
         /* Build ACC. */
         acc.ls_code.ls_code = LA_ELS_ACC;

@@ -6133,13 +6507,13 @@
         pkt->pkt_state = FC_PKT_SUCCESS;
 
         ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
             (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
-        return (rval);
+        return (FC_SUCCESS);
 }
 
 static int
 ql_els_rnid(ql_adapter_state_t *ha, fc_packet_t *pkt)
 {

@@ -6150,11 +6524,11 @@
         uint16_t                index;
         la_els_rnid_acc_t       acc;
         la_els_rnid_t           *req;
         size_t                  req_len;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         req_len =  FCIO_RNID_MAX_DATA_LEN + sizeof (fc_rnid_hdr_t);
         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
         index = ql_alpa_to_index[d_id.b.al_pa];
 

@@ -6190,18 +6564,18 @@
 
                 return (FC_FAILURE);
         }
 
         acc.ls_code.ls_code = LA_ELS_ACC;
-        bcopy(rnid_acc, &acc.hdr, req_len);
+        bcopy(rnid_acc, &acc.hdr, sizeof (fc_rnid_hdr_t));
         ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
             (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
 
         kmem_free(rnid_acc, req_len);
         pkt->pkt_state = FC_PKT_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (FC_SUCCESS);
 }
 
 static int

@@ -6212,11 +6586,11 @@
         ql_link_t               *link;
         ql_tgt_t                *tq;
         uint16_t                index;
         la_els_rls_acc_t        acc;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
         index = ql_alpa_to_index[d_id.b.al_pa];
 
         tq = NULL;

@@ -6267,11 +6641,11 @@
             (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
 
         kmem_free(rls_acc, sizeof (*rls_acc));
         pkt->pkt_state = FC_PKT_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (FC_SUCCESS);
 }
 
 static int

@@ -6282,11 +6656,11 @@
         fc_unsol_buf_t  *ubp;
         ql_link_t       *link, *next_link;
         int             rval = FC_SUCCESS;
         int             cnt = 5;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         /*
          * we need to ensure that q->outcnt == 0, otherwise
          * any cmd completed with PKT_PORT_OFFLINE after PLOGI
          * will confuse ulps.

@@ -6321,22 +6695,21 @@
          * return, if busy or if the plogi was asynchronous.
          */
         if ((rval != FC_SUCCESS) ||
             (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) &&
             pkt->pkt_comp)) {
-                QL_PRINT_3(CE_CONT, "(%d): done, busy or async\n",
-                    ha->instance);
+                QL_PRINT_3(ha, "done, busy or async\n");
                 return (rval);
         }
 
         /*
          * Let us give daemon sufficient time and hopefully
          * when transport retries PLOGI, it would have flushed
          * callback queue.
          */
         TASK_DAEMON_LOCK(ha);
-        for (link = ha->callback_queue.first; link != NULL;
+        for (link = ha->unsol_callback_queue.first; link != NULL;
             link = next_link) {
                 next_link = link->next;
                 sp = link->base_address;
                 if (sp->flags & SRB_UB_CALLBACK) {
                         ubp = ha->ub_array[sp->handle];

@@ -6351,11 +6724,11 @@
                         break;
                 }
         }
         TASK_DAEMON_UNLOCK(ha);
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (rval);
 }
 
 /*

@@ -6381,13 +6754,21 @@
         uint16_t                index;
         ql_tgt_t                *tq, *tq2;
         uint16_t                loop_id, first_loop_id, last_loop_id;
         int                     rval = QL_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
-            d_id.b24);
+        QL_PRINT_3(ha, "started, d_id=%xh\n", d_id.b24);
 
+        /* Do not login vports */
+        for (vha = ha->pha; vha != NULL; vha = vha->vp_next) {
+                if (vha->d_id.b24 == d_id.b24) {
+                        EL(ha, "failed=%xh, d_id=%xh vp_index=%xh\n",
+                            QL_FUNCTION_FAILED, d_id.b24, vha->vp_index);
+                        return (QL_FUNCTION_FAILED);
+                }
+        }
+
         /* Get head queue index. */
         index = ql_alpa_to_index[d_id.b.al_pa];
 
         /* Check for device already has a queue. */
         tq = NULL;

@@ -6412,12 +6793,18 @@
             !(tq->flags & TQF_FABRIC_DEVICE)) {
                 loop_id = (uint16_t)(tq->loop_id & ~PORT_LOST_ID);
         }
 
         /* Special case for Nameserver */
-        if (d_id.b24 == 0xFFFFFC) {
-                loop_id = (uint16_t)(CFG_IST(ha, CFG_CTRL_24258081) ?
+        if (d_id.b24 == FS_NAME_SERVER) {
+                if (!(ha->topology & QL_FABRIC_CONNECTION)) {
+                        EL(ha, "failed=%xh, d_id=%xh no fabric\n",
+                            QL_FUNCTION_FAILED, d_id.b24);
+                        return (QL_FUNCTION_FAILED);
+                }
+
+                loop_id = (uint16_t)(CFG_IST(ha, CFG_ISP_FW_TYPE_2) ?
                     SNS_24XX_HDL : SIMPLE_NAME_SERVER_LOOP_ID);
                 if (tq == NULL) {
                         ADAPTER_STATE_LOCK(ha);
                         tq = ql_dev_init(ha, d_id, loop_id);
                         ADAPTER_STATE_UNLOCK(ha);

@@ -6425,20 +6812,17 @@
                                 EL(ha, "failed=%xh, d_id=%xh\n",
                                     QL_FUNCTION_FAILED, d_id.b24);
                                 return (QL_FUNCTION_FAILED);
                         }
                 }
-                if (!(CFG_IST(ha, CFG_CTRL_8021))) {
+                if (!(CFG_IST(ha, CFG_CTRL_82XX))) {
                         rval = ql_login_fabric_port(ha, tq, loop_id);
                         if (rval == QL_SUCCESS) {
                                 tq->loop_id = loop_id;
                                 tq->flags |= TQF_FABRIC_DEVICE;
                                 (void) ql_get_port_database(ha, tq, PDF_NONE);
                         }
-                } else {
-                        ha->topology = (uint8_t)
-                            (ha->topology | QL_SNS_CONNECTION);
                 }
         /* Check for device already logged in. */
         } else if (tq != NULL && VALID_DEVICE_ID(ha, loop_id)) {
                 if (tq->flags & TQF_FABRIC_DEVICE) {
                         rval = ql_login_fabric_port(ha, tq, loop_id);

@@ -6453,13 +6837,13 @@
                                 DEVICE_QUEUE_LOCK(tq);
                                 tq->loop_id = loop_id;
                                 DEVICE_QUEUE_UNLOCK(tq);
                         }
                 }
-        } else if (ha->topology & QL_SNS_CONNECTION) {
+        } else if (ha->topology & QL_FABRIC_CONNECTION) {
                 /* Locate unused loop ID. */
-                if (CFG_IST(ha, CFG_CTRL_24258081)) {
+                if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
                         first_loop_id = 0;
                         last_loop_id = LAST_N_PORT_HDL;
                 } else if (ha->topology & QL_F_PORT) {
                         first_loop_id = 0;
                         last_loop_id = SNS_LAST_LOOP_ID;

@@ -6532,11 +6916,13 @@
                                 index = 1;
                                 break;
 
                         case QL_LOOP_ID_USED:
                                 tq->loop_id = PORT_NO_LOOP_ID;
+                                ADAPTER_STATE_LOCK(ha);
                                 loop_id = ha->pha->free_loop_id++;
+                                ADAPTER_STATE_UNLOCK(ha);
                                 break;
 
                         case QL_ALL_IDS_IN_USE:
                                 tq->loop_id = PORT_NO_LOOP_ID;
                                 index = 1;

@@ -6555,11 +6941,12 @@
         } else {
                 rval = QL_FUNCTION_FAILED;
         }
 
         if (rval != QL_SUCCESS) {
-                EL(ha, "failed=%xh, d_id=%xh\n", rval, d_id.b24);
+                EL(ha, "failed, rval=%xh, d_id=%xh\n",
+                    rval, d_id.b24);
         } else {
                 EL(ha, "d_id=%xh, loop_id=%xh, "
                     "wwpn=%02x%02x%02x%02x%02x%02x%02x%02xh\n", tq->d_id.b24,
                     tq->loop_id, tq->port_name[0], tq->port_name[1],
                     tq->port_name[2], tq->port_name[3], tq->port_name[4],

@@ -6591,29 +6978,27 @@
         int             retry = 0;
         port_id_t       d_id;
         ql_tgt_t        *newq;
         ql_mbx_data_t   mr;
 
-        QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
-            tq->d_id.b24);
+        QL_PRINT_3(ha, "started, d_id=%xh\n", tq->d_id.b24);
 
         /*
-         * QL_PARAMETER_ERROR also means the firmware is
-         * not able to allocate PCB entry due to resource
-         * issues, or collision.
+         * QL_PARAMETER_ERROR also means the firmware is not able to allocate
+         * PCB entry due to resource issues, or collision.
          */
         do {
                 rval = ql_login_fport(ha, tq, loop_id, LFF_NONE, &mr);
                 if ((rval == QL_PARAMETER_ERROR) ||
                     ((rval == QL_COMMAND_ERROR) && (mr.mb[1] == 2 ||
                     mr.mb[1] == 3 || mr.mb[1] == 7 || mr.mb[1] == 0xd))) {
                         retry++;
-                        drv_usecwait(10 * MILLISEC);
+                        drv_usecwait(ha->plogi_params->retry_dly_usec);
                 } else {
                         break;
                 }
-        } while (retry < 5);
+        } while (retry < ha->plogi_params->retry_cnt);
 
         switch (rval) {
         case QL_SUCCESS:
                 tq->loop_id = loop_id;
                 break;

@@ -6644,14 +7029,14 @@
                         /*
                          * This should NEVER ever happen; but this
                          * code is needed to bail out when the worst
                          * case happens - or as used to happen before
                          */
-                        QL_PRINT_2(CE_CONT, "(%d,%d): Loop ID is now "
+                        QL_PRINT_2(ha, "Loop ID is now "
                             "reassigned; old pairs: [%xh, %xh] and [%xh, %xh];"
                             "new pairs: [%xh, unknown] and [%xh, %xh]\n",
-                            ha->instance, ha->vp_index, tq->d_id.b24, loop_id,
+                            tq->d_id.b24, loop_id,
                             newq->d_id.b24, newq->loop_id, tq->d_id.b24,
                             newq->d_id.b24, loop_id);
 
                         if ((newq->d_id.b24 & 0xff) != (d_id.b24 & 0xff)) {
                                 ADAPTER_STATE_LOCK(ha);

@@ -6689,13 +7074,16 @@
                         case 2:
                         case 3:
                                 rval = QL_MEMORY_ALLOC_FAILED;
                                 break;
 
+                        case 0xd:
                         case 4:
                                 rval = QL_FUNCTION_TIMEOUT;
                                 break;
+                        case 1:
+                        case 5:
                         case 7:
                                 rval = QL_FABRIC_NOT_INITIALIZED;
                                 break;
                         default:
                                 EL(ha, "cmd rtn; mb1=%xh\n", mr.mb[1]);

@@ -6712,11 +7100,11 @@
         if (rval != QL_SUCCESS && rval != QL_PORT_ID_USED &&
             rval != QL_LOOP_ID_USED) {
                 EL(ha, "failed=%xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
         return (rval);
 }
 
 /*

@@ -6738,11 +7126,11 @@
 {
         ql_link_t       *link;
         ql_tgt_t        *tq;
         uint16_t        index;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         /* Get head queue index. */
         index = ql_alpa_to_index[d_id.b.al_pa];
 
         /* Get device queue. */

@@ -6759,11 +7147,11 @@
         if (tq != NULL && tq->flags & TQF_FABRIC_DEVICE) {
                 (void) ql_logout_fabric_port(ha, tq);
                 tq->loop_id = PORT_NO_LOOP_ID;
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (QL_SUCCESS);
 }
 
 /*

@@ -6787,17 +7175,15 @@
 {
         ql_link_t       *link;
         uint16_t        index;
         ql_tgt_t        *tq;
 
-        QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n",
-            ha->instance, d_id.b24, loop_id);
+        QL_PRINT_3(ha, "started, d_id=%xh, loop_id=%xh\n", d_id.b24, loop_id);
 
         index = ql_alpa_to_index[d_id.b.al_pa];
 
         /* If device queue exists, set proper loop ID. */
-        tq = NULL;
         for (link = ha->dev[index].first; link != NULL; link = link->next) {
                 tq = link->base_address;
                 if (tq->d_id.b24 == d_id.b24) {
                         tq->loop_id = loop_id;
 

@@ -6804,27 +7190,23 @@
                         /* Reset port down retry count. */
                         tq->port_down_retry_count = ha->port_down_retry_count;
                         tq->qfull_retry_count = ha->qfull_retry_count;
 
                         break;
-                } else {
-                        tq = NULL;
                 }
         }
 
         /* If device does not have queue. */
-        if (tq == NULL) {
+        if (link == NULL) {
                 tq = (ql_tgt_t *)kmem_zalloc(sizeof (ql_tgt_t), KM_SLEEP);
                 if (tq != NULL) {
                         /*
                          * mutex to protect the device queue,
                          * does not block interrupts.
                          */
                         mutex_init(&tq->mutex, NULL, MUTEX_DRIVER,
-                            (ha->iflags & IFLG_INTR_AIF) ?
-                            (void *)(uintptr_t)ha->intr_pri :
-                            (void *)(uintptr_t)ha->iblock_cookie);
+                            ha->intr_pri);
 
                         tq->d_id.b24 = d_id.b24;
                         tq->loop_id = loop_id;
                         tq->device.base_address = tq;
                         tq->iidma_rate = IIDMA_RATE_INIT;

@@ -6840,11 +7222,11 @@
 
         if (tq == NULL) {
                 EL(ha, "failed, d_id=%xh, loop_id=%xh\n", d_id.b24, loop_id);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
         return (tq);
 }
 
 /*

@@ -6864,15 +7246,17 @@
 {
         ql_link_t       *link;
         uint16_t        index;
         ql_lun_t        *lq;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         for (link = tq->lun_queues.first; link != NULL; link = link->next) {
                 lq = link->base_address;
                 if (lq->cmd.first != NULL) {
+                        EL(ha, "cmd %ph pending in lq=%ph, lun=%xh\n",
+                            lq->cmd.first, lq, lq->lun_no);
                         return;
                 }
         }
 
         if (tq->outcnt == 0) {

@@ -6898,74 +7282,87 @@
                                 break;
                         }
                 }
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_lun_queue
  *      Allocate LUN queue if does not exists.
  *
  * Input:
  *      ha:     adapter state pointer.
  *      tq:     target queue.
- *      lun:    LUN number.
+ *      lun_addr:       LUN number.
  *
  * Returns:
  *      NULL = failure
  *
  * Context:
  *      Kernel context.
  */
 static ql_lun_t *
-ql_lun_queue(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
+ql_lun_queue(ql_adapter_state_t *ha, ql_tgt_t *tq, uint64_t lun_addr)
 {
         ql_lun_t        *lq;
         ql_link_t       *link;
+        uint16_t        lun_no, lun_no_tmp;
+        fcp_ent_addr_t  *fcp_ent_addr = (fcp_ent_addr_t *)&lun_addr;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         /* Fast path. */
-        if (tq->last_lun_queue != NULL && tq->last_lun_queue->lun_no == lun) {
-                QL_PRINT_3(CE_CONT, "(%d): fast done\n", ha->instance);
+        if (tq->last_lun_queue != NULL && tq->last_lun_queue->lun_addr ==
+            lun_addr) {
+                QL_PRINT_3(ha, "fast done\n");
                 return (tq->last_lun_queue);
         }
 
-        if (lun >= MAX_LUNS) {
-                EL(ha, "Exceeded MAX_LUN=%d, lun=%d\n", MAX_LUNS, lun);
-                return (NULL);
-        }
         /* If device queue exists, set proper loop ID. */
-        lq = NULL;
         for (link = tq->lun_queues.first; link != NULL; link = link->next) {
                 lq = link->base_address;
-                if (lq->lun_no == lun) {
-                        QL_PRINT_3(CE_CONT, "(%d): found done\n", ha->instance);
+                if (lq->lun_addr == lun_addr) {
+                        QL_PRINT_3(ha, "found done\n");
                         tq->last_lun_queue = lq;
                         return (lq);
                 }
         }
 
-        /* If queue does exist. */
-        lq = (ql_lun_t *)kmem_zalloc(sizeof (ql_lun_t), KM_SLEEP);
+        /* Check the LUN addressing levels. */
+        if (fcp_ent_addr->ent_addr_1 != 0 || fcp_ent_addr->ent_addr_2 != 0 ||
+            fcp_ent_addr->ent_addr_3 != 0) {
+                EL(ha, "Unsupported LUN Addressing level=0x%llxh", lun_addr);
+        }
 
-        /* Initialize LUN queue. */
+        lun_no_tmp = CHAR_TO_SHORT(lobyte(fcp_ent_addr->ent_addr_0),
+            hibyte(fcp_ent_addr->ent_addr_0));
+
+        lun_no = lun_no_tmp & ~(QL_LUN_AM_MASK << 8);
+
+        if (lun_no_tmp & (QL_LUN_AM_LUN << 8)) {
+                EL(ha, "Unsupported first level LUN Addressing method=%xh, "
+                    "lun=%d(%xh)\n", lun_no_tmp & (QL_LUN_AM_MASK << 8),
+                    lun_no, lun_no_tmp);
+        }
+
+        /* Create and initialize LUN queue. */
+        lq = (ql_lun_t *)kmem_zalloc(sizeof (ql_lun_t), KM_SLEEP);
         if (lq != NULL) {
                 lq->link.base_address = lq;
-
-                lq->lun_no = lun;
                 lq->target_queue = tq;
+                lq->lun_addr = lun_addr;
+                lq->lun_no = lun_no;
 
                 DEVICE_QUEUE_LOCK(tq);
                 ql_add_link_b(&tq->lun_queues, &lq->link);
                 DEVICE_QUEUE_UNLOCK(tq);
                 tq->last_lun_queue = lq;
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (lq);
 }
 
 /*

@@ -6988,27 +7385,25 @@
 ql_fcp_scsi_cmd(ql_adapter_state_t *ha, fc_packet_t *pkt, ql_srb_t *sp)
 {
         port_id_t       d_id;
         ql_tgt_t        *tq;
         uint64_t        *ptr;
-        uint16_t        lun;
+        uint64_t        fcp_ent_addr = 0;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         tq = (ql_tgt_t *)pkt->pkt_fca_device;
         if (tq == NULL) {
                 d_id.r.rsvd_1 = 0;
                 d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
                 tq = ql_d_id_to_queue(ha, d_id);
         }
 
         sp->fcp = (struct fcp_cmd *)pkt->pkt_cmd;
-        lun = CHAR_TO_SHORT(lobyte(sp->fcp->fcp_ent_addr.ent_addr_0),
-            hibyte(sp->fcp->fcp_ent_addr.ent_addr_0));
-
+        fcp_ent_addr = *(uint64_t *)(&sp->fcp->fcp_ent_addr);
         if (tq != NULL &&
-            (sp->lun_queue = ql_lun_queue(ha, tq, lun)) != NULL) {
+            (sp->lun_queue = ql_lun_queue(ha, tq, fcp_ent_addr)) != NULL) {
 
                 /*
                  * zero out FCP response; 24 Bytes
                  */
                 ptr = (uint64_t *)pkt->pkt_resp;

@@ -7041,11 +7436,11 @@
                                             0, 0, DDI_DMA_SYNC_FORDEV);
                                 }
 
                                 /* Setup IOCB count. */
                                 if (pkt->pkt_data_cookie_cnt > ha->cmd_segs &&
-                                    (!CFG_IST(ha, CFG_CTRL_8021) ||
+                                    (!CFG_IST(ha, CFG_CTRL_82XX) ||
                                     sp->sg_dma.dma_handle == NULL)) {
                                         uint32_t        cnt;
 
                                         cnt = pkt->pkt_data_cookie_cnt -
                                             ha->cmd_segs;

@@ -7057,23 +7452,24 @@
                                         } else {
                                                 sp->req_cnt++;
                                         }
                                 }
                         }
-                        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                        QL_PRINT_3(ha, "done\n");
 
                         return (ql_start_cmd(ha, tq, pkt, sp));
                 }
         } else {
                 pkt->pkt_state = FC_PKT_LOCAL_RJT;
                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
 
-                if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp)
-                        ql_awaken_task_daemon(ha, sp, 0, 0);
+                if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) {
+                        ql_io_comp(sp);
         }
+        }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (FC_SUCCESS);
 }
 
 /*

@@ -7093,43 +7489,41 @@
 ql_task_mgmt(ql_adapter_state_t *ha, ql_tgt_t *tq, fc_packet_t *pkt,
     ql_srb_t *sp)
 {
         fcp_rsp_t               *fcpr;
         struct fcp_rsp_info     *rsp;
-        uint16_t                lun;
+        ql_lun_t                *lq = sp->lun_queue;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         fcpr = (fcp_rsp_t *)pkt->pkt_resp;
-        rsp = (struct fcp_rsp_info *)pkt->pkt_resp + sizeof (fcp_rsp_t);
+        rsp = (struct fcp_rsp_info *)(pkt->pkt_resp + sizeof (fcp_rsp_t));
 
         bzero(fcpr, pkt->pkt_rsplen);
 
         fcpr->fcp_u.fcp_status.rsp_len_set = 1;
         fcpr->fcp_response_len = 8;
-        lun = CHAR_TO_SHORT(lobyte(sp->fcp->fcp_ent_addr.ent_addr_0),
-            hibyte(sp->fcp->fcp_ent_addr.ent_addr_0));
 
         if (sp->fcp->fcp_cntl.cntl_clr_aca) {
-                if (ql_clear_aca(ha, tq, lun) != QL_SUCCESS) {
+                if (ql_clear_aca(ha, tq, lq) != QL_SUCCESS) {
                         rsp->rsp_code = FCP_TASK_MGMT_FAILED;
                 }
         } else if (sp->fcp->fcp_cntl.cntl_reset_lun) {
-                if (ql_lun_reset(ha, tq, lun) != QL_SUCCESS) {
+                if (ql_lun_reset(ha, tq, lq) != QL_SUCCESS) {
                         rsp->rsp_code = FCP_TASK_MGMT_FAILED;
                 }
         } else if (sp->fcp->fcp_cntl.cntl_reset_tgt) {
                 if (ql_target_reset(ha, tq, ha->loop_reset_delay) !=
                     QL_SUCCESS) {
                         rsp->rsp_code = FCP_TASK_MGMT_FAILED;
                 }
         } else if (sp->fcp->fcp_cntl.cntl_clr_tsk) {
-                if (ql_clear_task_set(ha, tq, lun) != QL_SUCCESS) {
+                if (ql_clear_task_set(ha, tq, lq) != QL_SUCCESS) {
                         rsp->rsp_code = FCP_TASK_MGMT_FAILED;
                 }
         } else if (sp->fcp->fcp_cntl.cntl_abort_tsk) {
-                if (ql_abort_task_set(ha, tq, lun) != QL_SUCCESS) {
+                if (ql_abort_task_set(ha, tq, lq) != QL_SUCCESS) {
                         rsp->rsp_code = FCP_TASK_MGMT_FAILED;
                 }
         } else {
                 rsp->rsp_code = FCP_TASK_MGMT_NOT_SUPPTD;
         }

@@ -7136,14 +7530,14 @@
 
         pkt->pkt_state = FC_PKT_SUCCESS;
 
         /* Do command callback. */
         if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) {
-                ql_awaken_task_daemon(ha, sp, 0, 0);
+                ql_io_comp(sp);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_fcp_ip_cmd
  *      Process fibre channel (FCP) Internet (IP) protocols commands.

@@ -7164,11 +7558,11 @@
 ql_fcp_ip_cmd(ql_adapter_state_t *ha, fc_packet_t *pkt, ql_srb_t *sp)
 {
         port_id_t       d_id;
         ql_tgt_t        *tq;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         tq = (ql_tgt_t *)pkt->pkt_fca_device;
         if (tq == NULL) {
                 d_id.r.rsvd_1 = 0;
                 d_id.b24 = pkt->pkt_cmd_fhdr.d_id;

@@ -7195,22 +7589,22 @@
                                 sp->req_cnt++;
                         }
                 } else {
                         sp->req_cnt = 1;
                 }
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
 
                 return (ql_start_cmd(ha, tq, pkt, sp));
         } else {
                 pkt->pkt_state = FC_PKT_LOCAL_RJT;
                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
 
                 if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp)
-                        ql_awaken_task_daemon(ha, sp, 0, 0);
+                        ql_io_comp(sp);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (FC_SUCCESS);
 }
 
 /*

@@ -7237,11 +7631,11 @@
         port_id_t       d_id;
         ql_tgt_t        *tq;
         ql_srb_t        *sp;
         int             rval;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&hdr,
             (uint8_t *)pkt->pkt_cmd, sizeof (hdr), DDI_DEV_AUTOINCR);
 
         bzero(&rjt, sizeof (rjt));

@@ -7256,24 +7650,33 @@
         }
 
         switch (hdr.ct_fcstype) {
         case FCSTYPE_DIRECTORY:
         case FCSTYPE_MGMTSERVICE:
+
                 /* An FCA must make sure that the header is in big endian */
                 ql_cthdr_endian(pkt->pkt_cmd_acc, pkt->pkt_cmd, B_FALSE);
 
                 d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
                 tq = ql_d_id_to_queue(ha, d_id);
                 sp = (ql_srb_t *)pkt->pkt_fca_private;
+
                 if (tq == NULL ||
                     (sp->lun_queue = ql_lun_queue(ha, tq, 0)) == NULL) {
                         pkt->pkt_state = FC_PKT_LOCAL_RJT;
                         pkt->pkt_reason = FC_REASON_NO_CONNECTION;
                         rval = QL_SUCCESS;
                         break;
                 }
 
+                if (tq->flags & TQF_LOGIN_NEEDED) {
+                        DEVICE_QUEUE_LOCK(tq);
+                        tq->flags &= ~TQF_LOGIN_NEEDED;
+                        DEVICE_QUEUE_UNLOCK(tq);
+                        (void) ql_login_fport(ha, tq, tq->loop_id, LFF_NONE,
+                            NULL);
+                }
                 /*
                  * Services data is bound to pkt_cmd_dma
                  */
                 (void) ddi_dma_sync(pkt->pkt_cmd_dma, 0, 0,
                     DDI_DMA_SYNC_FORDEV);

@@ -7284,23 +7687,22 @@
                 /* Setup IOCB count. */
                 sp->iocb = ha->ms_cmd;
                 if (pkt->pkt_resp_cookie_cnt > MS_DATA_SEGMENTS) {
                         cnt = pkt->pkt_resp_cookie_cnt - MS_DATA_SEGMENTS;
                         sp->req_cnt =
-                            (uint16_t)(cnt / CONT_TYPE_1_DATA_SEGMENTS);
-                        if (cnt % CONT_TYPE_1_DATA_SEGMENTS) {
+                            (uint16_t)(cnt / ha->cmd_cont_segs);
+                        if (cnt % ha->cmd_cont_segs) {
                                 sp->req_cnt = (uint16_t)(sp->req_cnt + 2);
                         } else {
                                 sp->req_cnt++;
                         }
                 } else {
                         sp->req_cnt = 1;
                 }
                 rval = ql_start_cmd(ha, tq, pkt, sp);
 
-                QL_PRINT_3(CE_CONT, "(%d): done, ql_start_cmd=%xh\n",
-                    ha->instance, rval);
+                QL_PRINT_3(ha, "done, ql_start_cmd=%xh\n", rval);
 
                 return (rval);
 
         default:
                 EL(ha, "unknown fcstype=%xh\n", hdr.ct_fcstype);

@@ -7321,15 +7723,14 @@
                 EL(ha, "LA_ELS_RJT, FC_REASON_UNSUPPORTED\n");
         }
 
         /* Do command callback. */
         if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) {
-                ql_awaken_task_daemon(ha, (ql_srb_t *)pkt->pkt_fca_private,
-                    0, 0);
+                ql_io_comp((ql_srb_t *)pkt->pkt_fca_private);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (FC_SUCCESS);
 }
 
 /*

@@ -7435,11 +7836,11 @@
 {
         int             rval = FC_SUCCESS;
         time_t          poll_wait = 0;
         ql_lun_t        *lq = sp->lun_queue;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         sp->handle = 0;
 
         /* Set poll for finish. */
         if (pkt->pkt_tran_flags & FC_TRAN_NO_INTR) {

@@ -7491,11 +7892,11 @@
                 sp->pkt->pkt_reason = CS_PORT_UNAVAILABLE;
 
                 /* Call done routine to handle completions. */
                 sp->cmd.next = NULL;
                 DEVICE_QUEUE_UNLOCK(tq);
-                ql_done(&sp->cmd);
+                ql_done(&sp->cmd, B_FALSE);
         } else {
                 if (ddi_in_panic() && (sp->flags & SRB_POLL)) {
                         int do_lip = 0;
 
                         DEVICE_QUEUE_UNLOCK(tq);

@@ -7539,21 +7940,15 @@
                 }
         }
 
         /* If polling, wait for finish. */
         if (poll_wait) {
-                if (ql_poll_cmd(ha, sp, poll_wait) != QL_SUCCESS) {
-                        int     res;
-
-                        res = ql_abort((opaque_t)ha, pkt, 0);
-                        if (res != FC_SUCCESS && res != FC_ABORTED) {
-                                DEVICE_QUEUE_LOCK(tq);
-                                ql_remove_link(&lq->cmd, &sp->cmd);
-                                sp->flags &= ~SRB_IN_DEVICE_QUEUE;
-                                DEVICE_QUEUE_UNLOCK(tq);
+                if (ql_poll_cmd(ha, sp, poll_wait) != QL_SUCCESS &&
+                    pkt->pkt_state == FC_PKT_SUCCESS) {
+                        pkt->pkt_state = FC_PKT_TIMEOUT;
+                        pkt->pkt_reason = FC_REASON_HW_ERROR;
                         }
-                }
 
                 if (pkt->pkt_state != FC_PKT_SUCCESS) {
                         EL(ha, "failed, FC_TRANSPORT_ERROR\n");
                         rval = FC_TRANSPORT_ERROR;
                 }

@@ -7571,10 +7966,11 @@
                                 d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
                                 (void) ql_login_port(ha, d_id);
                         }
                 }
 
+                (void) qlc_fm_check_pkt_dma_handle(ha, sp);
                 /*
                  * This should only happen during CPR dumping
                  */
                 if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) &&
                     pkt->pkt_comp) {

@@ -7581,11 +7977,11 @@
                         sp->flags &= ~SRB_POLL;
                         (*pkt->pkt_comp)(pkt);
                 }
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (rval);
 }
 
 /*

@@ -7604,20 +8000,22 @@
  *      Kernel context.
  */
 static int
 ql_poll_cmd(ql_adapter_state_t *vha, ql_srb_t *sp, time_t poll_wait)
 {
+        uint32_t                index;
         int                     rval = QL_SUCCESS;
         time_t                  msecs_left = poll_wait * 100;   /* 10ms inc */
         ql_adapter_state_t      *ha = vha->pha;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         while (sp->flags & SRB_POLL) {
 
                 if ((ha->flags & INTERRUPTS_ENABLED) == 0 ||
-                    ha->idle_timer >= 15 || ddi_in_panic()) {
+                    ha->idle_timer >= 15 || ddi_in_panic() ||
+                    curthread->t_flag & T_INTR_THREAD) {
 
                         /* If waiting for restart, do it now. */
                         if (ha->port_retry_timer != 0) {
                                 ADAPTER_STATE_LOCK(ha);
                                 ha->port_retry_timer = 0;

@@ -7626,37 +8024,65 @@
                                 TASK_DAEMON_LOCK(ha);
                                 ha->task_daemon_flags |= PORT_RETRY_NEEDED;
                                 TASK_DAEMON_UNLOCK(ha);
                         }
 
+                        ADAPTER_STATE_LOCK(ha);
+                        ha->flags |= POLL_INTR;
+                        ADAPTER_STATE_UNLOCK(ha);
+
                         if (INTERRUPT_PENDING(ha)) {
-                                (void) ql_isr((caddr_t)ha);
+                                (void) ql_isr_aif((caddr_t)ha, 0);
                                 INTR_LOCK(ha);
                                 ha->intr_claimed = TRUE;
                                 INTR_UNLOCK(ha);
                         }
+                        if (ha->flags & NO_INTR_HANDSHAKE) {
+                                for (index = 0; index < ha->rsp_queues_cnt;
+                                    index++) {
+                                        (void) ql_isr_aif((caddr_t)ha,
+                                            (caddr_t)((uintptr_t)(index + 1)));
+                                }
+                        }
 
+                        ADAPTER_STATE_LOCK(ha);
+                        ha->flags &= ~POLL_INTR;
+                        ADAPTER_STATE_UNLOCK(ha);
+
                         /*
                          * Call task thread function in case the
                          * daemon is not running.
                          */
                         TASK_DAEMON_LOCK(ha);
 
                         if (!ddi_in_panic() && QL_DAEMON_NOT_ACTIVE(ha) &&
                             QL_TASK_PENDING(ha)) {
-                                ha->task_daemon_flags |= TASK_THREAD_CALLED;
                                 ql_task_thread(ha);
-                                ha->task_daemon_flags &= ~TASK_THREAD_CALLED;
                         }
 
                         TASK_DAEMON_UNLOCK(ha);
                 }
 
-                if (msecs_left < 10) {
+                if (msecs_left == 0) {
+                        if (rval == QL_SUCCESS) {
+                                EL(ha, "timeout\n");
                         rval = QL_FUNCTION_TIMEOUT;
+                                if (ql_abort_io(ha, sp) == QL_SUCCESS) {
+                                        sp->pkt->pkt_reason = CS_ABORTED;
+                                        sp->cmd.next = NULL;
+                                        ql_done(&sp->cmd, B_FALSE);
                         break;
                 }
+                                sp->flags |= SRB_COMMAND_TIMEOUT;
+                                EL(ha, "abort failed, isp_abort_needed\n");
+                                ql_awaken_task_daemon(ha, NULL,
+                                    ISP_ABORT_NEEDED, 0);
+                                msecs_left = 30 * 100;
+                        } else {
+                                break;
+                        }
+                }
 
                 /*
                  * Polling interval is 10 milli seconds; Increasing
                  * the polling interval to seconds since disk IO
                  * timeout values are ~60 seconds is tempting enough,

@@ -7667,11 +8093,11 @@
                  */
                 ql_delay(ha, 10000);
                 msecs_left -= 10;
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (rval);
 }
 
 /*

@@ -7695,16 +8121,15 @@
         ql_srb_t                *sp;
         ql_link_t               *link;
         ql_tgt_t                *tq = lq->target_queue;
         ql_adapter_state_t      *ha = vha->pha;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         if (ddi_in_panic()) {
                 DEVICE_QUEUE_UNLOCK(tq);
-                QL_PRINT_3(CE_CONT, "(%d): panic/active exit\n",
-                    ha->instance);
+                QL_PRINT_3(ha, "panic/active exit\n");
                 return;
         }
 
         while ((link = lq->cmd.first) != NULL) {
                 sp = link->base_address;

@@ -7711,17 +8136,16 @@
 
                 /* Exit if can not start commands. */
                 if (DRIVER_SUSPENDED(ha) ||
                     (ha->flags & ONLINE) == 0 ||
                     !VALID_DEVICE_ID(ha, tq->loop_id) ||
-                    sp->flags & SRB_ABORT ||
                     tq->flags & (TQF_RSCN_RCVD | TQF_NEED_AUTHENTICATION |
                     TQF_QUEUE_SUSPENDED)) {
                         EL(vha, "break, d_id=%xh, tdf=%xh, tqf=%xh, spf=%xh, "
-                            "haf=%xh, loop_id=%xh\n", tq->d_id.b24,
+                            "haf=%xh, loop_id=%xh sp=%ph\n", tq->d_id.b24,
                             ha->task_daemon_flags, tq->flags, sp->flags,
-                            ha->flags, tq->loop_id);
+                            ha->flags, tq->loop_id, sp);
                         break;
                 }
 
                 /*
                  * Find out the LUN number for untagged command use.

@@ -7730,12 +8154,12 @@
                  * or if reached LUN execution throttle.
                  */
                 if (sp->flags & SRB_FCP_CMD_PKT) {
                         if (lq->flags & LQF_UNTAGGED_PENDING ||
                             lq->lun_outcnt >= ha->execution_throttle) {
-                                QL_PRINT_8(CE_CONT, "(%d): break, d_id=%xh, "
-                                    "lf=%xh, lun_outcnt=%xh\n", ha->instance,
+                                QL_PRINT_8(ha, "break, d_id=%xh, "
+                                    "lf=%xh, lun_outcnt=%xh\n",
                                     tq->d_id.b24, lq->flags, lq->lun_outcnt);
                                 break;
                         }
                         if (sp->fcp->fcp_cntl.cntl_qtype ==
                             FCP_QTYPE_UNTAGGED) {

@@ -7761,59 +8185,68 @@
         }
 
         /* Release device queue lock. */
         DEVICE_QUEUE_UNLOCK(tq);
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_done
  *      Process completed commands.
  *
  * Input:
  *      link:   first command link in chain.
+ *      cmplt:  do command complete call back.
  *
  * Context:
  *      Interrupt or Kernel context, no mailbox commands allowed.
  */
 void
-ql_done(ql_link_t *link)
+ql_done(ql_link_t *link, boolean_t cmplt)
 {
         ql_adapter_state_t      *ha;
         ql_link_t               *next_link;
         ql_srb_t                *sp;
         ql_tgt_t                *tq;
         ql_lun_t                *lq;
+        uint64_t                set_flags;
 
-        QL_PRINT_3(CE_CONT, "started\n");
+        QL_PRINT_3(NULL, "started\n");
 
         for (; link != NULL; link = next_link) {
                 next_link = link->next;
                 sp = link->base_address;
+                link->prev = link->next = NULL;
+                link->head = NULL;
                 ha = sp->ha;
+                set_flags = 0;
 
                 if (sp->flags & SRB_UB_CALLBACK) {
                         QL_UB_LOCK(ha);
                         if (sp->flags & SRB_UB_IN_ISP) {
                                 if (ha->ub_outcnt != 0) {
                                         ha->ub_outcnt--;
                                 }
-                                QL_UB_UNLOCK(ha);
-                                ql_isp_rcvbuf(ha);
-                                QL_UB_LOCK(ha);
+                                if (ha->flags & IP_ENABLED) {
+                                        set_flags |= NEED_UNSOLICITED_BUFFERS;
                         }
+                        }
                         QL_UB_UNLOCK(ha);
-                        ql_awaken_task_daemon(ha, sp, 0, 0);
+                        ql_awaken_task_daemon(ha, sp, set_flags, 0);
                 } else {
                         /* Free outstanding command slot. */
+                        INTR_LOCK(ha);
                         if (sp->handle != 0) {
-                                ha->outstanding_cmds[
+                                EL(ha, "free sp=%ph, sp->hdl=%xh\n",
+                                    (void *)sp, sp->handle);
+                                ha->pha->outstanding_cmds[
                                     sp->handle & OSC_INDEX_MASK] = NULL;
                                 sp->handle = 0;
                                 sp->flags &= ~SRB_IN_TOKEN_ARRAY;
                         }
+                        INTR_UNLOCK(ha);
 
                         /* Acquire device queue lock. */
                         lq = sp->lun_queue;
                         tq = lq->target_queue;
                         DEVICE_QUEUE_LOCK(tq);

@@ -7872,11 +8305,11 @@
                                 sp->wdg_q_time = sp->init_wdg_q_time;
 
                                 /* Issue marker command on reset status. */
                                 if (!(ha->task_daemon_flags & LOOP_DOWN) &&
                                     (sp->pkt->pkt_reason == CS_RESET ||
-                                    (CFG_IST(ha, CFG_CTRL_24258081) &&
+                                    (CFG_IST(ha, CFG_ISP_FW_TYPE_2) &&
                                     sp->pkt->pkt_reason == CS_ABORTED))) {
                                         (void) ql_marker(ha, tq->loop_id, 0,
                                             MK_SYNC_ID);
                                 }
 

@@ -7914,17 +8347,10 @@
                                 switch (sp->pkt->pkt_reason) {
                                 case CS_COMPLETE:
                                         sp->pkt->pkt_state = FC_PKT_SUCCESS;
                                         break;
                                 case CS_RESET:
-                                        /* Issue marker command. */
-                                        if (!(ha->task_daemon_flags &
-                                            LOOP_DOWN)) {
-                                                (void) ql_marker(ha,
-                                                    tq->loop_id, 0,
-                                                    MK_SYNC_ID);
-                                        }
                                         sp->pkt->pkt_state =
                                             FC_PKT_PORT_OFFLINE;
                                         sp->pkt->pkt_reason =
                                             FC_REASON_ABORTED;
                                         break;

@@ -7979,10 +8405,11 @@
                                         }
                                         DEVICE_QUEUE_UNLOCK(tq);
                                         break;
 
                                 case CS_TRANSPORT:
+                                case CS_DEV_NOT_READY:
                                         sp->pkt->pkt_state = FC_PKT_LOCAL_RJT;
                                         sp->pkt->pkt_reason =
                                             FC_PKT_TRAN_ERROR;
                                         break;
 

@@ -8000,27 +8427,26 @@
                                         sp->pkt->pkt_reason =
                                             FC_REASON_HW_ERROR;
                                         break;
                                 }
 
+                                (void) qlc_fm_check_pkt_dma_handle(ha, sp);
+
                                 /* Now call the pkt completion callback */
                                 if (sp->flags & SRB_POLL) {
                                         sp->flags &= ~SRB_POLL;
-                                } else if (sp->pkt->pkt_comp) {
-                                        if (sp->pkt->pkt_tran_flags &
-                                            FC_TRAN_IMMEDIATE_CB) {
-                                                (*sp->pkt->pkt_comp)(sp->pkt);
+                                } else if (cmplt == B_TRUE &&
+                                    sp->pkt->pkt_comp) {
+                                        (sp->pkt->pkt_comp)(sp->pkt);
                                         } else {
-                                                ql_awaken_task_daemon(ha, sp,
-                                                    0, 0);
+                                        ql_io_comp(sp);
                                         }
                                 }
                         }
                 }
-        }
 
-        QL_PRINT_3(CE_CONT, "done\n");
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_awaken_task_daemon
  *      Adds command completion callback to callback queue and/or

@@ -8035,60 +8461,50 @@
  * Context:
  *      Interrupt or Kernel context, no mailbox commands allowed.
  */
 void
 ql_awaken_task_daemon(ql_adapter_state_t *vha, ql_srb_t *sp,
-    uint32_t set_flags, uint32_t reset_flags)
+    uint64_t set_flags, uint64_t reset_flags)
 {
         ql_adapter_state_t      *ha = vha->pha;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started, sp=%p set_flags=%llx reset_flags=%llx\n",
+            sp, set_flags, reset_flags);
 
         /* Acquire task daemon lock. */
         TASK_DAEMON_LOCK(ha);
 
-        if (set_flags & ISP_ABORT_NEEDED) {
-                if (ha->task_daemon_flags & ABORT_ISP_ACTIVE) {
-                        set_flags &= ~ISP_ABORT_NEEDED;
+        if (set_flags) {
+                ha->task_daemon_flags |= set_flags;
                 }
+        if (reset_flags) {
+                ha->task_daemon_flags &= ~reset_flags;
         }
 
-        ha->task_daemon_flags |= set_flags;
-        ha->task_daemon_flags &= ~reset_flags;
-
-        if (QL_DAEMON_SUSPENDED(ha)) {
-                if (sp != NULL) {
+        if (!(ha->task_daemon_flags & TASK_DAEMON_ALIVE_FLG)) {
+                EL(ha, "done, not alive dtf=%xh\n", ha->task_daemon_flags);
                         TASK_DAEMON_UNLOCK(ha);
+                return;
+        }
 
-                        /* Do callback. */
+        if (sp != NULL) {
                         if (sp->flags & SRB_UB_CALLBACK) {
-                                ql_unsol_callback(sp);
+                        ql_add_link_b(&ha->unsol_callback_queue, &sp->cmd);
                         } else {
-                                (*sp->pkt->pkt_comp)(sp->pkt);
+                        EL(ha, "sp=%p, spf=%xh is not SRB_UB_CALLBACK",
+                            sp->flags);
                         }
-                } else {
-                        if (!(curthread->t_flag & T_INTR_THREAD) &&
-                            !(ha->task_daemon_flags & TASK_THREAD_CALLED)) {
-                                ha->task_daemon_flags |= TASK_THREAD_CALLED;
-                                ql_task_thread(ha);
-                                ha->task_daemon_flags &= ~TASK_THREAD_CALLED;
                         }
 
-                        TASK_DAEMON_UNLOCK(ha);
-                }
-        } else {
-                if (sp != NULL) {
-                        ql_add_link_b(&ha->callback_queue, &sp->cmd);
-                }
-
-                if (ha->task_daemon_flags & TASK_DAEMON_SLEEPING_FLG) {
+        if (!ha->driver_thread_awake) {
+                QL_PRINT_3(ha, "driver_thread_awake\n");
                         cv_broadcast(&ha->cv_task_daemon);
                 }
+
                 TASK_DAEMON_UNLOCK(ha);
-        }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_task_daemon
  *      Thread that is awaken by the driver when a

@@ -8103,61 +8519,46 @@
 static void
 ql_task_daemon(void *arg)
 {
         ql_adapter_state_t      *ha = (void *)arg;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
-        CALLB_CPR_INIT(&ha->cprinfo, &ha->task_daemon_mutex, callb_generic_cpr,
-            "ql_task_daemon");
-
         /* Acquire task daemon lock. */
         TASK_DAEMON_LOCK(ha);
 
-        ha->task_daemon_flags |= TASK_DAEMON_ALIVE_FLG;
-
         while ((ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) == 0) {
                 ql_task_thread(ha);
 
-                QL_PRINT_3(CE_CONT, "(%d): Going to sleep\n", ha->instance);
-
                 /*
                  * Before we wait on the conditional variable, we
                  * need to check if STOP_FLG is set for us to terminate
                  */
                 if (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) {
                         break;
                 }
 
-                /*LINTED [Solaris CALLB_CPR_SAFE_BEGIN Lint error]*/
-                CALLB_CPR_SAFE_BEGIN(&ha->cprinfo);
-
+                QL_PRINT_3(ha, "Going to sleep\n");
                 ha->task_daemon_flags |= TASK_DAEMON_SLEEPING_FLG;
 
                 /* If killed, stop task daemon */
                 if (cv_wait_sig(&ha->cv_task_daemon,
                     &ha->task_daemon_mutex) == 0) {
-                        ha->task_daemon_flags |= TASK_DAEMON_STOP_FLG;
+                        QL_PRINT_10(ha, "killed\n");
+                        break;
                 }
 
+                QL_PRINT_3(ha, "Awakened\n");
                 ha->task_daemon_flags &= ~TASK_DAEMON_SLEEPING_FLG;
-
-                /*LINTED [Solaris CALLB_CPR_SAFE_END Lint error]*/
-                CALLB_CPR_SAFE_END(&ha->cprinfo, &ha->task_daemon_mutex);
-
-                QL_PRINT_3(CE_CONT, "(%d): Awakened\n", ha->instance);
         }
 
-        ha->task_daemon_flags &= ~(TASK_DAEMON_STOP_FLG |
+        ha->task_daemon_flags &= ~(TASK_DAEMON_SLEEPING_FLG |
             TASK_DAEMON_ALIVE_FLG);
 
-        /*LINTED [Solaris CALLB_CPR_EXIT Lint error]*/
-        CALLB_CPR_EXIT(&ha->cprinfo);
+        TASK_DAEMON_UNLOCK(ha);
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
-
-        thread_exit();
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_task_thread
  *      Thread run by daemon.

@@ -8170,106 +8571,119 @@
  *      Kernel context.
  */
 static void
 ql_task_thread(ql_adapter_state_t *ha)
 {
-        int                     loop_again;
+        boolean_t               loop_again;
         ql_srb_t                *sp;
-        ql_head_t               *head;
         ql_link_t               *link;
         caddr_t                 msg;
         ql_adapter_state_t      *vha;
 
+        ha->driver_thread_awake++;
         do {
-                QL_PRINT_3(CE_CONT, "(%d): task_daemon_flags=%xh\n",
-                    ha->instance, ha->task_daemon_flags);
+                loop_again = B_FALSE;
 
-                loop_again = FALSE;
+                if (ha->sf != ha->flags ||
+                    (ha->task_daemon_flags & ~DTF_EL_MSG_SKIP_FLGS) != ha->df ||
+                    ha->cf != ha->cfg_flags) {
+                        ha->sf = ha->flags;
+                        ha->df = ha->task_daemon_flags & ~DTF_EL_MSG_SKIP_FLGS;
+                        ha->cf = ha->cfg_flags;
+                        EL(ha, "df=%xh, sf=%xh, cf=%xh\n",
+                            ha->df, ha->sf, ha->cf);
+                }
 
                 QL_PM_LOCK(ha);
                 if (ha->power_level != PM_LEVEL_D0) {
                         QL_PM_UNLOCK(ha);
-                        ha->task_daemon_flags |= TASK_DAEMON_STALLED_FLG;
+                        ha->task_daemon_flags |= DRIVER_STALL |
+                            TASK_DAEMON_STALLED_FLG;
                         break;
                 }
                 QL_PM_UNLOCK(ha);
 
-                /* IDC event. */
-                if (ha->task_daemon_flags & IDC_EVENT) {
-                        ha->task_daemon_flags &= ~IDC_EVENT;
+                if (ha->flags & ADAPTER_SUSPENDED) {
+                        ha->task_daemon_flags |= TASK_DAEMON_STALLED_FLG;
+                        break;
+                }
+
+                /* Handle FW IDC events. */
+                while (ha->flags & (IDC_STALL_NEEDED | IDC_RESTART_NEEDED |
+                    IDC_ACK_NEEDED)) {
                         TASK_DAEMON_UNLOCK(ha);
-                        ql_process_idc_event(ha);
+                        ql_idc(ha);
                         TASK_DAEMON_LOCK(ha);
-                        loop_again = TRUE;
+                        loop_again = B_TRUE;
                 }
 
-                if (ha->flags & ADAPTER_SUSPENDED || ha->task_daemon_flags &
+                if (ha->task_daemon_flags &
                     (TASK_DAEMON_STOP_FLG | DRIVER_STALL) ||
-                    (ha->flags & ONLINE) == 0) {
+                    !(ha->flags & ONLINE)) {
                         ha->task_daemon_flags |= TASK_DAEMON_STALLED_FLG;
                         break;
                 }
                 ha->task_daemon_flags &= ~TASK_DAEMON_STALLED_FLG;
 
-                if (ha->task_daemon_flags & ISP_ABORT_NEEDED) {
+                /* Store error log. */
+                if (ha->errlog[0] != 0 &&
+                    !(ha->task_daemon_flags & ISP_ABORT_NEEDED)) {
                         TASK_DAEMON_UNLOCK(ha);
-                        if (ha->log_parity_pause == B_TRUE) {
-                                (void) ql_flash_errlog(ha,
-                                    FLASH_ERRLOG_PARITY_ERR, 0,
-                                    MSW(ha->parity_stat_err),
-                                    LSW(ha->parity_stat_err));
-                                ha->log_parity_pause = B_FALSE;
-                        }
-                        ql_port_state(ha, FC_STATE_OFFLINE, FC_STATE_CHANGE);
+                        (void) ql_flash_errlog(ha, ha->errlog[0],
+                            ha->errlog[1], ha->errlog[2], ha->errlog[3]);
+                        ha->errlog[0] = 0;
                         TASK_DAEMON_LOCK(ha);
-                        loop_again = TRUE;
+                        loop_again = B_TRUE;
                 }
 
                 /* Idle Check. */
                 if (ha->task_daemon_flags & TASK_DAEMON_IDLE_CHK_FLG) {
                         ha->task_daemon_flags &= ~TASK_DAEMON_IDLE_CHK_FLG;
-                        if (!(ha->task_daemon_flags & QL_SUSPENDED)) {
+                        if (!DRIVER_SUSPENDED(ha)) {
                                 TASK_DAEMON_UNLOCK(ha);
                                 ql_idle_check(ha);
                                 TASK_DAEMON_LOCK(ha);
-                                loop_again = TRUE;
+                                loop_again = B_TRUE;
                         }
                 }
 
                 /* Crystal+ port#0 bypass transition */
                 if (ha->task_daemon_flags & HANDLE_PORT_BYPASS_CHANGE) {
                         ha->task_daemon_flags &= ~HANDLE_PORT_BYPASS_CHANGE;
                         TASK_DAEMON_UNLOCK(ha);
                         (void) ql_initiate_lip(ha);
                         TASK_DAEMON_LOCK(ha);
-                        loop_again = TRUE;
+                        loop_again = B_TRUE;
                 }
 
                 /* Abort queues needed. */
                 if (ha->task_daemon_flags & ABORT_QUEUES_NEEDED) {
                         ha->task_daemon_flags &= ~ABORT_QUEUES_NEEDED;
+                        if (ha->flags & ABORT_CMDS_LOOP_DOWN_TMO) {
                         TASK_DAEMON_UNLOCK(ha);
                         ql_abort_queues(ha);
                         TASK_DAEMON_LOCK(ha);
+                                loop_again = B_TRUE;
                 }
+                }
 
                 /* Not suspended, awaken waiting routines. */
-                if (!(ha->task_daemon_flags & QL_SUSPENDED) &&
+                if (!DRIVER_SUSPENDED(ha) &&
                     ha->task_daemon_flags & SUSPENDED_WAKEUP_FLG) {
                         ha->task_daemon_flags &= ~SUSPENDED_WAKEUP_FLG;
                         cv_broadcast(&ha->cv_dr_suspended);
-                        loop_again = TRUE;
+                        loop_again = B_TRUE;
                 }
 
                 /* Handle RSCN changes. */
                 for (vha = ha; vha != NULL; vha = vha->vp_next) {
                         if (vha->task_daemon_flags & RSCN_UPDATE_NEEDED) {
                                 vha->task_daemon_flags &= ~RSCN_UPDATE_NEEDED;
                                 TASK_DAEMON_UNLOCK(ha);
                                 (void) ql_handle_rscn_update(vha);
                                 TASK_DAEMON_LOCK(ha);
-                                loop_again = TRUE;
+                                loop_again = B_TRUE;
                         }
                 }
 
                 /* Handle state changes. */
                 for (vha = ha; vha != NULL; vha = vha->vp_next) {

@@ -8291,10 +8705,11 @@
                                                 TASK_DAEMON_UNLOCK(ha);
                                                 ql_cmd_wait(ha);
                                                 TASK_DAEMON_LOCK(ha);
                                                 ha->task_daemon_flags &=
                                                     ~COMMAND_WAIT_ACTIVE;
+                                                loop_again = B_TRUE;
                                         }
                                 }
 
                                 msg = NULL;
                                 if (FC_PORT_STATE_MASK(vha->state) ==

@@ -8333,44 +8748,25 @@
                                             "%s", QL_NAME, ha->instance,
                                             vha->vp_index, msg);
                                 }
 
                                 if (vha->flags & FCA_BOUND) {
-                                        QL_PRINT_10(CE_CONT, "(%d,%d): statec_"
-                                            "cb state=%xh\n", ha->instance,
-                                            vha->vp_index, vha->state);
+                                        QL_PRINT_10(vha, "statec_"
+                                            "cb state=%xh\n",
+                                            vha->state);
                                         TASK_DAEMON_UNLOCK(ha);
                                         (vha->bind_info.port_statec_cb)
                                             (vha->bind_info.port_handle,
                                             vha->state);
                                         TASK_DAEMON_LOCK(ha);
+                                        loop_again = B_TRUE;
                                 }
-                                loop_again = TRUE;
                         }
                 }
 
-                if (ha->task_daemon_flags & LIP_RESET_PENDING &&
-                    !(ha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN)) {
-                        EL(ha, "processing LIP reset\n");
-                        ha->task_daemon_flags &= ~LIP_RESET_PENDING;
-                        TASK_DAEMON_UNLOCK(ha);
-                        for (vha = ha; vha != NULL; vha = vha->vp_next) {
-                                if (vha->flags & FCA_BOUND) {
-                                        QL_PRINT_10(CE_CONT, "(%d,%d): statec_"
-                                            "cb reset\n", ha->instance,
-                                            vha->vp_index);
-                                        (vha->bind_info.port_statec_cb)
-                                            (vha->bind_info.port_handle,
-                                            FC_STATE_TARGET_PORT_RESET);
-                                }
-                        }
-                        TASK_DAEMON_LOCK(ha);
-                        loop_again = TRUE;
-                }
-
-                if (QL_IS_SET(ha->task_daemon_flags, NEED_UNSOLICITED_BUFFERS |
-                    FIRMWARE_UP)) {
+                if (ha->task_daemon_flags & NEED_UNSOLICITED_BUFFERS &&
+                    ha->task_daemon_flags & FIRMWARE_UP) {
                         /*
                          * The firmware needs more unsolicited
                          * buffers. We cannot allocate any new
                          * buffers unless the ULP module requests
                          * for new buffers. All we can do here is

@@ -8379,48 +8775,61 @@
                          */
                         ha->task_daemon_flags &= ~NEED_UNSOLICITED_BUFFERS;
                         TASK_DAEMON_UNLOCK(ha);
                         ql_isp_rcvbuf(ha);
                         TASK_DAEMON_LOCK(ha);
-                        loop_again = TRUE;
+                        loop_again = B_TRUE;
                 }
 
+                if (ha->task_daemon_flags & WATCHDOG_NEEDED) {
+                        ha->task_daemon_flags &= ~WATCHDOG_NEEDED;
+                        TASK_DAEMON_UNLOCK(ha);
+                        ql_watchdog(ha);
+                        TASK_DAEMON_LOCK(ha);
+                        loop_again = B_TRUE;
+                }
+
                 if (ha->task_daemon_flags & ISP_ABORT_NEEDED) {
                         TASK_DAEMON_UNLOCK(ha);
                         (void) ql_abort_isp(ha);
                         TASK_DAEMON_LOCK(ha);
-                        loop_again = TRUE;
+                        loop_again = B_TRUE;
                 }
 
-                if (!(ha->task_daemon_flags & (LOOP_DOWN | DRIVER_STALL |
-                    COMMAND_WAIT_NEEDED))) {
-                        if (QL_IS_SET(ha->task_daemon_flags,
-                            RESET_MARKER_NEEDED | FIRMWARE_UP)) {
-                                ha->task_daemon_flags &= ~RESET_MARKER_NEEDED;
-                                if (!(ha->task_daemon_flags & RESET_ACTIVE)) {
-                                        ha->task_daemon_flags |= RESET_ACTIVE;
+                if (!(ha->task_daemon_flags & (COMMAND_WAIT_NEEDED |
+                    ABORT_QUEUES_NEEDED | ISP_ABORT_NEEDED | LOOP_DOWN)) &&
+                    ha->task_daemon_flags & FIRMWARE_UP) {
+                        if (ha->task_daemon_flags & MARKER_NEEDED) {
+                                if (!(ha->task_daemon_flags & MARKER_ACTIVE)) {
+                                        ha->task_daemon_flags |= MARKER_ACTIVE;
+                                        ha->task_daemon_flags &= ~MARKER_NEEDED;
                                         TASK_DAEMON_UNLOCK(ha);
                                         for (vha = ha; vha != NULL;
                                             vha = vha->vp_next) {
-                                                ql_rst_aen(vha);
+                                                (void) ql_marker(vha, 0, 0,
+                                                    MK_SYNC_ALL);
                                         }
                                         TASK_DAEMON_LOCK(ha);
-                                        ha->task_daemon_flags &= ~RESET_ACTIVE;
-                                        loop_again = TRUE;
+                                        ha->task_daemon_flags &= ~MARKER_ACTIVE;
+                                        TASK_DAEMON_UNLOCK(ha);
+                                        ql_restart_queues(ha);
+                                        TASK_DAEMON_LOCK(ha);
+                                        loop_again = B_TRUE;
+                                } else {
+                                        ha->task_daemon_flags &= ~MARKER_NEEDED;
                                 }
                         }
 
-                        if (QL_IS_SET(ha->task_daemon_flags,
-                            LOOP_RESYNC_NEEDED | FIRMWARE_UP)) {
+                        if (ha->task_daemon_flags & LOOP_RESYNC_NEEDED) {
                                 if (!(ha->task_daemon_flags &
                                     LOOP_RESYNC_ACTIVE)) {
                                         ha->task_daemon_flags |=
                                             LOOP_RESYNC_ACTIVE;
                                         TASK_DAEMON_UNLOCK(ha);
-                                        (void) ql_loop_resync(ha);
+                                        ql_loop_resync(ha);
                                         TASK_DAEMON_LOCK(ha);
-                                        loop_again = TRUE;
+                                        loop_again = B_TRUE;
                                 }
                         }
                 }
 
                 /* Port retry needed. */

@@ -8437,11 +8846,10 @@
                 }
 
                 /* iiDMA setting needed? */
                 if (ha->task_daemon_flags & TD_IIDMA_NEEDED) {
                         ha->task_daemon_flags &= ~TD_IIDMA_NEEDED;
-
                         TASK_DAEMON_UNLOCK(ha);
                         ql_iidma(ha);
                         TASK_DAEMON_LOCK(ha);
                         loop_again = B_TRUE;
                 }

@@ -8449,37 +8857,45 @@
                 if (ha->task_daemon_flags & SEND_PLOGI) {
                         ha->task_daemon_flags &= ~SEND_PLOGI;
                         TASK_DAEMON_UNLOCK(ha);
                         (void) ql_n_port_plogi(ha);
                         TASK_DAEMON_LOCK(ha);
+                        loop_again = B_TRUE;
                 }
 
-                head = &ha->callback_queue;
-                if (head->first != NULL) {
-                        sp = head->first->base_address;
+                if (ha->unsol_callback_queue.first != NULL) {
+                        sp = (ha->unsol_callback_queue.first)->base_address;
                         link = &sp->cmd;
-
-                        /* Dequeue command. */
-                        ql_remove_link(head, link);
-
-                        /* Release task daemon lock. */
+                        ql_remove_link(&ha->unsol_callback_queue, link);
                         TASK_DAEMON_UNLOCK(ha);
-
-                        /* Do callback. */
-                        if (sp->flags & SRB_UB_CALLBACK) {
                                 ql_unsol_callback(sp);
-                        } else {
-                                (*sp->pkt->pkt_comp)(sp->pkt);
+                        TASK_DAEMON_LOCK(ha);
+                        loop_again = B_TRUE;
                         }
 
-                        /* Acquire task daemon lock. */
+                if (ha->task_daemon_flags & IDC_POLL_NEEDED) {
+                        ha->task_daemon_flags &= ~IDC_POLL_NEEDED;
+                        TASK_DAEMON_UNLOCK(ha);
+                        ql_8021_idc_poll(ha);
                         TASK_DAEMON_LOCK(ha);
+                        loop_again = B_TRUE;
+                }
 
-                        loop_again = TRUE;
+                if (ha->task_daemon_flags & LED_BLINK) {
+                        ha->task_daemon_flags &= ~LED_BLINK;
+                        TASK_DAEMON_UNLOCK(ha);
+                        ql_blink_led(ha);
+                        TASK_DAEMON_LOCK(ha);
+                        loop_again = B_TRUE;
                 }
 
-        } while (loop_again);
+        } while (loop_again == B_TRUE);
+
+        if (ha->driver_thread_awake) {
+                ha->driver_thread_awake--;
+        }
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_idle_check
  *      Test for adapter is alive and well.

@@ -8491,36 +8907,29 @@
  *      Kernel context.
  */
 static void
 ql_idle_check(ql_adapter_state_t *ha)
 {
-        ddi_devstate_t  state;
         int             rval;
         ql_mbx_data_t   mr;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         /* Firmware Ready Test. */
         rval = ql_get_firmware_state(ha, &mr);
-        if (!(ha->task_daemon_flags & QL_SUSPENDED) &&
+        if (!DRIVER_SUSPENDED(ha) &&
             (rval != QL_SUCCESS || mr.mb[1] != FSTATE_READY)) {
                 EL(ha, "failed, Firmware Ready Test = %xh\n", rval);
-                state = ddi_get_devstate(ha->dip);
-                if (state == DDI_DEVSTATE_UP) {
-                        /*EMPTY*/
-                        ddi_dev_report_fault(ha->dip, DDI_SERVICE_DEGRADED,
-                            DDI_DEVICE_FAULT, "Firmware Ready Test failed");
-                }
                 TASK_DAEMON_LOCK(ha);
                 if (!(ha->task_daemon_flags & ABORT_ISP_ACTIVE)) {
                         EL(ha, "fstate_ready, isp_abort_needed\n");
                         ha->task_daemon_flags |= ISP_ABORT_NEEDED;
                 }
                 TASK_DAEMON_UNLOCK(ha);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_unsol_callback
  *      Handle unsolicited buffer callbacks.

@@ -8540,11 +8949,11 @@
         uchar_t                 r_ctl;
         uchar_t                 ls_code;
         ql_tgt_t                *tq;
         ql_adapter_state_t      *ha = sp->ha, *pha = sp->ha->pha;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         ubp = ha->ub_array[sp->handle];
         r_ctl = ubp->ub_frame.r_ctl;
         ls_code = ubp->ub_buffer[0];
 

@@ -8564,11 +8973,11 @@
                 return;
         }
 
         /* Process RSCN */
         if (sp->flags & SRB_UB_RSCN) {
-                int sendup = 1;
+                int sendup;
 
                 /*
                  * Defer RSCN posting until commands return
                  */
                 QL_UB_UNLOCK(ha);

@@ -8578,21 +8987,21 @@
                 /* Abort outstanding commands */
                 sendup = ql_process_rscn(ha, af);
                 if (sendup == 0) {
 
                         TASK_DAEMON_LOCK(ha);
-                        ql_add_link_b(&pha->callback_queue, &sp->cmd);
+                        ql_add_link_b(&pha->unsol_callback_queue, &sp->cmd);
                         TASK_DAEMON_UNLOCK(ha);
 
                         /*
                          * Wait for commands to drain in F/W (doesn't take
                          * more than a few milliseconds)
                          */
                         ql_delay(ha, 10000);
 
-                        QL_PRINT_2(CE_CONT, "(%d,%d): done rscn_sendup=0, "
-                            "fmt=%xh, d_id=%xh\n", ha->instance, ha->vp_index,
+                        QL_PRINT_2(ha, "done rscn_sendup=0, "
+                            "fmt=%xh, d_id=%xh\n",
                             af->aff_format, af->aff_d_id);
                         return;
                 }
 
                 QL_UB_LOCK(ha);

@@ -8605,22 +9014,27 @@
         if ((r_ctl == R_CTL_ELS_REQ) && (ls_code == LA_ELS_LOGO)) {
                 QL_UB_UNLOCK(ha);
 
                 if (tq && (ql_process_logo_for_device(ha, tq) == 0)) {
                         TASK_DAEMON_LOCK(ha);
-                        ql_add_link_b(&pha->callback_queue, &sp->cmd);
+                        ql_add_link_b(&pha->unsol_callback_queue, &sp->cmd);
                         TASK_DAEMON_UNLOCK(ha);
-                        QL_PRINT_2(CE_CONT, "(%d,%d): logo_sendup=0, d_id=%xh"
-                            "\n", ha->instance, ha->vp_index, tq->d_id.b24);
+                        QL_PRINT_2(ha, "logo_sendup=0, d_id=%xh"
+                            "\n", tq->d_id.b24);
                         return;
                 }
 
                 QL_UB_LOCK(ha);
                 EL(ha, "sending unsol logout for %xh to transport\n",
                     ubp->ub_frame.s_id);
         }
 
+        if ((r_ctl == R_CTL_ELS_REQ) && (ls_code == LA_ELS_PLOGI)) {
+                EL(ha, "sending unsol plogi for %xh to transport\n",
+                    ubp->ub_frame.s_id);
+        }
+
         sp->flags &= ~(SRB_UB_IN_FCA | SRB_UB_IN_ISP | SRB_UB_RSCN |
             SRB_UB_FCP);
 
         if (sp->ub_type == FC_TYPE_IS8802_SNAP) {
                 (void) ddi_dma_sync(sp->ub_buffer.dma_handle, 0,

@@ -8629,11 +9043,11 @@
         QL_UB_UNLOCK(ha);
 
         (ha->bind_info.port_unsol_cb)(ha->bind_info.port_handle,
             ubp, sp->ub_type);
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_send_logo
  *

@@ -8651,14 +9065,13 @@
         fc_unsol_buf_t          *ubp;
         ql_srb_t                *sp;
         la_els_logo_t           *payload;
         ql_adapter_state_t      *ha = vha->pha;
 
-        QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
-            tq->d_id.b24);
+        QL_PRINT_3(ha, "started, d_id=%xh\n", tq->d_id.b24);
 
-        if ((tq->d_id.b24 == 0) || (tq->d_id.b24 == 0xffffff)) {
+        if ((tq->d_id.b24 == 0) || (tq->d_id.b24 == FS_BROADCAST)) {
                 EL(ha, "no device, d_id=%xh\n", tq->d_id.b24);
                 return;
         }
 
         if ((tq->flags & (TQF_RSCN_RCVD | TQF_PLOGI_PROGRS)) == 0 &&

@@ -8674,12 +9087,10 @@
                 DEVICE_QUEUE_LOCK(tq);
                 tq->flags |= TQF_NEED_AUTHENTICATION;
                 tq->logout_sent++;
                 DEVICE_QUEUE_UNLOCK(tq);
 
-                EL(vha, "Received LOGO from = %xh\n", tq->d_id.b24);
-
                 sp = ubp->ub_fca_private;
 
                 /* Set header. */
                 ubp->ub_frame.d_id = vha->d_id.b24;
                 ubp->ub_frame.r_ctl = R_CTL_ELS_REQ;

@@ -8719,11 +9130,11 @@
                 } else {
                         ql_awaken_task_daemon(ha, sp, 0, 0);
                 }
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 static int
 ql_process_logo_for_device(ql_adapter_state_t *ha, ql_tgt_t *tq)
 {

@@ -8730,11 +9141,11 @@
         port_id_t       d_id;
         ql_srb_t        *sp;
         ql_link_t       *link;
         int             sendup = 1;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         DEVICE_QUEUE_LOCK(tq);
         if (tq->outcnt) {
                 DEVICE_QUEUE_UNLOCK(tq);
                 sendup = 0;

@@ -8742,11 +9153,11 @@
                 ql_delay(ha, 10000);
         } else {
                 DEVICE_QUEUE_UNLOCK(tq);
                 TASK_DAEMON_LOCK(ha);
 
-                for (link = ha->pha->callback_queue.first; link != NULL;
+                for (link = ha->pha->unsol_callback_queue.first; link != NULL;
                     link = link->next) {
                         sp = link->base_address;
                         if (sp->flags & SRB_UB_CALLBACK) {
                                 continue;
                         }

@@ -8759,11 +9170,11 @@
                 }
 
                 TASK_DAEMON_UNLOCK(ha);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (sendup);
 }
 
 static int

@@ -8772,11 +9183,11 @@
         fc_unsol_buf_t          *ubp;
         ql_srb_t                *sp;
         la_els_logi_t           *payload;
         class_svc_param_t       *class3_param;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         if ((tq->flags & TQF_RSCN_RCVD) || (ha->task_daemon_flags &
             LOOP_DOWN)) {
                 EL(ha, "Failed, tqf=%xh\n", tq->flags);
                 return (QL_FUNCTION_FAILED);

@@ -8787,12 +9198,11 @@
         if (ubp == NULL) {
                 EL(ha, "Failed\n");
                 return (QL_FUNCTION_FAILED);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): Received LOGO from = %xh\n",
-            ha->instance, tq->d_id.b24);
+        QL_PRINT_3(ha, "Received LOGO from = %xh\n", tq->d_id.b24);
 
         EL(ha, "Emulate PLOGI from = %xh tq = %x\n", tq->d_id.b24, tq);
 
         sp = ubp->ub_fca_private;
 

@@ -8810,24 +9220,18 @@
         ubp->ub_frame.rx_id = 0xffff;
         ubp->ub_frame.ox_id = 0xffff;
 
         /* set payload. */
         payload = (la_els_logi_t *)ubp->ub_buffer;
-        bzero(payload, sizeof (payload));
+        bzero(payload, sizeof (la_els_logi_t));
 
         payload->ls_code.ls_code = LA_ELS_PLOGI;
         payload->common_service.fcph_version = 0x2006;
-        payload->common_service.cmn_features = 0x8800;
-
-        CFG_IST(ha, CFG_CTRL_24258081) ?
-            (payload->common_service.rx_bufsize = CHAR_TO_SHORT(
-            ha->init_ctrl_blk.cb24.max_frame_length[0],
-            ha->init_ctrl_blk.cb24.max_frame_length[1])) :
-            (payload->common_service.rx_bufsize = CHAR_TO_SHORT(
-            ha->init_ctrl_blk.cb.max_frame_length[0],
-            ha->init_ctrl_blk.cb.max_frame_length[1]));
-
+        payload->common_service.cmn_features =
+            ha->topology & QL_N_PORT ? 0x8000 : 0x8800;
+        payload->common_service.rx_bufsize =
+            ha->loginparams.common_service.rx_bufsize;
         payload->common_service.conc_sequences = 0xff;
         payload->common_service.relative_offset = 0x03;
         payload->common_service.e_d_tov = 0x7d0;
 
         bcopy((void *)&tq->port_name[0],

@@ -8846,19 +9250,17 @@
 
         QL_UB_LOCK(ha);
         sp->flags |= SRB_UB_CALLBACK;
         QL_UB_UNLOCK(ha);
 
-        ql_isp_els_handle_endian(ha, (uint8_t *)payload, LA_ELS_PLOGI);
-
         if (done_q) {
                 ql_add_link_b(done_q, &sp->cmd);
         } else {
                 ql_awaken_task_daemon(ha, sp, 0, 0);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (QL_SUCCESS);
 }
 
 /*

@@ -8873,11 +9275,11 @@
         ql_lun_t        *lq;
         int             rval = QL_SUCCESS;
         ql_srb_t        *sp;
         ql_head_t       done_q = { NULL, NULL };
 
-        QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
+        QL_PRINT_10(ha, "started\n");
 
         /*
          * First clear, internally queued commands
          */
         DEVICE_QUEUE_LOCK(tq);

@@ -8887,14 +9289,10 @@
                 link2 = lq->cmd.first;
                 while (link2 != NULL) {
                         sp = link2->base_address;
                         link2 = link2->next;
 
-                        if (sp->flags & SRB_ABORT) {
-                                continue;
-                        }
-
                         /* Remove srb from device command queue. */
                         ql_remove_link(&lq->cmd, &sp->cmd);
                         sp->flags &= ~SRB_IN_DEVICE_QUEUE;
 
                         /* Set ending status. */

@@ -8905,11 +9303,11 @@
                 }
         }
         DEVICE_QUEUE_UNLOCK(tq);
 
         if (done_q.first != NULL) {
-                ql_done(done_q.first);
+                ql_done(done_q.first, B_FALSE);
         }
 
         if (drain && VALID_TARGET_ID(ha, tq->loop_id) && PD_PORT_LOGIN(tq)) {
                 rval = ql_abort_target(ha, tq, 0);
         }

@@ -8916,12 +9314,11 @@
 
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
         } else {
                 /*EMPTY*/
-                QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance,
-                    ha->vp_index);
+                QL_PRINT_10(ha, "done\n");
         }
 
         return (rval);
 }
 

@@ -8944,11 +9341,11 @@
         ql_srb_t                *sp;
         fc_rscn_t               *rn;
         fc_affected_id_t        *af;
         port_id_t               d_id;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         /* Locate a buffer to use. */
         ubp = ql_get_unsolicited_buffer(ha, FC_TYPE_EXTENDED_LS);
         if (ubp != NULL) {
                 sp = ubp->ub_fca_private;

@@ -8993,11 +9390,11 @@
 
         if (ubp == NULL) {
                 EL(ha, "Failed, get_unsolicited_buffer\n");
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
 }
 
 /*
  * ql_update_rscn

@@ -9015,11 +9412,11 @@
 {
         ql_link_t       *link;
         uint16_t        index;
         ql_tgt_t        *tq;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         if (af->aff_format == FC_RSCN_PORT_ADDRESS) {
                 port_id_t d_id;
 
                 d_id.r.rsvd_1 = 0;

@@ -9028,14 +9425,14 @@
                 tq = ql_d_id_to_queue(ha, d_id);
                 if (tq) {
                         EL(ha, "SD_RSCN_RCVD %xh RPA\n", d_id.b24);
                         DEVICE_QUEUE_LOCK(tq);
                         tq->flags |= TQF_RSCN_RCVD;
+                        ql_requeue_pending_cmds(ha, tq);
                         DEVICE_QUEUE_UNLOCK(tq);
                 }
-                QL_PRINT_3(CE_CONT, "(%d): FC_RSCN_PORT_ADDRESS done\n",
-                    ha->instance);
+                QL_PRINT_3(ha, "FC_RSCN_PORT_ADDRESS done\n");
 
                 return;
         }
 
         for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {

@@ -9048,10 +9445,11 @@
                                 if (!RESERVED_LOOP_ID(ha, tq->loop_id)) {
                                         EL(ha, "SD_RSCN_RCVD %xh RFA\n",
                                             tq->d_id.b24);
                                         DEVICE_QUEUE_LOCK(tq);
                                         tq->flags |= TQF_RSCN_RCVD;
+                                        ql_requeue_pending_cmds(ha, tq);
                                         DEVICE_QUEUE_UNLOCK(tq);
                                 }
                                 break;
 
                         case FC_RSCN_AREA_ADDRESS:

@@ -9058,10 +9456,11 @@
                                 if ((tq->d_id.b24 & 0xffff00) == af->aff_d_id) {
                                         EL(ha, "SD_RSCN_RCVD %xh RAA\n",
                                             tq->d_id.b24);
                                         DEVICE_QUEUE_LOCK(tq);
                                         tq->flags |= TQF_RSCN_RCVD;
+                                        ql_requeue_pending_cmds(ha, tq);
                                         DEVICE_QUEUE_UNLOCK(tq);
                                 }
                                 break;
 
                         case FC_RSCN_DOMAIN_ADDRESS:

@@ -9068,23 +9467,74 @@
                                 if ((tq->d_id.b24 & 0xff0000) == af->aff_d_id) {
                                         EL(ha, "SD_RSCN_RCVD %xh RDA\n",
                                             tq->d_id.b24);
                                         DEVICE_QUEUE_LOCK(tq);
                                         tq->flags |= TQF_RSCN_RCVD;
+                                        ql_requeue_pending_cmds(ha, tq);
                                         DEVICE_QUEUE_UNLOCK(tq);
                                 }
                                 break;
 
                         default:
                                 break;
                         }
                 }
         }
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
+ * ql_requeue_pending_cmds
+ *      Requeue target commands from pending queue to LUN queue
+ *
+ * Input:
+ *      ha:     adapter state pointer.
+ *      tq:     target queue pointer.
+ *      DEVICE_QUEUE_LOCK must be already obtained.
+ *
+ * Context:
+ *      Interrupt or Kernel context, no mailbox commands allowed.
+ */
+void
+ql_requeue_pending_cmds(ql_adapter_state_t *vha, ql_tgt_t *tq)
+{
+        ql_link_t               *link;
+        ql_srb_t                *sp;
+        ql_lun_t                *lq;
+        ql_adapter_state_t      *ha = vha->pha;
+
+        QL_PRINT_3(ha, "started\n");
+
+        REQUEST_RING_LOCK(ha);
+        for (link = ha->pending_cmds.first; link != NULL; link = link->next) {
+                sp = link->base_address;
+                if ((lq = sp->lun_queue) == NULL || lq->target_queue != tq) {
+                        continue;
+                }
+                ql_remove_link(&ha->pending_cmds, &sp->cmd);
+
+                if (tq->outcnt) {
+                        tq->outcnt--;
+                }
+                if (sp->flags & SRB_FCP_CMD_PKT) {
+                        if (sp->fcp->fcp_cntl.cntl_qtype ==
+                            FCP_QTYPE_UNTAGGED) {
+                                lq->flags &= ~LQF_UNTAGGED_PENDING;
+                        }
+                        if (lq->lun_outcnt != 0) {
+                                lq->lun_outcnt--;
+                        }
+                }
+                ql_add_link_t(&lq->cmd, &sp->cmd);
+                sp->flags |= SRB_IN_DEVICE_QUEUE;
+        }
+        REQUEST_RING_UNLOCK(ha);
+
+        QL_PRINT_3(ha, "done\n");
+}
+
+/*
  * ql_process_rscn
  *
  * Input:
  *      ha:     adapter state pointer.
  *      af:     RSCN payload pointer.

@@ -9099,11 +9549,11 @@
         int             sendup = 1;
         ql_link_t       *link;
         uint16_t        index;
         ql_tgt_t        *tq;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         if (af->aff_format == FC_RSCN_PORT_ADDRESS) {
                 port_id_t d_id;
 
                 d_id.r.rsvd_1 = 0;

@@ -9112,11 +9562,11 @@
                 tq = ql_d_id_to_queue(ha, d_id);
                 if (tq) {
                         sendup = ql_process_rscn_for_device(ha, tq);
                 }
 
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
 
                 return (sendup);
         }
 
         for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {

@@ -9167,11 +9617,11 @@
                                 break;
                         }
                 }
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (sendup);
 }
 
 /*

@@ -9187,11 +9637,11 @@
 static int
 ql_process_rscn_for_device(ql_adapter_state_t *ha, ql_tgt_t *tq)
 {
         int sendup = 1;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         DEVICE_QUEUE_LOCK(tq);
 
         /*
          * Let FCP-2 compliant devices continue I/Os

@@ -9219,10 +9669,11 @@
                 (void) ql_abort_device(ha, tq, 1);
 
                 DEVICE_QUEUE_LOCK(tq);
 
                 if (tq->outcnt) {
+                        EL(ha, "busy tq->outcnt=%d\n", tq->outcnt);
                         sendup = 0;
                 } else {
                         tq->flags &= ~TQF_RSCN_RCVD;
                 }
         } else {

@@ -9235,11 +9686,11 @@
                 }
         }
 
         DEVICE_QUEUE_UNLOCK(tq);
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (sendup);
 }
 
 static int

@@ -9252,11 +9703,11 @@
         uint32_t                list_size;
         port_id_t               d_id;
         ql_mbx_data_t           mr;
         ql_head_t               done_q = { NULL, NULL };
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         list_size = sizeof (ql_dev_id_list_t) * DEVICE_LIST_ENTRIES;
         list = kmem_zalloc(list_size, KM_SLEEP);
         if (list == NULL) {
                 rval = QL_MEMORY_ALLOC_FAILED;

@@ -9290,11 +9741,12 @@
                         }
 
                         tq = ql_dev_init(ha, d_id, loop_id);
 
                         /* Test for fabric device. */
-                        if (d_id.b.domain != ha->d_id.b.domain ||
+                        if (ha->topology & QL_F_PORT ||
+                            d_id.b.domain != ha->d_id.b.domain ||
                             d_id.b.area != ha->d_id.b.area) {
                                 tq->flags |= TQF_FABRIC_DEVICE;
                         }
 
                         ADAPTER_STATE_UNLOCK(ha);

@@ -9315,20 +9767,20 @@
 
         /* Release adapter state lock. */
         ADAPTER_STATE_UNLOCK(ha);
 
         if (done_q.first != NULL) {
-                ql_done(done_q.first);
+                ql_done(done_q.first, B_FALSE);
         }
 
         kmem_free(list, list_size);
 
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed=%xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
 
         return (rval);
 }
 

@@ -9348,19 +9800,17 @@
 ql_free_unsolicited_buffer(ql_adapter_state_t *ha, fc_unsol_buf_t *ubp)
 {
         ql_srb_t        *sp;
         int             status;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         sp = ubp->ub_fca_private;
         if (sp->ub_type == FC_TYPE_IS8802_SNAP) {
                 /* Disconnect IP from system buffers. */
                 if (ha->flags & IP_INITIALIZED) {
-                        ADAPTER_STATE_UNLOCK(ha);
                         status = ql_shutdown_ip(ha);
-                        ADAPTER_STATE_LOCK(ha);
                         if (status != QL_SUCCESS) {
                                 cmn_err(CE_WARN,
                                     "!Qlogic %s(%d): Failed to shutdown IP",
                                     QL_NAME, ha->instance);
                                 return;

@@ -9375,15 +9825,17 @@
         }
 
         kmem_free(sp, sizeof (ql_srb_t));
         kmem_free(ubp, sizeof (fc_unsol_buf_t));
 
+        QL_UB_LOCK(ha);
         if (ha->ub_allocated != 0) {
                 ha->ub_allocated--;
         }
+        QL_UB_UNLOCK(ha);
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_get_unsolicited_buffer
  *      Locates a free unsolicited buffer.

@@ -9403,11 +9855,11 @@
 {
         fc_unsol_buf_t  *ubp;
         ql_srb_t        *sp;
         uint16_t        index;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         /* Locate a buffer to use. */
         ubp = NULL;
 
         QL_UB_LOCK(ha);

@@ -9431,11 +9883,11 @@
         if (ubp) {
                 ubp->ub_resp_token = NULL;
                 ubp->ub_class = FC_TRAN_CLASS3;
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (ubp);
 }
 
 /*

@@ -9461,11 +9913,11 @@
         fc_unsol_buf_t  *ubp;
         ql_srb_t        *sp;
         uint16_t        loop_id;
         int             rval = QL_FUNCTION_FAILED;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         QL_UB_LOCK(ha);
         if (index >= QL_UB_LIMIT || (ubp = ha->ub_array[index]) == NULL) {
                 EL(ha, "Invalid buffer index=%xh\n", index);
                 QL_UB_UNLOCK(ha);

@@ -9487,17 +9939,17 @@
         if ((sp->handle == index) &&
             (sp->flags & SRB_UB_IN_ISP) &&
             (sp->ub_type == FC_TYPE_IS8802_SNAP) &&
             (!(sp->flags & SRB_UB_ACQUIRED))) {
                 /* set broadcast D_ID */
-                loop_id = (uint16_t)(CFG_IST(ha, CFG_CTRL_24258081) ?
+                loop_id = (uint16_t)(CFG_IST(ha, CFG_ISP_FW_TYPE_2) ?
                     BROADCAST_24XX_HDL : IP_BROADCAST_LOOP_ID);
                 if (tq->ub_loop_id == loop_id) {
                         if (ha->topology & QL_FL_PORT) {
                                 ubp->ub_frame.d_id = 0x000000;
                         } else {
-                                ubp->ub_frame.d_id = 0xffffff;
+                                ubp->ub_frame.d_id = FS_BROADCAST;
                         }
                 } else {
                         ubp->ub_frame.d_id = ha->d_id.b24;
                 }
                 ubp->ub_frame.r_ctl = R_CTL_UNSOL_DATA;

@@ -9531,24 +9983,17 @@
                         ubp->ub_frame.f_ctl = F_CTL_RO_PRESENT |
                             F_CTL_FIRST_SEQ;
                         ubp->ub_frame.df_ctl = 0x20;
                 }
 
-                QL_PRINT_3(CE_CONT, "(%d): ub_frame.d_id=%xh\n",
-                    ha->instance, ubp->ub_frame.d_id);
-                QL_PRINT_3(CE_CONT, "(%d): ub_frame.s_id=%xh\n",
-                    ha->instance, ubp->ub_frame.s_id);
-                QL_PRINT_3(CE_CONT, "(%d): ub_frame.seq_cnt=%xh\n",
-                    ha->instance, ubp->ub_frame.seq_cnt);
-                QL_PRINT_3(CE_CONT, "(%d): ub_frame.seq_id=%xh\n",
-                    ha->instance, ubp->ub_frame.seq_id);
-                QL_PRINT_3(CE_CONT, "(%d): ub_frame.ro=%xh\n",
-                    ha->instance, ubp->ub_frame.ro);
-                QL_PRINT_3(CE_CONT, "(%d): ub_frame.f_ctl=%xh\n",
-                    ha->instance, ubp->ub_frame.f_ctl);
-                QL_PRINT_3(CE_CONT, "(%d): ub_bufsize=%xh\n",
-                    ha->instance, ubp->ub_bufsize);
+                QL_PRINT_3(ha, "ub_frame.d_id=%xh\n", ubp->ub_frame.d_id);
+                QL_PRINT_3(ha, "ub_frame.s_id=%xh\n", ubp->ub_frame.s_id);
+                QL_PRINT_3(ha, "ub_frame.seq_cnt=%xh\n", ubp->ub_frame.seq_cnt);
+                QL_PRINT_3(ha, "ub_frame.seq_id=%xh\n", ubp->ub_frame.seq_id);
+                QL_PRINT_3(ha, "ub_frame.ro=%xh\n", ubp->ub_frame.ro);
+                QL_PRINT_3(ha, "ub_frame.f_ctl=%xh\n", ubp->ub_frame.f_ctl);
+                QL_PRINT_3(ha, "ub_bufsize=%xh\n", ubp->ub_bufsize);
                 QL_DUMP_3(ubp->ub_buffer, 8,
                     ubp->ub_bufsize < 64 ? ubp->ub_bufsize : 64);
 
                 sp->flags |= SRB_UB_CALLBACK | SRB_UB_ACQUIRED;
                 ql_add_link_b(done_q, &sp->cmd);

@@ -9571,11 +10016,11 @@
                             index);
                 }
         }
         QL_UB_UNLOCK(ha);
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (rval);
 }
 
 /*

@@ -9590,52 +10035,52 @@
  */
 static void
 ql_timer(void *arg)
 {
         ql_link_t               *link;
-        uint32_t                set_flags;
-        uint32_t                reset_flags;
-        ql_adapter_state_t      *ha = NULL, *vha;
+        uint64_t                set_flags;
+        ql_adapter_state_t      *ha;
+        static uint32_t         sec_cnt = 0;
 
-        QL_PRINT_6(CE_CONT, "started\n");
+        QL_PRINT_6(NULL, "started\n");
 
         /* Acquire global state lock. */
-        GLOBAL_STATE_LOCK();
+        GLOBAL_TIMER_LOCK();
         if (ql_timer_timeout_id == NULL) {
                 /* Release global state lock. */
-                GLOBAL_STATE_UNLOCK();
+                GLOBAL_TIMER_UNLOCK();
                 return;
         }
 
+        sec_cnt++;
         for (link = ql_hba.first; link != NULL; link = link->next) {
                 ha = link->base_address;
 
-                /* Skip adapter if suspended of stalled. */
-                ADAPTER_STATE_LOCK(ha);
+                /* Skip adapter if suspended or stalled. */
                 if (ha->flags & ADAPTER_SUSPENDED ||
-                    ha->task_daemon_flags & DRIVER_STALL) {
-                        ADAPTER_STATE_UNLOCK(ha);
+                    ha->task_daemon_flags & DRIVER_STALL ||
+                    !(ha->task_daemon_flags & FIRMWARE_UP)) {
                         continue;
                 }
-                ha->flags |= ADAPTER_TIMER_BUSY;
-                ADAPTER_STATE_UNLOCK(ha);
 
                 QL_PM_LOCK(ha);
                 if (ha->power_level != PM_LEVEL_D0) {
                         QL_PM_UNLOCK(ha);
-
-                        ADAPTER_STATE_LOCK(ha);
-                        ha->flags &= ~ADAPTER_TIMER_BUSY;
-                        ADAPTER_STATE_UNLOCK(ha);
                         continue;
                 }
-                ha->busy++;
+                ha->pm_busy++;
                 QL_PM_UNLOCK(ha);
 
                 set_flags = 0;
-                reset_flags = 0;
 
+                /* All completion treads busy, wake up a helper thread. */
+                if (ha->comp_thds_awake == ha->comp_thds_active &&
+                    ha->comp_q.first != NULL) {
+                        QL_PRINT_10(ha, "comp queue helper thrd started\n");
+                        (void) timeout(ql_process_comp_queue, (void *)ha, 1);
+                }
+
                 /* Port retry timer handler. */
                 if (LOOP_READY(ha)) {
                         ADAPTER_STATE_LOCK(ha);
                         if (ha->port_retry_timer != 0) {
                                 ha->port_retry_timer--;

@@ -9655,12 +10100,13 @@
                                  * a chance to work.
                                  */
                                 if (ha->loop_down_timer == LOOP_DOWN_RESET) {
                                         if (CFG_IST(ha,
                                             CFG_DUMP_LOOP_OFFLINE_TIMEOUT)) {
-                                                (void) ql_binary_fw_dump(ha,
-                                                    TRUE);
+                                                ADAPTER_STATE_LOCK(ha);
+                                                ha->flags |= FW_DUMP_NEEDED;
+                                                ADAPTER_STATE_UNLOCK(ha);
                                         }
                                         EL(ha, "loop_down_reset, "
                                             "isp_abort_needed\n");
                                         set_flags |= ISP_ABORT_NEEDED;
                                 }

@@ -9681,22 +10127,15 @@
                                 if (ha->watchdog_timer == 0) {
                                         ha->watchdog_timer = WATCHDOG_TIME;
                                 } else if (LOOP_READY(ha)) {
                                         ha->watchdog_timer--;
                                         if (ha->watchdog_timer == 0) {
-                                                for (vha = ha; vha != NULL;
-                                                    vha = vha->vp_next) {
-                                                        ql_watchdog(vha,
-                                                            &set_flags,
-                                                            &reset_flags);
+                                                set_flags |= WATCHDOG_NEEDED;
                                                 }
-                                                ha->watchdog_timer =
-                                                    WATCHDOG_TIME;
                                         }
                                 }
                         }
-                }
 
                 /* Idle timer handler. */
                 if (!DRIVER_SUSPENDED(ha)) {
                         if (++ha->idle_timer >= IDLE_CHECK_TIMER) {
 #if defined(QL_DEBUG_LEVEL_6) || !defined(QL_DEBUG_LEVEL_3)

@@ -9709,38 +10148,24 @@
                                 if (ha->send_plogi_timer == NULL) {
                                         set_flags |= SEND_PLOGI;
                                 }
                         }
                 }
-                ADAPTER_STATE_LOCK(ha);
-                if (ha->idc_restart_timer != 0) {
-                        ha->idc_restart_timer--;
-                        if (ha->idc_restart_timer == 0) {
-                                ha->idc_restart_cnt = 0;
-                                reset_flags |= DRIVER_STALL;
+
+                if (CFG_IST(ha, CFG_CTRL_82XX) && ha->flags & ONLINE &&
+                    !(ha->task_daemon_flags & (ISP_ABORT_NEEDED |
+                    ABORT_ISP_ACTIVE)) &&
+                    !(sec_cnt % 2)) {
+                        set_flags |= IDC_POLL_NEEDED;
                         }
-                }
-                if (ha->idc_flash_acc_timer != 0) {
-                        ha->idc_flash_acc_timer--;
-                        if (ha->idc_flash_acc_timer == 0 &&
-                            ha->idc_flash_acc != 0) {
-                                ha->idc_flash_acc = 1;
-                                ha->idc_mb[0] = MBA_IDC_NOTIFICATION;
-                                ha->idc_mb[1] = 0;
-                                ha->idc_mb[2] = IDC_OPC_DRV_START;
-                                set_flags |= IDC_EVENT;
-                        }
-                }
-                ADAPTER_STATE_UNLOCK(ha);
 
-                if (set_flags != 0 || reset_flags != 0) {
-                        ql_awaken_task_daemon(ha, NULL, set_flags,
-                            reset_flags);
+                if (ha->ledstate.BeaconState == BEACON_ON) {
+                        set_flags |= LED_BLINK;
                 }
 
-                if (ha->xioctl->ledstate.BeaconState == BEACON_ON) {
-                        ql_blink_led(ha);
+                if (set_flags != 0) {
+                        ql_awaken_task_daemon(ha, NULL, set_flags, 0);
                 }
 
                 /* Update the IO stats */
                 if (ha->xioctl->IOInputByteCnt >= 0x100000) {
                         ha->xioctl->IOInputMByteCnt +=

@@ -9752,32 +10177,26 @@
                         ha->xioctl->IOOutputMByteCnt +=
                             (ha->xioctl->IOOutputByteCnt / 0x100000);
                         ha->xioctl->IOOutputByteCnt %= 0x100000;
                 }
 
-                if (CFG_IST(ha, CFG_CTRL_8021)) {
-                        (void) ql_8021_idc_handler(ha);
-                }
-
-                ADAPTER_STATE_LOCK(ha);
-                ha->flags &= ~ADAPTER_TIMER_BUSY;
-                ADAPTER_STATE_UNLOCK(ha);
-
                 QL_PM_LOCK(ha);
-                ha->busy--;
+                if (ha->pm_busy) {
+                        ha->pm_busy--;
+                }
                 QL_PM_UNLOCK(ha);
         }
 
         /* Restart timer, if not being stopped. */
         if (ql_timer_timeout_id != NULL) {
                 ql_timer_timeout_id = timeout(ql_timer, arg, ql_timer_ticks);
         }
 
         /* Release global state lock. */
-        GLOBAL_STATE_UNLOCK();
+        GLOBAL_TIMER_UNLOCK();
 
-        QL_PRINT_6(CE_CONT, "done\n");
+        QL_PRINT_6(ha, "done\n");
 }
 
 /*
  * ql_timeout_insert
  *      Function used to insert a command block onto the

@@ -9797,11 +10216,11 @@
  */
 /* ARGSUSED */
 static void
 ql_timeout_insert(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_srb_t *sp)
 {
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         if (sp->pkt->pkt_timeout != 0 && sp->pkt->pkt_timeout < 0x10000) {
                 sp->isp_timeout = (uint16_t)(sp->pkt->pkt_timeout);
                 /*
                  * The WATCHDOG_TIME must be rounded up + 1.  As an example,

@@ -9836,11 +10255,11 @@
                 sp->isp_timeout = 0;
                 sp->wdg_q_time = 0;
                 sp->init_wdg_q_time = 0;
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_watchdog
  *      Timeout handler that runs in interrupt context. The

@@ -9849,75 +10268,106 @@
  *      Function used to update timeout values and if timeout
  *      has occurred command will be aborted.
  *
  * Input:
  *      ha:             adapter state pointer.
- *      set_flags:      task daemon flags to set.
- *      reset_flags:    task daemon flags to reset.
  *
  * Context:
- *      Interrupt context, no mailbox commands allowed.
+ *      Kernel context.
  */
 static void
-ql_watchdog(ql_adapter_state_t *ha, uint32_t *set_flags, uint32_t *reset_flags)
+ql_watchdog(ql_adapter_state_t *ha)
 {
-        ql_srb_t        *sp;
         ql_link_t       *link;
-        ql_link_t       *next_cmd;
-        ql_link_t       *next_device;
         ql_tgt_t        *tq;
-        ql_lun_t        *lq;
         uint16_t        index;
-        int             q_sane;
+        ql_adapter_state_t      *vha;
 
-        QL_PRINT_6(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_6(ha, "started\n");
 
+        for (vha = ha; vha != NULL; vha = vha->vp_next) {
         /* Loop through all targets. */
         for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
-                for (link = ha->dev[index].first; link != NULL;
-                    link = next_device) {
+                        for (link = vha->dev[index].first; link != NULL;
+                            link = link->next) {
                         tq = link->base_address;
 
                         /* Try to acquire device queue lock. */
                         if (TRY_DEVICE_QUEUE_LOCK(tq) == 0) {
-                                next_device = NULL;
-                                continue;
+                                        break;
                         }
 
-                        next_device = link->next;
-
-                        if (!(CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING)) &&
+                                if (!(CFG_IST(ha,
+                                    CFG_ENABLE_LINK_DOWN_REPORTING)) &&
                             (tq->port_down_retry_count == 0)) {
                                 /* Release device queue lock. */
                                 DEVICE_QUEUE_UNLOCK(tq);
                                 continue;
                         }
+                                ql_wdg_tq_list(vha, tq);
+                        }
+                }
+        }
+        ha->watchdog_timer = WATCHDOG_TIME;
 
-                        /* Find out if this device is in a sane state. */
-                        if (tq->flags & (TQF_RSCN_RCVD |
-                            TQF_NEED_AUTHENTICATION | TQF_QUEUE_SUSPENDED)) {
-                                q_sane = 0;
+        QL_PRINT_6(ha, "done\n");
+}
+
+/*
+ * ql_wdg_tq_list
+ *      Timeout handler that runs in interrupt context. The
+ *      ql_adapter_state_t * argument is the parameter set up when the
+ *      timeout was initialized (state structure pointer).
+ *      Function used to update timeout values and if timeout
+ *      has occurred command will be aborted.
+ *
+ * Input:
+ *      ha:     adapter state pointer.
+ *      tq:     target queue pointer.
+ *      DEVICE_QUEUE_LOCK must be already obtained.
+ *
+ * Output:
+ *      Releases DEVICE_QUEUE_LOCK upon exit.
+ *
+ * Context:
+ *      Kernel context.
+ */
+static void
+ql_wdg_tq_list(ql_adapter_state_t *ha, ql_tgt_t *tq)
+{
+        ql_srb_t        *sp;
+        ql_link_t       *link, *next_cmd;
+        ql_lun_t        *lq;
+        boolean_t       q_sane, timeout = B_FALSE;
+
+        QL_PRINT_6(ha, "started\n");
+
+        /* Find out if this device is in a sane state */
+        if (tq->flags & (TQF_RSCN_RCVD | TQF_NEED_AUTHENTICATION |
+            TQF_QUEUE_SUSPENDED)) {
+                q_sane = B_FALSE;
                         } else {
-                                q_sane = 1;
+                q_sane = B_TRUE;
                         }
                         /* Loop through commands on watchdog queue. */
-                        for (link = tq->wdg.first; link != NULL;
-                            link = next_cmd) {
+        for (link = tq->wdg.first; link != NULL; link = next_cmd) {
                                 next_cmd = link->next;
                                 sp = link->base_address;
                                 lq = sp->lun_queue;
 
                                 /*
-                                 * For SCSI commands, if everything seems to
-                                 * be going fine and this packet is stuck
-                                 * because of throttling at LUN or target
-                                 * level then do not decrement the
-                                 * sp->wdg_q_time
+                 * For SCSI commands, if everything
+                 * seems to * be going fine and this
+                 * packet is stuck
+                 * because of throttling at LUN or
+                 * target level then do not decrement
+                 * the sp->wdg_q_time
                                  */
                                 if (ha->task_daemon_flags & STATE_ONLINE &&
-                                    (sp->flags & SRB_ISP_STARTED) == 0 &&
-                                    q_sane && sp->flags & SRB_FCP_CMD_PKT &&
+                    !(sp->flags & SRB_ISP_STARTED) &&
+                    q_sane == B_TRUE &&
+                    sp->flags & SRB_FCP_CMD_PKT &&
                                     lq->lun_outcnt >= ha->execution_throttle) {
                                         continue;
                                 }
 
                                 if (sp->wdg_q_time != 0) {

@@ -9926,37 +10376,38 @@
                                         /* Timeout? */
                                         if (sp->wdg_q_time != 0) {
                                                 continue;
                                         }
 
-                                        ql_remove_link(&tq->wdg, &sp->wdg);
-                                        sp->flags &= ~SRB_WATCHDOG_ENABLED;
+                        sp->flags |= SRB_COMMAND_TIMEOUT;
+                        timeout = B_TRUE;
+                }
+        }
 
-                                        if (sp->flags & SRB_ISP_STARTED) {
-                                                ql_cmd_timeout(ha, tq, sp,
-                                                    set_flags, reset_flags);
+        /*
+         * Loop through commands on watchdog queue and
+         * abort timed out commands.
+         */
+        if (timeout == B_TRUE) {
+                for (link = tq->wdg.first; link != NULL; link = next_cmd) {
+                        sp = link->base_address;
+                        next_cmd = link->next;
 
-                                                DEVICE_QUEUE_UNLOCK(tq);
-                                                tq = NULL;
-                                                next_cmd = NULL;
-                                                next_device = NULL;
-                                                index = DEVICE_HEAD_LIST_SIZE;
-                                        } else {
-                                                ql_cmd_timeout(ha, tq, sp,
-                                                    set_flags, reset_flags);
+                        if (sp->flags & SRB_COMMAND_TIMEOUT) {
+                                ql_remove_link(&tq->wdg, &sp->wdg);
+                                sp->flags &= ~(SRB_WATCHDOG_ENABLED |
+                                    SRB_COMMAND_TIMEOUT);
+                                ql_cmd_timeout(ha, tq, sp);
+                                next_cmd = tq->wdg.first;
                                         }
                                 }
                         }
 
                         /* Release device queue lock. */
-                        if (tq != NULL) {
                                 DEVICE_QUEUE_UNLOCK(tq);
-                        }
-                }
-        }
 
-        QL_PRINT_6(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_6(ha, "done\n");
 }
 
 /*
  * ql_cmd_timeout
  *      Command timeout handler.

@@ -9963,28 +10414,25 @@
  *
  * Input:
  *      ha:             adapter state pointer.
  *      tq:             target queue pointer.
  *      sp:             SRB pointer.
- *      set_flags:      task daemon flags to set.
- *      reset_flags:    task daemon flags to reset.
  *
  * Context:
- *      Interrupt context, no mailbox commands allowed.
+ *      Kernel context.
  */
-/* ARGSUSED */
 static void
-ql_cmd_timeout(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_srb_t *sp,
-    uint32_t *set_flags, uint32_t *reset_flags)
+ql_cmd_timeout(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_srb_t *sp)
 {
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        int     rval = 0;
 
-        if (!(sp->flags & SRB_ISP_STARTED)) {
+        QL_PRINT_3(ha, "started\n");
 
-                EL(ha, "command timed out in driver = %ph\n", (void *)sp);
-
                 REQUEST_RING_LOCK(ha);
+        if (!(sp->flags & SRB_ISP_STARTED)) {
+                EL(ha, "command timed out in driver, sp=%ph spf=%xh\n",
+                    (void *)sp, sp->flags);
 
                 /* if it's on a queue */
                 if (sp->cmd.head) {
                         /*
                          * The pending_cmds que needs to be

@@ -10003,114 +10451,61 @@
 
                 /* Ensure no retry */
                 sp->flags &= ~SRB_RETRY;
 
                 /* Call done routine to handle completion. */
-                ql_done(&sp->cmd);
+                ql_done(&sp->cmd, B_FALSE);
+        } else if (CFG_IST(ha, CFG_CTRL_82XX)) {
+                REQUEST_RING_UNLOCK(ha);
+                DEVICE_QUEUE_UNLOCK(tq);
 
-                DEVICE_QUEUE_LOCK(tq);
-        } else if (CFG_IST(ha, CFG_CTRL_8021)) {
-                int             rval;
-                uint32_t        index;
-
                 EL(ha, "command timed out in isp=%ph, osc=%ph, index=%xh, "
                     "spf=%xh\n", (void *)sp,
                     (void *)ha->outstanding_cmds[sp->handle & OSC_INDEX_MASK],
                     sp->handle & OSC_INDEX_MASK, sp->flags);
 
-                DEVICE_QUEUE_UNLOCK(tq);
-
-                INTR_LOCK(ha);
-                ha->pha->xioctl->ControllerErrorCount++;
-                if (sp->handle) {
-                        ha->pha->timeout_cnt++;
-                        index = sp->handle & OSC_INDEX_MASK;
-                        if (ha->pha->outstanding_cmds[index] == sp) {
-                                sp->request_ring_ptr->entry_type =
-                                    INVALID_ENTRY_TYPE;
-                                sp->request_ring_ptr->entry_count = 0;
-                                ha->pha->outstanding_cmds[index] = 0;
-                        }
-                        INTR_UNLOCK(ha);
-
-                        rval = ql_abort_command(ha, sp);
-                        if (rval == QL_FUNCTION_TIMEOUT ||
-                            rval == QL_LOCK_TIMEOUT ||
-                            rval == QL_FUNCTION_PARAMETER_ERROR ||
-                            ha->pha->timeout_cnt > TIMEOUT_THRESHOLD) {
-                                *set_flags |= ISP_ABORT_NEEDED;
+                if (ha->pha->timeout_cnt++ > TIMEOUT_THRESHOLD ||
+                    (rval = ql_abort_io(ha, sp)) != QL_SUCCESS) {
+                        sp->flags |= SRB_COMMAND_TIMEOUT;
+                        TASK_DAEMON_LOCK(ha);
+                        ha->task_daemon_flags |= ISP_ABORT_NEEDED;
+                        TASK_DAEMON_UNLOCK(ha);
                                 EL(ha, "abort status=%xh, tc=%xh, isp_abort_"
                                     "needed\n", rval, ha->pha->timeout_cnt);
                         }
-
-                        sp->handle = 0;
-                        sp->flags &= ~SRB_IN_TOKEN_ARRAY;
                 } else {
-                        INTR_UNLOCK(ha);
-                }
+                REQUEST_RING_UNLOCK(ha);
+                DEVICE_QUEUE_UNLOCK(tq);
 
-                /* Set timeout status */
-                sp->pkt->pkt_reason = CS_TIMEOUT;
-
-                /* Ensure no retry */
-                sp->flags &= ~SRB_RETRY;
-
-                /* Call done routine to handle completion. */
-                ql_done(&sp->cmd);
-
-                DEVICE_QUEUE_LOCK(tq);
-
-        } else {
                 EL(ha, "command timed out in isp=%ph, osc=%ph, index=%xh, "
                     "spf=%xh, isp_abort_needed\n", (void *)sp,
                     (void *)ha->outstanding_cmds[sp->handle & OSC_INDEX_MASK],
                     sp->handle & OSC_INDEX_MASK, sp->flags);
 
-                /* Release device queue lock. */
-                DEVICE_QUEUE_UNLOCK(tq);
-
                 INTR_LOCK(ha);
                 ha->pha->xioctl->ControllerErrorCount++;
                 INTR_UNLOCK(ha);
 
                 /* Set ISP needs to be reset */
                 sp->flags |= SRB_COMMAND_TIMEOUT;
 
                 if (CFG_IST(ha, CFG_DUMP_DRIVER_COMMAND_TIMEOUT)) {
-                        (void) ql_binary_fw_dump(ha, TRUE);
+                        ADAPTER_STATE_LOCK(ha);
+                        ha->flags |= FW_DUMP_NEEDED;
+                        ADAPTER_STATE_UNLOCK(ha);
                 }
 
-                *set_flags |= ISP_ABORT_NEEDED;
-
-                DEVICE_QUEUE_LOCK(tq);
+                TASK_DAEMON_LOCK(ha);
+                ha->task_daemon_flags |= ISP_ABORT_NEEDED;
+                TASK_DAEMON_UNLOCK(ha);
         }
+        DEVICE_QUEUE_LOCK(tq);
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
- * ql_rst_aen
- *      Processes asynchronous reset.
- *
- * Input:
- *      ha = adapter state pointer.
- *
- * Context:
- *      Kernel context.
- */
-static void
-ql_rst_aen(ql_adapter_state_t *ha)
-{
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
-
-        /* Issue marker command. */
-        (void) ql_marker(ha, 0, 0, MK_SYNC_ALL);
-
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
-}
-
-/*
  * ql_cmd_wait
  *      Stall driver until all outstanding commands are returned.
  *
  * Input:
  *      ha = adapter state pointer.

@@ -10124,11 +10519,11 @@
         uint16_t                index;
         ql_link_t               *link;
         ql_tgt_t                *tq;
         ql_adapter_state_t      *vha;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         /* Wait for all outstanding commands to be returned. */
         (void) ql_wait_outstanding(ha);
 
         /*

@@ -10139,18 +10534,19 @@
                         for (link = vha->dev[index].first; link != NULL;
                             link = link->next) {
                                 tq = link->base_address;
                                 if (tq &&
                                     (!(tq->prli_svc_param_word_3 &
-                                    PRLI_W3_RETRY))) {
+                                    PRLI_W3_RETRY) ||
+                                    ha->task_daemon_flags & ABORT_ISP_ACTIVE)) {
                                         (void) ql_abort_device(vha, tq, 0);
                                 }
                         }
                 }
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_wait_outstanding
  *      Wait for all outstanding commands to complete.

@@ -10168,32 +10564,34 @@
 ql_wait_outstanding(ql_adapter_state_t *ha)
 {
         ql_srb_t        *sp;
         uint16_t        index, count;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         count = ql_osc_wait_count;
-        for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
+        for (index = 1; index < ha->pha->osc_max_cnt; index++) {
                 if (ha->pha->pending_cmds.first != NULL) {
                         ql_start_iocb(ha, NULL);
                         index = 1;
                 }
                 if ((sp = ha->pha->outstanding_cmds[index]) != NULL &&
+                    sp != QL_ABORTED_SRB(ha) &&
                     (sp->flags & SRB_COMMAND_TIMEOUT) == 0) {
                         if (count-- != 0) {
                                 ql_delay(ha, 10000);
                                 index = 0;
                         } else {
-                                EL(ha, "failed, sp=%ph, oci=%d, hdl=%xh\n",
-                                    (void *)sp, index, sp->handle);
+                                EL(ha, "still in OSC,sp=%ph,oci=%d,sph=%xh,"
+                                    "spf=%xh\n", (void *) sp, index, sp->handle,
+                                    sp->flags);
                                 break;
                         }
                 }
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (index);
 }
 
 /*

@@ -10205,20 +10603,20 @@
  *      DEVICE_QUEUE_LOCK must be released.
  *
  * Context:
  *      Interrupt or Kernel context, no mailbox commands allowed.
  */
-static void
+void
 ql_restart_queues(ql_adapter_state_t *ha)
 {
         ql_link_t               *link, *link2;
         ql_tgt_t                *tq;
         ql_lun_t                *lq;
         uint16_t                index;
         ql_adapter_state_t      *vha;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         for (vha = ha->pha; vha != NULL; vha = vha->vp_next) {
                 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
                         for (link = vha->dev[index].first; link != NULL;
                             link = link->next) {

@@ -10243,11 +10641,11 @@
                                 DEVICE_QUEUE_UNLOCK(tq);
                         }
                 }
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_iidma
  *      Setup iiDMA parameters to firmware

@@ -10266,41 +10664,43 @@
         ql_tgt_t        *tq;
         uint16_t        index;
         char            buf[256];
         uint32_t        data;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
-        if ((CFG_IST(ha, CFG_CTRL_242581)) == 0) {
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        if (!CFG_IST(ha, CFG_IIDMA_SUPPORT)) {
+                QL_PRINT_3(ha, "done\n");
                 return;
         }
 
         for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
                 for (link = ha->dev[index].first; link != NULL;
                     link = link->next) {
                         tq = link->base_address;
 
-                        /* Acquire device queue lock. */
-                        DEVICE_QUEUE_LOCK(tq);
-
                         if ((tq->flags & TQF_IIDMA_NEEDED) == 0) {
-                                DEVICE_QUEUE_UNLOCK(tq);
                                 continue;
                         }
 
+                        /* Acquire device queue lock. */
+                        DEVICE_QUEUE_LOCK(tq);
+
                         tq->flags &= ~TQF_IIDMA_NEEDED;
 
+                        /* Release device queue lock. */
+                        DEVICE_QUEUE_UNLOCK(tq);
+
                         if ((tq->loop_id > LAST_N_PORT_HDL) ||
+                            (tq->d_id.b24 == FS_MANAGEMENT_SERVER) ||
+                            (tq->flags & TQF_INITIATOR_DEVICE) ||
                             (tq->iidma_rate == IIDMA_RATE_NDEF)) {
-                                DEVICE_QUEUE_UNLOCK(tq);
                                 continue;
                         }
 
                         /* Get the iiDMA persistent data */
-                        if (tq->iidma_rate == IIDMA_RATE_INIT) {
-                                (void) sprintf(buf,
+                        (void) snprintf(buf, sizeof (buf),
                                     "iidma-rate-%02x%02x%02x%02x%02x"
                                     "%02x%02x%02x", tq->port_name[0],
                                     tq->port_name[1], tq->port_name[2],
                                     tq->port_name[3], tq->port_name[4],
                                     tq->port_name[5], tq->port_name[6],

@@ -10309,52 +10709,46 @@
                                 if ((data = ql_get_prop(ha, buf)) ==
                                     0xffffffff) {
                                         tq->iidma_rate = IIDMA_RATE_NDEF;
                                 } else {
                                         switch (data) {
-                                        case IIDMA_RATE_1GB:
-                                        case IIDMA_RATE_2GB:
                                         case IIDMA_RATE_4GB:
+                                case IIDMA_RATE_8GB:
                                         case IIDMA_RATE_10GB:
+                                case IIDMA_RATE_16GB:
+                                case IIDMA_RATE_32GB:
                                                 tq->iidma_rate = data;
                                                 break;
-                                        case IIDMA_RATE_8GB:
-                                                if (CFG_IST(ha,
-                                                    CFG_CTRL_25XX)) {
-                                                        tq->iidma_rate = data;
-                                                } else {
-                                                        tq->iidma_rate =
-                                                            IIDMA_RATE_4GB;
-                                                }
-                                                break;
                                         default:
                                                 EL(ha, "invalid data for "
                                                     "parameter: %s: %xh\n",
                                                     buf, data);
                                                 tq->iidma_rate =
                                                     IIDMA_RATE_NDEF;
                                                 break;
                                         }
                                 }
-                        }
 
+                        EL(ha, "d_id = %xh iidma_rate = %xh\n",
+                            tq->d_id.b24, tq->iidma_rate);
+
                         /* Set the firmware's iiDMA rate */
-                        if (tq->iidma_rate <= IIDMA_RATE_MAX &&
-                            !(CFG_IST(ha, CFG_CTRL_8081))) {
+                        if (!CFG_IST(ha, CFG_FCOE_SUPPORT)) {
+                                if (tq->iidma_rate <= IIDMA_RATE_MAX) {
                                 data = ql_iidma_rate(ha, tq->loop_id,
-                                    &tq->iidma_rate, EXT_IIDMA_MODE_SET);
+                                            &tq->iidma_rate,
+                                            EXT_IIDMA_MODE_SET);
                                 if (data != QL_SUCCESS) {
-                                        EL(ha, "mbx failed: %xh\n", data);
+                                                EL(ha, "mbx failed: %xh\n",
+                                                    data);
                                 }
                         }
-
-                        /* Release device queue lock. */
-                        DEVICE_QUEUE_UNLOCK(tq);
                 }
         }
+        }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_abort_queues
  *      Abort all commands on device queues.

@@ -10363,26 +10757,26 @@
  *      ha = adapter state pointer.
  *
  * Context:
  *      Interrupt or Kernel context, no mailbox commands allowed.
  */
-static void
+void
 ql_abort_queues(ql_adapter_state_t *ha)
 {
         ql_link_t               *link;
         ql_tgt_t                *tq;
         ql_srb_t                *sp;
         uint16_t                index;
         ql_adapter_state_t      *vha;
 
-        QL_PRINT_10(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_10(ha, "started\n");
 
         /* Return all commands in outstanding command list. */
         INTR_LOCK(ha);
 
         /* Place all commands in outstanding cmd list on device queue. */
-        for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
+        for (index = 1; index < ha->osc_max_cnt; index++) {
                 if (ha->pending_cmds.first != NULL) {
                         INTR_UNLOCK(ha);
                         ql_start_iocb(ha, NULL);
                         /* Delay for system */
                         ql_delay(ha, 10000);

@@ -10389,14 +10783,20 @@
                         INTR_LOCK(ha);
                         index = 1;
                 }
                 sp = ha->outstanding_cmds[index];
 
+                if (sp && (sp == QL_ABORTED_SRB(ha) || sp->ha != ha)) {
+                        continue;
+                }
+
                 /* skip devices capable of FCP2 retrys */
-                if ((sp != NULL) &&
-                    ((tq = sp->lun_queue->target_queue) != NULL) &&
-                    (!(tq->prli_svc_param_word_3 & PRLI_W3_RETRY))) {
+                if (sp != NULL &&
+                    (sp->lun_queue == NULL ||
+                    (tq = sp->lun_queue->target_queue) == NULL ||
+                    !(tq->prli_svc_param_word_3 & PRLI_W3_RETRY) ||
+                    ha->task_daemon_flags & ABORT_ISP_ACTIVE)) {
                         ha->outstanding_cmds[index] = NULL;
                         sp->handle = 0;
                         sp->flags &= ~SRB_IN_TOKEN_ARRAY;
 
                         INTR_UNLOCK(ha);

@@ -10405,27 +10805,27 @@
                         sp->pkt->pkt_reason = CS_PORT_UNAVAILABLE;
                         sp->flags |= SRB_ISP_COMPLETED;
 
                         /* Call done routine to handle completions. */
                         sp->cmd.next = NULL;
-                        ql_done(&sp->cmd);
+                        ql_done(&sp->cmd, B_FALSE);
 
                         INTR_LOCK(ha);
                 }
         }
         INTR_UNLOCK(ha);
 
         for (vha = ha; vha != NULL; vha = vha->vp_next) {
-                QL_PRINT_10(CE_CONT, "(%d,%d): abort instance\n",
-                    vha->instance, vha->vp_index);
+                QL_PRINT_10(vha, "abort instance\n");
                 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
                         for (link = vha->dev[index].first; link != NULL;
                             link = link->next) {
                                 tq = link->base_address;
                                 /* skip devices capable of FCP2 retrys */
                                 if (!(tq->prli_svc_param_word_3 &
-                                    PRLI_W3_RETRY)) {
+                                    PRLI_W3_RETRY) ||
+                                    ha->task_daemon_flags & ABORT_ISP_ACTIVE) {
                                         /*
                                          * Set port unavailable status and
                                          * return all commands on a devices
                                          * queues.
                                          */

@@ -10432,11 +10832,11 @@
                                         ql_abort_device_queues(ha, tq);
                                 }
                         }
                 }
         }
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_abort_device_queues
  *      Abort all commands on device queues.

@@ -10452,27 +10852,23 @@
 {
         ql_link_t       *lun_link, *cmd_link;
         ql_srb_t        *sp;
         ql_lun_t        *lq;
 
-        QL_PRINT_10(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_10(ha, "started\n");
 
         DEVICE_QUEUE_LOCK(tq);
+        ql_requeue_pending_cmds(ha, tq);
 
         for (lun_link = tq->lun_queues.first; lun_link != NULL;
             lun_link = lun_link->next) {
                 lq = lun_link->base_address;
 
                 cmd_link = lq->cmd.first;
                 while (cmd_link != NULL) {
                         sp = cmd_link->base_address;
 
-                        if (sp->flags & SRB_ABORT) {
-                                cmd_link = cmd_link->next;
-                                continue;
-                        }
-
                         /* Remove srb from device cmd queue. */
                         ql_remove_link(&lq->cmd, &sp->cmd);
 
                         sp->flags &= ~SRB_IN_DEVICE_QUEUE;
 

@@ -10480,11 +10876,11 @@
 
                         /* Set ending status. */
                         sp->pkt->pkt_reason = CS_PORT_UNAVAILABLE;
 
                         /* Call done routine to handle completion. */
-                        ql_done(&sp->cmd);
+                        ql_done(&sp->cmd, B_FALSE);
 
                         /* Delay for system */
                         ql_delay(ha, 10000);
 
                         DEVICE_QUEUE_LOCK(tq);

@@ -10491,11 +10887,11 @@
                         cmd_link = lq->cmd.first;
                 }
         }
         DEVICE_QUEUE_UNLOCK(tq);
 
-        QL_PRINT_10(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_10(ha, "done\n");
 }
 
 /*
  * ql_loop_resync
  *      Resync with fibre channel devices.

@@ -10502,22 +10898,19 @@
  *
  * Input:
  *      ha = adapter state pointer.
  *      DEVICE_QUEUE_LOCK must be released.
  *
- * Returns:
- *      ql local function return status code.
- *
  * Context:
  *      Kernel context.
  */
-static int
+static void
 ql_loop_resync(ql_adapter_state_t *ha)
 {
         int rval;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         if (ha->flags & IP_INITIALIZED) {
                 (void) ql_shutdown_ip(ha);
         }
 

@@ -10528,16 +10921,14 @@
         TASK_DAEMON_UNLOCK(ha);
 
         /* Set loop online, if it really is. */
         if (rval == QL_SUCCESS) {
                 ql_loop_online(ha);
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         } else {
                 EL(ha, "failed, rval = %xh\n", rval);
         }
-
-        return (rval);
 }
 
 /*
  * ql_loop_online
  *      Set loop online status if it really is online.

@@ -10552,11 +10943,11 @@
 void
 ql_loop_online(ql_adapter_state_t *ha)
 {
         ql_adapter_state_t      *vha;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         /* Inform the FC Transport that the hardware is online. */
         for (vha = ha->pha; vha != NULL; vha = vha->vp_next) {
                 if (!(vha->task_daemon_flags &
                     (LOOP_RESYNC_NEEDED | LOOP_DOWN))) {

@@ -10586,11 +10977,11 @@
         ql_awaken_task_daemon(ha, NULL, 0, 0);
 
         /* Restart device queues that may have been stopped. */
         ql_restart_queues(ha);
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_fca_handle_to_state
  *      Verifies handle to be correct.

@@ -10627,11 +11018,11 @@
                 }
         }
 
         if (ha == NULL) {
                 /*EMPTY*/
-                QL_PRINT_2(CE_CONT, "failed\n");
+                QL_PRINT_2(ha, "failed\n");
         }
 
 #endif /* QL_DEBUG_ROUTINES */
 
         return ((ql_adapter_state_t *)fca_handle);

@@ -10724,24 +11115,24 @@
 static int
 ql_kstat_update(kstat_t *ksp, int rw)
 {
         int                     rval;
 
-        QL_PRINT_3(CE_CONT, "started\n");
+        QL_PRINT_3(ksp->ks_private, "started\n");
 
         if (rw == KSTAT_WRITE) {
                 rval = EACCES;
         } else {
                 rval = 0;
         }
 
         if (rval != 0) {
                 /*EMPTY*/
-                QL_PRINT_2(CE_CONT, "failed, rval = %xh\n", rval);
+                QL_PRINT_2(ksp->ks_private, "failed, rval = %xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "done\n");
+                QL_PRINT_3(ksp->ks_private, "done\n");
         }
         return (rval);
 }
 
 /*

@@ -10766,15 +11157,15 @@
         int             rval;
         uint32_t        size_to_offset;
         uint32_t        size_to_compare;
         int             erase_all;
 
-        if (CFG_IST(ha, CFG_CTRL_24258081)) {
+        if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
                 return (ql_24xx_load_flash(ha, dp, size, 0));
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         size_to_compare = 0x20000;
         size_to_offset = 0;
         erase_all = 0;
         if (CFG_IST(ha, CFG_SBUS_CARD)) {

@@ -10793,12 +11184,10 @@
                 rval = QL_FUNCTION_PARAMETER_ERROR;
                 EL(ha, "failed=%xh\n", rval);
                 return (rval);
         }
 
-        GLOBAL_HW_LOCK();
-
         /* Enable Flash Read/Write. */
         ql_flash_enable(ha);
 
         /* Erase flash prior to write. */
         rval = ql_erase_flash(ha, erase_all);

@@ -10818,17 +11207,15 @@
                 }
         }
 
         ql_flash_disable(ha);
 
-        GLOBAL_HW_UNLOCK();
-
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed=%xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
         return (rval);
 }
 
 /*

@@ -10849,11 +11236,11 @@
 static int
 ql_program_flash_address(ql_adapter_state_t *ha, uint32_t addr, uint8_t data)
 {
         int rval;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         if (CFG_IST(ha, CFG_SBUS_CARD)) {
                 ql_write_flash_byte(ha, 0x5555, 0xa0);
                 ql_write_flash_byte(ha, addr, data);
         } else {

@@ -10869,11 +11256,11 @@
 
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed=%xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
         return (rval);
 }
 
 /*

@@ -10898,14 +11285,13 @@
         uint32_t        ssize;
         uint32_t        cnt;
         uint8_t         *bfp;
         uint8_t         *tmp;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         if ((CFG_IST(ha, CFG_SBUS_CARD)) && !erase_all) {
-
                 if (ql_flash_sbus_fpga == 1) {
                         ssize = QL_SBUS_FCODE_SIZE;
                         sStartAddr = QL_FCODE_OFFSET;
                 } else {
                         ssize = QL_FPGA_SIZE;

@@ -10916,18 +11302,17 @@
 
                 bfp = (uint8_t *)kmem_zalloc(ssize, KM_SLEEP);
 
                 /* Save the section of flash we're not updating to buffer */
                 tmp = bfp;
-                for (cnt = sStartAddr; cnt < ssize+sStartAddr; cnt++) {
+                for (cnt = sStartAddr; cnt < ssize + sStartAddr; cnt++) {
                         /* Allow other system activity. */
                         if (cnt % 0x1000 == 0) {
                                 ql_delay(ha, 10000);
                         }
                         *tmp++ = (uint8_t)ql_read_flash_byte(ha, cnt);
                 }
-        }
 
         /* Chip Erase Command Sequence */
         ql_write_flash_byte(ha, 0x5555, 0xaa);
         ql_write_flash_byte(ha, 0x2aaa, 0x55);
         ql_write_flash_byte(ha, 0x5555, 0x80);

@@ -10938,41 +11323,47 @@
         ql_delay(ha, erase_delay);
 
         /* Wait for erase to complete. */
         rval = ql_poll_flash(ha, 0, 0x80);
 
-        if (rval != QL_SUCCESS) {
-                EL(ha, "failed=%xh\n", rval);
-                if (CFG_IST(ha, CFG_SBUS_CARD)) {
-                        kmem_free(bfp, ssize);
-                }
-                return (rval);
-        }
-
-        /* restore the section we saved in the buffer */
-        if ((CFG_IST(ha, CFG_SBUS_CARD)) && !erase_all) {
+                if (rval == QL_SUCCESS) {
                 /* Restore the section we saved off */
                 tmp = bfp;
-                for (cnt = sStartAddr; cnt < ssize+sStartAddr; cnt++) {
+                        for (cnt = sStartAddr; cnt < ssize + sStartAddr;
+                            cnt++) {
                         /* Allow other system activity. */
                         if (cnt % 0x1000 == 0) {
                                 ql_delay(ha, 10000);
                         }
-                        rval = ql_program_flash_address(ha, cnt, *tmp++);
+                                rval = ql_program_flash_address(ha, cnt,
+                                    *tmp++);
                         if (rval != QL_SUCCESS) {
                                 break;
                         }
                 }
-
+                }
                 kmem_free(bfp, ssize);
+        } else {
+                /* Chip Erase Command Sequence */
+                ql_write_flash_byte(ha, 0x5555, 0xaa);
+                ql_write_flash_byte(ha, 0x2aaa, 0x55);
+                ql_write_flash_byte(ha, 0x5555, 0x80);
+                ql_write_flash_byte(ha, 0x5555, 0xaa);
+                ql_write_flash_byte(ha, 0x2aaa, 0x55);
+                ql_write_flash_byte(ha, 0x5555, 0x10);
+
+                ql_delay(ha, erase_delay);
+
+                /* Wait for erase to complete. */
+                rval = ql_poll_flash(ha, 0, 0x80);
         }
 
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed=%xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
         return (rval);
 }
 
 /*

@@ -10995,11 +11386,11 @@
 {
         uint8_t         flash_data;
         uint32_t        cnt;
         int             rval = QL_FUNCTION_FAILED;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         poll_data = (uint8_t)(poll_data & BIT_7);
 
         /* Wait for 30 seconds for command to finish. */
         for (cnt = 30000000; cnt; cnt--) {

@@ -11017,11 +11408,11 @@
 
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed=%xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
         return (rval);
 }
 
 /*

@@ -11037,11 +11428,11 @@
 void
 ql_flash_enable(ql_adapter_state_t *ha)
 {
         uint16_t        data;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         /* Enable Flash Read/Write. */
         if (CFG_IST(ha, CFG_SBUS_CARD)) {
                 data = (uint16_t)ddi_get16(ha->sbus_fpga_dev_handle,
                     (uint16_t *)(ha->sbus_fpga_iobase + FPGA_CONF));

@@ -11063,11 +11454,11 @@
                 ql_write_flash_byte(ha, 0x2aaa, 0x55);
                 ql_write_flash_byte(ha, 0x5555, 0xf0);
         }
         (void) ql_read_flash_byte(ha, 0);
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_flash_disable
  *      Disable flash and allow RISC to run.

@@ -11081,11 +11472,11 @@
 void
 ql_flash_disable(ql_adapter_state_t *ha)
 {
         uint16_t        data;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         if (CFG_IST(ha, CFG_SBUS_CARD)) {
                 /*
                  * Lock the flash back up.
                  */

@@ -11101,11 +11492,11 @@
                 data = (uint16_t)(RD16_IO_REG(ha, ctrl_status) &
                     ~ISP_FLASH_ENABLE);
                 WRT16_IO_REG(ha, ctrl_status, data);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_write_flash_byte
  *      Write byte to flash.

@@ -11135,11 +11526,11 @@
                 uint16_t bank_select;
 
                 /* Setup bit 16 of flash address. */
                 bank_select = (uint16_t)RD16_IO_REG(ha, ctrl_status);
 
-                if (CFG_IST(ha, CFG_CTRL_6322)) {
+                if (ha->device_id == 0x2322 || ha->device_id == 0x6322) {
                         bank_select = (uint16_t)(bank_select & ~0xf0);
                         bank_select = (uint16_t)(bank_select |
                             ((addr >> 12 & 0xf0) | ISP_FLASH_64K_BANK));
                         WRT16_IO_REG(ha, ctrl_status, bank_select);
                 } else {

@@ -11197,11 +11588,11 @@
         } else {
                 uint16_t        bank_select;
 
                 /* Setup bit 16 of flash address. */
                 bank_select = RD16_IO_REG(ha, ctrl_status);
-                if (CFG_IST(ha, CFG_CTRL_6322)) {
+                if (ha->device_id == 0x2322 || ha->device_id == 0x6322) {
                         bank_select = (uint16_t)(bank_select & ~0xf0);
                         bank_select = (uint16_t)(bank_select |
                             ((addr >> 12 & 0xf0) | ISP_FLASH_64K_BANK));
                         WRT16_IO_REG(ha, ctrl_status, bank_select);
                 } else {

@@ -11249,18 +11640,23 @@
         int                     rval;
         uint32_t                fdata = 0;
         ql_adapter_state_t      *ha = vha->pha;
         ql_xioctl_t             *xp = ha->xioctl;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         rval = ql_24xx_read_flash(ha, FLASH_CONF_ADDR | 0x3AB, &fdata);
-
-        if (rval != QL_SUCCESS || fdata == 0 || CFG_IST(ha, CFG_CTRL_2581)) {
+        if (CFG_IST(ha, CFG_CTRL_24XX)) {
+                if (rval != QL_SUCCESS || fdata == 0) {
                 fdata = 0;
+                        rval = ql_24xx_read_flash(ha, FLASH_CONF_ADDR | 0x39F,
+                            &fdata);
+                }
+        } else {
+                fdata = 0;
                 rval = ql_24xx_read_flash(ha, FLASH_CONF_ADDR |
-                    (CFG_IST(ha, CFG_CTRL_2422) ? 0x39F : 0x49F), &fdata);
+                    (CFG_IST(ha, CFG_CTRL_25XX) ? 0x49F : 0x39F), &fdata);
         }
 
         if (rval != QL_SUCCESS) {
                 EL(ha, "24xx read_flash failed=%xh\n", rval);
         } else if (fdata != 0) {

@@ -11271,11 +11667,11 @@
                 xp->fdesc.flash_manuf = ATMEL_FLASH;
                 xp->fdesc.flash_id = ATMEL_FLASHID_1024K;
                 xp->fdesc.flash_len = 0;
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (rval);
 }
 
 /*

@@ -11302,34 +11698,31 @@
         uint32_t                cnt, rest_addr, fdata, wc;
         dma_mem_t               dmabuf = {0};
         ql_adapter_state_t      *ha = vha->pha;
         ql_xioctl_t             *xp = ha->xioctl;
 
-        QL_PRINT_3(CE_CONT, "(%d): started, faddr=%xh, size=%xh\n",
+        QL_PRINT_3(ha, "started, faddr=%xh, size=%xh\n",
             ha->instance, faddr, size);
 
         /* start address must be 32 bit word aligned */
         if ((faddr & 0x3) != 0) {
                 EL(ha, "incorrect buffer size alignment\n");
                 return (QL_FUNCTION_PARAMETER_ERROR);
         }
 
         /* Allocate DMA buffer */
-        if (CFG_IST(ha, CFG_CTRL_2581)) {
+        if (CFG_IST(ha, CFG_FLASH_DMA_SUPPORT)) {
                 if ((rval = ql_get_dma_mem(ha, &dmabuf, 0xffff,
                     LITTLE_ENDIAN_DMA, QL_DMA_DATA_ALIGN)) !=
                     QL_SUCCESS) {
                         EL(ha, "dma alloc failed, rval=%xh\n", rval);
                         return (rval);
                 }
         }
 
-        GLOBAL_HW_LOCK();
-
         /* Enable flash write */
         if ((rval = ql_24xx_unprotect_flash(ha)) != QL_SUCCESS) {
-                GLOBAL_HW_UNLOCK();
                 EL(ha, "unprotect_flash failed, rval=%xh\n", rval);
                 ql_free_phys(ha, &dmabuf);
                 return (rval);
         }
 

@@ -11345,21 +11738,21 @@
         size = (size + 3) >> 2; /* Round up & convert to dwords */
 
         while (cnt < size) {
                 /* Beginning of a sector? */
                 if ((faddr & rest_addr) == 0) {
-                        if (CFG_IST(ha, CFG_CTRL_8021)) {
+                        if (CFG_IST(ha, CFG_CTRL_82XX)) {
                                 fdata = ha->flash_data_addr | faddr;
                                 rval = ql_8021_rom_erase(ha, fdata);
                                 if (rval != QL_SUCCESS) {
                                         EL(ha, "8021 erase sector status="
                                             "%xh, start=%xh, end=%xh"
                                             "\n", rval, fdata,
                                             fdata + rest_addr);
                                         break;
                                 }
-                        } else if (CFG_IST(ha, CFG_CTRL_81XX)) {
+                        } else if (CFG_IST(ha, CFG_FLASH_ACC_SUPPORT)) {
                                 fdata = ha->flash_data_addr | faddr;
                                 rval = ql_flash_access(ha,
                                     FAC_ERASE_SECTOR, fdata, fdata +
                                     rest_addr, 0);
                                 if (rval != QL_SUCCESS) {

@@ -11393,11 +11786,11 @@
                                 }
                         }
                 }
 
                 /* Write data */
-                if (CFG_IST(ha, CFG_CTRL_2581) &&
+                if (CFG_IST(ha, CFG_FLASH_DMA_SUPPORT) &&
                     ((faddr & 0x3f) == 0)) {
                         /*
                          * Limit write up to sector boundary.
                          */
                         wc = ((~faddr & (rest_addr>>1)) + 1);

@@ -11444,19 +11837,19 @@
                 }
         }
 
         ql_24xx_protect_flash(ha);
 
+        if (CFG_IST(ha, CFG_FLASH_DMA_SUPPORT)) {
         ql_free_phys(ha, &dmabuf);
+        }
 
-        GLOBAL_HW_UNLOCK();
-
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed=%xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
         return (rval);
 }
 
 /*

@@ -11479,11 +11872,11 @@
 {
         uint32_t                timer;
         int                     rval = QL_SUCCESS;
         ql_adapter_state_t      *ha = vha->pha;
 
-        if (CFG_IST(ha, CFG_CTRL_8021)) {
+        if (CFG_IST(ha, CFG_CTRL_82XX)) {
                 if ((rval = ql_8021_rom_read(ha, faddr, bp)) != QL_SUCCESS) {
                         EL(ha, "8021 access error\n");
                 }
                 return (rval);
         }

@@ -11535,11 +11928,11 @@
 {
         uint32_t                timer, fdata;
         int                     rval = QL_SUCCESS;
         ql_adapter_state_t      *ha = vha->pha;
 
-        if (CFG_IST(ha, CFG_CTRL_8021)) {
+        if (CFG_IST(ha, CFG_CTRL_82XX)) {
                 if ((rval = ql_8021_rom_write(ha, addr, data)) != QL_SUCCESS) {
                         EL(ha, "8021 access error\n");
                 }
                 return (rval);
         }

@@ -11555,11 +11948,11 @@
         for (timer = 3000000; timer; timer--) {
                 if ((RD32_IO_REG(ha, flash_address) & FLASH_DATA_FLAG) == 0) {
                         /* Check flash write in progress. */
                         if ((addr & FLASH_ADDR_MASK) == FLASH_CONF_ADDR) {
                                 (void) ql_24xx_read_flash(ha,
-                                    FLASH_CONF_ADDR | 0x005, &fdata);
+                                    FLASH_CONF_ADDR | 0x105, &fdata);
                                 if (!(fdata & BIT_0)) {
                                         break;
                                 }
                         } else {
                                 break;

@@ -11592,45 +11985,67 @@
  */
 int
 ql_24xx_unprotect_flash(ql_adapter_state_t *vha)
 {
         int                     rval;
-        uint32_t                fdata;
+        uint32_t                fdata, timer;
         ql_adapter_state_t      *ha = vha->pha;
         ql_xioctl_t             *xp = ha->xioctl;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
-        if (CFG_IST(ha, CFG_CTRL_8021)) {
+        if (CFG_IST(ha, CFG_CTRL_82XX)) {
                 (void) ql_8021_rom_wrsr(ha, xp->fdesc.write_enable_bits);
                 rval = ql_8021_rom_wrsr(ha, xp->fdesc.write_enable_bits);
                 if (rval != QL_SUCCESS) {
                         EL(ha, "8021 access error\n");
                 }
                 return (rval);
         }
-        if (CFG_IST(ha, CFG_CTRL_81XX)) {
+        if (CFG_IST(ha, CFG_FLASH_ACC_SUPPORT)) {
                 if (ha->task_daemon_flags & FIRMWARE_UP) {
-                        if ((rval = ql_flash_access(ha, FAC_WRT_ENABLE, 0, 0,
-                            0)) != QL_SUCCESS) {
-                                EL(ha, "status=%xh\n", rval);
+                        for (timer = 3000; timer; timer--) {
+                                if (ha->task_daemon_flags & ISP_ABORT_NEEDED) {
+                                        EL(ha, "ISP_ABORT_NEEDED done\n");
+                                        return (QL_ABORTED);
                         }
-                        QL_PRINT_3(CE_CONT, "(%d): 8100 done\n",
-                            ha->instance);
-                        return (rval);
+                                rval = ql_flash_access(ha, FAC_SEMA_LOCK,
+                                    0, 0, NULL);
+                                if (rval == QL_SUCCESS ||
+                                    rval == QL_FUNCTION_TIMEOUT) {
+                                        EL(ha, "lock status=%xh\n", rval);
+                                        break;
                 }
+                                delay(1);
+                        }
+
+                        if (rval == QL_SUCCESS &&
+                            (rval = ql_flash_access(ha, FAC_WRT_ENABLE, 0,
+                            0, NULL)) != QL_SUCCESS) {
+                                EL(ha, "WRT_ENABLE status=%xh\n", rval);
+                                (void) ql_flash_access(ha, FAC_SEMA_UNLOCK,
+                                    0, 0, NULL);
+                        }
         } else {
+                        rval = QL_SUCCESS;
+                }
+                QL_PRINT_3(ha, "CFG_FLASH_ACC_SUPPORT done\n");
+                return (rval);
+        } else {
                 /* Enable flash write. */
                 WRT32_IO_REG(ha, ctrl_status,
                     RD32_IO_REG(ha, ctrl_status) | ISP_FLASH_ENABLE);
                 RD32_IO_REG(ha, ctrl_status);   /* PCI Posting. */
         }
 
+        /* Sector/Block Protection Register Lock (SST, ST, ATMEL). */
+        (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x100 |
+            xp->fdesc.write_statusreg_cmd, xp->fdesc.write_enable_bits);
+
         /*
-         * Remove block write protection (SST and ST) and
-         * Sector/Block Protection Register Lock (SST, ST, ATMEL).
-         * Unprotect sectors.
+         * Remove block write protection (SST and ST)
+         * Global unprotect sectors (ATMEL).
          */
         (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x100 |
             xp->fdesc.write_statusreg_cmd, xp->fdesc.write_enable_bits);
 
         if (xp->fdesc.unprotect_sector_cmd != 0) {

@@ -11645,11 +12060,11 @@
                     xp->fdesc.unprotect_sector_cmd, 0x00600f);
                 (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x300 |
                     xp->fdesc.unprotect_sector_cmd, 0x00800f);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (QL_SUCCESS);
 }
 
 /*

@@ -11664,32 +12079,52 @@
  */
 void
 ql_24xx_protect_flash(ql_adapter_state_t *vha)
 {
         int                     rval;
-        uint32_t                fdata;
+        uint32_t                fdata, timer;
         ql_adapter_state_t      *ha = vha->pha;
         ql_xioctl_t             *xp = ha->xioctl;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
-        if (CFG_IST(ha, CFG_CTRL_8021)) {
+        if (CFG_IST(ha, CFG_CTRL_82XX)) {
                 (void) ql_8021_rom_wrsr(ha, xp->fdesc.write_enable_bits);
                 rval = ql_8021_rom_wrsr(ha, xp->fdesc.write_disable_bits);
                 if (rval != QL_SUCCESS) {
                         EL(ha, "8021 access error\n");
                 }
                 return;
         }
-        if (CFG_IST(ha, CFG_CTRL_81XX)) {
+        if (CFG_IST(ha, CFG_FLASH_ACC_SUPPORT)) {
                 if (ha->task_daemon_flags & FIRMWARE_UP) {
-                        if ((rval = ql_flash_access(ha, FAC_WRT_PROTECT, 0, 0,
-                            0)) != QL_SUCCESS) {
-                                EL(ha, "status=%xh\n", rval);
+                        for (timer = 3000; timer; timer--) {
+                                if (ha->task_daemon_flags & ISP_ABORT_NEEDED) {
+                                        EL(ha, "ISP_ABORT_NEEDED done\n");
+                                        return;
                         }
-                        QL_PRINT_3(CE_CONT, "(%d): 8100 done\n",
-                            ha->instance);
+                                rval = ql_flash_access(ha, FAC_SEMA_LOCK,
+                                    0, 0, NULL);
+                                if (rval == QL_SUCCESS ||
+                                    rval == QL_FUNCTION_TIMEOUT) {
+                                        if (rval != QL_SUCCESS) {
+                                                EL(ha, "lock status=%xh\n",
+                                                    rval);
+                                        }
+                                        break;
+                                }
+                                delay(1);
+                        }
+
+                        if (rval == QL_SUCCESS &&
+                            (rval = ql_flash_access(ha, FAC_WRT_PROTECT, 0,
+                            0, NULL)) != QL_SUCCESS) {
+                                EL(ha, "protect status=%xh\n", rval);
+                                (void) ql_flash_access(ha, FAC_SEMA_UNLOCK, 0,
+                                    0, NULL);
+                        }
+                        QL_PRINT_3(ha, "CFG_FLASH_ACC_SUPPORT done\n");
                         return;
                 }
         } else {
                 /* Enable flash write. */
                 WRT32_IO_REG(ha, ctrl_status,

@@ -11703,35 +12138,35 @@
          * Sector/Block Protection Register Lock (SST, ST, ATMEL).
          */
         if (xp->fdesc.protect_sector_cmd != 0) {
                 for (fdata = 0; fdata < 0x10; fdata++) {
                         (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR |
-                            0x330 | xp->fdesc.protect_sector_cmd, fdata);
+                            0x300 | xp->fdesc.protect_sector_cmd, fdata);
                 }
-                (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x330 |
+                (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x300 |
                     xp->fdesc.protect_sector_cmd, 0x00400f);
-                (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x330 |
+                (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x300 |
                     xp->fdesc.protect_sector_cmd, 0x00600f);
-                (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x330 |
+                (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x300 |
                     xp->fdesc.protect_sector_cmd, 0x00800f);
-
-                /* TODO: ??? */
-                (void) ql_24xx_write_flash(ha,
-                    FLASH_CONF_ADDR | 0x101, 0x80);
-        } else {
-                (void) ql_24xx_write_flash(ha,
-                    FLASH_CONF_ADDR | 0x101, 0x9c);
         }
 
+        /* Remove Sector Protection Registers Locked (SPRL) bit. */
+        (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x100 |
+            xp->fdesc.write_statusreg_cmd, xp->fdesc.write_enable_bits);
+
+        (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x100 |
+            xp->fdesc.write_statusreg_cmd, xp->fdesc.write_disable_bits);
+
         /* Disable flash write. */
-        if (!(CFG_IST(ha, CFG_CTRL_81XX))) {
+        if (!CFG_IST(ha, CFG_FLASH_ACC_SUPPORT)) {
                 WRT32_IO_REG(ha, ctrl_status,
                     RD32_IO_REG(ha, ctrl_status) & ~ISP_FLASH_ENABLE);
                 RD32_IO_REG(ha, ctrl_status);   /* PCI Posting. */
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_dump_firmware
  *      Save RISC code state information.

@@ -11743,50 +12178,50 @@
  *      QL local function return status code.
  *
  * Context:
  *      Kernel context.
  */
-static int
+int
 ql_dump_firmware(ql_adapter_state_t *vha)
 {
         int                     rval;
         clock_t                 timer = drv_usectohz(30000000);
         ql_adapter_state_t      *ha = vha->pha;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         QL_DUMP_LOCK(ha);
 
         if (ha->ql_dump_state & QL_DUMPING ||
             (ha->ql_dump_state & QL_DUMP_VALID &&
             !(ha->ql_dump_state & QL_DUMP_UPLOADED))) {
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
                 QL_DUMP_UNLOCK(ha);
                 return (QL_SUCCESS);
         }
 
         QL_DUMP_UNLOCK(ha);
 
-        ql_awaken_task_daemon(ha, NULL, DRIVER_STALL, 0);
+        (void) ql_stall_driver(ha, 0);
 
-        /*
-         * Wait for all outstanding commands to complete
-         */
-        (void) ql_wait_outstanding(ha);
-
         /* Dump firmware. */
+        if (CFG_IST(ha, CFG_CTRL_82XX)) {
+                rval = ql_binary_fw_dump(ha, FALSE);
+        } else {
         rval = ql_binary_fw_dump(ha, TRUE);
+        }
 
         /* Do abort to force restart. */
-        ql_awaken_task_daemon(ha, NULL, ISP_ABORT_NEEDED, DRIVER_STALL);
+        ql_restart_driver(ha);
+        ql_awaken_task_daemon(ha, NULL, ISP_ABORT_NEEDED, 0);
         EL(ha, "restarting, isp_abort_needed\n");
 
         /* Acquire task daemon lock. */
         TASK_DAEMON_LOCK(ha);
 
         /* Wait for suspension to end. */
-        while (ha->task_daemon_flags & QL_SUSPENDED) {
+        while (DRIVER_SUSPENDED(ha)) {
                 ha->task_daemon_flags |= SUSPENDED_WAKEUP_FLG;
 
                 /* 30 seconds from now */
                 if (cv_reltimedwait(&ha->cv_dr_suspended,
                     &ha->task_daemon_mutex, timer, TR_CLOCK_TICK) == -1) {

@@ -11802,11 +12237,11 @@
         /* Release task daemon lock. */
         TASK_DAEMON_UNLOCK(ha);
 
         if (rval == QL_SUCCESS || rval == QL_DATA_EXISTS) {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         } else {
                 EL(ha, "failed, rval = %xh\n", rval);
         }
         return (rval);
 }

@@ -11826,19 +12261,22 @@
  *      Interrupt or Kernel context, no mailbox commands allowed.
  */
 int
 ql_binary_fw_dump(ql_adapter_state_t *vha, int lock_needed)
 {
+        uint32_t                cnt, index;
         clock_t                 timer;
-        mbx_cmd_t               mc;
-        mbx_cmd_t               *mcp = &mc;
         int                     rval = QL_SUCCESS;
         ql_adapter_state_t      *ha = vha->pha;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
-        if (CFG_IST(ha, CFG_CTRL_8021)) {
+        ADAPTER_STATE_LOCK(ha);
+        ha->flags &= ~FW_DUMP_NEEDED;
+        ADAPTER_STATE_UNLOCK(ha);
+
+        if (CFG_IST(ha, CFG_CTRL_82XX) && ha->md_capture_size == 0) {
                 EL(ha, "8021 not supported\n");
                 return (QL_NOT_SUPPORTED);
         }
 
         QL_DUMP_LOCK(ha);

@@ -11855,24 +12293,23 @@
         ha->ql_dump_state |= QL_DUMPING;
 
         QL_DUMP_UNLOCK(ha);
 
         if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE)) {
-
                 /* Insert Time Stamp */
                 rval = ql_fw_etrace(ha, &ha->fwexttracebuf,
-                    FTO_INSERT_TIME_STAMP);
+                    FTO_INSERT_TIME_STAMP, NULL);
                 if (rval != QL_SUCCESS) {
                         EL(ha, "f/w extended trace insert"
                             "time stamp failed: %xh\n", rval);
                 }
         }
 
         if (lock_needed == TRUE) {
                 /* Acquire mailbox register lock. */
                 MBX_REGISTER_LOCK(ha);
-                timer = (ha->mcp->timeout + 2) * drv_usectohz(1000000);
+                timer = ((MAILBOX_TOV + 6) * drv_usectohz(1000000));
 
                 /* Check for mailbox available, if not wait for signal. */
                 while (ha->mailbox_flags & MBX_BUSY_FLG) {
                         ha->mailbox_flags = (uint8_t)
                             (ha->mailbox_flags | MBX_WANT_FLG);

@@ -11896,12 +12333,10 @@
                 }
 
                 /* Set busy flag. */
                 ha->mailbox_flags = (uint8_t)
                     (ha->mailbox_flags | MBX_BUSY_FLG);
-                mcp->timeout = 120;
-                ha->mcp = mcp;
 
                 /* Release mailbox register lock. */
                 MBX_REGISTER_UNLOCK(ha);
         }
 

@@ -11909,39 +12344,76 @@
         if (ha->ql_dump_ptr != NULL) {
                 kmem_free(ha->ql_dump_ptr, ha->ql_dump_size);
                 ha->ql_dump_ptr = NULL;
         }
 
-        if (CFG_IST(ha, CFG_CTRL_2422)) {
+        if (CFG_IST(ha, CFG_CTRL_24XX)) {
                 ha->ql_dump_size = (uint32_t)(sizeof (ql_24xx_fw_dump_t) +
                     ha->fw_ext_memory_size);
         } else if (CFG_IST(ha, CFG_CTRL_25XX)) {
+                cnt = ha->rsp_queues_cnt > 1 ? ha->req_q[0]->req_ring.size +
+                    ha->req_q[1]->req_ring.size : ha->req_q[0]->req_ring.size;
+                index = ha->rsp_queues[0]->rsp_ring.size * ha->rsp_queues_cnt;
+
                 ha->ql_dump_size = (uint32_t)(sizeof (ql_25xx_fw_dump_t) +
-                    ha->fw_ext_memory_size);
+                    cnt + index + ha->fw_ext_memory_size +
+                    (ha->rsp_queues_cnt * 16));
+
         } else if (CFG_IST(ha, CFG_CTRL_81XX)) {
+                cnt = ha->rsp_queues_cnt > 1 ? ha->req_q[0]->req_ring.size +
+                    ha->req_q[1]->req_ring.size : ha->req_q[0]->req_ring.size;
+                index = ha->rsp_queues[0]->rsp_ring.size * ha->rsp_queues_cnt;
+
                 ha->ql_dump_size = (uint32_t)(sizeof (ql_81xx_fw_dump_t) +
-                    ha->fw_ext_memory_size);
+                    cnt + index + ha->fw_ext_memory_size +
+                    (ha->rsp_queues_cnt * 16));
+
+        } else if (CFG_IST(ha, CFG_CTRL_83XX)) {
+                cnt = ha->rsp_queues_cnt > 1 ? ha->req_q[0]->req_ring.size +
+                    ha->req_q[1]->req_ring.size : ha->req_q[0]->req_ring.size;
+                index = ha->rsp_queues[0]->rsp_ring.size * ha->rsp_queues_cnt;
+
+                ha->ql_dump_size = (uint32_t)(sizeof (ql_83xx_fw_dump_t) +
+                    cnt + index + ha->fw_ext_memory_size +
+                    (ha->rsp_queues_cnt * 16));
+        } else if (CFG_IST(ha, CFG_CTRL_82XX)) {
+                ha->ql_dump_size = ha->md_capture_size;
         } else {
                 ha->ql_dump_size = sizeof (ql_fw_dump_t);
         }
 
-        if ((ha->ql_dump_ptr = kmem_zalloc(ha->ql_dump_size, KM_NOSLEEP)) ==
-            NULL) {
+        if (CFG_IST(ha, CFG_CTRL_27XX)) {
+                rval = ql_27xx_binary_fw_dump(ha);
+        } else {
+                if ((ha->ql_dump_ptr =
+                    kmem_zalloc(ha->ql_dump_size, KM_NOSLEEP)) == NULL) {
                 rval = QL_MEMORY_ALLOC_FAILED;
         } else {
-                if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
-                        rval = ql_2300_binary_fw_dump(ha, ha->ql_dump_ptr);
+                        if (CFG_IST(ha, CFG_CTRL_2363)) {
+                                rval = ql_2300_binary_fw_dump(ha,
+                                    ha->ql_dump_ptr);
                 } else if (CFG_IST(ha, CFG_CTRL_81XX)) {
-                        rval = ql_81xx_binary_fw_dump(ha, ha->ql_dump_ptr);
+                                rval = ql_81xx_binary_fw_dump(ha,
+                                    ha->ql_dump_ptr);
+                        } else if (CFG_IST(ha, CFG_CTRL_83XX)) {
+                                rval = ql_83xx_binary_fw_dump(ha,
+                                    ha->ql_dump_ptr);
                 } else if (CFG_IST(ha, CFG_CTRL_25XX)) {
-                        rval = ql_25xx_binary_fw_dump(ha, ha->ql_dump_ptr);
-                } else if (CFG_IST(ha, CFG_CTRL_2422)) {
-                        rval = ql_24xx_binary_fw_dump(ha, ha->ql_dump_ptr);
+                                rval = ql_25xx_binary_fw_dump(ha,
+                                    ha->ql_dump_ptr);
+                        } else if (CFG_IST(ha, CFG_CTRL_24XX)) {
+                                rval = ql_24xx_binary_fw_dump(ha,
+                                    ha->ql_dump_ptr);
+                        } else if (CFG_IST(ha, CFG_CTRL_82XX)) {
+                                (void) ql_8021_reset_fw(ha);
+                                rval = QL_SUCCESS;
                 } else {
-                        rval = ql_2200_binary_fw_dump(ha, ha->ql_dump_ptr);
+                                rval = ql_2200_binary_fw_dump(ha,
+                                    ha->ql_dump_ptr);
                 }
         }
+        }
 
         /* Reset ISP chip. */
         ql_reset_chip(ha);
 
         QL_DUMP_LOCK(ha);

@@ -11986,22 +12458,30 @@
         caddr_t                 bp;
         int                     mbox_cnt;
         ql_adapter_state_t      *ha = vha->pha;
         ql_fw_dump_t            *fw = ha->ql_dump_ptr;
 
-        if (CFG_IST(ha, CFG_CTRL_2422)) {
+        if (CFG_IST(ha, CFG_CTRL_24XX)) {
                 return (ql_24xx_ascii_fw_dump(ha, bufp));
-        } else if (CFG_IST(ha, CFG_CTRL_2581)) {
-                return (ql_2581_ascii_fw_dump(ha, bufp));
+        } else if (CFG_IST(ha, CFG_CTRL_25XX)) {
+                return (ql_25xx_ascii_fw_dump(ha, bufp));
+        } else if (CFG_IST(ha, CFG_CTRL_81XX)) {
+                return (ql_81xx_ascii_fw_dump(ha, bufp));
+        } else if (CFG_IST(ha, CFG_CTRL_82XX)) {
+                return (ql_8021_ascii_fw_dump(ha, bufp));
+        } else if (CFG_IST(ha, CFG_CTRL_83XX)) {
+                return (ql_83xx_ascii_fw_dump(ha, bufp));
+        } else if (CFG_IST(ha, CFG_CTRL_27XX)) {
+                return (ql_27xx_ascii_fw_dump(ha, bufp));
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
-        if (CFG_IST(ha, CFG_CTRL_2300)) {
+        if (CFG_IST(ha, CFG_CTRL_23XX)) {
                 (void) sprintf(bufp, "\nISP 2300IP ");
-        } else if (CFG_IST(ha, CFG_CTRL_6322)) {
-                (void) sprintf(bufp, "\nISP 6322FLX ");
+        } else if (CFG_IST(ha, CFG_CTRL_63XX)) {
+                (void) sprintf(bufp, "\nISP 2322/6322FLX ");
         } else {
                 (void) sprintf(bufp, "\nISP 2200IP ");
         }
 
         bp = bufp + strlen(bufp);

@@ -12017,11 +12497,11 @@
                 }
                 (void) sprintf(bp, "%04x  ", fw->pbiu_reg[cnt]);
                 bp = bp + 6;
         }
 
-        if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
+        if (CFG_IST(ha, CFG_CTRL_2363)) {
                 (void) strcat(bufp, "\n\nReqQ-RspQ-Risc2Host Status "
                     "registers:");
                 bp = bufp + strlen(bufp);
                 for (cnt = 0; cnt < sizeof (fw->risc_host_reg) / 2; cnt++) {
                         if (cnt % 8 == 0) {

@@ -12032,20 +12512,20 @@
                 }
         }
 
         (void) strcat(bp, "\n\nMailbox Registers:");
         bp = bufp + strlen(bufp);
-        mbox_cnt = (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) ? 16 : 8;
+        mbox_cnt = CFG_IST(ha, CFG_CTRL_2363) ? 16 : 8;
         for (cnt = 0; cnt < mbox_cnt; cnt++) {
                 if (cnt % 8 == 0) {
                         *bp++ = '\n';
                 }
                 (void) sprintf(bp, "%04x  ", fw->mailbox_reg[cnt]);
                 bp = bp + 6;
         }
 
-        if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
+        if (CFG_IST(ha, CFG_CTRL_2363)) {
                 (void) strcat(bp, "\n\nAuto Request Response DMA Registers:");
                 bp = bufp + strlen(bufp);
                 for (cnt = 0; cnt < sizeof (fw->resp_dma_reg) / 2; cnt++) {
                         if (cnt % 8 == 0) {
                                 *bp++ = '\n';

@@ -12156,12 +12636,11 @@
         }
 
         (void) strcat(bp, "\n\nFrame Buffer Hardware Registers:");
         bp = bufp + strlen(bufp);
         for (cnt = 0; cnt < sizeof (fw->frame_buf_hdw_reg) / 2; cnt++) {
-                if ((cnt == 16) && ((CFG_IST(ha, (CFG_CTRL_2300 |
-                    CFG_CTRL_6322)) == 0))) {
+                if (cnt == 16 && !CFG_IST(ha, CFG_CTRL_2363)) {
                         break;
                 }
                 if (cnt % 8 == 0) {
                         *bp++ = '\n';
                 }

@@ -12187,11 +12666,11 @@
                 }
                 (void) sprintf(bp, "%04x  ", fw->fpm_b1_reg[cnt]);
                 bp = bp + 6;
         }
 
-        if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
+        if (CFG_IST(ha, CFG_CTRL_2363)) {
                 (void) strcat(bp, "\n\nCode RAM Dump:");
                 bp = bufp + strlen(bufp);
                 for (cnt = 0; cnt < sizeof (fw->risc_ram) / 2; cnt++) {
                         if (cnt % 8 == 0) {
                                 (void) sprintf(bp, "\n%05x: ", cnt + 0x0800);

@@ -12260,11 +12739,11 @@
                 bp += strlen(bp);
         }
 
         (void) sprintf(bp, "\n");
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_10(ha, "done, size=0x%x\n", strlen(bufp));
 
         return (strlen(bufp));
 }
 
 /*

@@ -12286,11 +12765,11 @@
 {
         uint32_t                cnt;
         caddr_t                 bp = bufp;
         ql_24xx_fw_dump_t       *fw = ha->ql_dump_ptr;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         (void) sprintf(bp, "ISP FW Version %d.%02d.%02d Attributes %X\n",
             ha->fw_major_version, ha->fw_minor_version,
             ha->fw_subminor_version, ha->fw_attributes);
         bp += strlen(bp);

@@ -12674,18 +13153,18 @@
         (void) sprintf(bp, "\n\n");
         bp += strlen(bp);
 
         cnt = (uint32_t)((uintptr_t)bp - (uintptr_t)bufp);
 
-        QL_PRINT_3(CE_CONT, "(%d): done=%xh\n", ha->instance, cnt);
+        QL_PRINT_10(ha, "done=%xh\n", cnt);
 
         return (cnt);
 }
 
 /*
- * ql_2581_ascii_fw_dump
- *      Converts ISP25xx or ISP81xx firmware binary dump to ascii.
+ * ql_25xx_ascii_fw_dump
+ *      Converts ISP25xx firmware binary dump to ascii.
  *
  * Input:
  *      ha = adapter state pointer.
  *      bptr = buffer pointer.
  *

@@ -12694,27 +13173,33 @@
  *
  * Context:
  *      Kernel context.
  */
 static size_t
-ql_2581_ascii_fw_dump(ql_adapter_state_t *ha, caddr_t bufp)
+ql_25xx_ascii_fw_dump(ql_adapter_state_t *ha, caddr_t bufp)
 {
-        uint32_t                cnt;
-        uint32_t                cnt1;
+        uint32_t                cnt, cnt1, *dp, *dp2;
         caddr_t                 bp = bufp;
         ql_25xx_fw_dump_t       *fw = ha->ql_dump_ptr;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         (void) sprintf(bp, "\nISP FW Version %d.%02d.%02d Attributes %X\n",
             ha->fw_major_version, ha->fw_minor_version,
             ha->fw_subminor_version, ha->fw_attributes);
         bp += strlen(bp);
 
+        (void) sprintf(bp, "\nHCCR Register\n%08x\n", fw->hccr);
+        bp += strlen(bp);
+
         (void) sprintf(bp, "\nR2H Status Register\n%08x\n", fw->r2h_status);
         bp += strlen(bp);
 
+        (void) sprintf(bp, "\nAER Uncorrectable Error Status Register\n%08x\n",
+            fw->aer_ues);
+        bp += strlen(bp);
+
         (void) sprintf(bp, "\nHostRisc Registers");
         bp += strlen(bp);
         for (cnt = 0; cnt < sizeof (fw->hostrisc_reg) / 4; cnt++) {
                 if (cnt % 8 == 0) {
                         (void) sprintf(bp++, "\n");

@@ -13017,13 +13502,11 @@
                 bp += 9;
         }
 
         (void) sprintf(bp, "\n\nFPM Hardware Registers");
         bp += strlen(bp);
-        cnt1 = CFG_IST(ha, CFG_CTRL_81XX) ?
-            (uint32_t)(sizeof (((ql_81xx_fw_dump_t *)(fw))->fpm_hdw_reg)) :
-            (uint32_t)(sizeof (fw->fpm_hdw_reg));
+        cnt1 = sizeof (fw->fpm_hdw_reg);
         for (cnt = 0; cnt < cnt1 / 4; cnt++) {
                 if (cnt % 8 == 0) {
                         (void) sprintf(bp++, "\n");
                 }
                 (void) sprintf(bp, "%08x ", fw->fpm_hdw_reg[cnt]);

@@ -13030,13 +13513,11 @@
                 bp += 9;
         }
 
         (void) sprintf(bp, "\n\nFB Hardware Registers");
         bp += strlen(bp);
-        cnt1 = CFG_IST(ha, CFG_CTRL_81XX) ?
-            (uint32_t)(sizeof (((ql_81xx_fw_dump_t *)(fw))->fb_hdw_reg)) :
-            (uint32_t)(sizeof (fw->fb_hdw_reg));
+        cnt1 = sizeof (fw->fb_hdw_reg);
         for (cnt = 0; cnt < cnt1 / 4; cnt++) {
                 if (cnt % 8 == 0) {
                         (void) sprintf(bp++, "\n");
                 }
                 (void) sprintf(bp, "%08x ", fw->fb_hdw_reg[cnt]);

@@ -13054,44 +13535,563 @@
                 bp += 9;
         }
 
         (void) sprintf(bp, "\n\nExternal Memory");
         bp += strlen(bp);
+        dp = (uint32_t *)((caddr_t)fw->req_rsp_ext_mem + fw->req_q_size[0] +
+            fw->req_q_size[1] + fw->rsp_q_size + (ha->rsp_queues_cnt * 16));
         for (cnt = 0; cnt < ha->fw_ext_memory_size / 4; cnt++) {
                 if (cnt % 8 == 0) {
                         (void) sprintf(bp, "\n%08x: ", cnt + 0x100000);
                         bp += 11;
                 }
-                (void) sprintf(bp, "%08x ", fw->ext_mem[cnt]);
+                (void) sprintf(bp, "%08x ", *dp++);
                 bp += 9;
         }
 
         (void) sprintf(bp, "\n[<==END] ISP Debug Dump");
         bp += strlen(bp);
 
-        (void) sprintf(bp, "\n\nRequest Queue");
+        dp = fw->req_rsp_ext_mem + (ha->rsp_queues_cnt * 4);
+        for (cnt = 0; cnt < 2 && fw->req_q_size[cnt]; cnt++) {
+                dp2 = dp;
+                for (cnt1 = 0; cnt1 < fw->req_q_size[cnt] / 4; cnt1++) {
+                        if (*dp2++) {
+                                break;
+                        }
+                }
+                if (cnt1 == fw->req_q_size[cnt] / 4) {
+                        dp = dp2;
+                        continue;
+                }
+                (void) sprintf(bp, "\n\nRequest Queue\nQueue %d:", cnt);
         bp += strlen(bp);
-        for (cnt = 0; cnt < REQUEST_QUEUE_SIZE / 4; cnt++) {
+                for (cnt1 = 0; cnt1 < fw->req_q_size[cnt] / 4; cnt1++) {
+                        if (cnt1 % 8 == 0) {
+                                (void) sprintf(bp, "\n%08x: ", cnt1);
+                                bp += strlen(bp);
+                        }
+                        (void) sprintf(bp, "%08x ", *dp++);
+                        bp += strlen(bp);
+                }
+        }
+
+        for (cnt = 0; cnt < ha->rsp_queues_cnt && cnt < 16; cnt++) {
+                dp2 = dp;
+                for (cnt1 = 0; cnt1 < ha->rsp_queues[cnt]->rsp_ring.size / 4;
+                    cnt1++) {
+                        if (*dp2++) {
+                                break;
+                        }
+                }
+                if (cnt1 == ha->rsp_queues[cnt]->rsp_ring.size / 4) {
+                        dp = dp2;
+                        continue;
+                }
+                (void) sprintf(bp, "\n\nResponse Queue\nQueue %d:", cnt);
+                bp += strlen(bp);
+                for (cnt1 = 0; cnt1 < ha->rsp_queues[cnt]->rsp_ring.size / 4;
+                    cnt1++) {
+                        if (cnt1 % 8 == 0) {
+                                (void) sprintf(bp, "\n%08x: ", cnt1);
+                                bp += strlen(bp);
+                        }
+                        (void) sprintf(bp, "%08x ", *dp++);
+                        bp += strlen(bp);
+                }
+        }
+
+        if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE) &&
+            (ha->fwexttracebuf.bp != NULL)) {
+                uint32_t cnt_b = 0;
+                uint64_t w64 = (uintptr_t)ha->fwexttracebuf.bp;
+
+                (void) sprintf(bp, "\n\nExtended Trace Buffer Memory");
+                bp += strlen(bp);
+                /* show data address as a byte address, data as long words */
+                for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
+                        cnt_b = cnt * 4;
+                        if (cnt_b % 32 == 0) {
+                                (void) sprintf(bp, "\n%08x: ",
+                                    (int)(w64 + cnt_b));
+                                bp += 11;
+                        }
+                        (void) sprintf(bp, "%08x ", fw->ext_trace_buf[cnt]);
+                        bp += 9;
+                }
+        }
+
+        if (CFG_IST(ha, CFG_ENABLE_FWFCETRACE) &&
+            (ha->fwfcetracebuf.bp != NULL)) {
+                uint32_t cnt_b = 0;
+                uint64_t w64 = (uintptr_t)ha->fwfcetracebuf.bp;
+
+                (void) sprintf(bp, "\n\nFC Event Trace Buffer Memory");
+                bp += strlen(bp);
+                /* show data address as a byte address, data as long words */
+                for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
+                        cnt_b = cnt * 4;
+                        if (cnt_b % 32 == 0) {
+                                (void) sprintf(bp, "\n%08x: ",
+                                    (int)(w64 + cnt_b));
+                                bp += 11;
+                        }
+                        (void) sprintf(bp, "%08x ", fw->fce_trace_buf[cnt]);
+                        bp += 9;
+                }
+        }
+
+        (void) sprintf(bp, "\n\n");
+        bp += strlen(bp);
+
+        cnt = (uint32_t)((uintptr_t)bp - (uintptr_t)bufp);
+
+        QL_PRINT_10(ha, "done=%xh\n", cnt);
+
+        return (cnt);
+}
+
+/*
+ * ql_81xx_ascii_fw_dump
+ *      Converts ISP81xx firmware binary dump to ascii.
+ *
+ * Input:
+ *      ha = adapter state pointer.
+ *      bptr = buffer pointer.
+ *
+ * Returns:
+ *      Amount of data buffer used.
+ *
+ * Context:
+ *      Kernel context.
+ */
+static size_t
+ql_81xx_ascii_fw_dump(ql_adapter_state_t *ha, caddr_t bufp)
+{
+        uint32_t                cnt, cnt1, *dp, *dp2;
+        caddr_t                 bp = bufp;
+        ql_81xx_fw_dump_t       *fw = ha->ql_dump_ptr;
+
+        QL_PRINT_3(ha, "started\n");
+
+        (void) sprintf(bp, "\nISP FW Version %d.%02d.%02d Attributes %X\n",
+            ha->fw_major_version, ha->fw_minor_version,
+            ha->fw_subminor_version, ha->fw_attributes);
+        bp += strlen(bp);
+
+        (void) sprintf(bp, "\nHCCR Register\n%08x\n", fw->hccr);
+        bp += strlen(bp);
+
+        (void) sprintf(bp, "\nR2H Status Register\n%08x\n", fw->r2h_status);
+        bp += strlen(bp);
+
+        (void) sprintf(bp, "\nAER Uncorrectable Error Status Register\n%08x\n",
+            fw->aer_ues);
+        bp += strlen(bp);
+
+        (void) sprintf(bp, "\nHostRisc Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->hostrisc_reg) / 4; cnt++) {
                 if (cnt % 8 == 0) {
-                        (void) sprintf(bp, "\n%08x: ", cnt);
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->hostrisc_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nPCIe Registers");
                         bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->pcie_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
                 }
-                (void) sprintf(bp, "%08x ", fw->req_q[cnt]);
+                (void) sprintf(bp, "%08x ", fw->pcie_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) strcat(bp, "\n\nHost Interface Registers");
                 bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->host_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
         }
+                (void) sprintf(bp, "%08x ", fw->host_reg[cnt]);
+                bp += 9;
+        }
 
-        (void) sprintf(bp, "\n\nResponse Queue");
+        (void) sprintf(bufp + strlen(bufp), "\n\nShadow Registers");
         bp += strlen(bp);
-        for (cnt = 0; cnt < RESPONSE_QUEUE_SIZE / 4; cnt++) {
+        for (cnt = 0; cnt < sizeof (fw->shadow_reg) / 4; cnt++) {
                 if (cnt % 8 == 0) {
-                        (void) sprintf(bp, "\n%08x: ", cnt);
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->shadow_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bufp + strlen(bufp), "\n\nRISC IO Register\n%08x",
+            fw->risc_io);
                         bp += strlen(bp);
+
+        (void) sprintf(bp, "\n\nMailbox Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) {
+                if (cnt % 16 == 0) {
+                        (void) sprintf(bp++, "\n");
                 }
-                (void) sprintf(bp, "%08x ", fw->rsp_q[cnt]);
+                (void) sprintf(bp, "%04x ", fw->mailbox_reg[cnt]);
+                bp += 5;
+        }
+
+        (void) sprintf(bp, "\n\nXSEQ GP Registers");
                 bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->xseq_gp_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
         }
+                (void) sprintf(bp, "%08x ", fw->xseq_gp_reg[cnt]);
+                bp += 9;
+        }
 
+        (void) sprintf(bp, "\n\nXSEQ-0 Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->xseq_0_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->xseq_0_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nXSEQ-1 Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->xseq_1_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->xseq_1_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nRSEQ GP Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->rseq_gp_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->rseq_gp_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nRSEQ-0 Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->rseq_0_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->rseq_0_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nRSEQ-1 Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->rseq_1_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->rseq_1_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nRSEQ-2 Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->rseq_2_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->rseq_2_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nASEQ GP Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->aseq_gp_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->aseq_gp_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nASEQ-0 Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->aseq_0_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->aseq_0_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nASEQ-1 Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->aseq_1_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->aseq_1_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nASEQ-2 Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->aseq_2_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->aseq_2_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nCommand DMA Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->cmd_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->cmd_dma_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nRequest0 Queue DMA Channel Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->req0_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->req0_dma_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nResponse0 Queue DMA Channel Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->resp0_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->resp0_dma_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nRequest1 Queue DMA Channel Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->req1_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->req1_dma_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nXMT0 Data DMA Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->xmt0_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->xmt0_dma_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nXMT1 Data DMA Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->xmt1_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->xmt1_dma_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nXMT2 Data DMA Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->xmt2_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->xmt2_dma_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nXMT3 Data DMA Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->xmt3_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->xmt3_dma_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nXMT4 Data DMA Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->xmt4_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->xmt4_dma_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nXMT Data DMA Common Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->xmt_data_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->xmt_data_dma_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nRCV Thread 0 Data DMA Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->rcvt0_data_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->rcvt0_data_dma_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nRCV Thread 1 Data DMA Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->rcvt1_data_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->rcvt1_data_dma_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nRISC GP Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->risc_gp_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->risc_gp_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nLMC Registers");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->lmc_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->lmc_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nFPM Hardware Registers");
+        bp += strlen(bp);
+        cnt1 = sizeof (fw->fpm_hdw_reg);
+        for (cnt = 0; cnt < cnt1 / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->fpm_hdw_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nFB Hardware Registers");
+        bp += strlen(bp);
+        cnt1 = sizeof (fw->fb_hdw_reg);
+        for (cnt = 0; cnt < cnt1 / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp++, "\n");
+                }
+                (void) sprintf(bp, "%08x ", fw->fb_hdw_reg[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nCode RAM");
+        bp += strlen(bp);
+        for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp, "\n%08x: ", cnt + 0x20000);
+                        bp += 11;
+                }
+                (void) sprintf(bp, "%08x ", fw->code_ram[cnt]);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n\nExternal Memory");
+        bp += strlen(bp);
+        dp = (uint32_t *)((caddr_t)fw->req_rsp_ext_mem + fw->req_q_size[0] +
+            fw->req_q_size[1] + fw->rsp_q_size + (ha->rsp_queues_cnt * 16));
+        for (cnt = 0; cnt < ha->fw_ext_memory_size / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) sprintf(bp, "\n%08x: ", cnt + 0x100000);
+                        bp += 11;
+                }
+                (void) sprintf(bp, "%08x ", *dp++);
+                bp += 9;
+        }
+
+        (void) sprintf(bp, "\n[<==END] ISP Debug Dump");
+        bp += strlen(bp);
+
+        dp = fw->req_rsp_ext_mem + (ha->rsp_queues_cnt * 4);
+        for (cnt = 0; cnt < 2 && fw->req_q_size[cnt]; cnt++) {
+                dp2 = dp;
+                for (cnt1 = 0; cnt1 < fw->req_q_size[cnt] / 4; cnt1++) {
+                        if (*dp2++) {
+                                break;
+                        }
+                }
+                if (cnt1 == fw->req_q_size[cnt] / 4) {
+                        dp = dp2;
+                        continue;
+                }
+                (void) sprintf(bp, "\n\nRequest Queue\nQueue %d:", cnt);
+                bp += strlen(bp);
+                for (cnt1 = 0; cnt1 < fw->req_q_size[cnt] / 4; cnt1++) {
+                        if (cnt1 % 8 == 0) {
+                                (void) sprintf(bp, "\n%08x: ", cnt1);
+                                bp += strlen(bp);
+                        }
+                        (void) sprintf(bp, "%08x ", *dp++);
+                        bp += strlen(bp);
+                }
+        }
+
+        for (cnt = 0; cnt < ha->rsp_queues_cnt && cnt < 16; cnt++) {
+                dp2 = dp;
+                for (cnt1 = 0; cnt1 < ha->rsp_queues[cnt]->rsp_ring.size / 4;
+                    cnt1++) {
+                        if (*dp2++) {
+                                break;
+                        }
+                }
+                if (cnt1 == ha->rsp_queues[cnt]->rsp_ring.size / 4) {
+                        dp = dp2;
+                        continue;
+                }
+                (void) sprintf(bp, "\n\nResponse Queue\nQueue %d:", cnt);
+                bp += strlen(bp);
+                for (cnt1 = 0; cnt1 < ha->rsp_queues[cnt]->rsp_ring.size / 4;
+                    cnt1++) {
+                        if (cnt1 % 8 == 0) {
+                                (void) sprintf(bp, "\n%08x: ", cnt1);
+                                bp += strlen(bp);
+                        }
+                        (void) sprintf(bp, "%08x ", *dp++);
+                        bp += strlen(bp);
+                }
+        }
+
         if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE) &&
             (ha->fwexttracebuf.bp != NULL)) {
                 uint32_t cnt_b = 0;
                 uint64_t w64 = (uintptr_t)ha->fwexttracebuf.bp;
 

@@ -13133,16 +14133,59 @@
         (void) sprintf(bp, "\n\n");
         bp += strlen(bp);
 
         cnt = (uint32_t)((uintptr_t)bp - (uintptr_t)bufp);
 
-        QL_PRINT_3(CE_CONT, "(%d): done=%xh\n", ha->instance, cnt);
+        QL_PRINT_10(ha, "done=%xh\n", cnt);
 
         return (cnt);
 }
 
 /*
+ * ql_8021_ascii_fw_dump
+ *      Converts ISP8021 firmware binary dump to ascii.
+ *
+ * Input:
+ *      ha = adapter state pointer.
+ *      bptr = buffer pointer.
+ *
+ * Returns:
+ *      Amount of data buffer used.
+ *
+ * Context:
+ *      Kernel context.
+ */
+static size_t
+ql_8021_ascii_fw_dump(ql_adapter_state_t *ha, caddr_t bufp)
+{
+        uint32_t        cnt;
+        caddr_t         bp = bufp;
+        uint8_t         *fw = ha->ql_dump_ptr;
+
+        /*
+         * 2 ascii bytes per binary byte + a space and
+         * a newline every 16 binary bytes
+         */
+        cnt = 0;
+        while (cnt < ha->ql_dump_size) {
+                (void) sprintf(bp, "%02x ", *fw++);
+                bp += strlen(bp);
+                if (++cnt % 16 == 0) {
+                        (void) sprintf(bp, "\n");
+                        bp += strlen(bp);
+                }
+        }
+        if (cnt % 16 != 0) {
+                (void) sprintf(bp, "\n");
+                bp += strlen(bp);
+        }
+        cnt = (uint32_t)((uintptr_t)bp - (uintptr_t)bufp);
+        QL_PRINT_10(ha, "done=%xh\n", cnt);
+        return (cnt);
+}
+
+/*
  * ql_2200_binary_fw_dump
  *
  * Input:
  *      ha:     adapter state pointer.
  *      fw:     firmware dump context pointer.

@@ -13161,17 +14204,14 @@
         clock_t         timer;
         mbx_cmd_t       mc;
         mbx_cmd_t       *mcp = &mc;
         int             rval = QL_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         /* Disable ISP interrupts. */
-        WRT16_IO_REG(ha, ictrl, 0);
-        ADAPTER_STATE_LOCK(ha);
-        ha->flags &= ~INTERRUPTS_ENABLED;
-        ADAPTER_STATE_UNLOCK(ha);
+        ql_disable_intr(ha);
 
         /* Release mailbox registers. */
         WRT16_IO_REG(ha, semaphore, 0);
 
         /* Pause RISC. */

@@ -13270,11 +14310,11 @@
                 /* Release RISC module. */
                 WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
 
                 /* Wait for RISC to recover from reset. */
                 timer = 30000;
-                while (RD16_IO_REG(ha, mailbox_out[0]) == MBS_BUSY) {
+                while (RD16_IO_REG(ha, mailbox_out[0]) == MBS_ROM_BUSY) {
                         if (timer-- != 0) {
                                 drv_usecwait(MILLISEC);
                         } else {
                                 rval = QL_FUNCTION_TIMEOUT;
                                 break;

@@ -13344,11 +14384,11 @@
                                 break;
                         }
                 }
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (rval);
 }
 
 /*

@@ -13368,17 +14408,14 @@
 ql_2300_binary_fw_dump(ql_adapter_state_t *ha, ql_fw_dump_t *fw)
 {
         clock_t timer;
         int     rval = QL_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         /* Disable ISP interrupts. */
-        WRT16_IO_REG(ha, ictrl, 0);
-        ADAPTER_STATE_LOCK(ha);
-        ha->flags &= ~INTERRUPTS_ENABLED;
-        ADAPTER_STATE_UNLOCK(ha);
+        ql_disable_intr(ha);
 
         /* Release mailbox registers. */
         WRT16_IO_REG(ha, semaphore, 0);
 
         /* Pause RISC. */

@@ -13483,11 +14520,11 @@
                 /* Release RISC module. */
                 WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
 
                 /* Wait for RISC to recover from reset. */
                 timer = 30000;
-                while (RD16_IO_REG(ha, mailbox_out[0]) == MBS_BUSY) {
+                while (RD16_IO_REG(ha, mailbox_out[0]) == MBS_ROM_BUSY) {
                         if (timer-- != 0) {
                                 drv_usecwait(MILLISEC);
                         } else {
                                 rval = QL_FUNCTION_TIMEOUT;
                                 break;

@@ -13509,11 +14546,11 @@
         /* Get DATA SRAM. */
         if (rval == QL_SUCCESS) {
                 rval = ql_read_risc_ram(ha, 0x10800, 0xf800, fw->data_ram);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (rval);
 }
 
 /*

@@ -13535,18 +14572,18 @@
         uint32_t        *reg32;
         void            *bp;
         clock_t         timer;
         int             rval = QL_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         fw->hccr = RD32_IO_REG(ha, hccr);
 
         /* Pause RISC. */
         if ((RD32_IO_REG(ha, risc2host) & RH_RISC_PAUSED) == 0) {
                 /* Disable ISP interrupts. */
-                WRT16_IO_REG(ha, ictrl, 0);
+                ql_disable_intr(ha);
 
                 WRT32_IO_REG(ha, hccr, HC24_PAUSE_RISC);
                 for (timer = 30000;
                     (RD32_IO_REG(ha, risc2host) & RH_RISC_PAUSED) == 0 &&
                     rval == QL_SUCCESS; timer--) {

@@ -13562,15 +14599,11 @@
                 /* Host interface registers. */
                 (void) ql_read_regs(ha, fw->host_reg, ha->iobase,
                     sizeof (fw->host_reg) / 4, 32);
 
                 /* Disable ISP interrupts. */
-                WRT32_IO_REG(ha, ictrl, 0);
-                RD32_IO_REG(ha, ictrl);
-                ADAPTER_STATE_LOCK(ha);
-                ha->flags &= ~INTERRUPTS_ENABLED;
-                ADAPTER_STATE_UNLOCK(ha);
+                ql_disable_intr(ha);
 
                 /* Shadow registers. */
 
                 WRT32_IO_REG(ha, io_base_addr, 0x0F70);
                 RD32_IO_REG(ha, io_base_addr);

@@ -13863,16 +14896,15 @@
         }
 
         /* Get the request queue */
         if (rval == QL_SUCCESS) {
                 uint32_t        cnt;
-                uint32_t        *w32 = (uint32_t *)ha->request_ring_bp;
+                uint32_t        *w32 = (uint32_t *)ha->req_q[0]->req_ring.bp;
 
                 /* Sync DMA buffer. */
-                (void) ddi_dma_sync(ha->hba_buf.dma_handle,
-                    REQUEST_Q_BUFFER_OFFSET, sizeof (fw->req_q),
-                    DDI_DMA_SYNC_FORKERNEL);
+                (void) ddi_dma_sync(ha->req_q[0]->req_ring.dma_handle,
+                    0, sizeof (fw->req_q), DDI_DMA_SYNC_FORKERNEL);
 
                 for (cnt = 0; cnt < sizeof (fw->req_q) / 4; cnt++) {
                         fw->req_q[cnt] = *w32++;
                         LITTLE_ENDIAN_32(&fw->req_q[cnt]);
                 }

@@ -13879,16 +14911,16 @@
         }
 
         /* Get the response queue */
         if (rval == QL_SUCCESS) {
                 uint32_t        cnt;
-                uint32_t        *w32 = (uint32_t *)ha->response_ring_bp;
+                uint32_t        *w32 =
+                    (uint32_t *)ha->rsp_queues[0]->rsp_ring.bp;
 
                 /* Sync DMA buffer. */
-                (void) ddi_dma_sync(ha->hba_buf.dma_handle,
-                    RESPONSE_Q_BUFFER_OFFSET, sizeof (fw->rsp_q),
-                    DDI_DMA_SYNC_FORKERNEL);
+                (void) ddi_dma_sync(ha->rsp_queues[0]->rsp_ring.dma_handle,
+                    0, sizeof (fw->rsp_q), DDI_DMA_SYNC_FORKERNEL);
 
                 for (cnt = 0; cnt < sizeof (fw->rsp_q) / 4; cnt++) {
                         fw->rsp_q[cnt] = *w32++;
                         LITTLE_ENDIAN_32(&fw->rsp_q[cnt]);
                 }

@@ -13945,11 +14977,11 @@
 
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed=%xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
 
         return (rval);
 }
 

@@ -13967,23 +14999,31 @@
  *      Interrupt or Kernel context, no mailbox commands allowed.
  */
 static int
 ql_25xx_binary_fw_dump(ql_adapter_state_t *ha, ql_25xx_fw_dump_t *fw)
 {
-        uint32_t        *reg32;
+        uint32_t        *reg32, cnt, *w32ptr, index, *dp;
         void            *bp;
         clock_t         timer;
         int             rval = QL_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
+        fw->req_q_size[0] = ha->req_q[0]->req_ring.size;
+        if (ha->req_q[1] != NULL) {
+                fw->req_q_size[1] = ha->req_q[1]->req_ring.size;
+        }
+        fw->rsp_q_size = ha->rsp_queues[0]->rsp_ring.size * ha->rsp_queues_cnt;
+
+        fw->hccr = RD32_IO_REG(ha, hccr);
         fw->r2h_status = RD32_IO_REG(ha, risc2host);
+        fw->aer_ues = ql_pci_config_get32(ha, 0x104);
 
         /* Pause RISC. */
         if ((RD32_IO_REG(ha, risc2host) & RH_RISC_PAUSED) == 0) {
                 /* Disable ISP interrupts. */
-                WRT16_IO_REG(ha, ictrl, 0);
+                ql_disable_intr(ha);
 
                 WRT32_IO_REG(ha, hccr, HC24_PAUSE_RISC);
                 for (timer = 30000;
                     (RD32_IO_REG(ha, risc2host) & RH_RISC_PAUSED) == 0 &&
                     rval == QL_SUCCESS; timer--) {

@@ -14006,11 +15046,11 @@
                 /* HostRisc registers. */
                 WRT32_IO_REG(ha, io_base_addr, 0x7000);
                 bp = ql_read_regs(ha, fw->hostrisc_reg, ha->iobase + 0xC0,
                     16, 32);
                 WRT32_IO_REG(ha, io_base_addr, 0x7010);
-                bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+                (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
 
                 /* PCIe registers. */
                 WRT32_IO_REG(ha, io_base_addr, 0x7c00);
                 WRT_REG_DWORD(ha, ha->iobase + 0xc0, 0x1);
                 bp = ql_read_regs(ha, fw->pcie_reg, ha->iobase + 0xC4,

@@ -14021,17 +15061,12 @@
                 /* Host interface registers. */
                 (void) ql_read_regs(ha, fw->host_reg, ha->iobase,
                     sizeof (fw->host_reg) / 4, 32);
 
                 /* Disable ISP interrupts. */
+                ql_disable_intr(ha);
 
-                WRT32_IO_REG(ha, ictrl, 0);
-                RD32_IO_REG(ha, ictrl);
-                ADAPTER_STATE_LOCK(ha);
-                ha->flags &= ~INTERRUPTS_ENABLED;
-                ADAPTER_STATE_UNLOCK(ha);
-
                 /* Shadow registers. */
 
                 WRT32_IO_REG(ha, io_base_addr, 0x0F70);
                 RD32_IO_REG(ha, io_base_addr);
 

@@ -14395,57 +15430,100 @@
                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
                 WRT32_IO_REG(ha, io_base_addr, 0x6F00);
                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
         }
 
-        /* Get the request queue */
         if (rval == QL_SUCCESS) {
-                uint32_t        cnt;
-                uint32_t        *w32 = (uint32_t *)ha->request_ring_bp;
-
-                /* Sync DMA buffer. */
-                (void) ddi_dma_sync(ha->hba_buf.dma_handle,
-                    REQUEST_Q_BUFFER_OFFSET, sizeof (fw->req_q),
-                    DDI_DMA_SYNC_FORKERNEL);
-
-                for (cnt = 0; cnt < sizeof (fw->req_q) / 4; cnt++) {
-                        fw->req_q[cnt] = *w32++;
-                        LITTLE_ENDIAN_32(&fw->req_q[cnt]);
+                /* Get the Queue Pointers */
+                dp = fw->req_rsp_ext_mem;
+                for (index = 0; index < ha->rsp_queues_cnt; index++) {
+                        if (index == 0 && ha->flags & MULTI_QUEUE) {
+                                *dp = RD32_MBAR_REG(ha,
+                                    ha->req_q[0]->mbar_req_in);
+                                LITTLE_ENDIAN_32(dp);
+                                dp++;
+                                *dp = RD32_MBAR_REG(ha,
+                                    ha->req_q[0]->mbar_req_out);
+                                LITTLE_ENDIAN_32(dp);
+                                dp++;
+                        } else if (index == 1 && ha->flags & MULTI_QUEUE) {
+                                *dp = RD32_MBAR_REG(ha,
+                                    ha->req_q[1]->mbar_req_in);
+                                LITTLE_ENDIAN_32(dp);
+                                dp++;
+                                *dp = RD32_MBAR_REG(ha,
+                                    ha->req_q[1]->mbar_req_out);
+                                LITTLE_ENDIAN_32(dp);
+                                dp++;
+                        } else {
+                                *dp++ = 0;
+                                *dp++ = 0;
                 }
+                        if (ha->flags & MULTI_QUEUE) {
+                                *dp = RD32_MBAR_REG(ha,
+                                    ha->rsp_queues[index]->mbar_rsp_in);
+                                LITTLE_ENDIAN_32(dp);
+                                dp++;
+                                *dp = RD32_MBAR_REG(ha,
+                                    ha->rsp_queues[index]->mbar_rsp_out);
+                                LITTLE_ENDIAN_32(dp);
+                                dp++;
+                        } else {
+                                *dp++ = 0;
+                                *dp++ = 0;
         }
+                }
+                /* Get the request queue */
+                (void) ddi_dma_sync(ha->req_q[0]->req_ring.dma_handle, 0, 0,
+                    DDI_DMA_SYNC_FORCPU);
+                w32ptr = (uint32_t *)ha->req_q[0]->req_ring.bp;
+                for (cnt = 0; cnt < fw->req_q_size[0] / 4; cnt++) {
+                        *dp = *w32ptr++;
+                        LITTLE_ENDIAN_32(dp);
+                        dp++;
+                }
+                if (ha->req_q[1] != NULL) {
+                        (void) ddi_dma_sync(ha->req_q[1]->req_ring.dma_handle,
+                            0, 0, DDI_DMA_SYNC_FORCPU);
+                        w32ptr = (uint32_t *)ha->req_q[1]->req_ring.bp;
+                        for (cnt = 0; cnt < fw->req_q_size[1] / 4; cnt++) {
+                                *dp = *w32ptr++;
+                                LITTLE_ENDIAN_32(dp);
+                                dp++;
+                        }
+                }
 
-        /* Get the respons queue */
-        if (rval == QL_SUCCESS) {
-                uint32_t        cnt;
-                uint32_t        *w32 = (uint32_t *)ha->response_ring_bp;
-
-                /* Sync DMA buffer. */
-                (void) ddi_dma_sync(ha->hba_buf.dma_handle,
-                    RESPONSE_Q_BUFFER_OFFSET, sizeof (fw->rsp_q),
-                    DDI_DMA_SYNC_FORKERNEL);
-
-                for (cnt = 0; cnt < sizeof (fw->rsp_q) / 4; cnt++) {
-                        fw->rsp_q[cnt] = *w32++;
-                        LITTLE_ENDIAN_32(&fw->rsp_q[cnt]);
+                /* Get the response queues */
+                for (index = 0; index < ha->rsp_queues_cnt; index++) {
+                        (void) ddi_dma_sync(
+                            ha->rsp_queues[index]->rsp_ring.dma_handle,
+                            0, 0, DDI_DMA_SYNC_FORCPU);
+                        w32ptr = (uint32_t *)
+                            ha->rsp_queues[index]->rsp_ring.bp;
+                        for (cnt = 0;
+                            cnt < ha->rsp_queues[index]->rsp_ring.size / 4;
+                            cnt++) {
+                                *dp = *w32ptr++;
+                                LITTLE_ENDIAN_32(dp);
+                                dp++;
                 }
         }
+        }
 
         /* Reset RISC. */
-
         ql_reset_chip(ha);
 
         /* Memory. */
-
         if (rval == QL_SUCCESS) {
                 /* Code RAM. */
                 rval = ql_read_risc_ram(ha, 0x20000,
                     sizeof (fw->code_ram) / 4, fw->code_ram);
         }
         if (rval == QL_SUCCESS) {
                 /* External Memory. */
                 rval = ql_read_risc_ram(ha, 0x100000,
-                    ha->fw_ext_memory_size / 4, fw->ext_mem);
+                    ha->fw_ext_memory_size / 4, dp);
         }
 
         /* Get the FC event trace buffer */
         if (rval == QL_SUCCESS) {
                 if (CFG_IST(ha, CFG_ENABLE_FWFCETRACE) &&

@@ -14482,11 +15560,11 @@
 
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed=%xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
 
         return (rval);
 }
 

@@ -14504,23 +15582,31 @@
  *      Interrupt or Kernel context, no mailbox commands allowed.
  */
 static int
 ql_81xx_binary_fw_dump(ql_adapter_state_t *ha, ql_81xx_fw_dump_t *fw)
 {
-        uint32_t        *reg32;
+        uint32_t        *reg32, cnt, *w32ptr, index, *dp;
         void            *bp;
         clock_t         timer;
         int             rval = QL_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
+        fw->req_q_size[0] = ha->req_q[0]->req_ring.size;
+        if (ha->req_q[1] != NULL) {
+                fw->req_q_size[1] = ha->req_q[1]->req_ring.size;
+        }
+        fw->rsp_q_size = ha->rsp_queues[0]->rsp_ring.size * ha->rsp_queues_cnt;
+
+        fw->hccr = RD32_IO_REG(ha, hccr);
         fw->r2h_status = RD32_IO_REG(ha, risc2host);
+        fw->aer_ues = ql_pci_config_get32(ha, 0x104);
 
         /* Pause RISC. */
         if ((RD32_IO_REG(ha, risc2host) & RH_RISC_PAUSED) == 0) {
                 /* Disable ISP interrupts. */
-                WRT16_IO_REG(ha, ictrl, 0);
+                ql_disable_intr(ha);
 
                 WRT32_IO_REG(ha, hccr, HC24_PAUSE_RISC);
                 for (timer = 30000;
                     (RD32_IO_REG(ha, risc2host) & RH_RISC_PAUSED) == 0 &&
                     rval == QL_SUCCESS; timer--) {

@@ -14543,11 +15629,11 @@
                 /* HostRisc registers. */
                 WRT32_IO_REG(ha, io_base_addr, 0x7000);
                 bp = ql_read_regs(ha, fw->hostrisc_reg, ha->iobase + 0xC0,
                     16, 32);
                 WRT32_IO_REG(ha, io_base_addr, 0x7010);
-                bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+                (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
 
                 /* PCIe registers. */
                 WRT32_IO_REG(ha, io_base_addr, 0x7c00);
                 WRT_REG_DWORD(ha, ha->iobase + 0xc0, 0x1);
                 bp = ql_read_regs(ha, fw->pcie_reg, ha->iobase + 0xC4,

@@ -14558,17 +15644,12 @@
                 /* Host interface registers. */
                 (void) ql_read_regs(ha, fw->host_reg, ha->iobase,
                     sizeof (fw->host_reg) / 4, 32);
 
                 /* Disable ISP interrupts. */
+                ql_disable_intr(ha);
 
-                WRT32_IO_REG(ha, ictrl, 0);
-                RD32_IO_REG(ha, ictrl);
-                ADAPTER_STATE_LOCK(ha);
-                ha->flags &= ~INTERRUPTS_ENABLED;
-                ADAPTER_STATE_UNLOCK(ha);
-
                 /* Shadow registers. */
 
                 WRT32_IO_REG(ha, io_base_addr, 0x0F70);
                 RD32_IO_REG(ha, io_base_addr);
 

@@ -14938,57 +16019,100 @@
                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
                 WRT32_IO_REG(ha, io_base_addr, 0x6F00);
                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
         }
 
-        /* Get the request queue */
         if (rval == QL_SUCCESS) {
-                uint32_t        cnt;
-                uint32_t        *w32 = (uint32_t *)ha->request_ring_bp;
-
-                /* Sync DMA buffer. */
-                (void) ddi_dma_sync(ha->hba_buf.dma_handle,
-                    REQUEST_Q_BUFFER_OFFSET, sizeof (fw->req_q),
-                    DDI_DMA_SYNC_FORKERNEL);
-
-                for (cnt = 0; cnt < sizeof (fw->req_q) / 4; cnt++) {
-                        fw->req_q[cnt] = *w32++;
-                        LITTLE_ENDIAN_32(&fw->req_q[cnt]);
+                /* Get the Queue Pointers */
+                dp = fw->req_rsp_ext_mem;
+                for (index = 0; index < ha->rsp_queues_cnt; index++) {
+                        if (index == 0 && ha->flags & MULTI_QUEUE) {
+                                *dp = RD32_MBAR_REG(ha,
+                                    ha->req_q[0]->mbar_req_in);
+                                LITTLE_ENDIAN_32(dp);
+                                dp++;
+                                *dp = RD32_MBAR_REG(ha,
+                                    ha->req_q[0]->mbar_req_out);
+                                LITTLE_ENDIAN_32(dp);
+                                dp++;
+                        } else if (index == 1 && ha->flags & MULTI_QUEUE) {
+                                *dp = RD32_MBAR_REG(ha,
+                                    ha->req_q[1]->mbar_req_in);
+                                LITTLE_ENDIAN_32(dp);
+                                dp++;
+                                *dp = RD32_MBAR_REG(ha,
+                                    ha->req_q[1]->mbar_req_out);
+                                LITTLE_ENDIAN_32(dp);
+                                dp++;
+                        } else {
+                                *dp++ = 0;
+                                *dp++ = 0;
                 }
+                        if (ha->flags & MULTI_QUEUE) {
+                                *dp = RD32_MBAR_REG(ha,
+                                    ha->rsp_queues[index]->mbar_rsp_in);
+                                LITTLE_ENDIAN_32(dp);
+                                dp++;
+                                *dp = RD32_MBAR_REG(ha,
+                                    ha->rsp_queues[index]->mbar_rsp_out);
+                                LITTLE_ENDIAN_32(dp);
+                                dp++;
+                        } else {
+                                *dp++ = 0;
+                                *dp++ = 0;
         }
+                }
+                /* Get the request queue */
+                (void) ddi_dma_sync(ha->req_q[0]->req_ring.dma_handle, 0, 0,
+                    DDI_DMA_SYNC_FORCPU);
+                w32ptr = (uint32_t *)ha->req_q[0]->req_ring.bp;
+                for (cnt = 0; cnt < fw->req_q_size[0] / 4; cnt++) {
+                        *dp = *w32ptr++;
+                        LITTLE_ENDIAN_32(dp);
+                        dp++;
+                }
+                if (ha->req_q[1] != NULL) {
+                        (void) ddi_dma_sync(ha->req_q[1]->req_ring.dma_handle,
+                            0, 0, DDI_DMA_SYNC_FORCPU);
+                        w32ptr = (uint32_t *)ha->req_q[1]->req_ring.bp;
+                        for (cnt = 0; cnt < fw->req_q_size[1] / 4; cnt++) {
+                                *dp = *w32ptr++;
+                                LITTLE_ENDIAN_32(dp);
+                                dp++;
+                        }
+                }
 
-        /* Get the response queue */
-        if (rval == QL_SUCCESS) {
-                uint32_t        cnt;
-                uint32_t        *w32 = (uint32_t *)ha->response_ring_bp;
-
-                /* Sync DMA buffer. */
-                (void) ddi_dma_sync(ha->hba_buf.dma_handle,
-                    RESPONSE_Q_BUFFER_OFFSET, sizeof (fw->rsp_q),
-                    DDI_DMA_SYNC_FORKERNEL);
-
-                for (cnt = 0; cnt < sizeof (fw->rsp_q) / 4; cnt++) {
-                        fw->rsp_q[cnt] = *w32++;
-                        LITTLE_ENDIAN_32(&fw->rsp_q[cnt]);
+                /* Get the response queues */
+                for (index = 0; index < ha->rsp_queues_cnt; index++) {
+                        (void) ddi_dma_sync(
+                            ha->rsp_queues[index]->rsp_ring.dma_handle,
+                            0, 0, DDI_DMA_SYNC_FORCPU);
+                        w32ptr = (uint32_t *)
+                            ha->rsp_queues[index]->rsp_ring.bp;
+                        for (cnt = 0;
+                            cnt < ha->rsp_queues[index]->rsp_ring.size / 4;
+                            cnt++) {
+                                *dp = *w32ptr++;
+                                LITTLE_ENDIAN_32(dp);
+                                dp++;
                 }
         }
+        }
 
         /* Reset RISC. */
-
         ql_reset_chip(ha);
 
         /* Memory. */
-
         if (rval == QL_SUCCESS) {
                 /* Code RAM. */
                 rval = ql_read_risc_ram(ha, 0x20000,
                     sizeof (fw->code_ram) / 4, fw->code_ram);
         }
         if (rval == QL_SUCCESS) {
                 /* External Memory. */
                 rval = ql_read_risc_ram(ha, 0x100000,
-                    ha->fw_ext_memory_size / 4, fw->ext_mem);
+                    ha->fw_ext_memory_size / 4, dp);
         }
 
         /* Get the FC event trace buffer */
         if (rval == QL_SUCCESS) {
                 if (CFG_IST(ha, CFG_ENABLE_FWFCETRACE) &&

@@ -15025,11 +16149,11 @@
 
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed=%xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
 
         return (rval);
 }
 

@@ -15063,23 +16187,23 @@
 
         for (cnt = 0; cnt < len; cnt++, risc_address++) {
                 WRT16_IO_REG(ha, mailbox_in[0], MBC_READ_RAM_EXTENDED);
                 WRT16_IO_REG(ha, mailbox_in[1], LSW(risc_address));
                 WRT16_IO_REG(ha, mailbox_in[8], MSW(risc_address));
-                if (CFG_IST(ha, CFG_CTRL_8021)) {
+                if (CFG_IST(ha, CFG_CTRL_82XX)) {
                         WRT32_IO_REG(ha, nx_host_int, NX_MBX_CMD);
-                } else if (CFG_IST(ha, CFG_CTRL_242581)) {
+                } else if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
                         WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT);
                 } else {
                         WRT16_IO_REG(ha, hccr, HC_SET_HOST_INT);
                 }
                 for (timer = 6000000; timer && rval == QL_SUCCESS; timer--) {
                         if (INTERRUPT_PENDING(ha)) {
                                 stat = (uint16_t)
                                     (RD16_IO_REG(ha, risc2host) & 0xff);
                                 if ((stat == 1) || (stat == 0x10)) {
-                                        if (CFG_IST(ha, CFG_CTRL_24258081)) {
+                                        if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
                                                 buf32[cnt] = SHORT_TO_LONG(
                                                     RD16_IO_REG(ha,
                                                     mailbox_out[2]),
                                                     RD16_IO_REG(ha,
                                                     mailbox_out[3]));

@@ -15092,33 +16216,36 @@
                                         break;
                                 } else if ((stat == 2) || (stat == 0x11)) {
                                         rval = RD16_IO_REG(ha, mailbox_out[0]);
                                         break;
                                 }
-                                if (CFG_IST(ha, CFG_CTRL_8021)) {
+                                if (CFG_IST(ha, CFG_CTRL_82XX)) {
                                         ql_8021_clr_hw_intr(ha);
                                         ql_8021_clr_fw_intr(ha);
-                                } else if (CFG_IST(ha, CFG_CTRL_242581)) {
+                                } else if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
                                         WRT32_IO_REG(ha, hccr,
                                             HC24_CLR_RISC_INT);
                                         RD32_IO_REG(ha, hccr);
                                 } else {
+                                        WRT16_IO_REG(ha, semaphore, 0);
                                         WRT16_IO_REG(ha, hccr,
                                             HC_CLR_RISC_INT);
+                                        RD16_IO_REG(ha, hccr);
                                 }
                         }
                         drv_usecwait(5);
                 }
-                if (CFG_IST(ha, CFG_CTRL_8021)) {
+                if (CFG_IST(ha, CFG_CTRL_82XX)) {
                         ql_8021_clr_hw_intr(ha);
                         ql_8021_clr_fw_intr(ha);
-                } else if (CFG_IST(ha, CFG_CTRL_242581)) {
+                } else if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
                         WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
                         RD32_IO_REG(ha, hccr);
                 } else {
-                        WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT);
                         WRT16_IO_REG(ha, semaphore, 0);
+                        WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT);
+                        RD16_IO_REG(ha, hccr);
                 }
 
                 if (timer == 0) {
                         rval = QL_FUNCTION_TIMEOUT;
                 }

@@ -15185,21 +16312,21 @@
         ql_config_space_t       chs;
         caddr_t                 prop = "ql-config-space";
 
         ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
         if (ha == NULL) {
-                QL_PRINT_2(CE_CONT, "(%d): no adapter\n",
+                QL_PRINT_2(NULL, "no adapter instance=%d\n",
                     ddi_get_instance(dip));
                 return (DDI_FAILURE);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
         if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, prop) ==
             1) {
-                QL_PRINT_2(CE_CONT, "(%d): no prop exit\n", ha->instance);
+                QL_PRINT_2(ha, "no prop exit\n");
                 return (DDI_SUCCESS);
         }
 
         chs.chs_command = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_COMM);
         chs.chs_header_type = (uint8_t)ql_pci_config_get8(ha,

@@ -15235,11 +16362,11 @@
                 cmn_err(CE_WARN, "!Qlogic %s(%d) can't update prop %s",
                     QL_NAME, ddi_get_instance(dip), prop);
                 return (DDI_FAILURE);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (DDI_SUCCESS);
 }
 
 static int

@@ -15250,22 +16377,22 @@
         ql_config_space_t       *chs_p;
         caddr_t                 prop = "ql-config-space";
 
         ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
         if (ha == NULL) {
-                QL_PRINT_2(CE_CONT, "(%d): no adapter\n",
+                QL_PRINT_2(NULL, "no adapter instance=%d\n",
                     ddi_get_instance(dip));
                 return (DDI_FAILURE);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
         if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip,
             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, prop,
             (uchar_t **)&chs_p, &elements) != DDI_PROP_SUCCESS) {
-                QL_PRINT_2(CE_CONT, "(%d): no prop exit\n", ha->instance);
+                QL_PRINT_2(ha, "no prop exit\n");
                 return (DDI_FAILURE);
         }
 
         ql_pci_config_put16(ha, PCI_CONF_COMM, chs_p->chs_command);
 

@@ -15298,11 +16425,11 @@
         if (ndi_prop_remove(DDI_DEV_T_NONE, dip, prop) != DDI_PROP_SUCCESS) {
                 cmn_err(CE_WARN, "!Qlogic %s(%d): can't remove prop %s",
                     QL_NAME, ddi_get_instance(dip), prop);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (DDI_SUCCESS);
 }
 
 uint8_t

@@ -15409,17 +16536,18 @@
  *      Kernel context.
  */
 static void
 ql_halt(ql_adapter_state_t *ha, int pwr)
 {
-        uint32_t        cnt;
+        ql_link_t       *link;
+        ql_response_q_t *rsp_q;
         ql_tgt_t        *tq;
         ql_srb_t        *sp;
+        uint32_t        cnt, i;
         uint16_t        index;
-        ql_link_t       *link;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         /* Wait for all commands running to finish. */
         for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
                 for (link = ha->dev[index].first; link != NULL;
                     link = link->next) {

@@ -15440,31 +16568,37 @@
                                         ql_delay(ha, 10000);
                                 }
                         }
 
                         /* Finish any commands waiting for more status. */
-                        if (ha->status_srb != NULL) {
-                                sp = ha->status_srb;
-                                ha->status_srb = NULL;
+                        for (i = 0; i < ha->rsp_queues_cnt; i++) {
+                                if ((rsp_q = ha->rsp_queues[i]) != NULL &&
+                                    (sp = rsp_q->status_srb) != NULL) {
+                                        rsp_q->status_srb = NULL;
                                 sp->cmd.next = NULL;
-                                ql_done(&sp->cmd);
+                                        ql_done(&sp->cmd, B_FALSE);
                         }
+                        }
 
                         /* Abort commands that did not finish. */
                         if (cnt == 0) {
-                                for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS;
+                                for (cnt = 1; cnt < ha->osc_max_cnt;
                                     cnt++) {
                                         if (ha->pending_cmds.first != NULL) {
                                                 ql_start_iocb(ha, NULL);
                                                 cnt = 1;
                                         }
                                         sp = ha->outstanding_cmds[cnt];
                                         if (sp != NULL &&
+                                            sp != QL_ABORTED_SRB(ha) &&
                                             sp->lun_queue->target_queue ==
                                             tq) {
-                                                (void) ql_abort((opaque_t)ha,
-                                                    sp->pkt, 0);
+                                                (void) ql_abort_io(ha, sp);
+                                                sp->pkt->pkt_reason =
+                                                    CS_ABORTED;
+                                                sp->cmd.next = NULL;
+                                                ql_done(&sp->cmd, B_FALSE);
                                         }
                                 }
                         }
                 }
         }

@@ -15479,20 +16613,24 @@
         ha->port_retry_timer = 0;
         ha->loop_down_timer = LOOP_DOWN_TIMER_OFF;
         ha->watchdog_timer = 0;
         ADAPTER_STATE_UNLOCK(ha);
 
-        if (pwr == PM_LEVEL_D3) {
+        if (pwr == PM_LEVEL_D3 && ha->flags & ONLINE) {
                 ADAPTER_STATE_LOCK(ha);
                 ha->flags &= ~ONLINE;
                 ADAPTER_STATE_UNLOCK(ha);
 
+                if (CFG_IST(ha, CFG_CTRL_82XX)) {
+                        ql_8021_clr_drv_active(ha);
+                }
+
                 /* Reset ISP chip. */
                 ql_reset_chip(ha);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_get_dma_mem
  *      Function used to allocate dma memory.

@@ -15512,15 +16650,15 @@
 ql_get_dma_mem(ql_adapter_state_t *ha, dma_mem_t *mem, uint32_t size,
     mem_alloc_type_t allocation_type, mem_alignment_t alignment)
 {
         int     rval;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         mem->size = size;
         mem->type = allocation_type;
-        mem->cookie_count = 1;
+        mem->max_cookie_count = 1;
 
         switch (alignment) {
         case QL_DMA_DATA_ALIGN:
                 mem->alignment = QL_DMA_ALIGN_8_BYTE_BOUNDARY;
                 break;

@@ -15535,16 +16673,38 @@
         if ((rval = ql_alloc_phys(ha, mem, KM_SLEEP)) != QL_SUCCESS) {
                 ql_free_phys(ha, mem);
                 EL(ha, "failed, alloc_phys=%xh\n", rval);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (rval);
 }
 
 /*
+ * ql_free_dma_resource
+ *      Function used to free dma memory.
+ *
+ * Input:
+ *      ha:             adapter state pointer.
+ *      mem:            pointer to dma memory object.
+ *      mem->dma_handle DMA memory handle.
+ *
+ * Context:
+ *      Kernel context.
+ */
+void
+ql_free_dma_resource(ql_adapter_state_t *ha, dma_mem_t *mem)
+{
+        QL_PRINT_3(ha, "started\n");
+
+        ql_free_phys(ha, mem);
+
+        QL_PRINT_3(ha, "done\n");
+}
+
+/*
  * ql_alloc_phys
  *      Function used to allocate memory and zero it.
  *      Memory is below 4 GB.
  *
  * Input:

@@ -15555,29 +16715,26 @@
  *      mem->type               memory allocation type.
  *      mem->size               memory size.
  *      mem->alignment          memory alignment.
  *
  * Returns:
- *      qn local function return status code.
+ *      ql local function return status code.
  *
  * Context:
  *      Kernel context.
  */
 int
 ql_alloc_phys(ql_adapter_state_t *ha, dma_mem_t *mem, int sleep)
 {
         size_t                  rlen;
-        ddi_dma_attr_t          dma_attr;
+        ddi_dma_attr_t          dma_attr = ha->io_dma_attr;
         ddi_device_acc_attr_t   acc_attr = ql_dev_acc_attr;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
-        dma_attr = CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING) ?
-            ql_64bit_io_dma_attr : ql_32bit_io_dma_attr;
-
         dma_attr.dma_attr_align = mem->alignment; /* DMA address alignment */
-        dma_attr.dma_attr_sgllen = (int)mem->cookie_count;
+        dma_attr.dma_attr_sgllen = (int)mem->max_cookie_count;
 
         /*
          * Workaround for SUN XMITS buffer must end and start on 8 byte
          * boundary. Else, hardware will overrun the buffer. Simple fix is
          * to make sure buffer has enough room for overrun.

@@ -15645,17 +16802,26 @@
                 return (QL_MEMORY_ALLOC_FAILED);
         }
 
         mem->flags |= DDI_DMA_RDWR;
 
+        if (qlc_fm_check_dma_handle(ha, mem->dma_handle)
+            != DDI_FM_OK) {
+                EL(ha, "failed, ddi_dma_addr_bind_handle\n");
+                ql_free_phys(ha, mem);
+                qlc_fm_report_err_impact(ha,
+                    QL_FM_EREPORT_DMA_HANDLE_CHECK);
+                return (QL_MEMORY_ALLOC_FAILED);
+        }
+
         if (ql_bind_dma_buffer(ha, mem, sleep) != DDI_DMA_MAPPED) {
                 EL(ha, "failed, ddi_dma_addr_bind_handle\n");
                 ql_free_phys(ha, mem);
                 return (QL_MEMORY_ALLOC_FAILED);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (QL_SUCCESS);
 }
 
 /*

@@ -15670,126 +16836,55 @@
  *      Kernel context.
  */
 void
 ql_free_phys(ql_adapter_state_t *ha, dma_mem_t *mem)
 {
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
-        if (mem != NULL && mem->dma_handle != NULL) {
+        if (mem != NULL) {
+                if (mem->memflags == DDI_DMA_MAPPED) {
                 ql_unbind_dma_buffer(ha, mem);
+                }
+
                 switch (mem->type) {
                 case KERNEL_MEM:
                         if (mem->bp != NULL) {
                                 kmem_free(mem->bp, mem->size);
+                                mem->bp = NULL;
                         }
                         break;
                 case LITTLE_ENDIAN_DMA:
                 case BIG_ENDIAN_DMA:
                 case NO_SWAP_DMA:
                         if (mem->acc_handle != NULL) {
                                 ddi_dma_mem_free(&mem->acc_handle);
                                 mem->acc_handle = NULL;
+                                mem->bp = NULL;
                         }
                         break;
                 default:
                         break;
                 }
-                mem->bp = NULL;
+                if (mem->dma_handle != NULL) {
                 ddi_dma_free_handle(&mem->dma_handle);
                 mem->dma_handle = NULL;
         }
-
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
-}
-
-/*
- * ql_alloc_dma_resouce.
- *      Allocates DMA resource for buffer.
- *
- * Input:
- *      ha:                     adapter state pointer.
- *      mem:                    pointer to dma memory object.
- *      sleep:                  KM_SLEEP/KM_NOSLEEP flag.
- *      mem->cookie_count       number of segments allowed.
- *      mem->type               memory allocation type.
- *      mem->size               memory size.
- *      mem->bp                 pointer to memory or struct buf
- *
- * Returns:
- *      qn local function return status code.
- *
- * Context:
- *      Kernel context.
- */
-int
-ql_alloc_dma_resouce(ql_adapter_state_t *ha, dma_mem_t *mem, int sleep)
-{
-        ddi_dma_attr_t  dma_attr;
-
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
-
-        dma_attr = CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING) ?
-            ql_64bit_io_dma_attr : ql_32bit_io_dma_attr;
-        dma_attr.dma_attr_sgllen = (int)mem->cookie_count;
-
-        /*
-         * Allocate DMA handle for command.
-         */
-        if (ddi_dma_alloc_handle(ha->dip, &dma_attr, (sleep == KM_SLEEP) ?
-            DDI_DMA_SLEEP : DDI_DMA_DONTWAIT, NULL, &mem->dma_handle) !=
-            DDI_SUCCESS) {
-                EL(ha, "failed, ddi_dma_alloc_handle\n");
-                mem->dma_handle = NULL;
-                return (QL_MEMORY_ALLOC_FAILED);
         }
 
-        mem->flags = DDI_DMA_RDWR | DDI_DMA_CONSISTENT;
-
-        if (ql_bind_dma_buffer(ha, mem, sleep) != DDI_DMA_MAPPED) {
-                EL(ha, "failed, bind_dma_buffer\n");
-                ddi_dma_free_handle(&mem->dma_handle);
-                mem->dma_handle = NULL;
-                return (QL_MEMORY_ALLOC_FAILED);
-        }
-
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
-
-        return (QL_SUCCESS);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
- * ql_free_dma_resource
- *      Frees DMA resources.
- *
- * Input:
- *      ha:             adapter state pointer.
- *      mem:            pointer to dma memory object.
- *      mem->dma_handle DMA memory handle.
- *
- * Context:
- *      Kernel context.
- */
-void
-ql_free_dma_resource(ql_adapter_state_t *ha, dma_mem_t *mem)
-{
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
-
-        ql_free_phys(ha, mem);
-
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
-}
-
-/*
  * ql_bind_dma_buffer
  *      Binds DMA buffer.
  *
  * Input:
  *      ha:                     adapter state pointer.
  *      mem:                    pointer to dma memory object.
- *      sleep:                  KM_SLEEP or KM_NOSLEEP.
+ *      kmflags:                KM_SLEEP or KM_NOSLEEP.
  *      mem->dma_handle         DMA memory handle.
- *      mem->cookie_count       number of segments allowed.
+ *      mem->max_cookie_count   number of segments allowed.
  *      mem->type               memory allocation type.
  *      mem->size               memory size.
  *      mem->bp                 pointer to memory or struct buf
  *
  * Returns:

@@ -15802,40 +16897,33 @@
  *
  * Context:
  *      Kernel context.
  */
 static int
-ql_bind_dma_buffer(ql_adapter_state_t *ha, dma_mem_t *mem, int sleep)
+ql_bind_dma_buffer(ql_adapter_state_t *ha, dma_mem_t *mem, int kmflags)
 {
-        int                     rval;
         ddi_dma_cookie_t        *cookiep;
-        uint32_t                cnt = mem->cookie_count;
+        uint32_t                cnt;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
-        if (mem->type == STRUCT_BUF_MEMORY) {
-                rval = ddi_dma_buf_bind_handle(mem->dma_handle, mem->bp,
-                    mem->flags, (sleep == KM_SLEEP) ? DDI_DMA_SLEEP :
-                    DDI_DMA_DONTWAIT, NULL, &mem->cookie, &mem->cookie_count);
-        } else {
-                rval = ddi_dma_addr_bind_handle(mem->dma_handle, NULL, mem->bp,
-                    mem->size, mem->flags, (sleep == KM_SLEEP) ?
+        mem->memflags = ddi_dma_addr_bind_handle(mem->dma_handle, NULL,
+            mem->bp, mem->size, mem->flags, (kmflags == KM_SLEEP) ?
                     DDI_DMA_SLEEP : DDI_DMA_DONTWAIT, NULL, &mem->cookie,
                     &mem->cookie_count);
-        }
 
-        if (rval == DDI_DMA_MAPPED) {
-                if (mem->cookie_count > cnt) {
+        if (mem->memflags == DDI_DMA_MAPPED) {
+                if (mem->cookie_count > mem->max_cookie_count) {
                         (void) ddi_dma_unbind_handle(mem->dma_handle);
                         EL(ha, "failed, cookie_count %d > %d\n",
-                            mem->cookie_count, cnt);
-                        rval = DDI_DMA_TOOBIG;
+                            mem->cookie_count, mem->max_cookie_count);
+                        mem->memflags = (uint32_t)DDI_DMA_TOOBIG;
                 } else {
                         if (mem->cookie_count > 1) {
                                 if (mem->cookies = kmem_zalloc(
                                     sizeof (ddi_dma_cookie_t) *
-                                    mem->cookie_count, sleep)) {
+                                    mem->cookie_count, kmflags)) {
                                         *mem->cookies = mem->cookie;
                                         cookiep = mem->cookies;
                                         for (cnt = 1; cnt < mem->cookie_count;
                                             cnt++) {
                                                 ddi_dma_nextcookie(

@@ -15844,11 +16932,12 @@
                                         }
                                 } else {
                                         (void) ddi_dma_unbind_handle(
                                             mem->dma_handle);
                                         EL(ha, "failed, kmem_zalloc\n");
-                                        rval = DDI_DMA_NORESOURCES;
+                                        mem->memflags = (uint32_t)
+                                            DDI_DMA_NORESOURCES;
                                 }
                         } else {
                                 /*
                                  * It has been reported that dmac_size at times
                                  * may be incorrect on sparc machines so for

@@ -15859,18 +16948,18 @@
                                 mem->cookies->dmac_size = mem->size;
                         }
                 }
         }
 
-        if (rval != DDI_DMA_MAPPED) {
-                EL(ha, "failed=%xh\n", rval);
+        if (mem->memflags != DDI_DMA_MAPPED) {
+                EL(ha, "failed=%xh\n", mem->memflags);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
 
-        return (rval);
+        return (mem->memflags);
 }
 
 /*
  * ql_unbind_dma_buffer
  *      Unbinds DMA buffer.

@@ -15887,31 +16976,43 @@
  */
 /* ARGSUSED */
 static void
 ql_unbind_dma_buffer(ql_adapter_state_t *ha, dma_mem_t *mem)
 {
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
+        if (mem->dma_handle != NULL && mem->memflags == DDI_DMA_MAPPED) {
         (void) ddi_dma_unbind_handle(mem->dma_handle);
+        }
         if (mem->cookie_count > 1) {
                 kmem_free(mem->cookies, sizeof (ddi_dma_cookie_t) *
                     mem->cookie_count);
                 mem->cookies = NULL;
         }
         mem->cookie_count = 0;
+        mem->memflags = (uint32_t)DDI_DMA_NORESOURCES;
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 static int
 ql_suspend_adapter(ql_adapter_state_t *ha)
 {
-        clock_t timer = 32 * drv_usectohz(1000000);
+        clock_t timer = (clock_t)(32 * drv_usectohz(1000000));
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
+        (void) ql_wait_outstanding(ha);
+
         /*
+         * here we are sure that there will not be any mbox interrupt.
+         * So, let's make sure that we return back all the outstanding
+         * cmds as well as internally queued commands.
+         */
+        ql_halt(ha, PM_LEVEL_D0);
+
+        /*
          * First we will claim mbox ownership so that no
          * thread using mbox hangs when we disable the
          * interrupt in the middle of it.
          */
         MBX_REGISTER_LOCK(ha);

@@ -15934,28 +17035,15 @@
 
         /* Set busy flag. */
         ha->mailbox_flags = (uint8_t)(ha->mailbox_flags | MBX_BUSY_FLG);
         MBX_REGISTER_UNLOCK(ha);
 
-        (void) ql_wait_outstanding(ha);
-
-        /*
-         * here we are sure that there will not be any mbox interrupt.
-         * So, let's make sure that we return back all the outstanding
-         * cmds as well as internally queued commands.
-         */
-        ql_halt(ha, PM_LEVEL_D0);
-
         if (ha->power_level != PM_LEVEL_D3) {
                 /* Disable ISP interrupts. */
-                WRT16_IO_REG(ha, ictrl, 0);
+                ql_disable_intr(ha);
         }
 
-        ADAPTER_STATE_LOCK(ha);
-        ha->flags &= ~INTERRUPTS_ENABLED;
-        ADAPTER_STATE_UNLOCK(ha);
-
         MBX_REGISTER_LOCK(ha);
         /* Reset busy status. */
         ha->mailbox_flags = (uint8_t)(ha->mailbox_flags & ~MBX_BUSY_FLG);
 
         /* If thread is waiting for mailbox go signal it to start. */

@@ -15965,11 +17053,11 @@
                 cv_broadcast(&ha->cv_mbx_wait);
         }
         /* Release mailbox register lock. */
         MBX_REGISTER_UNLOCK(ha);
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (QL_SUCCESS);
 }
 
 /*

@@ -15985,10 +17073,14 @@
  *      Interrupt or Kernel context, no mailbox commands allowed.
  */
 void
 ql_add_link_b(ql_head_t *head, ql_link_t *link)
 {
+        if (link->head != NULL) {
+                EL(NULL, "link in use by list=%ph\n", link->head);
+        }
+
         /* at the end there isn't a next */
         link->next = NULL;
 
         if ((link->prev = head->last) == NULL) {
                 head->first = link;

@@ -16013,10 +17105,13 @@
  *      Interrupt or Kernel context, no mailbox commands allowed.
  */
 void
 ql_add_link_t(ql_head_t *head, ql_link_t *link)
 {
+        if (link->head != NULL) {
+                EL(NULL, "link in use by list=%ph\n", link->head);
+        }
         link->prev = NULL;
 
         if ((link->next = head->first) == NULL) {
                 head->last = link;
         } else {

@@ -16032,18 +17127,19 @@
  *      Remove a link from the chain.
  *
  * Input:
  *      head = Head of link list.
  *      link = link to be removed.
- *      LOCK must be already obtained.
+ *      associated proper LOCK must be already obtained.
  *
  * Context:
  *      Interrupt or Kernel context, no mailbox commands allowed.
  */
 void
 ql_remove_link(ql_head_t *head, ql_link_t *link)
 {
+        if (head != NULL) {
         if (link->prev != NULL) {
                 if ((link->prev->next = link->next) == NULL) {
                         head->last = link->prev;
                 } else {
                         link->next->prev = link->prev;

@@ -16055,10 +17151,11 @@
         }
 
         /* not on a queue any more */
         link->prev = link->next = NULL;
         link->head = NULL;
+        }
 }
 
 /*
  * ql_chg_endian
  *      Change endianess of byte array.

@@ -16143,11 +17240,12 @@
  *      Kernel or Interrupt context, no mailbox commands allowed.
  */
 void
 ql_delay(ql_adapter_state_t *ha, clock_t usecs)
 {
-        if (QL_DAEMON_SUSPENDED(ha) || ddi_in_panic()) {
+        if (ha->flags & ADAPTER_SUSPENDED || ddi_in_panic() ||
+            curthread->t_flag & T_INTR_THREAD) {
                 drv_usecwait(usecs);
         } else {
                 delay(drv_usectohz(usecs));
         }
 }

@@ -16169,31 +17267,43 @@
  */
 int
 ql_stall_driver(ql_adapter_state_t *ha, uint32_t options)
 {
         ql_link_t               *link;
-        ql_adapter_state_t      *ha2;
+        ql_adapter_state_t      *ha2 = NULL;
         uint32_t                timer;
 
-        QL_PRINT_3(CE_CONT, "started\n");
+        QL_PRINT_3(ha, "started\n");
 
-        /* Wait for 30 seconds for daemons unstall. */
-        timer = 3000;
+        /* Tell all daemons to stall. */
         link = ha == NULL ? ql_hba.first : &ha->hba;
-        while (link != NULL && timer) {
+        while (link != NULL) {
                 ha2 = link->base_address;
 
                 ql_awaken_task_daemon(ha2, NULL, DRIVER_STALL, 0);
 
+                link = ha == NULL ? link->next : NULL;
+        }
+
+        /* Wait for 30 seconds for daemons stall. */
+        timer = 3000;
+        link = ha == NULL ? ql_hba.first : &ha->hba;
+        while (link != NULL && timer) {
+                ha2 = link->base_address;
+
                 if ((ha2->task_daemon_flags & TASK_DAEMON_ALIVE_FLG) == 0 ||
                     (ha2->task_daemon_flags & TASK_DAEMON_STOP_FLG) != 0 ||
+                    (ha2->task_daemon_flags & FIRMWARE_UP) == 0 ||
                     (ha2->task_daemon_flags & TASK_DAEMON_STALLED_FLG &&
-                    ql_wait_outstanding(ha2) == MAX_OUTSTANDING_COMMANDS)) {
+                    ql_wait_outstanding(ha2) == ha2->pha->osc_max_cnt)) {
                         link = ha == NULL ? link->next : NULL;
                         continue;
                 }
 
+                QL_PRINT_2(ha2, "status, dtf=%xh, stf=%xh\n",
+                    ha2->task_daemon_flags, ha2->flags);
+
                 ql_delay(ha2, 10000);
                 timer--;
                 link = ha == NULL ? ql_hba.first : &ha->hba;
         }
 

@@ -16205,11 +17315,11 @@
                         ql_awaken_task_daemon(ha2, NULL, 0, DRIVER_STALL);
                 }
                 return (QL_FUNCTION_TIMEOUT);
         }
 
-        QL_PRINT_3(CE_CONT, "done\n");
+        QL_PRINT_3(ha, "done\n");
 
         return (QL_SUCCESS);
 }
 
 /*

@@ -16227,11 +17337,11 @@
 {
         ql_link_t               *link;
         ql_adapter_state_t      *ha2;
         uint32_t                timer;
 
-        QL_PRINT_3(CE_CONT, "started\n");
+        QL_PRINT_3(ha, "started\n");
 
         /* Tell all daemons to unstall. */
         link = ha == NULL ? ql_hba.first : &ha->hba;
         while (link != NULL) {
                 ha2 = link->base_address;

@@ -16248,26 +17358,24 @@
                 ha2 = link->base_address;
 
                 if ((ha2->task_daemon_flags & TASK_DAEMON_ALIVE_FLG) == 0 ||
                     (ha2->task_daemon_flags & TASK_DAEMON_STOP_FLG) != 0 ||
                     (ha2->task_daemon_flags & TASK_DAEMON_STALLED_FLG) == 0) {
-                        QL_PRINT_2(CE_CONT, "(%d,%d): restarted\n",
-                            ha2->instance, ha2->vp_index);
+                        QL_PRINT_2(ha2, "restarted\n");
                         ql_restart_queues(ha2);
                         link = ha == NULL ? link->next : NULL;
                         continue;
                 }
 
-                QL_PRINT_2(CE_CONT, "(%d,%d): failed, tdf=%xh\n",
-                    ha2->instance, ha2->vp_index, ha2->task_daemon_flags);
+                QL_PRINT_2(ha2, "status, tdf=%xh\n", ha2->task_daemon_flags);
 
                 ql_delay(ha2, 10000);
                 timer--;
                 link = ha == NULL ? ql_hba.first : &ha->hba;
         }
 
-        QL_PRINT_3(CE_CONT, "done\n");
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_setup_interrupts
  *      Sets up interrupts based on the HBA's and platform's

@@ -16287,11 +17395,11 @@
 {
         int32_t         rval = DDI_FAILURE;
         int32_t         i;
         int32_t         itypes = 0;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         /*
          * The Solaris Advanced Interrupt Functions (aif) are only
          * supported on s10U1 or greater.
          */

@@ -16334,13 +17442,17 @@
         }
 
         if (rval != DDI_SUCCESS) {
                 EL(ha, "failed, aif, rval=%xh\n", rval);
         } else {
-                /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n");
+                /* Setup mutexes */
+                if ((rval = ql_init_mutex(ha)) != DDI_SUCCESS) {
+                        EL(ha, "failed, mutex init ret=%xh\n", rval);
+                        ql_release_intr(ha);
         }
+                QL_PRINT_3(ha, "done\n");
+        }
 
         return (rval);
 }
 
 /*

@@ -16357,26 +17469,26 @@
  *      Kernel context.
  */
 static int
 ql_setup_msi(ql_adapter_state_t *ha)
 {
+        uint_t          i;
         int32_t         count = 0;
         int32_t         avail = 0;
         int32_t         actual = 0;
         int32_t         msitype = DDI_INTR_TYPE_MSI;
         int32_t         ret;
-        ql_ifunc_t      itrfun[10] = {0};
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         if (ql_disable_msi != 0) {
                 EL(ha, "MSI is disabled by user\n");
                 return (DDI_FAILURE);
         }
 
         /* MSI support is only suported on 24xx HBA's. */
-        if (!(CFG_IST(ha, CFG_CTRL_24258081))) {
+        if (!CFG_IST(ha, CFG_MSI_SUPPORT)) {
                 EL(ha, "HBA does not support MSI\n");
                 return (DDI_FAILURE);
         }
 
         /* Get number of MSI interrupts the system supports */

@@ -16393,11 +17505,10 @@
                 return (DDI_FAILURE);
         }
 
         /* MSI requires only 1.  */
         count = 1;
-        itrfun[0].ifunc = &ql_isr_aif;
 
         /* Allocate space for interrupt handles */
         ha->hsize = ((uint32_t)(sizeof (ddi_intr_handle_t)) * count);
         ha->htable = kmem_zalloc(ha->hsize, KM_SLEEP);
 

@@ -16409,58 +17520,51 @@
                 EL(ha, "failed, intr_alloc ret=%xh, count = %xh, "
                     "actual=%xh\n", ret, count, actual);
                 ql_release_intr(ha);
                 return (DDI_FAILURE);
         }
-
         ha->intr_cnt = actual;
 
         /* Get interrupt priority */
-        if ((ret = ddi_intr_get_pri(ha->htable[0], &ha->intr_pri)) !=
-            DDI_SUCCESS) {
+        if ((ret = ddi_intr_get_pri(ha->htable[0], &i)) != DDI_SUCCESS) {
                 EL(ha, "failed, get_pri ret=%xh\n", ret);
                 ql_release_intr(ha);
                 return (ret);
         }
+        ha->intr_pri = DDI_INTR_PRI(i);
 
         /* Add the interrupt handler */
-        if ((ret = ddi_intr_add_handler(ha->htable[0], itrfun[0].ifunc,
+        if ((ret = ddi_intr_add_handler(ha->htable[0], ql_isr_aif,
             (caddr_t)ha, (caddr_t)0)) != DDI_SUCCESS) {
                 EL(ha, "failed, intr_add ret=%xh\n", ret);
                 ql_release_intr(ha);
                 return (ret);
         }
 
-        /* Setup mutexes */
-        if ((ret = ql_init_mutex(ha)) != DDI_SUCCESS) {
-                EL(ha, "failed, mutex init ret=%xh\n", ret);
-                ql_release_intr(ha);
-                return (ret);
-        }
-
         /* Get the capabilities */
         (void) ddi_intr_get_cap(ha->htable[0], &ha->intr_cap);
 
         /* Enable interrupts */
         if (ha->intr_cap & DDI_INTR_FLAG_BLOCK) {
                 if ((ret = ddi_intr_block_enable(ha->htable, ha->intr_cnt)) !=
                     DDI_SUCCESS) {
                         EL(ha, "failed, block enable, ret=%xh\n", ret);
-                        ql_destroy_mutex(ha);
                         ql_release_intr(ha);
                         return (ret);
                 }
         } else {
-                if ((ret = ddi_intr_enable(ha->htable[0])) != DDI_SUCCESS) {
+                for (i = 0; i < actual; i++) {
+                        if ((ret = ddi_intr_enable(ha->htable[i])) !=
+                            DDI_SUCCESS) {
                         EL(ha, "failed, intr enable, ret=%xh\n", ret);
-                        ql_destroy_mutex(ha);
                         ql_release_intr(ha);
                         return (ret);
                 }
         }
+        }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (DDI_SUCCESS);
 }
 
 /*

@@ -16477,114 +17581,106 @@
  *      Kernel context.
  */
 static int
 ql_setup_msix(ql_adapter_state_t *ha)
 {
-        uint16_t        hwvect;
+        int             hwvect;
         int32_t         count = 0;
         int32_t         avail = 0;
         int32_t         actual = 0;
         int32_t         msitype = DDI_INTR_TYPE_MSIX;
         int32_t         ret;
-        uint32_t        i;
-        ql_ifunc_t      itrfun[QL_MSIX_MAXAIF] = {0};
+        uint_t          i;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         if (ql_disable_msix != 0) {
                 EL(ha, "MSI-X is disabled by user\n");
                 return (DDI_FAILURE);
         }
 
+#ifdef __x86
+        if (get_hwenv() == HW_VMWARE) {
+                EL(ha, "running under hypervisor, disabling MSI-X\n");
+                return (DDI_FAILURE);
+        }
+#endif
+
         /*
          * MSI-X support is only available on 24xx HBA's that have
          * rev A2 parts (revid = 3) or greater.
          */
-        if (!((ha->device_id == 0x2532) || (ha->device_id == 0x2432) ||
-            (ha->device_id == 0x8432) || (ha->device_id == 0x8001) ||
-            (ha->device_id == 0x8021))) {
+        if (CFG_IST(ha, CFG_ISP_FW_TYPE_1) ||
+            (CFG_IST(ha, CFG_CTRL_24XX) && ha->rev_id < 3)) {
                 EL(ha, "HBA does not support MSI-X\n");
                 return (DDI_FAILURE);
         }
 
-        if (CFG_IST(ha, CFG_CTRL_2422) && (ha->rev_id < 3)) {
-                EL(ha, "HBA does not support MSI-X (revid)\n");
-                return (DDI_FAILURE);
-        }
-
         /* Per HP, these HP branded HBA's are not supported with MSI-X */
         if (ha->ven_id == 0x103C && (ha->subsys_id == 0x7041 ||
             ha->subsys_id == 0x7040 || ha->subsys_id == 0x1705)) {
                 EL(ha, "HBA does not support MSI-X (subdevid)\n");
                 return (DDI_FAILURE);
         }
 
-        /* Get the number of 24xx/25xx MSI-X h/w vectors */
-        hwvect = (uint16_t)(((CFG_IST(ha, CFG_CTRL_2422) ?
-            ql_pci_config_get16(ha, 0x7e) :
-            ql_pci_config_get16(ha, 0xa2)) & 0x3ff) + 1);
-
-        EL(ha, "pcie config space hwvect = %d\n", hwvect);
-
-        if (hwvect < QL_MSIX_MAXAIF) {
-                EL(ha, "failed, min h/w vectors req'd: %d, avail: %d\n",
-                    QL_MSIX_MAXAIF, hwvect);
-                return (DDI_FAILURE);
-        }
-
         /* Get number of MSI-X interrupts the platform h/w supports */
-        if (((ret = ddi_intr_get_nintrs(ha->dip, msitype, &count)) !=
-            DDI_SUCCESS) || count == 0) {
-                EL(ha, "failed, nintrs ret=%xh, cnt=%xh\n", ret, count);
+        if (((ret = ddi_intr_get_nintrs(ha->dip, msitype, &hwvect)) !=
+            DDI_SUCCESS) || hwvect == 0) {
+                EL(ha, "failed, nintrs ret=%xh, cnt=%xh\n", ret, hwvect);
                 return (DDI_FAILURE);
         }
+        QL_PRINT_10(ha, "ddi_intr_get_nintrs, hwvect=%d\n", hwvect);
 
         /* Get number of available system interrupts */
         if (((ret = ddi_intr_get_navail(ha->dip, msitype, &avail)) !=
             DDI_SUCCESS) || avail == 0) {
                 EL(ha, "failed, navail ret=%xh, avail=%xh\n", ret, avail);
                 return (DDI_FAILURE);
         }
+        QL_PRINT_10(ha, "ddi_intr_get_navail, avail=%d\n", avail);
 
         /* Fill out the intr table */
-        count = QL_MSIX_MAXAIF;
-        itrfun[QL_MSIX_AIF].ifunc = &ql_isr_aif;
-        itrfun[QL_MSIX_RSPQ].ifunc = &ql_isr_aif;
+        count = ha->interrupt_count;
+        if (ha->flags & MULTI_QUEUE && count < ha->mq_msix_vectors) {
+                count = ha->mq_msix_vectors;
+                /* don't exceed the h/w capability */
+                if (count > hwvect) {
+                        count = hwvect;
+                }
+        }
 
         /* Allocate space for interrupt handles */
         ha->hsize = ((uint32_t)(sizeof (ddi_intr_handle_t)) * hwvect);
-        if ((ha->htable = kmem_zalloc(ha->hsize, KM_SLEEP)) == NULL) {
-                ha->hsize = 0;
-                EL(ha, "failed, unable to allocate htable space\n");
-                return (DDI_FAILURE);
-        }
+        ha->htable = kmem_zalloc(ha->hsize, KM_SLEEP);
 
         ha->iflags |= IFLG_INTR_MSIX;
 
         /* Allocate the interrupts */
         if (((ret = ddi_intr_alloc(ha->dip, ha->htable, msitype,
             DDI_INTR_ALLOC_NORMAL, count, &actual, 0)) != DDI_SUCCESS) ||
-            actual < QL_MSIX_MAXAIF) {
+            actual < ha->interrupt_count) {
                 EL(ha, "failed, intr_alloc ret=%xh, count = %xh, "
                     "actual=%xh\n", ret, count, actual);
                 ql_release_intr(ha);
                 return (DDI_FAILURE);
         }
-
         ha->intr_cnt = actual;
+        EL(ha, "min=%d, multi-q=%d, req=%d, rcv=%d\n",
+            ha->interrupt_count, ha->mq_msix_vectors, count,
+            ha->intr_cnt);
 
         /* Get interrupt priority */
-        if ((ret = ddi_intr_get_pri(ha->htable[0], &ha->intr_pri)) !=
-            DDI_SUCCESS) {
+        if ((ret = ddi_intr_get_pri(ha->htable[0], &i)) != DDI_SUCCESS) {
                 EL(ha, "failed, get_pri ret=%xh\n", ret);
                 ql_release_intr(ha);
                 return (ret);
         }
+        ha->intr_pri = DDI_INTR_PRI(i);
 
         /* Add the interrupt handlers */
         for (i = 0; i < actual; i++) {
-                if ((ret = ddi_intr_add_handler(ha->htable[i], itrfun[i].ifunc,
+                if ((ret = ddi_intr_add_handler(ha->htable[i], ql_isr_aif,
                     (void *)ha, (void *)((ulong_t)i))) != DDI_SUCCESS) {
                         EL(ha, "failed, addh#=%xh, act=%xh, ret=%xh\n", i,
                             actual, ret);
                         ql_release_intr(ha);
                         return (ret);

@@ -16602,45 +17698,43 @@
                         EL(ha, "failed, intr_dup#=%xh, act=%xh, ret=%xh\n",
                             i, actual, ret);
                         ql_release_intr(ha);
                         return (ret);
                 }
-        }
-#endif
-
-        /* Setup mutexes */
-        if ((ret = ql_init_mutex(ha)) != DDI_SUCCESS) {
-                EL(ha, "failed, mutex init ret=%xh\n", ret);
+                if ((ret = ddi_intr_enable(ha->htable[i])) != DDI_SUCCESS) {
+                        EL(ha, "failed, intr enable, ret=%xh\n", ret);
                 ql_release_intr(ha);
                 return (ret);
         }
+        }
+#endif
 
         /* Get the capabilities */
         (void) ddi_intr_get_cap(ha->htable[0], &ha->intr_cap);
 
         /* Enable interrupts */
         if (ha->intr_cap & DDI_INTR_FLAG_BLOCK) {
-                if ((ret = ddi_intr_block_enable(ha->htable, ha->intr_cnt)) !=
+                if ((ret = ddi_intr_block_enable(ha->htable, actual)) !=
                     DDI_SUCCESS) {
                         EL(ha, "failed, block enable, ret=%xh\n", ret);
-                        ql_destroy_mutex(ha);
                         ql_release_intr(ha);
                         return (ret);
                 }
+                QL_PRINT_10(ha, "intr_block_enable %d\n", actual);
         } else {
-                for (i = 0; i < ha->intr_cnt; i++) {
+                for (i = 0; i < actual; i++) {
                         if ((ret = ddi_intr_enable(ha->htable[i])) !=
                             DDI_SUCCESS) {
                                 EL(ha, "failed, intr enable, ret=%xh\n", ret);
-                                ql_destroy_mutex(ha);
                                 ql_release_intr(ha);
                                 return (ret);
                         }
+                        QL_PRINT_10(ha, "intr_enable %d\n", i);
                 }
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (DDI_SUCCESS);
 }
 
 /*

@@ -16660,130 +17754,78 @@
 ql_setup_fixed(ql_adapter_state_t *ha)
 {
         int32_t         count = 0;
         int32_t         actual = 0;
         int32_t         ret;
-        uint32_t        i;
+        uint_t          i;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
+        if (ql_disable_intx != 0) {
+                EL(ha, "INT-X is disabled by user\n");
+                return (DDI_FAILURE);
+        }
+
         /* Get number of fixed interrupts the system supports */
         if (((ret = ddi_intr_get_nintrs(ha->dip, DDI_INTR_TYPE_FIXED,
             &count)) != DDI_SUCCESS) || count == 0) {
                 EL(ha, "failed, nintrs ret=%xh, cnt=%xh\n", ret, count);
                 return (DDI_FAILURE);
         }
 
-        ha->iflags |= IFLG_INTR_FIXED;
-
         /* Allocate space for interrupt handles */
         ha->hsize = ((uint32_t)(sizeof (ddi_intr_handle_t)) * count);
         ha->htable = kmem_zalloc(ha->hsize, KM_SLEEP);
 
+        ha->iflags |= IFLG_INTR_FIXED;
+
         /* Allocate the interrupts */
         if (((ret = ddi_intr_alloc(ha->dip, ha->htable, DDI_INTR_TYPE_FIXED,
             0, count, &actual, DDI_INTR_ALLOC_STRICT)) != DDI_SUCCESS) ||
             actual < count) {
                 EL(ha, "failed, intr_alloc ret=%xh, count=%xh, "
                     "actual=%xh\n", ret, count, actual);
                 ql_release_intr(ha);
                 return (DDI_FAILURE);
         }
-
         ha->intr_cnt = actual;
 
         /* Get interrupt priority */
-        if ((ret = ddi_intr_get_pri(ha->htable[0], &ha->intr_pri)) !=
-            DDI_SUCCESS) {
+        if ((ret = ddi_intr_get_pri(ha->htable[0], &i)) != DDI_SUCCESS) {
                 EL(ha, "failed, get_pri ret=%xh\n", ret);
                 ql_release_intr(ha);
                 return (ret);
         }
+        ha->intr_pri = DDI_INTR_PRI(i);
 
         /* Add the interrupt handlers */
-        for (i = 0; i < ha->intr_cnt; i++) {
-                if ((ret = ddi_intr_add_handler(ha->htable[i], &ql_isr_aif,
+        for (i = 0; i < actual; i++) {
+                if ((ret = ddi_intr_add_handler(ha->htable[i], ql_isr_aif,
                     (void *)ha, (void *)((ulong_t)(i)))) != DDI_SUCCESS) {
                         EL(ha, "failed, intr_add ret=%xh\n", ret);
                         ql_release_intr(ha);
                         return (ret);
                 }
         }
 
-        /* Setup mutexes */
-        if ((ret = ql_init_mutex(ha)) != DDI_SUCCESS) {
-                EL(ha, "failed, mutex init ret=%xh\n", ret);
-                ql_release_intr(ha);
-                return (ret);
-        }
-
         /* Enable interrupts */
-        for (i = 0; i < ha->intr_cnt; i++) {
+        for (i = 0; i < actual; i++) {
                 if ((ret = ddi_intr_enable(ha->htable[i])) != DDI_SUCCESS) {
                         EL(ha, "failed, intr enable, ret=%xh\n", ret);
-                        ql_destroy_mutex(ha);
                         ql_release_intr(ha);
                         return (ret);
                 }
         }
 
         EL(ha, "using FIXED interupts\n");
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (DDI_SUCCESS);
 }
 
 /*
- * ql_disable_intr
- *      Disables interrupts
- *
- * Input:
- *      ha = adapter state pointer.
- *
- * Returns:
- *
- * Context:
- *      Kernel context.
- */
-static void
-ql_disable_intr(ql_adapter_state_t *ha)
-{
-        uint32_t        i, rval;
-
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
-
-        if (!(ha->iflags & IFLG_INTR_AIF)) {
-
-                /* Disable legacy interrupts */
-                (void) ddi_remove_intr(ha->dip, 0, ha->iblock_cookie);
-
-        } else if ((ha->intr_cap & DDI_INTR_FLAG_BLOCK) &&
-            (ha->iflags & (IFLG_INTR_MSI | IFLG_INTR_MSIX))) {
-
-                /* Remove AIF block interrupts (MSI) */
-                if ((rval = ddi_intr_block_disable(ha->htable, ha->intr_cnt))
-                    != DDI_SUCCESS) {
-                        EL(ha, "failed intr block disable, rval=%x\n", rval);
-                }
-
-        } else {
-
-                /* Remove AIF non-block interrupts (fixed).  */
-                for (i = 0; i < ha->intr_cnt; i++) {
-                        if ((rval = ddi_intr_disable(ha->htable[i])) !=
-                            DDI_SUCCESS) {
-                                EL(ha, "failed intr disable, intr#=%xh, "
-                                    "rval=%xh\n", i, rval);
-                        }
-                }
-        }
-
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
-}
-
-/*
  * ql_release_intr
  *      Releases aif legacy interrupt resources
  *
  * Input:
  *      ha = adapter state pointer.

@@ -16794,47 +17836,56 @@
  *      Kernel context.
  */
 static void
 ql_release_intr(ql_adapter_state_t *ha)
 {
-        int32_t         i;
+        int32_t i, x;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         if (!(ha->iflags & IFLG_INTR_AIF)) {
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
-                return;
-        }
-
+                ddi_remove_intr(ha->dip, 0, ha->iblock_cookie);
+        } else {
         ha->iflags &= ~(IFLG_INTR_AIF);
         if (ha->htable != NULL && ha->hsize > 0) {
-                i = (int32_t)ha->hsize / (int32_t)sizeof (ddi_intr_handle_t);
+                        i = x = (int32_t)ha->hsize /
+                            (int32_t)sizeof (ddi_intr_handle_t);
+                        if (ha->intr_cap & DDI_INTR_FLAG_BLOCK) {
+                                (void) ddi_intr_block_disable(ha->htable,
+                                    ha->intr_cnt);
+                        } else {
                 while (i-- > 0) {
                         if (ha->htable[i] == 0) {
                                 EL(ha, "htable[%x]=0h\n", i);
                                 continue;
                         }
 
                         (void) ddi_intr_disable(ha->htable[i]);
+                                }
+                        }
 
+                        i = x;
+                        while (i-- > 0) {
                         if (i < ha->intr_cnt) {
-                                (void) ddi_intr_remove_handler(ha->htable[i]);
+                                        (void) ddi_intr_remove_handler(
+                                            ha->htable[i]);
                         }
-
                         (void) ddi_intr_free(ha->htable[i]);
                 }
 
+                        ha->intr_cnt = 0;
+                        ha->intr_cap = 0;
+
                 kmem_free(ha->htable, ha->hsize);
                 ha->htable = NULL;
+                        ha->hsize = 0;
         }
+        }
 
-        ha->hsize = 0;
-        ha->intr_cnt = 0;
-        ha->intr_pri = 0;
-        ha->intr_cap = 0;
+        ha->intr_pri = NULL;
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_legacy_intr
  *      Sets up legacy interrupts.

@@ -16852,36 +17903,38 @@
  *      Kernel context.
  */
 static int
 ql_legacy_intr(ql_adapter_state_t *ha)
 {
-        int     rval = DDI_SUCCESS;
+        int     rval;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
-        /* Setup mutexes */
-        if (ql_init_mutex(ha) != DDI_SUCCESS) {
-                EL(ha, "failed, mutex init\n");
-                return (DDI_FAILURE);
+        /* Get iblock cookies to initialize mutexes */
+        if ((rval = ddi_get_iblock_cookie(ha->dip, 0, &ha->iblock_cookie)) !=
+            DDI_SUCCESS) {
+                EL(ha, "failed, get_iblock: %xh\n", rval);
+                return (rval);
         }
+        ha->intr_pri = (void *)ha->iblock_cookie;
 
         /* Setup standard/legacy interrupt handler */
         if (ddi_add_intr(ha->dip, (uint_t)0, &ha->iblock_cookie,
             (ddi_idevice_cookie_t *)0, ql_isr, (caddr_t)ha) != DDI_SUCCESS) {
                 cmn_err(CE_WARN, "%s(%d): Failed to add legacy interrupt",
                     QL_NAME, ha->instance);
-                ql_destroy_mutex(ha);
-                rval = DDI_FAILURE;
+                return (rval);
         }
-
-        if (rval == DDI_SUCCESS) {
                 ha->iflags |= IFLG_INTR_LEGACY;
+
+        /* Setup mutexes */
+        if ((rval = ql_init_mutex(ha)) != DDI_SUCCESS) {
+                EL(ha, "failed, mutex init ret=%xh\n", rval);
+                ql_release_intr(ha);
+        } else {
                 EL(ha, "using legacy interrupts\n");
         }
-
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
-
         return (rval);
 }
 
 /*
  * ql_init_mutex

@@ -16897,68 +17950,47 @@
  *      Kernel context.
  */
 static int
 ql_init_mutex(ql_adapter_state_t *ha)
 {
-        int     ret;
-        void    *intr;
+        QL_PRINT_3(ha, "started\n");
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
-
-        if (ha->iflags & IFLG_INTR_AIF) {
-                intr = (void *)(uintptr_t)ha->intr_pri;
-        } else {
-                /* Get iblock cookies to initialize mutexes */
-                if ((ret = ddi_get_iblock_cookie(ha->dip, 0,
-                    &ha->iblock_cookie)) != DDI_SUCCESS) {
-                        EL(ha, "failed, get_iblock: %xh\n", ret);
-                        return (DDI_FAILURE);
-                }
-                intr = (void *)ha->iblock_cookie;
-        }
-
         /* mutexes to protect the adapter state structure. */
-        mutex_init(&ha->mutex, NULL, MUTEX_DRIVER, intr);
+        mutex_init(&ha->mutex, NULL, MUTEX_DRIVER, ha->intr_pri);
 
-        /* mutex to protect the ISP response ring. */
-        mutex_init(&ha->intr_mutex, NULL, MUTEX_DRIVER, intr);
+        /* mutex to protect the ISP request ring. */
+        mutex_init(&ha->req_ring_mutex, NULL, MUTEX_DRIVER, ha->intr_pri);
 
+        /* I/O completion queue protection. */
+        mutex_init(&ha->comp_q_mutex, NULL, MUTEX_DRIVER, ha->intr_pri);
+        cv_init(&ha->cv_comp_thread, NULL, CV_DRIVER, NULL);
+
         /* mutex to protect the mailbox registers. */
-        mutex_init(&ha->mbx_mutex, NULL, MUTEX_DRIVER, intr);
+        mutex_init(&ha->mbx_mutex, NULL, MUTEX_DRIVER, ha->intr_pri);
 
-        /* power management protection */
-        mutex_init(&ha->pm_mutex, NULL, MUTEX_DRIVER, intr);
-
         /* Mailbox wait and interrupt conditional variable. */
         cv_init(&ha->cv_mbx_wait, NULL, CV_DRIVER, NULL);
         cv_init(&ha->cv_mbx_intr, NULL, CV_DRIVER, NULL);
 
-        /* mutex to protect the ISP request ring. */
-        mutex_init(&ha->req_ring_mutex, NULL, MUTEX_DRIVER, intr);
+        /* power management protection */
+        mutex_init(&ha->pm_mutex, NULL, MUTEX_DRIVER, ha->intr_pri);
 
         /* Unsolicited buffer conditional variable. */
+        mutex_init(&ha->ub_mutex, NULL, MUTEX_DRIVER, ha->intr_pri);
         cv_init(&ha->cv_ub, NULL, CV_DRIVER, NULL);
 
-        mutex_init(&ha->ub_mutex, NULL, MUTEX_DRIVER, intr);
-        mutex_init(&ha->cache_mutex, NULL, MUTEX_DRIVER, intr);
+        /* mutex to protect task daemon context. */
+        mutex_init(&ha->task_daemon_mutex, NULL, MUTEX_DRIVER, ha->intr_pri);
+        cv_init(&ha->cv_task_daemon, NULL, CV_DRIVER, NULL);
 
         /* Suspended conditional variable. */
         cv_init(&ha->cv_dr_suspended, NULL, CV_DRIVER, NULL);
 
-        /* mutex to protect task daemon context. */
-        mutex_init(&ha->task_daemon_mutex, NULL, MUTEX_DRIVER, intr);
-
-        /* Task_daemon thread conditional variable. */
-        cv_init(&ha->cv_task_daemon, NULL, CV_DRIVER, NULL);
-
-        /* mutex to protect diag port manage interface */
-        mutex_init(&ha->portmutex, NULL, MUTEX_DRIVER, intr);
-
         /* mutex to protect per instance f/w dump flags and buffer */
-        mutex_init(&ha->dump_mutex, NULL, MUTEX_DRIVER, intr);
+        mutex_init(&ha->dump_mutex, NULL, MUTEX_DRIVER, ha->intr_pri);
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (DDI_SUCCESS);
 }
 
 /*

@@ -16974,29 +18006,28 @@
  *      Kernel context.
  */
 static void
 ql_destroy_mutex(ql_adapter_state_t *ha)
 {
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         mutex_destroy(&ha->dump_mutex);
-        mutex_destroy(&ha->portmutex);
+        cv_destroy(&ha->cv_dr_suspended);
         cv_destroy(&ha->cv_task_daemon);
         mutex_destroy(&ha->task_daemon_mutex);
-        cv_destroy(&ha->cv_dr_suspended);
-        mutex_destroy(&ha->cache_mutex);
-        mutex_destroy(&ha->ub_mutex);
         cv_destroy(&ha->cv_ub);
-        mutex_destroy(&ha->req_ring_mutex);
+        mutex_destroy(&ha->ub_mutex);
+        mutex_destroy(&ha->pm_mutex);
         cv_destroy(&ha->cv_mbx_intr);
         cv_destroy(&ha->cv_mbx_wait);
-        mutex_destroy(&ha->pm_mutex);
         mutex_destroy(&ha->mbx_mutex);
-        mutex_destroy(&ha->intr_mutex);
+        cv_destroy(&ha->cv_comp_thread);
+        mutex_destroy(&ha->comp_q_mutex);
+        mutex_destroy(&ha->req_ring_mutex);
         mutex_destroy(&ha->mutex);
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_fwmodule_resolve
  *      Loads and resolves external firmware module and symbols

@@ -17022,19 +18053,19 @@
 ql_fwmodule_resolve(ql_adapter_state_t *ha)
 {
         int8_t                  module[128];
         int8_t                  fw_version[128];
         uint32_t                rval = QL_SUCCESS;
-        caddr_t                 code, code02;
+        caddr_t                 code, code02, code03;
         uint8_t                 *p_ucfw;
         uint16_t                *p_usaddr, *p_uslen;
         uint32_t                *p_uiaddr, *p_uilen, *p_uifw;
-        uint32_t                *p_uiaddr02, *p_uilen02;
+        uint32_t                *p_uiaddr02, *p_uilen02, *p_uilen03;
         struct fw_table         *fwt;
         extern struct fw_table  fw_table[];
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         if (ha->fw_module != NULL) {
                 EL(ha, "%x f/w module %d.%02d.%02d is already loaded\n",
                     ha->fw_class, ha->fw_major_version, ha->fw_minor_version,
                     ha->fw_subminor_version);

@@ -17103,11 +18134,13 @@
                 }
                 break;
 
         case 0x2400:
         case 0x2500:
+        case 0x2700:
         case 0x8100:
+        case 0x8301fc:
 
                 if ((code = ddi_modsym(ha->fw_module, "risc_code01",
                     NULL)) == NULL) {
                         rval = QL_FWSYM_NOT_FOUND;
                         EL(ha, "failed, f/w module %d rc01 symbol\n", module);

@@ -17138,10 +18171,28 @@
                         rval = QL_FWSYM_NOT_FOUND;
                         EL(ha, "failed, f/w module %d rcl02 symbol\n", module);
                 }
 
                 if (rval == QL_SUCCESS) {
+                        if (ha->fw_class == 0x2700) {
+                                if ((code03 = ddi_modsym(ha->fw_module,
+                                    "tmplt_code01", NULL)) == NULL) {
+                                        EL(ha, "failed, f/w module %d "
+                                            "tmplt_code01 symbol\n", module);
+                                } else if ((p_uilen03 = ddi_modsym(
+                                    ha->fw_module, "tmplt_code_length01",
+                                    NULL)) == NULL) {
+                                        code03 = NULL;
+                                        EL(ha, "failed, f/w module %d "
+                                            "tmplt_code_length01 symbol\n",
+                                            module);
+                                }
+                                ha->risc_fw[2].code = code03;
+                                if ((ha->risc_fw[2].code = code03) != NULL) {
+                                        ha->risc_fw[2].length = *p_uilen03;
+                                }
+                        }
                         ha->risc_fw[0].code = code;
                         ha->risc_fw[0].addr = *p_uiaddr;
                         ha->risc_fw[0].length = *p_uilen;
                         ha->risc_fw[1].code = code02;
                         ha->risc_fw[1].addr = *p_uiaddr02;

@@ -17180,18 +18231,14 @@
 
                         cmn_err(CE_WARN, "%s(%d): driver / f/w version "
                             "mismatch for %x: driver-%s module-%s", QL_NAME,
                             ha->instance, ha->fw_class, fwt->fw_version,
                             fw_version);
-
-                        ha->cfg_flags |= CFG_FW_MISMATCH;
-                } else {
-                        ha->cfg_flags &= ~CFG_FW_MISMATCH;
                 }
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (rval);
 }
 
 /*

@@ -17209,11 +18256,11 @@
 void
 ql_port_state(ql_adapter_state_t *ha, uint32_t state, uint32_t flags)
 {
         ql_adapter_state_t      *vha;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         TASK_DAEMON_LOCK(ha);
         for (vha = ha->pha; vha != NULL; vha = vha->vp_next) {
                 if (FC_PORT_STATE_MASK(vha->state) != state) {
                         vha->state = state != FC_STATE_OFFLINE ?

@@ -17222,87 +18269,64 @@
                 }
         }
         ha->pha->task_daemon_flags |= flags & LOOP_DOWN;
         TASK_DAEMON_UNLOCK(ha);
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
- * ql_el_trace_desc_ctor - Construct an extended logging trace descriptor.
+ * ql_el_trace_alloc - Construct an extended logging trace descriptor.
  *
  * Input:       Pointer to the adapter state structure.
- * Returns:     Success or Failure.
  * Context:     Kernel context.
  */
-int
-ql_el_trace_desc_ctor(ql_adapter_state_t *ha)
+void
+ql_el_trace_alloc(ql_adapter_state_t *ha)
 {
-        int     rval = DDI_SUCCESS;
+        ql_trace_entry_t        *entry;
+        size_t                  maxsize;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        ha->ql_trace_desc =
+            (ql_trace_desc_t *)kmem_zalloc(
+            sizeof (ql_trace_desc_t), KM_SLEEP);
 
-        ha->el_trace_desc =
-            (el_trace_desc_t *)kmem_zalloc(sizeof (el_trace_desc_t), KM_SLEEP);
+        /* ql_log_entries could be adjusted in /etc/system */
+        maxsize = ql_log_entries * sizeof (ql_trace_entry_t);
+        entry = kmem_zalloc(maxsize, KM_SLEEP);
 
-        if (ha->el_trace_desc == NULL) {
-                cmn_err(CE_WARN, "%s(%d): can't construct trace descriptor",
-                    QL_NAME, ha->instance);
-                rval = DDI_FAILURE;
-        } else {
-                ha->el_trace_desc->next         = 0;
-                ha->el_trace_desc->trace_buffer =
-                    (char *)kmem_zalloc(EL_TRACE_BUF_SIZE, KM_SLEEP);
-
-                if (ha->el_trace_desc->trace_buffer == NULL) {
-                        cmn_err(CE_WARN, "%s(%d): can't get trace buffer",
-                            QL_NAME, ha->instance);
-                        kmem_free(ha->el_trace_desc, sizeof (el_trace_desc_t));
-                        rval = DDI_FAILURE;
-                } else {
-                        ha->el_trace_desc->trace_buffer_size =
-                            EL_TRACE_BUF_SIZE;
-                        mutex_init(&ha->el_trace_desc->mutex, NULL,
+        mutex_init(&ha->ql_trace_desc->mutex, NULL,
                             MUTEX_DRIVER, NULL);
-                }
-        }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        ha->ql_trace_desc->trace_buffer = entry;
+        ha->ql_trace_desc->trace_buffer_size = maxsize;
+        ha->ql_trace_desc->nindex = 0;
 
-        return (rval);
+        ha->ql_trace_desc->nentries = ql_log_entries;
+        ha->ql_trace_desc->start = ha->ql_trace_desc->end = 0;
+        ha->ql_trace_desc->csize = 0;
+        ha->ql_trace_desc->count = 0;
 }
 
 /*
- * ql_el_trace_desc_dtor - Destroy an extended logging trace descriptor.
+ * ql_el_trace_dealloc - Destroy an extended logging trace descriptor.
  *
  * Input:       Pointer to the adapter state structure.
- * Returns:     Success or Failure.
  * Context:     Kernel context.
  */
-int
-ql_el_trace_desc_dtor(ql_adapter_state_t *ha)
+void
+ql_el_trace_dealloc(ql_adapter_state_t *ha)
 {
-        int     rval = DDI_SUCCESS;
-
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
-
-        if (ha->el_trace_desc == NULL) {
-                cmn_err(CE_WARN, "%s(%d): can't destroy el trace descriptor",
-                    QL_NAME, ha->instance);
-                rval = DDI_FAILURE;
-        } else {
-                if (ha->el_trace_desc->trace_buffer != NULL) {
-                        kmem_free(ha->el_trace_desc->trace_buffer,
-                            ha->el_trace_desc->trace_buffer_size);
+        if (ha->ql_trace_desc != NULL) {
+                if (ha->ql_trace_desc->trace_buffer != NULL) {
+                        kmem_free(ha->ql_trace_desc->trace_buffer,
+                            ha->ql_trace_desc->trace_buffer_size);
                 }
-                mutex_destroy(&ha->el_trace_desc->mutex);
-                kmem_free(ha->el_trace_desc, sizeof (el_trace_desc_t));
+                mutex_destroy(&ha->ql_trace_desc->mutex);
+                kmem_free(ha->ql_trace_desc,
+                    sizeof (ql_trace_desc_t));
         }
-
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
-
-        return (rval);
 }
 
 /*
  * els_cmd_text - Return a pointer to a string describing the command
  *

@@ -17351,55 +18375,66 @@
         }
         return (entry->string);
 }
 
 /*
- * ql_els_24xx_mbox_cmd_iocb - els request indication.
+ * ql_els_24xx_iocb
+ *      els request indication.
  *
- * Input:       ha = adapter state pointer.
- *              srb = scsi request block pointer.
- *              arg = els passthru entry iocb pointer.
+ * Input:
+ *      ha:     adapter state pointer.
+ *      req_q:  request queue structure pointer.
+ *      srb:    scsi request block pointer.
+ *      arg:    els passthru entry iocb pointer.
+ *
  * Returns:
+ *
  * Context:     Kernel context.
  */
 void
-ql_els_24xx_iocb(ql_adapter_state_t *ha, ql_srb_t *srb, void *arg)
+ql_els_24xx_iocb(ql_adapter_state_t *ha, ql_request_q_t *req_q, ql_srb_t *srb,
+    void *arg)
 {
         els_descriptor_t        els_desc;
 
         /* Extract the ELS information */
-        ql_fca_isp_els_request(ha, (fc_packet_t *)srb->pkt, &els_desc);
+        ql_fca_isp_els_request(ha, req_q, (fc_packet_t *)srb->pkt,
+            &els_desc);
 
         /* Construct the passthru entry */
         ql_isp_els_request_ctor(&els_desc, (els_passthru_entry_t *)arg);
 
         /* Ensure correct endianness */
         ql_isp_els_handle_cmd_endian(ha, srb);
 }
 
 /*
- * ql_fca_isp_els_request - Extract into an els descriptor the info required
+ * ql_fca_isp_els_request
+ *      Extract into an els descriptor the info required
  *                          to build an els_passthru iocb from an fc packet.
  *
- * Input:       ha = adapter state pointer.
- *              pkt = fc packet pointer
- *              els_desc = els descriptor pointer
- * Returns:
- * Context:     Kernel context.
+ * Input:
+ *      ha:             adapter state pointer.
+ *      req_q:          request queue structure pointer.
+ *      pkt:            fc packet pointer
+ *      els_desc:       els descriptor pointer
+ *
+ * Context:
+ *      Kernel context.
  */
 static void
-ql_fca_isp_els_request(ql_adapter_state_t *ha, fc_packet_t *pkt,
-    els_descriptor_t *els_desc)
+ql_fca_isp_els_request(ql_adapter_state_t *ha, ql_request_q_t *req_q,
+    fc_packet_t *pkt, els_descriptor_t *els_desc)
 {
         ls_code_t       els;
 
         ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
             (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
 
         els_desc->els = els.ls_code;
 
-        els_desc->els_handle = ha->hba_buf.acc_handle;
+        els_desc->els_handle = req_q->req_ring.acc_handle;
         els_desc->d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
         els_desc->s_id.b24 = pkt->pkt_cmd_fhdr.s_id;
         /* if n_port_handle is not < 0x7d use 0 */
         if (LOCAL_LOOP_ID(ha->n_port->n_port_handle)) {
                 els_desc->n_port_handle = ha->n_port->n_port_handle;

@@ -17472,11 +18507,11 @@
         ddi_put32(els_desc->els_handle, &els_entry->rcv_payld_data_bcnt,
             els_desc->rsp_byte_count);
         ddi_put32(els_desc->els_handle, &els_entry->xmt_payld_data_bcnt,
             els_desc->cmd_byte_count);
         /* Load transmit data segments and count. */
-        ptr32 = (uint32_t *)&els_entry->xmt_dseg_0_address;
+        ptr32 = (uint32_t *)&els_entry->dseg;
         ddi_put16(els_desc->els_handle, &els_entry->xmt_dseg_count, 1);
         ddi_put32(els_desc->els_handle, ptr32++, els_desc->tx_dsd.addr[0]);
         ddi_put32(els_desc->els_handle, ptr32++, els_desc->tx_dsd.addr[1]);
         ddi_put32(els_desc->els_handle, ptr32++, els_desc->tx_dsd.length);
         ddi_put16(els_desc->els_handle, &els_entry->rcv_dseg_count, 1);

@@ -17619,11 +18654,11 @@
  */
 static int
 ql_n_port_plogi(ql_adapter_state_t *ha)
 {
         int             rval;
-        ql_tgt_t        *tq;
+        ql_tgt_t        *tq = NULL;
         ql_head_t done_q = { NULL, NULL };
 
         rval = QL_SUCCESS;
 
         if (ha->topology & QL_N_PORT) {

@@ -17640,11 +18675,11 @@
                 } else {
                         EL(ha, "n_port_handle = %x, tq = %x\n",
                             ha->n_port->n_port_handle, tq);
                 }
                 if (done_q.first != NULL) {
-                        ql_done(done_q.first);
+                        ql_done(done_q.first, B_FALSE);
                 }
         }
         return (rval);
 }
 

@@ -17658,20 +18693,17 @@
  * Return Values:
  *   if first == second return  0
  *   if first > second  return  1
  *   if first < second  return -1
  */
+/* ARGSUSED */
 int
 ql_wwn_cmp(ql_adapter_state_t *ha, la_wwn_t *first, la_wwn_t *second)
 {
         la_wwn_t t1, t2;
         int rval;
 
-        EL(ha, "WWPN=%08x%08x\n",
-            BE_32(first->i_wwn[0]), BE_32(first->i_wwn[1]));
-        EL(ha, "WWPN=%08x%08x\n",
-            BE_32(second->i_wwn[0]), BE_32(second->i_wwn[1]));
         /*
          * Fibre Channel protocol is big endian, so compare
          * as big endian values
          */
         t1.i_wwn[0] = BE_32(first->i_wwn[0]);

@@ -17697,49 +18729,10 @@
         }
         return (rval);
 }
 
 /*
- * ql_wait_for_td_stop
- *      Wait for task daemon to stop running.  Internal command timeout
- *      is approximately 30 seconds, so it may help in some corner
- *      cases to wait that long
- *
- * Input:
- *      ha = adapter state pointer.
- *
- * Returns:
- *      DDI_SUCCESS or DDI_FAILURE.
- *
- * Context:
- *      Kernel context.
- */
-
-static int
-ql_wait_for_td_stop(ql_adapter_state_t *ha)
-{
-        int     rval = DDI_FAILURE;
-        UINT16  wait_cnt;
-
-        for (wait_cnt = 0; wait_cnt < 3000; wait_cnt++) {
-                /* The task daemon clears the stop flag on exit. */
-                if (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) {
-                        if (ha->cprinfo.cc_events & CALLB_CPR_START ||
-                            ddi_in_panic()) {
-                                drv_usecwait(10000);
-                        } else {
-                                delay(drv_usectohz(10000));
-                        }
-                } else {
-                        rval = DDI_SUCCESS;
-                        break;
-                }
-        }
-        return (rval);
-}
-
-/*
  * ql_nvram_cache_desc_ctor - Construct an nvram cache descriptor.
  *
  * Input:       Pointer to the adapter state structure.
  * Returns:     Success or Failure.
  * Context:     Kernel context.

@@ -17747,11 +18740,11 @@
 int
 ql_nvram_cache_desc_ctor(ql_adapter_state_t *ha)
 {
         int     rval = DDI_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         ha->nvram_cache =
             (nvram_cache_desc_t *)kmem_zalloc(sizeof (nvram_cache_desc_t),
             KM_SLEEP);
 

@@ -17758,11 +18751,11 @@
         if (ha->nvram_cache == NULL) {
                 cmn_err(CE_WARN, "%s(%d): can't construct nvram cache"
                     " descriptor", QL_NAME, ha->instance);
                 rval = DDI_FAILURE;
         } else {
-                if (CFG_IST(ha, CFG_CTRL_24258081)) {
+                if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
                         ha->nvram_cache->size = sizeof (nvram_24xx_t);
                 } else {
                         ha->nvram_cache->size = sizeof (nvram_t);
                 }
                 ha->nvram_cache->cache =

@@ -17773,17 +18766,15 @@
                         kmem_free(ha->nvram_cache,
                             sizeof (nvram_cache_desc_t));
                         ha->nvram_cache = 0;
                         rval = DDI_FAILURE;
                 } else {
-                        mutex_init(&ha->nvram_cache->mutex, NULL,
-                            MUTEX_DRIVER, NULL);
                         ha->nvram_cache->valid = 0;
                 }
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (rval);
 }
 
 /*

@@ -17796,11 +18787,11 @@
 int
 ql_nvram_cache_desc_dtor(ql_adapter_state_t *ha)
 {
         int     rval = DDI_SUCCESS;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         if (ha->nvram_cache == NULL) {
                 cmn_err(CE_WARN, "%s(%d): can't destroy nvram descriptor",
                     QL_NAME, ha->instance);
                 rval = DDI_FAILURE;

@@ -17807,143 +18798,4225 @@
         } else {
                 if (ha->nvram_cache->cache != NULL) {
                         kmem_free(ha->nvram_cache->cache,
                             ha->nvram_cache->size);
                 }
-                mutex_destroy(&ha->nvram_cache->mutex);
                 kmem_free(ha->nvram_cache, sizeof (nvram_cache_desc_t));
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (rval);
 }
 
 /*
- * ql_process_idc_event - Handle an Inter-Driver Communication async event.
+ * ql_plogi_params_desc_ctor - Construct an plogi retry params descriptor.
  *
  * Input:       Pointer to the adapter state structure.
- * Returns:     void
+ * Returns:     Success or Failure.
  * Context:     Kernel context.
  */
+int
+ql_plogi_params_desc_ctor(ql_adapter_state_t *ha)
+{
+        int     rval = DDI_SUCCESS;
+
+        QL_PRINT_3(ha, "started\n");
+
+        ha->plogi_params =
+            (plogi_params_desc_t *)kmem_zalloc(sizeof (plogi_params_desc_t),
+            KM_SLEEP);
+
+        if (ha->plogi_params == NULL) {
+                cmn_err(CE_WARN, "%s(%d): can't construct plogi params"
+                    " descriptor", QL_NAME, ha->instance);
+                rval = DDI_FAILURE;
+        } else {
+                /* default initializers. */
+                ha->plogi_params->retry_cnt = QL_PLOGI_RETRY_CNT;
+                ha->plogi_params->retry_dly_usec = QL_PLOGI_RETRY_DLY_USEC;
+        }
+
+        QL_PRINT_3(ha, "done\n");
+
+        return (rval);
+}
+
+/*
+ * ql_plogi_params_desc_dtor - Destroy an plogi retry params descriptor.
+ *
+ * Input:       Pointer to the adapter state structure.
+ * Returns:     Success or Failure.
+ * Context:     Kernel context.
+ */
+int
+ql_plogi_params_desc_dtor(ql_adapter_state_t *ha)
+{
+        int     rval = DDI_SUCCESS;
+
+        QL_PRINT_3(ha, "started\n");
+
+        if (ha->plogi_params == NULL) {
+                cmn_err(CE_WARN, "%s(%d): can't destroy plogi params"
+                    " descriptor", QL_NAME, ha->instance);
+                rval = DDI_FAILURE;
+        } else {
+                kmem_free(ha->plogi_params, sizeof (plogi_params_desc_t));
+        }
+
+        QL_PRINT_3(ha, "done\n");
+
+        return (rval);
+}
+
+/*
+ * ql_toggle_loop_state
+ *      Changes looop state to offline and then online.
+ *
+ * Input:
+ *      ha:     adapter state pointer.
+ *
+ * Context:
+ *      Kernel context.
+ */
+void
+ql_toggle_loop_state(ql_adapter_state_t *ha)
+{
+        uint32_t        timer;
+
+        if (LOOP_READY(ha)) {
+                ql_port_state(ha, FC_STATE_OFFLINE, FC_STATE_CHANGE);
+                ql_awaken_task_daemon(ha, NULL, FC_STATE_CHANGE, 0);
+                for (timer = 30; timer; timer--) {
+                        if (!(ha->task_daemon_flags & FC_STATE_CHANGE)) {
+                                break;
+                        }
+                        delay(100);
+                }
+                ql_loop_online(ha);
+        }
+}
+
+/*
+ * ql_create_queues
+ *      Allocate request/response queues.
+ *
+ * Input:
+ *      ha:     adapter state pointer.
+ *
+ * Returns:
+ *      ql driver local function return status codes
+ *
+ * Context:
+ *      Kernel context.
+ */
+static int
+ql_create_queues(ql_adapter_state_t *ha)
+{
+        int             rval;
+        uint16_t        cnt;
+
+        QL_PRINT_10(ha, "started\n");
+
+        if (ha->req_q[0] != NULL) {
+                QL_PRINT_10(ha, "done, queues already exist\n");
+                return (QL_SUCCESS);
+        }
+        if (ha->vp_index != 0) {
+                QL_PRINT_10(ha, "done, no multi-req-q \n");
+                ha->req_q[0] = ha->pha->req_q[0];
+                ha->req_q[1] = ha->pha->req_q[1];
+                ha->rsp_queues = ha->pha->rsp_queues;
+                return (QL_SUCCESS);
+        }
+
+        /* Setup request queue buffer pointers. */
+        ha->req_q[0] = kmem_zalloc(sizeof (ql_request_q_t), KM_SLEEP);
+
+        /* Allocate request queue. */
+        ha->req_q[0]->req_entry_cnt = REQUEST_ENTRY_CNT;
+        ha->req_q[0]->req_ring.size = ha->req_q[0]->req_entry_cnt *
+            REQUEST_ENTRY_SIZE;
+        if (ha->flags & QUEUE_SHADOW_PTRS) {
+                ha->req_q[0]->req_ring.size += SHADOW_ENTRY_SIZE;
+        }
+        ha->req_q[0]->req_ring.type = LITTLE_ENDIAN_DMA;
+        ha->req_q[0]->req_ring.max_cookie_count = 1;
+        ha->req_q[0]->req_ring.alignment = 64;
+        if ((rval = ql_alloc_phys(ha, &ha->req_q[0]->req_ring, KM_SLEEP)) !=
+            QL_SUCCESS) {
+                EL(ha, "request queue status=%xh", rval);
+                ql_delete_queues(ha);
+                return (rval);
+        }
+        if (ha->flags & QUEUE_SHADOW_PTRS) {
+                ha->req_q[0]->req_out_shadow_ofst =
+                    ha->req_q[0]->req_entry_cnt * REQUEST_ENTRY_SIZE;
+                ha->req_q[0]->req_out_shadow_ptr = (uint32_t *)
+                    ((caddr_t)ha->req_q[0]->req_ring.bp +
+                    ha->req_q[0]->req_out_shadow_ofst);
+        }
+        ha->fw_transfer_size = ha->req_q[0]->req_ring.size;
+        if (ha->flags & MULTI_QUEUE) {
+                ha->req_q[0]->mbar_req_in = MBAR2_REQ_IN;
+                ha->req_q[0]->mbar_req_out = MBAR2_REQ_OUT;
+                if (ha->req_q[0]->mbar_req_in >= ha->mbar_size) {
+                        EL(ha, "req_q index=0 exceeds mbar size=%xh",
+                            ha->mbar_size);
+                        ql_delete_queues(ha);
+                        return (QL_FUNCTION_PARAMETER_ERROR);
+                }
+        }
+
+        /* Allocate response queues. */
+        if (ha->rsp_queues == NULL) {
+                if (ha->intr_cnt > 1) {
+                        ha->rsp_queues_cnt = (uint8_t)(ha->intr_cnt - 1);
+                } else {
+                        ha->rsp_queues_cnt = 1;
+                }
+                ha->io_min_rsp_q_number = 0;
+                if (ha->rsp_queues_cnt > 1) {
+                        /* Setup request queue buffer pointers. */
+                        ha->req_q[1] = kmem_zalloc(sizeof (ql_request_q_t),
+                            KM_SLEEP);
+
+                        /* Allocate request queue. */
+                        ha->req_q[1]->req_entry_cnt = REQUEST_ENTRY_CNT;
+                        ha->req_q[1]->req_ring.size =
+                            ha->req_q[1]->req_entry_cnt * REQUEST_ENTRY_SIZE;
+                        if (ha->flags & QUEUE_SHADOW_PTRS) {
+                                ha->req_q[1]->req_ring.size +=
+                                    SHADOW_ENTRY_SIZE;
+                        }
+                        ha->req_q[1]->req_ring.type = LITTLE_ENDIAN_DMA;
+                        ha->req_q[1]->req_ring.max_cookie_count = 1;
+                        ha->req_q[1]->req_ring.alignment = 64;
+                        if ((rval = ql_alloc_phys(ha, &ha->req_q[1]->req_ring,
+                            KM_SLEEP)) != QL_SUCCESS) {
+                                EL(ha, "ha request queue status=%xh", rval);
+                                ql_delete_queues(ha);
+                                return (rval);
+                        }
+                        if (ha->flags & QUEUE_SHADOW_PTRS) {
+                                ha->req_q[1]->req_out_shadow_ofst =
+                                    ha->req_q[1]->req_entry_cnt *
+                                    REQUEST_ENTRY_SIZE;
+                                ha->req_q[1]->req_out_shadow_ptr = (uint32_t *)
+                                    ((caddr_t)ha->req_q[1]->req_ring.bp +
+                                    ha->req_q[1]->req_out_shadow_ofst);
+                        }
+                        ha->req_q[1]->req_q_number = 1;
+                        if (ha->flags & MULTI_QUEUE) {
+                                ha->req_q[1]->mbar_req_in =
+                                    ha->mbar_queue_offset + MBAR2_REQ_IN;
+                                ha->req_q[1]->mbar_req_out =
+                                    ha->mbar_queue_offset + MBAR2_REQ_OUT;
+                                if (ha->req_q[1]->mbar_req_in >=
+                                    ha->mbar_size) {
+                                        EL(ha, "ha req_q index=1 exceeds mbar "
+                                            "size=%xh", ha->mbar_size);
+                                        ql_delete_queues(ha);
+                                        return (QL_FUNCTION_PARAMETER_ERROR);
+                                }
+                        }
+                }
+
+                /* Allocate enough rsp_queue descriptors for IRM */
+                ha->rsp_queues_size = (ha->hsize / sizeof (ddi_intr_handle_t)) *
+                    sizeof (ql_response_q_t *);
+                ha->rsp_queues = kmem_zalloc(ha->rsp_queues_size, KM_SLEEP);
+
+                /* Create rsp_queues for the current rsp_queue_cnt */
+                for (cnt = 0; cnt < ha->rsp_queues_cnt; cnt++) {
+                        rval = ql_create_rsp_queue(ha, cnt);
+                        if (rval != QL_SUCCESS) {
+                                ql_delete_queues(ha);
+                                return (rval);
+                        }
+                }
+        }
+
+        if (CFG_IST(ha, CFG_FCIP_TYPE_1)) {
+                /* Allocate IP receive queue. */
+                ha->rcv_ring.size = RCVBUF_QUEUE_SIZE;
+                ha->rcv_ring.type = LITTLE_ENDIAN_DMA;
+                ha->rcv_ring.max_cookie_count = 1;
+                ha->rcv_ring.alignment = 64;
+                if ((rval = ql_alloc_phys(ha, &ha->rcv_ring, KM_SLEEP)) !=
+                    QL_SUCCESS) {
+                        EL(ha, "receive queue status=%xh", rval);
+                        ql_delete_queues(ha);
+                        return (rval);
+                }
+        }
+
+        QL_PRINT_10(ha, "done\n");
+
+        return (rval);
+}
+
+/*
+ * ql_create_rsp_queue
+ *      Allocate a response queues.
+ *
+ * Input:
+ *      ha:     adapter state pointer.
+ *
+ * Returns:
+ *      ql driver local function return status codes
+ *
+ * Context:
+ *      Kernel context.
+ */
+static int
+ql_create_rsp_queue(ql_adapter_state_t *ha, uint16_t rsp_q_indx)
+{
+        ql_response_q_t *rsp_q;
+        int             rval = QL_SUCCESS;
+
+        QL_PRINT_3(ha, "started\n");
+
+        ha->rsp_queues[rsp_q_indx] = rsp_q =
+            kmem_zalloc(sizeof (ql_response_q_t), KM_SLEEP);
+        /* ISP response ring and interrupt protection. */
+        mutex_init(&rsp_q->intr_mutex, NULL, MUTEX_DRIVER, ha->intr_pri);
+        rsp_q->rsp_q_number = rsp_q_indx;
+        rsp_q->msi_x_vector = (uint16_t)(rsp_q_indx + 1);
+        if (ha->flags & MULTI_QUEUE) {
+                rsp_q->mbar_rsp_in = rsp_q->rsp_q_number *
+                    ha->mbar_queue_offset + MBAR2_RESP_IN;
+                rsp_q->mbar_rsp_out = rsp_q->rsp_q_number *
+                    ha->mbar_queue_offset + MBAR2_RESP_OUT;
+                if (rsp_q->mbar_rsp_in >= ha->mbar_size) {
+                        EL(ha, "rsp_q index=%xh exceeds mbar size=%xh",
+                            rsp_q_indx, ha->mbar_size);
+                        return (QL_FUNCTION_PARAMETER_ERROR);
+                }
+        }
+
+        rsp_q->rsp_entry_cnt = RESPONSE_ENTRY_CNT;
+        rsp_q->rsp_ring.size = rsp_q->rsp_entry_cnt * RESPONSE_ENTRY_SIZE;
+        if (ha->flags & QUEUE_SHADOW_PTRS) {
+                rsp_q->rsp_ring.size += SHADOW_ENTRY_SIZE;
+        }
+        rsp_q->rsp_ring.type = LITTLE_ENDIAN_DMA;
+        rsp_q->rsp_ring.max_cookie_count = 1;
+        rsp_q->rsp_ring.alignment = 64;
+        rval = ql_alloc_phys(ha, &rsp_q->rsp_ring, KM_SLEEP);
+        if (rval != QL_SUCCESS) {
+                EL(ha, "response queue status=%xh", rval);
+        }
+        if (ha->flags & QUEUE_SHADOW_PTRS) {
+                rsp_q->rsp_in_shadow_ofst =
+                    rsp_q->rsp_entry_cnt * RESPONSE_ENTRY_SIZE;
+                rsp_q->rsp_in_shadow_ptr = (uint32_t *)
+                    ((caddr_t)rsp_q->rsp_ring.bp +
+                    rsp_q->rsp_in_shadow_ofst);
+        }
+
+        QL_PRINT_3(ha, "done\n");
+        return (rval);
+}
+
+/*
+ * ql_delete_queues
+ *      Deletes request/response queues.
+ *
+ * Input:
+ *      ha = adapter state pointer.
+ *
+ * Context:
+ *      Kernel context.
+ */
 static void
-ql_process_idc_event(ql_adapter_state_t *ha)
+ql_delete_queues(ql_adapter_state_t *ha)
 {
+        uint32_t        cnt;
+
+        QL_PRINT_10(ha, "started\n");
+
+        if (ha->vp_index != 0) {
+                QL_PRINT_10(ha, "done, no multi-req-q \n");
+                ha->req_q[0] = ha->req_q[1] = NULL;
+                return;
+        }
+        if (ha->req_q[0] != NULL) {
+                ql_free_phys(ha, &ha->req_q[0]->req_ring);
+                kmem_free(ha->req_q[0], sizeof (ql_request_q_t));
+                ha->req_q[0] = NULL;
+        }
+        if (ha->req_q[1] != NULL) {
+                ql_free_phys(ha, &ha->req_q[1]->req_ring);
+                kmem_free(ha->req_q[1], sizeof (ql_request_q_t));
+                ha->req_q[1] = NULL;
+        }
+
+        if (ha->rsp_queues != NULL) {
+                ql_response_q_t *rsp_q;
+
+                for (cnt = 0; cnt < ha->rsp_queues_cnt; cnt++) {
+                        if ((rsp_q = ha->rsp_queues[cnt]) == NULL) {
+                                continue;
+                        }
+
+                        mutex_destroy(&rsp_q->intr_mutex);
+                        ql_free_phys(ha, &rsp_q->rsp_ring);
+                        kmem_free(rsp_q, sizeof (ql_response_q_t));
+                        ha->rsp_queues[cnt] = NULL;
+                }
+                kmem_free(ha->rsp_queues, ha->rsp_queues_size);
+                ha->rsp_queues = NULL;
+        }
+
+        QL_PRINT_10(ha, "done\n");
+}
+
+/*
+ * ql_multi_queue_support
+ *      Test 2500 or 8100 adapters for support of multi-queue
+ *
+ * Input:
+ *      ha:     adapter state pointer.
+ *
+ * Returns:
+ *      ql local function return status code.
+ *
+ * Context:
+ *      Kernel context.
+ */
+static int
+ql_multi_queue_support(ql_adapter_state_t *ha)
+{
+        uint32_t        data;
         int     rval;
 
-        switch (ha->idc_mb[0]) {
-        case MBA_IDC_NOTIFICATION:
+        data = ql_get_cap_ofst(ha, PCI_CAP_ID_MSI_X);
+        if ((ql_pci_config_get16(ha, data + PCI_MSIX_CTRL) &
+            PCI_MSIX_TBL_SIZE_MASK) > 2) {
+                ha->mbar_size = MBAR2_MULTI_Q_MAX * MBAR2_REG_OFFSET;
+
+                if (ql_map_mem_bar(ha, &ha->mbar_dev_handle, &ha->mbar,
+                    PCI_CONF_BASE3, ha->mbar_size) != DDI_SUCCESS) {
+                        return (QL_FUNCTION_FAILED);
+                }
+                if ((rval = qlc_fm_check_acc_handle(ha,
+                    ha->mbar_dev_handle)) != DDI_FM_OK) {
+                        qlc_fm_report_err_impact(ha,
+                            QL_FM_EREPORT_ACC_HANDLE_CHECK);
+                        EL(ha, "fm_check_acc_handle mbar_dev_handle "
+                            "status=%xh\n", rval);
+                        return (QL_FUNCTION_FAILED);
+                }
+                return (QL_SUCCESS);
+        }
+        return (QL_FUNCTION_FAILED);
+}
+
+/*
+ * ql_get_cap_ofst
+ *      Locates PCI configuration space capability pointer
+ *
+ * Input:
+ *      ha:     adapter state pointer.
+ *      cap_id: Capability ID.
+ *
+ * Returns:
+ *      capability offset
+ *
+ * Context:
+ *      Kernel context.
+ */
+int
+ql_get_cap_ofst(ql_adapter_state_t *ha, uint8_t cap_id)
+{
+        int     cptr = PCI_CAP_NEXT_PTR_NULL;
+
+        QL_PRINT_3(ha, "started\n");
+
+        if (ql_pci_config_get16(ha, PCI_CONF_STAT) & PCI_STAT_CAP) {
+                cptr = ql_pci_config_get8(ha, PCI_CONF_CAP_PTR);
+
+                while (cptr != PCI_CAP_NEXT_PTR_NULL) {
+                        if (ql_pci_config_get8(ha, cptr) == cap_id) {
+                                break;
+                        }
+                        cptr = ql_pci_config_get8(ha, cptr + PCI_CAP_NEXT_PTR);
+                }
+        }
+
+        QL_PRINT_3(ha, "done\n");
+        return (cptr);
+}
+
+/*
+ * ql_map_mem_bar
+ *      Map Mem BAR
+ *
+ * Input:
+ *      ha:              adapter state pointer.
+ *      handlep:        access handle pointer.
+ *      addrp:          address structure pointer.
+ *      ofst:           BAR offset.
+ *      len:            address space length.
+ *
+ * Returns:
+ *      DDI_SUCCESS or DDI_FAILURE.
+ *
+ * Context:
+ *      Kernel context.
+ */
+static int
+ql_map_mem_bar(ql_adapter_state_t *ha, ddi_acc_handle_t *handlep,
+    caddr_t *addrp, uint32_t ofst, uint32_t len)
+{
+        caddr_t         nreg;
+        pci_regspec_t   *reg, *reg2;
+        int             rval;
+        uint_t          rlen;
+        uint32_t        rcnt, w32, nreg_size;
+
+        QL_PRINT_10(ha, "started\n");
+
+        /* Check for Mem BAR */
+        w32 = ql_pci_config_get32(ha, ofst);
+        if (w32 == 0) {
+                EL(ha, "no Mem BAR %xh\n", ofst);
+                return (DDI_FAILURE);
+        }
+
+        /*LINTED [Solaris DDI_DEV_T_ANY Lint error]*/
+        if ((rval = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, ha->dip,
+            DDI_PROP_DONTPASS, "reg", (int **)&reg, &rlen)) !=
+            DDI_PROP_SUCCESS) {
+                EL(ha, "ddi_prop_lookup_int_array status=%xh\n", rval);
+                return (DDI_FAILURE);
+        }
+        rlen = (uint_t)(rlen * sizeof (int));   /* in bytes */
+        rcnt = (uint32_t)(rlen / sizeof (pci_regspec_t));
+
+        /* Check if register already added. */
+        reg2 = reg;
+        for (w32 = 0; w32 < rcnt; w32++) {
+                if ((reg2->pci_phys_hi & PCI_REG_REG_M) == ofst) {
+                        EL(ha, "already mapped\n");
+                        break;
+                }
+                reg2++;
+        }
+        if (w32 == rcnt) {
                 /*
-                 * The informational opcode (idc_mb[2]) can be a
-                 * defined value or the mailbox command being executed
-                 * on another function which stimulated this IDC message.
+                 * Allocate memory for the existing reg(s) plus one and then
+                 * build it.
                  */
-                ADAPTER_STATE_LOCK(ha);
-                switch (ha->idc_mb[2]) {
-                case IDC_OPC_DRV_START:
-                        if (ha->idc_flash_acc != 0) {
-                                ha->idc_flash_acc--;
-                                if (ha->idc_flash_acc == 0) {
-                                        ha->idc_flash_acc_timer = 0;
-                                        GLOBAL_HW_UNLOCK();
+                nreg_size = (uint32_t)(rlen + sizeof (pci_regspec_t));
+                nreg = kmem_zalloc(nreg_size, KM_SLEEP);
+
+                /*
+                 * Find a current map memory reg to copy.
+                 */
+                reg2 = reg;
+                while ((reg2->pci_phys_hi & PCI_REG_ADDR_M) !=
+                    PCI_ADDR_MEM32 && (reg2->pci_phys_hi & PCI_REG_ADDR_M) !=
+                    PCI_ADDR_MEM64) {
+                        reg2++;
+                        if ((caddr_t)reg2 >= (caddr_t)reg + rlen) {
+                                reg2 = reg;
+                                break;
                                 }
                         }
-                        if (ha->idc_restart_cnt != 0) {
-                                ha->idc_restart_cnt--;
-                                if (ha->idc_restart_cnt == 0) {
-                                        ha->idc_restart_timer = 0;
-                                        ADAPTER_STATE_UNLOCK(ha);
-                                        TASK_DAEMON_LOCK(ha);
-                                        ha->task_daemon_flags &= ~DRIVER_STALL;
-                                        TASK_DAEMON_UNLOCK(ha);
-                                        ql_restart_queues(ha);
-                                } else {
-                                        ADAPTER_STATE_UNLOCK(ha);
+                w32 = (reg2->pci_phys_hi & ~PCI_REG_REG_M) | ofst;
+
+                bcopy(reg, nreg, rlen);
+                reg2 = (pci_regspec_t *)(nreg + rlen);
+
+                reg2->pci_phys_hi = w32;
+                reg2->pci_phys_mid = 0;
+                reg2->pci_phys_low = 0;
+                reg2->pci_size_hi = 0;
+                reg2->pci_size_low = len;
+
+                /*
+                 * Write out the new "reg" property
+                 */
+                /*LINTED [Solaris DDI_DEV_T_NONE Lint error]*/
+                (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, ha->dip,
+                    "reg", (int *)nreg, (uint_t)(nreg_size / sizeof (int)));
+
+                w32 = (uint_t)(nreg_size / sizeof (pci_regspec_t) - 1);
+                kmem_free((caddr_t)nreg, nreg_size);
                                 }
+
+        ddi_prop_free(reg);
+
+        /* Map register */
+        rval = ddi_regs_map_setup(ha->dip, w32, addrp, 0, len,
+            &ql_dev_acc_attr, handlep);
+        if (rval != DDI_SUCCESS || *addrp == NULL || *handlep == NULL) {
+                EL(ha, "regs_map status=%xh, base=%xh, handle=%xh\n",
+                    rval, *addrp, *handlep);
+                if (*handlep != NULL) {
+                        ddi_regs_map_free(handlep);
+                        *handlep = NULL;
+                }
+        }
+
+        QL_PRINT_10(ha, "done\n");
+
+        return (rval);
+}
+
+/*
+ * ql_intr_lock
+ *      Acquires all interrupt locks.
+ *
+ * Input:
+ *      ha:     adapter state pointer.
+ *
+ * Context:
+ *      Kernel/Interrupt context.
+ */
+void
+ql_intr_lock(ql_adapter_state_t *ha)
+{
+        uint16_t        cnt;
+
+        QL_PRINT_3(ha, "started\n");
+
+        if (ha->rsp_queues != NULL) {
+                for (cnt = 0; cnt < ha->rsp_queues_cnt; cnt++) {
+                        if (ha->rsp_queues[cnt] != NULL) {
+                                INDX_INTR_LOCK(ha, cnt);
+                        }
+                }
+        }
+        QL_PRINT_3(ha, "done\n");
+}
+
+/*
+ * ql_intr_unlock
+ *      Releases all interrupt locks.
+ *
+ * Input:
+ *      ha:     adapter state pointer.
+ *
+ * Context:
+ *      Kernel/Interrupt context.
+ */
+void
+ql_intr_unlock(ql_adapter_state_t *ha)
+{
+        uint16_t        cnt;
+
+        QL_PRINT_3(ha, "started\n");
+
+        if (ha->rsp_queues != NULL) {
+                for (cnt = 0; cnt < ha->rsp_queues_cnt; cnt++) {
+                        if (ha->rsp_queues[cnt] != NULL) {
+                                INDX_INTR_UNLOCK(ha, cnt);
+                        }
+                }
+        }
+        QL_PRINT_3(ha, "done\n");
+}
+
+/*
+ * ql_completion_thread
+ *      I/O completion thread.
+ *
+ * Input:
+ *      arg:    port info pointer.
+ *      COMP_Q_LOCK must be acquired prior to call.
+ *
+ * Context:
+ *      Kernel context.
+ */
+static void
+ql_completion_thread(void *arg)
+{
+        ql_srb_t                *sp;
+        ql_adapter_state_t      *ha = arg;
+
+        QL_PRINT_3(ha, "started, hsp=%p\n", (void *)&sp);
+
+        COMP_Q_LOCK(ha);
+        ha->comp_thds_active++;
+        ha->comp_thds_awake++;
+        while (!(ha->flags & COMP_THD_TERMINATE)) {
+                /* process completion queue items */
+                while (ha->comp_q.first != NULL) {
+                        sp = (ha->comp_q.first)->base_address;
+                        /* Remove command from completion queue */
+                        ql_remove_link(&ha->comp_q, &sp->cmd);
+                        COMP_Q_UNLOCK(ha);
+                        QL_PRINT_3(ha, "pkt_comp, sp=%p, pkt_state=%xh, "
+                            "hsp=%p\n", (void*)sp, sp->pkt->pkt_state,
+                            (void *)&sp);
+                        (sp->pkt->pkt_comp)(sp->pkt);
+                        COMP_Q_LOCK(ha);
+                }
+                ha->comp_thds_awake--;
+                QL_PRINT_3(ha, "sleep, hsp=%p\n", (void *)&sp);
+                cv_wait(&ha->cv_comp_thread, &ha->comp_q_mutex);
+                QL_PRINT_3(ha, "awoke, hsp=%p\n", (void *)&sp);
+        }
+        ha->comp_thds_awake--;
+        ha->comp_thds_active--;
+        COMP_Q_UNLOCK(ha);
+
+        QL_PRINT_3(ha, "done\n");
+}
+
+/*
+ * ql_io_comp
+ *      Transport I/O completion
+ *
+ * Input:
+ *      sp:     SRB structure pointer
+ *
+ * Context:
+ *      Kernel context.
+ */
+void
+ql_io_comp(ql_srb_t *sp)
+{
+        ql_adapter_state_t      *ha = sp->ha->pha;
+
+        QL_PRINT_3(ha, "started, sp=%ph, d_id=%xh\n", (void*)sp,
+            sp->pkt->pkt_cmd_fhdr.d_id);
+
+        if (sp->pkt->pkt_comp && !ddi_in_panic()) {
+                QL_PRINT_3(ha, "added to comp_q\n");
+                COMP_Q_LOCK(ha);
+                ql_add_link_b(&ha->comp_q, &sp->cmd);
+                if (ha->comp_thds_awake < ha->comp_thds_active) {
+                        ha->comp_thds_awake++;
+                        QL_PRINT_3(ha, "signal\n");
+                        cv_signal(&ha->cv_comp_thread);
+                }
+                COMP_Q_UNLOCK(ha);
+        }
+
+        QL_PRINT_3(ha, "done\n");
+}
+
+/*
+ * ql_process_comp_queue
+ *      Process completion queue entries.
+ *
+ * Input:
+ *      arg:    adapter state pointer.
+ *
+ * Context:
+ *      Kernel context.
+ */
+static void
+ql_process_comp_queue(void *arg)
+{
+        ql_srb_t                *sp;
+        ql_adapter_state_t      *ha = arg;
+
+        QL_PRINT_3(ha, "started\n");
+
+        COMP_Q_LOCK(ha);
+
+        /* process completion queue items */
+        while (ha->comp_q.first != NULL) {
+                sp = (ha->comp_q.first)->base_address;
+                QL_PRINT_3(ha, "sending comp=0x%p\n", (void *)sp);
+                /* Remove command from completion queue */
+                ql_remove_link(&ha->comp_q, &sp->cmd);
+                COMP_Q_UNLOCK(ha);
+                (sp->pkt->pkt_comp)(sp->pkt);
+                COMP_Q_LOCK(ha);
+        }
+
+        COMP_Q_UNLOCK(ha);
+
+        QL_PRINT_3(ha, "done\n");
+}
+
+/*
+ * ql_abort_io
+ *      Abort I/O.
+ *
+ * Input:
+ *      ha:     adapter state pointer.
+ *      sp:     SRB pointer.
+ *
+ * Returns:
+ *      ql local function return status code.
+ *
+ * Context:
+ *      Kernel context.
+ */
+static int
+ql_abort_io(ql_adapter_state_t *vha, ql_srb_t *sp)
+{
+        ql_link_t               *link;
+        ql_srb_t                *sp2;
+        ql_tgt_t                *tq;
+        ql_lun_t                *lq;
+        int                     rval = QL_FUNCTION_FAILED;
+        ql_adapter_state_t      *ha = vha->pha;
+
+        QL_PRINT_10(ha, "started, sp=%ph, handle=%xh\n", (void *)sp,
+            sp->handle);
+
+        if ((lq = sp->lun_queue) != NULL) {
+                tq = lq->target_queue;
                         } else {
-                                ADAPTER_STATE_UNLOCK(ha);
+                tq = NULL;
                         }
+
+        /* Acquire target queue lock. */
+        if (tq) {
+                DEVICE_QUEUE_LOCK(tq);
+        }
+        REQUEST_RING_LOCK(ha);
+
+        /* If command not already started. */
+        if (!(sp->flags & SRB_ISP_STARTED)) {
+                rval = QL_FUNCTION_PARAMETER_ERROR;
+
+                /* Check pending queue for command. */
+                for (link = ha->pending_cmds.first; link != NULL;
+                    link = link->next) {
+                        sp2 = link->base_address;
+                        if (sp2 == sp) {
+                                rval = QL_SUCCESS;
+                                /* Remove srb from pending command queue */
+                                ql_remove_link(&ha->pending_cmds, &sp->cmd);
                         break;
-                case IDC_OPC_FLASH_ACC:
-                        ha->idc_flash_acc_timer = 30;
-                        if (ha->idc_flash_acc == 0) {
-                                GLOBAL_HW_LOCK();
                         }
-                        ha->idc_flash_acc++;
-                        ADAPTER_STATE_UNLOCK(ha);
+                }
+
+                if (link == NULL && lq) {
+                        /* Check for cmd on device queue. */
+                        for (link = lq->cmd.first; link != NULL;
+                            link = link->next) {
+                                sp2 = link->base_address;
+                                if (sp2 == sp) {
+                                        rval = QL_SUCCESS;
+                                        /* Remove srb from device queue. */
+                                        ql_remove_link(&lq->cmd, &sp->cmd);
+                                        sp->flags &= ~SRB_IN_DEVICE_QUEUE;
                         break;
-                case IDC_OPC_RESTART_MPI:
-                        ha->idc_restart_timer = 30;
-                        ha->idc_restart_cnt++;
+                                }
+                        }
+                }
+        }
+
+        REQUEST_RING_UNLOCK(ha);
+        if (tq) {
+                DEVICE_QUEUE_UNLOCK(tq);
+        }
+
+        if (sp->flags & SRB_ISP_COMPLETED || rval == QL_SUCCESS) {
+                rval = QL_SUCCESS;
+        } else {
+                uint32_t        index;
+
+                INTR_LOCK(ha);
+                sp->flags |= SRB_ABORTING;
+                if (sp->handle != 0) {
+                        index = sp->handle & OSC_INDEX_MASK;
+                        if (ha->outstanding_cmds[index] == sp) {
+                                ha->outstanding_cmds[index] =
+                                    QL_ABORTED_SRB(ha);
+                        }
+                        /* Decrement outstanding commands on device. */
+                        if (tq != NULL && tq->outcnt != 0) {
+                                tq->outcnt--;
+                        }
+                        if (lq != NULL && sp->flags & SRB_FCP_CMD_PKT &&
+                            lq->lun_outcnt != 0) {
+                                lq->lun_outcnt--;
+                        }
+                        /* Remove command from watchdog queue. */
+                        if (sp->flags & SRB_WATCHDOG_ENABLED) {
+                                if (tq != NULL) {
+                                        ql_remove_link(&tq->wdg, &sp->wdg);
+                                }
+                                sp->flags &= ~SRB_WATCHDOG_ENABLED;
+                        }
+                        INTR_UNLOCK(ha);
+                        (void) ql_abort_command(ha, sp);
+                        sp->handle = 0;
+                } else {
+                        INTR_UNLOCK(ha);
+                }
+                rval = QL_SUCCESS;
+        }
+
+        if (rval != QL_SUCCESS) {
+                EL(ha, "sp=%p not aborted=%xh\n", (void *)sp, rval);
+        } else {
+                /*EMPTY*/
+                QL_PRINT_10(ha, "done\n");
+        }
+        return (rval);
+}
+
+/*
+ *  ql_idc
+ *      Inter driver communication thread.
+ *
+ * Input:
+ *      ha = adapter state pointer.
+ *
+ * Context:
+ *      Kernel context.
+ */
+static void
+ql_idc(ql_adapter_state_t *ha)
+{
+        int             rval;
+        uint32_t        timer = 300;
+
+        QL_PRINT_10(ha, "started\n");
+
+        for (;;) {
+                /* IDC Stall needed. */
+                if (ha->flags & IDC_STALL_NEEDED) {
+                        ADAPTER_STATE_LOCK(ha);
+                        ha->flags &= ~IDC_STALL_NEEDED;
                         ADAPTER_STATE_UNLOCK(ha);
                         TASK_DAEMON_LOCK(ha);
                         ha->task_daemon_flags |= DRIVER_STALL;
                         TASK_DAEMON_UNLOCK(ha);
-                        break;
-                case IDC_OPC_PORT_RESET_MBC:
-                case IDC_OPC_SET_PORT_CONFIG_MBC:
-                        ha->idc_restart_timer = 30;
-                        ha->idc_restart_cnt++;
-                        ADAPTER_STATE_UNLOCK(ha);
-                        TASK_DAEMON_LOCK(ha);
-                        ha->task_daemon_flags |= DRIVER_STALL;
-                        TASK_DAEMON_UNLOCK(ha);
+                        if (LOOP_READY(ha)) {
+                                if ((ha->idc_mb[1] & IDC_TIMEOUT_MASK) <
+                                    IDC_TIMEOUT_MASK) {
+                                        ha->idc_mb[1] = (uint16_t)
+                                            (ha->idc_mb[1] | IDC_TIMEOUT_MASK);
+                                        rval = ql_idc_time_extend(ha);
+                                        if (rval != QL_SUCCESS) {
+                                                EL(ha, "idc_time_extend status"
+                                                    "=%xh\n", rval);
+                                        }
+                                }
                         (void) ql_wait_outstanding(ha);
-                        break;
-                default:
-                        ADAPTER_STATE_UNLOCK(ha);
-                        EL(ha, "Unknown IDC opcode=%xh %xh\n", ha->idc_mb[0],
-                            ha->idc_mb[2]);
-                        break;
                 }
-                /*
-                 * If there is a timeout value associated with this IDC
-                 * notification then there is an implied requirement
-                 * that we return an ACK.
-                 */
-                if (ha->idc_mb[1] & IDC_TIMEOUT_MASK) {
+                }
+
+                /* IDC ACK needed. */
+                if (ha->flags & IDC_ACK_NEEDED) {
+                        ADAPTER_STATE_LOCK(ha);
+                        ha->flags &= ~IDC_ACK_NEEDED;
+                        ADAPTER_STATE_UNLOCK(ha);
                         rval = ql_idc_ack(ha);
                         if (rval != QL_SUCCESS) {
-                                EL(ha, "idc_ack status=%xh %xh\n", rval,
-                                    ha->idc_mb[2]);
+                                EL(ha, "idc_ack status=%xh\n", rval);
+                                ADAPTER_STATE_LOCK(ha);
+                                ha->flags |= IDC_RESTART_NEEDED;
+                                ADAPTER_STATE_UNLOCK(ha);
                         }
                 }
-                break;
-        case MBA_IDC_COMPLETE:
-                /*
-                 * We don't ACK completions, only these require action.
-                 */
-                switch (ha->idc_mb[2]) {
-                case IDC_OPC_PORT_RESET_MBC:
-                case IDC_OPC_SET_PORT_CONFIG_MBC:
+
+                /* IDC Restart needed. */
+                if (timer-- == 0 || ha->flags & ADAPTER_SUSPENDED ||
+                    (ha->flags & IDC_RESTART_NEEDED &&
+                    !(ha->flags & LOOPBACK_ACTIVE))) {
                         ADAPTER_STATE_LOCK(ha);
-                        if (ha->idc_restart_cnt != 0) {
-                                ha->idc_restart_cnt--;
-                                if (ha->idc_restart_cnt == 0) {
-                                        ha->idc_restart_timer = 0;
+                        ha->flags &= ~(IDC_RESTART_NEEDED | IDC_STALL_NEEDED |
+                            IDC_ACK_NEEDED);
                                         ADAPTER_STATE_UNLOCK(ha);
                                         TASK_DAEMON_LOCK(ha);
                                         ha->task_daemon_flags &= ~DRIVER_STALL;
                                         TASK_DAEMON_UNLOCK(ha);
+                        if (LOOP_READY(ha)) {
                                         ql_restart_queues(ha);
+                        }
+                        break;
+                }
+                delay(10);
+        }
+
+        QL_PRINT_10(ha, "done\n");
+}
+
+/*
+ * ql_get_lun_addr
+ *      get the lunslun address.
+ *
+ * Input:
+ *      tq:     target queue pointer.
+ *      lun:    the lun number.
+ *
+ * Returns:
+ *      the lun address.
+ *
+ * Context:
+ *      Interrupt or Kernel context, no mailbox commands allowed.
+ */
+uint64_t
+ql_get_lun_addr(ql_tgt_t *tq, uint16_t lun)
+{
+        ql_lun_t                *lq;
+        ql_link_t               *link = NULL;
+        uint64_t                lun_addr = 0;
+        fcp_ent_addr_t          *fcp_ent_addr = (fcp_ent_addr_t *)&lun_addr;
+
+        /* If the lun queue exists */
+        if (tq) {
+                for (link = tq->lun_queues.first; link != NULL;
+                    link = link->next) {
+                        lq = link->base_address;
+                        if (lq->lun_no == lun) {
+                                break;
+                        }
+                }
+        }
+        if (link == NULL) {
+                /* create an fcp_ent_addr from the lun number */
+                if (MSB(lun)) {
+                        fcp_ent_addr->ent_addr_0 = CHAR_TO_SHORT(lobyte(lun),
+                            (hibyte(lun) | QL_LUN_AM_FLAT));
                                 } else {
-                                        ADAPTER_STATE_UNLOCK(ha);
+                        fcp_ent_addr->ent_addr_0 = CHAR_TO_SHORT(lobyte(lun),
+                            hibyte(lun));
                                 }
                         } else {
-                                ADAPTER_STATE_UNLOCK(ha);
+                lun_addr = lq->lun_addr;
                         }
+
+        return (lun_addr);
+}
+
+
+/*
+ * ql_83xx_binary_fw_dump
+ *
+ * Input:
+ *      ha:     adapter state pointer.
+ *      fw:     firmware dump context pointer.
+ *
+ * Returns:
+ *      ql local function return status code.
+ *
+ * Context:
+ *      Interrupt or Kernel context, no mailbox commands allowed.
+ */
+static int
+ql_83xx_binary_fw_dump(ql_adapter_state_t *ha, ql_83xx_fw_dump_t *fw)
+{
+        uint32_t        *reg32, cnt, *w32ptr, index, *dp;
+        void            *bp;
+        clock_t         timer;
+        int             rv, rval = QL_SUCCESS;
+
+        QL_PRINT_3(ha, "started\n");
+
+        fw->req_q_size[0] = ha->req_q[0]->req_ring.size;
+        if (ha->req_q[1] != NULL) {
+                fw->req_q_size[1] = ha->req_q[1]->req_ring.size;
+        }
+        fw->rsp_q_size = ha->rsp_queues[0]->rsp_ring.size * ha->rsp_queues_cnt;
+
+        fw->hccr = RD32_IO_REG(ha, hccr);
+        fw->r2h_status = RD32_IO_REG(ha, risc2host);
+        fw->aer_ues = ql_pci_config_get32(ha, 0x104);
+
+        /* Disable ISP interrupts. */
+        ql_disable_intr(ha);
+
+        /* Pause RISC. */
+        if ((RD32_IO_REG(ha, risc2host) & RH_RISC_PAUSED) == 0) {
+                WRT32_IO_REG(ha, hccr, HC24_PAUSE_RISC);
+                for (timer = 30000;
+                    (RD32_IO_REG(ha, risc2host) & RH_RISC_PAUSED) == 0 &&
+                    rval == QL_SUCCESS; timer--) {
+                        if (timer) {
+                                drv_usecwait(100);
+                                if (timer % 10000 == 0) {
+                                        EL(ha, "risc pause %d\n", timer);
+                                }
+                        } else {
+                                EL(ha, "risc pause timeout\n");
+                                rval = QL_FUNCTION_TIMEOUT;
+                        }
+                }
+        }
+
+        WRT32_IO_REG(ha, io_base_addr, 0x6000);
+        WRT_REG_DWORD(ha, ha->iobase + 0xc0, 0);
+        WRT_REG_DWORD(ha, ha->iobase + 0xcc, 0);
+
+        WRT32_IO_REG(ha, io_base_addr, 0x6010);
+        WRT_REG_DWORD(ha, ha->iobase + 0xd4, 0);
+
+        WRT32_IO_REG(ha, io_base_addr, 0x0F70);
+        WRT_REG_DWORD(ha, ha->iobase + 0xf0, 0x60000000);
+
+        /* Host Interface registers */
+
+        /* HostRisc registers. */
+        WRT32_IO_REG(ha, io_base_addr, 0x7000);
+        bp = ql_read_regs(ha, fw->hostrisc_reg, ha->iobase + 0xC0,
+            16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x7010);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x7040);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* PCIe registers. */
+        WRT32_IO_REG(ha, io_base_addr, 0x7c00);
+        WRT_REG_DWORD(ha, ha->iobase + 0xc0, 0x1);
+        bp = ql_read_regs(ha, fw->pcie_reg, ha->iobase + 0xC4,
+            3, 32);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 1, 32);
+        WRT_REG_DWORD(ha, ha->iobase + 0xc0, 0x0);
+
+        /* Host interface registers. */
+        (void) ql_read_regs(ha, fw->host_reg, ha->iobase,
+            sizeof (fw->host_reg) / 4, 32);
+
+        /* Shadow registers. */
+
+        WRT32_IO_REG(ha, io_base_addr, 0x0F70);
+        RD32_IO_REG(ha, io_base_addr);
+
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
+        WRT_REG_DWORD(ha, reg32, 0xB0000000);
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
+        fw->shadow_reg[0] = RD_REG_DWORD(ha, reg32);
+
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
+        WRT_REG_DWORD(ha, reg32, 0xB0100000);
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
+        fw->shadow_reg[1] = RD_REG_DWORD(ha, reg32);
+
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
+        WRT_REG_DWORD(ha, reg32, 0xB0200000);
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
+        fw->shadow_reg[2] = RD_REG_DWORD(ha, reg32);
+
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
+        WRT_REG_DWORD(ha, reg32, 0xB0300000);
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
+        fw->shadow_reg[3] = RD_REG_DWORD(ha, reg32);
+
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
+        WRT_REG_DWORD(ha, reg32, 0xB0400000);
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
+        fw->shadow_reg[4] = RD_REG_DWORD(ha, reg32);
+
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
+        WRT_REG_DWORD(ha, reg32, 0xB0500000);
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
+        fw->shadow_reg[5] = RD_REG_DWORD(ha, reg32);
+
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
+        WRT_REG_DWORD(ha, reg32, 0xB0600000);
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
+        fw->shadow_reg[6] = RD_REG_DWORD(ha, reg32);
+
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
+        WRT_REG_DWORD(ha, reg32, 0xB0700000);
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
+        fw->shadow_reg[7] = RD_REG_DWORD(ha, reg32);
+
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
+        WRT_REG_DWORD(ha, reg32, 0xB0800000);
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
+        fw->shadow_reg[8] = RD_REG_DWORD(ha, reg32);
+
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
+        WRT_REG_DWORD(ha, reg32, 0xB0900000);
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
+        fw->shadow_reg[9] = RD_REG_DWORD(ha, reg32);
+
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
+        WRT_REG_DWORD(ha, reg32, 0xB0A00000);
+        reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
+        fw->shadow_reg[0xa] = RD_REG_DWORD(ha, reg32);
+
+        /* RISC I/O register. */
+
+        WRT32_IO_REG(ha, io_base_addr, 0x0010);
+        (void) ql_read_regs(ha, &fw->risc_io, ha->iobase + 0xC0,
+            1, 32);
+
+        /* Mailbox registers. */
+
+        (void) ql_read_regs(ha, fw->mailbox_reg, ha->iobase + 0x80,
+            sizeof (fw->mailbox_reg) / 2, 16);
+
+        /* Transfer sequence registers. */
+
+        /* XSEQ GP */
+        WRT32_IO_REG(ha, io_base_addr, 0xBE00);
+        bp = ql_read_regs(ha, fw->xseq_gp_reg, ha->iobase + 0xC0,
+            16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xBE10);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xBE20);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xBE30);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xBE40);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xBE50);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xBE60);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xBE70);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xBF00);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xBF10);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xBF20);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xBF30);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xBF40);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xBF50);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xBF60);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xBF70);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* XSEQ-0 */
+        WRT32_IO_REG(ha, io_base_addr, 0xBFC0);
+        bp = ql_read_regs(ha, fw->xseq_0_reg, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xBFD0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xBFE0);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* XSEQ-1 */
+        WRT32_IO_REG(ha, io_base_addr, 0xBFF0);
+        (void) ql_read_regs(ha, fw->xseq_1_reg, ha->iobase + 0xC0,
+            16, 32);
+
+        /* XSEQ-2 */
+        WRT32_IO_REG(ha, io_base_addr, 0xBEF0);
+        (void) ql_read_regs(ha, fw->xseq_2_reg, ha->iobase + 0xC0,
+            16, 32);
+
+        /* Receive sequence registers. */
+
+        /* RSEQ GP */
+        WRT32_IO_REG(ha, io_base_addr, 0xFE00);
+        bp = ql_read_regs(ha, fw->rseq_gp_reg, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xFE10);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xFE20);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xFE30);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xFE40);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xFE50);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xFE60);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xFE70);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xFF00);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xFF10);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xFF20);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xFF30);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xFF40);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xFF50);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xFF60);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xFF70);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* RSEQ-0 */
+        WRT32_IO_REG(ha, io_base_addr, 0xFFC0);
+        bp = ql_read_regs(ha, fw->rseq_0_reg, ha->iobase + 0xC0,
+            16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xFFD0);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* RSEQ-1 */
+        WRT32_IO_REG(ha, io_base_addr, 0xFFE0);
+        (void) ql_read_regs(ha, fw->rseq_1_reg, ha->iobase + 0xC0,
+            sizeof (fw->rseq_1_reg) / 4, 32);
+
+        /* RSEQ-2 */
+        WRT32_IO_REG(ha, io_base_addr, 0xFFF0);
+        (void) ql_read_regs(ha, fw->rseq_2_reg, ha->iobase + 0xC0,
+            sizeof (fw->rseq_2_reg) / 4, 32);
+
+        /* RSEQ-3 */
+        WRT32_IO_REG(ha, io_base_addr, 0xFEF0);
+        (void) ql_read_regs(ha, fw->rseq_3_reg, ha->iobase + 0xC0,
+            sizeof (fw->rseq_3_reg) / 4, 32);
+
+        /* Auxiliary sequencer registers. */
+
+        /* ASEQ GP */
+        WRT32_IO_REG(ha, io_base_addr, 0xB000);
+        bp = ql_read_regs(ha, fw->aseq_gp_reg, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xB010);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xB020);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xB030);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xB040);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xB050);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xB060);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xB070);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xB100);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xB110);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xB120);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xB130);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xB140);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xB150);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xB160);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xB170);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* ASEQ-0 */
+        WRT32_IO_REG(ha, io_base_addr, 0xB0C0);
+        bp = ql_read_regs(ha, fw->aseq_0_reg, ha->iobase + 0xC0,
+            16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0xB0D0);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* ASEQ-1 */
+        WRT32_IO_REG(ha, io_base_addr, 0xB0E0);
+        (void) ql_read_regs(ha, fw->aseq_1_reg, ha->iobase + 0xC0,
+            16, 32);
+
+        /* ASEQ-2 */
+        WRT32_IO_REG(ha, io_base_addr, 0xB0F0);
+        (void) ql_read_regs(ha, fw->aseq_2_reg, ha->iobase + 0xC0,
+            16, 32);
+
+        /* ASEQ-3 */
+        WRT32_IO_REG(ha, io_base_addr, 0xB1F0);
+        (void) ql_read_regs(ha, fw->aseq_3_reg, ha->iobase + 0xC0,
+            16, 32);
+
+        /* Command DMA registers. */
+
+        WRT32_IO_REG(ha, io_base_addr, 0x7100);
+        bp = ql_read_regs(ha, fw->cmd_dma_reg, ha->iobase + 0xC0,
+            16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x7120);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x7130);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x71f0);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* Queues. */
+
+        /* RequestQ0 */
+        WRT32_IO_REG(ha, io_base_addr, 0x7200);
+        bp = ql_read_regs(ha, fw->req0_dma_reg, ha->iobase + 0xC0,
+            8, 32);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
+
+        /* ResponseQ0 */
+        WRT32_IO_REG(ha, io_base_addr, 0x7300);
+        bp = ql_read_regs(ha, fw->resp0_dma_reg, ha->iobase + 0xC0,
+            8, 32);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
+
+        /* RequestQ1 */
+        WRT32_IO_REG(ha, io_base_addr, 0x7400);
+        bp = ql_read_regs(ha, fw->req1_dma_reg, ha->iobase + 0xC0,
+            8, 32);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
+
+        /* Transmit DMA registers. */
+
+        /* XMT0 */
+        WRT32_IO_REG(ha, io_base_addr, 0x7600);
+        bp = ql_read_regs(ha, fw->xmt0_dma_reg, ha->iobase + 0xC0,
+            16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x7610);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* XMT1 */
+        WRT32_IO_REG(ha, io_base_addr, 0x7620);
+        bp = ql_read_regs(ha, fw->xmt1_dma_reg, ha->iobase + 0xC0,
+            16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x7630);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* XMT2 */
+        WRT32_IO_REG(ha, io_base_addr, 0x7640);
+        bp = ql_read_regs(ha, fw->xmt2_dma_reg, ha->iobase + 0xC0,
+            16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x7650);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* XMT3 */
+        WRT32_IO_REG(ha, io_base_addr, 0x7660);
+        bp = ql_read_regs(ha, fw->xmt3_dma_reg, ha->iobase + 0xC0,
+            16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x7670);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* XMT4 */
+        WRT32_IO_REG(ha, io_base_addr, 0x7680);
+        bp = ql_read_regs(ha, fw->xmt4_dma_reg, ha->iobase + 0xC0,
+            16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x7690);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* XMT Common */
+        WRT32_IO_REG(ha, io_base_addr, 0x76A0);
+        (void) ql_read_regs(ha, fw->xmt_data_dma_reg,
+            ha->iobase + 0xC0, sizeof (fw->xmt_data_dma_reg) / 4, 32);
+
+        /* Receive DMA registers. */
+
+        /* RCVThread0 */
+        WRT32_IO_REG(ha, io_base_addr, 0x7700);
+        bp = ql_read_regs(ha, fw->rcvt0_data_dma_reg,
+            ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x7710);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* RCVThread1 */
+        WRT32_IO_REG(ha, io_base_addr, 0x7720);
+        bp = ql_read_regs(ha, fw->rcvt1_data_dma_reg,
+            ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x7730);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* RISC registers. */
+
+        /* RISC GP */
+        WRT32_IO_REG(ha, io_base_addr, 0x0F00);
+        bp = ql_read_regs(ha, fw->risc_gp_reg, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x0F10);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x0F20);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x0F30);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x0F40);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x0F50);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x0F60);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x0F70);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* Local memory controller (LMC) registers. */
+
+        /* LMC */
+        WRT32_IO_REG(ha, io_base_addr, 0x3000);
+        bp = ql_read_regs(ha, fw->lmc_reg, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x3010);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x3020);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x3030);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x3040);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x3050);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x3060);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x3070);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* Fibre Protocol Module registers. */
+
+        /* FPM hardware */
+        WRT32_IO_REG(ha, io_base_addr, 0x4000);
+        bp = ql_read_regs(ha, fw->fpm_hdw_reg, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x4010);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x4020);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x4030);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x4040);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x4050);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x4060);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x4070);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x4080);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x4090);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x40A0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x40B0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x40C0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x40D0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x40E0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x40F0);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* Pointer arrays registers */
+
+        /* RQ0 Array registers. */
+        WRT32_IO_REG(ha, io_base_addr, 0x5C00);
+        bp = ql_read_regs(ha, fw->rq0_array_reg, ha->iobase + 0xC0,
+            16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5C10);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5C20);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5C30);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5C40);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5C50);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5C60);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5C70);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5C80);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5C90);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5CA0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5CB0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5CC0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5CD0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5CE0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5CF0);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* RQ1 Array registers. */
+        WRT32_IO_REG(ha, io_base_addr, 0x5D00);
+        bp = ql_read_regs(ha, fw->rq1_array_reg, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5D10);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5D20);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5D30);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5D40);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5D50);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5D60);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5D70);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5D80);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5D90);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5DA0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5DB0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5DC0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5DD0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5DE0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5DF0);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* RP0 Array registers. */
+        WRT32_IO_REG(ha, io_base_addr, 0x5E00);
+        bp = ql_read_regs(ha, fw->rp0_array_reg, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5E10);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5E20);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5E30);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5E40);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5E50);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5E60);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5E70);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5E80);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5E90);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5EA0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5EB0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5EC0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5ED0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5EE0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5EF0);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* RP1 Array registers. */
+        WRT32_IO_REG(ha, io_base_addr, 0x5F00);
+        bp = ql_read_regs(ha, fw->rp1_array_reg, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5F10);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5F20);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5F30);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5F40);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5F50);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5F60);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5F70);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5F80);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5F90);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5FA0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5FB0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5FC0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5FD0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5FE0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x5FF0);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* AT0 Array Registers */
+        WRT32_IO_REG(ha, io_base_addr, 0x7080);
+        bp = ql_read_regs(ha, fw->ato_array_reg, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x7090);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x70A0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x70B0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x70C0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x70D0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x70E0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x70F0);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* I/O queue control registers */
+
+        /* Queue Control Registers. */
+        WRT32_IO_REG(ha, io_base_addr, 0x7800);
+        (void) ql_read_regs(ha, fw->queue_control_reg, ha->iobase + 0xC0,
+            16, 32);
+
+        /* Frame Buffer registers. */
+
+        /* FB hardware */
+        WRT32_IO_REG(ha, io_base_addr, 0x6000);
+        bp = ql_read_regs(ha, fw->fb_hdw_reg, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x6010);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x6020);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x6030);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x6040);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x6060);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x6070);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x6100);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x6130);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x6150);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x6170);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x6190);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x61B0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x61C0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x6530);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x6540);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x6550);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x6560);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x6570);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x6580);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x6590);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x65A0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x65B0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x65C0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x65D0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x65E0);
+        bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+        WRT32_IO_REG(ha, io_base_addr, 0x6F00);
+        (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
+
+        /* Get the Queue Pointers */
+        dp = fw->req_rsp_ext_mem;
+        for (index = 0; index < ha->rsp_queues_cnt; index++) {
+                if (index == 0) {
+                        *dp = RD32_MBAR_REG(ha, ha->req_q[0]->mbar_req_in);
+                        LITTLE_ENDIAN_32(dp);
+                        dp++;
+                        *dp = RD32_MBAR_REG(ha, ha->req_q[0]->mbar_req_out);
+                        LITTLE_ENDIAN_32(dp);
+                        dp++;
+                } else if (index == 1) {
+                        *dp = RD32_MBAR_REG(ha, ha->req_q[1]->mbar_req_in);
+                        LITTLE_ENDIAN_32(dp);
+                        dp++;
+                        *dp = RD32_MBAR_REG(ha, ha->req_q[1]->mbar_req_out);
+                        LITTLE_ENDIAN_32(dp);
+                        dp++;
+                } else {
+                        *dp++ = 0;
+                        *dp++ = 0;
+                }
+                *dp = RD32_MBAR_REG(ha, ha->rsp_queues[index]->mbar_rsp_in);
+                LITTLE_ENDIAN_32(dp);
+                dp++;
+                *dp = RD32_MBAR_REG(ha, ha->rsp_queues[index]->mbar_rsp_out);
+                LITTLE_ENDIAN_32(dp);
+                dp++;
+        }
+
+        /* Get the request queue */
+        (void) ddi_dma_sync(ha->req_q[0]->req_ring.dma_handle, 0, 0,
+            DDI_DMA_SYNC_FORCPU);
+        w32ptr = (uint32_t *)ha->req_q[0]->req_ring.bp;
+        for (cnt = 0; cnt < fw->req_q_size[0] / 4; cnt++) {
+                *dp = *w32ptr++;
+                LITTLE_ENDIAN_32(dp);
+                dp++;
+        }
+        if (ha->req_q[1] != NULL) {
+                (void) ddi_dma_sync(ha->req_q[1]->req_ring.dma_handle, 0, 0,
+                    DDI_DMA_SYNC_FORCPU);
+                w32ptr = (uint32_t *)ha->req_q[1]->req_ring.bp;
+                for (cnt = 0; cnt < fw->req_q_size[1] / 4; cnt++) {
+                        *dp = *w32ptr++;
+                        LITTLE_ENDIAN_32(dp);
+                        dp++;
+                }
+        }
+
+        /* Get the response queues */
+        for (index = 0; index < ha->rsp_queues_cnt; index++) {
+                (void) ddi_dma_sync(ha->rsp_queues[index]->rsp_ring.dma_handle,
+                    0, 0, DDI_DMA_SYNC_FORCPU);
+                w32ptr = (uint32_t *)ha->rsp_queues[index]->rsp_ring.bp;
+                for (cnt = 0; cnt < ha->rsp_queues[index]->rsp_ring.size / 4;
+                    cnt++) {
+                        *dp = *w32ptr++;
+                        LITTLE_ENDIAN_32(dp);
+                        dp++;
+                }
+        }
+
+        /* Reset RISC. */
+        ql_reset_chip(ha);
+
+        /* Code RAM. */
+        rv = ql_read_risc_ram(ha, 0x20000, sizeof (fw->code_ram) / 4,
+            fw->code_ram);
+        if (rval == QL_SUCCESS) {
+                rval = rv;
+        }
+        rv = ql_read_risc_ram(ha, 0x100000,
+            ha->fw_ext_memory_size / 4, dp);
+        if (rval == QL_SUCCESS) {
+                rval = rv;
+        }
+
+        /* Get the extended trace buffer */
+        if (ha->fwexttracebuf.dma_handle != NULL) {
+                /* Sync DMA buffer. */
+                (void) ddi_dma_sync(ha->fwexttracebuf.dma_handle, 0,
+                    FWEXTSIZE, DDI_DMA_SYNC_FORCPU);
+
+                w32ptr = ha->fwexttracebuf.bp;
+                for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
+                        fw->ext_trace_buf[cnt] = *w32ptr++;
+                }
+        }
+
+        /* Get the FC event trace buffer */
+        if (ha->fwfcetracebuf.dma_handle != NULL) {
+                /* Sync DMA buffer. */
+                (void) ddi_dma_sync(ha->fwfcetracebuf.dma_handle, 0,
+                    FWFCESIZE, DDI_DMA_SYNC_FORCPU);
+
+                w32ptr = ha->fwfcetracebuf.bp;
+                for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
+                        fw->fce_trace_buf[cnt] = *w32ptr++;
+                }
+        }
+
+        if (rval != QL_SUCCESS) {
+                EL(ha, "failed, rval = %xh\n", rval);
+        } else {
+                /*EMPTY*/
+                QL_PRINT_10(ha, "done\n");
+        }
+        return (QL_SUCCESS);
+}
+
+/*
+ * ql_83xx_ascii_fw_dump
+ *      Converts ISP83xx firmware binary dump to ascii.
+ *
+ * Input:
+ *      ha = adapter state pointer.
+ *      bptr = buffer pointer.
+ *
+ * Returns:
+ *      Amount of data buffer used.
+ *
+ * Context:
+ *      Kernel context.
+ */
+static size_t
+ql_83xx_ascii_fw_dump(ql_adapter_state_t *ha, caddr_t bufp)
+{
+        uint32_t                cnt, cnt1, len, *dp, *dp2;
+        caddr_t                 bp = bufp;
+        ql_83xx_fw_dump_t       *fw = ha->ql_dump_ptr;
+
+        QL_PRINT_3(ha, "started\n");
+
+        if ((len = ha->risc_dump_size) == 0) {
+                QL_PRINT_10(ha, "no buffer\n");
+                return (0);
+        }
+        (void) snprintf(bp, len, "\nISP FW Version %d.%02d.%02d Attributes "
+            "%X\n", ha->fw_major_version, ha->fw_minor_version,
+            ha->fw_subminor_version, ha->fw_attributes);
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+
+        (void) snprintf(bp, len, "\nHCCR Register\n%08x\n", fw->hccr);
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+
+        (void) snprintf(bp, len, "\nR2H Status Register\n%08x\n",
+            fw->r2h_status);
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+
+        (void) snprintf(bp, len,
+            "\nAER Uncorrectable Error Status Register\n%08x\n", fw->aer_ues);
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+
+        (void) snprintf(bp, len, "\nHostRisc Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->hostrisc_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->hostrisc_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nPCIe Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->pcie_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->pcie_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        dp = fw->req_rsp_ext_mem;
+        for (cnt = 0; cnt < ha->rsp_queues_cnt; cnt++) {
+                (void) snprintf(bp, len, "\n\nQueue Pointers #%d:\n", cnt);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+                for (cnt1 = 0; cnt1 < 4; cnt1++) {
+                        (void) snprintf(bp, len, "%08x ", *dp++);
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nHost Interface Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->host_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->host_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nShadow Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->shadow_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->shadow_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nRISC IO Register\n%08x", fw->risc_io);
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+
+        (void) snprintf(bp, len, "\n\nMailbox Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) {
+                if (cnt % 16 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%04x ", fw->mailbox_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nXSEQ GP Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->xseq_gp_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->xseq_gp_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nXSEQ-0 Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->xseq_0_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->xseq_0_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nXSEQ-1 Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->xseq_1_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->xseq_1_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nXSEQ-2 Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->xseq_2_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->xseq_2_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nRSEQ GP Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->rseq_gp_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->rseq_gp_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nRSEQ-0 Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->rseq_0_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->rseq_0_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nRSEQ-1 Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->rseq_1_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->rseq_1_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nRSEQ-2 Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->rseq_2_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->rseq_2_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nRSEQ-3 Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->rseq_3_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->rseq_3_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nASEQ GP Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->aseq_gp_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->aseq_gp_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nASEQ-0 Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->aseq_0_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->aseq_0_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nASEQ-1 Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->aseq_1_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->aseq_1_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nASEQ-2 Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->aseq_2_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->aseq_2_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nASEQ-3 Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->aseq_3_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->aseq_3_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nCommand DMA Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->cmd_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->cmd_dma_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nRequest0 Queue DMA Channel Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->req0_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->req0_dma_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nResponse0 Queue DMA Channel Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->resp0_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->resp0_dma_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nRequest1 Queue DMA Channel Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->req1_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->req1_dma_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nXMT0 Data DMA Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->xmt0_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->xmt0_dma_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nXMT1 Data DMA Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->xmt1_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->xmt1_dma_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nXMT2 Data DMA Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->xmt2_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->xmt2_dma_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nXMT3 Data DMA Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->xmt3_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->xmt3_dma_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nXMT4 Data DMA Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->xmt4_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->xmt4_dma_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nXMT Data DMA Common Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->xmt_data_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->xmt_data_dma_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nRCV Thread 0 Data DMA Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->rcvt0_data_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->rcvt0_data_dma_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nRCV Thread 1 Data DMA Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->rcvt1_data_dma_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->rcvt1_data_dma_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nRISC GP Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->risc_gp_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->risc_gp_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nLMC Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->lmc_reg) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->lmc_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nFPM Hardware Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        cnt1 = (uint32_t)(sizeof (fw->fpm_hdw_reg));
+        for (cnt = 0; cnt < cnt1 / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->fpm_hdw_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nRQ0 Array Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        cnt1 = (uint32_t)(sizeof (fw->rq0_array_reg));
+        for (cnt = 0; cnt < cnt1 / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->rq0_array_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nRQ1 Array Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        cnt1 = (uint32_t)(sizeof (fw->rq1_array_reg));
+        for (cnt = 0; cnt < cnt1 / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->rq1_array_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nRP0 Array Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        cnt1 = (uint32_t)(sizeof (fw->rp0_array_reg));
+        for (cnt = 0; cnt < cnt1 / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->rp0_array_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nRP1 Array Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        cnt1 = (uint32_t)(sizeof (fw->rp1_array_reg));
+        for (cnt = 0; cnt < cnt1 / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->rp1_array_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nAT0 Array Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        cnt1 = (uint32_t)(sizeof (fw->ato_array_reg));
+        for (cnt = 0; cnt < cnt1 / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->ato_array_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nQueue Control Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        cnt1 = (uint32_t)(sizeof (fw->queue_control_reg));
+        for (cnt = 0; cnt < cnt1 / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->queue_control_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nFB Hardware Registers");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        cnt1 = (uint32_t)(sizeof (fw->fb_hdw_reg));
+        for (cnt = 0; cnt < cnt1 / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->fb_hdw_reg[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nCode RAM");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n%08x: ", cnt + 0x20000);
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", fw->code_ram[cnt]);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\nExternal Memory");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+        dp = (uint32_t *)((caddr_t)fw->req_rsp_ext_mem + fw->req_q_size[0] +
+            fw->req_q_size[1] + fw->rsp_q_size + (ha->rsp_queues_cnt * 16));
+        for (cnt = 0; cnt < ha->fw_ext_memory_size / 4; cnt++) {
+                if (cnt % 8 == 0) {
+                        (void) snprintf(bp, len, "\n%08x: ", cnt + 0x100000);
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+                (void) snprintf(bp, len, "%08x ", *dp++);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        (void) snprintf(bp, len, "\n\n[<==END] ISP Debug Dump");
+        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                return (strlen(bufp));
+        }
+
+        dp = fw->req_rsp_ext_mem + (ha->rsp_queues_cnt * 4);
+        for (cnt = 0; cnt < 2 && fw->req_q_size[cnt]; cnt++) {
+                dp2 = dp;
+                for (cnt1 = 0; cnt1 < fw->req_q_size[cnt] / 4; cnt1++) {
+                        if (*dp2++) {
                         break;
-                default:
-                        break; /* Don't care... */
                 }
+                }
+                if (cnt1 == fw->req_q_size[cnt] / 4) {
+                        dp = dp2;
+                        continue;
+                }
+                (void) snprintf(bp, len, "\n\nRequest Queue\nQueue %d:", cnt);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+                for (cnt1 = 0; cnt1 < fw->req_q_size[cnt] / 4; cnt1++) {
+                        if (cnt1 % 8 == 0) {
+                                (void) snprintf(bp, len, "\n%08x: ", cnt1);
+                                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                        return (strlen(bufp));
+                                }
+                        }
+                        (void) snprintf(bp, len, "%08x ", *dp++);
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+        }
+
+        for (cnt = 0; cnt < ha->rsp_queues_cnt; cnt++) {
+                dp2 = dp;
+                for (cnt1 = 0; cnt1 < ha->rsp_queues[cnt]->rsp_ring.size / 4;
+                    cnt1++) {
+                        if (*dp2++) {
                 break;
-        case MBA_IDC_TIME_EXTENDED:
-                QL_PRINT_10(CE_CONT, "(%d): MBA_IDC_TIME_EXTENDED="
-                    "%xh\n", ha->instance, ha->idc_mb[2]);
+                        }
+                }
+                if (cnt1 == ha->rsp_queues[cnt]->rsp_ring.size / 4) {
+                        dp = dp2;
+                        continue;
+                }
+                (void) snprintf(bp, len, "\n\nResponse Queue\nQueue %d:", cnt);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+                for (cnt1 = 0; cnt1 < ha->rsp_queues[cnt]->rsp_ring.size / 4;
+                    cnt1++) {
+                        if (cnt1 % 8 == 0) {
+                                (void) snprintf(bp, len, "\n%08x: ", cnt1);
+                                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                        return (strlen(bufp));
+                                }
+                        }
+                        (void) snprintf(bp, len, "%08x ", *dp++);
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+        }
+
+        if (ha->fwexttracebuf.dma_handle != NULL) {
+                uint32_t        cnt_b;
+                uint64_t        w64 = (uintptr_t)ha->fwexttracebuf.bp;
+
+                (void) snprintf(bp, len, "\n\nExtended Trace Buffer Memory");
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+                /* show data address as a byte address, data as long words */
+                for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
+                        cnt_b = cnt * 4;
+                        if (cnt_b % 32 == 0) {
+                                (void) snprintf(bp, len, "\n%08x: ",
+                                    (int)(w64 + cnt_b));
+                                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                        return (strlen(bufp));
+                                }
+                        }
+                        (void) snprintf(bp, len, "%08x ",
+                            fw->ext_trace_buf[cnt]);
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+        }
+
+        if (ha->fwfcetracebuf.dma_handle != NULL) {
+                uint32_t        cnt_b;
+                uint64_t        w64 = (uintptr_t)ha->fwfcetracebuf.bp;
+
+                (void) snprintf(bp, len, "\n\nFC Event Trace Buffer Memory");
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+                /* show data address as a byte address, data as long words */
+                for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
+                        cnt_b = cnt * 4;
+                        if (cnt_b % 32 == 0) {
+                                (void) snprintf(bp, len, "\n%08x: ",
+                                    (int)(w64 + cnt_b));
+                                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                        return (strlen(bufp));
+                                }
+                        }
+                        (void) snprintf(bp, len, "%08x ",
+                            fw->fce_trace_buf[cnt]);
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+        }
+
+        QL_PRINT_10(ha, "done=%xh\n", strlen(bufp));
+
+        return (strlen(bufp));
+}
+
+
+/*
+ * ql_str_ptr
+ *      Verifies buffer is not full
+ *
+ * Input:
+ *      ha:     adapter state pointer.
+ *      bp:     string buffer pointer
+ *      len:    buffer length
+ *
+ * Returns:
+ *      NULL = buffer full else adjusted buffer pointer
+ *
+ * Context:
+ *      Kernel context.
+ */
+/*ARGSUSED*/
+static caddr_t
+ql_str_ptr(ql_adapter_state_t *ha, caddr_t bp, uint32_t *len)
+{
+        uint32_t        i;
+
+        i = strlen(bp);
+        if (i > *len || !(*len -= i)) {
+                QL_PRINT_10(ha, "full buffer\n");
+                return (NULL);
+        }
+        return (bp += i);
+}
+
+/*
+ * ql_27xx_binary_fw_dump
+ *
+ * Input:
+ *      ha:     adapter state pointer.
+ *      dmp:    firmware dump pointer.
+ *
+ * Returns:
+ *      ql local function return status code.
+ *
+ * Context:
+ *      Interrupt or Kernel context, no mailbox commands allowed.
+ */
+static int
+ql_27xx_binary_fw_dump(ql_adapter_state_t *ha)
+{
+        ql_dmp_template_t       *template_buff;
+        int                     rval;
+        uint32_t                cnt, *dp, *bp, tsize;
+
+        QL_PRINT_10(ha, "started\n");
+
+        if (ha->dmp_template.dma_handle == NULL) {
+                rval = CFG_IST(ha, CFG_LOAD_FLASH_FW) ?
+                    ql_2700_get_flash_dmp_template(ha) :
+                    ql_2700_get_module_dmp_template(ha);
+                if (rval != QL_SUCCESS) {
+                        EL(ha, "no dump template, status=%xh\n", rval);
+                        return (QL_FUNCTION_PARAMETER_ERROR);
+                }
+        }
+        template_buff = ha->dmp_template.bp;
+        tsize = template_buff->hdr.size_of_template;
+
+        if (ha->md_capture_size == 0) {
+                ha->ql_dump_ptr = kmem_zalloc(tsize, KM_NOSLEEP);
+                if (ha->ql_dump_ptr == NULL) {
+                        QL_PRINT_10(ha, "done, failed alloc\n");
+                        return (QL_MEMORY_ALLOC_FAILED);
+                }
+                cnt = (uint32_t)(tsize / sizeof (uint32_t));
+                dp = (uint32_t *)ha->ql_dump_ptr;
+                bp = (uint32_t *)&template_buff->hdr;
+                while (cnt--) {
+                        *dp++ = ddi_get32(ha->dmp_template.acc_handle, bp++);
+                }
+                ha->md_capture_size = ql_2700_dmp_parse_template(ha,
+                    (ql_dt_hdr_t *)ha->ql_dump_ptr, NULL, 0);
+                kmem_free(ha->ql_dump_ptr, tsize);
+                ha->ql_dump_ptr = NULL;
+
+                if (ha->md_capture_size == 0) {
+                        return (QL_MEMORY_ALLOC_FAILED);
+                }
+
+                /*
+                 * Determine ascii dump file size
+                 * 2 ascii bytes per binary byte + a space and
+                 * a newline every 16 binary bytes
+                 */
+                ha->risc_dump_size = ha->md_capture_size << 1;
+                ha->risc_dump_size += ha->md_capture_size;
+                ha->risc_dump_size += ha->md_capture_size / 16 + 1;
+                QL_PRINT_10(ha, "md_capture_size=%xh, "
+                    "risc_dump_size=%xh\n", ha->md_capture_size,
+                    ha->risc_dump_size);
+        }
+
+        ha->ql_dump_ptr = kmem_zalloc(ha->md_capture_size, KM_NOSLEEP);
+        if (ha->ql_dump_ptr == NULL) {
+                QL_PRINT_10(ha, "done, failed alloc\n");
+                return (QL_MEMORY_ALLOC_FAILED);
+        }
+        ha->ql_dump_size = ha->md_capture_size;
+
+        /* Disable ISP interrupts. */
+        ql_disable_intr(ha);
+
+        cnt = (uint32_t)(tsize / sizeof (uint32_t));
+        dp = (uint32_t *)ha->ql_dump_ptr;
+        bp = (uint32_t *)&template_buff->hdr;
+        while (cnt--) {
+                *dp++ = ddi_get32(ha->dmp_template.acc_handle, bp++);
+        }
+
+        (void) ql_2700_dmp_parse_template(ha,
+            (ql_dt_hdr_t *)ha->ql_dump_ptr,
+            (uint8_t *)dp, ha->ql_dump_size);
+
+#ifdef _BIG_ENDIAN
+        cnt = (uint32_t)(tsize / sizeof (uint32_t));
+        dp = (uint32_t *)ha->ql_dump_ptr;
+        while (cnt--) {
+                ql_chg_endian((uint8_t *)dp, 4);
+                dp++;
+        }
+#endif
+        QL_PRINT_10(ha, "done\n");
+        return (QL_SUCCESS);
+}
+
+/*
+ * ql_27xx_ascii_fw_dump
+ *      Converts ISP27xx firmware binary dump to ascii.
+ *
+ * Input:
+ *      ha:     port info pointer.
+ *      bptr:   buffer pointer.
+ *
+ * Returns:
+ *      Amount of data buffer used.
+ *
+ * Context:
+ *      Kernel context.
+ */
+static size_t
+ql_27xx_ascii_fw_dump(ql_adapter_state_t *ha, caddr_t bufp)
+{
+        uint32_t        cnt, len, dsize;
+        uint8_t         *fw;
+        caddr_t         bp;
+
+        QL_PRINT_10(ha, "started\n");
+
+        if ((len = ha->risc_dump_size) == 0) {
+                QL_PRINT_10(ha, "no buffer\n");
+                return (0);
+        }
+
+        dsize = ha->ql_dump_size;
+        fw = (uint8_t *)ha->ql_dump_ptr;
+        bp = bufp;
+
+        QL_PRINT_10(ha, "fw_dump_buffer=%ph, fw_bin_dump_size=%xh\n",
+            (void *)ha->ql_dump_ptr, ha->ql_dump_size);
+
+        /*
+         * 2 ascii bytes per binary byte + a space and
+         * a newline every 16 binary bytes
+         */
+        cnt = 0;
+        while (cnt < dsize) {
+                (void) snprintf(bp, len, "%02x ", *fw++);
+                if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                        return (strlen(bufp));
+                }
+                if (++cnt % 16 == 0) {
+                        (void) snprintf(bp, len, "\n");
+                        if ((bp = ql_str_ptr(ha, bp, &len)) == NULL) {
+                                return (strlen(bufp));
+                        }
+                }
+        }
+        if (cnt % 16 != 0) {
+                (void) snprintf(bp, len, "\n");
+                bp = ql_str_ptr(ha, bp, &len);
+                if (bp == NULL) {
+                        return (strlen(bufp));
+                }
+        }
+
+        QL_PRINT_10(ha, "done=%xh\n", strlen(bufp));
+
+        return (strlen(bufp));
+}
+
+/* ******************************************************************* */
+/* ********************* Dump Template Functions ********************* */
+/* ******************************************************************* */
+
+/*
+ * ql_2700_get_module_dmp_template
+ *      Get dump template from firmware module
+ *
+ * Input:
+ *      ha:     adapter state pointer.
+ *
+ * Returns:
+ *      ql local function return status code.
+ *
+ * Context:
+ *      Kernel context.
+ */
+int
+ql_2700_get_module_dmp_template(ql_adapter_state_t *ha)
+{
+        int             rval;
+        uint32_t        word_count, cnt, *bp, *dp;
+
+        QL_PRINT_10(ha, "started\n");
+
+        if (ha->dmp_template.dma_handle != NULL) {
+                return (QL_SUCCESS);
+        }
+
+        if ((word_count = ha->risc_fw[2].length) == 0) {
+                EL(ha, "no dump template, length=0\n");
+                return (QL_FUNCTION_PARAMETER_ERROR);
+        }
+
+        /* Allocate template buffer. */
+        ha->dmp_template.size = word_count << 2;
+        ha->dmp_template.type = LITTLE_ENDIAN_DMA;
+        ha->dmp_template.max_cookie_count = 1;
+        ha->dmp_template.alignment = 8;
+        rval = ql_alloc_phys(ha, &ha->dmp_template, KM_SLEEP);
+        if (rval != QL_SUCCESS) {
+                EL(ha, "unable to allocate template buffer, "
+                    "status=%xh\n", rval);
+                return (rval);
+        }
+
+        /* Get big endian template. */
+        bp = ha->dmp_template.bp;
+        dp = (uint32_t *)ha->risc_fw[2].code;
+        for (cnt = 0; cnt < word_count; cnt++) {
+                ddi_put32(ha->dmp_template.acc_handle, bp, *dp++);
+                if (cnt > 6) {
+                        ql_chg_endian((uint8_t *)bp, 4);
+                }
+                bp++;
+        }
+
+        QL_PRINT_10(ha, "done\n");
+        return (rval);
+}
+
+/*
+ * ql_2700_get_flash_dmp_template
+ *      Get dump template from flash
+ *
+ * Input:
+ *      pi:     port info pointer.
+ *
+ * Returns:
+ *      ql local function return status code.
+ *
+ * Context:
+ *      Kernel context.
+ */
+int
+ql_2700_get_flash_dmp_template(ql_adapter_state_t *ha)
+{
+        int             rval;
+        uint32_t        word_count, cnt, *bp;
+        uint32_t        faddr = ha->flash_data_addr | ha->flash_fw_addr;
+        uint32_t        fdata = 0;
+
+        QL_PRINT_10(ha, "started, fw_addr=%xh\n", ha->flash_fw_addr);
+
+        if (ha->dmp_template.dma_handle != NULL) {
+                ql_free_phys(ha, &ha->dmp_template);
+        }
+
+        /* First array length */
+        rval = ql_24xx_read_flash(ha, faddr + 3, &fdata);
+        QL_PRINT_7(ha, "read_flash, fw_addr=0x%x, data=0x%x\n",
+            faddr + 3, fdata);
+        if (rval != QL_SUCCESS) {
+                EL(ha, "2700_read_flash status=%xh\n", rval);
+                return (rval);
+        }
+        if (fdata == 0 || fdata == 0xffffffff) {
+                EL(ha, "Invalid first array length = %xh\n", fdata);
+                return (QL_FUNCTION_PARAMETER_ERROR);
+        }
+        ql_chg_endian((uint8_t *)&fdata, 4);
+        QL_PRINT_7(ha, "First array length = %xh\n", fdata);
+        faddr += fdata;
+
+        /* Second array length */
+        rval = ql_24xx_read_flash(ha, faddr + 3, &fdata);
+        QL_PRINT_7(ha, "read_flash, fw_addr=0x%x, data=0x%x\n",
+            faddr + 3, fdata);
+        if (rval != QL_SUCCESS) {
+                EL(ha, "2700_read_flash status=%xh\n", rval);
+                return (rval);
+        }
+        if (fdata == 0 || fdata == 0xffffffff) {
+                EL(ha, "Invalid second array length = %xh\n", fdata);
+                return (QL_FUNCTION_PARAMETER_ERROR);
+        }
+        ql_chg_endian((uint8_t *)&fdata, 4);
+        QL_PRINT_7(ha, "Second array length = %xh\n", fdata);
+        faddr += fdata;
+
+        /* Third array length (dump template) */
+        rval = ql_24xx_read_flash(ha, faddr + 2, &fdata);
+        QL_PRINT_7(ha, "read_flash, fw_addr=0x%x, data=0x%x\n",
+            faddr + 2, fdata);
+        if (rval != QL_SUCCESS) {
+                EL(ha, "2700_read_flash status=%xh\n", rval);
+                return (rval);
+        }
+        if (fdata == 0 || fdata == 0xffffffff) {
+                EL(ha, "Invalid third array length = %xh\n", fdata);
+                return (QL_FUNCTION_PARAMETER_ERROR);
+        }
+        ql_chg_endian((uint8_t *)&fdata, 4);
+        QL_PRINT_7(ha, "Third array length = %xh\n", fdata);
+        word_count = fdata;
+
+        /* Allocate template buffer. */
+        ha->dmp_template.size = word_count << 2;
+        ha->dmp_template.type = LITTLE_ENDIAN_DMA;
+        ha->dmp_template.max_cookie_count = 1;
+        ha->dmp_template.alignment = 8;
+        rval = ql_alloc_phys(ha, &ha->dmp_template, KM_SLEEP);
+        if (rval != QL_SUCCESS) {
+                EL(ha, "unable to allocate template buffer, "
+                    "status=%xh\n", rval);
+                return (rval);
+        }
+
+        /* Get big endian template. */
+        bp = ha->dmp_template.bp;
+        for (cnt = 0; cnt < word_count; cnt++) {
+                rval = ql_24xx_read_flash(ha, faddr++, &fdata);
+                if (rval != QL_SUCCESS) {
+                        EL(ha, "2700_read_flash status=%xh\n", rval);
+                        ql_free_phys(ha, &ha->dmp_template);
+                        return (rval);
+                }
+                ddi_put32(ha->dmp_template.acc_handle, bp, fdata);
+                bp++;
+        }
+
+        QL_PRINT_10(ha, "done\n");
+        return (rval);
+}
+
+static uint32_t
+ql_2700_dmp_parse_template(ql_adapter_state_t *ha, ql_dt_hdr_t *template_hdr,
+    uint8_t *dump_buff, uint32_t buff_size)
+{
+        int             e_cnt, esize, num_of_entries;
+        uint32_t        bsize;
+        time_t          time;
+        uint8_t         *dbuff, *dbuff_end;
+        ql_dt_entry_t   *entry;
+        int             sane_end = 0;
+
+        dbuff = dump_buff;      /* dbuff = NULL size determination. */
+        dbuff_end = dump_buff + buff_size;
+
+        template_hdr->ver_attr[0] = ha->fw_major_version;
+        template_hdr->ver_attr[1] = ha->fw_minor_version;
+        template_hdr->ver_attr[2] = ha->fw_subminor_version;
+        template_hdr->ver_attr[3] = ha->fw_attributes;
+        template_hdr->ver_attr[4] = ha->fw_ext_attributes;
+
+        QL_PRINT_7(ha, "started, template_hdr=%ph, dump_buff=%ph, "
+            "buff_size=%xh, buff_end=%ph\n", (void *)template_hdr,
+            (void *)dbuff, buff_size, (void *)dbuff_end);
+
+        /* Setup parameters */
+        QL_PRINT_7(ha, "type=%d, first_entry_offset=%xh, "
+            "num_of_entries=%xh ver_attr=%xh,%xh,%xh,%xh,%xh\n",
+            template_hdr->type, template_hdr->first_entry_offset,
+            template_hdr->num_of_entries, template_hdr->ver_attr[0],
+            template_hdr->ver_attr[1], template_hdr->ver_attr[2],
+            template_hdr->ver_attr[3], template_hdr->ver_attr[4]);
+
+        if (template_hdr->type != DT_THDR) {
+                EL(ha, "Template header not found\n");
+                return (0);
+        }
+        if (dbuff != NULL) {
+                (void) drv_getparm(TIME, &time);
+                template_hdr->driver_timestamp = LSD(time);
+        }
+
+        num_of_entries = template_hdr->num_of_entries;
+        entry = (ql_dt_entry_t *)((caddr_t)template_hdr +
+            template_hdr->first_entry_offset);
+
+        bsize = template_hdr->size_of_template;
+        for (e_cnt = 0; e_cnt < num_of_entries; e_cnt++) {
+                QL_PRINT_7(ha, "e_cnt=%xh, entry=%ph, type=%d, size=%xh, "
+                    "capture_flags=%xh, driver_flags=%xh, bofst=%xh\n",
+                    e_cnt, (void *)entry, entry->h.type, entry->h.size,
+                    entry->h.capture_flags, entry->h.driver_flags,
+                    dbuff != NULL ? (uintptr_t)dbuff - (uintptr_t)template_hdr :
+                    bsize);
+                /*
+                 * Decode the entry type and process it accordingly
+                 */
+                esize = 0;
+                switch (entry->h.type) {
+                case DT_NOP:
+                        if (dbuff != NULL) {
+                                entry->h.driver_flags = (uint8_t)
+                                    (entry->h.driver_flags | SKIPPED_FLAG);
+                        }
+                        QL_PRINT_3(ha, "Skipping Entry ID=%d, type=%d\n",
+                            e_cnt, entry->h.type);
                 break;
+                case DT_TEND:
+                        if (dbuff != NULL) {
+                                entry->h.driver_flags = (uint8_t)
+                                    (entry->h.driver_flags | SKIPPED_FLAG);
+                        }
+                        QL_PRINT_3(ha, "Skipping Entry ID=%d, type=%d\n",
+                            e_cnt, entry->h.type);
+                        sane_end++;
+                        break;
+                case DT_RIOB1:
+                        esize = ql_2700_dt_riob1(ha, (ql_dt_riob1_t *)entry,
+                            dbuff, dbuff_end);
+                        break;
+                case DT_WIOB1:
+                        ql_2700_dt_wiob1(ha, (ql_dt_wiob1_t *)entry,
+                            dbuff, dbuff_end);
+                        break;
+                case DT_RIOB2:
+                        esize = ql_2700_dt_riob2(ha, (ql_dt_riob2_t *)entry,
+                            dbuff, dbuff_end);
+                        break;
+                case DT_WIOB2:
+                        ql_2700_dt_wiob2(ha, (ql_dt_wiob2_t *)entry,
+                            dbuff, dbuff_end);
+                        break;
+                case DT_RPCI:
+                        esize = ql_2700_dt_rpci(ha, (ql_dt_rpci_t *)entry,
+                            dbuff, dbuff_end);
+                        break;
+                case DT_WPCI:
+                        ql_2700_dt_wpci(ha, (ql_dt_wpci_t *)entry,
+                            dbuff, dbuff_end);
+                        break;
+                case DT_RRAM:
+                        esize = ql_2700_dt_rram(ha, (ql_dt_rram_t *)entry,
+                            dbuff, dbuff_end);
+                        break;
+                case DT_GQUE:
+                        esize = ql_2700_dt_gque(ha, (ql_dt_gque_t *)entry,
+                            dbuff, dbuff_end);
+                        break;
+                case DT_GFCE:
+                        esize = ql_2700_dt_gfce(ha, (ql_dt_gfce_t *)entry,
+                            dbuff, dbuff_end);
+                        break;
+                case DT_PRISC:
+                        ql_2700_dt_prisc(ha, (ql_dt_prisc_t *)entry,
+                            dbuff, dbuff_end);
+                        break;
+                case DT_RRISC:
+                        ql_2700_dt_rrisc(ha, (ql_dt_rrisc_t *)entry,
+                            dbuff, dbuff_end);
+                        break;
+                case DT_DINT:
+                        ql_2700_dt_dint(ha, (ql_dt_dint_t *)entry,
+                            dbuff, dbuff_end);
+                        break;
+                case DT_GHBD:
+                        esize = ql_2700_dt_ghbd(ha, (ql_dt_ghbd_t *)entry,
+                            dbuff, dbuff_end);
+                        break;
+                case DT_SCRA:
+                        esize = ql_2700_dt_scra(ha, (ql_dt_scra_t *)entry,
+                            dbuff, dbuff_end);
+                        break;
+                case DT_RRREG:
+                        esize = ql_2700_dt_rrreg(ha, (ql_dt_rrreg_t *)entry,
+                            dbuff, dbuff_end);
+                        break;
+                case DT_WRREG:
+                        ql_2700_dt_wrreg(ha, (ql_dt_wrreg_t *)entry,
+                            dbuff, dbuff_end);
+                        break;
+                case DT_RRRAM:
+                        esize = ql_2700_dt_rrram(ha, (ql_dt_rrram_t *)entry,
+                            dbuff, dbuff_end);
+                        break;
+                case DT_RPCIC:
+                        esize = ql_2700_dt_rpcic(ha, (ql_dt_rpcic_t *)entry,
+                            dbuff, dbuff_end);
+                        break;
+                case DT_GQUES:
+                        esize = ql_2700_dt_gques(ha, (ql_dt_gques_t *)entry,
+                            dbuff, dbuff_end);
+                        break;
+                case DT_WDMP:
+                        esize = ql_2700_dt_wdmp(ha, (ql_dt_wdmp_t *)entry,
+                            dbuff, dbuff_end);
+                        break;
         default:
-                EL(ha, "Inconsistent IDC event =%xh %xh\n", ha->idc_mb[0],
-                    ha->idc_mb[2]);
+                        entry->h.driver_flags = (uint8_t)
+                            (entry->h.driver_flags | SKIPPED_FLAG);
+                        EL(ha, "Entry ID=%d, type=%d unknown\n", e_cnt,
+                            entry->h.type);
+                        break;
+                }
+                if (dbuff != NULL && esize) {
+                        QL_PRINT_7(ha, "entry=%d, esize=%xh, capture data\n",
+                            entry->h.type, esize);
+                        QL_DUMP_3(dbuff, 8, esize);
+                        dbuff += esize;
+                }
+                bsize += esize;
+                /* next entry in the template */
+                entry = (ql_dt_entry_t *)((caddr_t)entry + entry->h.size);
+        }
+        if (sane_end > 1) {
+                EL(ha, "Template configuration error. Check Template\n");
+        }
+
+        QL_PRINT_7(ha, "done, num of entries=%xh, size=%xh\n",
+            template_hdr->num_of_entries, bsize);
+        return (bsize);
+}
+
+static int
+ql_2700_dt_riob1(ql_adapter_state_t *ha, ql_dt_riob1_t *entry,
+    uint8_t *dbuff, uint8_t *dbuff_end)
+{
+        int             esize;
+        uint32_t        i, cnt;
+        uint8_t         *bp = dbuff;
+        uint32_t        addr = entry->addr;
+        uint8_t         *reg = (uint8_t *)ha->iobase + entry->pci_offset;
+
+        QL_PRINT_7(ha, "started, buf=%ph, addr=%xh, reg_size=%xh, "
+            "reg_count=%x%02xh, pci_offset=%xh\n", (void *)dbuff, entry->addr,
+            entry->reg_size, entry->reg_count_h, entry->reg_count_l,
+            entry->pci_offset);
+
+        cnt = CHAR_TO_SHORT(entry->reg_count_l, entry->reg_count_h);
+        esize = cnt * 4;                /* addr */
+        esize += cnt * entry->reg_size; /* data */
+
+        if (dbuff == NULL) {
+                QL_PRINT_7(ha, "null buf done, esize=%xh\n", esize);
+                return (esize);
+        }
+        if (esize + dbuff >= dbuff_end) {
+                EL(ha, "skipped, no buffer space, needed=%xh\n", esize);
+                entry->h.driver_flags = (uint8_t)
+                    (entry->h.driver_flags | SKIPPED_FLAG);
+                return (0);
+        }
+
+        WRT32_IO_REG(ha, io_base_addr, addr);
+        while (cnt--) {
+                *bp++ = LSB(LSW(addr));
+                *bp++ = MSB(LSW(addr));
+                *bp++ = LSB(MSW(addr));
+                *bp++ = MSB(MSW(addr));
+                for (i = 0; i < entry->reg_size; i++) {
+                        *bp++ = RD_REG_BYTE(ha, reg++);
+                }
+                addr++;
+        }
+
+        QL_PRINT_7(ha, "done, esize=%xh\n", esize);
+        return (esize);
+}
+
+static void
+ql_2700_dt_wiob1(ql_adapter_state_t *ha, ql_dt_wiob1_t *entry,
+    uint8_t *dbuff, uint8_t *dbuff_end)
+{
+        uint8_t *reg = (uint8_t *)ha->iobase + entry->pci_offset;
+
+        QL_PRINT_7(ha, "started, addr=%xh, data=%xh, pci_offset=%xh\n",
+            entry->addr, entry->data, entry->pci_offset);
+
+        if (dbuff == NULL) {
+                QL_PRINT_7(ha, "null buf done\n");
+                return;
+        }
+        if (dbuff >= dbuff_end) {
+                EL(ha, "skipped, no buffer space, needed=0\n");
+                entry->h.driver_flags = (uint8_t)
+                    (entry->h.driver_flags | SKIPPED_FLAG);
+                return;
+        }
+
+        WRT32_IO_REG(ha, io_base_addr, entry->addr);
+        WRT_REG_DWORD(ha, reg, entry->data);
+
+        QL_PRINT_7(ha, "done\n");
+}
+
+static int
+ql_2700_dt_riob2(ql_adapter_state_t *ha, ql_dt_riob2_t *entry,
+    uint8_t *dbuff, uint8_t *dbuff_end)
+{
+        int             esize;
+        uint32_t        i, cnt;
+        uint8_t         *bp = dbuff;
+        uint8_t         *reg = (uint8_t *)ha->iobase + entry->pci_offset;
+        uint32_t        addr = entry->addr;
+
+        QL_PRINT_7(ha, "started, buf=%ph, addr=%xh, reg_size=%xh, "
+            "reg_count=%x%02xh, pci_offset=%xh, bank_sel_offset=%xh, "
+            "reg_bank=%xh\n", (void *)dbuff, entry->addr,
+            entry->reg_size, entry->reg_count_h, entry->reg_count_l,
+            entry->pci_offset, entry->bank_sel_offset, entry->reg_bank);
+
+        cnt = CHAR_TO_SHORT(entry->reg_count_l, entry->reg_count_h);
+        esize = cnt * 4;                /* addr */
+        esize += cnt * entry->reg_size; /* data */
+
+        if (dbuff == NULL) {
+                QL_PRINT_7(ha, "null buf done, esize=%xh\n", esize);
+                return (esize);
+        }
+        if (esize + dbuff >= dbuff_end) {
+                EL(ha, "skipped, no buffer space, needed=%xh\n", esize);
+                entry->h.driver_flags = (uint8_t)
+                    (entry->h.driver_flags | SKIPPED_FLAG);
+                return (0);
+        }
+
+        WRT32_IO_REG(ha, io_base_addr, addr);
+        WRT_REG_DWORD(ha, ha->iobase + entry->bank_sel_offset, entry->reg_bank);
+        while (cnt--) {
+                *bp++ = LSB(LSW(addr));
+                *bp++ = MSB(LSW(addr));
+                *bp++ = LSB(MSW(addr));
+                *bp++ = MSB(MSW(addr));
+                for (i = 0; i < entry->reg_size; i++) {
+                        *bp++ = RD_REG_BYTE(ha, reg++);
+                }
+                addr++;
+        }
+
+        QL_PRINT_7(ha, "done, esize=%xh\n", esize);
+        return (esize);
+}
+
+static void
+ql_2700_dt_wiob2(ql_adapter_state_t *ha, ql_dt_wiob2_t *entry,
+    uint8_t *dbuff, uint8_t *dbuff_end)
+{
+        uint16_t        data;
+        uint8_t         *reg = (uint8_t *)ha->iobase + entry->pci_offset;
+
+        QL_PRINT_7(ha, "started, addr=%xh, data=%x%02xh, pci_offset=%xhh, "
+            "bank_sel_offset=%xh, reg_bank=%xh\n", entry->addr, entry->data_h,
+            entry->data_l, entry->pci_offset, entry->bank_sel_offset,
+            entry->reg_bank);
+
+        if (dbuff == NULL) {
+                QL_PRINT_7(ha, "null buf done\n");
+                return;
+        }
+        if (dbuff >= dbuff_end) {
+                EL(ha, "skipped, no buffer space, needed=0\n");
+                entry->h.driver_flags = (uint8_t)
+                    (entry->h.driver_flags | SKIPPED_FLAG);
+                return;
+        }
+
+        data = CHAR_TO_SHORT(entry->data_l, entry->data_h);
+
+        WRT32_IO_REG(ha, io_base_addr, entry->addr);
+        WRT_REG_DWORD(ha, ha->iobase + entry->bank_sel_offset, entry->reg_bank);
+        WRT_REG_WORD(ha, reg, data);
+
+        QL_PRINT_7(ha, "done\n");
+}
+
+static int
+ql_2700_dt_rpci(ql_adapter_state_t *ha, ql_dt_rpci_t *entry, uint8_t *dbuff,
+    uint8_t *dbuff_end)
+{
+        int             esize;
+        uint32_t        i;
+        uint8_t         *bp = dbuff;
+        uint8_t         *reg = (uint8_t *)ha->iobase + entry->addr;
+
+        QL_PRINT_7(ha, "started, addr=%xh, reg=%ph\n", entry->addr,
+            (void *)reg);
+
+        esize = 4;      /* addr */
+        esize += 4;     /* data */
+
+        if (dbuff == NULL) {
+                QL_PRINT_7(ha, "null buf done, esize=%xh\n", esize);
+                return (esize);
+        }
+        if (esize + dbuff >= dbuff_end) {
+                EL(ha, "skipped, no buffer space, needed=%xh\n", esize);
+                entry->h.driver_flags = (uint8_t)
+                    (entry->h.driver_flags | SKIPPED_FLAG);
+                return (0);
+        }
+
+        *bp++ = LSB(LSW(entry->addr));
+        *bp++ = MSB(LSW(entry->addr));
+        *bp++ = LSB(MSW(entry->addr));
+        *bp++ = MSB(MSW(entry->addr));
+        for (i = 0; i < 4; i++) {
+                *bp++ = RD_REG_BYTE(ha, reg++);
+        }
+
+        QL_PRINT_7(ha, "done, esize=%xh\n", esize);
+        return (esize);
+}
+
+static void
+ql_2700_dt_wpci(ql_adapter_state_t *ha, ql_dt_wpci_t *entry,
+    uint8_t *dbuff, uint8_t *dbuff_end)
+{
+        uint8_t *reg = (uint8_t *)ha->iobase + entry->addr;
+
+        QL_PRINT_7(ha, "started, addr=%xh, data=%xh, reg=%ph\n",
+            entry->addr, entry->data, (void *)reg);
+
+        if (dbuff == NULL) {
+                QL_PRINT_7(ha, "null buf done\n");
+                return;
+        }
+        if (dbuff >= dbuff_end) {
+                EL(ha, "skipped, no buffer space, needed=0\n");
+                entry->h.driver_flags = (uint8_t)
+                    (entry->h.driver_flags | SKIPPED_FLAG);
+                return;
+        }
+
+        WRT_REG_DWORD(ha, reg, entry->data);
+
+        QL_PRINT_7(ha, "done\n");
+}
+
+static int
+ql_2700_dt_rram(ql_adapter_state_t *ha, ql_dt_rram_t *entry,
+    uint8_t *dbuff, uint8_t *dbuff_end)
+{
+        int             esize, rval;
+        uint32_t        start = entry->start_addr;
+        uint32_t        end = entry->end_addr;
+
+        QL_PRINT_7(ha, "started, buf=%ph, ram_area=%xh, start_addr=%xh, "
+            "end_addr=%xh\n", (void *)dbuff, entry->ram_area,
+            entry->start_addr, entry->end_addr);
+
+        if (entry->ram_area == 2) {
+                end = ha->fw_ext_memory_end;
+        } else if (entry->ram_area == 3) {
+                start = ha->fw_shared_ram_start;
+                end = ha->fw_shared_ram_end;
+        } else if (entry->ram_area == 4) {
+                start = ha->fw_ddr_ram_start;
+                end = ha->fw_ddr_ram_end;
+        } else if (entry->ram_area != 1) {
+                EL(ha, "skipped, unknown RAM_AREA %d\n", entry->ram_area);
+                start = 0;
+                end = 0;
+        }
+        esize = end > start ? end - start : 0;
+        if (esize) {
+                esize = (esize + 1) * 4;
+        }
+
+        if (dbuff == NULL) {
+                QL_PRINT_7(ha, "null buf done, esize=%xh\n", esize);
+                return (esize);
+        }
+        if (esize == 0 || esize + dbuff >= dbuff_end) {
+                if (esize != 0) {
+                        EL(ha, "skipped, no buffer space, needed=%xh\n",
+                            esize);
+                } else {
+                        /*EMPTY*/
+                        QL_PRINT_7(ha, "skipped, no ram_area=%xh, start=%xh, "
+                            "end=%xh\n", entry->ram_area, start, end);
+                }
+                entry->h.driver_flags = (uint8_t)
+                    (entry->h.driver_flags | SKIPPED_FLAG);
+                return (0);
+        }
+        entry->end_addr = end;
+        entry->start_addr = start;
+
+        if ((rval = ql_2700_dump_ram(ha, MBC_DUMP_RAM_EXTENDED,
+            start, esize / 4, dbuff)) != QL_SUCCESS) {
+                EL(ha, "dump_ram failed, rval=%xh, addr=%xh, len=%xh, "
+                    "esize=0\n", rval, start, esize / 4);
+                return (0);
+        }
+
+        QL_PRINT_7(ha, "done, esize=%xh\n", esize);
+        return (esize);
+}
+
+static int
+ql_2700_dt_gque(ql_adapter_state_t *ha, ql_dt_gque_t *entry,
+    uint8_t *dbuff, uint8_t *dbuff_end)
+{
+        int             esize;
+        uint32_t        cnt, q_cnt, e_cnt, i;
+        uint8_t         *bp = dbuff, *dp;
+
+        QL_PRINT_7(ha, "started, buf=%ph, num_queues=%xh, queue_type=%xh\n",
+            (void *)dbuff, entry->num_queues, entry->queue_type);
+
+        if (entry->queue_type == 1) {
+                ql_request_q_t  *req_q;
+
+                e_cnt = ha->rsp_queues_cnt > 1 ? 2 : 1;
+                esize = e_cnt * 2;      /* queue number */
+                esize += e_cnt * 2;     /* queue entries */
+
+                /* queue size */
+                esize += ha->req_q[0]->req_entry_cnt * REQUEST_ENTRY_SIZE;
+                if (e_cnt > 1) {
+                        esize += ha->req_q[1]->req_entry_cnt *
+                            REQUEST_ENTRY_SIZE;
+                }
+
+                if (dbuff == NULL) {
+                        QL_PRINT_7(ha, "null buf done, esize=%xh\n", esize);
+                        return (esize);
+                }
+                if (esize + dbuff >= dbuff_end) {
+                        EL(ha, "skipped, no buffer space, needed=%xh\n", esize);
+                        entry->h.driver_flags = (uint8_t)
+                            (entry->h.driver_flags | SKIPPED_FLAG);
+                        return (0);
+                }
+                entry->num_queues = e_cnt;
+
+                for (q_cnt = 0; q_cnt < entry->num_queues; q_cnt++) {
+                        req_q = q_cnt == 0 ? ha->req_q[0] : ha->req_q[1];
+                        e_cnt = req_q->req_entry_cnt;
+                        dp = req_q->req_ring.bp;
+                        *bp++ = LSB(q_cnt);
+                        *bp++ = MSB(q_cnt);
+                        *bp++ = LSB(e_cnt);
+                        *bp++ = MSB(e_cnt);
+                        for (cnt = 0; cnt < e_cnt; cnt++) {
+                                for (i = 0; i < REQUEST_ENTRY_SIZE; i++) {
+                                        *bp++ = *dp++;
+                                }
+                        }
+                }
+        } else if (entry->queue_type == 2) {
+                ql_response_q_t *rsp_q;
+
+                e_cnt = ha->rsp_queues_cnt;
+                esize = e_cnt * 2;      /* queue number */
+                esize += e_cnt * 2;     /* queue entries */
+
+                /* queue size */
+                for (q_cnt = 0; q_cnt < ha->rsp_queues_cnt; q_cnt++) {
+                        rsp_q = ha->rsp_queues[q_cnt];
+                        esize += rsp_q->rsp_entry_cnt * RESPONSE_ENTRY_SIZE;
+                }
+
+                if (dbuff == NULL) {
+                        QL_PRINT_7(ha, "null buf done, esize=%xh\n", esize);
+                        return (esize);
+                }
+                if (esize + dbuff >= dbuff_end) {
+                        EL(ha, "skipped2, no buffer space, needed=%xh\n",
+                            esize);
+                        entry->h.driver_flags = (uint8_t)
+                            (entry->h.driver_flags | SKIPPED_FLAG);
+                        return (0);
+                }
+                entry->num_queues = e_cnt;
+
+                for (q_cnt = 0; q_cnt < entry->num_queues; q_cnt++) {
+                        rsp_q = ha->rsp_queues[q_cnt];
+                        e_cnt = rsp_q->rsp_entry_cnt;
+                        dp = rsp_q->rsp_ring.bp;
+                        *bp++ = LSB(q_cnt);
+                        *bp++ = MSB(q_cnt);
+                        *bp++ = LSB(e_cnt);
+                        *bp++ = MSB(e_cnt);
+                        for (cnt = 0; cnt < e_cnt; cnt++) {
+                                for (i = 0; i < RESPONSE_ENTRY_SIZE; i++) {
+                                        *bp++ = *dp++;
+                                }
+                        }
+                }
+        } else if (entry->queue_type == 3) {
+                QL_PRINT_7(ha, "skipped, no ATIO queue, esize=0\n");
+                if (dbuff != NULL) {
+                        entry->num_queues = 0;
+                        entry->h.driver_flags = (uint8_t)
+                            (entry->h.driver_flags | SKIPPED_FLAG);
+                }
+                return (0);
+        } else {
+                EL(ha, "skipped, unknown queue_type %d, esize=0\n",
+                    entry->queue_type);
+                if (dbuff != NULL) {
+                        entry->h.driver_flags = (uint8_t)
+                            (entry->h.driver_flags | SKIPPED_FLAG);
+                }
+                return (0);
+        }
+
+        QL_PRINT_7(ha, "done, esize=%xh\n", esize);
+        return (esize);
+}
+
+/*ARGSUSED*/
+static int
+ql_2700_dt_gfce(ql_adapter_state_t *ha, ql_dt_gfce_t *entry,
+    uint8_t *dbuff, uint8_t *dbuff_end)
+{
+        QL_PRINT_7(ha, "started\n");
+
+        QL_PRINT_7(ha, "skipped, not supported, esize=0\n");
+        if (dbuff != NULL) {
+                entry->h.driver_flags = (uint8_t)
+                    (entry->h.driver_flags | SKIPPED_FLAG);
+        }
+
+        return (0);
+}
+
+static void
+ql_2700_dt_prisc(ql_adapter_state_t *ha, ql_dt_prisc_t *entry,
+    uint8_t *dbuff, uint8_t *dbuff_end)
+{
+        clock_t timer;
+
+        QL_PRINT_7(ha, "started\n");
+
+        if (dbuff == NULL) {
+                QL_PRINT_7(ha, "null buf done\n");
+                return;
+        }
+        if (dbuff >= dbuff_end) {
+                EL(ha, "skipped, no buffer space, needed=0\n");
+                entry->h.driver_flags = (uint8_t)
+                    (entry->h.driver_flags | SKIPPED_FLAG);
+                return;
+        }
+
+        /* Pause RISC. */
+        if ((RD32_IO_REG(ha, risc2host) & RH_RISC_PAUSED) == 0) {
+                WRT32_IO_REG(ha, hccr, HC24_PAUSE_RISC);
+                for (timer = 30000;
+                    (RD32_IO_REG(ha, risc2host) & RH_RISC_PAUSED) == 0;
+                    timer--) {
+                        if (timer) {
+                                drv_usecwait(100);
+                                if (timer % 10000 == 0) {
+                                        EL(ha, "risc pause %d\n", timer);
+                                }
+                        } else {
+                                EL(ha, "risc pause timeout\n");
+                                break;
+                        }
+                }
+        }
+
+        QL_PRINT_7(ha, "done\n");
+}
+
+static void
+ql_2700_dt_rrisc(ql_adapter_state_t *ha, ql_dt_rrisc_t *entry,
+    uint8_t *dbuff, uint8_t *dbuff_end)
+{
+        clock_t timer;
+
+        QL_PRINT_7(ha, "started\n");
+
+        if (dbuff == NULL) {
+                QL_PRINT_7(ha, "null buf done\n");
+                return;
+        }
+        if (dbuff >= dbuff_end) {
+                EL(ha, "skipped, no buffer space, needed=0\n");
+                entry->h.driver_flags = (uint8_t)
+                    (entry->h.driver_flags | SKIPPED_FLAG);
+                return;
+        }
+
+        /* Shutdown DMA. */
+        WRT32_IO_REG(ha, ctrl_status, DMA_SHUTDOWN);
+
+        /* Wait for DMA to stop. */
+        for (timer = 0; timer < 30000; timer++) {
+                if (!(RD32_IO_REG(ha, ctrl_status) & DMA_ACTIVE)) {
+                        break;
+                }
+                drv_usecwait(100);
+        }
+
+        /* Reset the chip. */
+        WRT32_IO_REG(ha, ctrl_status, ISP_RESET);
+        drv_usecwait(200);
+
+        /* Wait for RISC to recover from reset. */
+        for (timer = 30000; timer; timer--) {
+                ha->rom_status = RD16_IO_REG(ha, mailbox_out[0]);
+                if ((ha->rom_status & MBS_ROM_STATUS_MASK) != MBS_ROM_BUSY) {
+                        break;
+                }
+                drv_usecwait(100);
+        }
+
+        /* Wait for reset to finish. */
+        for (timer = 30000; timer; timer--) {
+                if (!(RD32_IO_REG(ha, ctrl_status) & ISP_RESET)) {
+                        break;
+                }
+                drv_usecwait(100);
+        }
+
+        ADAPTER_STATE_LOCK(ha);
+        ha->flags &= ~FIRMWARE_UP;
                 ADAPTER_STATE_UNLOCK(ha);
+
+        QL_PRINT_7(ha, "done\n");
+}
+
+static void
+ql_2700_dt_dint(ql_adapter_state_t *ha, ql_dt_dint_t *entry,
+    uint8_t *dbuff, uint8_t *dbuff_end)
+{
+        QL_PRINT_7(ha, "started, pci_offset=%xh, data=%xh\n",
+            entry->pci_offset, entry->data);
+
+        if (dbuff == NULL) {
+                QL_PRINT_7(ha, "null buf done\n");
+                return;
+        }
+        if (dbuff >= dbuff_end) {
+                EL(ha, "skipped, no buffer space, needed=0\n");
+                entry->h.driver_flags = (uint8_t)
+                    (entry->h.driver_flags | SKIPPED_FLAG);
+                return;
+        }
+
+        ql_pci_config_put32(ha, entry->pci_offset, entry->data);
+
+        QL_PRINT_7(ha, "done\n");
+}
+
+/*ARGSUSED*/
+static int
+ql_2700_dt_ghbd(ql_adapter_state_t *ha, ql_dt_ghbd_t *entry,
+    uint8_t *dbuff, uint8_t *dbuff_end)
+{
+        QL_PRINT_7(ha, "started\n");
+
+        QL_PRINT_7(ha, "skipped, not supported\n");
+        if (dbuff != NULL) {
+                entry->h.driver_flags = (uint8_t)
+                    (entry->h.driver_flags | SKIPPED_FLAG);
+        }
+
+        return (0);
+}
+
+/*ARGSUSED*/
+static int
+ql_2700_dt_scra(ql_adapter_state_t *ha, ql_dt_scra_t *entry,
+    uint8_t *dbuff, uint8_t *dbuff_end)
+{
+        QL_PRINT_7(ha, "started\n");
+
+        QL_PRINT_7(ha, "skipped, not supported, esize=0\n");
+        if (dbuff != NULL) {
+                entry->h.driver_flags = (uint8_t)
+                    (entry->h.driver_flags | SKIPPED_FLAG);
+        }
+
+        return (0);
+}
+
+static int
+ql_2700_dt_rrreg(ql_adapter_state_t *ha, ql_dt_rrreg_t *entry,
+    uint8_t *dbuff, uint8_t *dbuff_end)
+{
+        int             esize;
+        uint32_t        i;
+        uint8_t         *bp = dbuff;
+        uint8_t         *reg = (uint8_t *)ha->iobase + 0xc4;
+        uint32_t        addr = entry->addr;
+        uint32_t        cnt = entry->count;
+
+        QL_PRINT_7(ha, "started, buf=%ph, addr=%xh, count=%xh\n",
+            (void *)dbuff, entry->addr, entry->count);
+
+        esize = cnt * 4;        /* addr */
+        esize += cnt * 4;       /* data */
+
+        if (dbuff == NULL) {
+                QL_PRINT_7(ha, "null buf done, esize=%xh\n", esize);
+                return (esize);
+        }
+        if (esize + dbuff >= dbuff_end) {
+                EL(ha, "skipped, no buffer space, needed=%xh\n", esize);
+                entry->h.driver_flags = (uint8_t)
+                    (entry->h.driver_flags | SKIPPED_FLAG);
+                return (0);
+        }
+
+        WRT32_IO_REG(ha, io_base_addr, 0x40);
+        while (cnt--) {
+                WRT_REG_DWORD(ha, ha->iobase + 0xc0, addr | 0x80000000);
+                *bp++ = LSB(LSW(addr));
+                *bp++ = MSB(LSW(addr));
+                *bp++ = LSB(MSW(addr));
+                *bp++ = MSB(MSW(addr));
+                for (i = 0; i < 4; i++) {
+                        *bp++ = RD_REG_BYTE(ha, reg + i);
+                }
+                addr += 4;
+        }
+
+        QL_PRINT_7(ha, "done, esize=%xh\n", esize);
+        return (esize);
+}
+
+static void
+ql_2700_dt_wrreg(ql_adapter_state_t *ha, ql_dt_wrreg_t *entry,
+    uint8_t *dbuff, uint8_t *dbuff_end)
+{
+        QL_PRINT_7(ha, "started, addr=%xh, data=%xh\n", entry->addr,
+            entry->data);
+
+        if (dbuff == NULL) {
+                QL_PRINT_7(ha, "null buf done\n");
+                return;
+        }
+        if (dbuff >= dbuff_end) {
+                EL(ha, "skipped, no buffer space, needed=0\n");
+                entry->h.driver_flags = (uint8_t)
+                    (entry->h.driver_flags | SKIPPED_FLAG);
+                return;
+        }
+
+        WRT32_IO_REG(ha, io_base_addr, 0x40);
+        WRT_REG_DWORD(ha, ha->iobase + 0xc4, entry->data);
+        WRT_REG_DWORD(ha, ha->iobase + 0xc0, entry->addr);
+
+        QL_PRINT_7(ha, "done\n");
+}
+
+static int
+ql_2700_dt_rrram(ql_adapter_state_t *ha, ql_dt_rrram_t *entry,
+    uint8_t *dbuff, uint8_t *dbuff_end)
+{
+        int     rval, esize;
+
+        QL_PRINT_7(ha, "started, buf=%ph, addr=%xh, count=%xh\n",
+            (void *)dbuff, entry->addr, entry->count);
+
+        esize = entry->count * 4;       /* data */
+
+        if (dbuff == NULL) {
+                QL_PRINT_7(ha, "null buf done, esize=%xh\n", esize);
+                return (esize);
+        }
+        if (esize + dbuff >= dbuff_end) {
+                EL(ha, "skipped, no buffer space, needed=%xh\n", esize);
+                entry->h.driver_flags = (uint8_t)
+                    (entry->h.driver_flags | SKIPPED_FLAG);
+                return (0);
+        }
+
+        if ((rval = ql_2700_dump_ram(ha, MBC_MPI_RAM, entry->addr,
+            entry->count, dbuff)) != QL_SUCCESS) {
+                EL(ha, "dump_ram failed, rval=%xh, addr=%xh, len=%xh, "
+                    "esize=0\n", rval, entry->addr, entry->count);
+                return (0);
+        }
+
+        QL_PRINT_7(ha, "done, esize=%xh\n", esize);
+        return (esize);
+}
+
+static int
+ql_2700_dt_rpcic(ql_adapter_state_t *ha, ql_dt_rpcic_t *entry,
+    uint8_t *dbuff, uint8_t *dbuff_end)
+{
+        int             esize;
+        uint32_t        i;
+        uint8_t         *bp = dbuff;
+        uint32_t        addr = entry->addr;
+        uint32_t        cnt = entry->count;
+
+        QL_PRINT_7(ha, "started, buf=%ph, addr=%xh, count=%xh\n",
+            (void *)dbuff, entry->addr, entry->count);
+
+        esize = cnt * 4;        /* addr */
+        esize += cnt * 4;       /* data */
+
+        if (dbuff == NULL) {
+                QL_PRINT_7(ha, "null buf done, esize=%xh\n", esize);
+                return (esize);
+        }
+        if (esize + dbuff >= dbuff_end) {
+                EL(ha, "skipped, no buffer space, needed=%xh\n", esize);
+                entry->h.driver_flags = (uint8_t)
+                    (entry->h.driver_flags | SKIPPED_FLAG);
+                return (0);
+        }
+
+        while (cnt--) {
+                *bp++ = LSB(LSW(addr));
+                *bp++ = MSB(LSW(addr));
+                *bp++ = LSB(MSW(addr));
+                *bp++ = MSB(MSW(addr));
+                for (i = 0; i < 4; i++) {
+                        *bp++ = ql_pci_config_get8(ha, addr++);
+                }
+        }
+
+        QL_PRINT_7(ha, "done, esize=%xh\n", esize);
+        return (esize);
+}
+
+static int
+ql_2700_dt_gques(ql_adapter_state_t *ha, ql_dt_gques_t *entry,
+    uint8_t *dbuff, uint8_t *dbuff_end)
+{
+        int             esize;
+        uint32_t        q_cnt, e_cnt, data;
+        uint8_t         *bp = dbuff;
+
+        QL_PRINT_7(ha, "started, buf=%ph, num_queues=%xh, queue_type=%xh\n",
+            (void *)dbuff, entry->num_queues, entry->queue_type);
+
+        if (entry->queue_type == 1) {
+                ql_request_q_t  *req_q;
+
+                e_cnt = ha->rsp_queues_cnt > 1 ? 2 : 1;
+                esize = e_cnt * 2;      /* queue number */
+                esize += e_cnt * 2;     /* shadow entries */
+
+                /* shadow size */
+                esize += SHADOW_ENTRY_SIZE;
+                if (e_cnt > 1) {
+                        esize += SHADOW_ENTRY_SIZE;
+                }
+                if (dbuff == NULL) {
+                        QL_PRINT_7(ha, "null buf done, esize=%xh\n", esize);
+                        return (esize);
+                }
+                if (esize + dbuff >= dbuff_end) {
+                        EL(ha, "skipped, no buffer space, needed=%xh\n", esize);
+                        entry->h.driver_flags = (uint8_t)
+                            (entry->h.driver_flags | SKIPPED_FLAG);
+                        return (0);
+                }
+                entry->num_queues = e_cnt;
+
+                for (q_cnt = 0; q_cnt < entry->num_queues; q_cnt++) {
+                        req_q = q_cnt == 0 ? ha->req_q[0] : ha->req_q[1];
+                        e_cnt = 1;
+                        data = ddi_get32(req_q->req_ring.acc_handle,
+                            req_q->req_out_shadow_ptr);
+                        *bp++ = LSB(q_cnt);
+                        *bp++ = MSB(q_cnt);
+                        *bp++ = LSB(e_cnt);
+                        *bp++ = MSB(e_cnt);
+                        *bp++ = LSB(LSW(data));
+                        *bp++ = MSB(LSW(data));
+                        *bp++ = LSB(MSW(data));
+                        *bp++ = MSB(MSW(data));
+                }
+        } else if (entry->queue_type == 2) {
+                ql_response_q_t *rsp_q;
+
+                e_cnt = ha->rsp_queues_cnt;
+                esize = e_cnt * 2;      /* queue number */
+                esize += e_cnt * 2;     /* shadow entries */
+
+                /* shadow size */
+                for (q_cnt = 0; q_cnt < ha->rsp_queues_cnt; q_cnt++) {
+                        esize += SHADOW_ENTRY_SIZE;
+                }
+
+                if (dbuff == NULL) {
+                        QL_PRINT_7(ha, "null buf done, esize=%xh\n", esize);
+                        return (esize);
+                }
+                if (esize + dbuff >= dbuff_end) {
+                        EL(ha, "skipped2, no buffer space, needed=%xh\n",
+                            esize);
+                        entry->h.driver_flags = (uint8_t)
+                            (entry->h.driver_flags | SKIPPED_FLAG);
+                        return (0);
+                }
+                entry->num_queues = e_cnt;
+
+                for (q_cnt = 0; q_cnt < entry->num_queues; q_cnt++) {
+                        rsp_q = ha->rsp_queues[q_cnt];
+                        e_cnt = 1;
+                        data = ddi_get32(rsp_q->rsp_ring.acc_handle,
+                            rsp_q->rsp_in_shadow_ptr);
+                        *bp++ = LSB(q_cnt);
+                        *bp++ = MSB(q_cnt);
+                        *bp++ = LSB(e_cnt);
+                        *bp++ = MSB(e_cnt);
+                        *bp++ = LSB(LSW(data));
+                        *bp++ = MSB(LSW(data));
+                        *bp++ = LSB(MSW(data));
+                        *bp++ = MSB(MSW(data));
+                }
+        } else if (entry->queue_type == 3) {
+                EL(ha, "skipped, no ATIO queue, esize=0\n");
+                if (dbuff != NULL) {
+                        entry->num_queues = 0;
+                        entry->h.driver_flags = (uint8_t)
+                            (entry->h.driver_flags | SKIPPED_FLAG);
+                }
+                return (0);
+        } else {
+                EL(ha, "skipped, unknown queue_type %d, esize=0\n",
+                    entry->queue_type);
+                if (dbuff != NULL) {
+                        entry->h.driver_flags = (uint8_t)
+                            (entry->h.driver_flags | SKIPPED_FLAG);
+                }
+                return (0);
+        }
+
+        QL_PRINT_7(ha, "done, esize=%xh\n", esize);
+        return (esize);
+}
+
+static int
+ql_2700_dt_wdmp(ql_adapter_state_t *ha, ql_dt_wdmp_t *entry,
+    uint8_t *dbuff, uint8_t *dbuff_end)
+{
+        int             esize;
+        uint8_t         *bp = dbuff;
+        uint32_t        data, cnt = entry->length, *dp = entry->data;
+
+        QL_PRINT_7(ha, "started, buf=%ph, length=%xh\n",
+            (void *)dbuff, entry->length);
+
+        esize = cnt;
+        if (dbuff == NULL) {
+                QL_PRINT_7(ha, "null buf done, esize=%xh\n", esize);
+                return (esize);
+        }
+        if (esize + dbuff >= dbuff_end) {
+                EL(ha, "skipped, no buffer space, needed=%xh\n", esize);
+                entry->h.driver_flags = (uint8_t)
+                    (entry->h.driver_flags | SKIPPED_FLAG);
+                return (0);
+        }
+
+        while (cnt--) {
+                data = *dp++;
+                *bp++ = LSB(LSW(data));
+                *bp++ = MSB(LSW(data));
+                *bp++ = LSB(MSW(data));
+                *bp++ = MSB(MSW(data));
+        }
+        QL_PRINT_7(ha, "%s\n", dbuff);
+
+        QL_PRINT_7(ha, "done, esize=%xh\n", esize);
+        return (esize);
+}
+
+/*
+ * ql_2700_dump_ram
+ *      Dumps RAM.
+ *      Risc interrupts must be disabled when this routine is called.
+ *
+ * Input:
+ *      ha:             adapter state pointer.
+ *      cmd:            MBC_DUMP_RAM_EXTENDED/MBC_MPI_RAM.
+ *      risc_address:   RISC code start address.
+ *      len:            Number of words.
+ *      bp:             buffer pointer.
+ *
+ * Returns:
+ *      ql local function return status code.
+ *
+ * Context:
+ *      Interrupt or Kernel context, no mailbox commands allowed.
+ */
+static int
+ql_2700_dump_ram(ql_adapter_state_t *ha, uint16_t cmd, uint32_t risc_address,
+    uint32_t len, uint8_t *bp)
+{
+        dma_mem_t       mem;
+        uint32_t        i, stat, timer;
+        uint8_t         *dp;
+        int             rval = QL_SUCCESS;
+
+        QL_PRINT_7(ha, "started, cmd=%xh, risc_address=%xh, len=%xh, "
+            "bp=%ph\n", cmd, risc_address, len, (void *)bp);
+
+        mem.size = len * 4;
+        mem.type = LITTLE_ENDIAN_DMA;
+        mem.max_cookie_count = 1;
+        mem.alignment = 8;
+        if ((rval = ql_alloc_phys(ha, &mem, KM_SLEEP)) != QL_SUCCESS) {
+                EL(ha, "alloc status=%xh\n", rval);
+                return (rval);
+        }
+
+        WRT16_IO_REG(ha, mailbox_in[0], cmd);
+        WRT16_IO_REG(ha, mailbox_in[1], LSW(risc_address));
+        WRT16_IO_REG(ha, mailbox_in[2], MSW(LSD(mem.cookie.dmac_laddress)));
+        WRT16_IO_REG(ha, mailbox_in[3], LSW(LSD(mem.cookie.dmac_laddress)));
+        WRT16_IO_REG(ha, mailbox_in[4], MSW(len));
+        WRT16_IO_REG(ha, mailbox_in[5], LSW(len));
+        WRT16_IO_REG(ha, mailbox_in[6], MSW(MSD(mem.cookie.dmac_laddress)));
+        WRT16_IO_REG(ha, mailbox_in[7], LSW(MSD(mem.cookie.dmac_laddress)));
+        WRT16_IO_REG(ha, mailbox_in[8], MSW(risc_address));
+        if (cmd == MBC_MPI_RAM) {
+                WRT16_IO_REG(ha, mailbox_in[9], BIT_0);
+        }
+
+        WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT);
+        for (timer = 6000000; timer && rval == QL_SUCCESS; timer--) {
+                stat = RD32_IO_REG(ha, risc2host);
+                if (stat & RH_RISC_INT) {
+                        stat &= 0xff;
+                        if ((stat == 1) || (stat == 0x10)) {
                 break;
+                        } else if ((stat == 2) || (stat == 0x11)) {
+                                rval = RD16_IO_REG(ha, mailbox_out[0]);
+                                break;
         }
+                        WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
+                }
+                drv_usecwait(5);
+        }
+        WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
+
+        if (timer == 0) {
+                QL_PRINT_7(ha, "timeout addr=%xh\n", risc_address);
+                rval = QL_FUNCTION_TIMEOUT;
+        } else {
+                (void) ddi_dma_sync(mem.dma_handle, 0, 0, DDI_DMA_SYNC_FORCPU);
+                dp = mem.bp;
+                for (i = 0; i < mem.size; i++) {
+                        *bp++ = *dp++;
+                }
+        }
+
+        ql_free_phys(ha, &mem);
+
+        QL_PRINT_7(ha, "done\n");
+        return (rval);
 }