6029a2d88c01674debfd7c2e16c941a97302b739susans * megaraid_sas.c: source for mega_sas driver
6029a2d88c01674debfd7c2e16c941a97302b739susans * MegaRAID device driver for SAS controllers
6029a2d88c01674debfd7c2e16c941a97302b739susans * Copyright (c) 2005-2008, LSI Logic Corporation.
6029a2d88c01674debfd7c2e16c941a97302b739susans * All rights reserved.
6029a2d88c01674debfd7c2e16c941a97302b739susans * Rajesh Prabhakaran<Rajesh.Prabhakaran@lsil.com>
6029a2d88c01674debfd7c2e16c941a97302b739susans * Seokmann Ju
6029a2d88c01674debfd7c2e16c941a97302b739susans * Redistribution and use in source and binary forms, with or without
6029a2d88c01674debfd7c2e16c941a97302b739susans * modification, are permitted provided that the following conditions are met:
6029a2d88c01674debfd7c2e16c941a97302b739susans * 1. Redistributions of source code must retain the above copyright notice,
6029a2d88c01674debfd7c2e16c941a97302b739susans * this list of conditions and the following disclaimer.
6029a2d88c01674debfd7c2e16c941a97302b739susans * 2. Redistributions in binary form must reproduce the above copyright notice,
6029a2d88c01674debfd7c2e16c941a97302b739susans * this list of conditions and the following disclaimer in the documentation
6029a2d88c01674debfd7c2e16c941a97302b739susans * and/or other materials provided with the distribution.
6029a2d88c01674debfd7c2e16c941a97302b739susans * 3. Neither the name of the author nor the names of its contributors may be
6029a2d88c01674debfd7c2e16c941a97302b739susans * used to endorse or promote products derived from this software without
6029a2d88c01674debfd7c2e16c941a97302b739susans * specific prior written permission.
6029a2d88c01674debfd7c2e16c941a97302b739susans * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6029a2d88c01674debfd7c2e16c941a97302b739susans * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6029a2d88c01674debfd7c2e16c941a97302b739susans * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
6029a2d88c01674debfd7c2e16c941a97302b739susans * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
6029a2d88c01674debfd7c2e16c941a97302b739susans * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
6029a2d88c01674debfd7c2e16c941a97302b739susans * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
6029a2d88c01674debfd7c2e16c941a97302b739susans * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
6029a2d88c01674debfd7c2e16c941a97302b739susans * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
6029a2d88c01674debfd7c2e16c941a97302b739susans * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
6029a2d88c01674debfd7c2e16c941a97302b739susans * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
6029a2d88c01674debfd7c2e16c941a97302b739susans * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
9c57abc8d70cb139020be846baec0a9c4d9a73cdsrivijitha dugganapalli * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
6029a2d88c01674debfd7c2e16c941a97302b739susans * Use is subject to license terms.
89b43686db1fe9681d80a7cf5662730cb9378caeBayard Bell * Copyright (c) 2011 Bayard G. Bell. All rights reserved.
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China#include <sys/ddifm.h>
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China#include <sys/fm/protocol.h>
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China#include <sys/fm/util.h>
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China#include <sys/fm/io/ddi.h>
6029a2d88c01674debfd7c2e16c941a97302b739susans * Local static data
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele 0, /* low DMA address range */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele 0 /* bus specific DMA flags */
6029a2d88c01674debfd7c2e16c941a97302b739susans * cb_ops contains base level routines
6029a2d88c01674debfd7c2e16c941a97302b739susans 0, /* streamtab */
6029a2d88c01674debfd7c2e16c941a97302b739susans * dev_ops contains configuration routines
6029a2d88c01674debfd7c2e16c941a97302b739susans 0, /* refcnt */
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans * common entry points - for loadable kernel modules *
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans * _init - initialize a loadable module
6029a2d88c01674debfd7c2e16c941a97302b739susans * The driver should perform any one-time resource allocation or data
6029a2d88c01674debfd7c2e16c941a97302b739susans * initialization during driver loading in _init(). For example, the driver
6029a2d88c01674debfd7c2e16c941a97302b739susans * should initialize any mutexes global to the driver in this routine.
6029a2d88c01674debfd7c2e16c941a97302b739susans * The driver should not, however, use _init() to allocate or initialize
6029a2d88c01674debfd7c2e16c941a97302b739susans * anything that has to do with a particular instance of the device.
6029a2d88c01674debfd7c2e16c941a97302b739susans * Per-instance initialization must be done in attach().
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_instance), 0);
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ret != 0) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "megaraid: could not init state"));
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "megaraid: could not init scsi hba"));
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ret != 0) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "megaraid: mod_install failed"));
6029a2d88c01674debfd7c2e16c941a97302b739susans * _info - returns information about a loadable module.
6029a2d88c01674debfd7c2e16c941a97302b739susans * _info() is called to return module information. This is a typical entry
6029a2d88c01674debfd7c2e16c941a97302b739susans * point that does predefined role. It simply calls mod_info().
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans * _fini - prepare a loadable module for unloading
6029a2d88c01674debfd7c2e16c941a97302b739susans * In _fini(), the driver should release any resources that were allocated in
6029a2d88c01674debfd7c2e16c941a97302b739susans * _init(). The driver must remove itself from the system module list.
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans * common entry points - for autoconfiguration *
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans * attach - adds a device to the system as part of initialization
6029a2d88c01674debfd7c2e16c941a97302b739susans * The kernel calls a driver's attach() entry point to attach an instance of
6029a2d88c01674debfd7c2e16c941a97302b739susans * a device (for MegaRAID, it is instance of a controller) or to resume
6029a2d88c01674debfd7c2e16c941a97302b739susans * operation for an instance of a device that has been suspended or has been
6029a2d88c01674debfd7c2e16c941a97302b739susans * shut down by the power management framework
6029a2d88c01674debfd7c2e16c941a97302b739susans * The attach() entry point typically includes the following types of
6029a2d88c01674debfd7c2e16c941a97302b739susans * processing:
6029a2d88c01674debfd7c2e16c941a97302b739susans * - allocate a soft-state structure for the device instance (for MegaRAID,
6029a2d88c01674debfd7c2e16c941a97302b739susans * controller instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans * - initialize per-instance mutexes
6029a2d88c01674debfd7c2e16c941a97302b739susans * - initialize condition variables
6029a2d88c01674debfd7c2e16c941a97302b739susans * - register the device's interrupts (for MegaRAID, controller's interrupts)
6029a2d88c01674debfd7c2e16c941a97302b739susans * - map the registers and memory of the device instance (for MegaRAID,
6029a2d88c01674debfd7c2e16c941a97302b739susans * controller instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans * - create minor device nodes for the device instance (for MegaRAID,
6029a2d88c01674debfd7c2e16c941a97302b739susans * controller instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans * - report that the device instance (for MegaRAID, controller instance) has
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_dma_attr_t tran_dma_attr;
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele /* CONSTCOND */
6029a2d88c01674debfd7c2e16c941a97302b739susans * Since we know that some instantiations of this device can be
6029a2d88c01674debfd7c2e16c941a97302b739susans * plugged into slave-only SBus slots, check to see whether this is
6029a2d88c01674debfd7c2e16c941a97302b739susans * one such.
6029a2d88c01674debfd7c2e16c941a97302b739susans "mega%d: Device in slave-only slot, unused", instance_no));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate the soft state for the instance */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_soft_state_zalloc(megasas_state, instance_no)
6029a2d88c01674debfd7c2e16c941a97302b739susans "mega%d: Failed to allocate soft state",
6029a2d88c01674debfd7c2e16c941a97302b739susans instance = (struct megasas_instance *)ddi_get_soft_state
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_instance));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Setup the PCI configuration space handles */
6029a2d88c01674debfd7c2e16c941a97302b739susans "mega%d: pci config setup failed ",
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_func_ptr));
6029a2d88c01674debfd7c2e16c941a97302b739susans "megaraid: failed to get registers."));
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_func_ptr));
6029a2d88c01674debfd7c2e16c941a97302b739susans pci_config_put16(instance->pci_handle, PCI_CONF_COMM,
6029a2d88c01674debfd7c2e16c941a97302b739susans "0x%x:0x%x 0x%x:0x%x, irq:%d drv-ver:%s\n",
6029a2d88c01674debfd7c2e16c941a97302b739susans /* enable bus-mastering */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele con_log(CL_DLEVEL1, (CE_CONT, "megaraid%d: "
6029a2d88c01674debfd7c2e16c941a97302b739susans /* initialize function pointers */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China /* Initialize FMA */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China instance->fm_capabilities = ddi_prop_get_int(
6ec0e3088091a677d3f67cf54a25174b0eb6db4aSusan Scheufele DDI_DEV_T_ANY, instance->dip, DDI_PROP_DONTPASS,
6ec0e3088091a677d3f67cf54a25174b0eb6db4aSusan Scheufele DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_fm_init(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* setup the mfi based low level driver */
6029a2d88c01674debfd7c2e16c941a97302b739susans "could not initialize the low level driver"));
6029a2d88c01674debfd7c2e16c941a97302b739susans * Allocate the interrupt blocking cookie.
6029a2d88c01674debfd7c2e16c941a97302b739susans * It represents the information the framework
6029a2d88c01674debfd7c2e16c941a97302b739susans * needs to block interrupts. This cookie will
6029a2d88c01674debfd7c2e16c941a97302b739susans * be used by the locks shared accross our ISR.
6029a2d88c01674debfd7c2e16c941a97302b739susans * These locks must be initialized before we
6029a2d88c01674debfd7c2e16c941a97302b739susans * register our ISR.
6029a2d88c01674debfd7c2e16c941a97302b739susans * ddi_add_intr(9F)
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_get_soft_iblock_cookie(dip, DDI_SOFTINT_HIGH,
6029a2d88c01674debfd7c2e16c941a97302b739susans * Initialize the driver mutexes common to
6029a2d88c01674debfd7c2e16c941a97302b739susans * normal/high level isr
6029a2d88c01674debfd7c2e16c941a97302b739susans * Initialize the driver mutexes
6029a2d88c01674debfd7c2e16c941a97302b739susans * specific to soft-isr
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_init(&instance->abort_cmd_mtx, "abort_cmd_mtx",
6029a2d88c01674debfd7c2e16c941a97302b739susans cv_init(&instance->int_cmd_cv, NULL, CV_DRIVER, NULL);
6029a2d88c01674debfd7c2e16c941a97302b739susans cv_init(&instance->abort_cmd_cv, NULL, CV_DRIVER, NULL);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Register our isr. */
6029a2d88c01674debfd7c2e16c941a97302b739susans " ISR did not register"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Register our soft-isr for highlevel interrupts. */
6029a2d88c01674debfd7c2e16c941a97302b739susans " Software ISR did not register"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Allocate a transport structure */
6029a2d88c01674debfd7c2e16c941a97302b739susans "scsi_hba_tran_alloc failed"));
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China tran_dma_attr = megasas_generic_dma_attr;
6029a2d88c01674debfd7c2e16c941a97302b739susans tran_dma_attr.dma_attr_sgllen = instance->max_num_sge;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Attach this instance of the hba */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (scsi_hba_attach_setup(dip, &tran_dma_attr, tran, 0)
6029a2d88c01674debfd7c2e16c941a97302b739susans "scsi_hba_attach failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* create devctl node for cfgadm command */
6029a2d88c01674debfd7c2e16c941a97302b739susans "megaraid: failed to create devctl node."));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* create scsi node for cfgadm command */
6029a2d88c01674debfd7c2e16c941a97302b739susans "megaraid: failed to create scsi node."));
6029a2d88c01674debfd7c2e16c941a97302b739susans * Create a node for applications
6029a2d88c01674debfd7c2e16c941a97302b739susans * for issuing ioctl to the driver.
6029a2d88c01674debfd7c2e16c941a97302b739susans "megaraid: failed to create ioctl node."));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* enable interrupt */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* initiate AEN */
6029a2d88c01674debfd7c2e16c941a97302b739susans "megaraid: failed to initiate AEN."));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Finally! We are on the air. */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_acc_handle(instance->regmap_handle) !=
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_acc_handle(instance->pci_handle) !=
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: DDI_PM_RESUME"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: DDI_RESUME"));
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_fm_fini(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: return failure from mega_attach\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans * getinfo - gets device information
6029a2d88c01674debfd7c2e16c941a97302b739susans * @resultp:
6029a2d88c01674debfd7c2e16c941a97302b739susans * The system calls getinfo() to obtain configuration information that only
6029a2d88c01674debfd7c2e16c941a97302b739susans * the driver knows. The mapping of minor numbers to device instance is
6029a2d88c01674debfd7c2e16c941a97302b739susans * entirely under the control of the driver. The system sometimes needs to ask
6029a2d88c01674debfd7c2e16c941a97302b739susans * the driver which device a particular dev_t represents.
6029a2d88c01674debfd7c2e16c941a97302b739susans * Given the device number return the devinfo pointer from the scsi_device
6029a2d88c01674debfd7c2e16c941a97302b739susans * structure.
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp)
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans * detach - detaches a device from the system
6029a2d88c01674debfd7c2e16c941a97302b739susans * @dip: pointer to the device's dev_info structure
6029a2d88c01674debfd7c2e16c941a97302b739susans * @cmd: type of detach
6029a2d88c01674debfd7c2e16c941a97302b739susans * A driver's detach() entry point is called to detach an instance of a device
6029a2d88c01674debfd7c2e16c941a97302b739susans * that is bound to the driver. The entry point is called with the instance of
6029a2d88c01674debfd7c2e16c941a97302b739susans * the device node to be detached and with DDI_DETACH, which is specified as
6029a2d88c01674debfd7c2e16c941a97302b739susans * the cmd argument to the entry point.
6029a2d88c01674debfd7c2e16c941a97302b739susans * This routine is called during driver unload. We free all the allocated
6029a2d88c01674debfd7c2e16c941a97302b739susans * resources and call the corresponding LLD so that it can also release all
6029a2d88c01674debfd7c2e16c941a97302b739susans * its resources.
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele /* CONSTCOND */
6029a2d88c01674debfd7c2e16c941a97302b739susans instance = (struct megasas_instance *)ddi_get_soft_state(megasas_state,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas:%d could not get instance in detach",
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele "megasas%d: detaching device 0x%4x:0x%4x:0x%4x:0x%4x\n",
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele instance_no, instance->vendor_id, instance->device_id,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas_detach: DDI_DETACH\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas:%d failed to detach",
6029a2d88c01674debfd7c2e16c941a97302b739susans "failed to abort prevous AEN command\n"));
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_fm_fini(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_func_ptr));
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas_detach: DDI_PM_SUSPEND\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas_detach: DDI_SUSPEND\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans * common entry points - for character driver types *
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans * open - gets access to a device
6029a2d88c01674debfd7c2e16c941a97302b739susans * @openflags:
6029a2d88c01674debfd7c2e16c941a97302b739susans * Access to a device by one or more application programs is controlled
6029a2d88c01674debfd7c2e16c941a97302b739susans * through the open() and close() entry points. The primary function of
6029a2d88c01674debfd7c2e16c941a97302b739susans * open() is to verify that the open request is allowed.
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_open(dev_t *dev, int openflags, int otyp, cred_t *credp)
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Check root permissions */
6029a2d88c01674debfd7c2e16c941a97302b739susans "megaraid: Non-root ioctl access tried!"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Verify we are being opened as a character device */
6029a2d88c01674debfd7c2e16c941a97302b739susans "megaraid: ioctl node must be a char node\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_get_soft_state(megasas_state, MINOR2INST(getminor(*dev)))
6029a2d88c01674debfd7c2e16c941a97302b739susans * close - gives up access to a device
6029a2d88c01674debfd7c2e16c941a97302b739susans * @openflags:
6029a2d88c01674debfd7c2e16c941a97302b739susans * close() should perform any cleanup necessary to finish using the minor
6029a2d88c01674debfd7c2e16c941a97302b739susans * device, and prepare the device (and driver) to be opened again.
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_close(dev_t dev, int openflags, int otyp, cred_t *credp)
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* no need for locks! */
6029a2d88c01674debfd7c2e16c941a97302b739susans * ioctl - performs a range of I/O commands for character drivers
6029a2d88c01674debfd7c2e16c941a97302b739susans * ioctl() routine must make sure that user data is copied into or out of the
6029a2d88c01674debfd7c2e16c941a97302b739susans * kernel address space explicitly using copyin(), copyout(), ddi_copyin(),
6029a2d88c01674debfd7c2e16c941a97302b739susans * and ddi_copyout(), as appropriate.
6029a2d88c01674debfd7c2e16c941a97302b739susans * This is a wrapper routine to serialize access to the actual ioctl routine.
6029a2d88c01674debfd7c2e16c941a97302b739susans * ioctl() should return 0 on success, or the appropriate error number. The
6029a2d88c01674debfd7c2e16c941a97302b739susans * driver may also set the value returned to the calling process through rvalp.
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans instance = ddi_get_soft_state(megasas_state, MINOR2INST(getminor(dev)));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* invalid minor number */
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "megaraid: adapter not found."));
6029a2d88c01674debfd7c2e16c941a97302b739susans "ERROR IOCTL copyin"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas_ioctl: copy_to_user failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas_ioctl: ERROR AEN copyin"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas_ioctl: copy_to_user failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans * common entry points - for block driver types *
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans * reset - TBD
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susans instance = (struct megasas_instance *)ddi_get_soft_state
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans "megaraid:%d could not get adapter in reset",
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE, "flushing cache for instance %d ..",
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans * entry points (SCSI HBA) *
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_tgt_init - initialize a target device instance
6029a2d88c01674debfd7c2e16c941a97302b739susans * @hba_dip:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @tgt_dip:
6029a2d88c01674debfd7c2e16c941a97302b739susans * The tran_tgt_init() entry point enables the HBA to allocate and initialize
6029a2d88c01674debfd7c2e16c941a97302b739susans * any per-target resources. tran_tgt_init() also enables the HBA to qualify
6029a2d88c01674debfd7c2e16c941a97302b739susans * the device's address as valid and supportable for that particular HBA.
6029a2d88c01674debfd7c2e16c941a97302b739susans * By returning DDI_FAILURE, the instance of the target driver for that device
6029a2d88c01674debfd7c2e16c941a97302b739susans * is not probed or attached.
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_init_pkt - allocate & initialize a scsi_pkt structure
6029a2d88c01674debfd7c2e16c941a97302b739susans * @statuslen:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @callback:
6029a2d88c01674debfd7c2e16c941a97302b739susans * The tran_init_pkt() entry point allocates and initializes a scsi_pkt
6029a2d88c01674debfd7c2e16c941a97302b739susans * structure and DMA resources for a target driver request. The
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_init_pkt() entry point is called when the target driver calls the
6029a2d88c01674debfd7c2e16c941a97302b739susans * SCSA function scsi_init_pkt(). Each call of the tran_init_pkt() entry point
6029a2d88c01674debfd7c2e16c941a97302b739susans * is a request to perform one or more of three possible services:
6029a2d88c01674debfd7c2e16c941a97302b739susans * - allocation and initialization of a scsi_pkt structure
6029a2d88c01674debfd7c2e16c941a97302b739susans * - allocation of DMA resources for data transfer
6029a2d88c01674debfd7c2e16c941a97302b739susans * - reallocation of DMA resources for the next portion of the data transfer
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic struct scsi_pkt *
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_init_pkt(struct scsi_address *ap, register struct scsi_pkt *pkt,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct buf *bp, int cmdlen, int statuslen, int tgtlen,
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* step #1 : pkt allocation */
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt = scsi_hba_pkt_alloc(instance->dip, ap, cmdlen, statuslen,
6029a2d88c01674debfd7c2e16c941a97302b739susans * Initialize the new pkt - we redundantly initialize
6029a2d88c01674debfd7c2e16c941a97302b739susans * all the fields for illustrative purposes.
6029a2d88c01674debfd7c2e16c941a97302b739susans /* step #2 : dma allocation/move */
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_start - transport a SCSI command to the addressed target
6029a2d88c01674debfd7c2e16c941a97302b739susans * The tran_start() entry point for a SCSI HBA driver is called to transport a
6029a2d88c01674debfd7c2e16c941a97302b739susans * SCSI command to the addressed target. The SCSI command is described
6029a2d88c01674debfd7c2e16c941a97302b739susans * entirely within the scsi_pkt structure, which the target driver allocated
6029a2d88c01674debfd7c2e16c941a97302b739susans * through the HBA driver's tran_init_pkt() entry point. If the command
6029a2d88c01674debfd7c2e16c941a97302b739susans * involves a data transfer, DMA resources must also have been allocated for
6029a2d88c01674debfd7c2e16c941a97302b739susans * the scsi_pkt structure.
6029a2d88c01674debfd7c2e16c941a97302b739susans * Return Values :
6029a2d88c01674debfd7c2e16c941a97302b739susans * TRAN_BUSY - request queue is full, no more free scbs
6029a2d88c01674debfd7c2e16c941a97302b739susans * TRAN_ACCEPT - pkt has been submitted to the instance
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_start(struct scsi_address *ap, register struct scsi_pkt *pkt)
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d:SCSI CDB[0]=0x%x",
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw *pkt->pkt_scbp = STATUS_GOOD; /* clear arq scsi_status */
6029a2d88c01674debfd7c2e16c941a97302b739susans * Check if the command is already completed by the mega_build_cmd()
6029a2d88c01674debfd7c2e16c941a97302b739susans * routine. In which case the busy_flag would be clear and scb will be
6029a2d88c01674debfd7c2e16c941a97302b739susans * NULL and appropriate reason provided in pkt_reason field
9c57abc8d70cb139020be846baec0a9c4d9a73cdsrivijitha dugganapalli if ((pkt->pkt_flags & FLAG_NOINTR) == 0) {
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->fw_outstanding > instance->max_fw_cmds) {
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Syncronize the Cmd frame for the controller */
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) ddi_dma_sync(cmd->frame_dma_obj.dma_handle, 0, 0,
e7eb627d1ca522096231179b750ce579a5278324yd instance->func_ptr-> issue_cmd_in_poll_mode(instance, cmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_state |= STATE_XFERRED_DATA | STATE_GOT_STATUS;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China (void) megasas_common_check(instance, cmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_abort - Abort any commands that are currently in transport
6029a2d88c01674debfd7c2e16c941a97302b739susans * The tran_abort() entry point for a SCSI HBA driver is called to abort any
6029a2d88c01674debfd7c2e16c941a97302b739susans * commands that are currently in transport for a particular target. This entry
6029a2d88c01674debfd7c2e16c941a97302b739susans * point is called when a target driver calls scsi_abort(). The tran_abort()
6029a2d88c01674debfd7c2e16c941a97302b739susans * entry point should attempt to abort the command denoted by the pkt
6029a2d88c01674debfd7c2e16c941a97302b739susans * parameter. If the pkt parameter is NULL, tran_abort() should attempt to
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele * abort all outstanding commands in the transport layer for the particular
6029a2d88c01674debfd7c2e16c941a97302b739susans * target or logical unit.
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_abort(struct scsi_address *ap, struct scsi_pkt *pkt)
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* aborting command not supported by H/W */
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_reset - reset either the SCSI bus or target
6029a2d88c01674debfd7c2e16c941a97302b739susans * The tran_reset() entry point for a SCSI HBA driver is called to reset either
6029a2d88c01674debfd7c2e16c941a97302b739susans * the SCSI bus or a particular SCSI target device. This entry point is called
6029a2d88c01674debfd7c2e16c941a97302b739susans * when a target driver calls scsi_reset(). The tran_reset() entry point must
6029a2d88c01674debfd7c2e16c941a97302b739susans * reset the SCSI bus if level is RESET_ALL. If level is RESET_TARGET, just the
6029a2d88c01674debfd7c2e16c941a97302b739susans * particular target or logical unit must be reset.
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_reset(struct scsi_address *ap, int level)
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_bus_reset - reset the SCSI bus
6029a2d88c01674debfd7c2e16c941a97302b739susans * The tran_bus_reset() vector in the scsi_hba_tran structure should be
6029a2d88c01674debfd7c2e16c941a97302b739susans * initialized during the HBA driver's attach(). The vector should point to
6029a2d88c01674debfd7c2e16c941a97302b739susans * an HBA entry point that is to be called when a user initiates a bus reset.
6029a2d88c01674debfd7c2e16c941a97302b739susans * Implementation is hardware specific. If the HBA driver cannot reset the
6029a2d88c01674debfd7c2e16c941a97302b739susans * SCSI bus without affecting the targets, the driver should fail RESET_BUS
6029a2d88c01674debfd7c2e16c941a97302b739susans * or not initialize this vector.
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_instance *instance = ddi_get_soft_state(megasas_state,
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_getcap - get one of a set of SCSA-defined capabilities
6029a2d88c01674debfd7c2e16c941a97302b739susans * The target driver can request the current setting of the capability for a
6029a2d88c01674debfd7c2e16c941a97302b739susans * particular target by setting the whom parameter to nonzero. A whom value of
6029a2d88c01674debfd7c2e16c941a97302b739susans * zero indicates a request for the current setting of the general capability
6029a2d88c01674debfd7c2e16c941a97302b739susans * for the SCSI bus or for adapter hardware. The tran_getcap() should return -1
6029a2d88c01674debfd7c2e16c941a97302b739susans * for undefined capabilities or the current value of the requested capability.
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_getcap(struct scsi_address *ap, char *cap, int whom)
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* we do allow inquiring about capabilities for other targets */
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Limit to 16MB max transfer */
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_DLEVEL2, (CE_NOTE, "Default cap coming 0x%x",
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_setcap - set one of a set of SCSA-defined capabilities
6029a2d88c01674debfd7c2e16c941a97302b739susans * The target driver might request that the new value be set for a particular
6029a2d88c01674debfd7c2e16c941a97302b739susans * target by setting the whom parameter to nonzero. A whom value of zero
6029a2d88c01674debfd7c2e16c941a97302b739susans * means that request is to set the new value for the SCSI bus or for adapter
6029a2d88c01674debfd7c2e16c941a97302b739susans * hardware in general.
6029a2d88c01674debfd7c2e16c941a97302b739susans * The tran_setcap() should return the following values as appropriate:
6029a2d88c01674debfd7c2e16c941a97302b739susans * - -1 for undefined capabilities
6029a2d88c01674debfd7c2e16c941a97302b739susans * - 0 if the HBA driver cannot set the capability to the requested value
6029a2d88c01674debfd7c2e16c941a97302b739susans * - 1 if the HBA driver is able to set the capability to the requested value
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_setcap(struct scsi_address *ap, char *cap, int value, int whom)
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* We don't allow setting capabilities for other targets */
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans * None of these are settable via
6029a2d88c01674debfd7c2e16c941a97302b739susans * the capability interface.
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_destroy_pkt - deallocate scsi_pkt structure
6029a2d88c01674debfd7c2e16c941a97302b739susans * The tran_destroy_pkt() entry point is the HBA driver function that
6029a2d88c01674debfd7c2e16c941a97302b739susans * deallocates scsi_pkt structures. The tran_destroy_pkt() entry point is
6029a2d88c01674debfd7c2e16c941a97302b739susans * called when the target driver calls scsi_destroy_pkt(). The
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_destroy_pkt() entry point must free any DMA resources that have been
6029a2d88c01674debfd7c2e16c941a97302b739susans * allocated for the packet. An implicit DMA synchronization occurs if the
6029a2d88c01674debfd7c2e16c941a97302b739susans * DMA resources are freed and any cached data remains after the completion
6029a2d88c01674debfd7c2e16c941a97302b739susans * of the transfer.
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free the pkt */
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_dmafree - deallocates DMA resources
6029a2d88c01674debfd7c2e16c941a97302b739susans * The tran_dmafree() entry point deallocates DMAQ resources that have been
6029a2d88c01674debfd7c2e16c941a97302b739susans * allocated for a scsi_pkt structure. The tran_dmafree() entry point is
6029a2d88c01674debfd7c2e16c941a97302b739susans * called when the target driver calls scsi_dmafree(). The tran_dmafree() must
6029a2d88c01674debfd7c2e16c941a97302b739susans * free only DMA resources allocated for a scsi_pkt structure, not the
6029a2d88c01674debfd7c2e16c941a97302b739susans * scsi_pkt itself. When DMA resources are freed, a DMA synchronization is
6029a2d88c01674debfd7c2e16c941a97302b739susans * implicitly performed.
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_sync_pkt - synchronize the DMA object allocated
6029a2d88c01674debfd7c2e16c941a97302b739susans * The tran_sync_pkt() entry point synchronizes the DMA object allocated for
6029a2d88c01674debfd7c2e16c941a97302b739susans * the scsi_pkt structure before or after a DMA transfer. The tran_sync_pkt()
6029a2d88c01674debfd7c2e16c941a97302b739susans * entry point is called when the target driver calls scsi_sync_pkt(). If the
6029a2d88c01674debfd7c2e16c941a97302b739susans * data transfer direction is a DMA read from device to memory, tran_sync_pkt()
6029a2d88c01674debfd7c2e16c941a97302b739susans * must synchronize the CPU's view of the data. If the data transfer direction
6029a2d88c01674debfd7c2e16c941a97302b739susans * is a DMA write from memory to device, tran_sync_pkt() must synchronize the
6029a2d88c01674debfd7c2e16c941a97302b739susans * device's view of the data.
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans * following 'ddi_dma_sync()' API call
6029a2d88c01674debfd7c2e16c941a97302b739susans * already called for each I/O in the ISR
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele register struct scsa_cmd *acmd = PKT2CMD(pkt);
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) ddi_dma_sync(acmd->cmd_dmahandle, acmd->cmd_dma_offset,
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_dma_len, (acmd->cmd_flags & CFLAG_DMASEND) ?
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans * megasas_isr(caddr_t)
6029a2d88c01674debfd7c2e16c941a97302b739susans * The Interrupt Service Routine
6029a2d88c01674debfd7c2e16c941a97302b739susans * Collect status for all completed commands and do callback
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufelemegasas_isr(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) ddi_dma_sync(instance->mfi_internal_dma_obj.dma_handle,
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_dma_handle(instance->mfi_internal_dma_obj.dma_handle)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (DDI_INTR_UNCLAIMED);
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_CONT, " producer %x consumer %x ",
6029a2d88c01674debfd7c2e16c941a97302b739susans mlist_add_tail(&cmd->list, &instance->completed_pool_list);
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) ddi_dma_sync(instance->mfi_internal_dma_obj.dma_handle,
6029a2d88c01674debfd7c2e16c941a97302b739susans * Not a high-level interrupt, therefore call the soft level
6029a2d88c01674debfd7c2e16c941a97302b739susans * interrupt explicitly
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans * libraries *
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans * get_mfi_pkt : Get a command from the free pool
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic struct megasas_cmd *
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd = mlist_entry(head->next, struct megasas_cmd, list);
6029a2d88c01674debfd7c2e16c941a97302b739susans * return_mfi_pkt : Return a cmd to free command pool
6029a2d88c01674debfd7c2e16c941a97302b739susansreturn_mfi_pkt(struct megasas_instance *instance, struct megasas_cmd *cmd)
6029a2d88c01674debfd7c2e16c941a97302b739susans * destroy_mfi_frame_pool
6029a2d88c01674debfd7c2e16c941a97302b739susansdestroy_mfi_frame_pool(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans /* return all frames to pool */
6029a2d88c01674debfd7c2e16c941a97302b739susans for (i = 0; i < max_cmd; i++) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China (void) mega_free_dma_obj(instance, cmd->frame_dma_obj);
6029a2d88c01674debfd7c2e16c941a97302b739susans * create_mfi_frame_pool
6029a2d88c01674debfd7c2e16c941a97302b739susanscreate_mfi_frame_pool(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans /* calculated the number of 64byte frames required for SGL */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele tot_frame_size = sgl_sz + MEGAMFI_FRAME_SIZE + SENSE_LENGTH;
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_DLEVEL3, (CE_NOTE, "create_mfi_frame_pool: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "sgl_sz %x tot_frame_size %x", sgl_sz, tot_frame_size));
6029a2d88c01674debfd7c2e16c941a97302b739susans while (i < max_cmd) {
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_dma_obj.dma_attr = megasas_generic_dma_attr;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele cmd->frame_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele cmd->frame_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
6029a2d88c01674debfd7c2e16c941a97302b739susans cookie_cnt = mega_alloc_dma_obj(instance, &cmd->frame_dma_obj);
6029a2d88c01674debfd7c2e16c941a97302b739susans "create_mfi_frame_pool: could not alloc."));
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame = (union megasas_frame *)cmd->frame_dma_obj.buffer;
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: pci_pool_alloc failed \n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans * free_additional_dma_buffer
6029a2d88c01674debfd7c2e16c941a97302b739susansfree_additional_dma_buffer(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->mfi_internal_dma_obj.status == DMA_OBJ_ALLOCATED) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China (void) mega_free_dma_obj(instance,
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China instance->mfi_internal_dma_obj);
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.status = DMA_OBJ_FREED;
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->mfi_evt_detail_obj.status == DMA_OBJ_ALLOCATED) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China (void) mega_free_dma_obj(instance,
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China instance->mfi_evt_detail_obj);
6029a2d88c01674debfd7c2e16c941a97302b739susans * alloc_additional_dma_buffer
6029a2d88c01674debfd7c2e16c941a97302b739susansalloc_additional_dma_buffer(struct megasas_instance *instance)
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele /* max cmds plus 1 + producer & consumer */
6029a2d88c01674debfd7c2e16c941a97302b739susans reply_q_sz = sizeof (uint32_t) * (instance->max_fw_cmds + 1 + 2);
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.size = internal_buf_size;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.dma_attr = megasas_generic_dma_attr;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele instance->mfi_internal_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele instance->mfi_internal_dma_obj.dma_attr.dma_attr_count_max =
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.dma_attr.dma_attr_sgllen = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans if (mega_alloc_dma_obj(instance, &instance->mfi_internal_dma_obj)
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "megaraid: could not alloc reply Q"));
6029a2d88c01674debfd7c2e16c941a97302b739susans bzero(instance->mfi_internal_dma_obj.buffer, internal_buf_size);
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.status |= DMA_OBJ_ALLOCATED;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele instance->producer = (uint32_t *)((unsigned long)
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.buffer) + reply_q_sz + 8);
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address +
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate evt_detail */
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_evt_detail_obj.size = sizeof (struct megasas_evt_detail);
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_evt_detail_obj.dma_attr = megasas_generic_dma_attr;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele instance->mfi_evt_detail_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele instance->mfi_evt_detail_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_evt_detail_obj.dma_attr.dma_attr_sgllen = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_evt_detail_obj.dma_attr.dma_attr_align = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans if (mega_alloc_dma_obj(instance, &instance->mfi_evt_detail_obj) != 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "alloc_additional_dma_buffer: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "could not data transfer buffer alloc."));
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_evt_detail));
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_evt_detail_obj.status |= DMA_OBJ_ALLOCATED;
6029a2d88c01674debfd7c2e16c941a97302b739susans * free_space_for_mfi
6029a2d88c01674debfd7c2e16c941a97302b739susans /* already freed */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* first free the MFI frame pool */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free all the commands in the cmd_list */
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_cmd));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free the cmd_list buffer itself */
6029a2d88c01674debfd7c2e16c941a97302b739susans * alloc_space_for_mfi
6029a2d88c01674debfd7c2e16c941a97302b739susansalloc_space_for_mfi(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans * instance->cmd_list is an array of struct megasas_cmd pointers.
6029a2d88c01674debfd7c2e16c941a97302b739susans * Allocate the dynamic array first and then allocate individual
6029a2d88c01674debfd7c2e16c941a97302b739susans * commands.
6029a2d88c01674debfd7c2e16c941a97302b739susans for (i = 0; i < max_cmd; i++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->cmd_list[i] = kmem_zalloc(sizeof (struct megasas_cmd),
6029a2d88c01674debfd7c2e16c941a97302b739susans /* add all the commands to command pool (instance->cmd_pool) */
6029a2d88c01674debfd7c2e16c941a97302b739susans for (i = 0; i < max_cmd; i++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans mlist_add_tail(&cmd->list, &instance->cmd_pool_list);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* create a frame pool and assign one frame to each cmd */
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE, "error creating frame DMA pool\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* create a frame pool and assign one frame to each cmd */
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE, "error creating frame DMA pool\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans * get_ctrl_info
6029a2d88c01674debfd7c2e16c941a97302b739susans "Failed to get a cmd for ctrl info\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans ci = (struct megasas_ctrl_info *)instance->internal_buf;
6029a2d88c01674debfd7c2e16c941a97302b739susans "Failed to alloc mem for ctrl info\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memset(ci, 0, sizeof (struct megasas_ctrl_info));
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele /* for( i = 0; i < DCMD_MBOX_SZ; i++ ) dcmd->mbox.b[i] = 0; */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele (void) memset(dcmd->mbox.b, 0, DCMD_MBOX_SZ);
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele dcmd->cmd_status = MFI_CMD_STATUS_POLL_MODE;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->data_xfer_len = sizeof (struct megasas_ctrl_info);
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->sgl.sge32[0].phys_addr = instance->internal_buf_dmac_add;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->sgl.sge32[0].length = sizeof (struct megasas_ctrl_info);
6029a2d88c01674debfd7c2e16c941a97302b739susans if (!instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memcpy(ctrl_info, ci, sizeof (struct megasas_ctrl_info));
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "get_ctrl_info: Ctrl info failed\n"));
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_common_check(instance, cmd) != DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans * abort_aen_cmd
6029a2d88c01674debfd7c2e16c941a97302b739susans "Failed to get a cmd for ctrl info\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* prepare and issue the abort frame */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele abort_fr->cmd_status = MFI_CMD_STATUS_SYNC_MODE;
6029a2d88c01674debfd7c2e16c941a97302b739susans abort_fr->abort_mfi_phys_addr_lo = cmd_to_abort->frame_phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "abort_aen_cmd: issue_cmd_in_sync_mode failed\n"));
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China (void) megasas_common_check(instance, cmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans if ((ddi_dev_regsize(instance->dip, REGISTER_SET_IO, ®length)
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele != DDI_SUCCESS) || reglength < MINIMUM_MFI_MEM_SZ) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "mega: register length to map is 0x%lx bytes", reglength));
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_regs_map_setup(instance->dip, REGISTER_SET_IO,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megaraid: couldn't map control registers"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* we expect the FW state to be READY */
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "megaraid: F/W is not ready"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* get various operational parameters from status register */
6029a2d88c01674debfd7c2e16c941a97302b739susans * Reduce the max supported cmds by 1. This is to ensure that the
6029a2d88c01674debfd7c2e16c941a97302b739susans * reply_q_sz (1 more than the max cmd that driver may send)
6029a2d88c01674debfd7c2e16c941a97302b739susans * does not exceed max cmds that the FW can support
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->read_fw_status_reg(instance) & 0xFFFF;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* create a pool of commands */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* disable interrupt for initial preparation */
6029a2d88c01674debfd7c2e16c941a97302b739susans * Prepare a init frame. Note the init frame points to queue info
6029a2d88c01674debfd7c2e16c941a97302b739susans * structure. Each frame has SGL allocated after first 64 bytes. For
6029a2d88c01674debfd7c2e16c941a97302b739susans * this frame - since we don't need any SGL - we use SGL's space as
6029a2d88c01674debfd7c2e16c941a97302b739susans * queue info structure
6029a2d88c01674debfd7c2e16c941a97302b739susans init_frame = (struct megasas_init_frame *)cmd->frame;
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memset(initq_info, 0, sizeof (struct megasas_init_queue_info));
6029a2d88c01674debfd7c2e16c941a97302b739susans initq_info->reply_queue_entries = instance->max_fw_cmds + 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address + 4;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address + 8;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele init_frame->cmd_status = MFI_CMD_STATUS_POLL_MODE;
6029a2d88c01674debfd7c2e16c941a97302b739susans init_frame->data_xfer_len = sizeof (struct megasas_init_queue_info);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* issue the init frame in polled mode */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "failed to init firmware"));
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_common_check(instance, cmd) != DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans /* gather misc FW related information */
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->max_sectors_per_req = ctrl_info.max_request_size;
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "product name %s ld present %d",
6029a2d88c01674debfd7c2e16c941a97302b739susans ctrl_info.product_name, ctrl_info.ld_present_count));
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->max_sectors_per_req = instance->max_num_sge *
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans * mfi_state_transition_to_ready : Move the FW to READY state
6029a2d88c01674debfd7c2e16c941a97302b739susans * @reg_set : MFI register set
6029a2d88c01674debfd7c2e16c941a97302b739susansmfi_state_transition_to_ready(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->read_fw_status_reg(instance) & MFI_STATE_MASK;
6029a2d88c01674debfd7c2e16c941a97302b739susans "mfi_state_transition_to_ready:FW state = 0x%x", fw_state));
6029a2d88c01674debfd7c2e16c941a97302b739susans "mfi_state_transition_to_ready:FW state%x", fw_state));
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: FW in FAULT state!!"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* set the CLR bit in IMR0 */
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: FW waiting for HANDSHAKE"));
6029a2d88c01674debfd7c2e16c941a97302b739susans * PCI_Hot Plug: MFI F/W requires
6029a2d88c01674debfd7c2e16c941a97302b739susans * (MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG)
6029a2d88c01674debfd7c2e16c941a97302b739susans * to be set
6029a2d88c01674debfd7c2e16c941a97302b739susans /* WR_IB_MSG_0(MFI_INIT_CLEAR_HANDSHAKE, instance); */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* set the CLR bit in IMR0 */
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: FW state boot message pending"));
6029a2d88c01674debfd7c2e16c941a97302b739susans * PCI_Hot Plug: MFI F/W requires
6029a2d88c01674debfd7c2e16c941a97302b739susans * (MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG)
6029a2d88c01674debfd7c2e16c941a97302b739susans * to be set
6029a2d88c01674debfd7c2e16c941a97302b739susans /* bring it to READY state; assuming max wait 2 secs */
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: FW in OPERATIONAL state"));
6029a2d88c01674debfd7c2e16c941a97302b739susans * PCI_Hot Plug: MFI F/W requires
6029a2d88c01674debfd7c2e16c941a97302b739susans * (MFI_INIT_READY | MFI_INIT_MFIMODE | MFI_INIT_ABORT)
6029a2d88c01674debfd7c2e16c941a97302b739susans * to be set
6029a2d88c01674debfd7c2e16c941a97302b739susans /* WR_IB_DOORBELL(MFI_INIT_READY, instance); */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* this state should not last for more than 2 seconds */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* the cur_state should not last for more than max_wait secs */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele for (i = 0; i < (max_wait * MILLISEC); i++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans /* fw_state = RD_OB_MSG_0(instance) & MFI_STATE_MASK; */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* return error if fw_state hasn't changed after max_wait */
6029a2d88c01674debfd7c2e16c941a97302b739susans "mfi_state_transition_to_ready:FW ctrl = 0x%x", fw_ctrl));
6029a2d88c01674debfd7c2e16c941a97302b739susans * Write 0xF to the doorbell register to do the following.
6029a2d88c01674debfd7c2e16c941a97302b739susans * - Abort all outstanding commands (bit 0).
6029a2d88c01674debfd7c2e16c941a97302b739susans * - Transition from OPERATIONAL to READY state (bit 1).
6029a2d88c01674debfd7c2e16c941a97302b739susans * - Discard (possible) low MFA posted in 64-bit mode (bit-2).
6029a2d88c01674debfd7c2e16c941a97302b739susans * - Set to release FW to continue running (i.e. BIOS handshake
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans * get_seq_num
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate the data transfer buffer */
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd_dma_obj.size = sizeof (struct megasas_evt_log_info);
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele dcmd_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele dcmd_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
6029a2d88c01674debfd7c2e16c941a97302b739susans if (mega_alloc_dma_obj(instance, &dcmd_dma_obj) != 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "get_seq_num: could not data transfer buffer alloc."));
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_evt_log_info));
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele (void) memset(dcmd->mbox.b, 0, DCMD_MBOX_SZ);
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->data_xfer_len = sizeof (struct megasas_evt_log_info);
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->sgl.sge32[0].length = sizeof (struct megasas_evt_log_info);
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->sgl.sge32[0].phys_addr = dcmd_dma_obj.dma_cookie[0].dmac_address;
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "failed to issue MR_DCMD_CTRL_EVENT_GET_INFO\n");
6029a2d88c01674debfd7c2e16c941a97302b739susans /* copy the data back into callers buffer */
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_evt_log_info));
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (mega_free_dma_obj(instance, dcmd_dma_obj) != DDI_SUCCESS)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_common_check(instance, cmd) != DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans * start_mfi_aen
6029a2d88c01674debfd7c2e16c941a97302b739susans /* get the latest sequence number from FW */
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memset(&eli, 0, sizeof (struct megasas_evt_log_info));
6029a2d88c01674debfd7c2e16c941a97302b739susans cmn_err(CE_WARN, "start_mfi_aen: failed to get seq num\n");
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* register AEN with FW for latest sequence number plus 1 */
6029a2d88c01674debfd7c2e16c941a97302b739susans ret = register_mfi_aen(instance, eli.newest_seq_num + 1,
6029a2d88c01674debfd7c2e16c941a97302b739susans cmn_err(CE_WARN, "start_mfi_aen: aen registration failed\n");
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans * flush_cache
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele (void) memset(dcmd->mbox.b, 0, DCMD_MBOX_SZ);
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "flush_cache: failed to issue MFI_DCMD_CTRL_CACHE_FLUSH\n");
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China (void) megasas_common_check(instance, cmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans * service_mfi_aen- Completes an AEN command
6029a2d88c01674debfd7c2e16c941a97302b739susans * @instance: Adapter soft state
6029a2d88c01674debfd7c2e16c941a97302b739susans * @cmd: Command to be completed
6029a2d88c01674debfd7c2e16c941a97302b739susansservice_mfi_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
6029a2d88c01674debfd7c2e16c941a97302b739susans (struct megasas_evt_detail *)instance->mfi_evt_detail_obj.buffer;
6029a2d88c01674debfd7c2e16c941a97302b739susans * log the MFI AEN event to the sysevent queue so that
6029a2d88c01674debfd7c2e16c941a97302b739susans * application will get noticed
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_log_sysevent(instance->dip, DDI_VENDOR_LSI, "LSIMEGA", "SAS",
6029a2d88c01674debfd7c2e16c941a97302b739susans /* get copy of seq_num and class/locale for re-registration */
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memset(instance->mfi_evt_detail_obj.buffer, 0,
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_evt_detail));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Issue the aen registration frame */
6029a2d88c01674debfd7c2e16c941a97302b739susans * complete_cmd_in_sync_mode - Completes an internal command
6029a2d88c01674debfd7c2e16c941a97302b739susans * @instance: Adapter soft state
6029a2d88c01674debfd7c2e16c941a97302b739susans * @cmd: Command to be completed
6029a2d88c01674debfd7c2e16c941a97302b739susans * The issue_cmd_in_sync_mode() function waits for a command to complete
6029a2d88c01674debfd7c2e16c941a97302b739susans * after it issues a command. This function wakes up that waiting routine by
6029a2d88c01674debfd7c2e16c941a97302b739susans * calling wake_up() on the wait queue.
6029a2d88c01674debfd7c2e16c941a97302b739susanscomplete_cmd_in_sync_mode(struct megasas_instance *instance,
6029a2d88c01674debfd7c2e16c941a97302b739susans * megasas_softintr - The Software ISR
6029a2d88c01674debfd7c2e16c941a97302b739susans * @param arg : HBA soft state
6029a2d88c01674debfd7c2e16c941a97302b739susans * called from high-level interrupt if hi-level interrupt are not there,
6029a2d88c01674debfd7c2e16c941a97302b739susans * otherwise triggered as a soft interrupt
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufelemegasas_softintr(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_CONT, "megasas_softintr called"));
6029a2d88c01674debfd7c2e16c941a97302b739susans mlist_splice(&instance->completed_pool_list, &process_list);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* perform all callbacks first, before releasing the SCBs */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* syncronize the Cmd frame for the controller */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_dma_handle(cmd->frame_dma_obj.dma_handle) !=
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (DDI_INTR_UNCLAIMED);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* remove the internal command from the process list */
6029a2d88c01674debfd7c2e16c941a97302b739susans * MFI_CMD_OP_PD_SCSI and MFI_CMD_OP_LD_SCSI
6029a2d88c01674debfd7c2e16c941a97302b739susans * could have been issued either through an
6029a2d88c01674debfd7c2e16c941a97302b739susans * IO path or an IOCTL path. If it was via IOCTL,
6029a2d88c01674debfd7c2e16c941a97302b739susans * we will send it to internal completion.
6029a2d88c01674debfd7c2e16c941a97302b739susans /* regular commands */
6029a2d88c01674debfd7c2e16c941a97302b739susans "CDB[0] = %x completed for %s: size %lx context %x",
6029a2d88c01674debfd7c2e16c941a97302b739susans /* don't expose physical drives to OS */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* for physical disk */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ - these are not correct way */
6029a2d88c01674debfd7c2e16c941a97302b739susans "device not found error"));
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw * LOGICAL BLOCK ADDRESS OUT OF RANGE:
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw * ASC: 0x21h; ASCQ: 0x00h;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China (void) megasas_common_check(instance, cmd);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (acmd->cmd_dmahandle) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_dma_handle(
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China acmd->cmd_dmahandle) != DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip,
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China DDI_SERVICE_UNAFFECTED);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China pkt->pkt_reason = CMD_TRAN_ERR;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China pkt->pkt_statistics = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Call the callback routine */
9c57abc8d70cb139020be846baec0a9c4d9a73cdsrivijitha dugganapalli if ((pkt->pkt_flags & FLAG_NOINTR) == 0) {
6029a2d88c01674debfd7c2e16c941a97302b739susans /* see if got an event notification */
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas_softintr: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "aborted_aen returned"));
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "MFI_CMD_OP_ABORT complete"));
6029a2d88c01674debfd7c2e16c941a97302b739susans * MFI_CMD_OP_ABORT successfully completed
6029a2d88c01674debfd7c2e16c941a97302b739susans * in the synchronous mode
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (cmd->pkt != NULL) {
9c57abc8d70cb139020be846baec0a9c4d9a73cdsrivijitha dugganapalli if ((pkt->pkt_flags & FLAG_NOINTR) == 0) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China con_log(CL_ANN, (CE_WARN, "Cmd type unknown !!"));
6029a2d88c01674debfd7c2e16c941a97302b739susans * mega_alloc_dma_obj
6029a2d88c01674debfd7c2e16c941a97302b739susans * Allocate the memory and other resources for an dma object.
6029a2d88c01674debfd7c2e16c941a97302b739susansmega_alloc_dma_obj(struct megasas_instance *instance, dma_obj_t *obj)
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson tmp_endian_attr.devacc_attr_access = DDI_DEFAULT_ACC;
6029a2d88c01674debfd7c2e16c941a97302b739susans i = ddi_dma_alloc_handle(instance->dip, &obj->dma_attr,
6029a2d88c01674debfd7c2e16c941a97302b739susans switch (i) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "Failed ddi_dma_alloc_handle- Bad atrib"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "Failed ddi_dma_alloc_handle- No Resources"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "Failed ddi_dma_alloc_handle :unknown %d", i));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson if ((ddi_dma_mem_alloc(obj->dma_handle, obj->size, &tmp_endian_attr,
6029a2d88c01674debfd7c2e16c941a97302b739susans DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL,
6029a2d88c01674debfd7c2e16c941a97302b739susans &obj->buffer, &alen, &obj->acc_handle) != DDI_SUCCESS) ||
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "Failed : ddi_dma_mem_alloc"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_dma_addr_bind_handle(obj->dma_handle, NULL, obj->buffer,
6029a2d88c01674debfd7c2e16c941a97302b739susans obj->size, DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_SLEEP,
6029a2d88c01674debfd7c2e16c941a97302b739susans NULL, &obj->dma_cookie[0], &cookie_cnt) != DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "Failed : ddi_dma_addr_bind_handle"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_dma_handle(obj->dma_handle) != DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_acc_handle(obj->acc_handle) != DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * mega_free_dma_obj(struct megasas_instance *, dma_obj_t)
6029a2d88c01674debfd7c2e16c941a97302b739susans * De-allocate the memory and other resources for an dma object, which must
6029a2d88c01674debfd7c2e16c941a97302b739susans * have been alloated by a previous call to mega_alloc_dma_obj()
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinamega_free_dma_obj(struct megasas_instance *instance, dma_obj_t obj)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_dma_handle(obj.dma_handle) != DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (DDI_FAILURE);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_acc_handle(obj.acc_handle) != DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (DDI_FAILURE);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (DDI_SUCCESS);
6029a2d88c01674debfd7c2e16c941a97302b739susans * megasas_dma_alloc(instance_t *, struct scsi_pkt *, struct buf *,
6029a2d88c01674debfd7c2e16c941a97302b739susans * int, int (*)())
6029a2d88c01674debfd7c2e16c941a97302b739susans * Allocate dma resources for a new scsi command
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_dma_alloc(struct megasas_instance *instance, struct scsi_pkt *pkt,
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_dma_attr_t tmp_dma_attr = megasas_generic_dma_attr;
6029a2d88c01674debfd7c2e16c941a97302b739susans cb = (callback == NULL_FUNC) ? DDI_DMA_DONTWAIT : DDI_DMA_SLEEP;
6029a2d88c01674debfd7c2e16c941a97302b739susans tmp_dma_attr.dma_attr_sgllen = instance->max_num_sge;
03b14217e5b4702d6fc4b2ef4ece78b0cc99fc31Yu Wu - Sun Microsystems - Beijing China tmp_dma_attr.dma_attr_addr_hi = 0xffffffffffffffffull;
6029a2d88c01674debfd7c2e16c941a97302b739susans if ((i = ddi_dma_alloc_handle(instance->dip, &tmp_dma_attr,
6029a2d88c01674debfd7c2e16c941a97302b739susans switch (i) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans "0x%x impossible\n", i));
6029a2d88c01674debfd7c2e16c941a97302b739susans i = ddi_dma_buf_bind_handle(acmd->cmd_dmahandle, bp, dma_flags,
6029a2d88c01674debfd7c2e16c941a97302b739susans cb, 0, &acmd->cmd_dmacookies[0], &acmd->cmd_ncookies);
6029a2d88c01674debfd7c2e16c941a97302b739susans switch (i) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_PANIC, "ddi_dma_buf_bind_handle: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "DDI_DMA_PARTIAL_MAP impossible\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_dma_numwin(acmd->cmd_dmahandle, &acmd->cmd_nwin) ==
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_PANIC, "ddi_dma_numwin failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_dma_getwin(acmd->cmd_dmahandle, acmd->cmd_curwin,
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_PANIC, "ddi_dma_getwin failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_PANIC, "ddi_dma_buf_bind_handle:"
6029a2d88c01674debfd7c2e16c941a97302b739susans " DDI_DMA_INUSE impossible\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_PANIC, "ddi_dma_buf_bind_handle: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "0x%x impossible\n", i));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans * megasas_dma_move(struct megasas_instance *, struct scsi_pkt *, struct buf *)
6029a2d88c01674debfd7c2e16c941a97302b739susans * move dma resources to next dma window
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_dma_move(struct megasas_instance *instance, struct scsi_pkt *pkt,
6029a2d88c01674debfd7c2e16c941a97302b739susans * If there are no more cookies remaining in this window,
6029a2d88c01674debfd7c2e16c941a97302b739susans * must move to the next window first.
6029a2d88c01674debfd7c2e16c941a97302b739susans if (acmd->cmd_curwin == acmd->cmd_nwin && acmd->cmd_nwin == 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* at last window, cannot move */
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_dma_getwin(acmd->cmd_dmahandle, acmd->cmd_curwin,
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* still more cookies in this window - get the next one */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* get remaining cookies in this window, up to our maximum */
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_dmacount += acmd->cmd_dmacookies[i++].dmac_size;
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans * build_cmd
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic struct megasas_cmd *
6029a2d88c01674debfd7c2e16c941a97302b739susansbuild_cmd(struct megasas_instance *instance, struct scsi_address *ap,
03b14217e5b4702d6fc4b2ef4ece78b0cc99fc31Yu Wu - Sun Microsystems - Beijing China struct megasas_sge64 *mfi_sgl;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* find out if this is logical or physical drive command. */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* get the command packet */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* lets get the command directions */
03b14217e5b4702d6fc4b2ef4ece78b0cc99fc31Yu Wu - Sun Microsystems - Beijing China flags |= MFI_FRAME_SGL64;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw * case SCMD_SYNCHRONIZE_CACHE:
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw * flush_cache(instance);
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw * return_mfi_pkt(instance, cmd);
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw * *cmd_done = 1;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw * return (NULL);
6029a2d88c01674debfd7c2e16c941a97302b739susans * preare the Logical IO frame:
6029a2d88c01674debfd7c2e16c941a97302b739susans * 2nd bit is zero for all read cmds
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw /* Initialize sense Information */
03b14217e5b4702d6fc4b2ef4ece78b0cc99fc31Yu Wu - Sun Microsystems - Beijing China mfi_sgl = (struct megasas_sge64 *)&ldio->sgl;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* fall through For all non-rd/wr cmds */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* prepare the DCDB frame */
03b14217e5b4702d6fc4b2ef4ece78b0cc99fc31Yu Wu - Sun Microsystems - Beijing China mfi_sgl = (struct megasas_sge64 *)&pthru->sgl;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* bzero(mfi_sgl, sizeof (struct megasas_sge64) * MAX_SGL); */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* prepare the scatter-gather list for the firmware */
6029a2d88c01674debfd7c2e16c941a97302b739susans for (i = 0; i < acmd->cmd_cookiecnt; i++, mfi_sgl++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans mfi_sgl->phys_addr = acmd->cmd_dmacookies[i].dmac_laddress;
03b14217e5b4702d6fc4b2ef4ece78b0cc99fc31Yu Wu - Sun Microsystems - Beijing China sge_bytes = sizeof (struct megasas_sge64)*acmd->cmd_cookiecnt;
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) +
6029a2d88c01674debfd7c2e16c941a97302b739susans * wait_for_outstanding - Wait for all outstanding cmds
6029a2d88c01674debfd7c2e16c941a97302b739susans * @instance: Adapter soft state
6029a2d88c01674debfd7c2e16c941a97302b739susans * This function waits for upto MEGASAS_RESET_WAIT_TIME seconds for FW to
6029a2d88c01674debfd7c2e16c941a97302b739susans * complete all its outstanding commands. Returns error if one or more IOs
6029a2d88c01674debfd7c2e16c941a97302b739susans * are pending after this time period.
6029a2d88c01674debfd7c2e16c941a97302b739susanswait_for_outstanding(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans for (i = 0; i < wait_time; i++) {
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele drv_usecwait(MILLISEC); /* wait for 1000 usecs */;
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_acc_err_clear(instance->regmap_handle, DDI_FME_VERSION);
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans * issue_mfi_pthru
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_mfi_pthru(struct megasas_instance *instance, struct megasas_ioctl *ioctl,
6029a2d88c01674debfd7c2e16c941a97302b739susans kpthru = (struct megasas_pthru_frame *)&ioctl->frame[0];
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_pthru: DDI_MODEL_LP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans ubuf = (void *)(ulong_t)kpthru->sgl.sge32[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_pthru: DDI_MODEL_LP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans ubuf = (void *)(ulong_t)kpthru->sgl.sge32[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_pthru: DDI_MODEL_LP64"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans ubuf = (void *)(ulong_t)kpthru->sgl.sge64[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* means IOCTL requires DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate the data transfer buffer */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele pthru_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele pthru_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate kernel buffer for DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (mega_alloc_dma_obj(instance, &pthru_dma_obj) != 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "could not data transfer buffer alloc."));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy from user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans kphys_addr = pthru_dma_obj.dma_cookie[0].dmac_address;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr; */
6029a2d88c01674debfd7c2e16c941a97302b739susans bcopy((void *)kpthru->cdb, (void *)pthru->cdb, pthru->cdb_len);
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "issue_mfi_pthru: fw_ioctl failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans if (xferlen && (kpthru->flags & MFI_FRAME_DIR_READ)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy to user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE, "issue_mfi_pthru: cmd_status %x, "
6029a2d88c01674debfd7c2e16c941a97302b739susans "scsi_status %x\n", pthru->cmd_status, pthru->scsi_status));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free kernel buffer */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (mega_free_dma_obj(instance, pthru_dma_obj) != DDI_SUCCESS)
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans * issue_mfi_dcmd
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_mfi_dcmd(struct megasas_instance *instance, struct megasas_ioctl *ioctl,
6029a2d88c01674debfd7c2e16c941a97302b739susans kdcmd = (struct megasas_dcmd_frame *)&ioctl->frame[0];
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_dcmd: DDI_MODEL_ILP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_dcmd: DDI_MODEL_ILP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_dcmd: DDI_MODEL_LP64"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans ubuf = (void *)(ulong_t)dcmd->sgl.sge64[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* means IOCTL requires DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate the data transfer buffer */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele dcmd_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele dcmd_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate kernel buffer for DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (mega_alloc_dma_obj(instance, &dcmd_dma_obj) != 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "could not data transfer buffer alloc."));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy from user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans kphys_addr = dcmd_dma_obj.dma_cookie[0].dmac_address;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele bcopy((void *)kdcmd->mbox.b, (void *)dcmd->mbox.b, DCMD_MBOX_SZ);
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "issue_mfi_dcmd: fw_ioctl failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans if (xferlen && (kdcmd->flags & MFI_FRAME_DIR_READ)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy to user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free kernel buffer */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (mega_free_dma_obj(instance, dcmd_dma_obj) != DDI_SUCCESS)
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans * issue_mfi_smp
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_mfi_smp(struct megasas_instance *instance, struct megasas_ioctl *ioctl,
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: DDI_MODEL_ILP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "response_xferlen = %x, request_xferlen = %x",
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans "response_ubuf = %p, request_ubuf = %p",
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: DDI_MODEL_ILP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "response_xferlen = %x, request_xferlen = %x",
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans "response_ubuf = %p, request_ubuf = %p",
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: DDI_MODEL_LP64"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* means IOCTL requires DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate the data transfer buffer */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele request_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele request_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate kernel buffer for DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (mega_alloc_dma_obj(instance, &request_dma_obj) != 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "could not data transfer buffer alloc."));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyin(request_ubuf, (void *) request_dma_obj.buffer,
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy from user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* means IOCTL requires DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate the data transfer buffer */
6029a2d88c01674debfd7c2e16c941a97302b739susans response_dma_obj.dma_attr = megasas_generic_dma_attr;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele response_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele response_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate kernel buffer for DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (mega_alloc_dma_obj(instance, &response_dma_obj) != 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "could not data transfer buffer alloc."));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyin(response_ubuf, (void *) response_dma_obj.buffer,
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy from user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* smp->context = ksmp->context; */
6029a2d88c01674debfd7c2e16c941a97302b739susans bcopy((void *)&ksmp->sas_addr, (void *)&smp->sas_addr,
6029a2d88c01674debfd7c2e16c941a97302b739susans "handle_drv_ioctl: DDI_MODEL_ILP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "handle_drv_ioctl: DDI_MODEL_ILP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "issue_mfi_smp: DDI_MODEL_LP64"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "smp->response_xferlen = %d, smp->request_xferlen = %d "
6029a2d88c01674debfd7c2e16c941a97302b739susans "smp->data_xfer_len = %d", sge32[0].length, sge32[1].length,
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "issue_mfi_smp: fw_ioctl failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "issue_mfi_smp: copy to user space\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyout(request_dma_obj.buffer, request_ubuf,
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy to user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyout(response_dma_obj.buffer, response_ubuf,
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy to user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: smp->cmd_status = %d",
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free kernel buffer */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (mega_free_dma_obj(instance, request_dma_obj) != DDI_SUCCESS)
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free kernel buffer */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (mega_free_dma_obj(instance, response_dma_obj) !=
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans * issue_mfi_stp
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_mfi_stp(struct megasas_instance *instance, struct megasas_ioctl *ioctl,
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_stp: DDI_MODEL_ILP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans fis_ubuf = (void *)(ulong_t)kstp->sgl.sge32[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans data_ubuf = (void *)(ulong_t)kstp->sgl.sge32[1].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_stp: DDI_MODEL_ILP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans fis_ubuf = (void *)(ulong_t)kstp->sgl.sge32[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans data_ubuf = (void *)(ulong_t)kstp->sgl.sge32[1].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_stp: DDI_MODEL_LP64"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans fis_ubuf = (void *)(ulong_t)kstp->sgl.sge64[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans data_ubuf = (void *)(ulong_t)kstp->sgl.sge64[1].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans "fis_ubuf = %p fis_xferlen = %x", fis_ubuf, fis_xferlen));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* means IOCTL requires DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate the data transfer buffer */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele fis_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele fis_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate kernel buffer for DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (mega_alloc_dma_obj(instance, &fis_dma_obj) != 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "could not data transfer buffer alloc."));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy from user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE, "issue_mfi_stp: data_ubuf = %p "
6029a2d88c01674debfd7c2e16c941a97302b739susans /* means IOCTL requires DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate the data transfer buffer */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele data_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele data_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate kernel buffer for DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (mega_alloc_dma_obj(instance, &data_dma_obj) != 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "could not data transfer buffer alloc."));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyin(data_ubuf, (void *) data_dma_obj.buffer,
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy from user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* stp->context = kstp->context; */
6029a2d88c01674debfd7c2e16c941a97302b739susans stp->sgl.sge32[0].phys_addr = fis_dma_obj.dma_cookie[0].dmac_address;
6029a2d88c01674debfd7c2e16c941a97302b739susans stp->sgl.sge32[1].phys_addr = data_dma_obj.dma_cookie[0].dmac_address;
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: fw_ioctl failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy to user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy to user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free kernel buffer */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (mega_free_dma_obj(instance, fis_dma_obj) != DDI_SUCCESS)
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free kernel buffer */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (mega_free_dma_obj(instance, data_dma_obj) != DDI_SUCCESS)
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans * fill_up_drv_ver
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memset(dv, 0, sizeof (struct megasas_drv_ver));
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memcpy(dv->signature, "$LSI LOGIC$", strlen("$LSI LOGIC$"));
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memcpy(dv->os_name, "Solaris", strlen("Solaris"));
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memcpy(dv->drv_name, "megaraid_sas", strlen("megaraid_sas"));
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memcpy(dv->drv_ver, MEGASAS_VERSION, strlen(MEGASAS_VERSION));
6029a2d88c01674debfd7c2e16c941a97302b739susans * handle_drv_ioctl
6029a2d88c01674debfd7c2e16c941a97302b739susanshandle_drv_ioctl(struct megasas_instance *instance, struct megasas_ioctl *ioctl,
6029a2d88c01674debfd7c2e16c941a97302b739susans kdcmd = (struct megasas_dcmd_frame *)&ioctl->frame[0];
6029a2d88c01674debfd7c2e16c941a97302b739susans "handle_drv_ioctl: DDI_MODEL_ILP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans "handle_drv_ioctl: DDI_MODEL_ILP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans "handle_drv_ioctl: DDI_MODEL_LP64"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans ubuf = (void *)(ulong_t)kdcmd->sgl.sge64[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans "MR_DRIVER_IOCTL_DRIVER_VERSION"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "MR_DRIVER_IOCTL_DRIVER_VERSION : "
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy to user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "MR_DRIVER_IOCTL_PCI_INFORMAITON"));
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, instance->dip,
6029a2d88c01674debfd7c2e16c941a97302b739susans "MR_DRIVER_IOCTL_PCI_INFORMATION : "
6029a2d88c01674debfd7c2e16c941a97302b739susans "ddi_prop_look_int_array failed\n"));
2fbba054b269361b33411621fca09b77f0b7a30fyd for (i = 0; i < (sizeof (struct megasas_pci_information) -
2fbba054b269361b33411621fca09b77f0b7a30fyd offsetof(struct megasas_pci_information, pciHeaderInfo));
6029a2d88c01674debfd7c2e16c941a97302b739susans "MR_DRIVER_IOCTL_PCI_INFORMATION : "
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy to user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "invalid driver specific IOCTL opcode = 0x%x",
6029a2d88c01674debfd7c2e16c941a97302b739susans * handle_mfi_ioctl
6029a2d88c01674debfd7c2e16c941a97302b739susanshandle_mfi_ioctl(struct megasas_instance *instance, struct megasas_ioctl *ioctl,
6029a2d88c01674debfd7c2e16c941a97302b739susans "failed to get a cmd packet\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_common_check(instance, cmd) != DDI_SUCCESS)
6029a2d88c01674debfd7c2e16c941a97302b739susanshandle_mfi_aen(struct megasas_instance *instance, struct megasas_aen *aen)
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = register_mfi_aen(instance, instance->aen_seq_num,
6029a2d88c01674debfd7c2e16c941a97302b739susansregister_mfi_aen(struct megasas_instance *instance, uint32_t seq_num,
6029a2d88c01674debfd7c2e16c941a97302b739susans * If there an AEN pending already (aen_cmd), check if the
6029a2d88c01674debfd7c2e16c941a97302b739susans * class_locale of that pending AEN is inclusive of the new
6029a2d88c01674debfd7c2e16c941a97302b739susans * AEN request we currently have. If it is, then we don't have
6029a2d88c01674debfd7c2e16c941a97302b739susans * to do anything. In other words, whichever events the current
6029a2d88c01674debfd7c2e16c941a97302b739susans * AEN request is subscribing to, have already been subscribed
6029a2d88c01674debfd7c2e16c941a97302b739susans * If the old_cmd is _not_ inclusive, then we have to abort
6029a2d88c01674debfd7c2e16c941a97302b739susans * that command, form a class_locale that is superset of both
6029a2d88c01674debfd7c2e16c941a97302b739susans * old and current and re-issue to the FW
6029a2d88c01674debfd7c2e16c941a97302b739susans prev_aen.word = instance->aen_cmd->frame->dcmd.mbox.w[1];
6029a2d88c01674debfd7c2e16c941a97302b739susans * A class whose enum value is smaller is inclusive of all
6029a2d88c01674debfd7c2e16c941a97302b739susans * higher values. If a PROGRESS (= -1) was previously
6029a2d88c01674debfd7c2e16c941a97302b739susans * registered, then a new registration requests for higher
6029a2d88c01674debfd7c2e16c941a97302b739susans * classes need not be sent to FW. They are automatically
6029a2d88c01674debfd7c2e16c941a97302b739susans * included.
6029a2d88c01674debfd7c2e16c941a97302b739susans * Locale numbers don't have such hierarchy. They are bitmap
6029a2d88c01674debfd7c2e16c941a97302b739susans if ((prev_aen.members.class <= curr_aen.members.class) &&
6029a2d88c01674debfd7c2e16c941a97302b739susans !((prev_aen.members.locale & curr_aen.members.locale) ^
6029a2d88c01674debfd7c2e16c941a97302b739susans * Previously issued event registration includes
6029a2d88c01674debfd7c2e16c941a97302b739susans * current request. Nothing to do.
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans ret_val = abort_aen_cmd(instance, instance->aen_cmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans "failed to abort prevous AEN command\n"));
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele /* for(i = 0; i < DCMD_MBOX_SZ; i++) dcmd->mbox.b[i] = 0; */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele (void) memset(dcmd->mbox.b, 0, DCMD_MBOX_SZ);
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memset(instance->mfi_evt_detail_obj.buffer, 0,
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_evt_detail));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Prepare DCMD for aen registration */
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->data_xfer_len = sizeof (struct megasas_evt_detail);
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_evt_detail_obj.dma_cookie[0].dmac_address;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->sgl.sge32[0].length = sizeof (struct megasas_evt_detail);
6029a2d88c01674debfd7c2e16c941a97302b739susans * Store reference to the cmd used to register for AEN. When an
6029a2d88c01674debfd7c2e16c941a97302b739susans * application wants us to register for AEN, we have to abort this
6029a2d88c01674debfd7c2e16c941a97302b739susans * cmd and re-register with a new EVENT LOCALE supplied by that app
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Issue the aen registration frame */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* atomic_add_16 (&instance->fw_outstanding, 1); */
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans "Direct-Access ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Sequential-Access",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Printer ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Processor ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Scanner ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Optical Device ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Medium Changer ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Communications ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Unknown ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Unknown ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Unknown ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Enclosure ",
6029a2d88c01674debfd7c2e16c941a97302b739susans len += snprintf(inquiry_buf + len, 265 - len, " Vendor: ");
6029a2d88c01674debfd7c2e16c941a97302b739susans len += snprintf(inquiry_buf + len, 265 - len, " Model: ");
6029a2d88c01674debfd7c2e16c941a97302b739susans len += snprintf(inquiry_buf + len, 265 - len, " Rev: ");
6029a2d88c01674debfd7c2e16c941a97302b739susans len += snprintf(inquiry_buf + len, 265 - len, " Type: %s ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Unknown ");
6029a2d88c01674debfd7c2e16c941a97302b739susans if ((scsi_inq[2] & 0x07) == 1 && (scsi_inq[3] & 0x0f) == 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans len += snprintf(inquiry_buf + len, 265 - len, " CCS\n");
6029a2d88c01674debfd7c2e16c941a97302b739susansread_fw_status_reg_xscale(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susansread_fw_status_reg_ppc(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_cmd_xscale(struct megasas_cmd *cmd, struct megasas_instance *instance)
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_16(&instance->fw_outstanding);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Issue the command to the FW */
6029a2d88c01674debfd7c2e16c941a97302b739susans WR_IB_QPORT((host_to_le32(cmd->frame_phys_addr) >> 3) |
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_cmd_ppc(struct megasas_cmd *cmd, struct megasas_instance *instance)
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_16(&instance->fw_outstanding);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Issue the command to the FW */
6029a2d88c01674debfd7c2e16c941a97302b739susans * issue_cmd_in_sync_mode
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_cmd_in_sync_mode_xscale(struct megasas_instance *instance,
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele uint32_t msecs = MFI_POLL_TIMEOUT_SECS * (10 * MILLISEC);
6029a2d88c01674debfd7c2e16c941a97302b739susans WR_IB_QPORT((host_to_le32(cmd->frame_phys_addr) >> 3) |
6029a2d88c01674debfd7c2e16c941a97302b739susans for (i = 0; i < msecs && (cmd->cmd_status == ENODATA); i++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans cv_wait(&instance->int_cmd_cv, &instance->int_cmd_mtx);
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_cmd_in_sync_mode_ppc(struct megasas_instance *instance,
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele uint32_t msecs = MFI_POLL_TIMEOUT_SECS * (10 * MILLISEC);
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_sync_mode_ppc: called\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans for (i = 0; i < msecs && (cmd->cmd_status == ENODATA); i++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans cv_wait(&instance->int_cmd_cv, &instance->int_cmd_mtx);
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_sync_mode_ppc: done\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans * issue_cmd_in_poll_mode
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_cmd_in_poll_mode_xscale(struct megasas_instance *instance,
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele uint32_t msecs = MFI_POLL_TIMEOUT_SECS * MILLISEC;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele frame_hdr = (struct megasas_header *)cmd->frame;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele frame_hdr->cmd_status = MFI_CMD_STATUS_POLL_MODE;
6029a2d88c01674debfd7c2e16c941a97302b739susans frame_hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* issue the frame using inbound queue port */
6029a2d88c01674debfd7c2e16c941a97302b739susans WR_IB_QPORT((host_to_le32(cmd->frame_phys_addr) >> 3) |
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele /* wait for cmd_status to change from 0xFF */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele for (i = 0; i < msecs && (frame_hdr->cmd_status ==
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele drv_usecwait(MILLISEC); /* wait for 1000 usecs */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele if (frame_hdr->cmd_status == MFI_CMD_STATUS_POLL_MODE) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "cmd polling timed out"));
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_cmd_in_poll_mode_ppc(struct megasas_instance *instance,
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele uint32_t msecs = MFI_POLL_TIMEOUT_SECS * MILLISEC;
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_poll_mode_ppc: called\n"));
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele frame_hdr = (struct megasas_header *)cmd->frame;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele frame_hdr->cmd_status = MFI_CMD_STATUS_POLL_MODE;
6029a2d88c01674debfd7c2e16c941a97302b739susans frame_hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* issue the frame using inbound queue port */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele /* wait for cmd_status to change from 0xFF */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele for (i = 0; i < msecs && (frame_hdr->cmd_status ==
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele drv_usecwait(MILLISEC); /* wait for 1000 usecs */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele if (frame_hdr->cmd_status == MFI_CMD_STATUS_POLL_MODE) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "cmd polling timed out"));
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "enable_intr_ppc: called\n"));
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele /* WR_OB_DOORBELL_CLEAR(0xFFFFFFFF, instance); */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele WR_OB_DOORBELL_CLEAR(OB_DOORBELL_CLEAR_MASK, instance);
ea20edda2274918c047dc10b52891c14f2afb0besusans * As 1078DE is same as 1078 chip, the interrupt mask
ea20edda2274918c047dc10b52891c14f2afb0besusans * remains the same.
6029a2d88c01674debfd7c2e16c941a97302b739susans /* WR_OB_INTR_MASK(~0x80000000, instance); */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele WR_OB_INTR_MASK(~(MFI_REPLY_1078_MESSAGE_INTR), instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* dummy read to force PCI flush */
6029a2d88c01674debfd7c2e16c941a97302b739susansdisable_intr_xscale(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: called\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: before : "
6029a2d88c01674debfd7c2e16c941a97302b739susans "outbound_intr_mask = 0x%x\n", RD_OB_INTR_MASK(instance)));
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele /* WR_OB_INTR_MASK(0xFFFFFFFF, instance); */
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: after : "
6029a2d88c01674debfd7c2e16c941a97302b739susans "outbound_intr_mask = 0x%x\n", RD_OB_INTR_MASK(instance)));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* dummy read to force PCI flush */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* check if it is our interrupt */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* clear the interrupt by writing back the same value */
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "intr_ack_ppc: called\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* check if it is our interrupt */
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "intr_ack_ppc: status = 0x%x\n", status));
ea20edda2274918c047dc10b52891c14f2afb0besusans * As 1078DE is same as 1078 chip, the status field
ea20edda2274918c047dc10b52891c14f2afb0besusans * remains the same.
6029a2d88c01674debfd7c2e16c941a97302b739susans /* clear the interrupt by writing back the same value */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* dummy READ */
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "intr_ack_ppc: interrupt cleared\n"));
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinamegasas_common_check(struct megasas_instance *instance,
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China struct megasas_cmd *cmd)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China int ret = DDI_SUCCESS;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_dma_handle(cmd->frame_dma_obj.dma_handle) !=
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (cmd->pkt != NULL) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China cmd->pkt->pkt_reason = CMD_TRAN_ERR;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China cmd->pkt->pkt_statistics = 0;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_dma_handle(instance->mfi_internal_dma_obj.dma_handle)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (cmd->pkt != NULL) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China cmd->pkt->pkt_reason = CMD_TRAN_ERR;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China cmd->pkt->pkt_statistics = 0;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_dma_handle(instance->mfi_evt_detail_obj.dma_handle) !=
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (cmd->pkt != NULL) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China cmd->pkt->pkt_reason = CMD_TRAN_ERR;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China cmd->pkt->pkt_statistics = 0;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_acc_err_clear(instance->regmap_handle, DDI_FME_VER0);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (cmd->pkt != NULL) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China cmd->pkt->pkt_reason = CMD_TRAN_ERR;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China cmd->pkt->pkt_statistics = 0;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinamegasas_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * as the driver can always deal with an error in any dma or
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * access handle, we can just return the fme_status value.
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China pci_ereport_post(dip, err, NULL);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (err->fme_status);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinamegasas_fm_init(struct megasas_instance *instance)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China /* Need to change iblock to priority for new MSI intr */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_iblock_cookie_t fm_ibc;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China /* Only register with IO Fault Services if we have some capability */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (instance->fm_capabilities) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China /* Adjust access and dma attributes for FMA */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China endian_attr.devacc_attr_access = DDI_FLAGERR_ACC;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_generic_dma_attr.dma_attr_flags = DDI_DMA_FLAGERR;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * Register capabilities with IO Fault Services.
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * fm_capabilities will be updated to indicate
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * capabilities actually supported (not requested.)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_init(instance->dip, &instance->fm_capabilities, &fm_ibc);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * Initialize pci ereport capabilities if ereport
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * capable (should always be.)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (DDI_FM_EREPORT_CAP(instance->fm_capabilities) ||
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China DDI_FM_ERRCB_CAP(instance->fm_capabilities)) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China pci_ereport_setup(instance->dip);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * Register error callback if error callback capable.
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (DDI_FM_ERRCB_CAP(instance->fm_capabilities)) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_handler_register(instance->dip,
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_fm_error_cb, (void*) instance);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China endian_attr.devacc_attr_access = DDI_DEFAULT_ACC;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_generic_dma_attr.dma_attr_flags = 0;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinamegasas_fm_fini(struct megasas_instance *instance)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China /* Only unregister FMA capabilities if registered */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (instance->fm_capabilities) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * Un-register error callback if error callback capable.
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (DDI_FM_ERRCB_CAP(instance->fm_capabilities)) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_handler_unregister(instance->dip);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * Release any resources allocated by pci_ereport_setup()
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (DDI_FM_EREPORT_CAP(instance->fm_capabilities) ||
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China DDI_FM_ERRCB_CAP(instance->fm_capabilities)) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China pci_ereport_teardown(instance->dip);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China /* Unregister from IO Fault Services */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_fini(instance->dip);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China /* Adjust access and dma attributes for FMA */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China endian_attr.devacc_attr_access = DDI_DEFAULT_ACC;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_generic_dma_attr.dma_attr_flags = 0;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinamegasas_check_acc_handle(ddi_acc_handle_t handle)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (handle == NULL) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (DDI_FAILURE);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (de.fme_status);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinamegasas_check_dma_handle(ddi_dma_handle_t handle)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (handle == NULL) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (DDI_FAILURE);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (de.fme_status);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinamegasas_fm_ereport(struct megasas_instance *instance, char *detail)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China char buf[FM_MAX_CLASS];
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ena = fm_ena_generate(0, FM_ENA_FMT1);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (DDI_FM_EREPORT_CAP(instance->fm_capabilities)) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_ereport_post(instance->dip, buf, ena, DDI_NOSLEEP,