Print this page
3500 Support LSI SAS2008 (Falcon) Skinny FW for mr_sas(7D)

@@ -42,11 +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.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  */
 
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/file.h>

@@ -78,10 +78,19 @@
 #include <sys/ddifm.h>
 #include <sys/fm/protocol.h>
 #include <sys/fm/util.h>
 #include <sys/fm/io/ddi.h>
 
+/* Macros to help Skinny and stock 2108/MFI live together. */
+#define WR_IB_PICK_QPORT(addr, instance) \
+        if ((instance)->skinny) { \
+                WR_IB_LOW_QPORT((addr), (instance)); \
+                WR_IB_HIGH_QPORT(0, (instance)); \
+        } else { \
+                WR_IB_QPORT((addr), (instance)); \
+        }
+
 /*
  * Local static data
  */
 static void     *mrsas_state = NULL;
 static volatile boolean_t       mrsas_relaxed_ordering = B_TRUE;

@@ -133,13 +142,10 @@
 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 *,

@@ -573,10 +579,22 @@
                         instance->func_ptr =
                             &mrsas_function_template_fusion;
                         instance->tbolt = 1;
                         break;
 
+                case PCI_DEVICE_ID_LSI_SKINNY:
+                case PCI_DEVICE_ID_LSI_SKINNY_NEW:
+                        /*
+                         * FALLTHRU to PPC-style functions, but mark this
+                         * instance as Skinny, because the register set is
+                         * slightly different (See WR_IB_PICK_QPORT), and
+                         * certain other features are available to a Skinny
+                         * HBA.
+                         */
+                        instance->skinny = 1;
+                        /* FALLTHRU */
+
                 case PCI_DEVICE_ID_LSI_2108VDE:
                 case PCI_DEVICE_ID_LSI_2108V:
                         con_log(CL_ANN, (CE_NOTE,
                             "mr_sas: 2108 Liberator device detected"));
 

@@ -813,19 +831,15 @@
 
                 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;
+                if (instance->tbolt)
+                        tran->tran_start = mrsas_tbolt_tran_start;
+                else
                         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;

@@ -938,11 +952,11 @@
                     kmem_zalloc(MRDRV_MAX_LD * sizeof (struct mrsas_ld),
                     KM_SLEEP);
                 instance->unroll.ldlist_buff = 1;
 
 #ifdef PDSUPPORT
-                if (instance->tbolt) {
+                if (instance->tbolt || instance->skinny) {
                         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);

@@ -1661,11 +1675,11 @@
                         mutex_exit(&instance->config_dev_mtx);
                 }
         }
 
 #ifdef PDSUPPORT
-        else if (instance->tbolt) {
+        else if (instance->tbolt || instance->skinny) {
                 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;

@@ -1699,11 +1713,11 @@
                         mutex_exit(&instance->config_dev_mtx);
                 }
         }
 
 #ifdef PDSUPPORT
-        else if (instance->tbolt) {
+        else if (instance->tbolt || instance->skinny) {
                 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));

@@ -1936,11 +1950,11 @@
                 if (instance->fw_outstanding > instance->max_fw_cmds) {
                         con_log(CL_ANN, (CE_CONT, "mr_sas:Firmware busy"));
                         DTRACE_PROBE2(start_tran_err,
                             uint16_t, instance->fw_outstanding,
                             uint16_t, instance->max_fw_cmds);
-                        return_mfi_pkt(instance, cmd);
+                        mrsas_return_mfi_pkt(instance, cmd);
                         return (TRAN_BUSY);
                 }
 
                 /* Synchronize the Cmd frame for the controller */
                 (void) ddi_dma_sync(cmd->frame_dma_obj.dma_handle, 0, 0,

@@ -1985,11 +1999,11 @@
                 }
 
                 (void) mrsas_common_check(instance, cmd);
                 DTRACE_PROBE2(start_nointr_done, uint8_t, hdr->cmd,
                     uint8_t, hdr->cmd_status);
-                return_mfi_pkt(instance, cmd);
+                mrsas_return_mfi_pkt(instance, cmd);
 
                 if (pkt->pkt_comp) {
                         (*pkt->pkt_comp)(pkt);
                 }
 

@@ -2459,12 +2473,12 @@
  *
  * ***** Note *****
  * After clearing the frame buffer the context id of the
  * frame buffer SHOULD be restored back.
  */
-static struct mrsas_cmd *
-get_mfi_pkt(struct mrsas_instance *instance)
+struct mrsas_cmd *
+mrsas_get_mfi_pkt(struct mrsas_instance *instance)
 {
         mlist_t                 *head = &instance->cmd_pool_list;
         struct mrsas_cmd        *cmd = NULL;
 
         mutex_enter(&instance->cmd_pool_mtx);

@@ -2507,12 +2521,12 @@
         return (cmd);
 }
 /*
  * return_mfi_pkt : Return a cmd to free command pool
  */
-static void
-return_mfi_pkt(struct mrsas_instance *instance, struct mrsas_cmd *cmd)
+void
+mrsas_return_mfi_pkt(struct mrsas_instance *instance, struct mrsas_cmd *cmd)
 {
         mutex_enter(&instance->cmd_pool_mtx);
         /* use mlist_add_tail for debug assistance */
         mlist_add_tail(&cmd->list, &instance->cmd_pool_list);
 

@@ -3160,11 +3174,17 @@
 
         INIT_LIST_HEAD(&instance->cmd_pool_list);
         INIT_LIST_HEAD(&instance->cmd_pend_list);
         INIT_LIST_HEAD(&instance->app_cmd_pool_list);
 
-        reserve_cmd = MRSAS_APP_RESERVED_CMDS;
+        /*
+         * When max_cmd is lower than MRSAS_APP_RESERVED_CMDS, how do I split
+         * into app_cmd and regular cmd?  For now, just take
+         * max(1/8th of max, 4);
+         */
+        reserve_cmd = min(MRSAS_APP_RESERVED_CMDS,
+            max(max_cmd >> 3, MRSAS_APP_MIN_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);

@@ -3274,11 +3294,11 @@
         struct mrsas_ctrl_info  *ci;
 
         if (instance->tbolt) {
                 cmd = get_raid_msg_mfi_pkt(instance);
         } else {
-                cmd = get_mfi_pkt(instance);
+                cmd = mrsas_get_mfi_pkt(instance);
         }
 
         if (!cmd) {
                 con_log(CL_ANN, (CE_WARN,
                     "Failed to get a cmd for ctrl info"));

@@ -3297,11 +3317,11 @@
         ci = (struct mrsas_ctrl_info *)instance->internal_buf;
 
         if (!ci) {
                 cmn_err(CE_WARN,
                     "Failed to alloc mem for ctrl info");
-                return_mfi_pkt(instance, cmd);
+                mrsas_return_mfi_pkt(instance, cmd);
                 return (DDI_FAILURE);
         }
 
         (void) memset(ci, 0, sizeof (struct mrsas_ctrl_info));
 

@@ -3356,11 +3376,11 @@
                 ret = -1;
         }
         if (instance->tbolt) {
                 return_raid_msg_mfi_pkt(instance, cmd);
         } else {
-                return_mfi_pkt(instance, cmd);
+                mrsas_return_mfi_pkt(instance, cmd);
         }
 
         return (ret);
 }
 

@@ -3379,11 +3399,11 @@
         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);
+                cmd = mrsas_get_mfi_pkt(instance);
         }
 
         if (!cmd) {
                 con_log(CL_ANN1, (CE_WARN,
                     "abort_aen_cmd():Failed to get a cmd for abort_aen_cmd"));

@@ -3432,11 +3452,11 @@
         instance->aen_cmd = 0;
 
         if (instance->tbolt) {
                 return_raid_msg_mfi_pkt(instance, cmd);
         } else {
-                return_mfi_pkt(instance, cmd);
+                mrsas_return_mfi_pkt(instance, cmd);
         }
 
         atomic_add_16(&instance->fw_outstanding, (-1));
 
         return (ret);

@@ -3567,11 +3587,16 @@
                     "Error, failed to allocate memory for MFI adapter"));
                 return (DDI_FAILURE);
         }
 
         /* Build INIT command */
-        cmd = get_mfi_pkt(instance);
+        cmd = mrsas_get_mfi_pkt(instance);
+        if (cmd == NULL) {
+                DTRACE_PROBE2(init_adapter_mfi_err, uint16_t,
+                    instance->fw_outstanding, uint16_t, instance->max_fw_cmds);
+                return (DDI_FAILURE);
+        }
 
         if (mrsas_build_init_cmd(instance, &cmd) != DDI_SUCCESS) {
                 con_log(CL_ANN,
                     (CE_NOTE, "Error, failed to build INIT command"));
 

@@ -3587,20 +3612,22 @@
                 goto fail_fw_init;
         }
 
         if (mrsas_common_check(instance, cmd) != DDI_SUCCESS)
                 goto fail_fw_init;
-        return_mfi_pkt(instance, cmd);
+        mrsas_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"));
                 instance->flag_ieee = 1;
         } else {
                 instance->flag_ieee = 0;
         }
 
+        ASSERT(!instance->skinny || instance->flag_ieee);
+
         instance->unroll.alloc_space_mfi = 1;
         instance->unroll.verBuff = 1;
 
         return (DDI_SUCCESS);
 

@@ -3607,11 +3634,11 @@
 
 fail_fw_init:
         (void) mrsas_free_dma_obj(instance, instance->drv_ver_dma_obj);
 
 fail_undo_alloc_mfi_space:
-        return_mfi_pkt(instance, cmd);
+        mrsas_return_mfi_pkt(instance, cmd);
         free_space_for_mfi(instance);
 
         return (DDI_FAILURE);
 
 }

@@ -3759,11 +3786,11 @@
                 return_mfi_app_pkt(instance, cmd);
                 return (DDI_FAILURE);
         }
 
         if (mrsas_common_check(instance, cmd) != DDI_SUCCESS) {
-                return_mfi_pkt(instance, cmd);
+                return_mfi_app_pkt(instance, cmd);
                 return (DDI_FAILURE);
         }
 
         return_mfi_app_pkt(instance, cmd);
         con_log(CL_ANN1, (CE_CONT, "mrsas_issue_init_mfi: Done"));

@@ -3812,11 +3839,11 @@
                          * 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) {
+                        if (!instance->tbolt && !instance->skinny) {
                                 WR_IB_DOORBELL(MFI_INIT_CLEAR_HANDSHAKE |
                                     MFI_INIT_HOTPLUG, instance);
                         } else {
                                 WR_RESERVED0_REGISTER(MFI_INIT_CLEAR_HANDSHAKE |
                                     MFI_INIT_HOTPLUG, instance);

@@ -3831,11 +3858,11 @@
                         /*
                          * PCI_Hot Plug: MFI F/W requires
                          * (MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG)
                          * to be set
                          */
-                        if (!instance->tbolt) {
+                        if (!instance->tbolt && !instance->skinny) {
                                 WR_IB_DOORBELL(MFI_INIT_HOTPLUG, instance);
                         } else {
                                 WR_RESERVED0_REGISTER(MFI_INIT_HOTPLUG,
                                     instance);
                         }

@@ -3851,11 +3878,11 @@
                          * 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) {
+                        if (!instance->tbolt && !instance->skinny) {
                                 WR_IB_DOORBELL(MFI_RESET_FLAGS, instance);
                         } else {
                                 WR_RESERVED0_REGISTER(MFI_RESET_FLAGS,
                                     instance);
 

@@ -3935,11 +3962,12 @@
                             "FW state hasn't changed in %d secs", max_wait));
                         return (ENODEV);
                 }
         };
 
-        if (!instance->tbolt) {
+        /* This may also need to apply to Skinny, but for now, don't worry. */
+        if (!instance->tbolt && !instance->skinny) {
                 fw_ctrl = RD_IB_DOORBELL(instance);
                 con_log(CL_ANN1, (CE_CONT,
                     "mfi_state_transition_to_ready:FW ctrl = 0x%x", fw_ctrl));
 
                 /*

@@ -3974,11 +4002,11 @@
         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);
+                cmd = mrsas_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,

@@ -4050,11 +4078,11 @@
                 ret = DDI_FAILURE;
 
         if (instance->tbolt) {
                 return_raid_msg_mfi_pkt(instance, cmd);
         } else {
-                return_mfi_pkt(instance, cmd);
+                mrsas_return_mfi_pkt(instance, cmd);
         }
 
         return (ret);
 }
 

@@ -4103,11 +4131,11 @@
         struct mrsas_cmd                *cmd = NULL;
         struct mrsas_dcmd_frame         *dcmd;
         if (instance->tbolt) {
                 cmd = get_raid_msg_mfi_pkt(instance);
         } else {
-                cmd = get_mfi_pkt(instance);
+                cmd = mrsas_get_mfi_pkt(instance);
         }
 
         if (!cmd) {
                 con_log(CL_ANN1, (CE_WARN,
                     "flush_cache():Failed to get a cmd for flush_cache"));

@@ -4149,11 +4177,11 @@
         }
         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);
+                mrsas_return_mfi_pkt(instance, cmd);
         }
 
 }
 
 /*

@@ -4249,11 +4277,11 @@
                 break;
         } /* End of MR_EVT_LD_CREATED */
 
 #ifdef PDSUPPORT
         case MR_EVT_PD_REMOVED_EXT: {
-                if (instance->tbolt) {
+                if (instance->tbolt || instance->skinny) {
                         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));

@@ -4273,11 +4301,11 @@
                 }
                 break;
         } /* End of MR_EVT_PD_REMOVED_EXT */
 
         case MR_EVT_PD_INSERTED_EXT: {
-                if (instance->tbolt) {
+                if (instance->tbolt || instance->skinny) {
                         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:"

@@ -4287,11 +4315,11 @@
                 }
                 break;
         } /* End of MR_EVT_PD_INSERTED_EXT */
 
         case MR_EVT_PD_STATE_CHANGE: {
-                if (instance->tbolt) {
+                if (instance->tbolt || instance->skinny) {
                         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)) {

@@ -4523,10 +4551,16 @@
                                 if (acmd->cmd_dmacount != 0) {
                                         bp_mapin(acmd->cmd_buf);
                                         inq = (struct scsi_inquiry *)
                                             acmd->cmd_buf->b_un.b_addr;
 
+#ifdef PDSUPPORT
+                                        if (hdr->cmd_status == MFI_STAT_OK) {
+                                                display_scsi_inquiry(
+                                                    (caddr_t)inq);
+                                        }
+#else
                                         /* don't expose physical drives to OS */
                                         if (acmd->islogical &&
                                             (hdr->cmd_status == MFI_STAT_OK)) {
                                                 display_scsi_inquiry(
                                                     (caddr_t)inq);

@@ -4539,10 +4573,11 @@
 
                                                 /* for physical disk */
                                                 hdr->cmd_status =
                                                     MFI_STAT_DEVICE_NOT_FOUND;
                                         }
+#endif /* PDSUPPORT */
                                 }
                         }
 
                         DTRACE_PROBE2(softintr_done, uint8_t, hdr->cmd,
                             uint8_t, hdr->cmd_status);

@@ -4647,23 +4682,18 @@
                                         pkt->pkt_reason = CMD_TRAN_ERR;
                                         pkt->pkt_statistics = 0;
                                 }
                         }
 
+                        mrsas_return_mfi_pkt(instance, cmd);
+
                         /* Call the callback routine */
                         if (((pkt->pkt_flags & FLAG_NOINTR) == 0) &&
                             pkt->pkt_comp) {
-
-                                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);

@@ -5086,11 +5116,11 @@
         acmd->islogical = MRDRV_IS_LOGICAL(ap);
         acmd->device_id = MAP_DEVICE_ID(instance, ap);
         *cmd_done = 0;
 
         /* get the command packet */
-        if (!(cmd = get_mfi_pkt(instance))) {
+        if (!(cmd = mrsas_get_mfi_pkt(instance))) {
                 DTRACE_PROBE2(build_cmd_mfi_err, uint16_t,
                     instance->fw_outstanding, uint16_t, instance->max_fw_cmds);
                 return (NULL);
         }
 

@@ -5134,11 +5164,11 @@
         switch (pkt->pkt_cdbp[0]) {
 
         /*
          * case SCMD_SYNCHRONIZE_CACHE:
          *      flush_cache(instance);
-         *      return_mfi_pkt(instance, cmd);
+         *      mrsas_return_mfi_pkt(instance, cmd);
          *      *cmd_done = 1;
          *
          *      return (NULL);
          */
 

@@ -5243,11 +5273,11 @@
                                     ((uint32_t)(pkt->pkt_cdbp[2]) << 24)));
                         }
 
                         break;
                 }
-                /* fall through For all non-rd/wr cmds */
+                /* fall through For all non-rd/wr and physical disk cmds */
         default:
 
                 switch (pkt->pkt_cdbp[0]) {
                 case SCMD_MODE_SENSE:
                 case SCMD_MODE_SENSE_G1: {

@@ -5258,11 +5288,11 @@
                         page_code = (uint16_t)cdbp->cdb_un.sg.scsi[0];
                         switch (page_code) {
                         case 0x3:
                         case 0x4:
                                 (void) mrsas_mode_sense_build(pkt);
-                                return_mfi_pkt(instance, cmd);
+                                mrsas_return_mfi_pkt(instance, cmd);
                                 *cmd_done = 1;
                                 return (NULL);
                         }
                         break;
                 }

@@ -6292,11 +6322,11 @@
         struct mrsas_cmd        *cmd;
 
         if (instance->tbolt) {
                 cmd = get_raid_msg_mfi_pkt(instance);
         } else {
-                cmd = get_mfi_pkt(instance);
+                cmd = mrsas_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,

@@ -6336,11 +6366,11 @@
                 rval = DDI_FAILURE;
 
         if (instance->tbolt) {
                 return_raid_msg_mfi_pkt(instance, cmd);
         } else {
-                return_mfi_pkt(instance, cmd);
+                mrsas_return_mfi_pkt(instance, cmd);
         }
 
         return (rval);
 }
 

@@ -6433,11 +6463,11 @@
         }
 
         if (instance->tbolt) {
                 cmd = get_raid_msg_mfi_pkt(instance);
         } else {
-                cmd = get_mfi_pkt(instance);
+                cmd = mrsas_get_mfi_pkt(instance);
         }
 
         if (!cmd) {
                 DTRACE_PROBE2(mfi_aen_err, uint16_t, instance->fw_outstanding,
                     uint16_t, instance->max_fw_cmds);

@@ -6726,11 +6756,11 @@
                     "(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) |
+        WR_IB_PICK_QPORT((cmd->frame_phys_addr) |
             (((cmd->frame_count - 1) << 1) | 1), instance);
         mutex_exit(&instance->reg_write_mtx);
 
 }
 

@@ -6737,14 +6767,14 @@
 /*
  * issue_cmd_in_sync_mode
  */
 static int
 issue_cmd_in_sync_mode_ppc(struct mrsas_instance *instance,
-struct mrsas_cmd *cmd)
+    struct mrsas_cmd *cmd)
 {
         int     i;
-        uint32_t        msecs = MFI_POLL_TIMEOUT_SECS * (10 * MILLISEC);
+        uint32_t        msecs = MFI_POLL_TIMEOUT_SECS * MILLISEC;
         struct mrsas_header *hdr = &cmd->frame->hdr;
 
         con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_sync_mode_ppc: called"));
 
         if (instance->adapterresetinprogress) {

@@ -6753,11 +6783,11 @@
                 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) |
+                WR_IB_PICK_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"));

@@ -6766,11 +6796,11 @@
 
         cmd->cmd_status = ENODATA;
 
         mutex_enter(&instance->reg_write_mtx);
         /* Issue the command to the FW */
-        WR_IB_QPORT((cmd->frame_phys_addr) |
+        WR_IB_PICK_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++) {

@@ -6808,11 +6838,11 @@
         flags   |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
 
         ddi_put16(cmd->frame_dma_obj.acc_handle, &frame_hdr->flags, flags);
 
         /* issue the frame using inbound queue port */
-        WR_IB_QPORT((cmd->frame_phys_addr) |
+        WR_IB_PICK_QPORT((cmd->frame_phys_addr) |
             (((cmd->frame_count - 1) << 1) | 1), instance);
 
         /* wait for cmd_status to change from 0xFF */
         for (i = 0; i < msecs && (
             ddi_get8(cmd->frame_dma_obj.acc_handle, &frame_hdr->cmd_status)

@@ -6835,15 +6865,20 @@
 {
         uint32_t        mask;
 
         con_log(CL_ANN1, (CE_NOTE, "enable_intr_ppc: called"));
 
+        if (instance->skinny) {
+                /* For SKINNY, write ~0x1, from BSD's mfi driver. */
+                WR_OB_INTR_MASK(0xfffffffe, instance);
+        } else {
         /* WR_OB_DOORBELL_CLEAR(0xFFFFFFFF, instance); */
         WR_OB_DOORBELL_CLEAR(OB_DOORBELL_CLEAR_MASK, instance);
 
         /* WR_OB_INTR_MASK(~0x80000000, instance); */
         WR_OB_INTR_MASK(~(MFI_REPLY_2108_MESSAGE_INTR_MASK), instance);
+        }
 
         /* dummy read to force PCI flush */
         mask = RD_OB_INTR_MASK(instance);
 
         con_log(CL_ANN1, (CE_NOTE, "enable_intr_ppc: "

@@ -6858,11 +6893,12 @@
         con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: called"));
 
         con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: before : "
             "outbound_intr_mask = 0x%x", RD_OB_INTR_MASK(instance)));
 
-        /* WR_OB_INTR_MASK(0xFFFFFFFF, instance); */
+        /* For now, assume there are no extras needed for Skinny support. */
+
         WR_OB_INTR_MASK(OB_INTR_MASK, instance);
 
         con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: after : "
             "outbound_intr_mask = 0x%x", RD_OB_INTR_MASK(instance)));
 

@@ -6884,10 +6920,14 @@
         /* check if it is our interrupt */
         status = RD_OB_INTR_STATUS(instance);
 
         con_log(CL_ANN1, (CE_NOTE, "intr_ack_ppc: status = 0x%x", status));
 
+        /*
+         * NOTE:  Some drivers call out SKINNY here, but the return is the same
+         * for SKINNY and 2108.
+         */
         if (!(status & MFI_REPLY_2108_MESSAGE_INTR)) {
                 ret = DDI_INTR_UNCLAIMED;
         }
 
         if (mrsas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) {

@@ -6896,12 +6936,20 @@
         }
 
         if (ret == DDI_INTR_UNCLAIMED) {
                 return (ret);
         }
-        /* clear the interrupt by writing back the same value */
+
+        /*
+         * Clear the interrupt by writing back the same value.
+         * Another case where SKINNY is slightly different.
+         */
+        if (instance->skinny) {
+                WR_OB_INTR_STATUS(status, instance);
+        } else {
         WR_OB_DOORBELL_CLEAR(status, instance);
+        }
 
         /* dummy READ */
         status = RD_OB_INTR_STATUS(instance);
 
         con_log(CL_ANN1, (CE_NOTE, "intr_ack_ppc: interrupt cleared"));

@@ -7483,11 +7531,11 @@
                 }
 
                 if (lun == 0) {
                         rval = mrsas_config_ld(instance, tgt, lun, childp);
 #ifdef PDSUPPORT
-                } else if (instance->tbolt == 1 && lun != 0) {
+                } else if ((instance->tbolt || instance->skinny) && lun != 0) {
                         rval = mrsas_tbolt_config_pd(instance,
                             tgt, lun, childp);
 #endif
                 } else {
                         rval = NDI_FAILURE;

@@ -7526,11 +7574,11 @@
 
         }
 
 #ifdef PDSUPPORT
         /* Config PD devices connected to the card */
-        if (instance->tbolt) {
+        if (instance->tbolt || instance->skinny) {
                 for (tgt = 0; tgt < instance->mr_tbolt_pd_max; tgt++) {
                         (void) mrsas_tbolt_config_pd(instance, tgt, 1, NULL);
                 }
         }
 #endif

@@ -7780,11 +7828,11 @@
 
                         if (mrevt->lun == 0) {
                                 (void) mrsas_config_ld(instance, mrevt->tgt,
                                     0, NULL);
 #ifdef PDSUPPORT
-                        } else if (instance->tbolt) {
+                        } else if (instance->tbolt || instance->skinny) {
                                 (void) mrsas_tbolt_config_pd(instance,
                                     mrevt->tgt,
                                     1, NULL);
 #endif
                         }