Print this page
3178 Support for LSI 2208 chipset in mr_sas

@@ -1,18 +1,19 @@
 /*
  * mr_sas.c: source for mr_sas driver
  *
- * MegaRAID device driver for SAS2.0 controllers
- * Copyright (c) 2008-2010, LSI Logic Corporation.
+ * Solaris MegaRAID device driver for SAS2.0 controllers
+ * Copyright (c) 2008-2012, LSI Logic Corporation.
  * All rights reserved.
  *
  * Version:
  * Author:
+ *              Swaminathan K S
  *              Arun Chandrashekhar
  *              Manju R
- *              Rajesh Prabhakaran
- *              Seokmann Ju
+ *              Rasheed
+ *              Shakeel Bukhari
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
  *
  * 1. Redistributions of source code must retain the above copyright notice,

@@ -41,10 +42,11 @@
  */
 
 /*
  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2011 Bayard G. Bell. All rights reserved.
+ * Copyright 2012 Nexenta System, Inc. All rights reserved.
  */
 
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/file.h>

@@ -81,29 +83,149 @@
 /*
  * Local static data
  */
 static void     *mrsas_state = NULL;
 static volatile boolean_t       mrsas_relaxed_ordering = B_TRUE;
-static volatile int     debug_level_g = CL_NONE;
+volatile int    debug_level_g = CL_NONE;
 static volatile int     msi_enable = 1;
 static volatile int     ctio_enable = 1;
 
 /* Default Timeout value to issue online controller reset */
-static volatile int  debug_timeout_g  = 0xB4;
+volatile int  debug_timeout_g  = 0xF0;          /* 0xB4; */
 /* Simulate consecutive firmware fault */
 static volatile int  debug_fw_faults_after_ocr_g  = 0;
-
 #ifdef OCRDEBUG
 /* Simulate three consecutive timeout for an IO */
 static volatile int  debug_consecutive_timeout_after_ocr_g  = 0;
 #endif
 
 #pragma weak scsi_hba_open
 #pragma weak scsi_hba_close
 #pragma weak scsi_hba_ioctl
 
-static ddi_dma_attr_t mrsas_generic_dma_attr = {
+/* Local static prototypes. */
+static int      mrsas_getinfo(dev_info_t *, ddi_info_cmd_t,  void *, void **);
+static int      mrsas_attach(dev_info_t *, ddi_attach_cmd_t);
+#ifdef __sparc
+static int      mrsas_reset(dev_info_t *, ddi_reset_cmd_t);
+#else
+static int      mrsas_quiesce(dev_info_t *);
+#endif
+static int      mrsas_detach(dev_info_t *, ddi_detach_cmd_t);
+static int      mrsas_open(dev_t *, int, int, cred_t *);
+static int      mrsas_close(dev_t, int, int, cred_t *);
+static int      mrsas_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
+
+static int      mrsas_tran_tgt_init(dev_info_t *, dev_info_t *,
+                    scsi_hba_tran_t *, struct scsi_device *);
+static struct scsi_pkt *mrsas_tran_init_pkt(struct scsi_address *, register
+                    struct scsi_pkt *, struct buf *, int, int, int, int,
+                    int (*)(), caddr_t);
+static int      mrsas_tran_start(struct scsi_address *,
+                    register struct scsi_pkt *);
+static int      mrsas_tran_abort(struct scsi_address *, struct scsi_pkt *);
+static int      mrsas_tran_reset(struct scsi_address *, int);
+static int      mrsas_tran_getcap(struct scsi_address *, char *, int);
+static int      mrsas_tran_setcap(struct scsi_address *, char *, int, int);
+static void     mrsas_tran_destroy_pkt(struct scsi_address *,
+                    struct scsi_pkt *);
+static void     mrsas_tran_dmafree(struct scsi_address *, struct scsi_pkt *);
+static void     mrsas_tran_sync_pkt(struct scsi_address *, struct scsi_pkt *);
+static int      mrsas_tran_quiesce(dev_info_t *dip);
+static int      mrsas_tran_unquiesce(dev_info_t *dip);
+static uint_t   mrsas_isr();
+static uint_t   mrsas_softintr();
+static void     mrsas_undo_resources(dev_info_t *, struct mrsas_instance *);
+static struct mrsas_cmd *get_mfi_pkt(struct mrsas_instance *);
+static void     return_mfi_pkt(struct mrsas_instance *,
+                    struct mrsas_cmd *);
+
+static void     free_space_for_mfi(struct mrsas_instance *);
+static uint32_t read_fw_status_reg_ppc(struct mrsas_instance *);
+static void     issue_cmd_ppc(struct mrsas_cmd *, struct mrsas_instance *);
+static int      issue_cmd_in_poll_mode_ppc(struct mrsas_instance *,
+                    struct mrsas_cmd *);
+static int      issue_cmd_in_sync_mode_ppc(struct mrsas_instance *,
+                    struct mrsas_cmd *);
+static void     enable_intr_ppc(struct mrsas_instance *);
+static void     disable_intr_ppc(struct mrsas_instance *);
+static int      intr_ack_ppc(struct mrsas_instance *);
+static void     flush_cache(struct mrsas_instance *instance);
+void    display_scsi_inquiry(caddr_t);
+static int      start_mfi_aen(struct mrsas_instance *instance);
+static int      handle_drv_ioctl(struct mrsas_instance *instance,
+                    struct mrsas_ioctl *ioctl, int mode);
+static int      handle_mfi_ioctl(struct mrsas_instance *instance,
+                    struct mrsas_ioctl *ioctl, int mode);
+static int      handle_mfi_aen(struct mrsas_instance *instance,
+                    struct mrsas_aen *aen);
+static struct mrsas_cmd *build_cmd(struct mrsas_instance *,
+    struct scsi_address *, struct scsi_pkt *, uchar_t *);
+static int      alloc_additional_dma_buffer(struct mrsas_instance *);
+static void     complete_cmd_in_sync_mode(struct mrsas_instance *,
+                struct mrsas_cmd *);
+static int      mrsas_kill_adapter(struct mrsas_instance *);
+static int      mrsas_issue_init_mfi(struct mrsas_instance *);
+static int      mrsas_reset_ppc(struct mrsas_instance *);
+static uint32_t mrsas_initiate_ocr_if_fw_is_faulty(struct mrsas_instance *);
+static int      wait_for_outstanding(struct mrsas_instance *instance);
+static int      register_mfi_aen(struct mrsas_instance *instance,
+                    uint32_t seq_num, uint32_t class_locale_word);
+static int      issue_mfi_pthru(struct mrsas_instance *instance, struct
+                    mrsas_ioctl *ioctl, struct mrsas_cmd *cmd, int mode);
+static int      issue_mfi_dcmd(struct mrsas_instance *instance, struct
+                    mrsas_ioctl *ioctl, struct mrsas_cmd *cmd, int mode);
+static int      issue_mfi_smp(struct mrsas_instance *instance, struct
+                    mrsas_ioctl *ioctl, struct mrsas_cmd *cmd, int mode);
+static int      issue_mfi_stp(struct mrsas_instance *instance, struct
+                    mrsas_ioctl *ioctl, struct mrsas_cmd *cmd, int mode);
+static int      abort_aen_cmd(struct mrsas_instance *instance,
+                    struct mrsas_cmd *cmd_to_abort);
+
+static void     mrsas_rem_intrs(struct mrsas_instance *instance);
+static int      mrsas_add_intrs(struct mrsas_instance *instance, int intr_type);
+
+static void     mrsas_tran_tgt_free(dev_info_t *, dev_info_t *,
+                    scsi_hba_tran_t *, struct scsi_device *);
+static int      mrsas_tran_bus_config(dev_info_t *, uint_t,
+                    ddi_bus_config_op_t, void *, dev_info_t **);
+static int      mrsas_parse_devname(char *, int *, int *);
+static int      mrsas_config_all_devices(struct mrsas_instance *);
+static int      mrsas_config_ld(struct mrsas_instance *, uint16_t,
+                        uint8_t, dev_info_t **);
+static int      mrsas_name_node(dev_info_t *, char *, int);
+static void     mrsas_issue_evt_taskq(struct mrsas_eventinfo *);
+static void     free_additional_dma_buffer(struct mrsas_instance *);
+static void io_timeout_checker(void *);
+static void mrsas_fm_init(struct mrsas_instance *);
+static void mrsas_fm_fini(struct mrsas_instance *);
+
+static struct mrsas_function_template mrsas_function_template_ppc = {
+        .read_fw_status_reg = read_fw_status_reg_ppc,
+        .issue_cmd = issue_cmd_ppc,
+        .issue_cmd_in_sync_mode = issue_cmd_in_sync_mode_ppc,
+        .issue_cmd_in_poll_mode = issue_cmd_in_poll_mode_ppc,
+        .enable_intr = enable_intr_ppc,
+        .disable_intr = disable_intr_ppc,
+        .intr_ack = intr_ack_ppc,
+        .init_adapter = mrsas_init_adapter_ppc
+};
+
+
+static struct mrsas_function_template mrsas_function_template_fusion = {
+        .read_fw_status_reg = tbolt_read_fw_status_reg,
+        .issue_cmd = tbolt_issue_cmd,
+        .issue_cmd_in_sync_mode = tbolt_issue_cmd_in_sync_mode,
+        .issue_cmd_in_poll_mode = tbolt_issue_cmd_in_poll_mode,
+        .enable_intr = tbolt_enable_intr,
+        .disable_intr = tbolt_disable_intr,
+        .intr_ack = tbolt_intr_ack,
+        .init_adapter = mrsas_init_adapter_tbolt
+};
+
+
+ddi_dma_attr_t mrsas_generic_dma_attr = {
         DMA_ATTR_V0,            /* dma_attr_version */
         0,                      /* low DMA address range */
         0xFFFFFFFFU,            /* high DMA address range */
         0xFFFFFFFFU,            /* DMA counter register  */
         8,                      /* DMA address alignment */

@@ -117,10 +239,16 @@
 };
 
 int32_t mrsas_max_cap_maxxfer = 0x1000000;
 
 /*
+ * Fix for: Thunderbolt controller IO timeout when IO write size is 1MEG,
+ * Limit size to 256K
+ */
+uint32_t mrsas_tbolt_max_cap_maxxfer = (512 * 512);
+
+/*
  * cb_ops contains base level routines
  */
 static struct cb_ops mrsas_cb_ops = {
         mrsas_open,             /* open */
         mrsas_close,            /* close */

@@ -185,19 +313,33 @@
         DDI_STRUCTURE_LE_ACC,
         DDI_STRICTORDER_ACC,
         DDI_DEFAULT_ACC
 };
 
+/* Use the LSI Fast Path for the 2208 (tbolt) commands. */
+unsigned int enable_fp = 1;
 
+
 /*
  * ************************************************************************** *
  *                                                                            *
  *         common entry points - for loadable kernel modules                  *
  *                                                                            *
  * ************************************************************************** *
  */
 
+/*
+ * _init - initialize a loadable module
+ * @void
+ *
+ * The driver should perform any one-time resource allocation or data
+ * initialization during driver loading in _init(). For example, the driver
+ * should initialize any mutexes global to the driver in this routine.
+ * The driver should not, however, use _init() to allocate or initialize
+ * anything that has to do with a particular instance of the device.
+ * Per-instance initialization must be done in attach().
+ */
 int
 _init(void)
 {
         int ret;
 

@@ -205,52 +347,71 @@
 
         ret = ddi_soft_state_init(&mrsas_state,
             sizeof (struct mrsas_instance), 0);
 
         if (ret != DDI_SUCCESS) {
-                con_log(CL_ANN, (CE_WARN, "mr_sas: could not init state"));
+                cmn_err(CE_WARN, "mr_sas: could not init state");
                 return (ret);
         }
 
         if ((ret = scsi_hba_init(&modlinkage)) != DDI_SUCCESS) {
-                con_log(CL_ANN, (CE_WARN, "mr_sas: could not init scsi hba"));
+                cmn_err(CE_WARN, "mr_sas: could not init scsi hba");
                 ddi_soft_state_fini(&mrsas_state);
                 return (ret);
         }
 
         ret = mod_install(&modlinkage);
 
         if (ret != DDI_SUCCESS) {
-                con_log(CL_ANN, (CE_WARN, "mr_sas: mod_install failed"));
+                cmn_err(CE_WARN, "mr_sas: mod_install failed");
                 scsi_hba_fini(&modlinkage);
                 ddi_soft_state_fini(&mrsas_state);
         }
 
         return (ret);
 }
 
+/*
+ * _info - returns information about a loadable module.
+ * @void
+ *
+ * _info() is called to return module information. This is a typical entry
+ * point that does predefined role. It simply calls mod_info().
+ */
 int
 _info(struct modinfo *modinfop)
 {
         con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
 
         return (mod_info(&modlinkage, modinfop));
 }
 
+/*
+ * _fini - prepare a loadable module for unloading
+ * @void
+ *
+ * In _fini(), the driver should release any resources that were allocated in
+ * _init(). The driver must remove itself from the system module list.
+ */
 int
 _fini(void)
 {
         int ret;
 
         con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
 
-        if ((ret = mod_remove(&modlinkage)) != DDI_SUCCESS)
+        if ((ret = mod_remove(&modlinkage)) != DDI_SUCCESS) {
+                con_log(CL_ANN1,
+                    (CE_WARN, "_fini: mod_remove() failed, error 0x%X", ret));
                 return (ret);
+        }
 
         scsi_hba_fini(&modlinkage);
+        con_log(CL_DLEVEL1, (CE_NOTE, "_fini: scsi_hba_fini() done."));
 
         ddi_soft_state_fini(&mrsas_state);
+        con_log(CL_DLEVEL1, (CE_NOTE, "_fini: ddi_soft_state_fini() done."));
 
         return (ret);
 }
 
 

@@ -259,22 +420,39 @@
  *                                                                            *
  *               common entry points - for autoconfiguration                  *
  *                                                                            *
  * ************************************************************************** *
  */
-
+/*
+ * attach - adds a device to the system as part of initialization
+ * @dip:
+ * @cmd:
+ *
+ * The kernel calls a driver's attach() entry point to attach an instance of
+ * a device (for MegaRAID, it is instance of a controller) or to resume
+ * operation for an instance of a device that has been suspended or has been
+ * shut down by the power management framework
+ * The attach() entry point typically includes the following types of
+ * processing:
+ * - allocate a soft-state structure for the device instance (for MegaRAID,
+ *   controller instance)
+ * - initialize per-instance mutexes
+ * - initialize condition variables
+ * - register the device's interrupts (for MegaRAID, controller's interrupts)
+ * - map the registers and memory of the device instance (for MegaRAID,
+ *   controller instance)
+ * - create minor device nodes for the device instance (for MegaRAID,
+ *   controller instance)
+ * - report that the device instance (for MegaRAID, controller instance) has
+ *   attached
+ */
 static int
 mrsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
 {
         int             instance_no;
         int             nregs;
-        uint8_t         added_isr_f = 0;
-        uint8_t         added_soft_isr_f = 0;
-        uint8_t         create_devctl_node_f = 0;
-        uint8_t         create_scsi_node_f = 0;
-        uint8_t         create_ioc_node_f = 0;
-        uint8_t         tran_alloc_f = 0;
+        int             i = 0;
         uint8_t         irq;
         uint16_t        vendor_id;
         uint16_t        device_id;
         uint16_t        subsysvid;
         uint16_t        subsysid;

@@ -296,71 +474,56 @@
 
         /*
          * check to see whether this device is in a DMA-capable slot.
          */
         if (ddi_slaveonly(dip) == DDI_SUCCESS) {
-                con_log(CL_ANN, (CE_WARN,
+                cmn_err(CE_WARN,
                     "mr_sas%d: Device in slave-only slot, unused",
-                    instance_no));
+                    instance_no);
                 return (DDI_FAILURE);
         }
 
         switch (cmd) {
                 case DDI_ATTACH:
-                        con_log(CL_DLEVEL1, (CE_NOTE, "mr_sas: DDI_ATTACH"));
                         /* allocate the soft state for the instance */
                         if (ddi_soft_state_zalloc(mrsas_state, instance_no)
                             != DDI_SUCCESS) {
-                                con_log(CL_ANN, (CE_WARN,
+                        cmn_err(CE_WARN,
                                     "mr_sas%d: Failed to allocate soft state",
-                                    instance_no));
-
+                            instance_no);
                                 return (DDI_FAILURE);
                         }
 
                         instance = (struct mrsas_instance *)ddi_get_soft_state
                             (mrsas_state, instance_no);
 
                         if (instance == NULL) {
-                                con_log(CL_ANN, (CE_WARN,
-                                    "mr_sas%d: Bad soft state", instance_no));
-
+                        cmn_err(CE_WARN,
+                            "mr_sas%d: Bad soft state", instance_no);
                                 ddi_soft_state_free(mrsas_state, instance_no);
-
                                 return (DDI_FAILURE);
                         }
 
-                        bzero((caddr_t)instance,
-                            sizeof (struct mrsas_instance));
+                instance->unroll.softs  = 1;
 
-                        instance->func_ptr = kmem_zalloc(
-                            sizeof (struct mrsas_func_ptr), KM_SLEEP);
-                        ASSERT(instance->func_ptr);
-
                         /* Setup the PCI configuration space handles */
                         if (pci_config_setup(dip, &instance->pci_handle) !=
                             DDI_SUCCESS) {
-                                con_log(CL_ANN, (CE_WARN,
+                        cmn_err(CE_WARN,
                                     "mr_sas%d: pci config setup failed ",
-                                    instance_no));
+                            instance_no);
 
-                                kmem_free(instance->func_ptr,
-                                    sizeof (struct mrsas_func_ptr));
                                 ddi_soft_state_free(mrsas_state, instance_no);
-
                                 return (DDI_FAILURE);
                         }
 
                         if (ddi_dev_nregs(dip, &nregs) != DDI_SUCCESS) {
-                                con_log(CL_ANN, (CE_WARN,
-                                    "mr_sas: failed to get registers."));
+                        cmn_err(CE_WARN,
+                            "mr_sas: failed to get registers.");
 
                                 pci_config_teardown(&instance->pci_handle);
-                                kmem_free(instance->func_ptr,
-                                    sizeof (struct mrsas_func_ptr));
                                 ddi_soft_state_free(mrsas_state, instance_no);
-
                                 return (DDI_FAILURE);
                         }
 
                         vendor_id = pci_config_get16(instance->pci_handle,
                             PCI_CONF_VENID);

@@ -399,35 +562,36 @@
                                 con_log(CL_DLEVEL1, (CE_CONT, "mr_sas%d: "
                                 "bus-mastering already set", instance_no));
                         }
 
                         /* initialize function pointers */
-                        if ((device_id == PCI_DEVICE_ID_LSI_2108VDE) ||
-                            (device_id == PCI_DEVICE_ID_LSI_2108V)) {
-                                con_log(CL_DLEVEL1, (CE_CONT, "mr_sas%d: "
-                                    "2108V/DE detected", instance_no));
-                                instance->func_ptr->read_fw_status_reg =
-                                    read_fw_status_reg_ppc;
-                                instance->func_ptr->issue_cmd = issue_cmd_ppc;
-                                instance->func_ptr->issue_cmd_in_sync_mode =
-                                    issue_cmd_in_sync_mode_ppc;
-                                instance->func_ptr->issue_cmd_in_poll_mode =
-                                    issue_cmd_in_poll_mode_ppc;
-                                instance->func_ptr->enable_intr =
-                                    enable_intr_ppc;
-                                instance->func_ptr->disable_intr =
-                                    disable_intr_ppc;
-                                instance->func_ptr->intr_ack = intr_ack_ppc;
-                        } else {
-                                con_log(CL_ANN, (CE_WARN,
-                                    "mr_sas: Invalid device detected"));
+                switch (device_id) {
+                case PCI_DEVICE_ID_LSI_TBOLT:
+                case PCI_DEVICE_ID_LSI_INVADER:
+                        con_log(CL_ANN, (CE_NOTE,
+                            "mr_sas: 2208 T.B. device detected"));
 
+                        instance->func_ptr =
+                            &mrsas_function_template_fusion;
+                        instance->tbolt = 1;
+                        break;
+
+                case PCI_DEVICE_ID_LSI_2108VDE:
+                case PCI_DEVICE_ID_LSI_2108V:
+                        con_log(CL_ANN, (CE_NOTE,
+                            "mr_sas: 2108 Liberator device detected"));
+
+                        instance->func_ptr =
+                            &mrsas_function_template_ppc;
+                        break;
+
+                default:
+                        cmn_err(CE_WARN,
+                            "mr_sas: Invalid device detected");
+
                                 pci_config_teardown(&instance->pci_handle);
-                                kmem_free(instance->func_ptr,
-                                    sizeof (struct mrsas_func_ptr));
                                 ddi_soft_state_free(mrsas_state, instance_no);
-
                                 return (DDI_FAILURE);
                         }
 
                         instance->baseaddress = pci_config_get32(
                             instance->pci_handle, PCI_CONF_BASE0);

@@ -447,31 +611,33 @@
                             DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE
                             | DDI_FM_ERRCB_CAPABLE);
 
                         mrsas_fm_init(instance);
 
-                        /* Initialize Interrupts */
+                /* Setup register map */
                         if ((ddi_dev_regsize(instance->dip,
                             REGISTER_SET_IO_2108, &reglength) != DDI_SUCCESS) ||
                             reglength < MINIMUM_MFI_MEM_SZ) {
-                                return (DDI_FAILURE);
+                        goto fail_attach;
                         }
                         if (reglength > DEFAULT_MFI_MEM_SZ) {
                                 reglength = DEFAULT_MFI_MEM_SZ;
                                 con_log(CL_DLEVEL1, (CE_NOTE,
-                                    "mr_sas: register length to map is "
-                                    "0x%lx bytes", reglength));
+                            "mr_sas: register length to map is 0x%lx bytes",
+                            reglength));
                         }
                         if (ddi_regs_map_setup(instance->dip,
                             REGISTER_SET_IO_2108, &instance->regmap, 0,
                             reglength, &endian_attr, &instance->regmap_handle)
                             != DDI_SUCCESS) {
-                                con_log(CL_ANN, (CE_NOTE,
-                                    "mr_sas: couldn't map control registers"));
+                        cmn_err(CE_WARN,
+                            "mr_sas: couldn't map control registers");
                                 goto fail_attach;
                         }
 
+                instance->unroll.regs = 1;
+
                         /*
                          * Disable Interrupt Now.
                          * Setup Software interrupt
                          */
                         instance->func_ptr->disable_intr(instance);

@@ -479,156 +645,196 @@
                         if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0,
                             "mrsas-enable-msi", &data) == DDI_SUCCESS) {
                                 if (strncmp(data, "no", 3) == 0) {
                                         msi_enable = 0;
                                         con_log(CL_ANN1, (CE_WARN,
-                                            "msi_enable = %d disabled",
-                                            msi_enable));
+                                    "msi_enable = %d disabled", msi_enable));
                                 }
                                 ddi_prop_free(data);
                         }
 
-                        con_log(CL_DLEVEL1, (CE_WARN, "msi_enable = %d",
-                            msi_enable));
+                con_log(CL_DLEVEL1, (CE_NOTE, "msi_enable = %d", msi_enable));
 
+                if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0,
+                    "mrsas-enable-fp", &data) == DDI_SUCCESS) {
+                        if (strncmp(data, "no", 3) == 0) {
+                                enable_fp = 0;
+                                cmn_err(CE_NOTE,
+                                    "enable_fp = %d, Fast-Path disabled.\n",
+                                    enable_fp);
+                        }
+
+                        ddi_prop_free(data);
+                }
+
+                con_log(CL_DLEVEL1, (CE_NOTE, "enable_fp = %d\n", enable_fp));
+
                         /* Check for all supported interrupt types */
                         if (ddi_intr_get_supported_types(
                             dip, &intr_types) != DDI_SUCCESS) {
-                                con_log(CL_ANN, (CE_WARN,
-                                    "ddi_intr_get_supported_types() failed"));
+                        cmn_err(CE_WARN,
+                            "ddi_intr_get_supported_types() failed");
                                 goto fail_attach;
                         }
 
                         con_log(CL_DLEVEL1, (CE_NOTE,
-                            "ddi_intr_get_supported_types() ret: 0x%x",
-                            intr_types));
+                    "ddi_intr_get_supported_types() ret: 0x%x", intr_types));
 
                         /* Initialize and Setup Interrupt handler */
                         if (msi_enable && (intr_types & DDI_INTR_TYPE_MSIX)) {
-                                if (mrsas_add_intrs(instance,
-                                    DDI_INTR_TYPE_MSIX) != DDI_SUCCESS) {
-                                        con_log(CL_ANN, (CE_WARN,
-                                            "MSIX interrupt query failed"));
+                        if (mrsas_add_intrs(instance, DDI_INTR_TYPE_MSIX) !=
+                            DDI_SUCCESS) {
+                                cmn_err(CE_WARN,
+                                    "MSIX interrupt query failed");
                                         goto fail_attach;
                                 }
                                 instance->intr_type = DDI_INTR_TYPE_MSIX;
-                        } else if (msi_enable && (intr_types &
-                            DDI_INTR_TYPE_MSI)) {
-                                if (mrsas_add_intrs(instance,
-                                    DDI_INTR_TYPE_MSI) != DDI_SUCCESS) {
-                                        con_log(CL_ANN, (CE_WARN,
-                                            "MSI interrupt query failed"));
+                } else if (msi_enable && (intr_types & DDI_INTR_TYPE_MSI)) {
+                        if (mrsas_add_intrs(instance, DDI_INTR_TYPE_MSI) !=
+                            DDI_SUCCESS) {
+                                cmn_err(CE_WARN,
+                                    "MSI interrupt query failed");
                                         goto fail_attach;
                                 }
                                 instance->intr_type = DDI_INTR_TYPE_MSI;
                         } else if (intr_types & DDI_INTR_TYPE_FIXED) {
                                 msi_enable = 0;
-                                if (mrsas_add_intrs(instance,
-                                    DDI_INTR_TYPE_FIXED) != DDI_SUCCESS) {
-                                        con_log(CL_ANN, (CE_WARN,
-                                            "FIXED interrupt query failed"));
+                        if (mrsas_add_intrs(instance, DDI_INTR_TYPE_FIXED) !=
+                            DDI_SUCCESS) {
+                                cmn_err(CE_WARN,
+                                    "FIXED interrupt query failed");
                                         goto fail_attach;
                                 }
                                 instance->intr_type = DDI_INTR_TYPE_FIXED;
                         } else {
-                                con_log(CL_ANN, (CE_WARN, "Device cannot "
+                        cmn_err(CE_WARN, "Device cannot "
                                     "suppport either FIXED or MSI/X "
-                                    "interrupts"));
+                            "interrupts");
                                 goto fail_attach;
                         }
 
-                        added_isr_f = 1;
+                instance->unroll.intr = 1;
 
                         if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0,
                             "mrsas-enable-ctio", &data) == DDI_SUCCESS) {
                                 if (strncmp(data, "no", 3) == 0) {
                                         ctio_enable = 0;
                                         con_log(CL_ANN1, (CE_WARN,
-                                            "ctio_enable = %d disabled",
-                                            ctio_enable));
+                                    "ctio_enable = %d disabled", ctio_enable));
                                 }
                                 ddi_prop_free(data);
                         }
 
-                        con_log(CL_DLEVEL1, (CE_WARN, "ctio_enable = %d",
-                            ctio_enable));
+                con_log(CL_DLEVEL1, (CE_WARN, "ctio_enable = %d", ctio_enable));
 
                         /* setup the mfi based low level driver */
-                        if (init_mfi(instance) != DDI_SUCCESS) {
-                                con_log(CL_ANN, (CE_WARN, "mr_sas: "
-                                "could not initialize the low level driver"));
+                if (mrsas_init_adapter(instance) != DDI_SUCCESS) {
+                        cmn_err(CE_WARN, "mr_sas: "
+                            "could not initialize the low level driver");
 
                                 goto fail_attach;
                         }
 
                         /* Initialize all Mutex */
                         INIT_LIST_HEAD(&instance->completed_pool_list);
-                        mutex_init(&instance->completed_pool_mtx,
-                            "completed_pool_mtx", MUTEX_DRIVER,
-                            DDI_INTR_PRI(instance->intr_pri));
+                mutex_init(&instance->completed_pool_mtx, NULL,
+                    MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
 
-                        mutex_init(&instance->app_cmd_pool_mtx,
-                            "app_cmd_pool_mtx", MUTEX_DRIVER,
-                            DDI_INTR_PRI(instance->intr_pri));
+                mutex_init(&instance->sync_map_mtx, NULL,
+                    MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
 
-                        mutex_init(&instance->cmd_pend_mtx, "cmd_pend_mtx",
+                mutex_init(&instance->app_cmd_pool_mtx, NULL,
                             MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
 
-                        mutex_init(&instance->ocr_flags_mtx, "ocr_flags_mtx",
+                mutex_init(&instance->config_dev_mtx, NULL,
                             MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
 
-                        mutex_init(&instance->int_cmd_mtx, "int_cmd_mtx",
+                mutex_init(&instance->cmd_pend_mtx, NULL,
                             MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
+
+                mutex_init(&instance->ocr_flags_mtx, NULL,
+                    MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
+
+                mutex_init(&instance->int_cmd_mtx, NULL,
+                    MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
                         cv_init(&instance->int_cmd_cv, NULL, CV_DRIVER, NULL);
 
-                        mutex_init(&instance->cmd_pool_mtx, "cmd_pool_mtx",
+                mutex_init(&instance->cmd_pool_mtx, NULL,
                             MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
 
+                mutex_init(&instance->reg_write_mtx, NULL,
+                    MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
+
+                if (instance->tbolt) {
+                        mutex_init(&instance->cmd_app_pool_mtx, NULL,
+                            MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
+
+                        mutex_init(&instance->chip_mtx, NULL,
+                            MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
+
+                }
+
+                instance->unroll.mutexs = 1;
+
                         instance->timeout_id = (timeout_id_t)-1;
 
                         /* Register our soft-isr for highlevel interrupts. */
                         instance->isr_level = instance->intr_pri;
+                if (!(instance->tbolt)) {
                         if (instance->isr_level == HIGH_LEVEL_INTR) {
-                                if (ddi_add_softintr(dip, DDI_SOFTINT_HIGH,
+                                if (ddi_add_softintr(dip,
+                                    DDI_SOFTINT_HIGH,
                                     &instance->soft_intr_id, NULL, NULL,
                                     mrsas_softintr, (caddr_t)instance) !=
                                     DDI_SUCCESS) {
-                                        con_log(CL_ANN, (CE_WARN,
-                                            " Software ISR did not register"));
+                                        cmn_err(CE_WARN,
+                                            "Software ISR did not register");
 
                                         goto fail_attach;
                                 }
 
-                                added_soft_isr_f = 1;
+                                instance->unroll.soft_isr = 1;
+
                         }
+                }
 
+                instance->softint_running = 0;
+
                         /* Allocate a transport structure */
                         tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP);
 
                         if (tran == NULL) {
-                                con_log(CL_ANN, (CE_WARN,
-                                    "scsi_hba_tran_alloc failed"));
+                        cmn_err(CE_WARN,
+                            "scsi_hba_tran_alloc failed");
                                 goto fail_attach;
                         }
 
-                        tran_alloc_f = 1;
-
                         instance->tran = tran;
+                instance->unroll.tran = 1;
 
                         tran->tran_hba_private  = instance;
                         tran->tran_tgt_init     = mrsas_tran_tgt_init;
                         tran->tran_tgt_probe    = scsi_hba_probe;
                         tran->tran_tgt_free     = mrsas_tran_tgt_free;
+                if (instance->tbolt) {
+                        tran->tran_init_pkt     =
+                            mrsas_tbolt_tran_init_pkt;
+                        tran->tran_start        =
+                            mrsas_tbolt_tran_start;
+                } else {
                         tran->tran_init_pkt     = mrsas_tran_init_pkt;
                         tran->tran_start        = mrsas_tran_start;
+                }
                         tran->tran_abort        = mrsas_tran_abort;
                         tran->tran_reset        = mrsas_tran_reset;
                         tran->tran_getcap       = mrsas_tran_getcap;
                         tran->tran_setcap       = mrsas_tran_setcap;
                         tran->tran_destroy_pkt  = mrsas_tran_destroy_pkt;
                         tran->tran_dmafree      = mrsas_tran_dmafree;
                         tran->tran_sync_pkt     = mrsas_tran_sync_pkt;
+                tran->tran_quiesce      = mrsas_tran_quiesce;
+                tran->tran_unquiesce    = mrsas_tran_unquiesce;
                         tran->tran_bus_config   = mrsas_tran_bus_config;
 
                         if (mrsas_relaxed_ordering)
                                 mrsas_generic_dma_attr.dma_attr_flags |=
                                     DDI_DMA_RELAXED_ORDERING;

@@ -638,159 +844,173 @@
                         tran_dma_attr.dma_attr_sgllen = instance->max_num_sge;
 
                         /* Attach this instance of the hba */
                         if (scsi_hba_attach_setup(dip, &tran_dma_attr, tran, 0)
                             != DDI_SUCCESS) {
-                                con_log(CL_ANN, (CE_WARN,
-                                    "scsi_hba_attach failed"));
+                        cmn_err(CE_WARN,
+                            "scsi_hba_attach failed");
 
                                 goto fail_attach;
                         }
+                instance->unroll.tranSetup = 1;
+                con_log(CL_ANN1,
+                    (CE_CONT, "scsi_hba_attach_setup()  done."));
 
                         /* create devctl node for cfgadm command */
                         if (ddi_create_minor_node(dip, "devctl",
                             S_IFCHR, INST2DEVCTL(instance_no),
                             DDI_NT_SCSI_NEXUS, 0) == DDI_FAILURE) {
-                                con_log(CL_ANN, (CE_WARN,
-                                    "mr_sas: failed to create devctl node."));
+                        cmn_err(CE_WARN,
+                            "mr_sas: failed to create devctl node.");
 
                                 goto fail_attach;
                         }
 
-                        create_devctl_node_f = 1;
+                instance->unroll.devctl = 1;
 
                         /* create scsi node for cfgadm command */
                         if (ddi_create_minor_node(dip, "scsi", S_IFCHR,
-                            INST2SCSI(instance_no),
-                            DDI_NT_SCSI_ATTACHMENT_POINT, 0) ==
+                    INST2SCSI(instance_no), DDI_NT_SCSI_ATTACHMENT_POINT, 0) ==
                             DDI_FAILURE) {
-                                con_log(CL_ANN, (CE_WARN,
-                                    "mr_sas: failed to create scsi node."));
+                        cmn_err(CE_WARN,
+                            "mr_sas: failed to create scsi node.");
 
                                 goto fail_attach;
                         }
 
-                        create_scsi_node_f = 1;
+                instance->unroll.scsictl = 1;
 
                         (void) sprintf(instance->iocnode, "%d:lsirdctl",
                             instance_no);
 
                         /*
                          * Create a node for applications
                          * for issuing ioctl to the driver.
                          */
                         if (ddi_create_minor_node(dip, instance->iocnode,
-                            S_IFCHR, INST2LSIRDCTL(instance_no),
-                            DDI_PSEUDO, 0) == DDI_FAILURE) {
-                                con_log(CL_ANN, (CE_WARN,
-                                    "mr_sas: failed to create ioctl node."));
+                    S_IFCHR, INST2LSIRDCTL(instance_no), DDI_PSEUDO, 0) ==
+                    DDI_FAILURE) {
+                        cmn_err(CE_WARN,
+                            "mr_sas: failed to create ioctl node.");
 
                                 goto fail_attach;
                         }
 
-                        create_ioc_node_f = 1;
+                instance->unroll.ioctl = 1;
 
                         /* Create a taskq to handle dr events */
                         if ((instance->taskq = ddi_taskq_create(dip,
-                            "mrsas_dr_taskq", 1,
-                            TASKQ_DEFAULTPRI, 0)) == NULL) {
-                                con_log(CL_ANN, (CE_WARN,
-                                    "mr_sas: failed to create taskq "));
+                    "mrsas_dr_taskq", 1, TASKQ_DEFAULTPRI, 0)) == NULL) {
+                        cmn_err(CE_WARN,
+                            "mr_sas: failed to create taskq ");
                                 instance->taskq = NULL;
                                 goto fail_attach;
                         }
+                instance->unroll.taskq = 1;
+                con_log(CL_ANN1, (CE_CONT, "ddi_taskq_create()  done."));
 
                         /* enable interrupt */
                         instance->func_ptr->enable_intr(instance);
 
                         /* initiate AEN */
                         if (start_mfi_aen(instance)) {
-                                con_log(CL_ANN, (CE_WARN,
-                                    "mr_sas: failed to initiate AEN."));
-                                goto fail_initiate_aen;
+                        cmn_err(CE_WARN,
+                            "mr_sas: failed to initiate AEN.");
+                        goto fail_attach;
                         }
+                instance->unroll.aenPend = 1;
+                con_log(CL_ANN1,
+                    (CE_CONT, "AEN started for instance %d.", instance_no));
 
-                        con_log(CL_DLEVEL1, (CE_NOTE,
-                            "AEN started for instance %d.", instance_no));
-
                         /* Finally! We are on the air.  */
                         ddi_report_dev(dip);
 
+                /* FMA handle checking. */
                         if (mrsas_check_acc_handle(instance->regmap_handle) !=
                             DDI_SUCCESS) {
                                 goto fail_attach;
                         }
                         if (mrsas_check_acc_handle(instance->pci_handle) !=
                             DDI_SUCCESS) {
                                 goto fail_attach;
                         }
+
                         instance->mr_ld_list =
                             kmem_zalloc(MRDRV_MAX_LD * sizeof (struct mrsas_ld),
                             KM_SLEEP);
+                instance->unroll.ldlist_buff = 1;
+
+#ifdef PDSUPPORT
+                if (instance->tbolt) {
+                        instance->mr_tbolt_pd_max = MRSAS_TBOLT_PD_TGT_MAX;
+                        instance->mr_tbolt_pd_list =
+                            kmem_zalloc(MRSAS_TBOLT_GET_PD_MAX(instance) *
+                            sizeof (struct mrsas_tbolt_pd), KM_SLEEP);
+                        ASSERT(instance->mr_tbolt_pd_list);
+                        for (i = 0; i < instance->mr_tbolt_pd_max; i++) {
+                                instance->mr_tbolt_pd_list[i].lun_type =
+                                    MRSAS_TBOLT_PD_LUN;
+                                instance->mr_tbolt_pd_list[i].dev_id =
+                                    (uint8_t)i;
+                        }
+
+                        instance->unroll.pdlist_buff = 1;
+                }
+#endif
                         break;
                 case DDI_PM_RESUME:
-                        con_log(CL_ANN, (CE_NOTE,
-                            "mr_sas: DDI_PM_RESUME"));
+                con_log(CL_ANN, (CE_NOTE, "mr_sas: DDI_PM_RESUME"));
                         break;
                 case DDI_RESUME:
-                        con_log(CL_ANN, (CE_NOTE,
-                            "mr_sas: DDI_RESUME"));
+                con_log(CL_ANN, (CE_NOTE, "mr_sas: DDI_RESUME"));
                         break;
                 default:
-                        con_log(CL_ANN, (CE_WARN,
-                            "mr_sas: invalid attach cmd=%x", cmd));
+                con_log(CL_ANN,
+                    (CE_WARN, "mr_sas: invalid attach cmd=%x", cmd));
                         return (DDI_FAILURE);
         }
 
+
+        con_log(CL_DLEVEL1,
+            (CE_NOTE, "mrsas_attach() return SUCCESS instance_num %d",
+            instance_no));
         return (DDI_SUCCESS);
 
-fail_initiate_aen:
 fail_attach:
-        if (create_devctl_node_f) {
-                ddi_remove_minor_node(dip, "devctl");
-        }
 
-        if (create_scsi_node_f) {
-                ddi_remove_minor_node(dip, "scsi");
-        }
+        mrsas_undo_resources(dip, instance);
 
-        if (create_ioc_node_f) {
-                ddi_remove_minor_node(dip, instance->iocnode);
-        }
-
-        if (tran_alloc_f) {
-                scsi_hba_tran_free(tran);
-        }
-
-
-        if (added_soft_isr_f) {
-                ddi_remove_softintr(instance->soft_intr_id);
-        }
-
-        if (added_isr_f) {
-                mrsas_rem_intrs(instance);
-        }
-
-        if (instance && instance->taskq) {
-                ddi_taskq_destroy(instance->taskq);
-        }
-
         mrsas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE);
         ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
 
         mrsas_fm_fini(instance);
 
         pci_config_teardown(&instance->pci_handle);
-
         ddi_soft_state_free(mrsas_state, instance_no);
 
-        con_log(CL_ANN, (CE_NOTE,
-            "mr_sas: return failure from mrsas_attach"));
+        con_log(CL_ANN, (CE_WARN, "mr_sas: return failure from mrsas_attach"));
 
+        cmn_err(CE_WARN, "mrsas_attach() return FAILURE instance_num %d",
+            instance_no);
+
         return (DDI_FAILURE);
 }
 
+/*
+ * getinfo - gets device information
+ * @dip:
+ * @cmd:
+ * @arg:
+ * @resultp:
+ *
+ * The system calls getinfo() to obtain configuration information that only
+ * the driver knows. The mapping of minor numbers to device instance is
+ * entirely under the control of the driver. The system sometimes needs to ask
+ * the driver which device a particular dev_t represents.
+ * Given the device number return the devinfo pointer from the scsi_device
+ * structure.
+ */
 /*ARGSUSED*/
 static int
 mrsas_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd,  void *arg, void **resultp)
 {
         int     rval;

@@ -825,31 +1045,45 @@
         }
 
         return (rval);
 }
 
+/*
+ * detach - detaches a device from the system
+ * @dip: pointer to the device's dev_info structure
+ * @cmd: type of detach
+ *
+ * A driver's detach() entry point is called to detach an instance of a device
+ * that is bound to the driver. The entry point is called with the instance of
+ * the device node to be detached and with DDI_DETACH, which is specified as
+ * the cmd argument to the entry point.
+ * This routine is called during driver unload. We free all the allocated
+ * resources and call the corresponding LLD so that it can also release all
+ * its resources.
+ */
 static int
 mrsas_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
 {
         int     instance_no;
 
         struct mrsas_instance   *instance;
 
-        con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
+        con_log(CL_ANN, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
 
+
         /* CONSTCOND */
         ASSERT(NO_COMPETING_THREADS);
 
         instance_no = ddi_get_instance(dip);
 
         instance = (struct mrsas_instance *)ddi_get_soft_state(mrsas_state,
             instance_no);
 
         if (!instance) {
-                con_log(CL_ANN, (CE_WARN,
+                cmn_err(CE_WARN,
                     "mr_sas:%d could not get instance in detach",
-                    instance_no));
+                    instance_no);
 
                 return (DDI_FAILURE);
         }
 
         con_log(CL_ANN, (CE_NOTE,

@@ -860,57 +1094,42 @@
         switch (cmd) {
         case DDI_DETACH:
                 con_log(CL_ANN, (CE_NOTE,
                     "mrsas_detach: DDI_DETACH"));
 
-                if (scsi_hba_detach(dip) != DDI_SUCCESS) {
-                        con_log(CL_ANN, (CE_WARN,
-                            "mr_sas:%d failed to detach",
-                            instance_no));
-
-                        return (DDI_FAILURE);
+                        mutex_enter(&instance->config_dev_mtx);
+                        if (instance->timeout_id != (timeout_id_t)-1) {
+                                mutex_exit(&instance->config_dev_mtx);
+                                (void) untimeout(instance->timeout_id);
+                                instance->timeout_id = (timeout_id_t)-1;
+                                mutex_enter(&instance->config_dev_mtx);
+                                instance->unroll.timer = 0;
                 }
+                        mutex_exit(&instance->config_dev_mtx);
 
-                scsi_hba_tran_free(instance->tran);
-
-                flush_cache(instance);
-
-                if (abort_aen_cmd(instance, instance->aen_cmd)) {
-                        con_log(CL_ANN, (CE_WARN, "mrsas_detach: "
-                            "failed to abort prevous AEN command"));
-
+                        if (instance->unroll.tranSetup == 1) {
+                                if (scsi_hba_detach(dip) != DDI_SUCCESS) {
+                                        cmn_err(CE_WARN,
+                                            "mr_sas2%d: failed to detach",
+                                            instance_no);
                         return (DDI_FAILURE);
                 }
-
-                instance->func_ptr->disable_intr(instance);
-
-                if (instance->isr_level == HIGH_LEVEL_INTR) {
-                        ddi_remove_softintr(instance->soft_intr_id);
+                                instance->unroll.tranSetup = 0;
+                                con_log(CL_ANN1,
+                                    (CE_CONT, "scsi_hba_dettach()  done."));
                 }
 
-                mrsas_rem_intrs(instance);
+                        flush_cache(instance);
 
-                if (instance->taskq) {
-                        ddi_taskq_destroy(instance->taskq);
-                }
-                kmem_free(instance->mr_ld_list, MRDRV_MAX_LD
-                    * sizeof (struct mrsas_ld));
-                free_space_for_mfi(instance);
+                        mrsas_undo_resources(dip, instance);
 
                 mrsas_fm_fini(instance);
 
                 pci_config_teardown(&instance->pci_handle);
-
-                kmem_free(instance->func_ptr,
-                    sizeof (struct mrsas_func_ptr));
-
-                if (instance->timeout_id != (timeout_id_t)-1) {
-                        (void) untimeout(instance->timeout_id);
-                        instance->timeout_id = (timeout_id_t)-1;
-                }
                 ddi_soft_state_free(mrsas_state, instance_no);
                 break;
+
         case DDI_PM_SUSPEND:
                 con_log(CL_ANN, (CE_NOTE,
                     "mrsas_detach: DDI_PM_SUSPEND"));
 
                 break;

@@ -926,17 +1145,201 @@
         }
 
         return (DDI_SUCCESS);
 }
 
+
+static void
+mrsas_undo_resources(dev_info_t *dip, struct mrsas_instance *instance)
+{
+        int     instance_no;
+
+        con_log(CL_ANN, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
+
+
+        instance_no = ddi_get_instance(dip);
+
+
+        if (instance->unroll.ioctl == 1) {
+                ddi_remove_minor_node(dip, instance->iocnode);
+                instance->unroll.ioctl = 0;
+        }
+
+        if (instance->unroll.scsictl == 1) {
+                ddi_remove_minor_node(dip, "scsi");
+                instance->unroll.scsictl = 0;
+        }
+
+        if (instance->unroll.devctl == 1) {
+                ddi_remove_minor_node(dip, "devctl");
+                instance->unroll.devctl = 0;
+        }
+
+        if (instance->unroll.tranSetup == 1) {
+                if (scsi_hba_detach(dip) != DDI_SUCCESS) {
+                        cmn_err(CE_WARN,
+                            "mr_sas2%d: failed to detach", instance_no);
+                        return;  /* DDI_FAILURE */
+                }
+                instance->unroll.tranSetup = 0;
+                con_log(CL_ANN1, (CE_CONT, "scsi_hba_dettach()  done."));
+        }
+
+        if (instance->unroll.tran == 1)  {
+                scsi_hba_tran_free(instance->tran);
+                instance->unroll.tran = 0;
+                con_log(CL_ANN1, (CE_CONT, "scsi_hba_tran_free()  done."));
+        }
+
+        if (instance->unroll.syncCmd == 1) {
+                if (instance->tbolt) {
+                        if (abort_syncmap_cmd(instance,
+                            instance->map_update_cmd)) {
+                                cmn_err(CE_WARN, "mrsas_detach: "
+                                    "failed to abort previous syncmap command");
+                        }
+
+                        instance->unroll.syncCmd = 0;
+                        con_log(CL_ANN1, (CE_CONT, "sync cmd aborted, done."));
+                }
+        }
+
+        if (instance->unroll.aenPend == 1) {
+                if (abort_aen_cmd(instance, instance->aen_cmd))
+                        cmn_err(CE_WARN, "mrsas_detach: "
+                            "failed to abort prevous AEN command");
+
+                instance->unroll.aenPend = 0;
+                con_log(CL_ANN1, (CE_CONT, "aen cmd aborted, done."));
+                /* This means the controller is fully initialized and running */
+                /* Shutdown should be a last command to controller. */
+                /* shutdown_controller(); */
+        }
+
+
+        if (instance->unroll.timer == 1)         {
+                if (instance->timeout_id != (timeout_id_t)-1) {
+                        (void) untimeout(instance->timeout_id);
+                        instance->timeout_id = (timeout_id_t)-1;
+
+                        instance->unroll.timer = 0;
+                }
+        }
+
+        instance->func_ptr->disable_intr(instance);
+
+
+        if (instance->unroll.mutexs == 1) {
+                mutex_destroy(&instance->cmd_pool_mtx);
+                mutex_destroy(&instance->app_cmd_pool_mtx);
+                mutex_destroy(&instance->cmd_pend_mtx);
+                mutex_destroy(&instance->completed_pool_mtx);
+                mutex_destroy(&instance->sync_map_mtx);
+                mutex_destroy(&instance->int_cmd_mtx);
+                cv_destroy(&instance->int_cmd_cv);
+                mutex_destroy(&instance->config_dev_mtx);
+                mutex_destroy(&instance->ocr_flags_mtx);
+                mutex_destroy(&instance->reg_write_mtx);
+
+                if (instance->tbolt) {
+                        mutex_destroy(&instance->cmd_app_pool_mtx);
+                        mutex_destroy(&instance->chip_mtx);
+                }
+
+                instance->unroll.mutexs = 0;
+                con_log(CL_ANN1, (CE_CONT, "Destroy mutex & cv,  done."));
+        }
+
+
+        if (instance->unroll.soft_isr == 1) {
+                ddi_remove_softintr(instance->soft_intr_id);
+                instance->unroll.soft_isr = 0;
+        }
+
+        if (instance->unroll.intr == 1) {
+                mrsas_rem_intrs(instance);
+                instance->unroll.intr = 0;
+        }
+
+
+        if (instance->unroll.taskq == 1)         {
+                if (instance->taskq) {
+                        ddi_taskq_destroy(instance->taskq);
+                        instance->unroll.taskq = 0;
+                }
+
+        }
+
+        /*
+         * free dma memory allocated for
+         * cmds/frames/queues/driver version etc
+         */
+        if (instance->unroll.verBuff == 1) {
+                (void) mrsas_free_dma_obj(instance, instance->drv_ver_dma_obj);
+                instance->unroll.verBuff = 0;
+        }
+
+        if (instance->unroll.pdlist_buff == 1)  {
+                if (instance->mr_tbolt_pd_list != NULL) {
+                        kmem_free(instance->mr_tbolt_pd_list,
+                            MRSAS_TBOLT_GET_PD_MAX(instance) *
+                            sizeof (struct mrsas_tbolt_pd));
+                }
+
+                instance->mr_tbolt_pd_list = NULL;
+                instance->unroll.pdlist_buff = 0;
+        }
+
+        if (instance->unroll.ldlist_buff == 1)  {
+                if (instance->mr_ld_list != NULL) {
+                        kmem_free(instance->mr_ld_list, MRDRV_MAX_LD
+                            * sizeof (struct mrsas_ld));
+                }
+
+                instance->mr_ld_list = NULL;
+                instance->unroll.ldlist_buff = 0;
+        }
+
+        if (instance->tbolt) {
+                if (instance->unroll.alloc_space_mpi2 == 1) {
+                        free_space_for_mpi2(instance);
+                        instance->unroll.alloc_space_mpi2 = 0;
+                }
+        } else {
+                if (instance->unroll.alloc_space_mfi == 1) {
+                        free_space_for_mfi(instance);
+                        instance->unroll.alloc_space_mfi = 0;
+                }
+        }
+
+        if (instance->unroll.regs == 1)  {
+                ddi_regs_map_free(&instance->regmap_handle);
+                instance->unroll.regs = 0;
+                con_log(CL_ANN1, (CE_CONT, "ddi_regs_map_free()  done."));
+        }
+}
+
+
+
 /*
  * ************************************************************************** *
  *                                                                            *
  *             common entry points - for character driver types               *
  *                                                                            *
  * ************************************************************************** *
  */
+/*
+ * open - gets access to a device
+ * @dev:
+ * @openflags:
+ * @otyp:
+ * @credp:
+ *
+ * Access to a device by one or more application programs is controlled
+ * through the open() and close() entry points. The primary function of
+ * open() is to verify that the open request is allowed.
+ */
 static  int
 mrsas_open(dev_t *dev, int openflags, int otyp, cred_t *credp)
 {
         int     rval = 0;
 

@@ -966,10 +1369,20 @@
         }
 
         return (rval);
 }
 
+/*
+ * close - gives up access to a device
+ * @dev:
+ * @openflags:
+ * @otyp:
+ * @credp:
+ *
+ * close() should perform any cleanup necessary to finish using the minor
+ * device, and prepare the device (and driver) to be opened again.
+ */
 static  int
 mrsas_close(dev_t dev, int openflags, int otyp, cred_t *credp)
 {
         int     rval = 0;
 

@@ -982,10 +1395,27 @@
         }
 
         return (rval);
 }
 
+/*
+ * ioctl - performs a range of I/O commands for character drivers
+ * @dev:
+ * @cmd:
+ * @arg:
+ * @mode:
+ * @credp:
+ * @rvalp:
+ *
+ * ioctl() routine must make sure that user data is copied into or out of the
+ * kernel address space explicitly using copyin(), copyout(), ddi_copyin(),
+ * and ddi_copyout(), as appropriate.
+ * This is a wrapper routine to serialize access to the actual ioctl routine.
+ * ioctl() should return 0 on success, or the appropriate error number. The
+ * driver may also set the value returned to the calling process through rvalp.
+ */
+
 static int
 mrsas_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
     int *rvalp)
 {
         int     rval = 0;

@@ -1068,10 +1498,17 @@
  *               common entry points - for block driver types                 *
  *                                                                            *
  * ************************************************************************** *
  */
 #ifdef  __sparc
+/*
+ * reset - TBD
+ * @dip:
+ * @cmd:
+ *
+ * TBD
+ */
 /*ARGSUSED*/
 static int
 mrsas_reset(dev_info_t *dip, ddi_reset_cmd_t cmd)
 {
         int     instance_no;

@@ -1090,11 +1527,11 @@
                 return (DDI_FAILURE);
         }
 
         instance->func_ptr->disable_intr(instance);
 
-        con_log(CL_ANN1, (CE_NOTE, "flushing cache for instance %d",
+        con_log(CL_ANN1, (CE_CONT, "flushing cache for instance %d",
             instance_no));
 
         flush_cache(instance);
 
         return (DDI_SUCCESS);

@@ -1128,18 +1565,30 @@
         if (abort_aen_cmd(instance, instance->aen_cmd)) {
                 con_log(CL_ANN1, (CE_WARN, "mrsas_quiesce: "
                     "failed to abort prevous AEN command QUIESCE"));
         }
 
+        if (instance->tbolt) {
+                if (abort_syncmap_cmd(instance,
+                    instance->map_update_cmd)) {
+                        cmn_err(CE_WARN,
+                            "mrsas_detach: failed to abort "
+                            "previous syncmap command");
+                        return (DDI_FAILURE);
+                }
+        }
+
         instance->func_ptr->disable_intr(instance);
 
-        con_log(CL_ANN1, (CE_NOTE, "flushing cache for instance %d",
+        con_log(CL_ANN1, (CE_CONT, "flushing cache for instance %d",
             instance_no));
 
         flush_cache(instance);
 
         if (wait_for_outstanding(instance)) {
+                con_log(CL_ANN1,
+                    (CE_CONT, "wait_for_outstanding: return FAIL.\n"));
                 return (DDI_FAILURE);
         }
         return (DDI_SUCCESS);
 }
 #endif  /* __sparc */

@@ -1149,44 +1598,86 @@
  *                                                                            *
  *                          entry points (SCSI HBA)                           *
  *                                                                            *
  * ************************************************************************** *
  */
+/*
+ * tran_tgt_init - initialize a target device instance
+ * @hba_dip:
+ * @tgt_dip:
+ * @tran:
+ * @sd:
+ *
+ * The tran_tgt_init() entry point enables the HBA to allocate and initialize
+ * any per-target resources. tran_tgt_init() also enables the HBA to qualify
+ * the device's address as valid and supportable for that particular HBA.
+ * By returning DDI_FAILURE, the instance of the target driver for that device
+ * is not probed or attached.
+ */
 /*ARGSUSED*/
 static int
 mrsas_tran_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
                 scsi_hba_tran_t *tran, struct scsi_device *sd)
 {
         struct mrsas_instance *instance;
         uint16_t tgt = sd->sd_address.a_target;
         uint8_t lun = sd->sd_address.a_lun;
+        dev_info_t *child = NULL;
 
-        con_log(CL_ANN1, (CE_NOTE, "mrsas_tgt_init target %d lun %d",
+        con_log(CL_DLEVEL2, (CE_NOTE, "mrsas_tgt_init target %d lun %d",
             tgt, lun));
 
         instance = ADDR2MR(&sd->sd_address);
 
         if (ndi_dev_is_persistent_node(tgt_dip) == 0) {
-                (void) ndi_merge_node(tgt_dip, mrsas_name_node);
-                ddi_set_name_addr(tgt_dip, NULL);
-
-                con_log(CL_ANN1, (CE_NOTE, "mrsas_tgt_init in "
-                    "ndi_dev_is_persistent_node DDI_FAILURE t = %d l = %d",
-                    tgt, lun));
+                /*
+                 * If no persistent node exists, we don't allow .conf node
+                 * to be created.
+                 */
+                if ((child = mrsas_find_child(instance, tgt, lun)) != NULL) {
+                        con_log(CL_DLEVEL2,
+                            (CE_NOTE, "mrsas_tgt_init find child ="
+                            " %p t = %d l = %d", (void *)child, tgt, lun));
+                        if (ndi_merge_node(tgt_dip, mrsas_name_node) !=
+                            DDI_SUCCESS)
+                                /* Create this .conf node */
+                                return (DDI_SUCCESS);
+                }
+                con_log(CL_DLEVEL2, (CE_NOTE, "mrsas_tgt_init in ndi_per "
+                    "DDI_FAILURE t = %d l = %d", tgt, lun));
                 return (DDI_FAILURE);
+
         }
 
-        con_log(CL_ANN1, (CE_NOTE, "mrsas_tgt_init dev_dip %p tgt_dip %p",
+        con_log(CL_DLEVEL2, (CE_NOTE, "mrsas_tgt_init dev_dip %p tgt_dip %p",
             (void *)instance->mr_ld_list[tgt].dip, (void *)tgt_dip));
 
         if (tgt < MRDRV_MAX_LD && lun == 0) {
                 if (instance->mr_ld_list[tgt].dip == NULL &&
                     strcmp(ddi_driver_name(sd->sd_dev), "sd") == 0) {
+                        mutex_enter(&instance->config_dev_mtx);
                         instance->mr_ld_list[tgt].dip = tgt_dip;
                         instance->mr_ld_list[tgt].lun_type = MRSAS_LD_LUN;
+                        instance->mr_ld_list[tgt].flag = MRDRV_TGT_VALID;
+                        mutex_exit(&instance->config_dev_mtx);
                 }
         }
+
+#ifdef PDSUPPORT
+        else if (instance->tbolt) {
+                if (instance->mr_tbolt_pd_list[tgt].dip == NULL) {
+                        mutex_enter(&instance->config_dev_mtx);
+                        instance->mr_tbolt_pd_list[tgt].dip = tgt_dip;
+                        instance->mr_tbolt_pd_list[tgt].flag =
+                            MRDRV_TGT_VALID;
+                        mutex_exit(&instance->config_dev_mtx);
+                        con_log(CL_ANN1, (CE_NOTE, "mrsas_tran_tgt_init:"
+                            "t%xl%x", tgt, lun));
+                }
+        }
+#endif
+
         return (DDI_SUCCESS);
 }
 
 /*ARGSUSED*/
 static void

@@ -1197,20 +1688,33 @@
         int tgt = sd->sd_address.a_target;
         int lun = sd->sd_address.a_lun;
 
         instance = ADDR2MR(&sd->sd_address);
 
-        con_log(CL_ANN1, (CE_NOTE, "tgt_free t = %d l = %d", tgt, lun));
+        con_log(CL_DLEVEL2, (CE_NOTE, "tgt_free t = %d l = %d", tgt, lun));
 
         if (tgt < MRDRV_MAX_LD && lun == 0) {
                 if (instance->mr_ld_list[tgt].dip == tgt_dip) {
+                        mutex_enter(&instance->config_dev_mtx);
                         instance->mr_ld_list[tgt].dip = NULL;
+                        mutex_exit(&instance->config_dev_mtx);
                 }
         }
+
+#ifdef PDSUPPORT
+        else if (instance->tbolt) {
+                mutex_enter(&instance->config_dev_mtx);
+                instance->mr_tbolt_pd_list[tgt].dip = NULL;
+                mutex_exit(&instance->config_dev_mtx);
+                con_log(CL_ANN1, (CE_NOTE, "tgt_free: Setting dip = NULL"
+                    "for tgt:%x", tgt));
+        }
+#endif
+
 }
 
-static dev_info_t *
+dev_info_t *
 mrsas_find_child(struct mrsas_instance *instance, uint16_t tgt, uint8_t lun)
 {
         dev_info_t *child = NULL;
         char addr[SCSI_MAXNAMELEN];
         char tmp[MAXNAMELEN];

@@ -1217,57 +1721,87 @@
 
         (void) sprintf(addr, "%x,%x", tgt, lun);
         for (child = ddi_get_child(instance->dip); child;
             child = ddi_get_next_sibling(child)) {
 
+                if (ndi_dev_is_persistent_node(child) == 0) {
+                        continue;
+                }
+
                 if (mrsas_name_node(child, tmp, MAXNAMELEN) !=
                     DDI_SUCCESS) {
                         continue;
                 }
 
                 if (strcmp(addr, tmp) == 0) {
                         break;
                 }
         }
-        con_log(CL_ANN1, (CE_NOTE, "mrsas_find_child: return child = %p",
+        con_log(CL_DLEVEL2, (CE_NOTE, "mrsas_find_child: return child = %p",
             (void *)child));
         return (child);
 }
 
+/*
+ * mrsas_name_node -
+ * @dip:
+ * @name:
+ * @len:
+ */
 static int
 mrsas_name_node(dev_info_t *dip, char *name, int len)
 {
         int tgt, lun;
 
         tgt = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
             DDI_PROP_DONTPASS, "target", -1);
-        con_log(CL_ANN1, (CE_NOTE,
+        con_log(CL_DLEVEL2, (CE_NOTE,
             "mrsas_name_node: dip %p tgt %d", (void *)dip, tgt));
         if (tgt == -1) {
                 return (DDI_FAILURE);
         }
         lun = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
             "lun", -1);
-        con_log(CL_ANN1,
+        con_log(CL_DLEVEL2,
             (CE_NOTE, "mrsas_name_node: tgt %d lun %d", tgt, lun));
         if (lun == -1) {
                 return (DDI_FAILURE);
         }
         (void) snprintf(name, len, "%x,%x", tgt, lun);
         return (DDI_SUCCESS);
 }
 
+/*
+ * tran_init_pkt - allocate & initialize a scsi_pkt structure
+ * @ap:
+ * @pkt:
+ * @bp:
+ * @cmdlen:
+ * @statuslen:
+ * @tgtlen:
+ * @flags:
+ * @callback:
+ *
+ * The tran_init_pkt() entry point allocates and initializes a scsi_pkt
+ * structure and DMA resources for a target driver request. The
+ * tran_init_pkt() entry point is called when the target driver calls the
+ * SCSA function scsi_init_pkt(). Each call of the tran_init_pkt() entry point
+ * is a request to perform one or more of three possible services:
+ *  - allocation and initialization of a scsi_pkt structure
+ *  - allocation of DMA resources for data transfer
+ *  - reallocation of DMA resources for the next portion of the data transfer
+ */
 static struct scsi_pkt *
 mrsas_tran_init_pkt(struct scsi_address *ap, register struct scsi_pkt *pkt,
         struct buf *bp, int cmdlen, int statuslen, int tgtlen,
         int flags, int (*callback)(), caddr_t arg)
 {
         struct scsa_cmd *acmd;
         struct mrsas_instance   *instance;
         struct scsi_pkt *new_pkt;
 
-        con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
+        con_log(CL_DLEVEL1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
 
         instance = ADDR2MR(ap);
 
         /* step #1 : pkt allocation */
         if (pkt == NULL) {

@@ -1325,18 +1859,35 @@
         }
 
         return (pkt);
 }
 
+/*
+ * tran_start - transport a SCSI command to the addressed target
+ * @ap:
+ * @pkt:
+ *
+ * The tran_start() entry point for a SCSI HBA driver is called to transport a
+ * SCSI command to the addressed target. The SCSI command is described
+ * entirely within the scsi_pkt structure, which the target driver allocated
+ * through the HBA driver's tran_init_pkt() entry point. If the command
+ * involves a data transfer, DMA resources must also have been allocated for
+ * the scsi_pkt structure.
+ *
+ * Return Values :
+ *      TRAN_BUSY - request queue is full, no more free scbs
+ *      TRAN_ACCEPT - pkt has been submitted to the instance
+ */
 static int
 mrsas_tran_start(struct scsi_address *ap, register struct scsi_pkt *pkt)
 {
         uchar_t         cmd_done = 0;
 
         struct mrsas_instance   *instance = ADDR2MR(ap);
         struct mrsas_cmd        *cmd;
 
+        con_log(CL_DLEVEL1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
         if (instance->deadadapter == 1) {
                 con_log(CL_ANN1, (CE_WARN,
                     "mrsas_tran_start: return TRAN_FATAL_ERROR "
                     "for IO, as the HBA doesnt take any more IOs"));
                 if (pkt) {

@@ -1345,16 +1896,16 @@
                 }
                 return (TRAN_FATAL_ERROR);
         }
 
         if (instance->adapterresetinprogress) {
-                con_log(CL_ANN1, (CE_NOTE, "Reset flag set, "
+                con_log(CL_ANN1, (CE_NOTE, "mrsas_tran_start: Reset flag set, "
                     "returning mfi_pkt and setting TRAN_BUSY\n"));
                 return (TRAN_BUSY);
         }
 
-        con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d:SCSI CDB[0]=0x%x time:%x",
+        con_log(CL_ANN1, (CE_CONT, "chkpnt:%s:%d:SCSI CDB[0]=0x%x time:%x",
             __func__, __LINE__, pkt->pkt_cdbp[0], pkt->pkt_time));
 
         pkt->pkt_reason = CMD_CMPLT;
         *pkt->pkt_scbp = STATUS_GOOD; /* clear arq scsi_status */
 

@@ -1392,21 +1943,19 @@
                 }
 
                 /* Synchronize the Cmd frame for the controller */
                 (void) ddi_dma_sync(cmd->frame_dma_obj.dma_handle, 0, 0,
                     DDI_DMA_SYNC_FORDEV);
-                con_log(CL_ANN1, (CE_NOTE, "Push SCSI CDB[0]=0x%x"
+                con_log(CL_ANN, (CE_CONT, "issue_cmd_ppc: SCSI CDB[0]=0x%x"
                     "cmd->index:%x\n", pkt->pkt_cdbp[0], cmd->index));
                 instance->func_ptr->issue_cmd(cmd, instance);
 
         } else {
                 struct mrsas_header *hdr = &cmd->frame->hdr;
 
-                cmd->sync_cmd = MRSAS_TRUE;
+                instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd);
 
-                instance->func_ptr-> issue_cmd_in_poll_mode(instance, cmd);
-
                 pkt->pkt_reason         = CMD_CMPLT;
                 pkt->pkt_statistics     = 0;
                 pkt->pkt_state |= STATE_XFERRED_DATA | STATE_GOT_STATUS;
 
                 switch (ddi_get8(cmd->frame_dma_obj.acc_handle,

@@ -1414,18 +1963,21 @@
                 case MFI_STAT_OK:
                         pkt->pkt_scbp[0] = STATUS_GOOD;
                         break;
 
                 case MFI_STAT_SCSI_DONE_WITH_ERROR:
-
+                        con_log(CL_ANN, (CE_CONT,
+                            "mrsas_tran_start: scsi done with error"));
                         pkt->pkt_reason = CMD_CMPLT;
                         pkt->pkt_statistics = 0;
 
                         ((struct scsi_status *)pkt->pkt_scbp)->sts_chk = 1;
                         break;
 
                 case MFI_STAT_DEVICE_NOT_FOUND:
+                        con_log(CL_ANN, (CE_CONT,
+                            "mrsas_tran_start: device not found error"));
                         pkt->pkt_reason         = CMD_DEV_GONE;
                         pkt->pkt_statistics     = STAT_DISCON;
                         break;
 
                 default:

@@ -1444,10 +1996,23 @@
         }
 
         return (TRAN_ACCEPT);
 }
 
+/*
+ * tran_abort - Abort any commands that are currently in transport
+ * @ap:
+ * @pkt:
+ *
+ * The tran_abort() entry point for a SCSI HBA driver is called to abort any
+ * commands that are currently in transport for a particular target. This entry
+ * point is called when a target driver calls scsi_abort(). The tran_abort()
+ * entry point should attempt to abort the command denoted by the pkt
+ * parameter. If the pkt parameter is NULL, tran_abort() should attempt to
+ * abort all outstanding commands in the transport layer for the particular
+ * target or logical unit.
+ */
 /*ARGSUSED*/
 static int
 mrsas_tran_abort(struct scsi_address *ap, struct scsi_pkt *pkt)
 {
         con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));

@@ -1455,41 +2020,108 @@
         /* abort command not supported by H/W */
 
         return (DDI_FAILURE);
 }
 
+/*
+ * tran_reset - reset either the SCSI bus or target
+ * @ap:
+ * @level:
+ *
+ * The tran_reset() entry point for a SCSI HBA driver is called to reset either
+ * the SCSI bus or a particular SCSI target device. This entry point is called
+ * when a target driver calls scsi_reset(). The tran_reset() entry point must
+ * reset the SCSI bus if level is RESET_ALL. If level is RESET_TARGET, just the
+ * particular target or logical unit must be reset.
+ */
 /*ARGSUSED*/
 static int
 mrsas_tran_reset(struct scsi_address *ap, int level)
 {
+        struct mrsas_instance *instance = ADDR2MR(ap);
+
         con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
 
-        /* reset command not supported by H/W */
-
+        if (wait_for_outstanding(instance)) {
+                con_log(CL_ANN1,
+                    (CE_CONT, "wait_for_outstanding: return FAIL.\n"));
         return (DDI_FAILURE);
+        } else {
+                return (DDI_SUCCESS);
+        }
+}
 
+#if 0
+/*
+ * tran_bus_reset - reset the SCSI bus
+ * @dip:
+ * @level:
+ *
+ * The tran_bus_reset() vector in the scsi_hba_tran structure should be
+ * initialized during the HBA driver's attach(). The vector should point to
+ * an HBA entry point that is to be called when a user initiates a bus reset.
+ * Implementation is hardware specific. If the HBA driver cannot reset the
+ * SCSI bus without affecting the targets, the driver should fail RESET_BUS
+ * or not initialize this vector.
+ */
+/*ARGSUSED*/
+static int
+mrsas_tran_bus_reset(dev_info_t *dip, int level)
+{
+        int     instance_no = ddi_get_instance(dip);
+
+        struct mrsas_instance   *instance = ddi_get_soft_state(mrsas_state,
+            instance_no);
+
+        con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
+
+        if (wait_for_outstanding(instance)) {
+                con_log(CL_ANN1,
+                    (CE_CONT, "wait_for_outstanding: return FAIL.\n"));
+                return (DDI_FAILURE);
+        } else {
+                return (DDI_SUCCESS);
+        }
 }
+#endif
 
+/*
+ * tran_getcap - get one of a set of SCSA-defined capabilities
+ * @ap:
+ * @cap:
+ * @whom:
+ *
+ * The target driver can request the current setting of the capability for a
+ * particular target by setting the whom parameter to nonzero. A whom value of
+ * zero indicates a request for the current setting of the general capability
+ * for the SCSI bus or for adapter hardware. The tran_getcap() should return -1
+ * for undefined capabilities or the current value of the requested capability.
+ */
 /*ARGSUSED*/
 static int
 mrsas_tran_getcap(struct scsi_address *ap, char *cap, int whom)
 {
         int     rval = 0;
 
         struct mrsas_instance   *instance = ADDR2MR(ap);
 
-        con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
+        con_log(CL_DLEVEL2, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
 
         /* we do allow inquiring about capabilities for other targets */
         if (cap == NULL) {
                 return (-1);
         }
 
         switch (scsi_hba_lookup_capstr(cap)) {
         case SCSI_CAP_DMA_MAX:
+                if (instance->tbolt) {
+                        /* Limit to 256k max transfer */
+                        rval = mrsas_tbolt_max_cap_maxxfer;
+                } else {
                 /* Limit to 16MB max transfer */
                 rval = mrsas_max_cap_maxxfer;
+                }
                 break;
         case SCSI_CAP_MSG_OUT:
                 rval = 1;
                 break;
         case SCSI_CAP_DISCONNECT:

@@ -1534,17 +2166,33 @@
         }
 
         return (rval);
 }
 
+/*
+ * tran_setcap - set one of a set of SCSA-defined capabilities
+ * @ap:
+ * @cap:
+ * @value:
+ * @whom:
+ *
+ * The target driver might request that the new value be set for a particular
+ * target by setting the whom parameter to nonzero. A whom value of zero
+ * means that request is to set the new value for the SCSI bus or for adapter
+ * hardware in general.
+ * The tran_setcap() should return the following values as appropriate:
+ * - -1 for undefined capabilities
+ * - 0 if the HBA driver cannot set the capability to the requested value
+ * - 1 if the HBA driver is able to set the capability to the requested value
+ */
 /*ARGSUSED*/
 static int
 mrsas_tran_setcap(struct scsi_address *ap, char *cap, int value, int whom)
 {
         int             rval = 1;
 
-        con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
+        con_log(CL_DLEVEL2, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
 
         /* We don't allow setting capabilities for other targets */
         if (cap == NULL || whom == 0) {
                 return (-1);
         }

@@ -1582,16 +2230,29 @@
         }
 
         return (rval);
 }
 
+/*
+ * tran_destroy_pkt - deallocate scsi_pkt structure
+ * @ap:
+ * @pkt:
+ *
+ * The tran_destroy_pkt() entry point is the HBA driver function that
+ * deallocates scsi_pkt structures. The tran_destroy_pkt() entry point is
+ * called when the target driver calls scsi_destroy_pkt(). The
+ * tran_destroy_pkt() entry point must free any DMA resources that have been
+ * allocated for the packet. An implicit DMA synchronization occurs if the
+ * DMA resources are freed and any cached data remains after the completion
+ * of the transfer.
+ */
 static void
 mrsas_tran_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
 {
         struct scsa_cmd *acmd = PKT2CMD(pkt);
 
-        con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
+        con_log(CL_DLEVEL2, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
 
         if (acmd->cmd_flags & CFLAG_DMAVALID) {
                 acmd->cmd_flags &= ~CFLAG_DMAVALID;
 
                 (void) ddi_dma_unbind_handle(acmd->cmd_dmahandle);

@@ -1603,10 +2264,22 @@
 
         /* free the pkt */
         scsi_hba_pkt_free(ap, pkt);
 }
 
+/*
+ * tran_dmafree - deallocates DMA resources
+ * @ap:
+ * @pkt:
+ *
+ * The tran_dmafree() entry point deallocates DMAQ resources that have been
+ * allocated for a scsi_pkt structure. The tran_dmafree() entry point is
+ * called when the target driver calls scsi_dmafree(). The tran_dmafree() must
+ * free only DMA resources allocated for a scsi_pkt structure, not the
+ * scsi_pkt itself. When DMA resources are freed, a DMA synchronization is
+ * implicitly performed.
+ */
 /*ARGSUSED*/
 static void
 mrsas_tran_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
 {
         register struct scsa_cmd *acmd = PKT2CMD(pkt);

@@ -1622,10 +2295,23 @@
 
                 acmd->cmd_dmahandle = NULL;
         }
 }
 
+/*
+ * tran_sync_pkt - synchronize the DMA object allocated
+ * @ap:
+ * @pkt:
+ *
+ * The tran_sync_pkt() entry point synchronizes the DMA object allocated for
+ * the scsi_pkt structure before or after a DMA transfer. The tran_sync_pkt()
+ * entry point is called when the target driver calls scsi_sync_pkt(). If the
+ * data transfer direction is a DMA read from device to memory, tran_sync_pkt()
+ * must synchronize the CPU's view of the data. If the data transfer direction
+ * is a DMA write from memory to device, tran_sync_pkt() must synchronize the
+ * device's view of the data.
+ */
 /*ARGSUSED*/
 static void
 mrsas_tran_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
 {
         register struct scsa_cmd        *acmd = PKT2CMD(pkt);

@@ -1637,10 +2323,29 @@
                     acmd->cmd_dma_len, (acmd->cmd_flags & CFLAG_DMASEND) ?
                     DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU);
         }
 }
 
+/*ARGSUSED*/
+static int
+mrsas_tran_quiesce(dev_info_t *dip)
+{
+        con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
+
+        return (1);
+}
+
+/*ARGSUSED*/
+static int
+mrsas_tran_unquiesce(dev_info_t *dip)
+{
+        con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
+
+        return (1);
+}
+
+
 /*
  * mrsas_isr(caddr_t)
  *
  * The Interrupt Service Routine
  *

@@ -1652,20 +2357,34 @@
 {
         int             need_softintr;
         uint32_t        producer;
         uint32_t        consumer;
         uint32_t        context;
+        int             retval;
 
         struct mrsas_cmd        *cmd;
         struct mrsas_header     *hdr;
         struct scsi_pkt         *pkt;
 
+        con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
         ASSERT(instance);
+        if (instance->tbolt) {
+                mutex_enter(&instance->chip_mtx);
         if ((instance->intr_type == DDI_INTR_TYPE_FIXED) &&
+                    !(instance->func_ptr->intr_ack(instance))) {
+                        mutex_exit(&instance->chip_mtx);
+                        return (DDI_INTR_UNCLAIMED);
+                }
+                retval = mr_sas_tbolt_process_outstanding_cmd(instance);
+                mutex_exit(&instance->chip_mtx);
+                return (retval);
+        } else {
+                if ((instance->intr_type == DDI_INTR_TYPE_FIXED) &&
             !instance->func_ptr->intr_ack(instance)) {
                 return (DDI_INTR_UNCLAIMED);
         }
+        }
 
         (void) ddi_dma_sync(instance->mfi_internal_dma_obj.dma_handle,
             0, 0, DDI_DMA_SYNC_FORCPU);
 
         if (mrsas_check_dma_handle(instance->mfi_internal_dma_obj.dma_handle)

@@ -1692,14 +2411,14 @@
         producer = ddi_get32(instance->mfi_internal_dma_obj.acc_handle,
             instance->producer);
         consumer = ddi_get32(instance->mfi_internal_dma_obj.acc_handle,
             instance->consumer);
 
-        con_log(CL_ANN1, (CE_NOTE, " producer %x consumer %x ",
+        con_log(CL_ANN, (CE_CONT, " producer %x consumer %x ",
             producer, consumer));
         if (producer == consumer) {
-                con_log(CL_ANN1, (CE_WARN, "producer =  consumer case"));
+                con_log(CL_ANN, (CE_WARN, "producer ==  consumer case"));
                 DTRACE_PROBE2(isr_pc_err, uint32_t, producer,
                     uint32_t, consumer);
                 mutex_exit(&instance->cmd_pend_mtx);
                 mutex_exit(&instance->completed_pool_mtx);
                 return (DDI_INTR_CLAIMED);

@@ -1781,20 +2500,20 @@
 {
         mlist_t                 *head = &instance->cmd_pool_list;
         struct mrsas_cmd        *cmd = NULL;
 
         mutex_enter(&instance->cmd_pool_mtx);
-        ASSERT(mutex_owned(&instance->cmd_pool_mtx));
 
         if (!mlist_empty(head)) {
                 cmd = mlist_entry(head->next, struct mrsas_cmd, list);
                 mlist_del_init(head->next);
         }
         if (cmd != NULL) {
                 cmd->pkt = NULL;
                 cmd->retry_count_for_ocr = 0;
                 cmd->drv_pkt_time = 0;
+
         }
         mutex_exit(&instance->cmd_pool_mtx);
 
         return (cmd);
 }

@@ -1804,18 +2523,21 @@
 {
         mlist_t                         *head = &instance->app_cmd_pool_list;
         struct mrsas_cmd        *cmd = NULL;
 
         mutex_enter(&instance->app_cmd_pool_mtx);
-        ASSERT(mutex_owned(&instance->app_cmd_pool_mtx));
 
         if (!mlist_empty(head)) {
                 cmd = mlist_entry(head->next, struct mrsas_cmd, list);
                 mlist_del_init(head->next);
         }
-        if (cmd != NULL)
+        if (cmd != NULL) {
                 cmd->pkt = NULL;
+                cmd->retry_count_for_ocr = 0;
+                cmd->drv_pkt_time = 0;
+        }
+
         mutex_exit(&instance->app_cmd_pool_mtx);
 
         return (cmd);
 }
 /*

@@ -1823,11 +2545,10 @@
  */
 static void
 return_mfi_pkt(struct mrsas_instance *instance, struct mrsas_cmd *cmd)
 {
         mutex_enter(&instance->cmd_pool_mtx);
-        ASSERT(mutex_owned(&instance->cmd_pool_mtx));
         /* use mlist_add_tail for debug assistance */
         mlist_add_tail(&cmd->list, &instance->cmd_pool_list);
 
         mutex_exit(&instance->cmd_pool_mtx);
 }

@@ -1834,24 +2555,22 @@
 
 static void
 return_mfi_app_pkt(struct mrsas_instance *instance, struct mrsas_cmd *cmd)
 {
         mutex_enter(&instance->app_cmd_pool_mtx);
-        ASSERT(mutex_owned(&instance->app_cmd_pool_mtx));
 
         mlist_add(&cmd->list, &instance->app_cmd_pool_list);
 
         mutex_exit(&instance->app_cmd_pool_mtx);
 }
-static void
+void
 push_pending_mfi_pkt(struct mrsas_instance *instance, struct mrsas_cmd *cmd)
 {
         struct scsi_pkt *pkt;
         struct mrsas_header     *hdr;
-        con_log(CL_ANN1, (CE_NOTE, "push_pending_pkt(): Called\n"));
+        con_log(CL_DLEVEL2, (CE_NOTE, "push_pending_pkt(): Called\n"));
         mutex_enter(&instance->cmd_pend_mtx);
-        ASSERT(mutex_owned(&instance->cmd_pend_mtx));
         mlist_del_init(&cmd->list);
         mlist_add_tail(&cmd->list, &instance->cmd_pend_list);
         if (cmd->sync_cmd == MRSAS_TRUE) {
                 hdr = (struct mrsas_header *)&cmd->frame->hdr;
                 if (hdr) {

@@ -1891,61 +2610,87 @@
                             (void *) instance, drv_usectohz(MRSAS_1_SECOND));
                 }
         }
 
         mutex_exit(&instance->cmd_pend_mtx);
+
 }
 
-static int
+int
 mrsas_print_pending_cmds(struct mrsas_instance *instance)
 {
         mlist_t *head = &instance->cmd_pend_list;
         mlist_t *tmp = head;
         struct mrsas_cmd *cmd = NULL;
         struct mrsas_header     *hdr;
         unsigned int            flag = 1;
-
         struct scsi_pkt *pkt;
-        con_log(CL_ANN1, (CE_NOTE,
-            "mrsas_print_pending_cmds(): Called"));
+        int saved_level;
+        int cmd_count = 0;
+
+        saved_level = debug_level_g;
+        debug_level_g = CL_ANN1;
+
+        cmn_err(CE_NOTE, "mrsas_print_pending_cmds(): Called\n");
+
         while (flag) {
                 mutex_enter(&instance->cmd_pend_mtx);
                 tmp     =       tmp->next;
                 if (tmp == head) {
                         mutex_exit(&instance->cmd_pend_mtx);
                         flag = 0;
+                        con_log(CL_ANN1, (CE_CONT, "mrsas_print_pending_cmds():"
+                            " NO MORE CMDS PENDING....\n"));
                         break;
                 } else {
                         cmd = mlist_entry(tmp, struct mrsas_cmd, list);
                         mutex_exit(&instance->cmd_pend_mtx);
                         if (cmd) {
                                 if (cmd->sync_cmd == MRSAS_TRUE) {
-                                hdr = (struct mrsas_header *)&cmd->frame->hdr;
+                                        hdr = (struct mrsas_header *)
+                                            &cmd->frame->hdr;
                                         if (hdr) {
                                         con_log(CL_ANN1, (CE_CONT,
-                                            "print: cmd %p index %x hdr %p",
-                                            (void *)cmd, cmd->index,
+                                                    "print: cmd %p index 0x%x "
+                                                    "drv_pkt_time 0x%x (NO-PKT)"
+                                                    " hdr %p\n", (void *)cmd,
+                                                    cmd->index,
+                                                    cmd->drv_pkt_time,
                                             (void *)hdr));
                                         }
                                 } else {
                                         pkt = cmd->pkt;
                                         if (pkt) {
                                         con_log(CL_ANN1, (CE_CONT,
-                                            "print: cmd %p index %x "
-                                            "pkt %p", (void *)cmd, cmd->index,
-                                            (void *)pkt));
+                                            "print: cmd %p index 0x%x "
+                                            "drv_pkt_time 0x%x pkt %p \n",
+                                            (void *)cmd, cmd->index,
+                                            cmd->drv_pkt_time, (void *)pkt));
                                         }
                                 }
+
+                                if (++cmd_count == 1) {
+                                        mrsas_print_cmd_details(instance, cmd,
+                                            0xDD);
+                                } else {
+                                        mrsas_print_cmd_details(instance, cmd,
+                                            1);
                         }
+
                 }
         }
-        con_log(CL_ANN1, (CE_NOTE, "mrsas_print_pending_cmds(): Done\n"));
+        }
+        con_log(CL_ANN1, (CE_CONT, "mrsas_print_pending_cmds(): Done\n"));
+
+
+        debug_level_g = saved_level;
+
         return (DDI_SUCCESS);
 }
 
 
-static int
+int
 mrsas_complete_pending_cmds(struct mrsas_instance *instance)
 {
 
         struct mrsas_cmd *cmd = NULL;
         struct scsi_pkt *pkt;

@@ -1966,11 +2711,11 @@
                                     == 0) && pkt->pkt_comp) {
                                         pkt->pkt_reason
                                             = CMD_DEV_GONE;
                                         pkt->pkt_statistics
                                             = STAT_DISCON;
-                                        con_log(CL_ANN1, (CE_NOTE,
+                                        con_log(CL_ANN1, (CE_CONT,
                                             "fail and posting to scsa "
                                             "cmd %p index %x"
                                             " pkt %p "
                                             "time : %llx",
                                             (void *)cmd, cmd->index,

@@ -1978,11 +2723,11 @@
                                         (*pkt->pkt_comp)(pkt);
                                 }
                         } else { /* for DCMDS */
                                 if (cmd->sync_cmd == MRSAS_TRUE) {
                                 hdr = (struct mrsas_header *)&cmd->frame->hdr;
-                                con_log(CL_ANN1, (CE_NOTE,
+                                con_log(CL_ANN1, (CE_CONT,
                                     "posting invalid status to application "
                                     "cmd %p index %x"
                                     " hdr %p "
                                     "time : %llx",
                                     (void *)cmd, cmd->index,

@@ -1991,26 +2736,96 @@
                                 complete_cmd_in_sync_mode(instance, cmd);
                                 }
                         }
                         mlist_del_init(&cmd->list);
                 } else {
-                        con_log(CL_ANN1, (CE_NOTE,
+                        con_log(CL_ANN1, (CE_CONT,
                             "mrsas_complete_pending_cmds:"
                             "NULL command\n"));
                 }
-                con_log(CL_ANN1, (CE_NOTE,
+                con_log(CL_ANN1, (CE_CONT,
                     "mrsas_complete_pending_cmds:"
                     "looping for more commands\n"));
         }
         mutex_exit(&instance->cmd_pend_mtx);
 
-        con_log(CL_ANN1, (CE_NOTE, "mrsas_complete_pending_cmds(): DONE\n"));
+        con_log(CL_ANN1, (CE_CONT, "mrsas_complete_pending_cmds(): DONE\n"));
         return (DDI_SUCCESS);
 }
 
+void
+mrsas_print_cmd_details(struct mrsas_instance *instance, struct mrsas_cmd *cmd,
+    int detail)
+{
+        struct scsi_pkt *pkt = cmd->pkt;
+        Mpi2RaidSCSIIORequest_t *scsi_io = cmd->scsi_io_request;
+        int i;
+        int saved_level;
+        ddi_acc_handle_t acc_handle =
+            instance->mpi2_frame_pool_dma_obj.acc_handle;
 
-static int
+        if (detail == 0xDD) {
+                saved_level = debug_level_g;
+                debug_level_g = CL_ANN1;
+        }
+
+
+        if (instance->tbolt) {
+                con_log(CL_ANN1, (CE_CONT, "print_cmd_details: cmd %p "
+                    "cmd->index 0x%x SMID 0x%x timer 0x%x sec\n",
+                    (void *)cmd, cmd->index, cmd->SMID, cmd->drv_pkt_time));
+        } else {
+                con_log(CL_ANN1, (CE_CONT, "print_cmd_details: cmd %p "
+                    "cmd->index 0x%x timer 0x%x sec\n",
+                    (void *)cmd, cmd->index, cmd->drv_pkt_time));
+        }
+
+        if (pkt) {
+                con_log(CL_ANN1, (CE_CONT, "scsi_pkt CDB[0]=0x%x",
+                    pkt->pkt_cdbp[0]));
+        } else {
+                con_log(CL_ANN1, (CE_CONT, "NO-PKT"));
+        }
+
+        if ((detail == 0xDD) && instance->tbolt) {
+                con_log(CL_ANN1, (CE_CONT, "RAID_SCSI_IO_REQUEST\n"));
+                con_log(CL_ANN1, (CE_CONT, "DevHandle=0x%X Function=0x%X "
+                    "IoFlags=0x%X SGLFlags=0x%X DataLength=0x%X\n",
+                    ddi_get16(acc_handle, &scsi_io->DevHandle),
+                    ddi_get8(acc_handle, &scsi_io->Function),
+                    ddi_get16(acc_handle, &scsi_io->IoFlags),
+                    ddi_get16(acc_handle, &scsi_io->SGLFlags),
+                    ddi_get32(acc_handle, &scsi_io->DataLength)));
+
+                for (i = 0; i < 32; i++) {
+                        con_log(CL_ANN1, (CE_CONT, "CDB[%d]=0x%x ", i,
+                            ddi_get8(acc_handle, &scsi_io->CDB.CDB32[i])));
+                }
+
+                con_log(CL_ANN1, (CE_CONT, "RAID-CONTEXT\n"));
+                con_log(CL_ANN1, (CE_CONT, "status=0x%X extStatus=0x%X "
+                    "ldTargetId=0x%X timeoutValue=0x%X regLockFlags=0x%X "
+                    "RAIDFlags=0x%X regLockRowLBA=0x%" PRIu64
+                    " regLockLength=0x%X spanArm=0x%X\n",
+                    ddi_get8(acc_handle, &scsi_io->RaidContext.status),
+                    ddi_get8(acc_handle, &scsi_io->RaidContext.extStatus),
+                    ddi_get16(acc_handle, &scsi_io->RaidContext.ldTargetId),
+                    ddi_get16(acc_handle, &scsi_io->RaidContext.timeoutValue),
+                    ddi_get8(acc_handle, &scsi_io->RaidContext.regLockFlags),
+                    ddi_get8(acc_handle, &scsi_io->RaidContext.RAIDFlags),
+                    ddi_get64(acc_handle, &scsi_io->RaidContext.regLockRowLBA),
+                    ddi_get32(acc_handle, &scsi_io->RaidContext.regLockLength),
+                    ddi_get8(acc_handle, &scsi_io->RaidContext.spanArm)));
+        }
+
+        if (detail == 0xDD) {
+                debug_level_g = saved_level;
+        }
+}
+
+
+int
 mrsas_issue_pending_cmds(struct mrsas_instance *instance)
 {
         mlist_t *head   =       &instance->cmd_pend_list;
         mlist_t *tmp    =       head->next;
         struct mrsas_cmd *cmd = NULL;

@@ -2021,67 +2836,94 @@
                 mutex_enter(&instance->cmd_pend_mtx);
                 cmd = mlist_entry(tmp, struct mrsas_cmd, list);
                 tmp = tmp->next;
                 mutex_exit(&instance->cmd_pend_mtx);
                 if (cmd) {
-                        con_log(CL_ANN1, (CE_NOTE,
+                        con_log(CL_ANN1, (CE_CONT,
                             "mrsas_issue_pending_cmds(): "
-                            "Got a cmd: cmd:%p\n", (void *)cmd));
+                            "Got a cmd: cmd %p index 0x%x drv_pkt_time 0x%x ",
+                            (void *)cmd, cmd->index, cmd->drv_pkt_time));
+
+                        /* Reset command timeout value */
+                        if (cmd->drv_pkt_time < debug_timeout_g)
+                                cmd->drv_pkt_time = (uint16_t)debug_timeout_g;
+
                         cmd->retry_count_for_ocr++;
-                        con_log(CL_ANN1, (CE_NOTE,
-                            "mrsas_issue_pending_cmds(): "
-                            "cmd retry count = %d\n",
-                            cmd->retry_count_for_ocr));
+
+                        cmn_err(CE_CONT, "cmd retry count = %d\n",
+                            cmd->retry_count_for_ocr);
+
                         if (cmd->retry_count_for_ocr > IO_RETRY_COUNT) {
-                                con_log(CL_ANN1, (CE_NOTE,
+                                cmn_err(CE_WARN, "mrsas_issue_pending_cmds(): "
+                                    "cmd->retry_count exceeded limit >%d\n",
+                                    IO_RETRY_COUNT);
+                                mrsas_print_cmd_details(instance, cmd, 0xDD);
+
+                                cmn_err(CE_WARN,
                                     "mrsas_issue_pending_cmds():"
-                                    "Calling Kill Adapter\n"));
+                                    "Calling KILL Adapter\n");
+                                if (instance->tbolt)
+                                        mrsas_tbolt_kill_adapter(instance);
+                                else
                                 (void) mrsas_kill_adapter(instance);
                                 return (DDI_FAILURE);
                         }
+
                         pkt = cmd->pkt;
                         if (pkt) {
-                                con_log(CL_ANN1, (CE_NOTE,
-                                    "PENDING ISSUE: cmd %p index %x "
+                                con_log(CL_ANN1, (CE_CONT,
+                                    "PENDING PKT-CMD ISSUE: cmd %p index %x "
                                     "pkt %p time %llx",
                                     (void *)cmd, cmd->index,
                                     (void *)pkt,
                                     gethrtime()));
 
+                        } else {
+                                cmn_err(CE_CONT,
+                                    "mrsas_issue_pending_cmds(): NO-PKT, "
+                                    "cmd %p index 0x%x drv_pkt_time 0x%x ",
+                                    (void *)cmd, cmd->index, cmd->drv_pkt_time);
                         }
+
+
                         if (cmd->sync_cmd == MRSAS_TRUE) {
+                                cmn_err(CE_CONT, "mrsas_issue_pending_cmds(): "
+                                    "SYNC_CMD == TRUE \n");
                                 instance->func_ptr->issue_cmd_in_sync_mode(
                                     instance, cmd);
                         } else {
                                 instance->func_ptr->issue_cmd(cmd, instance);
                         }
                 } else {
-                        con_log(CL_ANN1, (CE_NOTE,
+                        con_log(CL_ANN1, (CE_CONT,
                             "mrsas_issue_pending_cmds: NULL command\n"));
                 }
-                con_log(CL_ANN1, (CE_NOTE,
+                con_log(CL_ANN1, (CE_CONT,
                     "mrsas_issue_pending_cmds:"
                     "looping for more commands"));
         }
-        con_log(CL_ANN1, (CE_NOTE, "mrsas_issue_pending_cmds(): DONE\n"));
+        con_log(CL_ANN1, (CE_CONT, "mrsas_issue_pending_cmds(): DONE\n"));
         return (DDI_SUCCESS);
 }
 
+
+
 /*
  * destroy_mfi_frame_pool
  */
-static void
+void
 destroy_mfi_frame_pool(struct mrsas_instance *instance)
 {
         int             i;
         uint32_t        max_cmd = instance->max_fw_cmds;
 
         struct mrsas_cmd        *cmd;
 
         /* return all frames to pool */
-        for (i = 0; i < max_cmd+1; i++) {
 
+        for (i = 0; i < max_cmd; i++) {
+
                 cmd = instance->cmd_list[i];
 
                 if (cmd->frame_dma_obj_status == DMA_OBJ_ALLOCATED)
                         (void) mrsas_free_dma_obj(instance, cmd->frame_dma_obj);
 

@@ -2091,50 +2933,49 @@
 }
 
 /*
  * create_mfi_frame_pool
  */
-static int
+int
 create_mfi_frame_pool(struct mrsas_instance *instance)
 {
         int             i = 0;
         int             cookie_cnt;
         uint16_t        max_cmd;
         uint16_t        sge_sz;
         uint32_t        sgl_sz;
         uint32_t        tot_frame_size;
         struct mrsas_cmd        *cmd;
+        int                     retval = DDI_SUCCESS;
 
         max_cmd = instance->max_fw_cmds;
-
         sge_sz  = sizeof (struct mrsas_sge_ieee);
-
         /* calculated the number of 64byte frames required for SGL */
         sgl_sz          = sge_sz * instance->max_num_sge;
         tot_frame_size  = sgl_sz + MRMFI_FRAME_SIZE + SENSE_LENGTH;
 
         con_log(CL_DLEVEL3, (CE_NOTE, "create_mfi_frame_pool: "
             "sgl_sz %x tot_frame_size %x", sgl_sz, tot_frame_size));
 
-        while (i < max_cmd+1) {
+        while (i < max_cmd) {
                 cmd = instance->cmd_list[i];
 
                 cmd->frame_dma_obj.size = tot_frame_size;
                 cmd->frame_dma_obj.dma_attr = mrsas_generic_dma_attr;
                 cmd->frame_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
                 cmd->frame_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
                 cmd->frame_dma_obj.dma_attr.dma_attr_sgllen = 1;
                 cmd->frame_dma_obj.dma_attr.dma_attr_align = 64;
 
-
                 cookie_cnt = mrsas_alloc_dma_obj(instance, &cmd->frame_dma_obj,
                     (uchar_t)DDI_STRUCTURE_LE_ACC);
 
                 if (cookie_cnt == -1 || cookie_cnt > 1) {
-                        con_log(CL_ANN, (CE_WARN,
-                            "create_mfi_frame_pool: could not alloc."));
-                        return (DDI_FAILURE);
+                        cmn_err(CE_WARN,
+                            "create_mfi_frame_pool: could not alloc.");
+                        retval = DDI_FAILURE;
+                        goto mrsas_undo_frame_pool;
                 }
 
                 bzero(cmd->frame_dma_obj.buffer, tot_frame_size);
 
                 cmd->frame_dma_obj_status = DMA_OBJ_ALLOCATED;

@@ -2148,14 +2989,14 @@
                 cmd->sense_phys_addr =
                     cmd->frame_dma_obj.dma_cookie[0].dmac_address +
                     tot_frame_size - SENSE_LENGTH;
 
                 if (!cmd->frame || !cmd->sense) {
-                        con_log(CL_ANN, (CE_NOTE,
-                            "mr_sas: pci_pool_alloc failed"));
-
-                        return (ENOMEM);
+                        cmn_err(CE_WARN,
+                            "mr_sas: pci_pool_alloc failed");
+                        retval = ENOMEM;
+                        goto mrsas_undo_frame_pool;
                 }
 
                 ddi_put32(cmd->frame_dma_obj.acc_handle,
                     &cmd->frame->io.context, cmd->index);
                 i++;

@@ -2163,10 +3004,16 @@
                 con_log(CL_DLEVEL3, (CE_NOTE, "[%x]-%x",
                     cmd->index, cmd->frame_phys_addr));
         }
 
         return (DDI_SUCCESS);
+
+mrsas_undo_frame_pool:
+        if (i > 0)
+                destroy_mfi_frame_pool(instance);
+
+        return (retval);
 }
 
 /*
  * free_additional_dma_buffer
  */

@@ -2205,12 +3052,12 @@
             0xFFFFFFFFU;
         instance->mfi_internal_dma_obj.dma_attr.dma_attr_sgllen = 1;
 
         if (mrsas_alloc_dma_obj(instance, &instance->mfi_internal_dma_obj,
             (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
-                con_log(CL_ANN, (CE_WARN,
-                    "mr_sas: could not alloc reply queue"));
+                cmn_err(CE_WARN,
+                    "mr_sas: could not alloc reply queue");
                 return (DDI_FAILURE);
         }
 
         bzero(instance->mfi_internal_dma_obj.buffer, internal_buf_size);
 

@@ -2238,133 +3085,217 @@
         instance->mfi_evt_detail_obj.dma_attr.dma_attr_sgllen = 1;
         instance->mfi_evt_detail_obj.dma_attr.dma_attr_align = 1;
 
         if (mrsas_alloc_dma_obj(instance, &instance->mfi_evt_detail_obj,
             (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
-                con_log(CL_ANN, (CE_WARN, "alloc_additional_dma_buffer: "
-                    "could not allocate data transfer buffer."));
-                return (DDI_FAILURE);
+                cmn_err(CE_WARN, "alloc_additional_dma_buffer: "
+                    "could not allocate data transfer buffer.");
+                goto mrsas_undo_internal_buff;
         }
 
         bzero(instance->mfi_evt_detail_obj.buffer,
             sizeof (struct mrsas_evt_detail));
 
         instance->mfi_evt_detail_obj.status |= DMA_OBJ_ALLOCATED;
 
         return (DDI_SUCCESS);
+
+mrsas_undo_internal_buff:
+        if (instance->mfi_internal_dma_obj.status == DMA_OBJ_ALLOCATED) {
+                (void) mrsas_free_dma_obj(instance,
+                    instance->mfi_internal_dma_obj);
+                instance->mfi_internal_dma_obj.status = DMA_OBJ_FREED;
+        }
+
+        return (DDI_FAILURE);
 }
 
-/*
- * free_space_for_mfi
- */
-static void
-free_space_for_mfi(struct mrsas_instance *instance)
+
+void
+mrsas_free_cmd_pool(struct mrsas_instance *instance)
 {
         int             i;
-        uint32_t        max_cmd = instance->max_fw_cmds;
+        uint32_t        max_cmd;
+        size_t          sz;
 
         /* already freed */
         if (instance->cmd_list == NULL) {
                 return;
         }
 
-        free_additional_dma_buffer(instance);
+        max_cmd = instance->max_fw_cmds;
 
-        /* first free the MFI frame pool */
-        destroy_mfi_frame_pool(instance);
+        /* size of cmd_list array */
+        sz = sizeof (struct mrsas_cmd *) * max_cmd;
 
-        /* free all the commands in the cmd_list */
-        for (i = 0; i < instance->max_fw_cmds+1; i++) {
+        /* First free each cmd */
+        for (i = 0; i < max_cmd; i++) {
+                if (instance->cmd_list[i] != NULL) {
                 kmem_free(instance->cmd_list[i],
                     sizeof (struct mrsas_cmd));
+                }
 
                 instance->cmd_list[i] = NULL;
         }
 
-        /* free the cmd_list buffer itself */
-        kmem_free(instance->cmd_list,
-            sizeof (struct mrsas_cmd *) * (max_cmd+1));
+        /* Now, free cmd_list array */
+        if (instance->cmd_list != NULL)
+                kmem_free(instance->cmd_list, sz);
 
         instance->cmd_list = NULL;
 
         INIT_LIST_HEAD(&instance->cmd_pool_list);
-        INIT_LIST_HEAD(&instance->app_cmd_pool_list);
         INIT_LIST_HEAD(&instance->cmd_pend_list);
+        if (instance->tbolt) {
+                INIT_LIST_HEAD(&instance->cmd_app_pool_list);
+        } else {
+                INIT_LIST_HEAD(&instance->app_cmd_pool_list);
+        }
+
 }
 
+
 /*
- * alloc_space_for_mfi
+ * mrsas_alloc_cmd_pool
  */
-static int
-alloc_space_for_mfi(struct mrsas_instance *instance)
+int
+mrsas_alloc_cmd_pool(struct mrsas_instance *instance)
 {
         int             i;
+        int             count;
         uint32_t        max_cmd;
         uint32_t        reserve_cmd;
         size_t          sz;
 
         struct mrsas_cmd        *cmd;
 
         max_cmd = instance->max_fw_cmds;
+        con_log(CL_ANN1, (CE_NOTE, "mrsas_alloc_cmd_pool: "
+            "max_cmd %x", max_cmd));
 
-        /* reserve 1 more slot for flush_cache */
-        sz = sizeof (struct mrsas_cmd *) * (max_cmd+1);
 
+        sz = sizeof (struct mrsas_cmd *) * max_cmd;
+
         /*
          * instance->cmd_list is an array of struct mrsas_cmd pointers.
          * Allocate the dynamic array first and then allocate individual
          * commands.
          */
         instance->cmd_list = kmem_zalloc(sz, KM_SLEEP);
         ASSERT(instance->cmd_list);
 
-        for (i = 0; i < max_cmd+1; i++) {
-                instance->cmd_list[i] = kmem_zalloc(sizeof (struct mrsas_cmd),
-                    KM_SLEEP);
-                ASSERT(instance->cmd_list[i]);
+        /* create a frame pool and assign one frame to each cmd */
+        for (count = 0; count < max_cmd; count++) {
+                instance->cmd_list[count] =
+                    kmem_zalloc(sizeof (struct mrsas_cmd), KM_SLEEP);
+                ASSERT(instance->cmd_list[count]);
         }
 
+        /* add all the commands to command pool */
+
         INIT_LIST_HEAD(&instance->cmd_pool_list);
         INIT_LIST_HEAD(&instance->cmd_pend_list);
-        /* add all the commands to command pool (instance->cmd_pool) */
-        reserve_cmd     =       APP_RESERVE_CMDS;
         INIT_LIST_HEAD(&instance->app_cmd_pool_list);
-        for (i = 0; i < reserve_cmd-1; i++) {
+
+        reserve_cmd = MRSAS_APP_RESERVED_CMDS;
+
+        for (i = 0; i < reserve_cmd; i++) {
                 cmd     = instance->cmd_list[i];
                 cmd->index      = i;
                 mlist_add_tail(&cmd->list, &instance->app_cmd_pool_list);
         }
-        /*
-         * reserve slot instance->cmd_list[APP_RESERVE_CMDS-1]
-         * for abort_aen_cmd
-         */
+
+
         for (i = reserve_cmd; i < max_cmd; i++) {
                 cmd                     = instance->cmd_list[i];
                 cmd->index      = i;
                 mlist_add_tail(&cmd->list, &instance->cmd_pool_list);
         }
 
-        /* single slot for flush_cache won't be added in command pool */
-        cmd             = instance->cmd_list[max_cmd];
-        cmd->index      = i;
+        return (DDI_SUCCESS);
 
-        /* create a frame pool and assign one frame to each cmd */
-        if (create_mfi_frame_pool(instance)) {
-                con_log(CL_ANN, (CE_NOTE, "error creating frame DMA pool"));
+mrsas_undo_cmds:
+        if (count > 0) {
+                /* free each cmd */
+                for (i = 0; i < count; i++) {
+                        if (instance->cmd_list[i] != NULL) {
+                                kmem_free(instance->cmd_list[i],
+                                    sizeof (struct mrsas_cmd));
+                        }
+                        instance->cmd_list[i] = NULL;
+                }
+        }
+
+mrsas_undo_cmd_list:
+        if (instance->cmd_list != NULL)
+                kmem_free(instance->cmd_list, sz);
+        instance->cmd_list = NULL;
+
                 return (DDI_FAILURE);
+}
+
+
+/*
+ * free_space_for_mfi
+ */
+static void
+free_space_for_mfi(struct mrsas_instance *instance)
+{
+
+        /* already freed */
+        if (instance->cmd_list == NULL) {
+                return;
         }
 
-        /* create a frame pool and assign one frame to each cmd */
-        if (alloc_additional_dma_buffer(instance)) {
-                con_log(CL_ANN, (CE_NOTE, "error creating frame DMA pool"));
+        /* Free additional dma buffer */
+        free_additional_dma_buffer(instance);
+
+        /* Free the MFI frame pool */
+        destroy_mfi_frame_pool(instance);
+
+        /* Free all the commands in the cmd_list */
+        /* Free the cmd_list buffer itself */
+        mrsas_free_cmd_pool(instance);
+}
+
+/*
+ * alloc_space_for_mfi
+ */
+static int
+alloc_space_for_mfi(struct mrsas_instance *instance)
+{
+        /* Allocate command pool (memory for cmd_list & individual commands) */
+        if (mrsas_alloc_cmd_pool(instance)) {
+                cmn_err(CE_WARN, "error creating cmd pool");
                 return (DDI_FAILURE);
         }
 
+        /* Allocate MFI Frame pool */
+        if (create_mfi_frame_pool(instance)) {
+                cmn_err(CE_WARN, "error creating frame DMA pool");
+                goto mfi_undo_cmd_pool;
+        }
+
+        /* Allocate additional DMA buffer */
+        if (alloc_additional_dma_buffer(instance)) {
+                cmn_err(CE_WARN, "error creating frame DMA pool");
+                goto mfi_undo_frame_pool;
+        }
+
         return (DDI_SUCCESS);
+
+mfi_undo_frame_pool:
+        destroy_mfi_frame_pool(instance);
+
+mfi_undo_cmd_pool:
+        mrsas_free_cmd_pool(instance);
+
+        return (DDI_FAILURE);
 }
 
 
+
 /*
  * get_ctrl_info
  */
 static int
 get_ctrl_info(struct mrsas_instance *instance,

@@ -2374,20 +3305,24 @@
 
         struct mrsas_cmd                *cmd;
         struct mrsas_dcmd_frame *dcmd;
         struct mrsas_ctrl_info  *ci;
 
+        if (instance->tbolt) {
+                cmd = get_raid_msg_mfi_pkt(instance);
+        } else {
         cmd = get_mfi_pkt(instance);
+        }
 
         if (!cmd) {
                 con_log(CL_ANN, (CE_WARN,
                     "Failed to get a cmd for ctrl info"));
                 DTRACE_PROBE2(info_mfi_err, uint16_t, instance->fw_outstanding,
                     uint16_t, instance->max_fw_cmds);
                 return (DDI_FAILURE);
         }
-        cmd->retry_count_for_ocr = 0;
+
         /* Clear the frame buffer and assign back the context id */
         (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
         ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
             cmd->index);
 

@@ -2394,12 +3329,12 @@
         dcmd = &cmd->frame->dcmd;
 
         ci = (struct mrsas_ctrl_info *)instance->internal_buf;
 
         if (!ci) {
-                con_log(CL_ANN, (CE_WARN,
-                    "Failed to alloc mem for ctrl info"));
+                cmn_err(CE_WARN,
+                    "Failed to alloc mem for ctrl info");
                 return_mfi_pkt(instance, cmd);
                 return (DDI_FAILURE);
         }
 
         (void) memset(ci, 0, sizeof (struct mrsas_ctrl_info));

@@ -2423,37 +3358,44 @@
         ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->sgl.sge32[0].length,
             sizeof (struct mrsas_ctrl_info));
 
         cmd->frame_count = 1;
 
+        if (instance->tbolt) {
+                mr_sas_tbolt_build_mfi_cmd(instance, cmd);
+        }
+
         if (!instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) {
         ret = 0;
 
         ctrl_info->max_request_size = ddi_get32(
             cmd->frame_dma_obj.acc_handle, &ci->max_request_size);
 
         ctrl_info->ld_present_count = ddi_get16(
             cmd->frame_dma_obj.acc_handle, &ci->ld_present_count);
 
-        ctrl_info->properties.on_off_properties =
-            ddi_get32(cmd->frame_dma_obj.acc_handle,
+                ctrl_info->properties.on_off_properties = ddi_get32(
+                    cmd->frame_dma_obj.acc_handle,
             &ci->properties.on_off_properties);
-
         ddi_rep_get8(cmd->frame_dma_obj.acc_handle,
             (uint8_t *)(ctrl_info->product_name),
             (uint8_t *)(ci->product_name), 80 * sizeof (char),
             DDI_DEV_AUTOINCR);
         /* should get more members of ci with ddi_get when needed */
         } else {
-                con_log(CL_ANN, (CE_WARN, "get_ctrl_info: Ctrl info failed"));
+                cmn_err(CE_WARN, "get_ctrl_info: Ctrl info failed");
                 ret = -1;
         }
 
         if (mrsas_common_check(instance, cmd) != DDI_SUCCESS) {
                 ret = -1;
         }
+        if (instance->tbolt) {
+                return_raid_msg_mfi_pkt(instance, cmd);
+        } else {
         return_mfi_pkt(instance, cmd);
+        }
 
         return (ret);
 }
 
 /*

@@ -2466,20 +3408,26 @@
         int     ret = 0;
 
         struct mrsas_cmd                *cmd;
         struct mrsas_abort_frame        *abort_fr;
 
-        cmd = instance->cmd_list[APP_RESERVE_CMDS-1];
+        con_log(CL_ANN1, (CE_NOTE, "chkpnt: abort_aen:%d", __LINE__));
 
+        if (instance->tbolt) {
+                cmd = get_raid_msg_mfi_pkt(instance);
+        } else {
+                cmd = get_mfi_pkt(instance);
+        }
+
         if (!cmd) {
                 con_log(CL_ANN1, (CE_WARN,
                     "abort_aen_cmd():Failed to get a cmd for abort_aen_cmd"));
                 DTRACE_PROBE2(abort_mfi_err, uint16_t, instance->fw_outstanding,
                     uint16_t, instance->max_fw_cmds);
                 return (DDI_FAILURE);
         }
-        cmd->retry_count_for_ocr = 0;
+
         /* Clear the frame buffer and assign back the context id */
         (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
         ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
             cmd->index);
 

@@ -2498,13 +3446,16 @@
         ddi_put32(cmd->frame_dma_obj.acc_handle,
             &abort_fr->abort_mfi_phys_addr_hi, 0);
 
         instance->aen_cmd->abort_aen = 1;
 
-        cmd->sync_cmd = MRSAS_TRUE;
         cmd->frame_count = 1;
 
+        if (instance->tbolt) {
+                mr_sas_tbolt_build_mfi_cmd(instance, cmd);
+        }
+
         if (instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) {
                 con_log(CL_ANN1, (CE_WARN,
                     "abort_aen_cmd: issue_cmd_in_poll_mode failed"));
                 ret = -1;
         } else {

@@ -2512,63 +3463,41 @@
         }
 
         instance->aen_cmd->abort_aen = 1;
         instance->aen_cmd = 0;
 
+        if (instance->tbolt) {
+                return_raid_msg_mfi_pkt(instance, cmd);
+        } else {
+                return_mfi_pkt(instance, cmd);
+        }
+
         atomic_add_16(&instance->fw_outstanding, (-1));
 
         return (ret);
 }
 
 
-/*
- * init_mfi
- */
 static int
-init_mfi(struct mrsas_instance *instance)
+mrsas_build_init_cmd(struct mrsas_instance *instance,
+    struct mrsas_cmd **cmd_ptr)
 {
         struct mrsas_cmd                *cmd;
-        struct mrsas_ctrl_info          ctrl_info;
         struct mrsas_init_frame         *init_frame;
         struct mrsas_init_queue_info    *initq_info;
+        struct mrsas_drv_ver            drv_ver_info;
 
-        /* we expect the FW state to be READY */
-        if (mfi_state_transition_to_ready(instance)) {
-                con_log(CL_ANN, (CE_WARN, "mr_sas: F/W is not ready"));
-                goto fail_ready_state;
-        }
 
-        /* get various operational parameters from status register */
-        instance->max_num_sge =
-            (instance->func_ptr->read_fw_status_reg(instance) &
-            0xFF0000) >> 0x10;
         /*
-         * Reduce the max supported cmds by 1. This is to ensure that the
-         * reply_q_sz (1 more than the max cmd that driver may send)
-         * does not exceed max cmds that the FW can support
-         */
-        instance->max_fw_cmds =
-            instance->func_ptr->read_fw_status_reg(instance) & 0xFFFF;
-        instance->max_fw_cmds = instance->max_fw_cmds - 1;
-
-        instance->max_num_sge =
-            (instance->max_num_sge > MRSAS_MAX_SGE_CNT) ?
-            MRSAS_MAX_SGE_CNT : instance->max_num_sge;
-
-        /* create a pool of commands */
-        if (alloc_space_for_mfi(instance) != DDI_SUCCESS)
-                goto fail_alloc_fw_space;
-
-        /*
          * Prepare a init frame. Note the init frame points to queue info
          * structure. Each frame has SGL allocated after first 64 bytes. For
          * this frame - since we don't need any SGL - we use SGL's space as
          * queue info structure
          */
-        cmd = get_mfi_pkt(instance);
-        cmd->retry_count_for_ocr = 0;
+        cmd = *cmd_ptr;
 
+
         /* Clear the frame buffer and assign back the context id */
         (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
         ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
             cmd->index);
 

@@ -2611,26 +3540,91 @@
             &init_frame->queue_info_new_phys_addr_lo,
             cmd->frame_phys_addr + 64);
         ddi_put32(cmd->frame_dma_obj.acc_handle,
             &init_frame->queue_info_new_phys_addr_hi, 0);
 
+
+        /* fill driver version information */
+        fill_up_drv_ver(&drv_ver_info);
+
+        /* allocate the driver version data transfer buffer */
+        instance->drv_ver_dma_obj.size = sizeof (drv_ver_info.drv_ver);
+        instance->drv_ver_dma_obj.dma_attr = mrsas_generic_dma_attr;
+        instance->drv_ver_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
+        instance->drv_ver_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
+        instance->drv_ver_dma_obj.dma_attr.dma_attr_sgllen = 1;
+        instance->drv_ver_dma_obj.dma_attr.dma_attr_align = 1;
+
+        if (mrsas_alloc_dma_obj(instance, &instance->drv_ver_dma_obj,
+            (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
+                con_log(CL_ANN, (CE_WARN,
+                    "init_mfi : Could not allocate driver version buffer."));
+                return (DDI_FAILURE);
+        }
+        /* copy driver version to dma buffer */
+        (void) memset(instance->drv_ver_dma_obj.buffer, 0,
+            sizeof (drv_ver_info.drv_ver));
+        ddi_rep_put8(cmd->frame_dma_obj.acc_handle,
+            (uint8_t *)drv_ver_info.drv_ver,
+            (uint8_t *)instance->drv_ver_dma_obj.buffer,
+            sizeof (drv_ver_info.drv_ver), DDI_DEV_AUTOINCR);
+
+
+        /* copy driver version physical address to init frame */
+        ddi_put64(cmd->frame_dma_obj.acc_handle, &init_frame->driverversion,
+            instance->drv_ver_dma_obj.dma_cookie[0].dmac_address);
+
         ddi_put32(cmd->frame_dma_obj.acc_handle, &init_frame->data_xfer_len,
             sizeof (struct mrsas_init_queue_info));
 
         cmd->frame_count = 1;
 
-        /* issue the init frame in polled mode */
+        *cmd_ptr = cmd;
+
+        return (DDI_SUCCESS);
+}
+
+
+/*
+ * mrsas_init_adapter_ppc - Initialize MFI interface adapter.
+ */
+int
+mrsas_init_adapter_ppc(struct mrsas_instance *instance)
+{
+        struct mrsas_cmd                *cmd;
+
+        /*
+         * allocate memory for mfi adapter(cmd pool, individual commands, mfi
+         * frames etc
+         */
+        if (alloc_space_for_mfi(instance) != DDI_SUCCESS) {
+                con_log(CL_ANN, (CE_NOTE,
+                    "Error, failed to allocate memory for MFI adapter"));
+                return (DDI_FAILURE);
+        }
+
+        /* Build INIT command */
+        cmd = get_mfi_pkt(instance);
+
+        if (mrsas_build_init_cmd(instance, &cmd) != DDI_SUCCESS) {
+                con_log(CL_ANN,
+                    (CE_NOTE, "Error, failed to build INIT command"));
+
+                goto fail_undo_alloc_mfi_space;
+        }
+
+        /*
+         * Disable interrupt before sending init frame ( see linux driver code)
+         * send INIT MFI frame in polled mode
+         */
         if (instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) {
                 con_log(CL_ANN, (CE_WARN, "failed to init firmware"));
-                return_mfi_pkt(instance, cmd);
                 goto fail_fw_init;
         }
 
-        if (mrsas_common_check(instance, cmd) != DDI_SUCCESS) {
-                return_mfi_pkt(instance, cmd);
+        if (mrsas_common_check(instance, cmd) != DDI_SUCCESS)
                 goto fail_fw_init;
-        }
         return_mfi_pkt(instance, cmd);
 
         if (ctio_enable &&
             (instance->func_ptr->read_fw_status_reg(instance) & 0x04000000)) {
                 con_log(CL_ANN, (CE_NOTE, "mr_sas: IEEE SGL's supported"));

@@ -2637,12 +3631,71 @@
                 instance->flag_ieee = 1;
         } else {
                 instance->flag_ieee = 0;
         }
 
-        instance->disable_online_ctrl_reset = 0;
+        instance->unroll.alloc_space_mfi = 1;
+        instance->unroll.verBuff = 1;
+
+        return (DDI_SUCCESS);
+
+
+fail_fw_init:
+        (void) mrsas_free_dma_obj(instance, instance->drv_ver_dma_obj);
+
+fail_undo_alloc_mfi_space:
+        return_mfi_pkt(instance, cmd);
+        free_space_for_mfi(instance);
+
+        return (DDI_FAILURE);
+
+}
+
+/*
+ * mrsas_init_adapter - Initialize adapter.
+ */
+int
+mrsas_init_adapter(struct mrsas_instance *instance)
+{
+        struct mrsas_ctrl_info          ctrl_info;
+
+
+        /* we expect the FW state to be READY */
+        if (mfi_state_transition_to_ready(instance)) {
+                con_log(CL_ANN, (CE_WARN, "mr_sas: F/W is not ready"));
+                return (DDI_FAILURE);
+        }
+
+        /* get various operational parameters from status register */
+        instance->max_num_sge =
+            (instance->func_ptr->read_fw_status_reg(instance) &
+            0xFF0000) >> 0x10;
+        instance->max_num_sge =
+            (instance->max_num_sge > MRSAS_MAX_SGE_CNT) ?
+            MRSAS_MAX_SGE_CNT : instance->max_num_sge;
+
+        /*
+         * Reduce the max supported cmds by 1. This is to ensure that the
+         * reply_q_sz (1 more than the max cmd that driver may send)
+         * does not exceed max cmds that the FW can support
+         */
+        instance->max_fw_cmds =
+            instance->func_ptr->read_fw_status_reg(instance) & 0xFFFF;
+        instance->max_fw_cmds = instance->max_fw_cmds - 1;
+
+
+
+        /* Initialize adapter */
+        if (instance->func_ptr->init_adapter(instance) != DDI_SUCCESS) {
+                con_log(CL_ANN,
+                    (CE_WARN, "mr_sas: could not initialize adapter"));
+                return (DDI_FAILURE);
+        }
+
         /* gather misc FW related information */
+        instance->disable_online_ctrl_reset = 0;
+
         if (!get_ctrl_info(instance, &ctrl_info)) {
                 instance->max_sectors_per_req = ctrl_info.max_request_size;
                 con_log(CL_ANN1, (CE_NOTE,
                     "product name %s ld present %d",
                     ctrl_info.product_name, ctrl_info.ld_present_count));

@@ -2654,27 +3707,14 @@
         if (ctrl_info.properties.on_off_properties & DISABLE_OCR_PROP_FLAG)
                 instance->disable_online_ctrl_reset = 1;
 
         return (DDI_SUCCESS);
 
-fail_fw_init:
-fail_alloc_fw_space:
-
-        free_space_for_mfi(instance);
-
-fail_ready_state:
-        ddi_regs_map_free(&instance->regmap_handle);
-
-fail_mfi_reg_setup:
-        return (DDI_FAILURE);
 }
 
 
 
-
-
-
 static int
 mrsas_issue_init_mfi(struct mrsas_instance *instance)
 {
         struct mrsas_cmd                *cmd;
         struct mrsas_init_frame         *init_frame;

@@ -2689,11 +3729,11 @@
         con_log(CL_ANN1, (CE_NOTE,
             "mrsas_issue_init_mfi: entry\n"));
         cmd = get_mfi_app_pkt(instance);
 
         if (!cmd) {
-                con_log(CL_ANN1, (CE_NOTE,
+                con_log(CL_ANN1, (CE_WARN,
                     "mrsas_issue_init_mfi: get_pkt failed\n"));
                 return (DDI_FAILURE);
         }
 
         /* Clear the frame buffer and assign back the context id */

@@ -2751,44 +3791,52 @@
                     "mrsas_issue_init_mfi():failed to "
                     "init firmware"));
                 return_mfi_app_pkt(instance, cmd);
                 return (DDI_FAILURE);
         }
+
+        if (mrsas_common_check(instance, cmd) != DDI_SUCCESS) {
+                return_mfi_pkt(instance, cmd);
+                return (DDI_FAILURE);
+        }
+
         return_mfi_app_pkt(instance, cmd);
-        con_log(CL_ANN1, (CE_NOTE, "mrsas_issue_init_mfi: Done"));
+        con_log(CL_ANN1, (CE_CONT, "mrsas_issue_init_mfi: Done"));
+
         return (DDI_SUCCESS);
 }
 /*
  * mfi_state_transition_to_ready        : Move the FW to READY state
  *
  * @reg_set                     : MFI register set
  */
-static int
+int
 mfi_state_transition_to_ready(struct mrsas_instance *instance)
 {
         int             i;
         uint8_t         max_wait;
-        uint32_t        fw_ctrl;
+        uint32_t        fw_ctrl = 0;
         uint32_t        fw_state;
         uint32_t        cur_state;
         uint32_t        cur_abs_reg_val;
         uint32_t        prev_abs_reg_val;
+        uint32_t        status;
 
         cur_abs_reg_val =
             instance->func_ptr->read_fw_status_reg(instance);
         fw_state =
             cur_abs_reg_val & MFI_STATE_MASK;
-        con_log(CL_ANN1, (CE_NOTE,
+        con_log(CL_ANN1, (CE_CONT,
             "mfi_state_transition_to_ready:FW state = 0x%x", fw_state));
 
         while (fw_state != MFI_STATE_READY) {
-                con_log(CL_ANN, (CE_NOTE,
+                con_log(CL_ANN, (CE_CONT,
                     "mfi_state_transition_to_ready:FW state%x", fw_state));
 
                 switch (fw_state) {
                 case MFI_STATE_FAULT:
-                        con_log(CL_ANN1, (CE_NOTE,
+                        con_log(CL_ANN, (CE_NOTE,
                             "mr_sas: FW in FAULT state!!"));
 
                         return (ENODEV);
                 case MFI_STATE_WAIT_HANDSHAKE:
                         /* set the CLR bit in IMR0 */

@@ -2798,14 +3846,18 @@
                          * PCI_Hot Plug: MFI F/W requires
                          * (MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG)
                          * to be set
                          */
                         /* WR_IB_MSG_0(MFI_INIT_CLEAR_HANDSHAKE, instance); */
+                        if (!instance->tbolt) {
                         WR_IB_DOORBELL(MFI_INIT_CLEAR_HANDSHAKE |
                             MFI_INIT_HOTPLUG, instance);
-
-                        max_wait        = 2;
+                        } else {
+                                WR_RESERVED0_REGISTER(MFI_INIT_CLEAR_HANDSHAKE |
+                                    MFI_INIT_HOTPLUG, instance);
+                        }
+                        max_wait        = (instance->tbolt == 1) ? 180 : 2;
                         cur_state       = MFI_STATE_WAIT_HANDSHAKE;
                         break;
                 case MFI_STATE_BOOT_MESSAGE_PENDING:
                         /* set the CLR bit in IMR0 */
                         con_log(CL_ANN1, (CE_NOTE,

@@ -2813,13 +3865,17 @@
                         /*
                          * PCI_Hot Plug: MFI F/W requires
                          * (MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG)
                          * to be set
                          */
+                        if (!instance->tbolt) {
                         WR_IB_DOORBELL(MFI_INIT_HOTPLUG, instance);
-
-                        max_wait        = 10;
+                        } else {
+                                WR_RESERVED0_REGISTER(MFI_INIT_HOTPLUG,
+                                    instance);
+                        }
+                        max_wait        = (instance->tbolt == 1) ? 180 : 10;
                         cur_state       = MFI_STATE_BOOT_MESSAGE_PENDING;
                         break;
                 case MFI_STATE_OPERATIONAL:
                         /* bring it to READY state; assuming max wait 2 secs */
                         instance->func_ptr->disable_intr(instance);

@@ -2829,37 +3885,61 @@
                          * PCI_Hot Plug: MFI F/W requires
                          * (MFI_INIT_READY | MFI_INIT_MFIMODE | MFI_INIT_ABORT)
                          * to be set
                          */
                         /* WR_IB_DOORBELL(MFI_INIT_READY, instance); */
+                        if (!instance->tbolt) {
                         WR_IB_DOORBELL(MFI_RESET_FLAGS, instance);
+                        } else {
+                                WR_RESERVED0_REGISTER(MFI_RESET_FLAGS,
+                                    instance);
 
-                        max_wait        = 10;
+                                for (i = 0; i < (10 * 1000); i++) {
+                                        status =
+                                            RD_RESERVED0_REGISTER(instance);
+                                        if (status & 1) {
+                                                delay(1 *
+                                                    drv_usectohz(MILLISEC));
+                                        } else {
+                                                break;
+                                        }
+                                }
+
+                        }
+                        max_wait        = (instance->tbolt == 1) ? 180 : 10;
                         cur_state       = MFI_STATE_OPERATIONAL;
                         break;
                 case MFI_STATE_UNDEFINED:
                         /* this state should not last for more than 2 seconds */
                         con_log(CL_ANN1, (CE_NOTE, "FW state undefined"));
 
-                        max_wait        = 2;
+                        max_wait        = (instance->tbolt == 1) ? 180 : 2;
                         cur_state       = MFI_STATE_UNDEFINED;
                         break;
                 case MFI_STATE_BB_INIT:
-                        max_wait        = 2;
+                        max_wait        = (instance->tbolt == 1) ? 180 : 2;
                         cur_state       = MFI_STATE_BB_INIT;
                         break;
                 case MFI_STATE_FW_INIT:
-                        max_wait        = 2;
+                        max_wait        = (instance->tbolt == 1) ? 180 : 2;
                         cur_state       = MFI_STATE_FW_INIT;
                         break;
+                case MFI_STATE_FW_INIT_2:
+                        max_wait        = 180;
+                        cur_state       = MFI_STATE_FW_INIT_2;
+                        break;
                 case MFI_STATE_DEVICE_SCAN:
                         max_wait        = 180;
                         cur_state       = MFI_STATE_DEVICE_SCAN;
                         prev_abs_reg_val = cur_abs_reg_val;
                         con_log(CL_NONE, (CE_NOTE,
                             "Device scan in progress ...\n"));
                         break;
+                case MFI_STATE_FLUSH_CACHE:
+                        max_wait        = 180;
+                        cur_state       = MFI_STATE_FLUSH_CACHE;
+                        break;
                 default:
                         con_log(CL_ANN1, (CE_NOTE,
                             "mr_sas: Unknown state 0x%x", fw_state));
                         return (ENODEV);
                 }

@@ -2883,19 +3963,19 @@
                         }
                 }
 
                 /* return error if fw_state hasn't changed after max_wait */
                 if (fw_state == cur_state) {
-                        con_log(CL_ANN1, (CE_NOTE,
+                        con_log(CL_ANN1, (CE_WARN,
                             "FW state hasn't changed in %d secs", max_wait));
                         return (ENODEV);
                 }
         };
 
+        if (!instance->tbolt) {
         fw_ctrl = RD_IB_DOORBELL(instance);
-
-        con_log(CL_ANN1, (CE_NOTE,
+                con_log(CL_ANN1, (CE_CONT,
             "mfi_state_transition_to_ready:FW ctrl = 0x%x", fw_ctrl));
 
         /*
          * Write 0xF to the doorbell register to do the following.
          * - Abort all outstanding commands (bit 0).

@@ -2903,14 +3983,16 @@
          * - Discard (possible) low MFA posted in 64-bit mode (bit-2).
          * - Set to release FW to continue running (i.e. BIOS handshake
          *   (bit 3).
          */
         WR_IB_DOORBELL(0xF, instance);
+        }
 
         if (mrsas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) {
-                return (ENODEV);
+                return (EIO);
         }
+
         return (DDI_SUCCESS);
 }
 
 /*
  * get_seq_num

@@ -2923,19 +4005,23 @@
 
         dma_obj_t                       dcmd_dma_obj;
         struct mrsas_cmd                *cmd;
         struct mrsas_dcmd_frame         *dcmd;
         struct mrsas_evt_log_info *eli_tmp;
+        if (instance->tbolt) {
+                cmd = get_raid_msg_mfi_pkt(instance);
+        } else {
         cmd = get_mfi_pkt(instance);
+        }
 
         if (!cmd) {
                 cmn_err(CE_WARN, "mr_sas: failed to get a cmd");
                 DTRACE_PROBE2(seq_num_mfi_err, uint16_t,
                     instance->fw_outstanding, uint16_t, instance->max_fw_cmds);
                 return (ENOMEM);
         }
-        cmd->retry_count_for_ocr = 0;
+
         /* Clear the frame buffer and assign back the context id */
         (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
         ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
             cmd->index);
 

@@ -2949,12 +4035,12 @@
         dcmd_dma_obj.dma_attr.dma_attr_sgllen = 1;
         dcmd_dma_obj.dma_attr.dma_attr_align = 1;
 
         if (mrsas_alloc_dma_obj(instance, &dcmd_dma_obj,
             (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
-                con_log(CL_ANN, (CE_WARN,
-                    "get_seq_num: could not allocate data transfer buffer."));
+                cmn_err(CE_WARN,
+                    "get_seq_num: could not allocate data transfer buffer.");
                 return (DDI_FAILURE);
         }
 
         (void) memset(dcmd_dma_obj.buffer, 0,
             sizeof (struct mrsas_evt_log_info));

@@ -2977,10 +4063,14 @@
             dcmd_dma_obj.dma_cookie[0].dmac_address);
 
         cmd->sync_cmd = MRSAS_TRUE;
         cmd->frame_count = 1;
 
+        if (instance->tbolt) {
+                mr_sas_tbolt_build_mfi_cmd(instance, cmd);
+        }
+
         if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
                 cmn_err(CE_WARN, "get_seq_num: "
                     "failed to issue MRSAS_DCMD_CTRL_EVENT_GET_INFO");
                 ret = DDI_FAILURE;
         } else {

@@ -2991,16 +4081,16 @@
         }
 
         if (mrsas_free_dma_obj(instance, dcmd_dma_obj) != DDI_SUCCESS)
                 ret = DDI_FAILURE;
 
-        if (mrsas_common_check(instance, cmd) != DDI_SUCCESS) {
-                ret = DDI_FAILURE;
+        if (instance->tbolt) {
+                return_raid_msg_mfi_pkt(instance, cmd);
+        } else {
+                return_mfi_pkt(instance, cmd);
         }
 
-        return_mfi_pkt(instance, cmd);
-
         return (ret);
 }
 
 /*
  * start_mfi_aen

@@ -3032,10 +4122,11 @@
         if (ret) {
                 cmn_err(CE_WARN, "start_mfi_aen: aen registration failed");
                 return (-1);
         }
 
+
         return (ret);
 }
 
 /*
  * flush_cache

@@ -3043,22 +4134,24 @@
 static void
 flush_cache(struct mrsas_instance *instance)
 {
         struct mrsas_cmd                *cmd = NULL;
         struct mrsas_dcmd_frame         *dcmd;
-        uint32_t        max_cmd = instance->max_fw_cmds;
+        if (instance->tbolt) {
+                cmd = get_raid_msg_mfi_pkt(instance);
+        } else {
+                cmd = get_mfi_pkt(instance);
+        }
 
-        cmd = instance->cmd_list[max_cmd];
-
         if (!cmd) {
                 con_log(CL_ANN1, (CE_WARN,
                     "flush_cache():Failed to get a cmd for flush_cache"));
                 DTRACE_PROBE2(flush_cache_err, uint16_t,
                     instance->fw_outstanding, uint16_t, instance->max_fw_cmds);
                 return;
         }
-        cmd->retry_count_for_ocr = 0;
+
         /* Clear the frame buffer and assign back the context id */
         (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
         ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
             cmd->index);
 

@@ -3078,37 +4171,51 @@
         ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->mbox.b[0],
             MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE);
 
         cmd->frame_count = 1;
 
+        if (instance->tbolt) {
+                mr_sas_tbolt_build_mfi_cmd(instance, cmd);
+        }
+
         if (instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) {
                 con_log(CL_ANN1, (CE_WARN,
             "flush_cache: failed to issue MFI_DCMD_CTRL_CACHE_FLUSH"));
         }
-        con_log(CL_ANN1, (CE_NOTE, "flush_cache done"));
+        con_log(CL_ANN1, (CE_CONT, "flush_cache done"));
+        if (instance->tbolt) {
+                return_raid_msg_mfi_pkt(instance, cmd);
+        } else {
+                return_mfi_pkt(instance, cmd);
+        }
+
 }
 
 /*
  * service_mfi_aen-     Completes an AEN command
  * @instance:                   Adapter soft state
  * @cmd:                        Command to be completed
  *
  */
-static void
+void
 service_mfi_aen(struct mrsas_instance *instance, struct mrsas_cmd *cmd)
 {
         uint32_t        seq_num;
         struct mrsas_evt_detail *evt_detail =
             (struct mrsas_evt_detail *)instance->mfi_evt_detail_obj.buffer;
         int             rval = 0;
         int             tgt = 0;
+        uint8_t         dtype;
+#ifdef PDSUPPORT
+        mrsas_pd_address_t      *pd_addr;
+#endif
         ddi_acc_handle_t                acc_handle;
 
-        acc_handle = cmd->frame_dma_obj.acc_handle;
+        con_log(CL_ANN, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
 
+        acc_handle = cmd->frame_dma_obj.acc_handle;
         cmd->cmd_status = ddi_get8(acc_handle, &cmd->frame->io.cmd_status);
-
         if (cmd->cmd_status == ENODATA) {
                 cmd->cmd_status = 0;
         }
 
         /*

@@ -3123,11 +4230,11 @@
         }
         /*
          * Check for any ld devices that has changed state. i.e. online
          * or offline.
          */
-        con_log(CL_ANN1, (CE_NOTE,
+        con_log(CL_ANN1, (CE_CONT,
             "AEN: code = %x class = %x locale = %x args = %x",
             ddi_get32(acc_handle, &evt_detail->code),
             evt_detail->cl.members.class,
             ddi_get16(acc_handle, &evt_detail->cl.members.locale),
             ddi_get8(acc_handle, &evt_detail->arg_type)));

@@ -3134,10 +4241,14 @@
 
         switch (ddi_get32(acc_handle, &evt_detail->code)) {
         case MR_EVT_CFG_CLEARED: {
                 for (tgt = 0; tgt < MRDRV_MAX_LD; tgt++) {
                         if (instance->mr_ld_list[tgt].dip != NULL) {
+                                mutex_enter(&instance->config_dev_mtx);
+                                instance->mr_ld_list[tgt].flag =
+                                    (uint8_t)~MRDRV_TGT_VALID;
+                                mutex_exit(&instance->config_dev_mtx);
                                 rval = mrsas_service_evt(instance, tgt, 0,
                                     MRSAS_EVT_UNCONFIG_TGT, NULL);
                                 con_log(CL_ANN1, (CE_WARN,
                                     "mr_sas: CFG CLEARED AEN rval = %d "
                                     "tgt id = %d", rval, tgt));

@@ -3145,10 +4256,14 @@
                 }
                 break;
         }
 
         case MR_EVT_LD_DELETED: {
+                tgt = ddi_get16(acc_handle, &evt_detail->args.ld.target_id);
+                mutex_enter(&instance->config_dev_mtx);
+                instance->mr_ld_list[tgt].flag = (uint8_t)~MRDRV_TGT_VALID;
+                mutex_exit(&instance->config_dev_mtx);
                 rval = mrsas_service_evt(instance,
                     ddi_get16(acc_handle, &evt_detail->args.ld.target_id), 0,
                     MRSAS_EVT_UNCONFIG_TGT, NULL);
                 con_log(CL_ANN1, (CE_WARN, "mr_sas: LD DELETED AEN rval = %d "
                     "tgt id = %d index = %d", rval,

@@ -3165,10 +4280,90 @@
                     "tgt id = %d index = %d", rval,
                     ddi_get16(acc_handle, &evt_detail->args.ld.target_id),
                     ddi_get8(acc_handle, &evt_detail->args.ld.ld_index)));
                 break;
         } /* End of MR_EVT_LD_CREATED */
+
+#ifdef PDSUPPORT
+        case MR_EVT_PD_REMOVED_EXT: {
+                if (instance->tbolt) {
+                        pd_addr = &evt_detail->args.pd_addr;
+                        dtype = pd_addr->scsi_dev_type;
+                        con_log(CL_DLEVEL1, (CE_NOTE,
+                            " MR_EVT_PD_REMOVED_EXT: dtype = %x,"
+                            " arg_type = %d ", dtype, evt_detail->arg_type));
+                        tgt = ddi_get16(acc_handle,
+                            &evt_detail->args.pd.device_id);
+                        mutex_enter(&instance->config_dev_mtx);
+                        instance->mr_tbolt_pd_list[tgt].flag =
+                            (uint8_t)~MRDRV_TGT_VALID;
+                        mutex_exit(&instance->config_dev_mtx);
+                        rval = mrsas_service_evt(instance, ddi_get16(
+                            acc_handle, &evt_detail->args.pd.device_id),
+                            1, MRSAS_EVT_UNCONFIG_TGT, NULL);
+                        con_log(CL_ANN1, (CE_WARN, "mr_sas: PD_REMOVED:"
+                            "rval = %d tgt id = %d ", rval,
+                            ddi_get16(acc_handle,
+                            &evt_detail->args.pd.device_id)));
+                }
+                break;
+        } /* End of MR_EVT_PD_REMOVED_EXT */
+
+        case MR_EVT_PD_INSERTED_EXT: {
+                if (instance->tbolt) {
+                        rval = mrsas_service_evt(instance,
+                            ddi_get16(acc_handle,
+                            &evt_detail->args.pd.device_id),
+                            1, MRSAS_EVT_CONFIG_TGT, NULL);
+                        con_log(CL_ANN1, (CE_WARN, "mr_sas: PD_INSERTEDi_EXT:"
+                            "rval = %d tgt id = %d ", rval,
+                            ddi_get16(acc_handle,
+                            &evt_detail->args.pd.device_id)));
+                }
+                break;
+        } /* End of MR_EVT_PD_INSERTED_EXT */
+
+        case MR_EVT_PD_STATE_CHANGE: {
+                if (instance->tbolt) {
+                        tgt = ddi_get16(acc_handle,
+                            &evt_detail->args.pd.device_id);
+                        if ((evt_detail->args.pd_state.prevState ==
+                            PD_SYSTEM) &&
+                            (evt_detail->args.pd_state.newState != PD_SYSTEM)) {
+                                mutex_enter(&instance->config_dev_mtx);
+                                instance->mr_tbolt_pd_list[tgt].flag =
+                                    (uint8_t)~MRDRV_TGT_VALID;
+                                mutex_exit(&instance->config_dev_mtx);
+                                rval = mrsas_service_evt(instance,
+                                    ddi_get16(acc_handle,
+                                    &evt_detail->args.pd.device_id),
+                                    1, MRSAS_EVT_UNCONFIG_TGT, NULL);
+                                con_log(CL_ANN1, (CE_WARN, "mr_sas: PD_REMOVED:"
+                                    "rval = %d tgt id = %d ", rval,
+                                    ddi_get16(acc_handle,
+                                    &evt_detail->args.pd.device_id)));
+                                break;
+                        }
+                        if ((evt_detail->args.pd_state.prevState
+                            == UNCONFIGURED_GOOD) &&
+                            (evt_detail->args.pd_state.newState == PD_SYSTEM)) {
+                                rval = mrsas_service_evt(instance,
+                                    ddi_get16(acc_handle,
+                                    &evt_detail->args.pd.device_id),
+                                    1, MRSAS_EVT_CONFIG_TGT, NULL);
+                                con_log(CL_ANN1, (CE_WARN,
+                                    "mr_sas: PD_INSERTED: rval = %d "
+                                    " tgt id = %d ", rval,
+                                    ddi_get16(acc_handle,
+                                    &evt_detail->args.pd.device_id)));
+                                break;
+                        }
+                }
+                break;
+        }
+#endif
+
         } /* End of Main Switch */
 
         /* get copy of seq_num and class/locale for re-registration */
         seq_num = ddi_get32(acc_handle, &evt_detail->seq_num);
         seq_num++;

@@ -3180,10 +4375,13 @@
 
         instance->aen_seq_num = seq_num;
 
         cmd->frame_count = 1;
 
+        cmd->retry_count_for_ocr = 0;
+        cmd->drv_pkt_time = 0;
+
         /* Issue the aen registration frame */
         instance->func_ptr->issue_cmd(cmd, instance);
 }
 
 /*

@@ -3202,18 +4400,20 @@
         cmd->cmd_status = ddi_get8(cmd->frame_dma_obj.acc_handle,
             &cmd->frame->io.cmd_status);
 
         cmd->sync_cmd = MRSAS_FALSE;
 
-        if (cmd->cmd_status == ENODATA) {
-                cmd->cmd_status = 0;
-        }
-
         con_log(CL_ANN1, (CE_NOTE, "complete_cmd_in_sync_mode called %p \n",
             (void *)cmd));
 
+        mutex_enter(&instance->int_cmd_mtx);
+        if (cmd->cmd_status == ENODATA) {
+                cmd->cmd_status = 0;
+        }
         cv_broadcast(&instance->int_cmd_cv);
+        mutex_exit(&instance->int_cmd_mtx);
+
 }
 
 /*
  * Call this function inside mrsas_softintr.
  * mrsas_initiate_ocr_if_fw_is_faulty  - Initiates OCR if FW status is faulty

@@ -3227,24 +4427,26 @@
         uint32_t        fw_state;
 
         cur_abs_reg_val =  instance->func_ptr->read_fw_status_reg(instance);
         fw_state = cur_abs_reg_val & MFI_STATE_MASK;
         if (fw_state == MFI_STATE_FAULT) {
-
                 if (instance->disable_online_ctrl_reset == 1) {
-                con_log(CL_ANN1, (CE_NOTE,
+                        cmn_err(CE_WARN,
                     "mrsas_initiate_ocr_if_fw_is_faulty: "
                     "FW in Fault state, detected in ISR: "
-                    "FW doesn't support ocr "));
+                            "FW doesn't support ocr ");
+
                 return (ADAPTER_RESET_NOT_REQUIRED);
                 } else {
-                con_log(CL_ANN1, (CE_NOTE,
-                    "mrsas_initiate_ocr_if_fw_is_faulty: "
-                    "FW in Fault state, detected in ISR: FW supports ocr "));
+                        con_log(CL_ANN, (CE_NOTE,
+                            "mrsas_initiate_ocr_if_fw_is_faulty: FW in Fault "
+                            "state, detected in ISR: FW supports ocr "));
+
                         return (ADAPTER_RESET_REQUIRED);
                 }
         }
+
         return (ADAPTER_RESET_NOT_REQUIRED);
 }
 
 /*
  * mrsas_softintr - The Software ISR

@@ -3262,11 +4464,11 @@
         struct mlist_head       *pos, *next;
         mlist_t                 process_list;
         struct mrsas_header     *hdr;
         struct scsi_arq_status  *arqstat;
 
-        con_log(CL_ANN1, (CE_CONT, "mrsas_softintr called"));
+        con_log(CL_ANN1, (CE_NOTE, "mrsas_softintr() called."));
 
         ASSERT(instance);
 
         mutex_enter(&instance->completed_pool_mtx);
 

@@ -3339,11 +4541,11 @@
                         pkt->pkt_statistics     = 0;
                         pkt->pkt_state = STATE_GOT_BUS
                             | STATE_GOT_TARGET | STATE_SENT_CMD
                             | STATE_XFERRED_DATA | STATE_GOT_STATUS;
 
-                        con_log(CL_ANN1, (CE_CONT,
+                        con_log(CL_ANN, (CE_CONT,
                             "CDB[0] = %x completed for %s: size %lx context %x",
                             pkt->pkt_cdbp[0], ((acmd->islogical) ? "LD" : "PD"),
                             acmd->cmd_dmacount, hdr->context));
                         DTRACE_PROBE3(softintr_cdb, uint8_t, pkt->pkt_cdbp[0],
                             uint_t, acmd->cmd_cdblen, ulong_t,

@@ -3392,21 +4594,19 @@
                                     (CE_WARN, "Initialization in Progress"));
                                 pkt->pkt_reason = CMD_TRAN_ERR;
 
                                 break;
                         case MFI_STAT_SCSI_DONE_WITH_ERROR:
-                                con_log(CL_ANN1, (CE_CONT, "scsi_done error"));
+                                con_log(CL_ANN, (CE_CONT, "scsi_done error"));
 
                                 pkt->pkt_reason = CMD_CMPLT;
                                 ((struct scsi_status *)
                                     pkt->pkt_scbp)->sts_chk = 1;
 
                                 if (pkt->pkt_cdbp[0] == SCMD_TEST_UNIT_READY) {
-
                                         con_log(CL_ANN,
                                             (CE_WARN, "TEST_UNIT_READY fail"));
-
                                 } else {
                                         pkt->pkt_state |= STATE_ARQ_DONE;
                                         arqstat = (void *)(pkt->pkt_scbp);
                                         arqstat->sts_rqpkt_reason = CMD_CMPLT;
                                         arqstat->sts_rqpkt_resid = 0;

@@ -3419,18 +4619,17 @@
                                         ddi_rep_get8(
                                             cmd->frame_dma_obj.acc_handle,
                                             (uint8_t *)
                                             &(arqstat->sts_sensedata),
                                             cmd->sense,
-                                            acmd->cmd_scblen -
-                                            offsetof(struct scsi_arq_status,
-                                            sts_sensedata), DDI_DEV_AUTOINCR);
+                                            sizeof (struct scsi_extended_sense),
+                                            DDI_DEV_AUTOINCR);
                         }
                                 break;
                         case MFI_STAT_LD_OFFLINE:
                         case MFI_STAT_DEVICE_NOT_FOUND:
-                                con_log(CL_ANN1, (CE_CONT,
+                                con_log(CL_ANN, (CE_CONT,
                                 "mrsas_softintr:device not found error"));
                                 pkt->pkt_reason = CMD_DEV_GONE;
                                 pkt->pkt_statistics  = STAT_DISCON;
                                 break;
                         case MFI_STAT_LD_LBA_OUT_OF_RANGE:

@@ -3486,23 +4685,26 @@
 
                         /* Call the callback routine */
                         if (((pkt->pkt_flags & FLAG_NOINTR) == 0) &&
                             pkt->pkt_comp) {
 
-                                con_log(CL_ANN1, (CE_NOTE, "mrsas_softintr: "
+                                con_log(CL_DLEVEL1, (CE_NOTE, "mrsas_softintr: "
                                     "posting to scsa cmd %p index %x pkt %p "
                                     "time %llx", (void *)cmd, cmd->index,
                                     (void *)pkt, gethrtime()));
                                 (*pkt->pkt_comp)(pkt);
 
                         }
+
                         return_mfi_pkt(instance, cmd);
                         break;
+
                 case MFI_CMD_OP_SMP:
                 case MFI_CMD_OP_STP:
                         complete_cmd_in_sync_mode(instance, cmd);
                         break;
+
                 case MFI_CMD_OP_DCMD:
                         /* see if got an event notification */
                         if (ddi_get32(cmd->frame_dma_obj.acc_handle,
                             &cmd->frame->dcmd.opcode) ==
                             MR_DCMD_CTRL_EVENT_WAIT) {

@@ -3519,18 +4721,20 @@
                         } else {
                                 complete_cmd_in_sync_mode(instance, cmd);
                         }
 
                         break;
+
                 case MFI_CMD_OP_ABORT:
-                        con_log(CL_ANN, (CE_WARN, "MFI_CMD_OP_ABORT complete"));
+                        con_log(CL_ANN, (CE_NOTE, "MFI_CMD_OP_ABORT complete"));
                         /*
                          * MFI_CMD_OP_ABORT successfully completed
                          * in the synchronous mode
                          */
                         complete_cmd_in_sync_mode(instance, cmd);
                         break;
+
                 default:
                         mrsas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE);
                         ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
 
                         if (cmd->pkt != NULL) {

@@ -3561,11 +4765,11 @@
 /*
  * mrsas_alloc_dma_obj
  *
  * Allocate the memory and other resources for an dma object.
  */
-static int
+int
 mrsas_alloc_dma_obj(struct mrsas_instance *instance, dma_obj_t *obj,
     uchar_t endian_flags)
 {
         int     i;
         size_t  alen = 0;

@@ -3640,14 +4844,22 @@
  * mrsas_free_dma_obj(struct mrsas_instance *, dma_obj_t)
  *
  * De-allocate the memory and other resources for an dma object, which must
  * have been alloated by a previous call to mrsas_alloc_dma_obj()
  */
-static int
+int
 mrsas_free_dma_obj(struct mrsas_instance *instance, dma_obj_t obj)
 {
 
+        if ((obj.dma_handle == NULL) || (obj.acc_handle == NULL)) {
+                return (DDI_SUCCESS);
+        }
+
+        /*
+         * NOTE: These check-handle functions fail if *_handle == NULL, but
+         * this function succeeds because of the previous check.
+         */
         if (mrsas_check_dma_handle(obj.dma_handle) != DDI_SUCCESS) {
                 ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
                 return (DDI_FAILURE);
         }
 

@@ -3657,21 +4869,21 @@
         }
 
         (void) ddi_dma_unbind_handle(obj.dma_handle);
         ddi_dma_mem_free(&obj.acc_handle);
         ddi_dma_free_handle(&obj.dma_handle);
-
+        obj.acc_handle = NULL;
         return (DDI_SUCCESS);
 }
 
 /*
  * mrsas_dma_alloc(instance_t *, struct scsi_pkt *, struct buf *,
  * int, int (*)())
  *
  * Allocate dma resources for a new scsi command
  */
-static int
+int
 mrsas_dma_alloc(struct mrsas_instance *instance, struct scsi_pkt *pkt,
     struct buf *bp, int flags, int (*callback)())
 {
         int     dma_flags;
         int     (*cb)(caddr_t);

@@ -3703,10 +4915,17 @@
 
         cb = (callback == NULL_FUNC) ? DDI_DMA_DONTWAIT : DDI_DMA_SLEEP;
 
         tmp_dma_attr.dma_attr_sgllen = instance->max_num_sge;
         tmp_dma_attr.dma_attr_addr_hi = 0xffffffffffffffffull;
+        if (instance->tbolt) {
+                /* OCR-RESET FIX */
+                tmp_dma_attr.dma_attr_count_max =
+                    (U64)mrsas_tbolt_max_cap_maxxfer;  /* limit to 256K */
+                tmp_dma_attr.dma_attr_maxxfer =
+                    (U64)mrsas_tbolt_max_cap_maxxfer;  /* limit to 256K */
+        }
 
         if ((i = ddi_dma_alloc_handle(instance->dip, &tmp_dma_attr,
             cb, 0, &acmd->cmd_dmahandle)) != DDI_SUCCESS) {
                 switch (i) {
                 case DDI_DMA_BADATTR:

@@ -3814,11 +5033,11 @@
  * mrsas_dma_move(struct mrsas_instance *, struct scsi_pkt *, struct buf *)
  *
  * move dma resources to next dma window
  *
  */
-static int
+int
 mrsas_dma_move(struct mrsas_instance *instance, struct scsi_pkt *pkt,
     struct buf *bp)
 {
         int     i = 0;
 

@@ -3886,10 +5105,11 @@
 {
         uint16_t        flags = 0;
         uint32_t        i;
         uint32_t        context;
         uint32_t        sge_bytes;
+        uint32_t        tmp_data_xfer_len;
         ddi_acc_handle_t acc_handle;
         struct mrsas_cmd                *cmd;
         struct mrsas_sge64              *mfi_sgl;
         struct mrsas_sge_ieee           *mfi_sgl_ieee;
         struct scsa_cmd                 *acmd = PKT2CMD(pkt);

@@ -3906,12 +5126,10 @@
                 DTRACE_PROBE2(build_cmd_mfi_err, uint16_t,
                     instance->fw_outstanding, uint16_t, instance->max_fw_cmds);
                 return (NULL);
         }
 
-        cmd->retry_count_for_ocr = 0;
-
         acc_handle = cmd->frame_dma_obj.acc_handle;
 
         /* Clear the frame buffer and assign back the context id */
         (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
         ddi_put32(acc_handle, &cmd->frame->hdr.context, cmd->index);

@@ -3960,10 +5178,14 @@
 
         case SCMD_READ:
         case SCMD_WRITE:
         case SCMD_READ_G1:
         case SCMD_WRITE_G1:
+        case SCMD_READ_G4:
+        case SCMD_WRITE_G4:
+        case SCMD_READ_G5:
+        case SCMD_WRITE_G5:
                 if (acmd->islogical) {
                         ldio = (struct mrsas_io_frame *)cmd->frame;
 
                         /*
                          * preare the Logical IO frame:

@@ -3999,54 +5221,58 @@
                         }
 
                         context = ddi_get32(acc_handle, &ldio->context);
 
                         if (acmd->cmd_cdblen == CDB_GROUP0) {
+                                /* 6-byte cdb */
                                 ddi_put32(acc_handle, &ldio->lba_count, (
                                     (uint16_t)(pkt->pkt_cdbp[4])));
 
                                 ddi_put32(acc_handle, &ldio->start_lba_lo, (
                                     ((uint32_t)(pkt->pkt_cdbp[3])) |
                                     ((uint32_t)(pkt->pkt_cdbp[2]) << 8) |
                                     ((uint32_t)((pkt->pkt_cdbp[1]) & 0x1F)
                                     << 16)));
                         } else if (acmd->cmd_cdblen == CDB_GROUP1) {
+                                /* 10-byte cdb */
                                 ddi_put32(acc_handle, &ldio->lba_count, (
                                     ((uint16_t)(pkt->pkt_cdbp[8])) |
                                     ((uint16_t)(pkt->pkt_cdbp[7]) << 8)));
 
                                 ddi_put32(acc_handle, &ldio->start_lba_lo, (
                                     ((uint32_t)(pkt->pkt_cdbp[5])) |
                                     ((uint32_t)(pkt->pkt_cdbp[4]) << 8) |
                                     ((uint32_t)(pkt->pkt_cdbp[3]) << 16) |
                                     ((uint32_t)(pkt->pkt_cdbp[2]) << 24)));
-                        } else if (acmd->cmd_cdblen == CDB_GROUP2) {
+                        } else if (acmd->cmd_cdblen == CDB_GROUP5) {
+                                /* 12-byte cdb */
                                 ddi_put32(acc_handle, &ldio->lba_count, (
-                                    ((uint16_t)(pkt->pkt_cdbp[9])) |
-                                    ((uint16_t)(pkt->pkt_cdbp[8]) << 8) |
-                                    ((uint16_t)(pkt->pkt_cdbp[7]) << 16) |
-                                    ((uint16_t)(pkt->pkt_cdbp[6]) << 24)));
+                                    ((uint32_t)(pkt->pkt_cdbp[9])) |
+                                    ((uint32_t)(pkt->pkt_cdbp[8]) << 8) |
+                                    ((uint32_t)(pkt->pkt_cdbp[7]) << 16) |
+                                    ((uint32_t)(pkt->pkt_cdbp[6]) << 24)));
 
                                 ddi_put32(acc_handle, &ldio->start_lba_lo, (
                                     ((uint32_t)(pkt->pkt_cdbp[5])) |
                                     ((uint32_t)(pkt->pkt_cdbp[4]) << 8) |
                                     ((uint32_t)(pkt->pkt_cdbp[3]) << 16) |
                                     ((uint32_t)(pkt->pkt_cdbp[2]) << 24)));
-                        } else if (acmd->cmd_cdblen == CDB_GROUP3) {
+                        } else if (acmd->cmd_cdblen == CDB_GROUP4) {
+                                /* 16-byte cdb */
                                 ddi_put32(acc_handle, &ldio->lba_count, (
-                                    ((uint16_t)(pkt->pkt_cdbp[13])) |
-                                    ((uint16_t)(pkt->pkt_cdbp[12]) << 8) |
-                                    ((uint16_t)(pkt->pkt_cdbp[11]) << 16) |
-                                    ((uint16_t)(pkt->pkt_cdbp[10]) << 24)));
+                                    ((uint32_t)(pkt->pkt_cdbp[13])) |
+                                    ((uint32_t)(pkt->pkt_cdbp[12]) << 8) |
+                                    ((uint32_t)(pkt->pkt_cdbp[11]) << 16) |
+                                    ((uint32_t)(pkt->pkt_cdbp[10]) << 24)));
 
                                 ddi_put32(acc_handle, &ldio->start_lba_lo, (
                                     ((uint32_t)(pkt->pkt_cdbp[9])) |
                                     ((uint32_t)(pkt->pkt_cdbp[8]) << 8) |
                                     ((uint32_t)(pkt->pkt_cdbp[7]) << 16) |
                                     ((uint32_t)(pkt->pkt_cdbp[6]) << 24)));
 
-                                ddi_put32(acc_handle, &ldio->start_lba_lo, (
+                                ddi_put32(acc_handle, &ldio->start_lba_hi, (
                                     ((uint32_t)(pkt->pkt_cdbp[5])) |
                                     ((uint32_t)(pkt->pkt_cdbp[4]) << 8) |
                                     ((uint32_t)(pkt->pkt_cdbp[3]) << 16) |
                                     ((uint32_t)(pkt->pkt_cdbp[2]) << 24)));
                         }

@@ -4088,12 +5314,16 @@
                 ddi_put8(acc_handle, &pthru->target_id, acmd->device_id);
                 ddi_put8(acc_handle, &pthru->lun, 0);
                 ddi_put8(acc_handle, &pthru->cdb_len, acmd->cmd_cdblen);
                 ddi_put16(acc_handle, &pthru->timeout, 0);
                 ddi_put16(acc_handle, &pthru->flags, flags);
+                tmp_data_xfer_len = 0;
+                for (i = 0; i < acmd->cmd_cookiecnt; i++) {
+                        tmp_data_xfer_len += acmd->cmd_dmacookies[i].dmac_size;
+                }
                 ddi_put32(acc_handle, &pthru->data_xfer_len,
-                    acmd->cmd_dmacount);
+                    tmp_data_xfer_len);
                 ddi_put8(acc_handle, &pthru->sge_count, acmd->cmd_cookiecnt);
                 if (instance->flag_ieee) {
                         mfi_sgl_ieee = (struct mrsas_sge_ieee *)&pthru->sgl;
                 } else {
                         mfi_sgl = (struct mrsas_sge64 *)&pthru->sgl;

@@ -4140,11 +5370,20 @@
                 cmd->frame_count = 8;
         }
 
         return (cmd);
 }
+
 #ifndef __sparc
+/*
+ * wait_for_outstanding -       Wait for all outstanding cmds
+ * @instance:                           Adapter soft state
+ *
+ * This function waits for upto MRDRV_RESET_WAIT_TIME seconds for FW to
+ * complete all its outstanding commands. Returns error if one or more IOs
+ * are pending after this time period.
+ */
 static int
 wait_for_outstanding(struct mrsas_instance *instance)
 {
         int             i;
         uint32_t        wait_time = 90;

@@ -4151,10 +5390,11 @@
 
         for (i = 0; i < wait_time; i++) {
                 if (!instance->fw_outstanding) {
                         break;
                 }
+
                 drv_usecwait(MILLISEC); /* wait for 1000 usecs */;
         }
 
         if (instance->fw_outstanding) {
                 return (1);

@@ -4161,10 +5401,11 @@
         }
 
         return (0);
 }
 #endif  /* __sparc */
+
 /*
  * issue_mfi_pthru
  */
 static int
 issue_mfi_pthru(struct mrsas_instance *instance, struct mrsas_ioctl *ioctl,

@@ -4171,10 +5412,11 @@
     struct mrsas_cmd *cmd, int mode)
 {
         void            *ubuf;
         uint32_t        kphys_addr = 0;
         uint32_t        xferlen = 0;
+        uint32_t        new_xfer_length = 0;
         uint_t          model;
         ddi_acc_handle_t        acc_handle = cmd->frame_dma_obj.acc_handle;
         dma_obj_t                       pthru_dma_obj;
         struct mrsas_pthru_frame        *kpthru;
         struct mrsas_pthru_frame        *pthru;

@@ -4181,37 +5423,40 @@
         int i;
         pthru = &cmd->frame->pthru;
         kpthru = (struct mrsas_pthru_frame *)&ioctl->frame[0];
 
         if (instance->adapterresetinprogress) {
-                con_log(CL_ANN1, (CE_NOTE, "issue_mfi_pthru: Reset flag set, "
+                con_log(CL_ANN1, (CE_WARN, "issue_mfi_pthru: Reset flag set, "
                 "returning mfi_pkt and setting TRAN_BUSY\n"));
                 return (DDI_FAILURE);
         }
         model = ddi_model_convert_from(mode & FMODELS);
         if (model == DDI_MODEL_ILP32) {
-                con_log(CL_ANN1, (CE_NOTE, "issue_mfi_pthru: DDI_MODEL_LP32"));
+                con_log(CL_ANN1, (CE_CONT, "issue_mfi_pthru: DDI_MODEL_LP32"));
 
                 xferlen = kpthru->sgl.sge32[0].length;
 
                 ubuf    = (void *)(ulong_t)kpthru->sgl.sge32[0].phys_addr;
         } else {
 #ifdef _ILP32
-                con_log(CL_ANN1, (CE_NOTE, "issue_mfi_pthru: DDI_MODEL_LP32"));
+                con_log(CL_ANN1, (CE_CONT, "issue_mfi_pthru: DDI_MODEL_LP32"));
                 xferlen = kpthru->sgl.sge32[0].length;
                 ubuf    = (void *)(ulong_t)kpthru->sgl.sge32[0].phys_addr;
 #else
-                con_log(CL_ANN1, (CE_NOTE, "issue_mfi_pthru: DDI_MODEL_LP64"));
+                con_log(CL_ANN1, (CE_CONT, "issue_mfi_pthru: DDI_MODEL_LP64"));
                 xferlen = kpthru->sgl.sge64[0].length;
                 ubuf    = (void *)(ulong_t)kpthru->sgl.sge64[0].phys_addr;
 #endif
         }
 
         if (xferlen) {
                 /* means IOCTL requires DMA */
                 /* allocate the data transfer buffer */
-                pthru_dma_obj.size = xferlen;
+                /* pthru_dma_obj.size = xferlen; */
+                MRSAS_GET_BOUNDARY_ALIGNED_LEN(xferlen, new_xfer_length,
+                    PAGESIZE);
+                pthru_dma_obj.size = new_xfer_length;
                 pthru_dma_obj.dma_attr = mrsas_generic_dma_attr;
                 pthru_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
                 pthru_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
                 pthru_dma_obj.dma_attr.dma_attr_sgllen = 1;
                 pthru_dma_obj.dma_attr.dma_attr_align = 1;

@@ -4241,11 +5486,11 @@
 
                 kphys_addr = pthru_dma_obj.dma_cookie[0].dmac_address;
         }
 
         ddi_put8(acc_handle, &pthru->cmd, kpthru->cmd);
-        ddi_put8(acc_handle, &pthru->sense_len, 0);
+        ddi_put8(acc_handle, &pthru->sense_len, SENSE_LENGTH);
         ddi_put8(acc_handle, &pthru->cmd_status, 0);
         ddi_put8(acc_handle, &pthru->scsi_status, 0);
         ddi_put8(acc_handle, &pthru->target_id, kpthru->target_id);
         ddi_put8(acc_handle, &pthru->lun, kpthru->lun);
         ddi_put8(acc_handle, &pthru->cdb_len, kpthru->cdb_len);

@@ -4252,12 +5497,12 @@
         ddi_put8(acc_handle, &pthru->sge_count, kpthru->sge_count);
         ddi_put16(acc_handle, &pthru->timeout, kpthru->timeout);
         ddi_put32(acc_handle, &pthru->data_xfer_len, kpthru->data_xfer_len);
 
         ddi_put32(acc_handle, &pthru->sense_buf_phys_addr_hi, 0);
-        /* pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr; */
-        ddi_put32(acc_handle, &pthru->sense_buf_phys_addr_lo, 0);
+        pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr;
+        /* ddi_put32(acc_handle, &pthru->sense_buf_phys_addr_lo, 0); */
 
         ddi_rep_put8(acc_handle, (uint8_t *)kpthru->cdb, (uint8_t *)pthru->cdb,
             pthru->cdb_len, DDI_DEV_AUTOINCR);
 
         ddi_put16(acc_handle, &pthru->flags, kpthru->flags & ~MFI_FRAME_SGL64);

@@ -4265,10 +5510,14 @@
         ddi_put32(acc_handle, &pthru->sgl.sge32[0].phys_addr, kphys_addr);
 
         cmd->sync_cmd = MRSAS_TRUE;
         cmd->frame_count = 1;
 
+        if (instance->tbolt) {
+                mr_sas_tbolt_build_mfi_cmd(instance, cmd);
+        }
+
         if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
                 con_log(CL_ANN, (CE_WARN,
                     "issue_mfi_pthru: fw_ioctl failed"));
         } else {
                 if (xferlen && kpthru->flags & MFI_FRAME_DIR_READ) {

@@ -4286,15 +5535,39 @@
         }
 
         kpthru->cmd_status = ddi_get8(acc_handle, &pthru->cmd_status);
         kpthru->scsi_status = ddi_get8(acc_handle, &pthru->scsi_status);
 
-        con_log(CL_ANN, (CE_NOTE, "issue_mfi_pthru: cmd_status %x, "
+        con_log(CL_ANN, (CE_CONT, "issue_mfi_pthru: cmd_status %x, "
             "scsi_status %x", kpthru->cmd_status, kpthru->scsi_status));
         DTRACE_PROBE3(issue_pthru, uint8_t, kpthru->cmd, uint8_t,
             kpthru->cmd_status, uint8_t, kpthru->scsi_status);
 
+        if (kpthru->sense_len) {
+                uint_t sense_len = SENSE_LENGTH;
+                void *sense_ubuf =
+                    (void *)(ulong_t)kpthru->sense_buf_phys_addr_lo;
+                if (kpthru->sense_len <= SENSE_LENGTH) {
+                        sense_len = kpthru->sense_len;
+                }
+
+                for (i = 0; i < sense_len; i++) {
+                        if (ddi_copyout(
+                            (uint8_t *)cmd->sense+i,
+                            (uint8_t *)sense_ubuf+i, 1, mode)) {
+                                con_log(CL_ANN, (CE_WARN,
+                                    "issue_mfi_pthru : "
+                                    "copy to user space failed"));
+                        }
+                        con_log(CL_DLEVEL1, (CE_WARN,
+                            "Copying Sense info sense_buff[%d] = 0x%X",
+                            i, *((uint8_t *)cmd->sense + i)));
+                }
+        }
+        (void) ddi_dma_sync(cmd->frame_dma_obj.dma_handle, 0, 0,
+            DDI_DMA_SYNC_FORDEV);
+
         if (xferlen) {
                 /* free kernel buffer */
                 if (mrsas_free_dma_obj(instance, pthru_dma_obj) != DDI_SUCCESS)
                         return (DDI_FAILURE);
         }

@@ -4310,56 +5583,62 @@
     struct mrsas_cmd *cmd, int mode)
 {
         void            *ubuf;
         uint32_t        kphys_addr = 0;
         uint32_t        xferlen = 0;
+        uint32_t        new_xfer_length = 0;
         uint32_t        model;
         dma_obj_t       dcmd_dma_obj;
         struct mrsas_dcmd_frame *kdcmd;
         struct mrsas_dcmd_frame *dcmd;
         ddi_acc_handle_t        acc_handle = cmd->frame_dma_obj.acc_handle;
         int i;
         dcmd = &cmd->frame->dcmd;
         kdcmd = (struct mrsas_dcmd_frame *)&ioctl->frame[0];
+
         if (instance->adapterresetinprogress) {
                 con_log(CL_ANN1, (CE_NOTE, "Reset flag set, "
-                "returning mfi_pkt and setting TRAN_BUSY\n"));
+                "returning mfi_pkt and setting TRAN_BUSY"));
                 return (DDI_FAILURE);
         }
         model = ddi_model_convert_from(mode & FMODELS);
         if (model == DDI_MODEL_ILP32) {
-                con_log(CL_ANN1, (CE_NOTE, "issue_mfi_dcmd: DDI_MODEL_ILP32"));
+                con_log(CL_ANN1, (CE_CONT, "issue_mfi_dcmd: DDI_MODEL_ILP32"));
 
                 xferlen = kdcmd->sgl.sge32[0].length;
 
                 ubuf    = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr;
         } else {
 #ifdef _ILP32
-                con_log(CL_ANN1, (CE_NOTE, "issue_mfi_dcmd: DDI_MODEL_ILP32"));
+                con_log(CL_ANN1, (CE_CONT, "issue_mfi_dcmd: DDI_MODEL_ILP32"));
                 xferlen = kdcmd->sgl.sge32[0].length;
                 ubuf    = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr;
 #else
-                con_log(CL_ANN1, (CE_NOTE, "issue_mfi_dcmd: DDI_MODEL_LP64"));
+                con_log(CL_ANN1, (CE_CONT, "issue_mfi_dcmd: DDI_MODEL_LP64"));
                 xferlen = kdcmd->sgl.sge64[0].length;
                 ubuf    = (void *)(ulong_t)kdcmd->sgl.sge64[0].phys_addr;
 #endif
         }
         if (xferlen) {
                 /* means IOCTL requires DMA */
                 /* allocate the data transfer buffer */
-                dcmd_dma_obj.size = xferlen;
+                /* dcmd_dma_obj.size = xferlen; */
+                MRSAS_GET_BOUNDARY_ALIGNED_LEN(xferlen, new_xfer_length,
+                    PAGESIZE);
+                dcmd_dma_obj.size = new_xfer_length;
                 dcmd_dma_obj.dma_attr = mrsas_generic_dma_attr;
                 dcmd_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
                 dcmd_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
                 dcmd_dma_obj.dma_attr.dma_attr_sgllen = 1;
                 dcmd_dma_obj.dma_attr.dma_attr_align = 1;
 
                 /* allocate kernel buffer for DMA */
                 if (mrsas_alloc_dma_obj(instance, &dcmd_dma_obj,
                     (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
-                        con_log(CL_ANN, (CE_WARN, "issue_mfi_dcmd: "
-                            "could not allocate data transfer buffer."));
+                                con_log(CL_ANN,
+                                    (CE_WARN, "issue_mfi_dcmd: could not "
+                                    "allocate data transfer buffer."));
                         return (DDI_FAILURE);
                 }
                 (void) memset(dcmd_dma_obj.buffer, 0, xferlen);
 
                 /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */

@@ -4394,10 +5673,14 @@
         ddi_put32(acc_handle, &dcmd->sgl.sge32[0].phys_addr, kphys_addr);
 
         cmd->sync_cmd = MRSAS_TRUE;
         cmd->frame_count = 1;
 
+        if (instance->tbolt) {
+                mr_sas_tbolt_build_mfi_cmd(instance, cmd);
+        }
+
         if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
                 con_log(CL_ANN, (CE_WARN, "issue_mfi_dcmd: fw_ioctl failed"));
         } else {
                 if (xferlen && (kdcmd->flags & MFI_FRAME_DIR_READ)) {
                         for (i = 0; i < xferlen; i++) {

@@ -4413,10 +5696,12 @@
                         }
                 }
         }
 
         kdcmd->cmd_status = ddi_get8(acc_handle, &dcmd->cmd_status);
+        con_log(CL_ANN,
+            (CE_CONT, "issue_mfi_dcmd: cmd_status %x", kdcmd->cmd_status));
         DTRACE_PROBE3(issue_dcmd, uint32_t, kdcmd->opcode, uint8_t,
             kdcmd->cmd, uint8_t, kdcmd->cmd_status);
 
         if (xferlen) {
                 /* free kernel buffer */

@@ -4436,10 +5721,12 @@
 {
         void            *request_ubuf;
         void            *response_ubuf;
         uint32_t        request_xferlen = 0;
         uint32_t        response_xferlen = 0;
+        uint32_t        new_xfer_length1 = 0;
+        uint32_t        new_xfer_length2 = 0;
         uint_t          model;
         dma_obj_t                       request_dma_obj;
         dma_obj_t                       response_dma_obj;
         ddi_acc_handle_t        acc_handle = cmd->frame_dma_obj.acc_handle;
         struct mrsas_smp_frame          *ksmp;

@@ -4453,48 +5740,48 @@
 
         smp = &cmd->frame->smp;
         ksmp = (struct mrsas_smp_frame *)&ioctl->frame[0];
 
         if (instance->adapterresetinprogress) {
-                con_log(CL_ANN1, (CE_NOTE, "Reset flag set, "
+                con_log(CL_ANN1, (CE_WARN, "Reset flag set, "
                 "returning mfi_pkt and setting TRAN_BUSY\n"));
                 return (DDI_FAILURE);
         }
         model = ddi_model_convert_from(mode & FMODELS);
         if (model == DDI_MODEL_ILP32) {
-                con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: DDI_MODEL_ILP32"));
+                con_log(CL_ANN1, (CE_CONT, "issue_mfi_smp: DDI_MODEL_ILP32"));
 
                 sge32                   = &ksmp->sgl[0].sge32[0];
                 response_xferlen        = sge32[0].length;
                 request_xferlen         = sge32[1].length;
-                con_log(CL_ANN, (CE_NOTE, "issue_mfi_smp: "
+                con_log(CL_ANN, (CE_CONT, "issue_mfi_smp: "
                     "response_xferlen = %x, request_xferlen = %x",
                     response_xferlen, request_xferlen));
 
                 response_ubuf   = (void *)(ulong_t)sge32[0].phys_addr;
                 request_ubuf    = (void *)(ulong_t)sge32[1].phys_addr;
-                con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: "
+                con_log(CL_ANN1, (CE_CONT, "issue_mfi_smp: "
                     "response_ubuf = %p, request_ubuf = %p",
                     response_ubuf, request_ubuf));
         } else {
 #ifdef _ILP32
-                con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: DDI_MODEL_ILP32"));
+                con_log(CL_ANN1, (CE_CONT, "issue_mfi_smp: DDI_MODEL_ILP32"));
 
                 sge32                   = &ksmp->sgl[0].sge32[0];
                 response_xferlen        = sge32[0].length;
                 request_xferlen         = sge32[1].length;
-                con_log(CL_ANN, (CE_NOTE, "issue_mfi_smp: "
+                con_log(CL_ANN, (CE_CONT, "issue_mfi_smp: "
                     "response_xferlen = %x, request_xferlen = %x",
                     response_xferlen, request_xferlen));
 
                 response_ubuf   = (void *)(ulong_t)sge32[0].phys_addr;
                 request_ubuf    = (void *)(ulong_t)sge32[1].phys_addr;
-                con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: "
+                con_log(CL_ANN1, (CE_CONT, "issue_mfi_smp: "
                     "response_ubuf = %p, request_ubuf = %p",
                     response_ubuf, request_ubuf));
 #else
-                con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: DDI_MODEL_LP64"));
+                con_log(CL_ANN1, (CE_CONT, "issue_mfi_smp: DDI_MODEL_LP64"));
 
                 sge64                   = &ksmp->sgl[0].sge64[0];
                 response_xferlen        = sge64[0].length;
                 request_xferlen         = sge64[1].length;
 

@@ -4503,11 +5790,14 @@
 #endif
         }
         if (request_xferlen) {
                 /* means IOCTL requires DMA */
                 /* allocate the data transfer buffer */
-                request_dma_obj.size = request_xferlen;
+                /* request_dma_obj.size = request_xferlen; */
+                MRSAS_GET_BOUNDARY_ALIGNED_LEN(request_xferlen,
+                    new_xfer_length1, PAGESIZE);
+                request_dma_obj.size = new_xfer_length1;
                 request_dma_obj.dma_attr = mrsas_generic_dma_attr;
                 request_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
                 request_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
                 request_dma_obj.dma_attr.dma_attr_sgllen = 1;
                 request_dma_obj.dma_attr.dma_attr_align = 1;

@@ -4534,11 +5824,14 @@
         }
 
         if (response_xferlen) {
                 /* means IOCTL requires DMA */
                 /* allocate the data transfer buffer */
-                response_dma_obj.size = response_xferlen;
+                /* response_dma_obj.size = response_xferlen; */
+                MRSAS_GET_BOUNDARY_ALIGNED_LEN(response_xferlen,
+                    new_xfer_length2, PAGESIZE);
+                response_dma_obj.size = new_xfer_length2;
                 response_dma_obj.dma_attr = mrsas_generic_dma_attr;
                 response_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
                 response_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
                 response_dma_obj.dma_attr.dma_attr_sgllen = 1;
                 response_dma_obj.dma_attr.dma_attr_align = 1;

@@ -4578,11 +5871,11 @@
 
         ddi_put16(acc_handle, &smp->flags, ksmp->flags & ~MFI_FRAME_SGL64);
 
         model = ddi_model_convert_from(mode & FMODELS);
         if (model == DDI_MODEL_ILP32) {
-                con_log(CL_ANN1, (CE_NOTE,
+                con_log(CL_ANN1, (CE_CONT,
                     "issue_mfi_smp: DDI_MODEL_ILP32"));
 
                 sge32 = &smp->sgl[0].sge32[0];
                 ddi_put32(acc_handle, &sge32[0].length, response_xferlen);
                 ddi_put32(acc_handle, &sge32[0].phys_addr,

@@ -4590,21 +5883,21 @@
                 ddi_put32(acc_handle, &sge32[1].length, request_xferlen);
                 ddi_put32(acc_handle, &sge32[1].phys_addr,
                     request_dma_obj.dma_cookie[0].dmac_address);
         } else {
 #ifdef _ILP32
-                con_log(CL_ANN1, (CE_NOTE,
+                con_log(CL_ANN1, (CE_CONT,
                     "issue_mfi_smp: DDI_MODEL_ILP32"));
                 sge32 = &smp->sgl[0].sge32[0];
                 ddi_put32(acc_handle, &sge32[0].length, response_xferlen);
                 ddi_put32(acc_handle, &sge32[0].phys_addr,
                     response_dma_obj.dma_cookie[0].dmac_address);
                 ddi_put32(acc_handle, &sge32[1].length, request_xferlen);
                 ddi_put32(acc_handle, &sge32[1].phys_addr,
                     request_dma_obj.dma_cookie[0].dmac_address);
 #else
-                con_log(CL_ANN1, (CE_NOTE,
+                con_log(CL_ANN1, (CE_CONT,
                     "issue_mfi_smp: DDI_MODEL_LP64"));
                 sge64 = &smp->sgl[0].sge64[0];
                 ddi_put32(acc_handle, &sge64[0].length, response_xferlen);
                 ddi_put64(acc_handle, &sge64[0].phys_addr,
                     response_dma_obj.dma_cookie[0].dmac_address);

@@ -4611,24 +5904,28 @@
                 ddi_put32(acc_handle, &sge64[1].length, request_xferlen);
                 ddi_put64(acc_handle, &sge64[1].phys_addr,
                     request_dma_obj.dma_cookie[0].dmac_address);
 #endif
         }
-        con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp : "
+        con_log(CL_ANN1, (CE_CONT, "issue_mfi_smp : "
             "smp->response_xferlen = %d, smp->request_xferlen = %d "
             "smp->data_xfer_len = %d", ddi_get32(acc_handle, &sge32[0].length),
             ddi_get32(acc_handle, &sge32[1].length),
             ddi_get32(acc_handle, &smp->data_xfer_len)));
 
         cmd->sync_cmd = MRSAS_TRUE;
         cmd->frame_count = 1;
 
+        if (instance->tbolt) {
+                mr_sas_tbolt_build_mfi_cmd(instance, cmd);
+        }
+
         if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
                 con_log(CL_ANN, (CE_WARN,
                     "issue_mfi_smp: fw_ioctl failed"));
         } else {
-                con_log(CL_ANN1, (CE_NOTE,
+                con_log(CL_ANN1, (CE_CONT,
                     "issue_mfi_smp: copy to user space"));
 
                 if (request_xferlen) {
                         for (i = 0; i < request_xferlen; i++) {
                                 if (ddi_copyout(

@@ -4658,11 +5955,11 @@
                 }
         }
 
         ksmp->cmd_status = ddi_get8(acc_handle, &smp->cmd_status);
         con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: smp->cmd_status = %d",
-            ddi_get8(acc_handle, &smp->cmd_status)));
+            ksmp->cmd_status));
         DTRACE_PROBE2(issue_smp, uint8_t, ksmp->cmd, uint8_t, ksmp->cmd_status);
 
         if (request_xferlen) {
                 /* free kernel buffer */
                 if (mrsas_free_dma_obj(instance, request_dma_obj) !=

@@ -4688,10 +5985,12 @@
     struct mrsas_cmd *cmd, int mode)
 {
         void            *fis_ubuf;
         void            *data_ubuf;
         uint32_t        fis_xferlen = 0;
+        uint32_t   new_xfer_length1 = 0;
+        uint32_t   new_xfer_length2 = 0;
         uint32_t        data_xferlen = 0;
         uint_t          model;
         dma_obj_t       fis_dma_obj;
         dma_obj_t       data_dma_obj;
         struct mrsas_stp_frame  *kstp;

@@ -4701,36 +6000,34 @@
 
         stp = &cmd->frame->stp;
         kstp = (struct mrsas_stp_frame *)&ioctl->frame[0];
 
         if (instance->adapterresetinprogress) {
-                con_log(CL_ANN1, (CE_NOTE, "Reset flag set, "
+                con_log(CL_ANN1, (CE_WARN, "Reset flag set, "
                 "returning mfi_pkt and setting TRAN_BUSY\n"));
                 return (DDI_FAILURE);
         }
         model = ddi_model_convert_from(mode & FMODELS);
         if (model == DDI_MODEL_ILP32) {
-                con_log(CL_ANN1, (CE_NOTE, "issue_mfi_stp: DDI_MODEL_ILP32"));
+                con_log(CL_ANN1, (CE_CONT, "issue_mfi_stp: DDI_MODEL_ILP32"));
 
                 fis_xferlen     = kstp->sgl.sge32[0].length;
                 data_xferlen    = kstp->sgl.sge32[1].length;
 
                 fis_ubuf        = (void *)(ulong_t)kstp->sgl.sge32[0].phys_addr;
                 data_ubuf       = (void *)(ulong_t)kstp->sgl.sge32[1].phys_addr;
-        }
-        else
-        {
+        } else {
 #ifdef _ILP32
-                con_log(CL_ANN1, (CE_NOTE, "issue_mfi_stp: DDI_MODEL_ILP32"));
+                con_log(CL_ANN1, (CE_CONT, "issue_mfi_stp: DDI_MODEL_ILP32"));
 
                 fis_xferlen     = kstp->sgl.sge32[0].length;
                 data_xferlen    = kstp->sgl.sge32[1].length;
 
                 fis_ubuf        = (void *)(ulong_t)kstp->sgl.sge32[0].phys_addr;
                 data_ubuf       = (void *)(ulong_t)kstp->sgl.sge32[1].phys_addr;
 #else
-                con_log(CL_ANN1, (CE_NOTE, "issue_mfi_stp: DDI_MODEL_LP64"));
+                con_log(CL_ANN1, (CE_CONT, "issue_mfi_stp: DDI_MODEL_LP64"));
 
                 fis_xferlen     = kstp->sgl.sge64[0].length;
                 data_xferlen    = kstp->sgl.sge64[1].length;
 
                 fis_ubuf        = (void *)(ulong_t)kstp->sgl.sge64[0].phys_addr;

@@ -4738,16 +6035,19 @@
 #endif
         }
 
 
         if (fis_xferlen) {
-                con_log(CL_ANN, (CE_NOTE, "issue_mfi_stp: "
+                con_log(CL_ANN, (CE_CONT, "issue_mfi_stp: "
                     "fis_ubuf = %p fis_xferlen = %x", fis_ubuf, fis_xferlen));
 
                 /* means IOCTL requires DMA */
                 /* allocate the data transfer buffer */
-                fis_dma_obj.size = fis_xferlen;
+                /* fis_dma_obj.size = fis_xferlen; */
+                MRSAS_GET_BOUNDARY_ALIGNED_LEN(fis_xferlen,
+                    new_xfer_length1, PAGESIZE);
+                fis_dma_obj.size = new_xfer_length1;
                 fis_dma_obj.dma_attr = mrsas_generic_dma_attr;
                 fis_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
                 fis_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
                 fis_dma_obj.dma_attr.dma_attr_sgllen = 1;
                 fis_dma_obj.dma_attr.dma_attr_align = 1;

@@ -4771,23 +6071,26 @@
                         }
                 }
         }
 
         if (data_xferlen) {
-                con_log(CL_ANN, (CE_NOTE, "issue_mfi_stp: data_ubuf = %p "
+                con_log(CL_ANN, (CE_CONT, "issue_mfi_stp: data_ubuf = %p "
                     "data_xferlen = %x", data_ubuf, data_xferlen));
 
                 /* means IOCTL requires DMA */
                 /* allocate the data transfer buffer */
-                data_dma_obj.size = data_xferlen;
+                /* data_dma_obj.size = data_xferlen; */
+                MRSAS_GET_BOUNDARY_ALIGNED_LEN(data_xferlen, new_xfer_length2,
+                    PAGESIZE);
+                data_dma_obj.size = new_xfer_length2;
                 data_dma_obj.dma_attr = mrsas_generic_dma_attr;
                 data_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
                 data_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
                 data_dma_obj.dma_attr.dma_attr_sgllen = 1;
                 data_dma_obj.dma_attr.dma_attr_align = 1;
 
-/* allocate kernel buffer for DMA */
+                /* allocate kernel buffer for DMA */
                 if (mrsas_alloc_dma_obj(instance, &data_dma_obj,
                     (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
                         con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: "
                             "could not allocate data transfer buffer."));
                         return (DDI_FAILURE);

@@ -4827,10 +6130,14 @@
             data_dma_obj.dma_cookie[0].dmac_address);
 
         cmd->sync_cmd = MRSAS_TRUE;
         cmd->frame_count = 1;
 
+        if (instance->tbolt) {
+                mr_sas_tbolt_build_mfi_cmd(instance, cmd);
+        }
+
         if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
                 con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: fw_ioctl failed"));
         } else {
 
                 if (fis_xferlen) {

@@ -4858,10 +6165,12 @@
                         }
                 }
         }
 
         kstp->cmd_status = ddi_get8(acc_handle, &stp->cmd_status);
+        con_log(CL_ANN1, (CE_NOTE, "issue_mfi_stp: stp->cmd_status = %d",
+            kstp->cmd_status));
         DTRACE_PROBE2(issue_stp, uint8_t, kstp->cmd, uint8_t, kstp->cmd_status);
 
         if (fis_xferlen) {
                 /* free kernel buffer */
                 if (mrsas_free_dma_obj(instance, fis_dma_obj) != DDI_SUCCESS)

@@ -4878,11 +6187,11 @@
 }
 
 /*
  * fill_up_drv_ver
  */
-static void
+void
 fill_up_drv_ver(struct mrsas_drv_ver *dv)
 {
         (void) memset(dv, 0, sizeof (struct mrsas_drv_ver));
 
         (void) memcpy(dv->signature, "$LSI LOGIC$", strlen("$LSI LOGIC$"));

@@ -4889,10 +6198,11 @@
         (void) memcpy(dv->os_name, "Solaris", strlen("Solaris"));
         (void) memcpy(dv->drv_name, "mr_sas", strlen("mr_sas"));
         (void) memcpy(dv->drv_ver, MRSAS_VERSION, strlen(MRSAS_VERSION));
         (void) memcpy(dv->drv_rel_date, MRSAS_RELDATE,
             strlen(MRSAS_RELDATE));
+
 }
 
 /*
  * handle_drv_ioctl
  */

@@ -4915,35 +6225,35 @@
 
         kdcmd = (struct mrsas_dcmd_frame *)&ioctl->frame[0];
 
         model = ddi_model_convert_from(mode & FMODELS);
         if (model == DDI_MODEL_ILP32) {
-                con_log(CL_ANN1, (CE_NOTE,
+                con_log(CL_ANN1, (CE_CONT,
                     "handle_drv_ioctl: DDI_MODEL_ILP32"));
 
                 xferlen = kdcmd->sgl.sge32[0].length;
 
                 ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr;
         } else {
 #ifdef _ILP32
-                con_log(CL_ANN1, (CE_NOTE,
+                con_log(CL_ANN1, (CE_CONT,
                     "handle_drv_ioctl: DDI_MODEL_ILP32"));
                 xferlen = kdcmd->sgl.sge32[0].length;
                 ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr;
 #else
-                con_log(CL_ANN1, (CE_NOTE,
+                con_log(CL_ANN1, (CE_CONT,
                     "handle_drv_ioctl: DDI_MODEL_LP64"));
                 xferlen = kdcmd->sgl.sge64[0].length;
                 ubuf = (void *)(ulong_t)kdcmd->sgl.sge64[0].phys_addr;
 #endif
         }
-        con_log(CL_ANN1, (CE_NOTE, "handle_drv_ioctl: "
+        con_log(CL_ANN1, (CE_CONT, "handle_drv_ioctl: "
             "dataBuf=%p size=%d bytes", ubuf, xferlen));
 
         switch (kdcmd->opcode) {
         case MRSAS_DRIVER_IOCTL_DRIVER_VERSION:
-                con_log(CL_ANN1, (CE_NOTE, "handle_drv_ioctl: "
+                con_log(CL_ANN1, (CE_CONT, "handle_drv_ioctl: "
                     "MRSAS_DRIVER_IOCTL_DRIVER_VERSION"));
 
                 fill_up_drv_ver(&dv);
 
                 if (ddi_copyout(&dv, ubuf, xferlen, mode)) {

@@ -5015,20 +6325,22 @@
         int     rval = DDI_SUCCESS;
 
         struct mrsas_header     *hdr;
         struct mrsas_cmd        *cmd;
 
+        if (instance->tbolt) {
+                cmd = get_raid_msg_mfi_pkt(instance);
+        } else {
         cmd = get_mfi_pkt(instance);
-
+        }
         if (!cmd) {
                 con_log(CL_ANN, (CE_WARN, "mr_sas: "
                     "failed to get a cmd packet"));
                 DTRACE_PROBE2(mfi_ioctl_err, uint16_t,
                     instance->fw_outstanding, uint16_t, instance->max_fw_cmds);
                 return (DDI_FAILURE);
         }
-        cmd->retry_count_for_ocr = 0;
 
         /* Clear the frame buffer and assign back the context id */
         (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
         ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
             cmd->index);

@@ -5057,11 +6369,15 @@
         }
 
         if (mrsas_common_check(instance, cmd) != DDI_SUCCESS)
                 rval = DDI_FAILURE;
 
+        if (instance->tbolt) {
+                return_raid_msg_mfi_pkt(instance, cmd);
+        } else {
         return_mfi_pkt(instance, cmd);
+        }
 
         return (rval);
 }
 
 /*

@@ -5089,10 +6405,11 @@
         struct mrsas_cmd        *cmd, *aen_cmd;
         struct mrsas_dcmd_frame *dcmd;
         union mrsas_evt_class_locale    curr_aen;
         union mrsas_evt_class_locale    prev_aen;
 
+        con_log(CL_ANN, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
         /*
          * If there an AEN pending already (aen_cmd), check if the
          * class_locale of that pending AEN is inclusive of the new
          * AEN request we currently have. If it is, then we don't have
          * to do anything. In other words, whichever events the current

@@ -5149,18 +6466,22 @@
         } else {
                 curr_aen.word = LE_32(class_locale_word);
                 curr_aen.members.locale = LE_16(curr_aen.members.locale);
         }
 
+        if (instance->tbolt) {
+                cmd = get_raid_msg_mfi_pkt(instance);
+        } else {
         cmd = get_mfi_pkt(instance);
+        }
 
         if (!cmd) {
                 DTRACE_PROBE2(mfi_aen_err, uint16_t, instance->fw_outstanding,
                     uint16_t, instance->max_fw_cmds);
                 return (ENOMEM);
         }
-        cmd->retry_count_for_ocr = 0;
+
         /* Clear the frame buffer and assign back the context id */
         (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
         ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
             cmd->index);
 

@@ -5205,16 +6526,19 @@
 
         cmd->frame_count = 1;
 
         /* Issue the aen registration frame */
         /* atomic_add_16 (&instance->fw_outstanding, 1); */
+        if (instance->tbolt) {
+                mr_sas_tbolt_build_mfi_cmd(instance, cmd);
+        }
         instance->func_ptr->issue_cmd(cmd, instance);
 
         return (0);
 }
 
-static void
+void
 display_scsi_inquiry(caddr_t scsi_inq)
 {
 #define MAX_SCSI_DEVICE_CODE    14
         int             i;
         char            inquiry_buf[256] = {0};

@@ -5276,11 +6600,11 @@
                 len += snprintf(inquiry_buf + len, 265 - len, " CCS\n");
         } else {
                 len += snprintf(inquiry_buf + len, 265 - len, "\n");
         }
 
-        con_log(CL_ANN1, (CE_CONT, inquiry_buf));
+        con_log(CL_DLEVEL2, (CE_CONT, inquiry_buf));
 }
 
 static void
 io_timeout_checker(void *arg)
 {

@@ -5292,23 +6616,32 @@
         int counter = 0;
         struct mlist_head       *pos, *next;
         mlist_t                 process_list;
 
         if (instance->adapterresetinprogress == 1) {
-                con_log(CL_ANN1, (CE_NOTE, "io_timeout_checker"
+                con_log(CL_ANN, (CE_NOTE, "io_timeout_checker:"
                     " reset in progress"));
+
                 instance->timeout_id = timeout(io_timeout_checker,
                     (void *) instance, drv_usectohz(MRSAS_1_SECOND));
                 return;
         }
 
         /* See if this check needs to be in the beginning or last in ISR */
         if (mrsas_initiate_ocr_if_fw_is_faulty(instance) ==  1) {
-                con_log(CL_ANN1, (CE_NOTE,
-                    "Fw Fault state Handling in io_timeout_checker"));
+                cmn_err(CE_WARN, "io_timeout_checker: "
+                    "FW Fault, calling reset adapter");
+                cmn_err(CE_CONT, "io_timeout_checker: "
+                    "fw_outstanding 0x%X max_fw_cmds 0x%X",
+                    instance->fw_outstanding, instance->max_fw_cmds);
                 if (instance->adapterresetinprogress == 0) {
+                        instance->adapterresetinprogress = 1;
+                        if (instance->tbolt)
+                                (void) mrsas_tbolt_reset_ppc(instance);
+                        else
                         (void) mrsas_reset_ppc(instance);
+                        instance->adapterresetinprogress = 0;
                 }
                 instance->timeout_id = timeout(io_timeout_checker,
                     (void *) instance, drv_usectohz(MRSAS_1_SECOND));
                 return;
         }

@@ -5335,67 +6668,74 @@
                                 continue;
                         }
                         time = --cmd->drv_pkt_time;
                 }
                 if (time <= 0) {
-                        con_log(CL_ANN1, (CE_NOTE, "%llx: "
-                            "io_timeout_checker: TIMING OUT: pkt "
-                            ": %p, cmd %p", gethrtime(), (void *)pkt,
-                            (void *)cmd));
+                        cmn_err(CE_WARN, "%llx: "
+                            "io_timeout_checker: TIMING OUT: pkt: %p, "
+                            "cmd %p fw_outstanding 0x%X max_fw_cmds 0x%X\n",
+                            gethrtime(), (void *)pkt, (void *)cmd,
+                            instance->fw_outstanding, instance->max_fw_cmds);
+
                         counter++;
                         break;
                 }
         }
         mutex_exit(&instance->cmd_pend_mtx);
 
         if (counter) {
-                con_log(CL_ANN1, (CE_NOTE,
-                    "io_timeout_checker "
-                    "cmd->retrycount_for_ocr %d, "
-                    "cmd index %d , cmd address %p ",
-                    cmd->retry_count_for_ocr+1, cmd->index, (void *)cmd));
-
                 if (instance->disable_online_ctrl_reset == 1) {
-                        con_log(CL_ANN1, (CE_NOTE, "mrsas: "
-                            "OCR is not supported by the Firmware "
-                            "Failing all the queued packets \n"));
+                        cmn_err(CE_WARN, "mr_sas %d: %s(): OCR is NOT "
+                            "supported by Firmware, KILL adapter!!!",
+                            instance->instance, __func__);
 
+                        if (instance->tbolt)
+                                mrsas_tbolt_kill_adapter(instance);
+                        else
                         (void) mrsas_kill_adapter(instance);
+
                         return;
                 } else {
                         if (cmd->retry_count_for_ocr <=  IO_RETRY_COUNT) {
                                 if (instance->adapterresetinprogress == 0) {
-                                con_log(CL_ANN1, (CE_NOTE, "mrsas: "
-                                    "OCR is supported by FW "
-                                    "triggering  mrsas_reset_ppc"));
-                                (void) mrsas_reset_ppc(instance);
+                                        if (instance->tbolt) {
+                                                (void) mrsas_tbolt_reset_ppc(
+                                                    instance);
+                                        } else {
+                                                (void) mrsas_reset_ppc(
+                                                    instance);
                                 }
+                                }
                         } else {
-                                con_log(CL_ANN1, (CE_NOTE,
-                                    "io_timeout_checker:"
-                                    " cmdindex: %d,cmd address: %p "
+                                cmn_err(CE_WARN,
+                                    "io_timeout_checker: "
+                                    "cmd %p cmd->index %d "
                                     "timed out even after 3 resets: "
-                                    "so kill adapter", cmd->index,
-                                    (void *)cmd));
+                                    "so KILL adapter", (void *)cmd, cmd->index);
+
+                                mrsas_print_cmd_details(instance, cmd, 0xDD);
+
+                                if (instance->tbolt)
+                                        mrsas_tbolt_kill_adapter(instance);
+                                else
                                 (void) mrsas_kill_adapter(instance);
                                 return;
                         }
                 }
         }
-
-
-        con_log(CL_ANN1, (CE_NOTE, "mrsas: "
+        con_log(CL_ANN, (CE_NOTE, "mrsas: "
             "schedule next timeout check: "
             "do timeout \n"));
         instance->timeout_id =
             timeout(io_timeout_checker, (void *)instance,
             drv_usectohz(MRSAS_1_SECOND));
 }
-static int
+
+static uint32_t
 read_fw_status_reg_ppc(struct mrsas_instance *instance)
 {
-        return ((int)RD_OB_SCRATCH_PAD_0(instance));
+        return ((uint32_t)RD_OB_SCRATCH_PAD_0(instance));
 }
 
 static void
 issue_cmd_ppc(struct mrsas_cmd *cmd, struct mrsas_instance *instance)
 {

@@ -5402,11 +6742,11 @@
         struct scsi_pkt *pkt;
         atomic_add_16(&instance->fw_outstanding, 1);
 
         pkt = cmd->pkt;
         if (pkt) {
-                con_log(CL_ANN1, (CE_CONT, "%llx : issue_cmd_ppc:"
+                con_log(CL_DLEVEL1, (CE_NOTE, "%llx : issue_cmd_ppc:"
                     "ISSUED CMD TO FW : called : cmd:"
                     ": %p instance : %p pkt : %p pkt_time : %x\n",
                     gethrtime(), (void *)cmd, (void *)instance,
                     (void *)pkt, cmd->drv_pkt_time));
                 if (instance->adapterresetinprogress) {

@@ -5415,17 +6755,21 @@
                 } else {
                         push_pending_mfi_pkt(instance, cmd);
                 }
 
         } else {
-                con_log(CL_ANN1, (CE_CONT, "%llx : issue_cmd_ppc:"
+                con_log(CL_DLEVEL1, (CE_NOTE, "%llx : issue_cmd_ppc:"
                     "ISSUED CMD TO FW : called : cmd : %p, instance: %p"
                     "(NO PKT)\n", gethrtime(), (void *)cmd, (void *)instance));
         }
+
+        mutex_enter(&instance->reg_write_mtx);
         /* Issue the command to the FW */
         WR_IB_QPORT((cmd->frame_phys_addr) |
             (((cmd->frame_count - 1) << 1) | 1), instance);
+        mutex_exit(&instance->reg_write_mtx);
+
 }
 
 /*
  * issue_cmd_in_sync_mode
  */

@@ -5442,31 +6786,34 @@
         if (instance->adapterresetinprogress) {
                 cmd->drv_pkt_time = ddi_get16(
                     cmd->frame_dma_obj.acc_handle, &hdr->timeout);
                 if (cmd->drv_pkt_time < debug_timeout_g)
                         cmd->drv_pkt_time = (uint16_t)debug_timeout_g;
+
                 con_log(CL_ANN1, (CE_NOTE, "sync_mode_ppc: "
                     "issue and return in reset case\n"));
                 WR_IB_QPORT((cmd->frame_phys_addr) |
                     (((cmd->frame_count - 1) << 1) | 1), instance);
+
                 return (DDI_SUCCESS);
         } else {
                 con_log(CL_ANN1, (CE_NOTE, "sync_mode_ppc: pushing the pkt\n"));
                 push_pending_mfi_pkt(instance, cmd);
         }
 
         cmd->cmd_status = ENODATA;
 
+        mutex_enter(&instance->reg_write_mtx);
+        /* Issue the command to the FW */
         WR_IB_QPORT((cmd->frame_phys_addr) |
             (((cmd->frame_count - 1) << 1) | 1), instance);
+        mutex_exit(&instance->reg_write_mtx);
 
         mutex_enter(&instance->int_cmd_mtx);
-
         for (i = 0; i < msecs && (cmd->cmd_status == ENODATA); i++) {
                 cv_wait(&instance->int_cmd_cv, &instance->int_cmd_mtx);
         }
-
         mutex_exit(&instance->int_cmd_mtx);
 
         con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_sync_mode_ppc: done"));
 
         if (i < (msecs -1)) {

@@ -5509,11 +6856,11 @@
                 drv_usecwait(MILLISEC); /* wait for 1000 usecs */
         }
 
         if (ddi_get8(cmd->frame_dma_obj.acc_handle, &frame_hdr->cmd_status)
             == MFI_CMD_STATUS_POLL_MODE) {
-                con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_poll_mode: "
+                con_log(CL_ANN, (CE_NOTE, "issue_cmd_in_poll_mode: "
                     "cmd polling timed out"));
                 return (DDI_FAILURE);
         }
 
         return (DDI_SUCCESS);

@@ -5628,20 +6975,23 @@
         uint32_t status;
         uint32_t retry = 0;
         uint32_t cur_abs_reg_val;
         uint32_t fw_state;
 
+        con_log(CL_ANN, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
+
         if (instance->deadadapter == 1) {
-                con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: "
-                    "no more resets as HBA has been marked dead "));
+                cmn_err(CE_WARN, "mrsas_reset_ppc: "
+                    "no more resets as HBA has been marked dead ");
                 return (DDI_FAILURE);
         }
         mutex_enter(&instance->ocr_flags_mtx);
         instance->adapterresetinprogress = 1;
         mutex_exit(&instance->ocr_flags_mtx);
         con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: adpterresetinprogress "
             "flag set, time %llx", gethrtime()));
+
         instance->func_ptr->disable_intr(instance);
 retry_reset:
         WR_IB_WRITE_SEQ(0, instance);
         WR_IB_WRITE_SEQ(4, instance);
         WR_IB_WRITE_SEQ(0xb, instance);

@@ -5655,12 +7005,12 @@
 
         while (!(status & DIAG_WRITE_ENABLE)) {
                 delay(100 * drv_usectohz(MILLISEC));
                 status = RD_OB_DRWE(instance);
                 if (retry++ == 100) {
-                        con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: DRWE bit "
-                            "check retry count %d\n", retry));
+                        cmn_err(CE_WARN, "mrsas_reset_ppc: DRWE bit "
+                            "check retry count %d", retry);
                         return (DDI_FAILURE);
                 }
         }
         WR_IB_DRWE(status | DIAG_RESET_ADAPTER, instance);
         delay(100 * drv_usectohz(MILLISEC));

@@ -5667,15 +7017,18 @@
         status = RD_OB_DRWE(instance);
         while (status & DIAG_RESET_ADAPTER) {
                 delay(100 * drv_usectohz(MILLISEC));
                 status = RD_OB_DRWE(instance);
                 if (retry++ == 100) {
+                        cmn_err(CE_WARN, "mrsas_reset_ppc: "
+                            "RESET FAILED. KILL adapter called.");
+
                         (void) mrsas_kill_adapter(instance);
                         return (DDI_FAILURE);
                 }
         }
-        con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: Adapter reset complete"));
+        con_log(CL_ANN, (CE_NOTE, "mrsas_reset_ppc: Adapter reset complete"));
         con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: "
             "Calling mfi_state_transition_to_ready"));
 
         /* Mark HBA as bad, if FW is fault after 3 continuous resets */
         if (mfi_state_transition_to_ready(instance) ||

@@ -5698,19 +7051,22 @@
                 if (fw_state == MFI_STATE_FAULT) {
                         /* increment the count */
                         instance->fw_fault_count_after_ocr++;
                         if (instance->fw_fault_count_after_ocr
                             < MAX_FW_RESET_COUNT) {
-                                con_log(CL_ANN1, (CE_WARN, "mrsas_reset_ppc: "
-                                    "FW is in fault after OCR count %d ",
-                                    instance->fw_fault_count_after_ocr));
+                                cmn_err(CE_WARN, "mrsas_reset_ppc: "
+                                    "FW is in fault after OCR count %d "
+                                    "Retry Reset",
+                                    instance->fw_fault_count_after_ocr);
                                 goto retry_reset;
 
                         } else {
-                                con_log(CL_ANN1, (CE_WARN, "mrsas_reset_ppc: "
-                                    "Max Reset Count exceeded "
-                                    "Mark HBA as bad"));
+                                cmn_err(CE_WARN, "mrsas_reset_ppc: "
+                                    "Max Reset Count exceeded >%d"
+                                    "Mark HBA as bad, KILL adapter",
+                                    MAX_FW_RESET_COUNT);
+
                                 (void) mrsas_kill_adapter(instance);
                                 return (DDI_FAILURE);
                         }
                 }
         }

@@ -5732,41 +7088,56 @@
         con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: "
             "Calling mrsas_issue_init_mfi"));
         (void) mrsas_issue_init_mfi(instance);
         con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: "
             "mrsas_issue_init_mfi Done"));
+
         con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: "
             "Calling mrsas_print_pending_cmd\n"));
         (void) mrsas_print_pending_cmds(instance);
         con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: "
             "mrsas_print_pending_cmd done\n"));
+
         instance->func_ptr->enable_intr(instance);
         instance->fw_outstanding = 0;
+
         con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: "
             "Calling mrsas_issue_pending_cmds"));
         (void) mrsas_issue_pending_cmds(instance);
         con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: "
-        "Complete"));
+            "issue_pending_cmds done.\n"));
+
         con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: "
             "Calling aen registration"));
+
+
+        instance->aen_cmd->retry_count_for_ocr = 0;
+        instance->aen_cmd->drv_pkt_time = 0;
+
         instance->func_ptr->issue_cmd(instance->aen_cmd, instance);
         con_log(CL_ANN1, (CE_NOTE, "Unsetting adpresetinprogress flag.\n"));
+
         mutex_enter(&instance->ocr_flags_mtx);
         instance->adapterresetinprogress = 0;
         mutex_exit(&instance->ocr_flags_mtx);
         con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: "
             "adpterresetinprogress flag unset"));
+
         con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc done\n"));
         return (DDI_SUCCESS);
 }
-static int
-mrsas_common_check(struct mrsas_instance *instance,
-    struct  mrsas_cmd *cmd)
+
+/*
+ * FMA functions.
+ */
+int
+mrsas_common_check(struct mrsas_instance *instance, struct  mrsas_cmd *cmd)
 {
         int ret = DDI_SUCCESS;
 
-        if (mrsas_check_dma_handle(cmd->frame_dma_obj.dma_handle) !=
+        if (cmd != NULL &&
+            mrsas_check_dma_handle(cmd->frame_dma_obj.dma_handle) !=
             DDI_SUCCESS) {
                 ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
                 if (cmd->pkt != NULL) {
                         cmd->pkt->pkt_reason = CMD_TRAN_ERR;
                         cmd->pkt->pkt_statistics = 0;

@@ -5774,20 +7145,20 @@
                 ret = DDI_FAILURE;
         }
         if (mrsas_check_dma_handle(instance->mfi_internal_dma_obj.dma_handle)
             != DDI_SUCCESS) {
                 ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
-                if (cmd->pkt != NULL) {
+                if (cmd != NULL && cmd->pkt != NULL) {
                         cmd->pkt->pkt_reason = CMD_TRAN_ERR;
                         cmd->pkt->pkt_statistics = 0;
                 }
                 ret = DDI_FAILURE;
         }
         if (mrsas_check_dma_handle(instance->mfi_evt_detail_obj.dma_handle) !=
             DDI_SUCCESS) {
                 ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
-                if (cmd->pkt != NULL) {
+                if (cmd != NULL && cmd->pkt != NULL) {
                         cmd->pkt->pkt_reason = CMD_TRAN_ERR;
                         cmd->pkt->pkt_statistics = 0;
                 }
                 ret = DDI_FAILURE;
         }

@@ -5794,11 +7165,11 @@
         if (mrsas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) {
                 ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
 
                 ddi_fm_acc_err_clear(instance->regmap_handle, DDI_FME_VER0);
 
-                if (cmd->pkt != NULL) {
+                if (cmd != NULL && cmd->pkt != NULL) {
                         cmd->pkt->pkt_reason = CMD_TRAN_ERR;
                         cmd->pkt->pkt_statistics = 0;
                 }
                 ret = DDI_FAILURE;
         }

@@ -5938,11 +7309,11 @@
 
         dev_info_t *dip = instance->dip;
         int     avail, actual, count;
         int     i, flag, ret;
 
-        con_log(CL_DLEVEL1, (CE_WARN, "mrsas_add_intrs: intr_type = %x",
+        con_log(CL_DLEVEL1, (CE_NOTE, "mrsas_add_intrs: intr_type = %x",
             intr_type));
 
         /* Get number of interrupts */
         ret = ddi_intr_get_nintrs(dip, intr_type, &count);
         if ((ret != DDI_SUCCESS) || (count == 0)) {

@@ -5950,21 +7321,21 @@
                     "ret %d count %d", ret, count));
 
                 return (DDI_FAILURE);
         }
 
-        con_log(CL_DLEVEL1, (CE_WARN, "mrsas_add_intrs: count = %d ", count));
+        con_log(CL_DLEVEL1, (CE_NOTE, "mrsas_add_intrs: count = %d ", count));
 
         /* Get number of available interrupts */
         ret = ddi_intr_get_navail(dip, intr_type, &avail);
         if ((ret != DDI_SUCCESS) || (avail == 0)) {
                 con_log(CL_ANN, (CE_WARN, "ddi_intr_get_navail() failed:"
                     "ret %d avail %d", ret, avail));
 
                 return (DDI_FAILURE);
         }
-        con_log(CL_DLEVEL1, (CE_WARN, "mrsas_add_intrs: avail = %d ", avail));
+        con_log(CL_DLEVEL1, (CE_NOTE, "mrsas_add_intrs: avail = %d ", avail));
 
         /* Only one interrupt routine. So limit the count to 1 */
         if (count > 1) {
                 count = 1;
         }

@@ -5971,27 +7342,29 @@
 
         /*
          * Allocate an array of interrupt handlers. Currently we support
          * only one interrupt. The framework can be extended later.
          */
-        instance->intr_size = count * sizeof (ddi_intr_handle_t);
-        instance->intr_htable = kmem_zalloc(instance->intr_size, KM_SLEEP);
+        instance->intr_htable_size = count * sizeof (ddi_intr_handle_t);
+        instance->intr_htable = kmem_zalloc(instance->intr_htable_size,
+            KM_SLEEP);
         ASSERT(instance->intr_htable);
 
-        flag = ((intr_type == DDI_INTR_TYPE_MSI) || (intr_type ==
-            DDI_INTR_TYPE_MSIX)) ? DDI_INTR_ALLOC_STRICT:DDI_INTR_ALLOC_NORMAL;
+        flag = ((intr_type == DDI_INTR_TYPE_MSI) ||
+            (intr_type == DDI_INTR_TYPE_MSIX)) ?
+            DDI_INTR_ALLOC_STRICT : DDI_INTR_ALLOC_NORMAL;
 
         /* Allocate interrupt */
         ret = ddi_intr_alloc(dip, instance->intr_htable, intr_type, 0,
             count, &actual, flag);
 
         if ((ret != DDI_SUCCESS) || (actual == 0)) {
                 con_log(CL_ANN, (CE_WARN, "mrsas_add_intrs: "
                     "avail = %d", avail));
-                kmem_free(instance->intr_htable, instance->intr_size);
-                return (DDI_FAILURE);
+                goto mrsas_free_htable;
         }
+
         if (actual < count) {
                 con_log(CL_ANN, (CE_WARN, "mrsas_add_intrs: "
                     "Requested = %d  Received = %d", count, actual));
         }
         instance->intr_cnt = actual;

@@ -6001,31 +7374,21 @@
          */
         if ((ret = ddi_intr_get_pri(instance->intr_htable[0],
             &instance->intr_pri)) != DDI_SUCCESS) {
                 con_log(CL_ANN, (CE_WARN, "mrsas_add_intrs: "
                     "get priority call failed"));
-
-                for (i = 0; i < actual; i++) {
-                        (void) ddi_intr_free(instance->intr_htable[i]);
+                goto mrsas_free_handles;
                 }
-                kmem_free(instance->intr_htable, instance->intr_size);
-                return (DDI_FAILURE);
-        }
 
         /*
          * Test for high level mutex. we don't support them.
          */
         if (instance->intr_pri >= ddi_intr_get_hilevel_pri()) {
                 con_log(CL_ANN, (CE_WARN, "mrsas_add_intrs: "
                     "High level interrupts not supported."));
-
-                for (i = 0; i < actual; i++) {
-                        (void) ddi_intr_free(instance->intr_htable[i]);
+                goto mrsas_free_handles;
                 }
-                kmem_free(instance->intr_htable, instance->intr_size);
-                return (DDI_FAILURE);
-        }
 
         con_log(CL_DLEVEL1, (CE_NOTE, "mrsas_add_intrs: intr_pri = 0x%x ",
             instance->intr_pri));
 
         /* Call ddi_intr_add_handler() */

@@ -6035,36 +7398,23 @@
                     (caddr_t)(uintptr_t)i);
 
                 if (ret != DDI_SUCCESS) {
                         con_log(CL_ANN, (CE_WARN, "mrsas_add_intrs:"
                             "failed %d", ret));
-
-                        for (i = 0; i < actual; i++) {
-                                (void) ddi_intr_free(instance->intr_htable[i]);
+                        goto mrsas_free_handles;
                         }
-                        kmem_free(instance->intr_htable, instance->intr_size);
-                        return (DDI_FAILURE);
-                }
 
         }
 
-        con_log(CL_DLEVEL1, (CE_WARN, " ddi_intr_add_handler done"));
+        con_log(CL_DLEVEL1, (CE_NOTE, " ddi_intr_add_handler done"));
 
         if ((ret = ddi_intr_get_cap(instance->intr_htable[0],
             &instance->intr_cap)) != DDI_SUCCESS) {
                 con_log(CL_ANN, (CE_WARN, "ddi_intr_get_cap() failed %d",
                     ret));
-
-                /* Free already allocated intr */
-                for (i = 0; i < actual; i++) {
-                        (void) ddi_intr_remove_handler(
-                            instance->intr_htable[i]);
-                        (void) ddi_intr_free(instance->intr_htable[i]);
+                goto mrsas_free_handlers;
                 }
-                kmem_free(instance->intr_htable, instance->intr_size);
-                return (DDI_FAILURE);
-        }
 
         if (instance->intr_cap &  DDI_INTR_FLAG_BLOCK) {
                 con_log(CL_ANN, (CE_WARN, "Calling ddi_intr_block _enable"));
 
                 (void) ddi_intr_block_enable(instance->intr_htable,

@@ -6079,10 +7429,27 @@
                 }
         }
 
         return (DDI_SUCCESS);
 
+mrsas_free_handlers:
+        for (i = 0; i < actual; i++)
+                (void) ddi_intr_remove_handler(instance->intr_htable[i]);
+
+mrsas_free_handles:
+        for (i = 0; i < actual; i++)
+                (void) ddi_intr_free(instance->intr_htable[i]);
+
+mrsas_free_htable:
+        if (instance->intr_htable != NULL)
+                kmem_free(instance->intr_htable, instance->intr_htable_size);
+
+        instance->intr_htable = NULL;
+        instance->intr_htable_size = 0;
+
+        return (DDI_FAILURE);
+
 }
 
 
 static void
 mrsas_rem_intrs(struct mrsas_instance *instance)

@@ -6106,20 +7473,25 @@
         for (i = 0; i < instance->intr_cnt; i++) {
                 (void) ddi_intr_remove_handler(instance->intr_htable[i]);
                 (void) ddi_intr_free(instance->intr_htable[i]);
         }
 
-        kmem_free(instance->intr_htable, instance->intr_size);
+        if (instance->intr_htable != NULL)
+                kmem_free(instance->intr_htable, instance->intr_htable_size);
+
+        instance->intr_htable = NULL;
+        instance->intr_htable_size = 0;
+
 }
 
 static int
 mrsas_tran_bus_config(dev_info_t *parent, uint_t flags,
     ddi_bus_config_op_t op, void *arg, dev_info_t **childp)
 {
         struct mrsas_instance *instance;
         int config;
-        int rval;
+        int rval  = NDI_SUCCESS;
 
         char *ptr = NULL;
         int tgt, lun;
 
         con_log(CL_ANN1, (CE_NOTE, "Bus config called for op = %x", op));

@@ -6146,10 +7518,15 @@
                         break;
                 }
 
                 if (lun == 0) {
                         rval = mrsas_config_ld(instance, tgt, lun, childp);
+#ifdef PDSUPPORT
+                } else if (instance->tbolt == 1 && lun != 0) {
+                        rval = mrsas_tbolt_config_pd(instance,
+                            tgt, lun, childp);
+#endif
                 } else {
                         rval = NDI_FAILURE;
                 }
 
                 break;

@@ -6183,10 +7560,19 @@
         for (tgt = 0; tgt < MRDRV_MAX_LD; tgt++) {
                 (void) mrsas_config_ld(instance, tgt, 0, NULL);
 
         }
 
+#ifdef PDSUPPORT
+        /* Config PD devices connected to the card */
+        if (instance->tbolt) {
+                for (tgt = 0; tgt < instance->mr_tbolt_pd_max; tgt++) {
+                        (void) mrsas_tbolt_config_pd(instance, tgt, 1, NULL);
+                }
+        }
+#endif
+
         rval = NDI_SUCCESS;
         return (rval);
 }
 
 static int

@@ -6239,20 +7625,25 @@
 {
         struct scsi_device *sd;
         dev_info_t *child;
         int rval;
 
-        con_log(CL_ANN1, (CE_NOTE, "mrsas_config_ld: t = %d l = %d",
+        con_log(CL_DLEVEL1, (CE_NOTE, "mrsas_config_ld: t = %d l = %d",
             tgt, lun));
 
         if ((child = mrsas_find_child(instance, tgt, lun)) != NULL) {
                 if (ldip) {
                         *ldip = child;
                 }
-                con_log(CL_ANN1, (CE_NOTE,
-                    "mrsas_config_ld: Child = %p found t = %d l = %d",
-                    (void *)child, tgt, lun));
+                if (instance->mr_ld_list[tgt].flag != MRDRV_TGT_VALID) {
+                        rval = mrsas_service_evt(instance, tgt, 0,
+                            MRSAS_EVT_UNCONFIG_TGT, NULL);
+                        con_log(CL_ANN1, (CE_WARN,
+                            "mr_sas: DELETING STALE ENTRY rval = %d "
+                            "tgt id = %d ", rval, tgt));
+                        return (NDI_FAILURE);
+                }
                 return (NDI_SUCCESS);
         }
 
         sd = kmem_zalloc(sizeof (struct scsi_device), KM_SLEEP);
         sd->sd_address.a_hba_tran = instance->tran;

@@ -6269,16 +7660,16 @@
                 kmem_free(sd->sd_inq, SUN_INQSIZE);
                 sd->sd_inq = (struct scsi_inquiry *)NULL;
         }
 
         kmem_free(sd, sizeof (struct scsi_device));
-        con_log(CL_ANN1, (CE_NOTE, "mrsas_config_ld: return rval = %d",
+        con_log(CL_DLEVEL1, (CE_NOTE, "mrsas_config_ld: return rval = %d",
             rval));
         return (rval);
 }
 
-static int
+int
 mrsas_config_scsi_device(struct mrsas_instance *instance,
     struct scsi_device *sd, dev_info_t **dipp)
 {
         char *nodename = NULL;
         char **compatible = NULL;

@@ -6288,11 +7679,11 @@
         int tgt = sd->sd_address.a_target;
         int lun = sd->sd_address.a_lun;
         int dtype = sd->sd_inq->inq_dtype & DTYPE_MASK;
         int rval;
 
-        con_log(CL_ANN1, (CE_WARN, "mr_sas: scsi_device t%dL%d", tgt, lun));
+        con_log(CL_DLEVEL1, (CE_NOTE, "mr_sas: scsi_device t%dL%d", tgt, lun));
         scsi_hba_nodename_compatible_get(sd->sd_inq, NULL, dtype,
             NULL, &nodename, &compatible, &ncompatible);
 
         if (nodename == NULL) {
                 con_log(CL_ANN1, (CE_WARN, "mr_sas: Found no compatible driver "

@@ -6300,16 +7691,16 @@
                 rval = NDI_FAILURE;
                 goto finish;
         }
 
         childname = (dtype == DTYPE_DIRECT) ? "sd" : nodename;
-        con_log(CL_ANN1, (CE_WARN,
+        con_log(CL_DLEVEL1, (CE_NOTE,
             "mr_sas: Childname = %2s nodename = %s", childname, nodename));
 
         /* Create a dev node */
         rval = ndi_devi_alloc(instance->dip, childname, DEVI_SID_NODEID, &ldip);
-        con_log(CL_ANN1, (CE_WARN,
+        con_log(CL_DLEVEL1, (CE_NOTE,
             "mr_sas_config_scsi_device: ndi_devi_alloc rval = %x", rval));
         if (rval == NDI_SUCCESS) {
                 if (ndi_prop_update_int(DDI_DEV_T_NONE, ldip, "target", tgt) !=
                     DDI_PROP_SUCCESS) {
                         con_log(CL_ANN1, (CE_WARN, "mr_sas: unable to create "

@@ -6339,29 +7730,29 @@
                         con_log(CL_ANN1, (CE_WARN, "mr_sas: unable to online "
                             "t%dl%d", tgt, lun));
                         ndi_prop_remove_all(ldip);
                         (void) ndi_devi_free(ldip);
                 } else {
-                        con_log(CL_ANN1, (CE_WARN, "mr_sas: online Done :"
+                        con_log(CL_ANN1, (CE_CONT, "mr_sas: online Done :"
                             "0 t%dl%d", tgt, lun));
                 }
 
         }
 finish:
         if (dipp) {
                 *dipp = ldip;
         }
 
-        con_log(CL_DLEVEL1, (CE_WARN,
+        con_log(CL_DLEVEL1, (CE_NOTE,
             "mr_sas: config_scsi_device rval = %d t%dL%d",
             rval, tgt, lun));
         scsi_hba_nodename_compatible_free(nodename, compatible);
         return (rval);
 }
 
 /*ARGSUSED*/
-static int
+int
 mrsas_service_evt(struct mrsas_instance *instance, int tgt, int lun, int event,
     uint64_t wwn)
 {
         struct mrsas_eventinfo *mrevt = NULL;
 

@@ -6376,10 +7767,11 @@
 
         mrevt->instance = instance;
         mrevt->tgt = tgt;
         mrevt->lun = lun;
         mrevt->event = event;
+        mrevt->wwn = wwn;
 
         if ((ddi_taskq_dispatch(instance->taskq,
             (void (*)(void *))mrsas_issue_evt_taskq, mrevt, DDI_NOSLEEP)) !=
             DDI_SUCCESS) {
                 con_log(CL_ANN1, (CE_NOTE,

@@ -6403,23 +7795,36 @@
         con_log(CL_ANN1, (CE_NOTE, "mrsas_issue_evt_taskq: called for"
             " tgt %d lun %d event %d",
             mrevt->tgt, mrevt->lun, mrevt->event));
 
         if (mrevt->tgt < MRDRV_MAX_LD && mrevt->lun == 0) {
+                mutex_enter(&instance->config_dev_mtx);
                 dip = instance->mr_ld_list[mrevt->tgt].dip;
+                mutex_exit(&instance->config_dev_mtx);
+#ifdef PDSUPPORT
         } else {
-                return;
+                mutex_enter(&instance->config_dev_mtx);
+                dip = instance->mr_tbolt_pd_list[mrevt->tgt].dip;
+                mutex_exit(&instance->config_dev_mtx);
+#endif
         }
 
+
         ndi_devi_enter(instance->dip, &circ1);
         switch (mrevt->event) {
         case MRSAS_EVT_CONFIG_TGT:
                 if (dip == NULL) {
 
                         if (mrevt->lun == 0) {
                                 (void) mrsas_config_ld(instance, mrevt->tgt,
                                     0, NULL);
+#ifdef PDSUPPORT
+                        } else if (instance->tbolt) {
+                                (void) mrsas_tbolt_config_pd(instance,
+                                    mrevt->tgt,
+                                    1, NULL);
+#endif
                         }
                         con_log(CL_ANN1, (CE_NOTE,
                             "mr_sas: EVT_CONFIG_TGT called:"
                             " for tgt %d lun %d event %d",
                             mrevt->tgt, mrevt->lun, mrevt->event));

@@ -6459,11 +7864,12 @@
         }
         kmem_free(mrevt, sizeof (struct mrsas_eventinfo));
         ndi_devi_exit(instance->dip, circ1);
 }
 
-static int
+
+int
 mrsas_mode_sense_build(struct scsi_pkt *pkt)
 {
         union scsi_cdb          *cdbp;
         uint16_t                page_code;
         struct scsa_cmd         *acmd;