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
}