Print this page
3500 Support LSI SAS2008 (Falcon) Skinny FW for mr_sas(7D)
*** 42,52 ****
*/
/*
* 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>
--- 42,52 ----
*/
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 Bayard G. Bell. All rights reserved.
! * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/file.h>
*** 78,87 ****
--- 78,96 ----
#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,145 ****
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 *,
--- 142,151 ----
*** 573,582 ****
--- 579,600 ----
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,831 ****
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;
--- 831,845 ----
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;
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,948 ****
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);
--- 952,962 ----
kmem_zalloc(MRDRV_MAX_LD * sizeof (struct mrsas_ld),
KM_SLEEP);
instance->unroll.ldlist_buff = 1;
#ifdef PDSUPPORT
! 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,1671 ****
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;
--- 1675,1685 ----
mutex_exit(&instance->config_dev_mtx);
}
}
#ifdef PDSUPPORT
! 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,1709 ****
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));
--- 1713,1723 ----
mutex_exit(&instance->config_dev_mtx);
}
}
#ifdef PDSUPPORT
! 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,1946 ****
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);
return (TRAN_BUSY);
}
/* Synchronize the Cmd frame for the controller */
(void) ddi_dma_sync(cmd->frame_dma_obj.dma_handle, 0, 0,
--- 1950,1960 ----
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);
! 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,1995 ****
}
(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);
if (pkt->pkt_comp) {
(*pkt->pkt_comp)(pkt);
}
--- 1999,2009 ----
}
(void) mrsas_common_check(instance, cmd);
DTRACE_PROBE2(start_nointr_done, uint8_t, hdr->cmd,
uint8_t, hdr->cmd_status);
! mrsas_return_mfi_pkt(instance, cmd);
if (pkt->pkt_comp) {
(*pkt->pkt_comp)(pkt);
}
*** 2459,2470 ****
*
* ***** 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)
{
mlist_t *head = &instance->cmd_pool_list;
struct mrsas_cmd *cmd = NULL;
mutex_enter(&instance->cmd_pool_mtx);
--- 2473,2484 ----
*
* ***** Note *****
* After clearing the frame buffer the context id of the
* frame buffer SHOULD be restored back.
*/
! 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,2518 ****
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)
{
mutex_enter(&instance->cmd_pool_mtx);
/* use mlist_add_tail for debug assistance */
mlist_add_tail(&cmd->list, &instance->cmd_pool_list);
--- 2521,2532 ----
return (cmd);
}
/*
* return_mfi_pkt : Return a cmd to free command pool
*/
! 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,3170 ****
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;
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);
--- 3174,3190 ----
INIT_LIST_HEAD(&instance->cmd_pool_list);
INIT_LIST_HEAD(&instance->cmd_pend_list);
INIT_LIST_HEAD(&instance->app_cmd_pool_list);
! /*
! * 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,3284 ****
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"));
--- 3294,3304 ----
struct mrsas_ctrl_info *ci;
if (instance->tbolt) {
cmd = get_raid_msg_mfi_pkt(instance);
} else {
! cmd = mrsas_get_mfi_pkt(instance);
}
if (!cmd) {
con_log(CL_ANN, (CE_WARN,
"Failed to get a cmd for ctrl info"));
*** 3297,3307 ****
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);
return (DDI_FAILURE);
}
(void) memset(ci, 0, sizeof (struct mrsas_ctrl_info));
--- 3317,3327 ----
ci = (struct mrsas_ctrl_info *)instance->internal_buf;
if (!ci) {
cmn_err(CE_WARN,
"Failed to alloc mem for ctrl info");
! mrsas_return_mfi_pkt(instance, cmd);
return (DDI_FAILURE);
}
(void) memset(ci, 0, sizeof (struct mrsas_ctrl_info));
*** 3356,3366 ****
ret = -1;
}
if (instance->tbolt) {
return_raid_msg_mfi_pkt(instance, cmd);
} else {
! return_mfi_pkt(instance, cmd);
}
return (ret);
}
--- 3376,3386 ----
ret = -1;
}
if (instance->tbolt) {
return_raid_msg_mfi_pkt(instance, cmd);
} else {
! mrsas_return_mfi_pkt(instance, cmd);
}
return (ret);
}
*** 3379,3389 ****
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"));
--- 3399,3409 ----
con_log(CL_ANN1, (CE_NOTE, "chkpnt: abort_aen:%d", __LINE__));
if (instance->tbolt) {
cmd = get_raid_msg_mfi_pkt(instance);
} else {
! 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,3442 ****
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);
--- 3452,3462 ----
instance->aen_cmd = 0;
if (instance->tbolt) {
return_raid_msg_mfi_pkt(instance, cmd);
} else {
! mrsas_return_mfi_pkt(instance, cmd);
}
atomic_add_16(&instance->fw_outstanding, (-1));
return (ret);
*** 3567,3577 ****
"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"));
--- 3587,3602 ----
"Error, failed to allocate memory for MFI adapter"));
return (DDI_FAILURE);
}
/* Build INIT command */
! 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,3606 ****
goto fail_fw_init;
}
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"));
instance->flag_ieee = 1;
} else {
instance->flag_ieee = 0;
}
instance->unroll.alloc_space_mfi = 1;
instance->unroll.verBuff = 1;
return (DDI_SUCCESS);
--- 3612,3633 ----
goto fail_fw_init;
}
if (mrsas_common_check(instance, cmd) != DDI_SUCCESS)
goto fail_fw_init;
! 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,3617 ****
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);
}
--- 3634,3644 ----
fail_fw_init:
(void) mrsas_free_dma_obj(instance, instance->drv_ver_dma_obj);
fail_undo_alloc_mfi_space:
! mrsas_return_mfi_pkt(instance, cmd);
free_space_for_mfi(instance);
return (DDI_FAILURE);
}
*** 3759,3769 ****
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_CONT, "mrsas_issue_init_mfi: Done"));
--- 3786,3796 ----
return_mfi_app_pkt(instance, cmd);
return (DDI_FAILURE);
}
if (mrsas_common_check(instance, cmd) != DDI_SUCCESS) {
! 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,3822 ****
* 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);
} else {
WR_RESERVED0_REGISTER(MFI_INIT_CLEAR_HANDSHAKE |
MFI_INIT_HOTPLUG, instance);
--- 3839,3849 ----
* 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 && !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,3841 ****
/*
* 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);
} else {
WR_RESERVED0_REGISTER(MFI_INIT_HOTPLUG,
instance);
}
--- 3858,3868 ----
/*
* PCI_Hot Plug: MFI F/W requires
* (MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG)
* to be set
*/
! if (!instance->tbolt && !instance->skinny) {
WR_IB_DOORBELL(MFI_INIT_HOTPLUG, instance);
} else {
WR_RESERVED0_REGISTER(MFI_INIT_HOTPLUG,
instance);
}
*** 3851,3861 ****
* 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);
--- 3878,3888 ----
* 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 && !instance->skinny) {
WR_IB_DOORBELL(MFI_RESET_FLAGS, instance);
} else {
WR_RESERVED0_REGISTER(MFI_RESET_FLAGS,
instance);
*** 3935,3945 ****
"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_CONT,
"mfi_state_transition_to_ready:FW ctrl = 0x%x", fw_ctrl));
/*
--- 3962,3973 ----
"FW state hasn't changed in %d secs", max_wait));
return (ENODEV);
}
};
! /* 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,3984 ****
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,
--- 4002,4012 ----
struct mrsas_dcmd_frame *dcmd;
struct mrsas_evt_log_info *eli_tmp;
if (instance->tbolt) {
cmd = get_raid_msg_mfi_pkt(instance);
} else {
! 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,4060 ****
ret = DDI_FAILURE;
if (instance->tbolt) {
return_raid_msg_mfi_pkt(instance, cmd);
} else {
! return_mfi_pkt(instance, cmd);
}
return (ret);
}
--- 4078,4088 ----
ret = DDI_FAILURE;
if (instance->tbolt) {
return_raid_msg_mfi_pkt(instance, cmd);
} else {
! mrsas_return_mfi_pkt(instance, cmd);
}
return (ret);
}
*** 4103,4113 ****
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);
}
if (!cmd) {
con_log(CL_ANN1, (CE_WARN,
"flush_cache():Failed to get a cmd for flush_cache"));
--- 4131,4141 ----
struct mrsas_cmd *cmd = NULL;
struct mrsas_dcmd_frame *dcmd;
if (instance->tbolt) {
cmd = get_raid_msg_mfi_pkt(instance);
} else {
! 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,4159 ****
}
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);
}
}
/*
--- 4177,4187 ----
}
con_log(CL_ANN1, (CE_CONT, "flush_cache done"));
if (instance->tbolt) {
return_raid_msg_mfi_pkt(instance, cmd);
} else {
! mrsas_return_mfi_pkt(instance, cmd);
}
}
/*
*** 4249,4259 ****
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));
--- 4277,4287 ----
break;
} /* End of MR_EVT_LD_CREATED */
#ifdef PDSUPPORT
case MR_EVT_PD_REMOVED_EXT: {
! 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,4283 ****
}
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:"
--- 4301,4311 ----
}
break;
} /* End of MR_EVT_PD_REMOVED_EXT */
case MR_EVT_PD_INSERTED_EXT: {
! 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,4297 ****
}
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)) {
--- 4315,4325 ----
}
break;
} /* End of MR_EVT_PD_INSERTED_EXT */
case MR_EVT_PD_STATE_CHANGE: {
! 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,4532 ****
--- 4551,4566 ----
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,4548 ****
--- 4573,4583 ----
/* 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,4669 ****
pkt->pkt_reason = CMD_TRAN_ERR;
pkt->pkt_statistics = 0;
}
}
/* 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);
--- 4682,4699 ----
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) {
(*pkt->pkt_comp)(pkt);
}
break;
case MFI_CMD_OP_SMP:
case MFI_CMD_OP_STP:
complete_cmd_in_sync_mode(instance, cmd);
*** 5086,5096 ****
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))) {
DTRACE_PROBE2(build_cmd_mfi_err, uint16_t,
instance->fw_outstanding, uint16_t, instance->max_fw_cmds);
return (NULL);
}
--- 5116,5126 ----
acmd->islogical = MRDRV_IS_LOGICAL(ap);
acmd->device_id = MAP_DEVICE_ID(instance, ap);
*cmd_done = 0;
/* get the command packet */
! 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,5144 ****
switch (pkt->pkt_cdbp[0]) {
/*
* case SCMD_SYNCHRONIZE_CACHE:
* flush_cache(instance);
! * return_mfi_pkt(instance, cmd);
* *cmd_done = 1;
*
* return (NULL);
*/
--- 5164,5174 ----
switch (pkt->pkt_cdbp[0]) {
/*
* case SCMD_SYNCHRONIZE_CACHE:
* flush_cache(instance);
! * mrsas_return_mfi_pkt(instance, cmd);
* *cmd_done = 1;
*
* return (NULL);
*/
*** 5243,5253 ****
((uint32_t)(pkt->pkt_cdbp[2]) << 24)));
}
break;
}
! /* fall through For all non-rd/wr cmds */
default:
switch (pkt->pkt_cdbp[0]) {
case SCMD_MODE_SENSE:
case SCMD_MODE_SENSE_G1: {
--- 5273,5283 ----
((uint32_t)(pkt->pkt_cdbp[2]) << 24)));
}
break;
}
! /* 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,5268 ****
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);
*cmd_done = 1;
return (NULL);
}
break;
}
--- 5288,5298 ----
page_code = (uint16_t)cdbp->cdb_un.sg.scsi[0];
switch (page_code) {
case 0x3:
case 0x4:
(void) mrsas_mode_sense_build(pkt);
! mrsas_return_mfi_pkt(instance, cmd);
*cmd_done = 1;
return (NULL);
}
break;
}
*** 6292,6302 ****
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,
--- 6322,6332 ----
struct mrsas_cmd *cmd;
if (instance->tbolt) {
cmd = get_raid_msg_mfi_pkt(instance);
} else {
! 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,6346 ****
rval = DDI_FAILURE;
if (instance->tbolt) {
return_raid_msg_mfi_pkt(instance, cmd);
} else {
! return_mfi_pkt(instance, cmd);
}
return (rval);
}
--- 6366,6376 ----
rval = DDI_FAILURE;
if (instance->tbolt) {
return_raid_msg_mfi_pkt(instance, cmd);
} else {
! mrsas_return_mfi_pkt(instance, cmd);
}
return (rval);
}
*** 6433,6443 ****
}
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);
--- 6463,6473 ----
}
if (instance->tbolt) {
cmd = get_raid_msg_mfi_pkt(instance);
} else {
! 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,6736 ****
"(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);
}
--- 6756,6766 ----
"(NO PKT)\n", gethrtime(), (void *)cmd, (void *)instance));
}
mutex_enter(&instance->reg_write_mtx);
/* Issue the command to the FW */
! WR_IB_PICK_QPORT((cmd->frame_phys_addr) |
(((cmd->frame_count - 1) << 1) | 1), instance);
mutex_exit(&instance->reg_write_mtx);
}
*** 6737,6750 ****
/*
* issue_cmd_in_sync_mode
*/
static int
issue_cmd_in_sync_mode_ppc(struct mrsas_instance *instance,
! struct mrsas_cmd *cmd)
{
int i;
! uint32_t msecs = MFI_POLL_TIMEOUT_SECS * (10 * MILLISEC);
struct mrsas_header *hdr = &cmd->frame->hdr;
con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_sync_mode_ppc: called"));
if (instance->adapterresetinprogress) {
--- 6767,6780 ----
/*
* issue_cmd_in_sync_mode
*/
static int
issue_cmd_in_sync_mode_ppc(struct mrsas_instance *instance,
! struct mrsas_cmd *cmd)
{
int i;
! 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,6763 ****
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"));
--- 6783,6793 ----
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_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,6776 ****
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++) {
--- 6796,6806 ----
cmd->cmd_status = ENODATA;
mutex_enter(&instance->reg_write_mtx);
/* Issue the command to the FW */
! 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,6818 ****
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) |
(((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)
--- 6838,6848 ----
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_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,6849 ****
--- 6865,6884 ----
{
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,6868 ****
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); */
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)));
--- 6893,6904 ----
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)));
! /* 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,6893 ****
--- 6920,6933 ----
/* 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,6907 ****
}
if (ret == DDI_INTR_UNCLAIMED) {
return (ret);
}
! /* clear the interrupt by writing back the same value */
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"));
--- 6936,6955 ----
}
if (ret == DDI_INTR_UNCLAIMED) {
return (ret);
}
!
! /*
! * 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,7493 ****
}
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;
--- 7531,7541 ----
}
if (lun == 0) {
rval = mrsas_config_ld(instance, tgt, lun, childp);
#ifdef PDSUPPORT
! } else if ((instance->tbolt || instance->skinny) && lun != 0) {
rval = mrsas_tbolt_config_pd(instance,
tgt, lun, childp);
#endif
} else {
rval = NDI_FAILURE;
*** 7526,7536 ****
}
#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
--- 7574,7584 ----
}
#ifdef PDSUPPORT
/* Config PD devices connected to the card */
! 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,7790 ****
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
}
--- 7828,7838 ----
if (mrevt->lun == 0) {
(void) mrsas_config_ld(instance, mrevt->tgt,
0, NULL);
#ifdef PDSUPPORT
! } else if (instance->tbolt || instance->skinny) {
(void) mrsas_tbolt_config_pd(instance,
mrevt->tgt,
1, NULL);
#endif
}