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 }