Print this page

        

*** 10,21 **** --- 10,54 ---- * Swaminathan K S * Arun Chandrashekhar * Manju R * Rasheed * Shakeel Bukhari + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the author nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. */ + /* + * 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> #include <sys/errno.h> #include <sys/open.h>
*** 38,82 **** #include <sys/fs/dv_node.h> /* devfs_clean */ #include "mr_sas.h" /* * Local static data */ static void *mrsas_state = NULL; ! static volatile boolean_t mrsas_relaxed_ordering = 0; volatile int debug_level_g = CL_NONE; - static volatile int msi_enable = 1; /* Default Timeout value to issue online controller reset */ ! volatile int debug_timeout_g = 0xF0; //0xB4; /* Simulate consecutive firmware fault */ static volatile int debug_fw_faults_after_ocr_g = 0; #ifdef OCRDEBUG /* Simulate three consecutive timeout for an IO */ static volatile int debug_consecutive_timeout_after_ocr_g = 0; #endif - /* Enable OCR on firmware fault */ - static volatile int debug_support_ocr_isr_g = 0; #pragma weak scsi_hba_open #pragma weak scsi_hba_close #pragma weak scsi_hba_ioctl static struct mrsas_function_template mrsas_function_template_ppc = { .read_fw_status_reg = read_fw_status_reg_ppc, .issue_cmd = issue_cmd_ppc, .issue_cmd_in_sync_mode = issue_cmd_in_sync_mode_ppc, .issue_cmd_in_poll_mode = issue_cmd_in_poll_mode_ppc, .enable_intr = enable_intr_ppc, .disable_intr = disable_intr_ppc, .intr_ack = intr_ack_ppc, .init_adapter = mrsas_init_adapter_ppc - // .reset_adapter = mrsas_reset_adapter_ppc }; static struct mrsas_function_template mrsas_function_template_fusion = { .read_fw_status_reg = tbolt_read_fw_status_reg, --- 71,215 ---- #include <sys/fs/dv_node.h> /* devfs_clean */ #include "mr_sas.h" /* + * FMA header files + */ + #include <sys/ddifm.h> + #include <sys/fm/protocol.h> + #include <sys/fm/util.h> + #include <sys/fm/io/ddi.h> + + /* * Local static data */ static void *mrsas_state = NULL; ! static volatile boolean_t mrsas_relaxed_ordering = B_TRUE; volatile int debug_level_g = CL_NONE; static volatile int msi_enable = 1; + static volatile int ctio_enable = 1; /* Default Timeout value to issue online controller reset */ ! volatile int debug_timeout_g = 0xF0; /* 0xB4; */ /* Simulate consecutive firmware fault */ static volatile int debug_fw_faults_after_ocr_g = 0; #ifdef OCRDEBUG /* Simulate three consecutive timeout for an IO */ static volatile int debug_consecutive_timeout_after_ocr_g = 0; #endif #pragma weak scsi_hba_open #pragma weak scsi_hba_close #pragma weak scsi_hba_ioctl + /* Local static prototypes. */ + static int mrsas_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); + static int mrsas_attach(dev_info_t *, ddi_attach_cmd_t); + #ifdef __sparc + static int mrsas_reset(dev_info_t *, ddi_reset_cmd_t); + #else + static int mrsas_quiesce(dev_info_t *); + #endif + static int mrsas_detach(dev_info_t *, ddi_detach_cmd_t); + static int mrsas_open(dev_t *, int, int, cred_t *); + static int mrsas_close(dev_t, int, int, cred_t *); + static int mrsas_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); + static int mrsas_tran_tgt_init(dev_info_t *, dev_info_t *, + scsi_hba_tran_t *, struct scsi_device *); + static struct scsi_pkt *mrsas_tran_init_pkt(struct scsi_address *, register + struct scsi_pkt *, struct buf *, int, int, int, int, + int (*)(), caddr_t); + static int mrsas_tran_start(struct scsi_address *, + register struct scsi_pkt *); + static int mrsas_tran_abort(struct scsi_address *, struct scsi_pkt *); + static int mrsas_tran_reset(struct scsi_address *, int); + static int mrsas_tran_getcap(struct scsi_address *, char *, int); + static int mrsas_tran_setcap(struct scsi_address *, char *, int, int); + static void mrsas_tran_destroy_pkt(struct scsi_address *, + struct scsi_pkt *); + static void mrsas_tran_dmafree(struct scsi_address *, struct scsi_pkt *); + static void mrsas_tran_sync_pkt(struct scsi_address *, struct scsi_pkt *); + static int mrsas_tran_quiesce(dev_info_t *dip); + static int mrsas_tran_unquiesce(dev_info_t *dip); + static uint_t mrsas_isr(); + static uint_t mrsas_softintr(); + static void mrsas_undo_resources(dev_info_t *, struct mrsas_instance *); + static struct mrsas_cmd *get_mfi_pkt(struct mrsas_instance *); + static void return_mfi_pkt(struct mrsas_instance *, + struct mrsas_cmd *); + static void free_space_for_mfi(struct mrsas_instance *); + static uint32_t read_fw_status_reg_ppc(struct mrsas_instance *); + static void issue_cmd_ppc(struct mrsas_cmd *, struct mrsas_instance *); + static int issue_cmd_in_poll_mode_ppc(struct mrsas_instance *, + struct mrsas_cmd *); + static int issue_cmd_in_sync_mode_ppc(struct mrsas_instance *, + struct mrsas_cmd *); + static void enable_intr_ppc(struct mrsas_instance *); + static void disable_intr_ppc(struct mrsas_instance *); + static int intr_ack_ppc(struct mrsas_instance *); + static void flush_cache(struct mrsas_instance *instance); + void display_scsi_inquiry(caddr_t); + static int start_mfi_aen(struct mrsas_instance *instance); + static int handle_drv_ioctl(struct mrsas_instance *instance, + struct mrsas_ioctl *ioctl, int mode); + static int handle_mfi_ioctl(struct mrsas_instance *instance, + struct mrsas_ioctl *ioctl, int mode); + static int handle_mfi_aen(struct mrsas_instance *instance, + struct mrsas_aen *aen); + static struct mrsas_cmd *build_cmd(struct mrsas_instance *, + struct scsi_address *, struct scsi_pkt *, uchar_t *); + static int alloc_additional_dma_buffer(struct mrsas_instance *); + static void complete_cmd_in_sync_mode(struct mrsas_instance *, + struct mrsas_cmd *); + static int mrsas_kill_adapter(struct mrsas_instance *); + static int mrsas_issue_init_mfi(struct mrsas_instance *); + static int mrsas_reset_ppc(struct mrsas_instance *); + static uint32_t mrsas_initiate_ocr_if_fw_is_faulty(struct mrsas_instance *); + static int wait_for_outstanding(struct mrsas_instance *instance); + static int register_mfi_aen(struct mrsas_instance *instance, + uint32_t seq_num, uint32_t class_locale_word); + static int issue_mfi_pthru(struct mrsas_instance *instance, struct + mrsas_ioctl *ioctl, struct mrsas_cmd *cmd, int mode); + static int issue_mfi_dcmd(struct mrsas_instance *instance, struct + mrsas_ioctl *ioctl, struct mrsas_cmd *cmd, int mode); + static int issue_mfi_smp(struct mrsas_instance *instance, struct + mrsas_ioctl *ioctl, struct mrsas_cmd *cmd, int mode); + static int issue_mfi_stp(struct mrsas_instance *instance, struct + mrsas_ioctl *ioctl, struct mrsas_cmd *cmd, int mode); + static int abort_aen_cmd(struct mrsas_instance *instance, + struct mrsas_cmd *cmd_to_abort); + + static void mrsas_rem_intrs(struct mrsas_instance *instance); + static int mrsas_add_intrs(struct mrsas_instance *instance, int intr_type); + + static void mrsas_tran_tgt_free(dev_info_t *, dev_info_t *, + scsi_hba_tran_t *, struct scsi_device *); + static int mrsas_tran_bus_config(dev_info_t *, uint_t, + ddi_bus_config_op_t, void *, dev_info_t **); + static int mrsas_parse_devname(char *, int *, int *); + static int mrsas_config_all_devices(struct mrsas_instance *); + static int mrsas_config_ld(struct mrsas_instance *, uint16_t, + uint8_t, dev_info_t **); + static int mrsas_name_node(dev_info_t *, char *, int); + static void mrsas_issue_evt_taskq(struct mrsas_eventinfo *); + static void free_additional_dma_buffer(struct mrsas_instance *); + static void io_timeout_checker(void *); + static void mrsas_fm_init(struct mrsas_instance *); + static void mrsas_fm_fini(struct mrsas_instance *); + static struct mrsas_function_template mrsas_function_template_ppc = { .read_fw_status_reg = read_fw_status_reg_ppc, .issue_cmd = issue_cmd_ppc, .issue_cmd_in_sync_mode = issue_cmd_in_sync_mode_ppc, .issue_cmd_in_poll_mode = issue_cmd_in_poll_mode_ppc, .enable_intr = enable_intr_ppc, .disable_intr = disable_intr_ppc, .intr_ack = intr_ack_ppc, .init_adapter = mrsas_init_adapter_ppc }; static struct mrsas_function_template mrsas_function_template_fusion = { .read_fw_status_reg = tbolt_read_fw_status_reg,
*** 85,95 **** .issue_cmd_in_poll_mode = tbolt_issue_cmd_in_poll_mode, .enable_intr = tbolt_enable_intr, .disable_intr = tbolt_disable_intr, .intr_ack = tbolt_intr_ack, .init_adapter = mrsas_init_adapter_tbolt - // .reset_adapter = mrsas_reset_adapter_tbolt }; ddi_dma_attr_t mrsas_generic_dma_attr = { DMA_ATTR_V0, /* dma_attr_version */ --- 218,227 ----
*** 106,116 **** 0 /* bus specific DMA flags */ }; int32_t mrsas_max_cap_maxxfer = 0x1000000; ! //Fix for: Thunderbolt controller IO timeout when IO write size is 1MEG, Limit size to 256K uint32_t mrsas_tbolt_max_cap_maxxfer = (512 * 512); /* * cb_ops contains base level routines */ --- 238,251 ---- 0 /* bus specific DMA flags */ }; int32_t mrsas_max_cap_maxxfer = 0x1000000; ! /* ! * Fix for: Thunderbolt controller IO timeout when IO write size is 1MEG, ! * Limit size to 256K ! */ uint32_t mrsas_tbolt_max_cap_maxxfer = (512 * 512); /* * cb_ops contains base level routines */
*** 144,169 **** mrsas_getinfo, /* getinfo */ nulldev, /* identify */ nulldev, /* probe */ mrsas_attach, /* attach */ mrsas_detach, /* detach */ ! #if defined(__SunOS_5_11) ! nodev, ! #else mrsas_reset, /* reset */ ! #endif /* defined(__SunOS_5_11) */ &mrsas_cb_ops, /* char/block ops */ NULL, /* bus ops */ NULL, /* power */ ! #ifdef __SunOS_5_11 mrsas_quiesce /* quiesce */ ! #endif /*__SunOS_5_11 */ ! }; - char _depends_on[] = "misc/scsi"; - static struct modldrv modldrv = { &mod_driverops, /* module type - driver */ MRSAS_VERSION, &mrsas_ops, /* driver ops */ }; --- 279,303 ---- mrsas_getinfo, /* getinfo */ nulldev, /* identify */ nulldev, /* probe */ mrsas_attach, /* attach */ mrsas_detach, /* detach */ ! #ifdef __sparc mrsas_reset, /* reset */ ! #else /* __sparc */ ! nodev, ! #endif /* __sparc */ &mrsas_cb_ops, /* char/block ops */ NULL, /* bus ops */ NULL, /* power */ ! #ifdef __sparc ! ddi_quiesce_not_needed ! #else /* __sparc */ mrsas_quiesce /* quiesce */ ! #endif /* __sparc */ }; static struct modldrv modldrv = { &mod_driverops, /* module type - driver */ MRSAS_VERSION, &mrsas_ops, /* driver ops */ };
*** 179,189 **** DDI_STRUCTURE_LE_ACC, DDI_STRICTORDER_ACC, DDI_DEFAULT_ACC }; ! unsigned int enable_fp = 1; /* * ************************************************************************** * --- 313,323 ---- DDI_STRUCTURE_LE_ACC, DDI_STRICTORDER_ACC, DDI_DEFAULT_ACC }; ! /* Use the LSI Fast Path for the 2208 (tbolt) commands. */ unsigned int enable_fp = 1; /* * ************************************************************************** *
*** 263,275 **** { int ret; con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); ! if ((ret = mod_remove(&modlinkage)) != DDI_SUCCESS) ! { ! con_log(CL_ANN1, (CE_WARN, "_fini: mod_remove() failed, error 0x%X", ret)); return (ret); } scsi_hba_fini(&modlinkage); con_log(CL_DLEVEL1, (CE_NOTE, "_fini: scsi_hba_fini() done.")); --- 397,409 ---- { int ret; con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); ! if ((ret = mod_remove(&modlinkage)) != DDI_SUCCESS) { ! con_log(CL_ANN1, ! (CE_WARN, "_fini: mod_remove() failed, error 0x%X", ret)); return (ret); } scsi_hba_fini(&modlinkage); con_log(CL_DLEVEL1, (CE_NOTE, "_fini: scsi_hba_fini() done."));
*** 309,322 **** * - create minor device nodes for the device instance (for MegaRAID, * controller instance) * - report that the device instance (for MegaRAID, controller instance) has * attached */ - #if __SunOS_5_11 - #define DDI_PM_RESUME DDI_PM_RESUME_OBSOLETE - #define DDI_PM_SUSPEND DDI_PM_SUSPEND_OBSOLETE - #endif // __SunOS_5_11 static int mrsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) { int instance_no; int nregs; --- 443,452 ----
*** 352,387 **** return (DDI_FAILURE); } switch (cmd) { case DDI_ATTACH: - /* allocate the soft state for the instance */ if (ddi_soft_state_zalloc(mrsas_state, instance_no) != DDI_SUCCESS) { cmn_err(CE_WARN, "mr_sas%d: Failed to allocate soft state", instance_no); - return (DDI_FAILURE); } instance = (struct mrsas_instance *)ddi_get_soft_state (mrsas_state, instance_no); if (instance == NULL) { cmn_err(CE_WARN, "mr_sas%d: Bad soft state", instance_no); - ddi_soft_state_free(mrsas_state, instance_no); - return (DDI_FAILURE); } - bzero((caddr_t)instance, - sizeof (struct mrsas_instance)); - instance->unroll.softs = 1; /* Setup the PCI configuration space handles */ if (pci_config_setup(dip, &instance->pci_handle) != DDI_SUCCESS) { --- 482,510 ----
*** 390,409 **** instance_no); ddi_soft_state_free(mrsas_state, instance_no); return (DDI_FAILURE); } - if (instance->pci_handle == NULL) { - cmn_err(CE_WARN, - "mr_sas%d: pci config setup failed ", - instance_no); - ddi_soft_state_free(mrsas_state, instance_no); - return (DDI_FAILURE); - } - - if (ddi_dev_nregs(dip, &nregs) != DDI_SUCCESS) { cmn_err(CE_WARN, "mr_sas: failed to get registers."); pci_config_teardown(&instance->pci_handle); --- 513,523 ----
*** 448,483 **** con_log(CL_DLEVEL1, (CE_CONT, "mr_sas%d: " "bus-mastering already set", instance_no)); } /* initialize function pointers */ ! switch(device_id) { case PCI_DEVICE_ID_LSI_TBOLT: case PCI_DEVICE_ID_LSI_INVADER: con_log(CL_ANN, (CE_NOTE, "mr_sas: 2208 T.B. device detected")); ! instance->func_ptr = &mrsas_function_template_fusion; instance->tbolt = 1; break; case PCI_DEVICE_ID_LSI_2108VDE: case PCI_DEVICE_ID_LSI_2108V: con_log(CL_ANN, (CE_NOTE, "mr_sas: 2108 Liberator device detected")); ! instance->func_ptr = &mrsas_function_template_ppc; break; default: cmn_err(CE_WARN, "mr_sas: Invalid device detected"); pci_config_teardown(&instance->pci_handle); ddi_soft_state_free(mrsas_state, instance_no); return (DDI_FAILURE); - } instance->baseaddress = pci_config_get32( instance->pci_handle, PCI_CONF_BASE0); instance->baseaddress &= 0x0fffc; --- 562,598 ---- con_log(CL_DLEVEL1, (CE_CONT, "mr_sas%d: " "bus-mastering already set", instance_no)); } /* initialize function pointers */ ! switch (device_id) { case PCI_DEVICE_ID_LSI_TBOLT: case PCI_DEVICE_ID_LSI_INVADER: con_log(CL_ANN, (CE_NOTE, "mr_sas: 2208 T.B. device detected")); ! instance->func_ptr = ! &mrsas_function_template_fusion; instance->tbolt = 1; break; case PCI_DEVICE_ID_LSI_2108VDE: case PCI_DEVICE_ID_LSI_2108V: con_log(CL_ANN, (CE_NOTE, "mr_sas: 2108 Liberator device detected")); ! instance->func_ptr = ! &mrsas_function_template_ppc; break; default: cmn_err(CE_WARN, "mr_sas: Invalid device detected"); pci_config_teardown(&instance->pci_handle); ddi_soft_state_free(mrsas_state, instance_no); return (DDI_FAILURE); } instance->baseaddress = pci_config_get32( instance->pci_handle, PCI_CONF_BASE0); instance->baseaddress &= 0x0fffc;
*** 487,522 **** instance->device_id = device_id; instance->subsysvid = subsysvid; instance->subsysid = subsysid; instance->instance = instance_no; /* Setup register map */ if ((ddi_dev_regsize(instance->dip, REGISTER_SET_IO_2108, &reglength) != DDI_SUCCESS) || reglength < MINIMUM_MFI_MEM_SZ) { goto fail_attach; } if (reglength > DEFAULT_MFI_MEM_SZ) { reglength = DEFAULT_MFI_MEM_SZ; con_log(CL_DLEVEL1, (CE_NOTE, ! "mr_sas: register length to map is " ! "0x%lx bytes", reglength)); } if (ddi_regs_map_setup(instance->dip, REGISTER_SET_IO_2108, &instance->regmap, 0, reglength, &endian_attr, &instance->regmap_handle) != DDI_SUCCESS) { cmn_err(CE_WARN, "mr_sas: couldn't map control registers"); goto fail_attach; } - if (instance->regmap_handle == NULL) { - cmn_err(CE_WARN, - "mr_sas: couldn't map control registers"); - goto fail_attach; - } instance->unroll.regs = 1; /* * Disable Interrupt Now. --- 602,640 ---- instance->device_id = device_id; instance->subsysvid = subsysvid; instance->subsysid = subsysid; instance->instance = instance_no; + /* Initialize FMA */ + instance->fm_capabilities = ddi_prop_get_int( + DDI_DEV_T_ANY, instance->dip, DDI_PROP_DONTPASS, + "fm-capable", DDI_FM_EREPORT_CAPABLE | + DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE + | DDI_FM_ERRCB_CAPABLE); + mrsas_fm_init(instance); + /* Setup register map */ if ((ddi_dev_regsize(instance->dip, REGISTER_SET_IO_2108, &reglength) != DDI_SUCCESS) || reglength < MINIMUM_MFI_MEM_SZ) { goto fail_attach; } if (reglength > DEFAULT_MFI_MEM_SZ) { reglength = DEFAULT_MFI_MEM_SZ; con_log(CL_DLEVEL1, (CE_NOTE, ! "mr_sas: register length to map is 0x%lx bytes", ! reglength)); } if (ddi_regs_map_setup(instance->dip, REGISTER_SET_IO_2108, &instance->regmap, 0, reglength, &endian_attr, &instance->regmap_handle) != DDI_SUCCESS) { cmn_err(CE_WARN, "mr_sas: couldn't map control registers"); goto fail_attach; } instance->unroll.regs = 1; /* * Disable Interrupt Now.
*** 527,538 **** if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0, "mrsas-enable-msi", &data) == DDI_SUCCESS) { if (strncmp(data, "no", 3) == 0) { msi_enable = 0; con_log(CL_ANN1, (CE_WARN, ! "msi_enable = %d disabled", ! msi_enable)); } ddi_prop_free(data); } con_log(CL_DLEVEL1, (CE_NOTE, "msi_enable = %d", msi_enable)); --- 645,655 ---- if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0, "mrsas-enable-msi", &data) == DDI_SUCCESS) { if (strncmp(data, "no", 3) == 0) { msi_enable = 0; con_log(CL_ANN1, (CE_WARN, ! "msi_enable = %d disabled", msi_enable)); } ddi_prop_free(data); } con_log(CL_DLEVEL1, (CE_NOTE, "msi_enable = %d", msi_enable));
*** 547,557 **** } ddi_prop_free(data); } ! cmn_err(CE_NOTE, "enable_fp = %d\n", enable_fp); /* Check for all supported interrupt types */ if (ddi_intr_get_supported_types( dip, &intr_types) != DDI_SUCCESS) { cmn_err(CE_WARN, --- 664,674 ---- } ddi_prop_free(data); } ! con_log(CL_DLEVEL1, (CE_NOTE, "enable_fp = %d\n", enable_fp)); /* Check for all supported interrupt types */ if (ddi_intr_get_supported_types( dip, &intr_types) != DDI_SUCCESS) { cmn_err(CE_WARN,
*** 558,592 **** "ddi_intr_get_supported_types() failed"); goto fail_attach; } con_log(CL_DLEVEL1, (CE_NOTE, ! "ddi_intr_get_supported_types() ret: 0x%x", ! intr_types)); /* Initialize and Setup Interrupt handler */ if (msi_enable && (intr_types & DDI_INTR_TYPE_MSIX)) { ! if (mrsas_add_intrs(instance, ! DDI_INTR_TYPE_MSIX) != DDI_SUCCESS) { cmn_err(CE_WARN, "MSIX interrupt query failed"); goto fail_attach; } instance->intr_type = DDI_INTR_TYPE_MSIX; ! } else if (msi_enable && (intr_types & ! DDI_INTR_TYPE_MSI)) { ! if (mrsas_add_intrs(instance, ! DDI_INTR_TYPE_MSI) != DDI_SUCCESS) { cmn_err(CE_WARN, "MSI interrupt query failed"); goto fail_attach; } instance->intr_type = DDI_INTR_TYPE_MSI; } else if (intr_types & DDI_INTR_TYPE_FIXED) { msi_enable = 0; ! if (mrsas_add_intrs(instance, ! DDI_INTR_TYPE_FIXED) != DDI_SUCCESS) { cmn_err(CE_WARN, "FIXED interrupt query failed"); goto fail_attach; } instance->intr_type = DDI_INTR_TYPE_FIXED; --- 675,707 ---- "ddi_intr_get_supported_types() failed"); goto fail_attach; } con_log(CL_DLEVEL1, (CE_NOTE, ! "ddi_intr_get_supported_types() ret: 0x%x", intr_types)); /* Initialize and Setup Interrupt handler */ if (msi_enable && (intr_types & DDI_INTR_TYPE_MSIX)) { ! if (mrsas_add_intrs(instance, DDI_INTR_TYPE_MSIX) != ! DDI_SUCCESS) { cmn_err(CE_WARN, "MSIX interrupt query failed"); goto fail_attach; } instance->intr_type = DDI_INTR_TYPE_MSIX; ! } else if (msi_enable && (intr_types & DDI_INTR_TYPE_MSI)) { ! if (mrsas_add_intrs(instance, DDI_INTR_TYPE_MSI) != ! DDI_SUCCESS) { cmn_err(CE_WARN, "MSI interrupt query failed"); goto fail_attach; } instance->intr_type = DDI_INTR_TYPE_MSI; } else if (intr_types & DDI_INTR_TYPE_FIXED) { msi_enable = 0; ! if (mrsas_add_intrs(instance, DDI_INTR_TYPE_FIXED) != ! DDI_SUCCESS) { cmn_err(CE_WARN, "FIXED interrupt query failed"); goto fail_attach; } instance->intr_type = DDI_INTR_TYPE_FIXED;
*** 597,607 **** --- 712,733 ---- goto fail_attach; } instance->unroll.intr = 1; + if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0, + "mrsas-enable-ctio", &data) == DDI_SUCCESS) { + if (strncmp(data, "no", 3) == 0) { + ctio_enable = 0; + con_log(CL_ANN1, (CE_WARN, + "ctio_enable = %d disabled", ctio_enable)); + } + ddi_prop_free(data); + } + con_log(CL_DLEVEL1, (CE_WARN, "ctio_enable = %d", ctio_enable)); + /* setup the mfi based low level driver */ if (mrsas_init_adapter(instance) != DDI_SUCCESS) { cmn_err(CE_WARN, "mr_sas: " "could not initialize the low level driver");
*** 608,656 **** goto fail_attach; } /* Initialize all Mutex */ INIT_LIST_HEAD(&instance->completed_pool_list); ! mutex_init(&instance->completed_pool_mtx, ! "completed_pool_mtx", MUTEX_DRIVER, ! DDI_INTR_PRI(instance->intr_pri)); ! mutex_init(&instance->sync_map_mtx, ! "sync_map_mtx", MUTEX_DRIVER, ! DDI_INTR_PRI(instance->intr_pri)); ! mutex_init(&instance->app_cmd_pool_mtx, ! "app_cmd_pool_mtx", MUTEX_DRIVER, ! DDI_INTR_PRI(instance->intr_pri)); ! mutex_init(&instance->config_dev_mtx, "config_dev_mtx", MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri)); ! mutex_init(&instance->cmd_pend_mtx, "cmd_pend_mtx", MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri)); ! mutex_init(&instance->ocr_flags_mtx, "ocr_flags_mtx", MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri)); ! mutex_init(&instance->int_cmd_mtx, "int_cmd_mtx", MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri)); cv_init(&instance->int_cmd_cv, NULL, CV_DRIVER, NULL); ! mutex_init(&instance->cmd_pool_mtx, "cmd_pool_mtx", MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri)); ! mutex_init(&instance->reg_write_mtx,"reg_write_mtx", ! MUTEX_DRIVER,DDI_INTR_PRI(instance->intr_pri)); if (instance->tbolt) { ! mutex_init(&instance->cmd_app_pool_mtx, ! "cmd_app_pool_mtx", MUTEX_DRIVER, ! DDI_INTR_PRI(instance->intr_pri)); ! mutex_init(&instance->chip_mtx, ! "chip_mtx", MUTEX_DRIVER, ! DDI_INTR_PRI(instance->intr_pri)); } instance->unroll.mutexs = 1; --- 734,777 ---- goto fail_attach; } /* Initialize all Mutex */ INIT_LIST_HEAD(&instance->completed_pool_list); ! mutex_init(&instance->completed_pool_mtx, NULL, ! MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri)); ! mutex_init(&instance->sync_map_mtx, NULL, ! MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri)); ! mutex_init(&instance->app_cmd_pool_mtx, NULL, ! MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri)); ! mutex_init(&instance->config_dev_mtx, NULL, MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri)); ! mutex_init(&instance->cmd_pend_mtx, NULL, MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri)); ! mutex_init(&instance->ocr_flags_mtx, NULL, MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri)); ! mutex_init(&instance->int_cmd_mtx, NULL, MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri)); cv_init(&instance->int_cmd_cv, NULL, CV_DRIVER, NULL); ! mutex_init(&instance->cmd_pool_mtx, NULL, MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri)); ! mutex_init(&instance->reg_write_mtx, NULL, ! MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri)); if (instance->tbolt) { ! mutex_init(&instance->cmd_app_pool_mtx, NULL, ! MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri)); ! mutex_init(&instance->chip_mtx, NULL, ! MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri)); } instance->unroll.mutexs = 1;
*** 660,676 **** instance->isr_level = instance->intr_pri; if (!(instance->tbolt)) { if (instance->isr_level == HIGH_LEVEL_INTR) { if (ddi_add_softintr(dip, DDI_SOFTINT_HIGH, ! &instance->soft_intr_id, ! NULL, NULL, mrsas_softintr, ! (caddr_t)instance) != DDI_SUCCESS) { cmn_err(CE_WARN, ! "Software ISR " ! "did not register"); goto fail_attach; } instance->unroll.soft_isr = 1; --- 781,795 ---- instance->isr_level = instance->intr_pri; if (!(instance->tbolt)) { if (instance->isr_level == HIGH_LEVEL_INTR) { if (ddi_add_softintr(dip, DDI_SOFTINT_HIGH, ! &instance->soft_intr_id, NULL, NULL, ! mrsas_softintr, (caddr_t)instance) != DDI_SUCCESS) { cmn_err(CE_WARN, ! "Software ISR did not register"); goto fail_attach; } instance->unroll.soft_isr = 1;
*** 731,744 **** "scsi_hba_attach failed"); goto fail_attach; } instance->unroll.tranSetup = 1; ! con_log(CL_ANN1, (CE_CONT, ! "scsi_hba_attach_setup() done.")); - /* create devctl node for cfgadm command */ if (ddi_create_minor_node(dip, "devctl", S_IFCHR, INST2DEVCTL(instance_no), DDI_NT_SCSI_NEXUS, 0) == DDI_FAILURE) { cmn_err(CE_WARN, --- 850,862 ---- "scsi_hba_attach failed"); goto fail_attach; } instance->unroll.tranSetup = 1; ! con_log(CL_ANN1, ! (CE_CONT, "scsi_hba_attach_setup() done.")); /* create devctl node for cfgadm command */ if (ddi_create_minor_node(dip, "devctl", S_IFCHR, INST2DEVCTL(instance_no), DDI_NT_SCSI_NEXUS, 0) == DDI_FAILURE) { cmn_err(CE_WARN,
*** 749,760 **** instance->unroll.devctl = 1; /* create scsi node for cfgadm command */ if (ddi_create_minor_node(dip, "scsi", S_IFCHR, ! INST2SCSI(instance_no), ! DDI_NT_SCSI_ATTACHMENT_POINT, 0) == DDI_FAILURE) { cmn_err(CE_WARN, "mr_sas: failed to create scsi node."); goto fail_attach; --- 867,877 ---- instance->unroll.devctl = 1; /* create scsi node for cfgadm command */ if (ddi_create_minor_node(dip, "scsi", S_IFCHR, ! INST2SCSI(instance_no), DDI_NT_SCSI_ATTACHMENT_POINT, 0) == DDI_FAILURE) { cmn_err(CE_WARN, "mr_sas: failed to create scsi node."); goto fail_attach;
*** 768,779 **** /* * Create a node for applications * for issuing ioctl to the driver. */ if (ddi_create_minor_node(dip, instance->iocnode, ! S_IFCHR, INST2LSIRDCTL(instance_no), ! DDI_PSEUDO, 0) == DDI_FAILURE) { cmn_err(CE_WARN, "mr_sas: failed to create ioctl node."); goto fail_attach; } --- 885,896 ---- /* * Create a node for applications * for issuing ioctl to the driver. */ if (ddi_create_minor_node(dip, instance->iocnode, ! S_IFCHR, INST2LSIRDCTL(instance_no), DDI_PSEUDO, 0) == ! DDI_FAILURE) { cmn_err(CE_WARN, "mr_sas: failed to create ioctl node."); goto fail_attach; }
*** 780,799 **** instance->unroll.ioctl = 1; /* Create a taskq to handle dr events */ if ((instance->taskq = ddi_taskq_create(dip, ! "mrsas_dr_taskq", 1, ! TASKQ_DEFAULTPRI, 0)) == NULL) { cmn_err(CE_WARN, "mr_sas: failed to create taskq "); instance->taskq = NULL; goto fail_attach; } instance->unroll.taskq = 1; ! con_log(CL_ANN1, (CE_CONT, ! "ddi_taskq_create() done.")); /* enable interrupt */ instance->func_ptr->enable_intr(instance); /* initiate AEN */ --- 897,914 ---- instance->unroll.ioctl = 1; /* Create a taskq to handle dr events */ if ((instance->taskq = ddi_taskq_create(dip, ! "mrsas_dr_taskq", 1, TASKQ_DEFAULTPRI, 0)) == NULL) { cmn_err(CE_WARN, "mr_sas: failed to create taskq "); instance->taskq = NULL; goto fail_attach; } instance->unroll.taskq = 1; ! con_log(CL_ANN1, (CE_CONT, "ddi_taskq_create() done.")); /* enable interrupt */ instance->func_ptr->enable_intr(instance); /* initiate AEN */
*** 801,832 **** cmn_err(CE_WARN, "mr_sas: failed to initiate AEN."); goto fail_attach; } instance->unroll.aenPend = 1; ! con_log(CL_ANN1, (CE_CONT, ! "AEN started for instance %d.", instance_no)); /* Finally! We are on the air. */ ddi_report_dev(dip); instance->mr_ld_list = kmem_zalloc(MRDRV_MAX_LD * sizeof (struct mrsas_ld), KM_SLEEP); - if (instance->mr_ld_list == NULL) { - cmn_err(CE_WARN, - "mr_sas attach(): failed to allocate ld_list array"); - goto fail_attach; - } instance->unroll.ldlist_buff = 1; #ifdef PDSUPPORT ! if(instance->tbolt) { instance->mr_tbolt_pd_max = MRSAS_TBOLT_PD_TGT_MAX; instance->mr_tbolt_pd_list = ! kmem_zalloc(MRSAS_TBOLT_GET_PD_MAX(instance) ! * sizeof (struct mrsas_tbolt_pd), KM_SLEEP); ASSERT(instance->mr_tbolt_pd_list); for (i = 0; i < instance->mr_tbolt_pd_max; i++) { instance->mr_tbolt_pd_list[i].lun_type = MRSAS_TBOLT_PD_LUN; instance->mr_tbolt_pd_list[i].dev_id = --- 916,952 ---- cmn_err(CE_WARN, "mr_sas: failed to initiate AEN."); goto fail_attach; } instance->unroll.aenPend = 1; ! con_log(CL_ANN1, ! (CE_CONT, "AEN started for instance %d.", instance_no)); /* Finally! We are on the air. */ ddi_report_dev(dip); + /* FMA handle checking. */ + if (mrsas_check_acc_handle(instance->regmap_handle) != + DDI_SUCCESS) { + goto fail_attach; + } + if (mrsas_check_acc_handle(instance->pci_handle) != + DDI_SUCCESS) { + goto fail_attach; + } + instance->mr_ld_list = kmem_zalloc(MRDRV_MAX_LD * sizeof (struct mrsas_ld), KM_SLEEP); instance->unroll.ldlist_buff = 1; #ifdef PDSUPPORT ! if (instance->tbolt) { instance->mr_tbolt_pd_max = MRSAS_TBOLT_PD_TGT_MAX; instance->mr_tbolt_pd_list = ! kmem_zalloc(MRSAS_TBOLT_GET_PD_MAX(instance) * ! sizeof (struct mrsas_tbolt_pd), KM_SLEEP); ASSERT(instance->mr_tbolt_pd_list); for (i = 0; i < instance->mr_tbolt_pd_max; i++) { instance->mr_tbolt_pd_list[i].lun_type = MRSAS_TBOLT_PD_LUN; instance->mr_tbolt_pd_list[i].dev_id =
*** 836,873 **** instance->unroll.pdlist_buff = 1; } #endif break; case DDI_PM_RESUME: ! con_log(CL_ANN, (CE_NOTE, ! "mr_sas: DDI_PM_RESUME")); break; case DDI_RESUME: ! con_log(CL_ANN, (CE_NOTE, ! "mr_sas: DDI_RESUME")); break; default: ! con_log(CL_ANN, (CE_WARN, ! "mr_sas: invalid attach cmd=%x", cmd)); return (DDI_FAILURE); } ! cmn_err(CE_NOTE, "mrsas_attach() return SUCCESS instance_num %d", instance_no); return (DDI_SUCCESS); fail_attach: mrsas_undo_resources(dip, instance); pci_config_teardown(&instance->pci_handle); ddi_soft_state_free(mrsas_state, instance_no); ! con_log(CL_ANN, (CE_WARN, ! "mr_sas: return failure from mrsas_attach")); ! cmn_err(CE_WARN, "mrsas_attach() return FAILURE instance_num %d", instance_no); return (DDI_FAILURE); } /* --- 956,998 ---- instance->unroll.pdlist_buff = 1; } #endif break; case DDI_PM_RESUME: ! con_log(CL_ANN, (CE_NOTE, "mr_sas: DDI_PM_RESUME")); break; case DDI_RESUME: ! con_log(CL_ANN, (CE_NOTE, "mr_sas: DDI_RESUME")); break; default: ! con_log(CL_ANN, ! (CE_WARN, "mr_sas: invalid attach cmd=%x", cmd)); return (DDI_FAILURE); } ! con_log(CL_DLEVEL1, ! (CE_NOTE, "mrsas_attach() return SUCCESS instance_num %d", ! instance_no)); return (DDI_SUCCESS); fail_attach: mrsas_undo_resources(dip, instance); + mrsas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE); + ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST); + + mrsas_fm_fini(instance); + pci_config_teardown(&instance->pci_handle); ddi_soft_state_free(mrsas_state, instance_no); ! con_log(CL_ANN, (CE_WARN, "mr_sas: return failure from mrsas_attach")); ! cmn_err(CE_WARN, "mrsas_attach() return FAILURE instance_num %d", ! instance_no); return (DDI_FAILURE); } /*
*** 979,1002 **** mutex_enter(&instance->config_dev_mtx); instance->unroll.timer = 0; } mutex_exit(&instance->config_dev_mtx); ! if(instance->unroll.tranSetup == 1) { if (scsi_hba_detach(dip) != DDI_SUCCESS) { cmn_err(CE_WARN, ! "mr_sas2%d: failed to detach", instance_no); return (DDI_FAILURE); } instance->unroll.tranSetup = 0; ! con_log(CL_ANN1, (CE_CONT, "scsi_hba_dettach() done.")); } flush_cache(instance); mrsas_undo_resources(dip, instance); pci_config_teardown(&instance->pci_handle); ddi_soft_state_free(mrsas_state, instance_no); break; case DDI_PM_SUSPEND: --- 1104,1131 ---- mutex_enter(&instance->config_dev_mtx); instance->unroll.timer = 0; } mutex_exit(&instance->config_dev_mtx); ! if (instance->unroll.tranSetup == 1) { if (scsi_hba_detach(dip) != DDI_SUCCESS) { cmn_err(CE_WARN, ! "mr_sas2%d: failed to detach", ! instance_no); return (DDI_FAILURE); } instance->unroll.tranSetup = 0; ! con_log(CL_ANN1, ! (CE_CONT, "scsi_hba_dettach() done.")); } flush_cache(instance); mrsas_undo_resources(dip, instance); + mrsas_fm_fini(instance); + pci_config_teardown(&instance->pci_handle); ddi_soft_state_free(mrsas_state, instance_no); break; case DDI_PM_SUSPEND:
*** 1017,1092 **** return (DDI_SUCCESS); } ! static int ! mrsas_undo_resources (dev_info_t *dip, struct mrsas_instance *instance) { int instance_no; con_log(CL_ANN, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); instance_no = ddi_get_instance(dip); ! if(instance->unroll.ioctl == 1) { ddi_remove_minor_node(dip, instance->iocnode); instance->unroll.ioctl = 0; } ! if(instance->unroll.scsictl == 1) { ddi_remove_minor_node(dip, "scsi"); instance->unroll.scsictl = 0; } ! if(instance->unroll.devctl == 1) { ddi_remove_minor_node(dip, "devctl"); instance->unroll.devctl = 0; } ! if(instance->unroll.tranSetup == 1) { if (scsi_hba_detach(dip) != DDI_SUCCESS) { cmn_err(CE_WARN, "mr_sas2%d: failed to detach", instance_no); ! return (DDI_FAILURE); } instance->unroll.tranSetup = 0; con_log(CL_ANN1, (CE_CONT, "scsi_hba_dettach() done.")); } ! if(instance->unroll.tran == 1) { scsi_hba_tran_free(instance->tran); instance->unroll.tran = 0; con_log(CL_ANN1, (CE_CONT, "scsi_hba_tran_free() done.")); } ! if(instance->unroll.syncCmd == 1) { ! if(instance->tbolt) { ! if (abort_syncmap_cmd(instance, instance->map_update_cmd)) cmn_err(CE_WARN, "mrsas_detach: " "failed to abort previous syncmap command"); instance->unroll.syncCmd = 0; con_log(CL_ANN1, (CE_CONT, "sync cmd aborted, done.")); } } ! if(instance->unroll.aenPend == 1) { if (abort_aen_cmd(instance, instance->aen_cmd)) cmn_err(CE_WARN, "mrsas_detach: " "failed to abort prevous AEN command"); instance->unroll.aenPend = 0; con_log(CL_ANN1, (CE_CONT, "aen cmd aborted, done.")); ! /*This means the controller is fully initialzed and running */ ! // shutdown_controller();Shutdown should be a last command to controller. } ! if(instance->unroll.timer == 1) { if (instance->timeout_id != (timeout_id_t)-1) { (void) untimeout(instance->timeout_id); instance->timeout_id = (timeout_id_t)-1; instance->unroll.timer = 0; --- 1146,1224 ---- return (DDI_SUCCESS); } ! static void ! mrsas_undo_resources(dev_info_t *dip, struct mrsas_instance *instance) { int instance_no; con_log(CL_ANN, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); instance_no = ddi_get_instance(dip); ! if (instance->unroll.ioctl == 1) { ddi_remove_minor_node(dip, instance->iocnode); instance->unroll.ioctl = 0; } ! if (instance->unroll.scsictl == 1) { ddi_remove_minor_node(dip, "scsi"); instance->unroll.scsictl = 0; } ! if (instance->unroll.devctl == 1) { ddi_remove_minor_node(dip, "devctl"); instance->unroll.devctl = 0; } ! if (instance->unroll.tranSetup == 1) { if (scsi_hba_detach(dip) != DDI_SUCCESS) { cmn_err(CE_WARN, "mr_sas2%d: failed to detach", instance_no); ! return; /* DDI_FAILURE */ } instance->unroll.tranSetup = 0; con_log(CL_ANN1, (CE_CONT, "scsi_hba_dettach() done.")); } ! if (instance->unroll.tran == 1) { scsi_hba_tran_free(instance->tran); instance->unroll.tran = 0; con_log(CL_ANN1, (CE_CONT, "scsi_hba_tran_free() done.")); } ! if (instance->unroll.syncCmd == 1) { ! if (instance->tbolt) { ! if (abort_syncmap_cmd(instance, ! instance->map_update_cmd)) { cmn_err(CE_WARN, "mrsas_detach: " "failed to abort previous syncmap command"); + } instance->unroll.syncCmd = 0; con_log(CL_ANN1, (CE_CONT, "sync cmd aborted, done.")); } } ! if (instance->unroll.aenPend == 1) { if (abort_aen_cmd(instance, instance->aen_cmd)) cmn_err(CE_WARN, "mrsas_detach: " "failed to abort prevous AEN command"); instance->unroll.aenPend = 0; con_log(CL_ANN1, (CE_CONT, "aen cmd aborted, done.")); ! /* This means the controller is fully initialized and running */ ! /* Shutdown should be a last command to controller. */ ! /* shutdown_controller(); */ } ! if (instance->unroll.timer == 1) { if (instance->timeout_id != (timeout_id_t)-1) { (void) untimeout(instance->timeout_id); instance->timeout_id = (timeout_id_t)-1; instance->unroll.timer = 0;
*** 1094,1104 **** } instance->func_ptr->disable_intr(instance); ! if(instance->unroll.mutexs == 1) { mutex_destroy(&instance->cmd_pool_mtx); mutex_destroy(&instance->app_cmd_pool_mtx); mutex_destroy(&instance->cmd_pend_mtx); mutex_destroy(&instance->completed_pool_mtx); mutex_destroy(&instance->sync_map_mtx); --- 1226,1236 ---- } instance->func_ptr->disable_intr(instance); ! if (instance->unroll.mutexs == 1) { mutex_destroy(&instance->cmd_pool_mtx); mutex_destroy(&instance->app_cmd_pool_mtx); mutex_destroy(&instance->cmd_pend_mtx); mutex_destroy(&instance->completed_pool_mtx); mutex_destroy(&instance->sync_map_mtx);
*** 1121,1188 **** if (instance->unroll.soft_isr == 1) { ddi_remove_softintr(instance->soft_intr_id); instance->unroll.soft_isr = 0; } ! if(instance->unroll.intr == 1) { mrsas_rem_intrs(instance); instance->unroll.intr = 0; } ! if(instance->unroll.taskq == 1) { if (instance->taskq) { ddi_taskq_destroy(instance->taskq); instance->unroll.taskq = 0; } } ! /*free dma memory allocated for ! cmds/frames/queues/driver version etc */ ! if(instance->unroll.verBuff == 1) { ! mrsas_free_dma_obj(instance, instance->drv_ver_dma_obj); instance->unroll.verBuff = 0; } ! if(instance->unroll.pdlist_buff == 1) { ! if (instance->mr_tbolt_pd_list != NULL) kmem_free(instance->mr_tbolt_pd_list, ! MRSAS_TBOLT_GET_PD_MAX(instance) * sizeof (struct mrsas_tbolt_pd)); instance->mr_tbolt_pd_list = NULL; instance->unroll.pdlist_buff = 0; } ! if(instance->unroll.ldlist_buff == 1) { ! if (instance->mr_ld_list != NULL) kmem_free(instance->mr_ld_list, MRDRV_MAX_LD * sizeof (struct mrsas_ld)); instance->mr_ld_list = NULL; instance->unroll.ldlist_buff = 0; } if (instance->tbolt) { ! if(instance->unroll.alloc_space_mpi2 == 1) { free_space_for_mpi2(instance); instance->unroll.alloc_space_mpi2 = 0; } } else { ! if(instance->unroll.alloc_space_mfi == 1) { free_space_for_mfi(instance); instance->unroll.alloc_space_mfi = 0; } } ! if(instance->unroll.regs == 1) { ddi_regs_map_free(&instance->regmap_handle); instance->unroll.regs = 0; con_log(CL_ANN1, (CE_CONT, "ddi_regs_map_free() done.")); } - - return (DDI_SUCCESS); } /* --- 1253,1323 ---- if (instance->unroll.soft_isr == 1) { ddi_remove_softintr(instance->soft_intr_id); instance->unroll.soft_isr = 0; } ! if (instance->unroll.intr == 1) { mrsas_rem_intrs(instance); instance->unroll.intr = 0; } ! if (instance->unroll.taskq == 1) { if (instance->taskq) { ddi_taskq_destroy(instance->taskq); instance->unroll.taskq = 0; } } ! /* ! * free dma memory allocated for ! * cmds/frames/queues/driver version etc ! */ ! if (instance->unroll.verBuff == 1) { ! (void) mrsas_free_dma_obj(instance, instance->drv_ver_dma_obj); instance->unroll.verBuff = 0; } ! if (instance->unroll.pdlist_buff == 1) { ! if (instance->mr_tbolt_pd_list != NULL) { kmem_free(instance->mr_tbolt_pd_list, ! MRSAS_TBOLT_GET_PD_MAX(instance) * ! sizeof (struct mrsas_tbolt_pd)); ! } instance->mr_tbolt_pd_list = NULL; instance->unroll.pdlist_buff = 0; } ! if (instance->unroll.ldlist_buff == 1) { ! if (instance->mr_ld_list != NULL) { kmem_free(instance->mr_ld_list, MRDRV_MAX_LD * sizeof (struct mrsas_ld)); + } instance->mr_ld_list = NULL; instance->unroll.ldlist_buff = 0; } if (instance->tbolt) { ! if (instance->unroll.alloc_space_mpi2 == 1) { free_space_for_mpi2(instance); instance->unroll.alloc_space_mpi2 = 0; } } else { ! if (instance->unroll.alloc_space_mfi == 1) { free_space_for_mfi(instance); instance->unroll.alloc_space_mfi = 0; } } ! if (instance->unroll.regs == 1) { ddi_regs_map_free(&instance->regmap_handle); instance->unroll.regs = 0; con_log(CL_ANN1, (CE_CONT, "ddi_regs_map_free() done.")); } } /*
*** 1298,1312 **** return (ENXIO); } ioctl = (struct mrsas_ioctl *)kmem_zalloc(sizeof (struct mrsas_ioctl), KM_SLEEP); ! if (ioctl == NULL) { ! /* Failed to allocate memory for ioctl */ ! con_log(CL_ANN, (CE_WARN, "mr_sas_ioctl: failed to allocate memory for ioctl")); ! return (ENXIO); ! } switch ((uint_t)cmd) { case MRSAS_IOCTL_FIRMWARE: if (ddi_copyin((void *)arg, ioctl, sizeof (struct mrsas_ioctl), mode)) { --- 1433,1443 ---- return (ENXIO); } ioctl = (struct mrsas_ioctl *)kmem_zalloc(sizeof (struct mrsas_ioctl), KM_SLEEP); ! ASSERT(ioctl); switch ((uint_t)cmd) { case MRSAS_IOCTL_FIRMWARE: if (ddi_copyin((void *)arg, ioctl, sizeof (struct mrsas_ioctl), mode)) {
*** 1329,1341 **** rval = 1; } break; case MRSAS_IOCTL_AEN: - con_log(CL_ANN, (CE_NOTE, - "mrsas_ioctl: IOCTL Register AEN.\n")); - if (ddi_copyin((void *) arg, &aen, sizeof (struct mrsas_aen), mode)) { con_log(CL_ANN, (CE_WARN, "mrsas_ioctl: ERROR AEN copyin")); kmem_free(ioctl, sizeof (struct mrsas_ioctl)); --- 1460,1469 ----
*** 1369,1378 **** --- 1497,1507 ---- * * * common entry points - for block driver types * * * * ************************************************************************** * */ + #ifdef __sparc /* * reset - TBD * @dip: * @cmd: *
*** 1405,1418 **** flush_cache(instance); return (DDI_SUCCESS); } ! ! /*ARGSUSED*/ ! int mrsas_quiesce(dev_info_t *dip) { int instance_no; struct mrsas_instance *instance; --- 1534,1546 ---- flush_cache(instance); return (DDI_SUCCESS); } ! #else /* __sparc */ /*ARGSUSED*/ ! static int mrsas_quiesce(dev_info_t *dip) { int instance_no; struct mrsas_instance *instance;
*** 1455,1469 **** instance_no)); flush_cache(instance); if (wait_for_outstanding(instance)) { ! con_log(CL_ANN1, (CE_CONT, "wait_for_outstanding: return FAIL.\n")); return (DDI_FAILURE); } return (DDI_SUCCESS); } /* * ************************************************************************** * * * * entry points (SCSI HBA) * --- 1583,1599 ---- instance_no)); flush_cache(instance); if (wait_for_outstanding(instance)) { ! con_log(CL_ANN1, ! (CE_CONT, "wait_for_outstanding: return FAIL.\n")); return (DDI_FAILURE); } return (DDI_SUCCESS); } + #endif /* __sparc */ /* * ************************************************************************** * * * * entry points (SCSI HBA) *
*** 1502,1512 **** /* * If no persistent node exists, we don't allow .conf node * to be created. */ if ((child = mrsas_find_child(instance, tgt, lun)) != NULL) { ! con_log(CL_DLEVEL2, (CE_NOTE, "mrsas_tgt_init find child =" " %p t = %d l = %d", (void *)child, tgt, lun)); if (ndi_merge_node(tgt_dip, mrsas_name_node) != DDI_SUCCESS) /* Create this .conf node */ return (DDI_SUCCESS); --- 1632,1643 ---- /* * If no persistent node exists, we don't allow .conf node * to be created. */ if ((child = mrsas_find_child(instance, tgt, lun)) != NULL) { ! con_log(CL_DLEVEL2, ! (CE_NOTE, "mrsas_tgt_init find child =" " %p t = %d l = %d", (void *)child, tgt, lun)); if (ndi_merge_node(tgt_dip, mrsas_name_node) != DDI_SUCCESS) /* Create this .conf node */ return (DDI_SUCCESS);
*** 1530,1540 **** 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; --- 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;
*** 1568,1578 **** 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)); --- 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));
*** 1801,1812 **** return (TRAN_BUSY); } if ((pkt->pkt_flags & FLAG_NOINTR) == 0) { if (instance->fw_outstanding > instance->max_fw_cmds) { ! cmn_err(CE_WARN, "mr_sas:Firmware BUSY, fw_outstanding(0x%X) > max_fw_cmds(0x%X)", ! instance->fw_outstanding, instance->max_fw_cmds ); return_mfi_pkt(instance, cmd); return (TRAN_BUSY); } /* Synchronize the Cmd frame for the controller */ --- 1932,1945 ---- return (TRAN_BUSY); } if ((pkt->pkt_flags & FLAG_NOINTR) == 0) { 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 */
*** 1817,1829 **** instance->func_ptr->issue_cmd(cmd, instance); } else { struct mrsas_header *hdr = &cmd->frame->hdr; - instance->func_ptr-> issue_cmd_in_poll_mode(instance, cmd); - pkt->pkt_reason = CMD_CMPLT; pkt->pkt_statistics = 0; pkt->pkt_state |= STATE_XFERRED_DATA | STATE_GOT_STATUS; switch (ddi_get8(cmd->frame_dma_obj.acc_handle, --- 1950,1961 ---- instance->func_ptr->issue_cmd(cmd, instance); } else { struct mrsas_header *hdr = &cmd->frame->hdr; + instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd); pkt->pkt_reason = CMD_CMPLT; pkt->pkt_statistics = 0; pkt->pkt_state |= STATE_XFERRED_DATA | STATE_GOT_STATUS; switch (ddi_get8(cmd->frame_dma_obj.acc_handle,
*** 1850,1859 **** --- 1982,1994 ---- default: ((struct scsi_status *)pkt->pkt_scbp)->sts_busy = 1; } + (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); }
*** 1905,1921 **** struct mrsas_instance *instance = ADDR2MR(ap); con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); if (wait_for_outstanding(instance)) { ! con_log(CL_ANN1, (CE_CONT, "wait_for_outstanding: return FAIL.\n")); return (DDI_FAILURE); } else { return (DDI_SUCCESS); } } /* * tran_bus_reset - reset the SCSI bus * @dip: * @level: * --- 2040,2058 ---- struct mrsas_instance *instance = ADDR2MR(ap); con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); if (wait_for_outstanding(instance)) { ! con_log(CL_ANN1, ! (CE_CONT, "wait_for_outstanding: return FAIL.\n")); return (DDI_FAILURE); } else { return (DDI_SUCCESS); } } + #if 0 /* * tran_bus_reset - reset the SCSI bus * @dip: * @level: *
*** 1936,1951 **** instance_no); con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); if (wait_for_outstanding(instance)) { ! con_log(CL_ANN1, (CE_CONT, "wait_for_outstanding: return FAIL.\n")); return (DDI_FAILURE); } else { return (DDI_SUCCESS); } } /* * tran_getcap - get one of a set of SCSA-defined capabilities * @ap: * @cap: --- 2073,2090 ---- instance_no); con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); if (wait_for_outstanding(instance)) { ! con_log(CL_ANN1, ! (CE_CONT, "wait_for_outstanding: return FAIL.\n")); return (DDI_FAILURE); } else { return (DDI_SUCCESS); } } + #endif /* * tran_getcap - get one of a set of SCSA-defined capabilities * @ap: * @cap:
*** 2218,2228 **** { int need_softintr; uint32_t producer; uint32_t consumer; uint32_t context; - uint32_t status, value; int retval; struct mrsas_cmd *cmd; struct mrsas_header *hdr; struct scsi_pkt *pkt; --- 2357,2366 ----
*** 2247,2256 **** --- 2385,2404 ---- } (void) ddi_dma_sync(instance->mfi_internal_dma_obj.dma_handle, 0, 0, DDI_DMA_SYNC_FORCPU); + if (mrsas_check_dma_handle(instance->mfi_internal_dma_obj.dma_handle) + != DDI_SUCCESS) { + mrsas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE); + ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST); + con_log(CL_ANN1, (CE_WARN, + "mr_sas_isr(): FMA check, returning DDI_INTR_UNCLAIMED")); + return (DDI_INTR_CLAIMED); + } + con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); + #ifdef OCRDEBUG if (debug_consecutive_timeout_after_ocr_g == 1) { con_log(CL_ANN1, (CE_NOTE, "simulating consecutive timeout after ocr")); return (DDI_INTR_CLAIMED);
*** 2267,2276 **** --- 2415,2426 ---- con_log(CL_ANN, (CE_CONT, " producer %x consumer %x ", producer, consumer)); if (producer == consumer) { con_log(CL_ANN, (CE_WARN, "producer == consumer case")); + DTRACE_PROBE2(isr_pc_err, uint32_t, producer, + uint32_t, consumer); mutex_exit(&instance->cmd_pend_mtx); mutex_exit(&instance->completed_pool_mtx); return (DDI_INTR_CLAIMED); }
*** 2350,2360 **** { mlist_t *head = &instance->cmd_pool_list; struct mrsas_cmd *cmd = NULL; mutex_enter(&instance->cmd_pool_mtx); - ASSERT(mutex_owned(&instance->cmd_pool_mtx)); if (!mlist_empty(head)) { cmd = mlist_entry(head->next, struct mrsas_cmd, list); mlist_del_init(head->next); } --- 2500,2509 ----
*** 2374,2390 **** { mlist_t *head = &instance->app_cmd_pool_list; struct mrsas_cmd *cmd = NULL; mutex_enter(&instance->app_cmd_pool_mtx); - ASSERT(mutex_owned(&instance->app_cmd_pool_mtx)); if (!mlist_empty(head)) { cmd = mlist_entry(head->next, struct mrsas_cmd, list); mlist_del_init(head->next); } ! if (cmd != NULL){ cmd->pkt = NULL; cmd->retry_count_for_ocr = 0; cmd->drv_pkt_time = 0; } --- 2523,2538 ---- { mlist_t *head = &instance->app_cmd_pool_list; struct mrsas_cmd *cmd = NULL; mutex_enter(&instance->app_cmd_pool_mtx); if (!mlist_empty(head)) { cmd = mlist_entry(head->next, struct mrsas_cmd, list); mlist_del_init(head->next); } ! if (cmd != NULL) { cmd->pkt = NULL; cmd->retry_count_for_ocr = 0; cmd->drv_pkt_time = 0; }
*** 2397,2418 **** */ static void return_mfi_pkt(struct mrsas_instance *instance, struct mrsas_cmd *cmd) { mutex_enter(&instance->cmd_pool_mtx); ! ASSERT(mutex_owned(&instance->cmd_pool_mtx)); ! mlist_add_tail(&cmd->list, &instance->cmd_pool_list); mutex_exit(&instance->cmd_pool_mtx); } static void return_mfi_app_pkt(struct mrsas_instance *instance, struct mrsas_cmd *cmd) { mutex_enter(&instance->app_cmd_pool_mtx); - ASSERT(mutex_owned(&instance->app_cmd_pool_mtx)); mlist_add(&cmd->list, &instance->app_cmd_pool_list); mutex_exit(&instance->app_cmd_pool_mtx); } --- 2545,2564 ---- */ 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); mutex_exit(&instance->cmd_pool_mtx); } static void return_mfi_app_pkt(struct mrsas_instance *instance, struct mrsas_cmd *cmd) { mutex_enter(&instance->app_cmd_pool_mtx); mlist_add(&cmd->list, &instance->app_cmd_pool_list); mutex_exit(&instance->app_cmd_pool_mtx); }
*** 2421,2431 **** { struct scsi_pkt *pkt; struct mrsas_header *hdr; con_log(CL_DLEVEL2, (CE_NOTE, "push_pending_pkt(): Called\n")); mutex_enter(&instance->cmd_pend_mtx); - ASSERT(mutex_owned(&instance->cmd_pend_mtx)); mlist_del_init(&cmd->list); mlist_add_tail(&cmd->list, &instance->cmd_pend_list); if (cmd->sync_cmd == MRSAS_TRUE) { hdr = (struct mrsas_header *)&cmd->frame->hdr; if (hdr) { --- 2567,2576 ----
*** 2480,2490 **** unsigned int flag = 1; struct scsi_pkt *pkt; int saved_level; int cmd_count = 0; - saved_level = debug_level_g; debug_level_g = CL_ANN1; cmn_err(CE_NOTE, "mrsas_print_pending_cmds(): Called\n"); --- 2625,2634 ----
*** 2492,2527 **** mutex_enter(&instance->cmd_pend_mtx); tmp = tmp->next; if (tmp == head) { mutex_exit(&instance->cmd_pend_mtx); flag = 0; ! con_log(CL_ANN1, (CE_CONT, "mrsas_print_pending_cmds(): NO MORE CMDS PENDING....\n")); break; } else { cmd = mlist_entry(tmp, struct mrsas_cmd, list); mutex_exit(&instance->cmd_pend_mtx); if (cmd) { if (cmd->sync_cmd == MRSAS_TRUE) { ! hdr = (struct mrsas_header *)&cmd->frame->hdr; if (hdr) { con_log(CL_ANN1, (CE_CONT, ! "print: cmd %p index 0x%x drv_pkt_time 0x%x (NO-PKT) hdr %p\n", ! (void *)cmd, cmd->index, cmd->drv_pkt_time, (void *)hdr)); } } else { pkt = cmd->pkt; if (pkt) { con_log(CL_ANN1, (CE_CONT, ! "print: cmd %p index 0x%x drv_pkt_time 0x%x pkt %p \n", ! (void *)cmd, cmd->index, cmd->drv_pkt_time, (void *)pkt)); } } ! if (++cmd_count == 1) ! mrsas_print_cmd_details(instance, cmd, 0xDD); ! else ! mrsas_print_cmd_details(instance, cmd, 1); } } } con_log(CL_ANN1, (CE_CONT, "mrsas_print_pending_cmds(): Done\n")); --- 2636,2682 ---- mutex_enter(&instance->cmd_pend_mtx); tmp = tmp->next; if (tmp == head) { mutex_exit(&instance->cmd_pend_mtx); flag = 0; ! con_log(CL_ANN1, (CE_CONT, "mrsas_print_pending_cmds():" ! " NO MORE CMDS PENDING....\n")); break; } else { cmd = mlist_entry(tmp, struct mrsas_cmd, list); mutex_exit(&instance->cmd_pend_mtx); if (cmd) { if (cmd->sync_cmd == MRSAS_TRUE) { ! hdr = (struct mrsas_header *) ! &cmd->frame->hdr; if (hdr) { con_log(CL_ANN1, (CE_CONT, ! "print: cmd %p index 0x%x " ! "drv_pkt_time 0x%x (NO-PKT)" ! " hdr %p\n", (void *)cmd, ! cmd->index, ! cmd->drv_pkt_time, ! (void *)hdr)); } } else { pkt = cmd->pkt; if (pkt) { con_log(CL_ANN1, (CE_CONT, ! "print: cmd %p index 0x%x " ! "drv_pkt_time 0x%x pkt %p \n", ! (void *)cmd, cmd->index, ! cmd->drv_pkt_time, (void *)pkt)); } } ! if (++cmd_count == 1) { ! mrsas_print_cmd_details(instance, cmd, ! 0xDD); ! } else { ! mrsas_print_cmd_details(instance, cmd, ! 1); ! } } } } con_log(CL_ANN1, (CE_CONT, "mrsas_print_pending_cmds(): Done\n"));
*** 2596,2673 **** con_log(CL_ANN1, (CE_CONT, "mrsas_complete_pending_cmds(): DONE\n")); return (DDI_SUCCESS); } void ! mrsas_print_cmd_details(struct mrsas_instance *instance, ! struct mrsas_cmd *cmd, int detail ) { struct scsi_pkt *pkt = cmd->pkt; Mpi2RaidSCSIIORequest_t *scsi_io = cmd->scsi_io_request; ! MPI2_SCSI_IO_VENDOR_UNIQUE *raidContext; ! uint8_t *cdb_p; ! char str[100], *strp; ! int i, j, len; int saved_level; - if (detail == 0xDD) { saved_level = debug_level_g; debug_level_g = CL_ANN1; } if (instance->tbolt) { ! con_log(CL_ANN1, (CE_CONT, "print_cmd_details: cmd %p cmd->index 0x%x SMID 0x%x timer 0x%x sec\n", (void *)cmd, cmd->index, cmd->SMID, cmd->drv_pkt_time)); ! } ! else { ! con_log(CL_ANN1, (CE_CONT, "print_cmd_details: cmd %p cmd->index 0x%x timer 0x%x sec\n", (void *)cmd, cmd->index, cmd->drv_pkt_time)); } ! if(pkt) { con_log(CL_ANN1, (CE_CONT, "scsi_pkt CDB[0]=0x%x", pkt->pkt_cdbp[0])); ! }else { con_log(CL_ANN1, (CE_CONT, "NO-PKT")); } ! if((detail==0xDD) && instance->tbolt) { con_log(CL_ANN1, (CE_CONT, "RAID_SCSI_IO_REQUEST\n")); ! con_log(CL_ANN1, (CE_CONT, "DevHandle=0x%X Function=0x%X IoFlags=0x%X SGLFlags=0x%X DataLength=0x%X\n", ! ddi_get16(instance->mpi2_frame_pool_dma_obj.acc_handle, &scsi_io->DevHandle), ! ddi_get8(instance->mpi2_frame_pool_dma_obj.acc_handle, &scsi_io->Function), ! ddi_get16(instance->mpi2_frame_pool_dma_obj.acc_handle, &scsi_io->IoFlags), ! ddi_get16(instance->mpi2_frame_pool_dma_obj.acc_handle, &scsi_io->SGLFlags), ! ddi_get32(instance->mpi2_frame_pool_dma_obj.acc_handle, &scsi_io->DataLength) )); ! for(i=0; i < 32; i++) ! con_log(CL_ANN1, (CE_CONT, "CDB[%d]=0x%x ",i, ! ddi_get8(instance->mpi2_frame_pool_dma_obj.acc_handle, &scsi_io->CDB.CDB32[i]) )); con_log(CL_ANN1, (CE_CONT, "RAID-CONTEXT\n")); ! con_log(CL_ANN1, (CE_CONT, "status=0x%X extStatus=0x%X ldTargetId=0x%X timeoutValue=0x%X" ! "regLockFlags=0x%X RAIDFlags=0x%X regLockRowLBA=0x%lX regLockLength=0x%X spanArm=0x%X\n", ! ddi_get8(instance->mpi2_frame_pool_dma_obj.acc_handle, &scsi_io->RaidContext.status), ! ddi_get8(instance->mpi2_frame_pool_dma_obj.acc_handle, &scsi_io->RaidContext.extStatus), ! ddi_get16(instance->mpi2_frame_pool_dma_obj.acc_handle, &scsi_io->RaidContext.ldTargetId), ! ddi_get16(instance->mpi2_frame_pool_dma_obj.acc_handle, &scsi_io->RaidContext.timeoutValue), ! ddi_get8(instance->mpi2_frame_pool_dma_obj.acc_handle, &scsi_io->RaidContext.regLockFlags), ! ddi_get8(instance->mpi2_frame_pool_dma_obj.acc_handle, &scsi_io->RaidContext.RAIDFlags), ! ddi_get64(instance->mpi2_frame_pool_dma_obj.acc_handle, &scsi_io->RaidContext.regLockRowLBA), ! ddi_get32(instance->mpi2_frame_pool_dma_obj.acc_handle, &scsi_io->RaidContext.regLockLength), ! ddi_get8(instance->mpi2_frame_pool_dma_obj.acc_handle, &scsi_io->RaidContext.spanArm) )); ! ! } if (detail == 0xDD) { debug_level_g = saved_level; } - - return; } int mrsas_issue_pending_cmds(struct mrsas_instance *instance) --- 2751,2827 ---- con_log(CL_ANN1, (CE_CONT, "mrsas_complete_pending_cmds(): DONE\n")); return (DDI_SUCCESS); } void ! mrsas_print_cmd_details(struct mrsas_instance *instance, struct mrsas_cmd *cmd, ! int detail) { struct scsi_pkt *pkt = cmd->pkt; Mpi2RaidSCSIIORequest_t *scsi_io = cmd->scsi_io_request; ! int i; int saved_level; + ddi_acc_handle_t acc_handle = + instance->mpi2_frame_pool_dma_obj.acc_handle; if (detail == 0xDD) { saved_level = debug_level_g; debug_level_g = CL_ANN1; } if (instance->tbolt) { ! con_log(CL_ANN1, (CE_CONT, "print_cmd_details: cmd %p " ! "cmd->index 0x%x SMID 0x%x timer 0x%x sec\n", (void *)cmd, cmd->index, cmd->SMID, cmd->drv_pkt_time)); ! } else { ! con_log(CL_ANN1, (CE_CONT, "print_cmd_details: cmd %p " ! "cmd->index 0x%x timer 0x%x sec\n", (void *)cmd, cmd->index, cmd->drv_pkt_time)); } ! if (pkt) { con_log(CL_ANN1, (CE_CONT, "scsi_pkt CDB[0]=0x%x", pkt->pkt_cdbp[0])); ! } else { con_log(CL_ANN1, (CE_CONT, "NO-PKT")); } ! if ((detail == 0xDD) && instance->tbolt) { con_log(CL_ANN1, (CE_CONT, "RAID_SCSI_IO_REQUEST\n")); ! con_log(CL_ANN1, (CE_CONT, "DevHandle=0x%X Function=0x%X " ! "IoFlags=0x%X SGLFlags=0x%X DataLength=0x%X\n", ! ddi_get16(acc_handle, &scsi_io->DevHandle), ! ddi_get8(acc_handle, &scsi_io->Function), ! ddi_get16(acc_handle, &scsi_io->IoFlags), ! ddi_get16(acc_handle, &scsi_io->SGLFlags), ! ddi_get32(acc_handle, &scsi_io->DataLength))); ! for (i = 0; i < 32; i++) { ! con_log(CL_ANN1, (CE_CONT, "CDB[%d]=0x%x ", i, ! ddi_get8(acc_handle, &scsi_io->CDB.CDB32[i]))); ! } con_log(CL_ANN1, (CE_CONT, "RAID-CONTEXT\n")); ! con_log(CL_ANN1, (CE_CONT, "status=0x%X extStatus=0x%X " ! "ldTargetId=0x%X timeoutValue=0x%X regLockFlags=0x%X " ! "RAIDFlags=0x%X regLockRowLBA=0x%" PRIu64 ! " regLockLength=0x%X spanArm=0x%X\n", ! ddi_get8(acc_handle, &scsi_io->RaidContext.status), ! ddi_get8(acc_handle, &scsi_io->RaidContext.extStatus), ! ddi_get16(acc_handle, &scsi_io->RaidContext.ldTargetId), ! ddi_get16(acc_handle, &scsi_io->RaidContext.timeoutValue), ! ddi_get8(acc_handle, &scsi_io->RaidContext.regLockFlags), ! ddi_get8(acc_handle, &scsi_io->RaidContext.RAIDFlags), ! ddi_get64(acc_handle, &scsi_io->RaidContext.regLockRowLBA), ! ddi_get32(acc_handle, &scsi_io->RaidContext.regLockLength), ! ddi_get8(acc_handle, &scsi_io->RaidContext.spanArm))); } if (detail == 0xDD) { debug_level_g = saved_level; } } int mrsas_issue_pending_cmds(struct mrsas_instance *instance)
*** 2687,2715 **** con_log(CL_ANN1, (CE_CONT, "mrsas_issue_pending_cmds(): " "Got a cmd: cmd %p index 0x%x drv_pkt_time 0x%x ", (void *)cmd, cmd->index, cmd->drv_pkt_time)); if (cmd->drv_pkt_time < debug_timeout_g) ! cmd->drv_pkt_time = (uint16_t)debug_timeout_g; /* Reset command timeout value */ cmd->retry_count_for_ocr++; cmn_err(CE_CONT, "cmd retry count = %d\n", cmd->retry_count_for_ocr); if (cmd->retry_count_for_ocr > IO_RETRY_COUNT) { ! cmn_err(CE_WARN, ! "mrsas_issue_pending_cmds(): cmd->retry_count exceeded limit >%d\n", IO_RETRY_COUNT); mrsas_print_cmd_details(instance, cmd, 0xDD); cmn_err(CE_WARN, "mrsas_issue_pending_cmds():" "Calling KILL Adapter\n"); if (instance->tbolt) ! (void) mrsas_tbolt_kill_adapter(instance); else (void) mrsas_kill_adapter(instance); return (DDI_FAILURE); } --- 2841,2870 ---- con_log(CL_ANN1, (CE_CONT, "mrsas_issue_pending_cmds(): " "Got a cmd: cmd %p index 0x%x drv_pkt_time 0x%x ", (void *)cmd, cmd->index, cmd->drv_pkt_time)); + /* Reset command timeout value */ if (cmd->drv_pkt_time < debug_timeout_g) ! cmd->drv_pkt_time = (uint16_t)debug_timeout_g; cmd->retry_count_for_ocr++; cmn_err(CE_CONT, "cmd retry count = %d\n", cmd->retry_count_for_ocr); if (cmd->retry_count_for_ocr > IO_RETRY_COUNT) { ! cmn_err(CE_WARN, "mrsas_issue_pending_cmds(): " ! "cmd->retry_count exceeded limit >%d\n", IO_RETRY_COUNT); mrsas_print_cmd_details(instance, cmd, 0xDD); cmn_err(CE_WARN, "mrsas_issue_pending_cmds():" "Calling KILL Adapter\n"); if (instance->tbolt) ! mrsas_tbolt_kill_adapter(instance); else (void) mrsas_kill_adapter(instance); return (DDI_FAILURE); }
*** 2722,2741 **** (void *)pkt, gethrtime())); } else { cmn_err(CE_CONT, ! "mrsas_issue_pending_cmds(): " ! "NO-PKT, cmd %p index 0x%x drv_pkt_time 0x%x ", (void *)cmd, cmd->index, cmd->drv_pkt_time); } if (cmd->sync_cmd == MRSAS_TRUE) { ! cmn_err(CE_CONT, "mrsas_issue_pending_cmds(): SYNC_CMD == TRUE \n"); ! ! instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd); } else { instance->func_ptr->issue_cmd(cmd, instance); } } else { con_log(CL_ANN1, (CE_CONT, --- 2877,2897 ---- (void *)pkt, gethrtime())); } else { cmn_err(CE_CONT, ! "mrsas_issue_pending_cmds(): NO-PKT, " ! "cmd %p index 0x%x drv_pkt_time 0x%x ", (void *)cmd, cmd->index, cmd->drv_pkt_time); } if (cmd->sync_cmd == MRSAS_TRUE) { ! cmn_err(CE_CONT, "mrsas_issue_pending_cmds(): " ! "SYNC_CMD == TRUE \n"); ! instance->func_ptr->issue_cmd_in_sync_mode( ! instance, cmd); } else { instance->func_ptr->issue_cmd(cmd, instance); } } else { con_log(CL_ANN1, (CE_CONT,
*** 2971,2998 **** /* size of cmd_list array */ sz = sizeof (struct mrsas_cmd *) * max_cmd; /* First free each cmd */ for (i = 0; i < max_cmd; i++) { ! if (instance->cmd_list[i] != NULL) ! kmem_free(instance->cmd_list[i],sizeof (struct mrsas_cmd)); instance->cmd_list[i] = NULL; } /* Now, free cmd_list array */ if (instance->cmd_list != NULL) ! kmem_free(instance->cmd_list,sz); instance->cmd_list = NULL; INIT_LIST_HEAD(&instance->cmd_pool_list); INIT_LIST_HEAD(&instance->cmd_pend_list); if (instance->tbolt) { INIT_LIST_HEAD(&instance->cmd_app_pool_list); ! } ! else { INIT_LIST_HEAD(&instance->app_cmd_pool_list); } } --- 3127,3155 ---- /* size of cmd_list array */ sz = sizeof (struct mrsas_cmd *) * max_cmd; /* First free each cmd */ for (i = 0; i < max_cmd; i++) { ! if (instance->cmd_list[i] != NULL) { ! kmem_free(instance->cmd_list[i], ! sizeof (struct mrsas_cmd)); ! } instance->cmd_list[i] = NULL; } /* Now, free cmd_list array */ if (instance->cmd_list != NULL) ! kmem_free(instance->cmd_list, sz); instance->cmd_list = NULL; INIT_LIST_HEAD(&instance->cmd_pool_list); INIT_LIST_HEAD(&instance->cmd_pend_list); if (instance->tbolt) { INIT_LIST_HEAD(&instance->cmd_app_pool_list); ! } else { INIT_LIST_HEAD(&instance->app_cmd_pool_list); } }
*** 3022,3047 **** * instance->cmd_list is an array of struct mrsas_cmd pointers. * Allocate the dynamic array first and then allocate individual * commands. */ instance->cmd_list = kmem_zalloc(sz, KM_SLEEP); ! if (instance->cmd_list == NULL) { ! con_log(CL_NONE, (CE_WARN, ! "Failed to allocate memory for cmd_list")); ! return (DDI_FAILURE); ! } /* create a frame pool and assign one frame to each cmd */ for (count = 0; count < max_cmd; count++) { ! instance->cmd_list[count] = kmem_zalloc(sizeof (struct mrsas_cmd), ! KM_SLEEP); ! if (instance->cmd_list[count] == NULL) { ! con_log(CL_NONE, (CE_WARN, ! "Failed to allocate memory for mrsas_cmd")); ! goto mrsas_undo_cmds; } - } /* add all the commands to command pool */ INIT_LIST_HEAD(&instance->cmd_pool_list); INIT_LIST_HEAD(&instance->cmd_pend_list); --- 3179,3196 ---- * instance->cmd_list is an array of struct mrsas_cmd pointers. * Allocate the dynamic array first and then allocate individual * commands. */ instance->cmd_list = kmem_zalloc(sz, KM_SLEEP); ! ASSERT(instance->cmd_list); /* create a frame pool and assign one frame to each cmd */ for (count = 0; count < max_cmd; count++) { ! instance->cmd_list[count] = ! kmem_zalloc(sizeof (struct mrsas_cmd), KM_SLEEP); ! ASSERT(instance->cmd_list[count]); } /* add all the commands to command pool */ INIT_LIST_HEAD(&instance->cmd_pool_list); INIT_LIST_HEAD(&instance->cmd_pend_list);
*** 3066,3084 **** mrsas_undo_cmds: if (count > 0) { /* free each cmd */ for (i = 0; i < count; i++) { ! if (instance->cmd_list[i] != NULL) ! kmem_free(instance->cmd_list[i],sizeof (struct mrsas_cmd)); instance->cmd_list[i] = NULL; } } mrsas_undo_cmd_list: if (instance->cmd_list != NULL) ! kmem_free(instance->cmd_list,sz); instance->cmd_list = NULL; return (DDI_FAILURE); } --- 3215,3235 ---- mrsas_undo_cmds: if (count > 0) { /* free each cmd */ for (i = 0; i < count; i++) { ! if (instance->cmd_list[i] != NULL) { ! kmem_free(instance->cmd_list[i], ! sizeof (struct mrsas_cmd)); ! } instance->cmd_list[i] = NULL; } } mrsas_undo_cmd_list: if (instance->cmd_list != NULL) ! kmem_free(instance->cmd_list, sz); instance->cmd_list = NULL; return (DDI_FAILURE); }
*** 3110,3120 **** * alloc_space_for_mfi */ static int alloc_space_for_mfi(struct mrsas_instance *instance) { ! /* Allocate command pool ( memory for cmd_list & individual commands )*/ if (mrsas_alloc_cmd_pool(instance)) { cmn_err(CE_WARN, "error creating cmd pool"); return (DDI_FAILURE); } --- 3261,3271 ---- * alloc_space_for_mfi */ static int alloc_space_for_mfi(struct mrsas_instance *instance) { ! /* Allocate command pool (memory for cmd_list & individual commands) */ if (mrsas_alloc_cmd_pool(instance)) { cmn_err(CE_WARN, "error creating cmd pool"); return (DDI_FAILURE); }
*** 3154,3174 **** struct mrsas_cmd *cmd; struct mrsas_dcmd_frame *dcmd; struct mrsas_ctrl_info *ci; ! if(instance->tbolt) { cmd = get_raid_msg_mfi_pkt(instance); ! } ! else { cmd = get_mfi_pkt(instance); } if (!cmd) { ! cmn_err(CE_WARN, ! "Failed to get a cmd from free-pool in get_ctrl_info(). fw_outstanding=0x%X max_fw_cmds=0x%X", ! instance->fw_outstanding, instance->max_fw_cmds); return (DDI_FAILURE); } /* Clear the frame buffer and assign back the context id */ (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame)); --- 3305,3325 ---- struct mrsas_cmd *cmd; struct mrsas_dcmd_frame *dcmd; struct mrsas_ctrl_info *ci; ! if (instance->tbolt) { cmd = get_raid_msg_mfi_pkt(instance); ! } else { cmd = get_mfi_pkt(instance); } if (!cmd) { ! con_log(CL_ANN, (CE_WARN, ! "Failed to get a cmd for ctrl info")); ! DTRACE_PROBE2(info_mfi_err, uint16_t, instance->fw_outstanding, ! uint16_t, instance->max_fw_cmds); return (DDI_FAILURE); } /* Clear the frame buffer and assign back the context id */ (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
*** 3220,3231 **** cmd->frame_dma_obj.acc_handle, &ci->max_request_size); ctrl_info->ld_present_count = ddi_get16( cmd->frame_dma_obj.acc_handle, &ci->ld_present_count); ! ctrl_info->properties.on_off_properties = ! ddi_get32(cmd->frame_dma_obj.acc_handle, &ci->properties.on_off_properties); ddi_rep_get8(cmd->frame_dma_obj.acc_handle, (uint8_t *)(ctrl_info->product_name), (uint8_t *)(ci->product_name), 80 * sizeof (char), DDI_DEV_AUTOINCR); --- 3371,3382 ---- cmd->frame_dma_obj.acc_handle, &ci->max_request_size); ctrl_info->ld_present_count = ddi_get16( cmd->frame_dma_obj.acc_handle, &ci->ld_present_count); ! ctrl_info->properties.on_off_properties = ddi_get32( ! cmd->frame_dma_obj.acc_handle, &ci->properties.on_off_properties); ddi_rep_get8(cmd->frame_dma_obj.acc_handle, (uint8_t *)(ctrl_info->product_name), (uint8_t *)(ci->product_name), 80 * sizeof (char), DDI_DEV_AUTOINCR);
*** 3233,3246 **** } else { cmn_err(CE_WARN, "get_ctrl_info: Ctrl info failed"); ret = -1; } ! if(instance->tbolt) { ! return_raid_msg_mfi_pkt(instance, cmd); } ! else { return_mfi_pkt(instance, cmd); } return (ret); } --- 3384,3399 ---- } else { cmn_err(CE_WARN, "get_ctrl_info: Ctrl info failed"); ret = -1; } ! if (mrsas_common_check(instance, cmd) != DDI_SUCCESS) { ! ret = -1; } ! if (instance->tbolt) { ! return_raid_msg_mfi_pkt(instance, cmd); ! } else { return_mfi_pkt(instance, cmd); } return (ret); }
*** 3264,3278 **** } else { cmd = get_mfi_pkt(instance); } if (!cmd) { ! cmn_err(CE_WARN, ! "Failed to get a cmd from free-pool in abort_aen_cmd(). fw_outstanding=0x%X max_fw_cmds=0x%X", ! instance->fw_outstanding, instance->max_fw_cmds); return (DDI_FAILURE); } /* Clear the frame buffer and assign back the context id */ (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame)); ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context, cmd->index); --- 3417,3433 ---- } else { cmd = get_mfi_pkt(instance); } if (!cmd) { ! con_log(CL_ANN1, (CE_WARN, ! "abort_aen_cmd():Failed to get a cmd for abort_aen_cmd")); ! DTRACE_PROBE2(abort_mfi_err, uint16_t, instance->fw_outstanding, ! uint16_t, instance->max_fw_cmds); return (DDI_FAILURE); } + /* Clear the frame buffer and assign back the context id */ (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame)); ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context, cmd->index);
*** 3321,3331 **** return (ret); } static int ! mrsas_build_init_cmd(struct mrsas_instance *instance, struct mrsas_cmd **cmd_ptr) { struct mrsas_cmd *cmd; struct mrsas_init_frame *init_frame; struct mrsas_init_queue_info *initq_info; struct mrsas_drv_ver drv_ver_info; --- 3476,3487 ---- return (ret); } static int ! mrsas_build_init_cmd(struct mrsas_instance *instance, ! struct mrsas_cmd **cmd_ptr) { struct mrsas_cmd *cmd; struct mrsas_init_frame *init_frame; struct mrsas_init_queue_info *initq_info; struct mrsas_drv_ver drv_ver_info;
*** 3385,3399 **** cmd->frame_phys_addr + 64); ddi_put32(cmd->frame_dma_obj.acc_handle, &init_frame->queue_info_new_phys_addr_hi, 0); ! /* fill driver version information*/ fill_up_drv_ver(&drv_ver_info); /* allocate the driver version data transfer buffer */ ! instance->drv_ver_dma_obj.size = sizeof(drv_ver_info.drv_ver); instance->drv_ver_dma_obj.dma_attr = mrsas_generic_dma_attr; instance->drv_ver_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; instance->drv_ver_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; instance->drv_ver_dma_obj.dma_attr.dma_attr_sgllen = 1; instance->drv_ver_dma_obj.dma_attr.dma_attr_align = 1; --- 3541,3555 ---- cmd->frame_phys_addr + 64); ddi_put32(cmd->frame_dma_obj.acc_handle, &init_frame->queue_info_new_phys_addr_hi, 0); ! /* fill driver version information */ fill_up_drv_ver(&drv_ver_info); /* allocate the driver version data transfer buffer */ ! instance->drv_ver_dma_obj.size = sizeof (drv_ver_info.drv_ver); instance->drv_ver_dma_obj.dma_attr = mrsas_generic_dma_attr; instance->drv_ver_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; instance->drv_ver_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; instance->drv_ver_dma_obj.dma_attr.dma_attr_sgllen = 1; instance->drv_ver_dma_obj.dma_attr.dma_attr_align = 1;
*** 3402,3422 **** (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) { con_log(CL_ANN, (CE_WARN, "init_mfi : Could not allocate driver version buffer.")); return (DDI_FAILURE); } ! /* copy driver version to dma buffer*/ ! (void) memset(instance->drv_ver_dma_obj.buffer, 0,sizeof(drv_ver_info.drv_ver)); ddi_rep_put8(cmd->frame_dma_obj.acc_handle, (uint8_t *)drv_ver_info.drv_ver, (uint8_t *)instance->drv_ver_dma_obj.buffer, ! sizeof(drv_ver_info.drv_ver), DDI_DEV_AUTOINCR); ! /*copy driver version physical address to init frame*/ ! ddi_put64(cmd->frame_dma_obj.acc_handle, ! &init_frame->driverversion, instance->drv_ver_dma_obj.dma_cookie[0].dmac_address); ddi_put32(cmd->frame_dma_obj.acc_handle, &init_frame->data_xfer_len, sizeof (struct mrsas_init_queue_info)); cmd->frame_count = 1; --- 3558,3579 ---- (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) { con_log(CL_ANN, (CE_WARN, "init_mfi : Could not allocate driver version buffer.")); return (DDI_FAILURE); } ! /* copy driver version to dma buffer */ ! (void) memset(instance->drv_ver_dma_obj.buffer, 0, ! sizeof (drv_ver_info.drv_ver)); ddi_rep_put8(cmd->frame_dma_obj.acc_handle, (uint8_t *)drv_ver_info.drv_ver, (uint8_t *)instance->drv_ver_dma_obj.buffer, ! sizeof (drv_ver_info.drv_ver), DDI_DEV_AUTOINCR); ! /* copy driver version physical address to init frame */ ! ddi_put64(cmd->frame_dma_obj.acc_handle, &init_frame->driverversion, ! instance->drv_ver_dma_obj.dma_cookie[0].dmac_address); ddi_put32(cmd->frame_dma_obj.acc_handle, &init_frame->data_xfer_len, sizeof (struct mrsas_init_queue_info)); cmd->frame_count = 1;
*** 3429,3479 **** /* * mrsas_init_adapter_ppc - Initialize MFI interface adapter. */ int ! mrsas_init_adapter_ppc (struct mrsas_instance *instance) { struct mrsas_cmd *cmd; ! /* allocate memory for mfi adapter(cmd pool, individual commands, mfi frames etc */ ! if (alloc_space_for_mfi(instance) != DDI_SUCCESS){ con_log(CL_ANN, (CE_NOTE, "Error, failed to allocate memory for MFI adapter")); return (DDI_FAILURE); } /* Build INIT command */ cmd = get_mfi_pkt(instance); ! if (mrsas_build_init_cmd(instance, &cmd) != DDI_SUCCESS){ ! con_log(CL_ANN, (CE_NOTE, ! "Error, failed to build INIT command")); goto fail_undo_alloc_mfi_space; } ! //Disalbe interrupt before sending init frame ( see linux driver code) ! /* send INIT MFI frame in polled mode */ if (instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) { con_log(CL_ANN, (CE_WARN, "failed to init firmware")); goto fail_fw_init; } ! if (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; } instance->unroll.alloc_space_mfi = 1; instance->unroll.verBuff = 1; return (DDI_SUCCESS); fail_fw_init: ! 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); --- 3586,3648 ---- /* * mrsas_init_adapter_ppc - Initialize MFI interface adapter. */ int ! mrsas_init_adapter_ppc(struct mrsas_instance *instance) { struct mrsas_cmd *cmd; ! /* ! * allocate memory for mfi adapter(cmd pool, individual commands, mfi ! * frames etc ! */ ! if (alloc_space_for_mfi(instance) != DDI_SUCCESS) { con_log(CL_ANN, (CE_NOTE, "Error, failed to allocate memory for MFI adapter")); return (DDI_FAILURE); } /* Build INIT command */ cmd = get_mfi_pkt(instance); ! if (mrsas_build_init_cmd(instance, &cmd) != DDI_SUCCESS) { ! con_log(CL_ANN, ! (CE_NOTE, "Error, failed to build INIT command")); goto fail_undo_alloc_mfi_space; } ! /* ! * Disable interrupt before sending init frame ( see linux driver code) ! * send INIT MFI frame in polled mode ! */ if (instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) { con_log(CL_ANN, (CE_WARN, "failed to init firmware")); 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); 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);
*** 3483,3493 **** /* * mrsas_init_adapter - Initialize adapter. */ int ! mrsas_init_adapter (struct mrsas_instance *instance) { struct mrsas_ctrl_info ctrl_info; /* we expect the FW state to be READY */ --- 3652,3662 ---- /* * mrsas_init_adapter - Initialize adapter. */ int ! mrsas_init_adapter(struct mrsas_instance *instance) { struct mrsas_ctrl_info ctrl_info; /* we expect the FW state to be READY */
*** 3515,3526 **** /* Initialize adapter */ if (instance->func_ptr->init_adapter(instance) != DDI_SUCCESS) { ! con_log(CL_ANN, (CE_WARN, "mr_sas: " ! "could not initialize adapter")); return (DDI_FAILURE); } /* gather misc FW related information */ instance->disable_online_ctrl_reset = 0; --- 3684,3695 ---- /* Initialize adapter */ if (instance->func_ptr->init_adapter(instance) != DDI_SUCCESS) { ! con_log(CL_ANN, ! (CE_WARN, "mr_sas: could not initialize adapter")); return (DDI_FAILURE); } /* gather misc FW related information */ instance->disable_online_ctrl_reset = 0;
*** 3533,3551 **** } else { instance->max_sectors_per_req = instance->max_num_sge * PAGESIZE / 512; } ! if (ctrl_info.properties.on_off_properties & DISABLE_OCR_PROP_FLAG) { instance->disable_online_ctrl_reset = 1; - con_log(CL_ANN1, (CE_NOTE, - "Disable online control Flag is set\n")); - } - else { - con_log(CL_ANN1, (CE_NOTE, - "Disable online control Flag is not set\n")); - } return (DDI_SUCCESS); } --- 3702,3713 ---- } else { instance->max_sectors_per_req = instance->max_num_sge * PAGESIZE / 512; } ! if (ctrl_info.properties.on_off_properties & DISABLE_OCR_PROP_FLAG) instance->disable_online_ctrl_reset = 1; return (DDI_SUCCESS); }
*** 3630,3639 **** --- 3792,3806 ---- "init firmware")); return_mfi_app_pkt(instance, cmd); return (DDI_FAILURE); } + if (mrsas_common_check(instance, cmd) != DDI_SUCCESS) { + return_mfi_pkt(instance, cmd); + return (DDI_FAILURE); + } + return_mfi_app_pkt(instance, cmd); con_log(CL_ANN1, (CE_CONT, "mrsas_issue_init_mfi: Done")); return (DDI_SUCCESS); }
*** 3727,3742 **** instance); for (i = 0; i < (10 * 1000); i++) { status = RD_RESERVED0_REGISTER(instance); ! if (status & 1) delay(1 * drv_usectohz(MILLISEC)); ! else break; } } max_wait = (instance->tbolt == 1) ? 180 : 10; cur_state = MFI_STATE_OPERATIONAL; break; --- 3894,3910 ---- instance); for (i = 0; i < (10 * 1000); i++) { status = RD_RESERVED0_REGISTER(instance); ! if (status & 1) { delay(1 * drv_usectohz(MILLISEC)); ! } else { break; } + } } max_wait = (instance->tbolt == 1) ? 180 : 10; cur_state = MFI_STATE_OPERATIONAL; break;
*** 3805,3830 **** 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)); - } - #if 0 /* * Write 0xF to the doorbell register to do the following. * - Abort all outstanding commands (bit 0). * - Transition from OPERATIONAL to READY state (bit 1). * - Discard (possible) low MFA posted in 64-bit mode (bit-2). * - Set to release FW to continue running (i.e. BIOS handshake * (bit 3). */ - if (!instance->tbolt) { WR_IB_DOORBELL(0xF, instance); } - #endif return (DDI_SUCCESS); } /* * get_seq_num --- 3973,3998 ---- 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)); /* * Write 0xF to the doorbell register to do the following. * - Abort all outstanding commands (bit 0). * - Transition from OPERATIONAL to READY state (bit 1). * - Discard (possible) low MFA posted in 64-bit mode (bit-2). * - Set to release FW to continue running (i.e. BIOS handshake * (bit 3). */ WR_IB_DOORBELL(0xF, instance); } + if (mrsas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) { + return (EIO); + } + return (DDI_SUCCESS); } /* * get_seq_num
*** 3844,3856 **** } else { cmd = get_mfi_pkt(instance); } if (!cmd) { ! cmn_err(CE_WARN, ! "Failed to get a cmd from free-pool in get_seq_num(). fw_outstanding=0x%X max_fw_cmds=0x%X", ! instance->fw_outstanding, instance->max_fw_cmds); return (ENOMEM); } /* Clear the frame buffer and assign back the context id */ (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame)); --- 4012,4024 ---- } else { cmd = get_mfi_pkt(instance); } if (!cmd) { ! cmn_err(CE_WARN, "mr_sas: failed to get a cmd"); ! DTRACE_PROBE2(seq_num_mfi_err, uint16_t, ! instance->fw_outstanding, uint16_t, instance->max_fw_cmds); return (ENOMEM); } /* Clear the frame buffer and assign back the context id */ (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
*** 3966,3986 **** static void flush_cache(struct mrsas_instance *instance) { struct mrsas_cmd *cmd = NULL; struct mrsas_dcmd_frame *dcmd; - uint32_t max_cmd = instance->max_fw_cmds; if (instance->tbolt) { cmd = get_raid_msg_mfi_pkt(instance); } else { cmd = get_mfi_pkt(instance); } if (!cmd) { ! cmn_err(CE_WARN, ! "Failed to get a cmd from free-pool in flush_cache(). fw_outstanding=0x%X max_fw_cmds=0x%X", ! instance->fw_outstanding, instance->max_fw_cmds); return; } /* Clear the frame buffer and assign back the context id */ (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame)); --- 4134,4154 ---- static void flush_cache(struct mrsas_instance *instance) { 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")); ! DTRACE_PROBE2(flush_cache_err, uint16_t, ! instance->fw_outstanding, uint16_t, instance->max_fw_cmds); return; } /* Clear the frame buffer and assign back the context id */ (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
*** 4030,4040 **** */ void service_mfi_aen(struct mrsas_instance *instance, struct mrsas_cmd *cmd) { uint32_t seq_num; - uint32_t i; struct mrsas_evt_detail *evt_detail = (struct mrsas_evt_detail *)instance->mfi_evt_detail_obj.buffer; int rval = 0; int tgt = 0; uint8_t dtype; --- 4198,4207 ----
*** 4076,4086 **** case MR_EVT_CFG_CLEARED: { for (tgt = 0; tgt < MRDRV_MAX_LD; tgt++) { if (instance->mr_ld_list[tgt].dip != NULL) { mutex_enter(&instance->config_dev_mtx); instance->mr_ld_list[tgt].flag = ! ~MRDRV_TGT_VALID; mutex_exit(&instance->config_dev_mtx); rval = mrsas_service_evt(instance, tgt, 0, MRSAS_EVT_UNCONFIG_TGT, NULL); con_log(CL_ANN1, (CE_WARN, "mr_sas: CFG CLEARED AEN rval = %d " --- 4243,4253 ---- case MR_EVT_CFG_CLEARED: { for (tgt = 0; tgt < MRDRV_MAX_LD; tgt++) { if (instance->mr_ld_list[tgt].dip != NULL) { mutex_enter(&instance->config_dev_mtx); instance->mr_ld_list[tgt].flag = ! (uint8_t)~MRDRV_TGT_VALID; mutex_exit(&instance->config_dev_mtx); rval = mrsas_service_evt(instance, tgt, 0, MRSAS_EVT_UNCONFIG_TGT, NULL); con_log(CL_ANN1, (CE_WARN, "mr_sas: CFG CLEARED AEN rval = %d "
*** 4091,4101 **** } case MR_EVT_LD_DELETED: { tgt = ddi_get16(acc_handle, &evt_detail->args.ld.target_id); mutex_enter(&instance->config_dev_mtx); ! instance->mr_ld_list[tgt].flag = ~MRDRV_TGT_VALID; mutex_exit(&instance->config_dev_mtx); rval = mrsas_service_evt(instance, ddi_get16(acc_handle, &evt_detail->args.ld.target_id), 0, MRSAS_EVT_UNCONFIG_TGT, NULL); con_log(CL_ANN1, (CE_WARN, "mr_sas: LD DELETED AEN rval = %d " --- 4258,4268 ---- } case MR_EVT_LD_DELETED: { tgt = ddi_get16(acc_handle, &evt_detail->args.ld.target_id); mutex_enter(&instance->config_dev_mtx); ! instance->mr_ld_list[tgt].flag = (uint8_t)~MRDRV_TGT_VALID; mutex_exit(&instance->config_dev_mtx); rval = mrsas_service_evt(instance, ddi_get16(acc_handle, &evt_detail->args.ld.target_id), 0, MRSAS_EVT_UNCONFIG_TGT, NULL); con_log(CL_ANN1, (CE_WARN, "mr_sas: LD DELETED AEN rval = %d "
*** 4122,4161 **** pd_addr = &evt_detail->args.pd_addr; dtype = pd_addr->scsi_dev_type; con_log(CL_DLEVEL1, (CE_NOTE, " MR_EVT_PD_REMOVED_EXT: dtype = %x," " arg_type = %d ", dtype, evt_detail->arg_type)); ! tgt = ddi_get16(acc_handle, &evt_detail->args.pd.device_id); mutex_enter(&instance->config_dev_mtx); ! instance->mr_tbolt_pd_list[tgt].flag = (uint8_t)~MRDRV_TGT_VALID; mutex_exit(&instance->config_dev_mtx); ! rval = mrsas_service_evt(instance, ! ddi_get16(acc_handle, &evt_detail->args.pd.device_id), 1, MRSAS_EVT_UNCONFIG_TGT, NULL); con_log(CL_ANN1, (CE_WARN, "mr_sas: PD_REMOVED:" "rval = %d tgt id = %d ", rval, ! ddi_get16(acc_handle, &evt_detail->args.pd.device_id))); ! break; } ! }/* End of MR_EVT_PD_REMOVED_EXT */ case MR_EVT_PD_INSERTED_EXT: { if (instance->tbolt) { rval = mrsas_service_evt(instance, ! ddi_get16(acc_handle, &evt_detail->args.pd.device_id), 1, MRSAS_EVT_CONFIG_TGT, NULL); con_log(CL_ANN1, (CE_WARN, "mr_sas: PD_INSERTEDi_EXT:" "rval = %d tgt id = %d ", rval, ! ddi_get16(acc_handle, &evt_detail->args.pd.device_id))); ! break; } ! }/* End of MR_EVT_PD_INSERTED_EXT */ case MR_EVT_PD_STATE_CHANGE: { if (instance->tbolt) { ! tgt = ddi_get16(acc_handle, &evt_detail->args.pd.device_id); ! if ((evt_detail->args.pd_state.prevState == PD_SYSTEM) && (evt_detail->args.pd_state.newState != PD_SYSTEM)) { mutex_enter(&instance->config_dev_mtx); instance->mr_tbolt_pd_list[tgt].flag = (uint8_t)~MRDRV_TGT_VALID; mutex_exit(&instance->config_dev_mtx); --- 4289,4335 ---- pd_addr = &evt_detail->args.pd_addr; dtype = pd_addr->scsi_dev_type; con_log(CL_DLEVEL1, (CE_NOTE, " MR_EVT_PD_REMOVED_EXT: dtype = %x," " arg_type = %d ", dtype, evt_detail->arg_type)); ! tgt = ddi_get16(acc_handle, ! &evt_detail->args.pd.device_id); mutex_enter(&instance->config_dev_mtx); ! instance->mr_tbolt_pd_list[tgt].flag = ! (uint8_t)~MRDRV_TGT_VALID; mutex_exit(&instance->config_dev_mtx); ! rval = mrsas_service_evt(instance, ddi_get16( ! acc_handle, &evt_detail->args.pd.device_id), 1, MRSAS_EVT_UNCONFIG_TGT, NULL); con_log(CL_ANN1, (CE_WARN, "mr_sas: PD_REMOVED:" "rval = %d tgt id = %d ", rval, ! ddi_get16(acc_handle, ! &evt_detail->args.pd.device_id))); } ! break; ! } /* End of MR_EVT_PD_REMOVED_EXT */ case MR_EVT_PD_INSERTED_EXT: { if (instance->tbolt) { rval = mrsas_service_evt(instance, ! ddi_get16(acc_handle, ! &evt_detail->args.pd.device_id), 1, MRSAS_EVT_CONFIG_TGT, NULL); con_log(CL_ANN1, (CE_WARN, "mr_sas: PD_INSERTEDi_EXT:" "rval = %d tgt id = %d ", rval, ! ddi_get16(acc_handle, ! &evt_detail->args.pd.device_id))); } ! break; ! } /* End of MR_EVT_PD_INSERTED_EXT */ case MR_EVT_PD_STATE_CHANGE: { if (instance->tbolt) { ! tgt = ddi_get16(acc_handle, ! &evt_detail->args.pd.device_id); ! if ((evt_detail->args.pd_state.prevState == ! PD_SYSTEM) && (evt_detail->args.pd_state.newState != PD_SYSTEM)) { mutex_enter(&instance->config_dev_mtx); instance->mr_tbolt_pd_list[tgt].flag = (uint8_t)~MRDRV_TGT_VALID; mutex_exit(&instance->config_dev_mtx);
*** 4182,4191 **** --- 4356,4366 ---- ddi_get16(acc_handle, &evt_detail->args.pd.device_id))); break; } } + break; } #endif } /* End of Main Switch */
*** 4261,4272 **** "FW doesn't support ocr "); return (ADAPTER_RESET_NOT_REQUIRED); } else { con_log(CL_ANN, (CE_NOTE, ! "mrsas_initiate_ocr_if_fw_is_faulty: " ! "FW in Fault state, detected in ISR: FW supports ocr ")); return (ADAPTER_RESET_REQUIRED); } } --- 4436,4447 ---- "FW doesn't support ocr "); return (ADAPTER_RESET_NOT_REQUIRED); } else { con_log(CL_ANN, (CE_NOTE, ! "mrsas_initiate_ocr_if_fw_is_faulty: FW in Fault " ! "state, detected in ISR: FW supports ocr ")); return (ADAPTER_RESET_REQUIRED); } }
*** 4316,4325 **** --- 4491,4510 ---- /* syncronize the Cmd frame for the controller */ (void) ddi_dma_sync(cmd->frame_dma_obj.dma_handle, 0, 0, DDI_DMA_SYNC_FORCPU); + if (mrsas_check_dma_handle(cmd->frame_dma_obj.dma_handle) != + DDI_SUCCESS) { + mrsas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE); + ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST); + con_log(CL_ANN1, (CE_WARN, + "mrsas_softintr: " + "FMA check reports DMA handle failure")); + return (DDI_INTR_CLAIMED); + } + hdr = &cmd->frame->hdr; /* remove the internal command from the process list */ mlist_del_init(&cmd->list);
*** 4360,4369 **** --- 4545,4557 ---- con_log(CL_ANN, (CE_CONT, "CDB[0] = %x completed for %s: size %lx context %x", pkt->pkt_cdbp[0], ((acmd->islogical) ? "LD" : "PD"), acmd->cmd_dmacount, hdr->context)); + DTRACE_PROBE3(softintr_cdb, uint8_t, pkt->pkt_cdbp[0], + uint_t, acmd->cmd_cdblen, ulong_t, + acmd->cmd_dmacount); if (pkt->pkt_cdbp[0] == SCMD_INQUIRY) { struct scsi_inquiry *inq; if (acmd->cmd_dmacount != 0) {
*** 4388,4407 **** MFI_STAT_DEVICE_NOT_FOUND; } } } switch (hdr->cmd_status) { case MFI_STAT_OK: pkt->pkt_scbp[0] = STATUS_GOOD; break; case MFI_STAT_LD_CC_IN_PROGRESS: case MFI_STAT_LD_RECON_IN_PROGRESS: pkt->pkt_scbp[0] = STATUS_GOOD; break; case MFI_STAT_LD_INIT_IN_PROGRESS: ! con_log(CL_ANN, (CE_WARN, "Initialization in Progress")); pkt->pkt_reason = CMD_TRAN_ERR; break; case MFI_STAT_SCSI_DONE_WITH_ERROR: con_log(CL_ANN, (CE_CONT, "scsi_done error")); --- 4576,4599 ---- MFI_STAT_DEVICE_NOT_FOUND; } } } + DTRACE_PROBE2(softintr_done, uint8_t, hdr->cmd, + uint8_t, hdr->cmd_status); + switch (hdr->cmd_status) { case MFI_STAT_OK: pkt->pkt_scbp[0] = STATUS_GOOD; break; case MFI_STAT_LD_CC_IN_PROGRESS: case MFI_STAT_LD_RECON_IN_PROGRESS: pkt->pkt_scbp[0] = STATUS_GOOD; break; case MFI_STAT_LD_INIT_IN_PROGRESS: ! con_log(CL_ANN, ! (CE_WARN, "Initialization in Progress")); pkt->pkt_reason = CMD_TRAN_ERR; break; case MFI_STAT_SCSI_DONE_WITH_ERROR: con_log(CL_ANN, (CE_CONT, "scsi_done error"));
*** 4409,4421 **** pkt->pkt_reason = CMD_CMPLT; ((struct scsi_status *) pkt->pkt_scbp)->sts_chk = 1; if (pkt->pkt_cdbp[0] == SCMD_TEST_UNIT_READY) { ! ! con_log(CL_ANN, (CE_WARN, "TEST_UNIT_READY fail")); ! } else { pkt->pkt_state |= STATE_ARQ_DONE; arqstat = (void *)(pkt->pkt_scbp); arqstat->sts_rqpkt_reason = CMD_CMPLT; arqstat->sts_rqpkt_resid = 0; --- 4601,4612 ---- pkt->pkt_reason = CMD_CMPLT; ((struct scsi_status *) pkt->pkt_scbp)->sts_chk = 1; if (pkt->pkt_cdbp[0] == SCMD_TEST_UNIT_READY) { ! con_log(CL_ANN, ! (CE_WARN, "TEST_UNIT_READY fail")); } else { pkt->pkt_state |= STATE_ARQ_DONE; arqstat = (void *)(pkt->pkt_scbp); arqstat->sts_rqpkt_reason = CMD_CMPLT; arqstat->sts_rqpkt_resid = 0;
*** 4478,4487 **** --- 4669,4690 ---- break; } atomic_add_16(&instance->fw_outstanding, (-1)); + (void) mrsas_common_check(instance, cmd); + + if (acmd->cmd_dmahandle) { + if (mrsas_check_dma_handle( + acmd->cmd_dmahandle) != DDI_SUCCESS) { + ddi_fm_service_impact(instance->dip, + DDI_SERVICE_UNAFFECTED); + 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: "
*** 4529,4538 **** --- 4732,4744 ---- */ complete_cmd_in_sync_mode(instance, cmd); break; default: + mrsas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE); + ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST); + if (cmd->pkt != NULL) { pkt = cmd->pkt; if (((pkt->pkt_flags & FLAG_NOINTR) == 0) && pkt->pkt_comp) {
*** 4606,4619 **** con_log(CL_ANN, (CE_WARN, "Failed : ddi_dma_mem_alloc")); return (-1); } - if (obj->dma_handle == NULL) { - con_log(CL_ANN, (CE_WARN, "Failed : ddi_dma_mem_alloc")); - return (-1); - } if (ddi_dma_addr_bind_handle(obj->dma_handle, NULL, obj->buffer, obj->size, DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL, &obj->dma_cookie[0], &cookie_cnt) != DDI_SUCCESS) { --- 4812,4821 ----
*** 4622,4639 **** con_log(CL_ANN, (CE_WARN, "Failed : ddi_dma_addr_bind_handle")); return (-1); } - if (obj->acc_handle == NULL) { - ddi_dma_mem_free(&obj->acc_handle); - ddi_dma_free_handle(&obj->dma_handle); ! con_log(CL_ANN, (CE_WARN, "Failed : ddi_dma_addr_bind_handle")); return (-1); } return (cookie_cnt); } /* --- 4824,4843 ---- con_log(CL_ANN, (CE_WARN, "Failed : ddi_dma_addr_bind_handle")); return (-1); } ! if (mrsas_check_dma_handle(obj->dma_handle) != DDI_SUCCESS) { ! ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST); return (-1); } + if (mrsas_check_acc_handle(obj->acc_handle) != DDI_SUCCESS) { + ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST); + return (-1); + } return (cookie_cnt); } /*
*** 4644,4657 **** */ int mrsas_free_dma_obj(struct mrsas_instance *instance, dma_obj_t obj) { ! if ( (obj.dma_handle == NULL) || (obj.acc_handle == NULL) ) { return (DDI_SUCCESS); } (void) ddi_dma_unbind_handle(obj.dma_handle); ddi_dma_mem_free(&obj.acc_handle); ddi_dma_free_handle(&obj.dma_handle); obj.acc_handle = NULL; return (DDI_SUCCESS); --- 4848,4875 ---- */ int mrsas_free_dma_obj(struct mrsas_instance *instance, dma_obj_t obj) { ! if ((obj.dma_handle == NULL) || (obj.acc_handle == NULL)) { return (DDI_SUCCESS); } + /* + * NOTE: These check-handle functions fail if *_handle == NULL, but + * this function succeeds because of the previous check. + */ + if (mrsas_check_dma_handle(obj.dma_handle) != DDI_SUCCESS) { + ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED); + return (DDI_FAILURE); + } + + if (mrsas_check_acc_handle(obj.acc_handle) != DDI_SUCCESS) { + ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED); + return (DDI_FAILURE); + } + (void) ddi_dma_unbind_handle(obj.dma_handle); ddi_dma_mem_free(&obj.acc_handle); ddi_dma_free_handle(&obj.dma_handle); obj.acc_handle = NULL; return (DDI_SUCCESS);
*** 4698,4713 **** cb = (callback == NULL_FUNC) ? DDI_DMA_DONTWAIT : DDI_DMA_SLEEP; tmp_dma_attr.dma_attr_sgllen = instance->max_num_sge; tmp_dma_attr.dma_attr_addr_hi = 0xffffffffffffffffull; if (instance->tbolt) { ! //OCR-RESET FIX ! tmp_dma_attr.dma_attr_count_max = (U64)mrsas_tbolt_max_cap_maxxfer; //limit to 256K ! tmp_dma_attr.dma_attr_maxxfer = (U64)mrsas_tbolt_max_cap_maxxfer; //limit to 256K } - if ((i = ddi_dma_alloc_handle(instance->dip, &tmp_dma_attr, cb, 0, &acmd->cmd_dmahandle)) != DDI_SUCCESS) { switch (i) { case DDI_DMA_BADATTR: bioerror(bp, EFAULT); --- 4916,4932 ---- cb = (callback == NULL_FUNC) ? DDI_DMA_DONTWAIT : DDI_DMA_SLEEP; tmp_dma_attr.dma_attr_sgllen = instance->max_num_sge; tmp_dma_attr.dma_attr_addr_hi = 0xffffffffffffffffull; if (instance->tbolt) { ! /* OCR-RESET FIX */ ! tmp_dma_attr.dma_attr_count_max = ! (U64)mrsas_tbolt_max_cap_maxxfer; /* limit to 256K */ ! tmp_dma_attr.dma_attr_maxxfer = ! (U64)mrsas_tbolt_max_cap_maxxfer; /* limit to 256K */ } if ((i = ddi_dma_alloc_handle(instance->dip, &tmp_dma_attr, cb, 0, &acmd->cmd_dmahandle)) != DDI_SUCCESS) { switch (i) { case DDI_DMA_BADATTR: bioerror(bp, EFAULT);
*** 4902,4914 **** acmd->device_id = MAP_DEVICE_ID(instance, ap); *cmd_done = 0; /* get the command packet */ if (!(cmd = get_mfi_pkt(instance))) { ! cmn_err(CE_WARN, ! "Failed to get a cmd from free-pool in build_cmd(). fw_outstanding=0x%X max_fw_cmds=0x%X", ! instance->fw_outstanding, instance->max_fw_cmds); return (NULL); } acc_handle = cmd->frame_dma_obj.acc_handle; --- 5121,5132 ---- 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); } acc_handle = cmd->frame_dma_obj.acc_handle;
*** 4916,4925 **** --- 5134,5145 ---- (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame)); ddi_put32(acc_handle, &cmd->frame->hdr.context, cmd->index); cmd->pkt = pkt; cmd->cmd = acmd; + DTRACE_PROBE3(build_cmds, uint8_t, pkt->pkt_cdbp[0], + ulong_t, acmd->cmd_dmacount, ulong_t, acmd->cmd_dma_len); /* lets get the command directions */ if (acmd->cmd_flags & CFLAG_DMASEND) { flags = MFI_FRAME_DIR_WRITE;
*** 5000,5029 **** mfi_sgl = (struct mrsas_sge64 *)&ldio->sgl; } context = ddi_get32(acc_handle, &ldio->context); ! if (acmd->cmd_cdblen == CDB_GROUP0) { /* 6-byte cdb */ ddi_put32(acc_handle, &ldio->lba_count, ( (uint16_t)(pkt->pkt_cdbp[4]))); ddi_put32(acc_handle, &ldio->start_lba_lo, ( ((uint32_t)(pkt->pkt_cdbp[3])) | ((uint32_t)(pkt->pkt_cdbp[2]) << 8) | ((uint32_t)((pkt->pkt_cdbp[1]) & 0x1F) << 16))); ! } else if (acmd->cmd_cdblen == CDB_GROUP1) { /* 10-byte cdb */ ddi_put32(acc_handle, &ldio->lba_count, ( ((uint16_t)(pkt->pkt_cdbp[8])) | ((uint16_t)(pkt->pkt_cdbp[7]) << 8))); ddi_put32(acc_handle, &ldio->start_lba_lo, ( ((uint32_t)(pkt->pkt_cdbp[5])) | ((uint32_t)(pkt->pkt_cdbp[4]) << 8) | ((uint32_t)(pkt->pkt_cdbp[3]) << 16) | ((uint32_t)(pkt->pkt_cdbp[2]) << 24))); ! } else if (acmd->cmd_cdblen == CDB_GROUP5) { /* 12-byte cdb */ ddi_put32(acc_handle, &ldio->lba_count, ( ((uint32_t)(pkt->pkt_cdbp[9])) | ((uint32_t)(pkt->pkt_cdbp[8]) << 8) | ((uint32_t)(pkt->pkt_cdbp[7]) << 16) | ((uint32_t)(pkt->pkt_cdbp[6]) << 24))); --- 5220,5252 ---- mfi_sgl = (struct mrsas_sge64 *)&ldio->sgl; } context = ddi_get32(acc_handle, &ldio->context); ! if (acmd->cmd_cdblen == CDB_GROUP0) { ! /* 6-byte cdb */ ddi_put32(acc_handle, &ldio->lba_count, ( (uint16_t)(pkt->pkt_cdbp[4]))); ddi_put32(acc_handle, &ldio->start_lba_lo, ( ((uint32_t)(pkt->pkt_cdbp[3])) | ((uint32_t)(pkt->pkt_cdbp[2]) << 8) | ((uint32_t)((pkt->pkt_cdbp[1]) & 0x1F) << 16))); ! } else if (acmd->cmd_cdblen == CDB_GROUP1) { ! /* 10-byte cdb */ ddi_put32(acc_handle, &ldio->lba_count, ( ((uint16_t)(pkt->pkt_cdbp[8])) | ((uint16_t)(pkt->pkt_cdbp[7]) << 8))); ddi_put32(acc_handle, &ldio->start_lba_lo, ( ((uint32_t)(pkt->pkt_cdbp[5])) | ((uint32_t)(pkt->pkt_cdbp[4]) << 8) | ((uint32_t)(pkt->pkt_cdbp[3]) << 16) | ((uint32_t)(pkt->pkt_cdbp[2]) << 24))); ! } else if (acmd->cmd_cdblen == CDB_GROUP5) { ! /* 12-byte cdb */ ddi_put32(acc_handle, &ldio->lba_count, ( ((uint32_t)(pkt->pkt_cdbp[9])) | ((uint32_t)(pkt->pkt_cdbp[8]) << 8) | ((uint32_t)(pkt->pkt_cdbp[7]) << 16) | ((uint32_t)(pkt->pkt_cdbp[6]) << 24)));
*** 5031,5041 **** ddi_put32(acc_handle, &ldio->start_lba_lo, ( ((uint32_t)(pkt->pkt_cdbp[5])) | ((uint32_t)(pkt->pkt_cdbp[4]) << 8) | ((uint32_t)(pkt->pkt_cdbp[3]) << 16) | ((uint32_t)(pkt->pkt_cdbp[2]) << 24))); ! } else if (acmd->cmd_cdblen == CDB_GROUP4) { /* 16-byte cdb */ ddi_put32(acc_handle, &ldio->lba_count, ( ((uint32_t)(pkt->pkt_cdbp[13])) | ((uint32_t)(pkt->pkt_cdbp[12]) << 8) | ((uint32_t)(pkt->pkt_cdbp[11]) << 16) | ((uint32_t)(pkt->pkt_cdbp[10]) << 24))); --- 5254,5265 ---- ddi_put32(acc_handle, &ldio->start_lba_lo, ( ((uint32_t)(pkt->pkt_cdbp[5])) | ((uint32_t)(pkt->pkt_cdbp[4]) << 8) | ((uint32_t)(pkt->pkt_cdbp[3]) << 16) | ((uint32_t)(pkt->pkt_cdbp[2]) << 24))); ! } else if (acmd->cmd_cdblen == CDB_GROUP4) { ! /* 16-byte cdb */ ddi_put32(acc_handle, &ldio->lba_count, ( ((uint32_t)(pkt->pkt_cdbp[13])) | ((uint32_t)(pkt->pkt_cdbp[12]) << 8) | ((uint32_t)(pkt->pkt_cdbp[11]) << 16) | ((uint32_t)(pkt->pkt_cdbp[10]) << 24)));
*** 5147,5156 **** --- 5371,5381 ---- } return (cmd); } + #ifndef __sparc /* * wait_for_outstanding - Wait for all outstanding cmds * @instance: Adapter soft state * * This function waits for upto MRDRV_RESET_WAIT_TIME seconds for FW to
*** 5175,5186 **** return (1); } return (0); } - /* * issue_mfi_pthru */ static int issue_mfi_pthru(struct mrsas_instance *instance, struct mrsas_ioctl *ioctl, --- 5400,5411 ---- return (1); } return (0); } + #endif /* __sparc */ /* * issue_mfi_pthru */ static int issue_mfi_pthru(struct mrsas_instance *instance, struct mrsas_ioctl *ioctl,
*** 5187,5197 **** struct mrsas_cmd *cmd, int mode) { void *ubuf; uint32_t kphys_addr = 0; uint32_t xferlen = 0; ! uint32_t new_xfer_length =0; uint_t model; ddi_acc_handle_t acc_handle = cmd->frame_dma_obj.acc_handle; dma_obj_t pthru_dma_obj; struct mrsas_pthru_frame *kpthru; struct mrsas_pthru_frame *pthru; --- 5412,5422 ---- struct mrsas_cmd *cmd, int mode) { void *ubuf; uint32_t kphys_addr = 0; uint32_t xferlen = 0; ! uint32_t new_xfer_length = 0; uint_t model; ddi_acc_handle_t acc_handle = cmd->frame_dma_obj.acc_handle; dma_obj_t pthru_dma_obj; struct mrsas_pthru_frame *kpthru; struct mrsas_pthru_frame *pthru;
*** 5224,5235 **** } if (xferlen) { /* means IOCTL requires DMA */ /* allocate the data transfer buffer */ ! //pthru_dma_obj.size = xferlen; ! MRSAS_GET_BOUNDARY_ALIGNED_LEN(xferlen,new_xfer_length,PAGESIZE); pthru_dma_obj.size = new_xfer_length; pthru_dma_obj.dma_attr = mrsas_generic_dma_attr; pthru_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; pthru_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; pthru_dma_obj.dma_attr.dma_attr_sgllen = 1; --- 5449,5461 ---- } if (xferlen) { /* means IOCTL requires DMA */ /* allocate the data transfer buffer */ ! /* pthru_dma_obj.size = xferlen; */ ! MRSAS_GET_BOUNDARY_ALIGNED_LEN(xferlen, new_xfer_length, ! PAGESIZE); pthru_dma_obj.size = new_xfer_length; pthru_dma_obj.dma_attr = mrsas_generic_dma_attr; pthru_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; pthru_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; pthru_dma_obj.dma_attr.dma_attr_sgllen = 1;
*** 5272,5282 **** ddi_put16(acc_handle, &pthru->timeout, kpthru->timeout); ddi_put32(acc_handle, &pthru->data_xfer_len, kpthru->data_xfer_len); ddi_put32(acc_handle, &pthru->sense_buf_phys_addr_hi, 0); pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr; ! /*ddi_put32(acc_handle, &pthru->sense_buf_phys_addr_lo, 0); */ ddi_rep_put8(acc_handle, (uint8_t *)kpthru->cdb, (uint8_t *)pthru->cdb, pthru->cdb_len, DDI_DEV_AUTOINCR); ddi_put16(acc_handle, &pthru->flags, kpthru->flags & ~MFI_FRAME_SGL64); --- 5498,5508 ---- ddi_put16(acc_handle, &pthru->timeout, kpthru->timeout); ddi_put32(acc_handle, &pthru->data_xfer_len, kpthru->data_xfer_len); ddi_put32(acc_handle, &pthru->sense_buf_phys_addr_hi, 0); pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr; ! /* ddi_put32(acc_handle, &pthru->sense_buf_phys_addr_lo, 0); */ ddi_rep_put8(acc_handle, (uint8_t *)kpthru->cdb, (uint8_t *)pthru->cdb, pthru->cdb_len, DDI_DEV_AUTOINCR); ddi_put16(acc_handle, &pthru->flags, kpthru->flags & ~MFI_FRAME_SGL64);
*** 5311,5324 **** kpthru->cmd_status = ddi_get8(acc_handle, &pthru->cmd_status); kpthru->scsi_status = ddi_get8(acc_handle, &pthru->scsi_status); con_log(CL_ANN, (CE_CONT, "issue_mfi_pthru: cmd_status %x, " "scsi_status %x", kpthru->cmd_status, kpthru->scsi_status)); if (kpthru->sense_len) { ! uint sense_len = SENSE_LENGTH; ! void *sense_ubuf = (void *)(ulong_t)kpthru->sense_buf_phys_addr_lo; if (kpthru->sense_len <= SENSE_LENGTH) { sense_len = kpthru->sense_len; } for (i = 0; i < sense_len; i++) { --- 5537,5553 ---- kpthru->cmd_status = ddi_get8(acc_handle, &pthru->cmd_status); kpthru->scsi_status = ddi_get8(acc_handle, &pthru->scsi_status); con_log(CL_ANN, (CE_CONT, "issue_mfi_pthru: cmd_status %x, " "scsi_status %x", kpthru->cmd_status, kpthru->scsi_status)); + DTRACE_PROBE3(issue_pthru, uint8_t, kpthru->cmd, uint8_t, + kpthru->cmd_status, uint8_t, kpthru->scsi_status); if (kpthru->sense_len) { ! uint_t sense_len = SENSE_LENGTH; ! void *sense_ubuf = ! (void *)(ulong_t)kpthru->sense_buf_phys_addr_lo; if (kpthru->sense_len <= SENSE_LENGTH) { sense_len = kpthru->sense_len; } for (i = 0; i < sense_len; i++) {
*** 5328,5338 **** con_log(CL_ANN, (CE_WARN, "issue_mfi_pthru : " "copy to user space failed")); } con_log(CL_DLEVEL1, (CE_WARN, ! "Copying Sense info sense_buff[%d] = 0x%X\n",i,*((uint8_t *)cmd->sense+i))); } } (void) ddi_dma_sync(cmd->frame_dma_obj.dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV); --- 5557,5568 ---- con_log(CL_ANN, (CE_WARN, "issue_mfi_pthru : " "copy to user space failed")); } con_log(CL_DLEVEL1, (CE_WARN, ! "Copying Sense info sense_buff[%d] = 0x%X", ! i, *((uint8_t *)cmd->sense + i))); } } (void) ddi_dma_sync(cmd->frame_dma_obj.dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV);
*** 5364,5375 **** int i; dcmd = &cmd->frame->dcmd; kdcmd = (struct mrsas_dcmd_frame *)&ioctl->frame[0]; if (instance->adapterresetinprogress) { ! con_log(CL_ANN1, (CE_WARN, "Reset flag set, " ! "returning mfi_pkt and setting TRAN_BUSY\n")); return (DDI_FAILURE); } model = ddi_model_convert_from(mode & FMODELS); if (model == DDI_MODEL_ILP32) { con_log(CL_ANN1, (CE_CONT, "issue_mfi_dcmd: DDI_MODEL_ILP32")); --- 5594,5605 ---- int i; dcmd = &cmd->frame->dcmd; kdcmd = (struct mrsas_dcmd_frame *)&ioctl->frame[0]; if (instance->adapterresetinprogress) { ! con_log(CL_ANN1, (CE_NOTE, "Reset flag set, " ! "returning mfi_pkt and setting TRAN_BUSY")); return (DDI_FAILURE); } model = ddi_model_convert_from(mode & FMODELS); if (model == DDI_MODEL_ILP32) { con_log(CL_ANN1, (CE_CONT, "issue_mfi_dcmd: DDI_MODEL_ILP32"));
*** 5389,5400 **** #endif } if (xferlen) { /* means IOCTL requires DMA */ /* allocate the data transfer buffer */ ! //dcmd_dma_obj.size = xferlen; ! MRSAS_GET_BOUNDARY_ALIGNED_LEN(xferlen,new_xfer_length,PAGESIZE); dcmd_dma_obj.size = new_xfer_length; dcmd_dma_obj.dma_attr = mrsas_generic_dma_attr; dcmd_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; dcmd_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; dcmd_dma_obj.dma_attr.dma_attr_sgllen = 1; --- 5619,5631 ---- #endif } if (xferlen) { /* means IOCTL requires DMA */ /* allocate the data transfer buffer */ ! /* dcmd_dma_obj.size = xferlen; */ ! MRSAS_GET_BOUNDARY_ALIGNED_LEN(xferlen, new_xfer_length, ! PAGESIZE); dcmd_dma_obj.size = new_xfer_length; dcmd_dma_obj.dma_attr = mrsas_generic_dma_attr; dcmd_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; dcmd_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; dcmd_dma_obj.dma_attr.dma_attr_sgllen = 1;
*** 5401,5412 **** dcmd_dma_obj.dma_attr.dma_attr_align = 1; /* allocate kernel buffer for DMA */ if (mrsas_alloc_dma_obj(instance, &dcmd_dma_obj, (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) { ! con_log(CL_ANN, (CE_WARN, "issue_mfi_dcmd: " ! "could not allocate data transfer buffer.")); return (DDI_FAILURE); } (void) memset(dcmd_dma_obj.buffer, 0, xferlen); /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */ --- 5632,5644 ---- dcmd_dma_obj.dma_attr.dma_attr_align = 1; /* allocate kernel buffer for DMA */ if (mrsas_alloc_dma_obj(instance, &dcmd_dma_obj, (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) { ! con_log(CL_ANN, ! (CE_WARN, "issue_mfi_dcmd: could not " ! "allocate data transfer buffer.")); return (DDI_FAILURE); } (void) memset(dcmd_dma_obj.buffer, 0, xferlen); /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
*** 5464,5474 **** } } } kdcmd->cmd_status = ddi_get8(acc_handle, &dcmd->cmd_status); ! con_log(CL_ANN, (CE_CONT, "issue_mfi_dcmd: cmd_status %x", kdcmd->cmd_status)); if (xferlen) { /* free kernel buffer */ if (mrsas_free_dma_obj(instance, dcmd_dma_obj) != DDI_SUCCESS) return (DDI_FAILURE); --- 5696,5709 ---- } } } kdcmd->cmd_status = ddi_get8(acc_handle, &dcmd->cmd_status); ! con_log(CL_ANN, ! (CE_CONT, "issue_mfi_dcmd: cmd_status %x", kdcmd->cmd_status)); ! DTRACE_PROBE3(issue_dcmd, uint32_t, kdcmd->opcode, uint8_t, ! kdcmd->cmd, uint8_t, kdcmd->cmd_status); if (xferlen) { /* free kernel buffer */ if (mrsas_free_dma_obj(instance, dcmd_dma_obj) != DDI_SUCCESS) return (DDI_FAILURE);
*** 5555,5566 **** #endif } if (request_xferlen) { /* means IOCTL requires DMA */ /* allocate the data transfer buffer */ ! //request_dma_obj.size = request_xferlen; ! MRSAS_GET_BOUNDARY_ALIGNED_LEN(request_xferlen,new_xfer_length1,PAGESIZE); request_dma_obj.size = new_xfer_length1; request_dma_obj.dma_attr = mrsas_generic_dma_attr; request_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; request_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; request_dma_obj.dma_attr.dma_attr_sgllen = 1; --- 5790,5802 ---- #endif } if (request_xferlen) { /* means IOCTL requires DMA */ /* allocate the data transfer buffer */ ! /* request_dma_obj.size = request_xferlen; */ ! MRSAS_GET_BOUNDARY_ALIGNED_LEN(request_xferlen, ! new_xfer_length1, PAGESIZE); request_dma_obj.size = new_xfer_length1; request_dma_obj.dma_attr = mrsas_generic_dma_attr; request_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; request_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; request_dma_obj.dma_attr.dma_attr_sgllen = 1;
*** 5588,5599 **** } if (response_xferlen) { /* means IOCTL requires DMA */ /* allocate the data transfer buffer */ ! //response_dma_obj.size = response_xferlen; ! MRSAS_GET_BOUNDARY_ALIGNED_LEN(response_xferlen,new_xfer_length2,PAGESIZE); response_dma_obj.size = new_xfer_length2; response_dma_obj.dma_attr = mrsas_generic_dma_attr; response_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; response_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; response_dma_obj.dma_attr.dma_attr_sgllen = 1; --- 5824,5836 ---- } if (response_xferlen) { /* means IOCTL requires DMA */ /* allocate the data transfer buffer */ ! /* response_dma_obj.size = response_xferlen; */ ! MRSAS_GET_BOUNDARY_ALIGNED_LEN(response_xferlen, ! new_xfer_length2, PAGESIZE); response_dma_obj.size = new_xfer_length2; response_dma_obj.dma_attr = mrsas_generic_dma_attr; response_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; response_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; response_dma_obj.dma_attr.dma_attr_sgllen = 1;
*** 5719,5728 **** --- 5956,5966 ---- } ksmp->cmd_status = ddi_get8(acc_handle, &smp->cmd_status); con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: smp->cmd_status = %d", ksmp->cmd_status)); + DTRACE_PROBE2(issue_smp, uint8_t, ksmp->cmd, uint8_t, ksmp->cmd_status); if (request_xferlen) { /* free kernel buffer */ if (mrsas_free_dma_obj(instance, request_dma_obj) != DDI_SUCCESS)
*** 5775,5787 **** fis_xferlen = kstp->sgl.sge32[0].length; data_xferlen = kstp->sgl.sge32[1].length; fis_ubuf = (void *)(ulong_t)kstp->sgl.sge32[0].phys_addr; data_ubuf = (void *)(ulong_t)kstp->sgl.sge32[1].phys_addr; ! } ! else ! { #ifdef _ILP32 con_log(CL_ANN1, (CE_CONT, "issue_mfi_stp: DDI_MODEL_ILP32")); fis_xferlen = kstp->sgl.sge32[0].length; data_xferlen = kstp->sgl.sge32[1].length; --- 6013,6023 ---- fis_xferlen = kstp->sgl.sge32[0].length; data_xferlen = kstp->sgl.sge32[1].length; fis_ubuf = (void *)(ulong_t)kstp->sgl.sge32[0].phys_addr; data_ubuf = (void *)(ulong_t)kstp->sgl.sge32[1].phys_addr; ! } else { #ifdef _ILP32 con_log(CL_ANN1, (CE_CONT, "issue_mfi_stp: DDI_MODEL_ILP32")); fis_xferlen = kstp->sgl.sge32[0].length; data_xferlen = kstp->sgl.sge32[1].length;
*** 5804,5815 **** con_log(CL_ANN, (CE_CONT, "issue_mfi_stp: " "fis_ubuf = %p fis_xferlen = %x", fis_ubuf, fis_xferlen)); /* means IOCTL requires DMA */ /* allocate the data transfer buffer */ ! //fis_dma_obj.size = fis_xferlen; ! MRSAS_GET_BOUNDARY_ALIGNED_LEN(fis_xferlen,new_xfer_length1,PAGESIZE); fis_dma_obj.size = new_xfer_length1; fis_dma_obj.dma_attr = mrsas_generic_dma_attr; fis_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; fis_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; fis_dma_obj.dma_attr.dma_attr_sgllen = 1; --- 6040,6052 ---- con_log(CL_ANN, (CE_CONT, "issue_mfi_stp: " "fis_ubuf = %p fis_xferlen = %x", fis_ubuf, fis_xferlen)); /* means IOCTL requires DMA */ /* allocate the data transfer buffer */ ! /* fis_dma_obj.size = fis_xferlen; */ ! MRSAS_GET_BOUNDARY_ALIGNED_LEN(fis_xferlen, ! new_xfer_length1, PAGESIZE); fis_dma_obj.size = new_xfer_length1; fis_dma_obj.dma_attr = mrsas_generic_dma_attr; fis_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; fis_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; fis_dma_obj.dma_attr.dma_attr_sgllen = 1;
*** 5839,5858 **** con_log(CL_ANN, (CE_CONT, "issue_mfi_stp: data_ubuf = %p " "data_xferlen = %x", data_ubuf, data_xferlen)); /* means IOCTL requires DMA */ /* allocate the data transfer buffer */ ! //data_dma_obj.size = data_xferlen; ! MRSAS_GET_BOUNDARY_ALIGNED_LEN(data_xferlen,new_xfer_length2,PAGESIZE); data_dma_obj.size = new_xfer_length2; data_dma_obj.dma_attr = mrsas_generic_dma_attr; data_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; data_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; data_dma_obj.dma_attr.dma_attr_sgllen = 1; data_dma_obj.dma_attr.dma_attr_align = 1; ! /* allocate kernel buffer for DMA */ if (mrsas_alloc_dma_obj(instance, &data_dma_obj, (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) { con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: " "could not allocate data transfer buffer.")); return (DDI_FAILURE); --- 6076,6096 ---- con_log(CL_ANN, (CE_CONT, "issue_mfi_stp: data_ubuf = %p " "data_xferlen = %x", data_ubuf, data_xferlen)); /* means IOCTL requires DMA */ /* allocate the data transfer buffer */ ! /* data_dma_obj.size = data_xferlen; */ ! MRSAS_GET_BOUNDARY_ALIGNED_LEN(data_xferlen, new_xfer_length2, ! PAGESIZE); data_dma_obj.size = new_xfer_length2; data_dma_obj.dma_attr = mrsas_generic_dma_attr; data_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; data_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; data_dma_obj.dma_attr.dma_attr_sgllen = 1; data_dma_obj.dma_attr.dma_attr_align = 1; ! /* allocate kernel buffer for DMA */ if (mrsas_alloc_dma_obj(instance, &data_dma_obj, (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) { con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: " "could not allocate data transfer buffer.")); return (DDI_FAILURE);
*** 5929,5938 **** --- 6167,6177 ---- } kstp->cmd_status = ddi_get8(acc_handle, &stp->cmd_status); con_log(CL_ANN1, (CE_NOTE, "issue_mfi_stp: stp->cmd_status = %d", kstp->cmd_status)); + DTRACE_PROBE2(issue_stp, uint8_t, kstp->cmd, uint8_t, kstp->cmd_status); if (fis_xferlen) { /* free kernel buffer */ if (mrsas_free_dma_obj(instance, fis_dma_obj) != DDI_SUCCESS) return (DDI_FAILURE);
*** 6092,6105 **** cmd = get_raid_msg_mfi_pkt(instance); } else { cmd = get_mfi_pkt(instance); } if (!cmd) { ! cmn_err(CE_WARN, ! "Failed to get a cmd from free-pool in handle_mfi_ioctl(). " ! "fw_outstanding=0x%X max_fw_cmds=0x%X", ! instance->fw_outstanding, instance->max_fw_cmds); return (DDI_FAILURE); } /* Clear the frame buffer and assign back the context id */ (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame)); --- 6331,6344 ---- cmd = get_raid_msg_mfi_pkt(instance); } else { cmd = get_mfi_pkt(instance); } if (!cmd) { ! con_log(CL_ANN, (CE_WARN, "mr_sas: " ! "failed to get a cmd packet")); ! DTRACE_PROBE2(mfi_ioctl_err, uint16_t, ! instance->fw_outstanding, uint16_t, instance->max_fw_cmds); return (DDI_FAILURE); } /* Clear the frame buffer and assign back the context id */ (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
*** 6127,6136 **** --- 6366,6378 ---- "invalid mfi ioctl hdr->cmd = %d", hdr->cmd)); rval = DDI_FAILURE; break; } + if (mrsas_common_check(instance, cmd) != DDI_SUCCESS) + rval = DDI_FAILURE; + if (instance->tbolt) { return_raid_msg_mfi_pkt(instance, cmd); } else { return_mfi_pkt(instance, cmd); }
*** 6231,6248 **** } else { cmd = get_mfi_pkt(instance); } if (!cmd) { ! cmn_err(CE_WARN, ! "Failed to get a cmd from free-pool in register_mfi_aen(). " ! "fw_outstanding=0x%X max_fw_cmds=0x%X", ! instance->fw_outstanding, instance->max_fw_cmds); return (ENOMEM); } - /* Clear the frame buffer and assign back the context id */ (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame)); ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context, cmd->index); --- 6473,6487 ---- } else { cmd = get_mfi_pkt(instance); } if (!cmd) { ! DTRACE_PROBE2(mfi_aen_err, uint16_t, instance->fw_outstanding, ! uint16_t, instance->max_fw_cmds); return (ENOMEM); } /* Clear the frame buffer and assign back the context id */ (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame)); ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context, cmd->index);
*** 6364,6374 **** } con_log(CL_DLEVEL2, (CE_CONT, inquiry_buf)); } ! void io_timeout_checker(void *arg) { struct scsi_pkt *pkt; struct mrsas_instance *instance = arg; struct mrsas_cmd *cmd = NULL; --- 6603,6613 ---- } con_log(CL_DLEVEL2, (CE_CONT, inquiry_buf)); } ! static void io_timeout_checker(void *arg) { struct scsi_pkt *pkt; struct mrsas_instance *instance = arg; struct mrsas_cmd *cmd = NULL;
*** 6387,6406 **** return; } /* See if this check needs to be in the beginning or last in ISR */ if (mrsas_initiate_ocr_if_fw_is_faulty(instance) == 1) { ! cmn_err(CE_WARN, "io_timeout_checker:" "FW Fault, calling reset adapter"); ! cmn_err(CE_CONT, "io_timeout_checker: fw_outstanding 0x%X max_fw_cmds 0x%X", ! instance->fw_outstanding, instance->max_fw_cmds ); if (instance->adapterresetinprogress == 0) { instance->adapterresetinprogress = 1; if (instance->tbolt) ! mrsas_tbolt_reset_ppc(instance); else ! mrsas_reset_ppc(instance); instance->adapterresetinprogress = 0; } instance->timeout_id = timeout(io_timeout_checker, (void *) instance, drv_usectohz(MRSAS_1_SECOND)); return; --- 6626,6646 ---- return; } /* See if this check needs to be in the beginning or last in ISR */ if (mrsas_initiate_ocr_if_fw_is_faulty(instance) == 1) { ! cmn_err(CE_WARN, "io_timeout_checker: " "FW Fault, calling reset adapter"); ! cmn_err(CE_CONT, "io_timeout_checker: " ! "fw_outstanding 0x%X max_fw_cmds 0x%X", ! instance->fw_outstanding, instance->max_fw_cmds); if (instance->adapterresetinprogress == 0) { instance->adapterresetinprogress = 1; if (instance->tbolt) ! (void) mrsas_tbolt_reset_ppc(instance); else ! (void) mrsas_reset_ppc(instance); instance->adapterresetinprogress = 0; } instance->timeout_id = timeout(io_timeout_checker, (void *) instance, drv_usectohz(MRSAS_1_SECOND)); return;
*** 6429,6467 **** } time = --cmd->drv_pkt_time; } if (time <= 0) { cmn_err(CE_WARN, "%llx: " ! "io_timeout_checker: TIMING OUT: pkt " ! ": %p, cmd %p fw_outstanding 0x%X max_fw_cmds 0x%X\n", ! gethrtime(), (void *)pkt, (void *)cmd, instance->fw_outstanding, instance->max_fw_cmds); counter++; break; } } mutex_exit(&instance->cmd_pend_mtx); if (counter) { if (instance->disable_online_ctrl_reset == 1) { ! cmn_err(CE_WARN, "mr_sas %d: %s(): OCR is NOT supported by Firmware, KILL adapter!!!", instance->instance, __func__); if (instance->tbolt) ! (void) mrsas_tbolt_kill_adapter(instance); else (void) mrsas_kill_adapter(instance); return; } else { if (cmd->retry_count_for_ocr <= IO_RETRY_COUNT) { if (instance->adapterresetinprogress == 0) { ! if (instance->tbolt) ! mrsas_tbolt_reset_ppc(instance); ! else ! mrsas_reset_ppc(instance); } } else { cmn_err(CE_WARN, "io_timeout_checker: " "cmd %p cmd->index %d " "timed out even after 3 resets: " --- 6669,6712 ---- } time = --cmd->drv_pkt_time; } if (time <= 0) { cmn_err(CE_WARN, "%llx: " ! "io_timeout_checker: TIMING OUT: pkt: %p, " ! "cmd %p fw_outstanding 0x%X max_fw_cmds 0x%X\n", ! gethrtime(), (void *)pkt, (void *)cmd, ! instance->fw_outstanding, instance->max_fw_cmds); counter++; break; } } mutex_exit(&instance->cmd_pend_mtx); if (counter) { if (instance->disable_online_ctrl_reset == 1) { ! cmn_err(CE_WARN, "mr_sas %d: %s(): OCR is NOT " ! "supported by Firmware, KILL adapter!!!", instance->instance, __func__); if (instance->tbolt) ! mrsas_tbolt_kill_adapter(instance); else (void) mrsas_kill_adapter(instance); return; } else { if (cmd->retry_count_for_ocr <= IO_RETRY_COUNT) { if (instance->adapterresetinprogress == 0) { ! if (instance->tbolt) { ! (void) mrsas_tbolt_reset_ppc( ! instance); ! } else { ! (void) mrsas_reset_ppc( ! instance); } + } } else { cmn_err(CE_WARN, "io_timeout_checker: " "cmd %p cmd->index %d " "timed out even after 3 resets: "
*** 6468,6478 **** "so KILL adapter", (void *)cmd, cmd->index); mrsas_print_cmd_details(instance, cmd, 0xDD); if (instance->tbolt) ! (void) mrsas_tbolt_kill_adapter(instance); else (void) mrsas_kill_adapter(instance); return; } } --- 6713,6723 ---- "so KILL adapter", (void *)cmd, cmd->index); mrsas_print_cmd_details(instance, cmd, 0xDD); if (instance->tbolt) ! mrsas_tbolt_kill_adapter(instance); else (void) mrsas_kill_adapter(instance); return; } }
*** 6516,6526 **** "ISSUED CMD TO FW : called : cmd : %p, instance: %p" "(NO PKT)\n", gethrtime(), (void *)cmd, (void *)instance)); } mutex_enter(&instance->reg_write_mtx); - ASSERT(mutex_owned(&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); --- 6761,6770 ----
*** 6557,6567 **** } cmd->cmd_status = ENODATA; mutex_enter(&instance->reg_write_mtx); - ASSERT(mutex_owned(&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); --- 6801,6810 ----
*** 6681,6690 **** --- 6924,6938 ---- if (!(status & MFI_REPLY_2108_MESSAGE_INTR)) { ret = DDI_INTR_UNCLAIMED; } + if (mrsas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) { + ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST); + ret = DDI_INTR_UNCLAIMED; + } + if (ret == DDI_INTR_UNCLAIMED) { return (ret); } /* clear the interrupt by writing back the same value */ WR_OB_DOORBELL_CLEAR(status, instance);
*** 6758,6768 **** while (!(status & DIAG_WRITE_ENABLE)) { delay(100 * drv_usectohz(MILLISEC)); status = RD_OB_DRWE(instance); if (retry++ == 100) { cmn_err(CE_WARN, "mrsas_reset_ppc: DRWE bit " ! "check retry count %d\n", retry); return (DDI_FAILURE); } } WR_IB_DRWE(status | DIAG_RESET_ADAPTER, instance); delay(100 * drv_usectohz(MILLISEC)); --- 7006,7016 ---- while (!(status & DIAG_WRITE_ENABLE)) { delay(100 * drv_usectohz(MILLISEC)); status = RD_OB_DRWE(instance); if (retry++ == 100) { cmn_err(CE_WARN, "mrsas_reset_ppc: DRWE bit " ! "check retry count %d", retry); return (DDI_FAILURE); } } WR_IB_DRWE(status | DIAG_RESET_ADAPTER, instance); delay(100 * drv_usectohz(MILLISEC));
*** 6769,6780 **** status = RD_OB_DRWE(instance); while (status & DIAG_RESET_ADAPTER) { delay(100 * drv_usectohz(MILLISEC)); status = RD_OB_DRWE(instance); if (retry++ == 100) { ! cmn_err(CE_WARN, ! "mrsas_reset_ppc: RESET FAILED. KILL adapter called\n."); (void) mrsas_kill_adapter(instance); return (DDI_FAILURE); } } --- 7017,7028 ---- status = RD_OB_DRWE(instance); while (status & DIAG_RESET_ADAPTER) { delay(100 * drv_usectohz(MILLISEC)); status = RD_OB_DRWE(instance); if (retry++ == 100) { ! cmn_err(CE_WARN, "mrsas_reset_ppc: " ! "RESET FAILED. KILL adapter called."); (void) mrsas_kill_adapter(instance); return (DDI_FAILURE); } }
*** 6812,6822 **** goto retry_reset; } else { cmn_err(CE_WARN, "mrsas_reset_ppc: " "Max Reset Count exceeded >%d" ! "Mark HBA as bad, KILL adapter", MAX_FW_RESET_COUNT); (void) mrsas_kill_adapter(instance); return (DDI_FAILURE); } } --- 7060,7071 ---- goto retry_reset; } else { cmn_err(CE_WARN, "mrsas_reset_ppc: " "Max Reset Count exceeded >%d" ! "Mark HBA as bad, KILL adapter", ! MAX_FW_RESET_COUNT); (void) mrsas_kill_adapter(instance); return (DDI_FAILURE); } }
*** 6875,6886 **** --- 7124,7311 ---- con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc done\n")); return (DDI_SUCCESS); } + /* + * FMA functions. + */ + int + mrsas_common_check(struct mrsas_instance *instance, struct mrsas_cmd *cmd) + { + int ret = DDI_SUCCESS; + if (cmd != NULL && + mrsas_check_dma_handle(cmd->frame_dma_obj.dma_handle) != + DDI_SUCCESS) { + ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED); + if (cmd->pkt != NULL) { + cmd->pkt->pkt_reason = CMD_TRAN_ERR; + cmd->pkt->pkt_statistics = 0; + } + ret = DDI_FAILURE; + } + if (mrsas_check_dma_handle(instance->mfi_internal_dma_obj.dma_handle) + != DDI_SUCCESS) { + ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED); + if (cmd != NULL && cmd->pkt != NULL) { + cmd->pkt->pkt_reason = CMD_TRAN_ERR; + cmd->pkt->pkt_statistics = 0; + } + ret = DDI_FAILURE; + } + if (mrsas_check_dma_handle(instance->mfi_evt_detail_obj.dma_handle) != + DDI_SUCCESS) { + ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED); + if (cmd != NULL && cmd->pkt != NULL) { + cmd->pkt->pkt_reason = CMD_TRAN_ERR; + cmd->pkt->pkt_statistics = 0; + } + ret = DDI_FAILURE; + } + if (mrsas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) { + ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED); + + ddi_fm_acc_err_clear(instance->regmap_handle, DDI_FME_VER0); + + if (cmd != NULL && cmd->pkt != NULL) { + cmd->pkt->pkt_reason = CMD_TRAN_ERR; + cmd->pkt->pkt_statistics = 0; + } + ret = DDI_FAILURE; + } + + return (ret); + } + + /*ARGSUSED*/ static int + mrsas_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data) + { + /* + * as the driver can always deal with an error in any dma or + * access handle, we can just return the fme_status value. + */ + pci_ereport_post(dip, err, NULL); + return (err->fme_status); + } + + static void + mrsas_fm_init(struct mrsas_instance *instance) + { + /* Need to change iblock to priority for new MSI intr */ + ddi_iblock_cookie_t fm_ibc; + + /* Only register with IO Fault Services if we have some capability */ + if (instance->fm_capabilities) { + /* Adjust access and dma attributes for FMA */ + endian_attr.devacc_attr_access = DDI_FLAGERR_ACC; + mrsas_generic_dma_attr.dma_attr_flags = DDI_DMA_FLAGERR; + + /* + * Register capabilities with IO Fault Services. + * fm_capabilities will be updated to indicate + * capabilities actually supported (not requested.) + */ + + ddi_fm_init(instance->dip, &instance->fm_capabilities, &fm_ibc); + + /* + * Initialize pci ereport capabilities if ereport + * capable (should always be.) + */ + + if (DDI_FM_EREPORT_CAP(instance->fm_capabilities) || + DDI_FM_ERRCB_CAP(instance->fm_capabilities)) { + pci_ereport_setup(instance->dip); + } + + /* + * Register error callback if error callback capable. + */ + if (DDI_FM_ERRCB_CAP(instance->fm_capabilities)) { + ddi_fm_handler_register(instance->dip, + mrsas_fm_error_cb, (void*) instance); + } + } else { + endian_attr.devacc_attr_access = DDI_DEFAULT_ACC; + mrsas_generic_dma_attr.dma_attr_flags = 0; + } + } + + static void + mrsas_fm_fini(struct mrsas_instance *instance) + { + /* Only unregister FMA capabilities if registered */ + if (instance->fm_capabilities) { + /* + * Un-register error callback if error callback capable. + */ + if (DDI_FM_ERRCB_CAP(instance->fm_capabilities)) { + ddi_fm_handler_unregister(instance->dip); + } + + /* + * Release any resources allocated by pci_ereport_setup() + */ + if (DDI_FM_EREPORT_CAP(instance->fm_capabilities) || + DDI_FM_ERRCB_CAP(instance->fm_capabilities)) { + pci_ereport_teardown(instance->dip); + } + + /* Unregister from IO Fault Services */ + ddi_fm_fini(instance->dip); + + /* Adjust access and dma attributes for FMA */ + endian_attr.devacc_attr_access = DDI_DEFAULT_ACC; + mrsas_generic_dma_attr.dma_attr_flags = 0; + } + } + + int + mrsas_check_acc_handle(ddi_acc_handle_t handle) + { + ddi_fm_error_t de; + + if (handle == NULL) { + return (DDI_FAILURE); + } + + ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION); + + return (de.fme_status); + } + + int + mrsas_check_dma_handle(ddi_dma_handle_t handle) + { + ddi_fm_error_t de; + + if (handle == NULL) { + return (DDI_FAILURE); + } + + ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION); + + return (de.fme_status); + } + + void + mrsas_fm_ereport(struct mrsas_instance *instance, char *detail) + { + uint64_t ena; + char buf[FM_MAX_CLASS]; + + (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail); + ena = fm_ena_generate(0, FM_ENA_FMT1); + if (DDI_FM_EREPORT_CAP(instance->fm_capabilities)) { + ddi_fm_ereport_post(instance->dip, buf, ena, DDI_NOSLEEP, + FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERSION, NULL); + } + } + + static int mrsas_add_intrs(struct mrsas_instance *instance, int intr_type) { dev_info_t *dip = instance->dip; int avail, actual, count;
*** 6918,6937 **** /* * Allocate an array of interrupt handlers. Currently we support * only one interrupt. The framework can be extended later. */ instance->intr_htable_size = count * sizeof (ddi_intr_handle_t); ! instance->intr_htable = kmem_zalloc(instance->intr_htable_size, KM_SLEEP); ! if (instance->intr_htable == NULL) { ! con_log(CL_ANN, (CE_WARN, "mrsas_add_intrs: " ! "failed to allocate memory for intr-handle table")); ! instance->intr_htable_size = 0; ! return (DDI_FAILURE); ! } ! flag = ((intr_type == DDI_INTR_TYPE_MSI) || (intr_type == ! DDI_INTR_TYPE_MSIX)) ? DDI_INTR_ALLOC_STRICT:DDI_INTR_ALLOC_NORMAL; /* Allocate interrupt */ ret = ddi_intr_alloc(dip, instance->intr_htable, intr_type, 0, count, &actual, flag); --- 7343,7359 ---- /* * Allocate an array of interrupt handlers. Currently we support * only one interrupt. The framework can be extended later. */ instance->intr_htable_size = count * sizeof (ddi_intr_handle_t); ! instance->intr_htable = kmem_zalloc(instance->intr_htable_size, ! KM_SLEEP); ! ASSERT(instance->intr_htable); ! flag = ((intr_type == DDI_INTR_TYPE_MSI) || ! (intr_type == DDI_INTR_TYPE_MSIX)) ? ! DDI_INTR_ALLOC_STRICT : DDI_INTR_ALLOC_NORMAL; /* Allocate interrupt */ ret = ddi_intr_alloc(dip, instance->intr_htable, intr_type, 0, count, &actual, flag);
*** 7009,7033 **** return (DDI_SUCCESS); mrsas_free_handlers: for (i = 0; i < actual; i++) - { (void) ddi_intr_remove_handler(instance->intr_htable[i]); - } mrsas_free_handles: for (i = 0; i < actual; i++) - { (void) ddi_intr_free(instance->intr_htable[i]); - } mrsas_free_htable: if (instance->intr_htable != NULL) kmem_free(instance->intr_htable, instance->intr_htable_size); ! instance->intr_htable =NULL; instance->intr_htable_size = 0; return (DDI_FAILURE); } --- 7431,7451 ---- return (DDI_SUCCESS); mrsas_free_handlers: for (i = 0; i < actual; i++) (void) ddi_intr_remove_handler(instance->intr_htable[i]); mrsas_free_handles: for (i = 0; i < actual; i++) (void) ddi_intr_free(instance->intr_htable[i]); mrsas_free_htable: if (instance->intr_htable != NULL) kmem_free(instance->intr_htable, instance->intr_htable_size); ! instance->intr_htable = NULL; instance->intr_htable_size = 0; return (DDI_FAILURE); }
*** 7058,7068 **** } if (instance->intr_htable != NULL) kmem_free(instance->intr_htable, instance->intr_htable_size); ! instance->intr_htable =NULL; instance->intr_htable_size = 0; } static int --- 7476,7486 ---- } if (instance->intr_htable != NULL) kmem_free(instance->intr_htable, instance->intr_htable_size); ! instance->intr_htable = NULL; instance->intr_htable_size = 0; } static int
*** 7100,7117 **** break; } if (lun == 0) { rval = mrsas_config_ld(instance, tgt, lun, childp); - } #ifdef PDSUPPORT ! else if ( instance->tbolt == 1 && lun != 0) { rval = mrsas_tbolt_config_pd(instance, tgt, lun, childp); - } #endif ! else { rval = NDI_FAILURE; } break; } --- 7518,7533 ---- break; } if (lun == 0) { rval = mrsas_config_ld(instance, tgt, lun, childp); #ifdef PDSUPPORT ! } else if (instance->tbolt == 1 && lun != 0) { rval = mrsas_tbolt_config_pd(instance, tgt, lun, childp); #endif ! } else { rval = NDI_FAILURE; } break; }
*** 7146,7156 **** } #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 --- 7562,7572 ---- } #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
*** 7228,7242 **** } return (NDI_SUCCESS); } sd = kmem_zalloc(sizeof (struct scsi_device), KM_SLEEP); - if (sd == NULL) { - con_log(CL_ANN1, (CE_WARN, - "mrsas_config_ld: failed to allocate mem for scsi_device")); - return (NDI_FAILURE); - } sd->sd_address.a_hba_tran = instance->tran; sd->sd_address.a_target = (uint16_t)tgt; sd->sd_address.a_lun = (uint8_t)lun; if (scsi_hba_probe(sd, NULL) == SCSIPROBE_EXISTS) --- 7644,7653 ----
*** 7367,7377 **** "mr_sas: Event task failed for t%dl%d event = %d", tgt, lun, event)); kmem_free(mrevt, sizeof (struct mrsas_eventinfo)); return (DDI_FAILURE); } ! return (DDI_SUCCESS); } static void mrsas_issue_evt_taskq(struct mrsas_eventinfo *mrevt) --- 7778,7788 ---- "mr_sas: Event task failed for t%dl%d event = %d", tgt, lun, event)); kmem_free(mrevt, sizeof (struct mrsas_eventinfo)); return (DDI_FAILURE); } ! DTRACE_PROBE3(service_evt, int, tgt, int, lun, int, event); return (DDI_SUCCESS); } static void mrsas_issue_evt_taskq(struct mrsas_eventinfo *mrevt)
*** 7387,7422 **** if (mrevt->tgt < MRDRV_MAX_LD && mrevt->lun == 0) { mutex_enter(&instance->config_dev_mtx); dip = instance->mr_ld_list[mrevt->tgt].dip; mutex_exit(&instance->config_dev_mtx); - } - #ifdef PDSUPPORT ! else { mutex_enter(&instance->config_dev_mtx); dip = instance->mr_tbolt_pd_list[mrevt->tgt].dip; mutex_exit(&instance->config_dev_mtx); - } #endif ndi_devi_enter(instance->dip, &circ1); switch (mrevt->event) { case MRSAS_EVT_CONFIG_TGT: if (dip == NULL) { if (mrevt->lun == 0) { (void) mrsas_config_ld(instance, mrevt->tgt, 0, NULL); - } #ifdef PDSUPPORT ! else if (instance->tbolt) { (void) mrsas_tbolt_config_pd(instance, mrevt->tgt, 1, NULL); - } #endif con_log(CL_ANN1, (CE_NOTE, "mr_sas: EVT_CONFIG_TGT called:" " for tgt %d lun %d event %d", mrevt->tgt, mrevt->lun, mrevt->event)); --- 7798,7831 ---- if (mrevt->tgt < MRDRV_MAX_LD && mrevt->lun == 0) { mutex_enter(&instance->config_dev_mtx); dip = instance->mr_ld_list[mrevt->tgt].dip; mutex_exit(&instance->config_dev_mtx); #ifdef PDSUPPORT ! } else { mutex_enter(&instance->config_dev_mtx); dip = instance->mr_tbolt_pd_list[mrevt->tgt].dip; mutex_exit(&instance->config_dev_mtx); #endif + } + ndi_devi_enter(instance->dip, &circ1); switch (mrevt->event) { case MRSAS_EVT_CONFIG_TGT: if (dip == NULL) { if (mrevt->lun == 0) { (void) mrsas_config_ld(instance, mrevt->tgt, 0, NULL); #ifdef PDSUPPORT ! } else if (instance->tbolt) { (void) mrsas_tbolt_config_pd(instance, mrevt->tgt, 1, NULL); #endif + } con_log(CL_ANN1, (CE_NOTE, "mr_sas: EVT_CONFIG_TGT called:" " for tgt %d lun %d event %d", mrevt->tgt, mrevt->lun, mrevt->event));
*** 7512,7517 **** default: break; } return (NULL); } - --- 7921,7925 ----