megaraid_sas.c revision ea20edda2274918c047dc10b52891c14f2afb0be
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
6029a2d88c01674debfd7c2e16c941a97302b739susans * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
6029a2d88c01674debfd7c2e16c941a97302b739susans * Use is subject to license terms.
6029a2d88c01674debfd7c2e16c941a97302b739susans#pragma ident "%Z%%M% %I% %E% SMI"
6029a2d88c01674debfd7c2e16c941a97302b739susans * Local static data
6029a2d88c01674debfd7c2e16c941a97302b739susans (unsigned long long)0, /* low DMA address range */
6029a2d88c01674debfd7c2e16c941a97302b739susans (unsigned long long)0xffffffff, /* high DMA address range */
6029a2d88c01674debfd7c2e16c941a97302b739susans (unsigned long long)0xffffffff, /* DMA counter register */
6029a2d88c01674debfd7c2e16c941a97302b739susans (unsigned long long)0xffffffff, /* segment boundary */
6029a2d88c01674debfd7c2e16c941a97302b739susans 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 * probe - called before attach for a given instance
6029a2d88c01674debfd7c2e16c941a97302b739susans * This is an optional entry for self-identifiable device.
6029a2d88c01674debfd7c2e16c941a97302b739susans * static int megasas_probe(dev_info_t *dip)
6029a2d88c01674debfd7c2e16c941a97302b739susans * return (DDI_SUCCESS);
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
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_dma_attr_t tran_dma_attr = megasas_generic_dma_attr;
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* initialize function pointers */
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"));
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. */
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: DDI_PM_RESUME"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: DDI_RESUME"));
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__));
6029a2d88c01674debfd7c2e16c941a97302b739susans instance = (struct megasas_instance *)ddi_get_soft_state(megasas_state,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas:%d could not get instance in detach",
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: detaching device 0x%4x:0x%4x:0x%4x:0x%4x\n",
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->vendor_id, instance->device_id, instance->subsysvid,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas_detach: DDI_DETACH\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas:%d failed to detach",
6029a2d88c01674debfd7c2e16c941a97302b739susans "failed to abort prevous AEN command\n"));
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 "megasas_ioctl: scsi_hba_ioctl is NULL."));
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 adp = (struct megasas_instance *)ddi_get_soft_state(mega_state,
6029a2d88c01674debfd7c2e16c941a97302b739susans if ((sd->sd_address.a_target >= (adp->max_channel * 16 + MAX_LD_64)) ||
6029a2d88c01674debfd7c2e16c941a97302b739susans MRAID_IS_LOGICAL(sd->sd_address.a_target, islogical);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Allow non-disk device commands to pass */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* From Target 40 - 64 there will be no devices */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (sd->sd_address.a_target > MAX_LOGICAL_DRIVES_40LD) {
6029a2d88c01674debfd7c2e16c941a97302b739susans * Get information about the logical drives.
6029a2d88c01674debfd7c2e16c941a97302b739susans if (megaraid_ld_state_instance(adp) != DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "megaraid: failed query adapter"));
6029a2d88c01674debfd7c2e16c941a97302b739susans if (adp->ldrv_state[adp->device_ids[0][sd->sd_address.a_target]]
6029a2d88c01674debfd7c2e16c941a97302b739susans adp->ldrv_state[adp->device_ids[0][sd->sd_address.a_target]]
6029a2d88c01674debfd7c2e16c941a97302b739susans#endif /* NOT_YET */
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_tgt_probe - probe for the existence of a target device
6029a2d88c01674debfd7c2e16c941a97302b739susans * @callback:
6029a2d88c01674debfd7c2e16c941a97302b739susans * The tran_tgt_probe() entry point enables the HBA to customize the operation
6029a2d88c01674debfd7c2e16c941a97302b739susans * of scsi_probe(), if necessary. This entry point is called only when the
6029a2d88c01674debfd7c2e16c941a97302b739susans * target driver calls scsi_probe(). The HBA driver can retain the normal
6029a2d88c01674debfd7c2e16c941a97302b739susans * operation of scsi_probe() by calling scsi_hba_probe() and returning its
6029a2d88c01674debfd7c2e16c941a97302b739susans * return value. This entry point is not required, and if not needed, the HBA
6029a2d88c01674debfd7c2e16c941a97302b739susans * driver should set the tran_tgt_ probe vector in the scsi_hba_tran structure
6029a2d88c01674debfd7c2e16c941a97302b739susans * to point to scsi_hba_probe().
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_tgt_probe(struct scsi_device *sd, int (*callback)())
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans * the HBA driver should set the tran_tgt_probe vector in the
6029a2d88c01674debfd7c2e16c941a97302b739susans * scsi_hba_tran structure to point to scsi_hba_probe()
6029a2d88c01674debfd7c2e16c941a97302b739susans#endif /* defined (USELESS) && !defined (lint) */
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",
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
6029a2d88c01674debfd7c2e16c941a97302b739susans if (((pkt->pkt_flags & FLAG_NOINTR) == 0) && pkt->pkt_comp) {
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,
6029a2d88c01674debfd7c2e16c941a97302b739susans * before return, set timer - for timeout checking
6029a2d88c01674debfd7c2e16c941a97302b739susans * (for every 1 second)
6029a2d88c01674debfd7c2e16c941a97302b739susans#endif /* defined(NOT_YET) && !defined(lint) */
e7eb627d1ca522096231179b750ce579a5278324yd instance->func_ptr-> issue_cmd_in_poll_mode(instance, cmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_state |= STATE_XFERRED_DATA | STATE_GOT_STATUS;
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
6029a2d88c01674debfd7c2e16c941a97302b739susans * abort all outstandidng 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 if (ap->a_target >= (adapter->max_channel * 16 + MAX_LD_64)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Limit to 16MB max transfer */
6029a2d88c01674debfd7c2e16c941a97302b739susans "fail geometry for phy [%d:%d]\n",
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
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
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) ddi_dma_sync(acmd->cmd_dmahandle, acmd->cmd_dma_offset,
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_dma_len, (acmd->cmd_flags & CFLAG_DMASEND) ?
6029a2d88c01674debfd7c2e16c941a97302b739susans#endif /* TBD */
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
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) ddi_dma_sync(instance->mfi_internal_dma_obj.dma_handle,
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_CONT, " producer %x consumer %x ",
6029a2d88c01674debfd7c2e16c941a97302b739susans * con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans * " context returned %x ",context));
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 /* LINTED E_BAD_PTR_CAST_ALIGN */
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 * 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
6029a2d88c01674debfd7c2e16c941a97302b739susanspush_pend_queue(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++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans * create_mfi_frame_pool
6029a2d88c01674debfd7c2e16c941a97302b739susanscreate_mfi_frame_pool(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans /* calculated the number of 64byte frames required for SGL */
6029a2d88c01674debfd7c2e16c941a97302b739susans tot_frame_size = sgl_sz + MEGAMFI_FRAME_SIZE + NUM_SENSE_KEYS;
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;
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_dma_obj.dma_attr.dma_attr_addr_hi = 0xffffffff;
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_dma_obj.dma_attr.dma_attr_count_max = 0xffffffff;
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) {
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.status = DMA_OBJ_FREED;
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->mfi_evt_detail_obj.status == DMA_OBJ_ALLOCATED) {
6029a2d88c01674debfd7c2e16c941a97302b739susans * alloc_additional_dma_buffer
6029a2d88c01674debfd7c2e16c941a97302b739susansalloc_additional_dma_buffer(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans /* max cmds plus 1 + procudure & 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;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.dma_attr.dma_attr_addr_hi = 0xffffffff;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.dma_attr.dma_attr_count_max = 0xffffffff;
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;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->producer = (uint32_t *)instance->mfi_internal_dma_obj.buffer;
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;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_evt_detail_obj.dma_attr.dma_attr_addr_hi = 0xffffffff;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_evt_detail_obj.dma_attr.dma_attr_count_max = 0xffffffff;
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));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* for( i = 0; i < 12; i++ ) dcmd->mbox.b[i] = 0; */
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"));
6029a2d88c01674debfd7c2e16c941a97302b739susans * abort_aen_cmd
6029a2d88c01674debfd7c2e16c941a97302b739susans "Failed to get a cmd for ctrl info\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* prepare and issue the abort frame */
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"));
6029a2d88c01674debfd7c2e16c941a97302b739susans if ((ddi_dev_regsize(instance->dip, REGISTER_SET_IO, ®length)
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 * con_log(CL_ANN, (CE_WARN, "megaraid: "
6029a2d88c01674debfd7c2e16c941a97302b739susans * "max_num_sge = %d max_fw_cmds = %d\n",
6029a2d88c01674debfd7c2e16c941a97302b739susans * instance->max_num_sge, instance->max_fw_cmds));
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;
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"));
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 *
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 /* LINTED E_BAD_PTR_CAST_ALIGN */
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 /* LINTED E_BAD_PTR_CAST_ALIGN */
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 /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* this state should not last for more than 2 seconds */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* the cur_state should not last for more than max_wait secs */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* fw_state = RD_OB_MSG_0(instance) & MFI_STATE_MASK; */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* return error if fw_state hasn't changed after max_wait */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
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
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans * get_seq_num
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate the data transfer buffer */
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd_dma_obj.size = sizeof (struct megasas_evt_log_info);
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd_dma_obj.dma_attr.dma_attr_count_max = 0xffffffff;
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));
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));
6029a2d88c01674debfd7c2e16c941a97302b739susansget_seq_num_in_poll(struct megasas_instance *instance,
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate the data transfer buffer */
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd_dma_obj.size = sizeof (struct megasas_evt_log_info);
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd_dma_obj.dma_attr.dma_attr_count_max = 0xffffffff;
6029a2d88c01674debfd7c2e16c941a97302b739susans if (mega_alloc_dma_obj(instance, &dcmd_dma_obj) != 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "could not data transfer buffer alloc."));
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_evt_log_info));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* for( i = 0; i < 12; i++ ) dcmd->mbox.b[i] = 0; */
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_poll_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));
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
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");
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#endif /* TBD */
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 class_locale.word = instance->aen_cmd->frame->dcmd.mbox.w[1];
6029a2d88c01674debfd7c2e16c941a97302b739susans ret = register_mfi_aen(instance, seq_num, class_locale.word);
6029a2d88c01674debfd7c2e16c941a97302b739susans cmn_err(CE_WARN, "service_mfi_aen: aen registration failed\n");
6029a2d88c01674debfd7c2e16c941a97302b739susans#endif /* TBD */
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
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_CONT, "megasas_softintr called"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susans mlist_splice(&instance->completed_pool_list, &process_list);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* perform all callbacks first, before releasing the SCBs */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* syncronize the Cmd frame for the controller */
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 /* con_log(CL_ANN, (CE_CONT,"pkt recived")); */
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_state = STATE_XFERRED_DATA | STATE_GOT_STATUS;
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"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* pull_pend_queue(instance); */
6029a2d88c01674debfd7c2e16c941a97302b739susans * con_log(CL_ANN,
6029a2d88c01674debfd7c2e16c941a97302b739susans * (CE_CONT,"call add %lx",pkt->pkt_comp));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Call the callback routine */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* con_log(CL_ANN, (CE_CONT, "call complete")); */
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
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)
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);
6029a2d88c01674debfd7c2e16c941a97302b739susans if ((ddi_dma_mem_alloc(obj->dma_handle, obj->size, &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);
6029a2d88c01674debfd7c2e16c941a97302b739susans * mega_free_dma_obj(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()
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;
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 /* NOTREACHED */
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 /* NOTREACHED */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_dma_numwin(acmd->cmd_dmahandle, &acmd->cmd_nwin) ==
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_PANIC, "ddi_dma_numwin failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* NOTREACHED */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_dma_getwin(acmd->cmd_dmahandle, acmd->cmd_curwin,
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_PANIC, "ddi_dma_getwin failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* NOTREACHED */
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_PANIC, "ddi_dma_buf_bind_handle:"
6029a2d88c01674debfd7c2e16c941a97302b739susans " DDI_DMA_INUSE impossible\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* NOTREACHED */
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_PANIC, "ddi_dma_buf_bind_handle: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "0x%x impossible\n", i));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* NOTREACHED */
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,
6029a2d88c01674debfd7c2e16c941a97302b739susans /* find out if this is logical or physical drive command. */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* get the command packet */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* lets get the command directions */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* flags |= MFI_FRAME_SGL64; */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Mode sense */
6029a2d88c01674debfd7c2e16c941a97302b739susans * preare the Logical IO frame:
6029a2d88c01674debfd7c2e16c941a97302b739susans * 2nd bit is zero for all read cmds
6029a2d88c01674debfd7c2e16c941a97302b739susans /* fall through For all non-rd/wr cmds */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* prepare the DCDB frame */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* pthru->sense_len = NUM_SENSE_KEYS; */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr; */
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;
6029a2d88c01674debfd7c2e16c941a97302b739susans sge_bytes = sizeof (struct megasas_sge32)*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++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru_dma_obj.dma_attr.dma_attr_addr_hi = 0xffffffff;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru_dma_obj.dma_attr.dma_attr_count_max = 0xffffffff;
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 * con_log(CL_ANN, (CE_WARN, "issue_mfi_pthru: "
6029a2d88c01674debfd7c2e16c941a97302b739susans * "copy to user space\n"));
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 */
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd_dma_obj.dma_attr.dma_attr_count_max = 0xffffffff;
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;
6029a2d88c01674debfd7c2e16c941a97302b739susans bcopy((void *)kdcmd->mbox.b, (void *)dcmd->mbox.b, 12);
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 * con_log(CL_ANN, (CE_WARN,"issue_mfi_dcmd: "
6029a2d88c01674debfd7c2e16c941a97302b739susans * copy to user space\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy to user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free kernel buffer */
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans request_dma_obj.dma_attr.dma_attr_addr_hi = 0xffffffff;
6029a2d88c01674debfd7c2e16c941a97302b739susans request_dma_obj.dma_attr.dma_attr_count_max = 0xffffffff;
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;
6029a2d88c01674debfd7c2e16c941a97302b739susans response_dma_obj.dma_attr.dma_attr_addr_hi = 0xffffffff;
6029a2d88c01674debfd7c2e16c941a97302b739susans response_dma_obj.dma_attr.dma_attr_count_max = 0xffffffff;
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free kernel buffer */
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans fis_dma_obj.dma_attr.dma_attr_count_max = 0xffffffff;
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans data_dma_obj.dma_attr.dma_attr_count_max = 0xffffffff;
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 * con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: "
6029a2d88c01674debfd7c2e16c941a97302b739susans * "copy to user space\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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free kernel buffer */
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->os_ver, "Build 36", strlen("Build 36"));
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"));
6029a2d88c01674debfd7c2e16c941a97302b739susans for (i = 0; i < sizeof (struct megasas_pci_information); i++) {
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);
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"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* for(i = 0; i < 12; i++) dcmd->mbox.b[i] = 0; */
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/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susans const char *const scsi_device_types[] = {
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");
6029a2d88c01674debfd7c2e16c941a97302b739susans * lint pointed out a bug that pkt may be used before being set
6029a2d88c01674debfd7c2e16c941a97302b739susans unsigned int cookie;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* decrease the timeout value per each packet */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* this means that the scsi command has timed out */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* pull out the packet from the list */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* call callback in the scsi_pkt structure */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* schedule next timeout check */
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->timeout_id = timeout(io_timeout_checker, (void *)instance,
6029a2d88c01674debfd7c2e16c941a97302b739susans#endif /* defined(NOT_YET) && !defined(lint) */
6029a2d88c01674debfd7c2e16c941a97302b739susansread_fw_status_reg_xscale(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susansread_fw_status_reg_ppc(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans /* con_log(CL_ANN, (CE_WARN, "read_fw_status_reg_ppc: called\n")); */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_cmd_xscale(struct megasas_cmd *cmd, struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans /* push_pend_queue(instance, cmd); */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Issue the command to the FW */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susans WR_IB_QPORT((host_to_le32(cmd->frame_phys_addr) >> 3) |
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_cmd_ppc(struct megasas_cmd *cmd, struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans /* con_log(CL_ANN, (CE_WARN, "issue_cmd_ppc: called\n")); */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Issue the command to the FW */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susans * issue_cmd_in_sync_mode
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_cmd_in_sync_mode_xscale(struct megasas_instance *instance,
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
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,
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_sync_mode_ppc: called\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
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,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_header *frame_hdr = (struct megasas_header *)cmd->frame;
6029a2d88c01674debfd7c2e16c941a97302b739susans frame_hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* issue the frame using inbound queue port */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susans WR_IB_QPORT((host_to_le32(cmd->frame_phys_addr) >> 3) |
6029a2d88c01674debfd7c2e16c941a97302b739susans /* wait for cmd_status to change */
6029a2d88c01674debfd7c2e16c941a97302b739susans for (i = 0; i < msecs && (frame_hdr->cmd_status == 0xff); i++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "cmd polling timed out"));
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_cmd_in_poll_mode_ppc(struct megasas_instance *instance,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_header *frame_hdr = (struct megasas_header *)cmd->frame;
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_poll_mode_ppc: called\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans frame_hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* issue the frame using inbound queue port */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* wait for cmd_status to change */
6029a2d88c01674debfd7c2e16c941a97302b739susans for (i = 0; i < msecs && (frame_hdr->cmd_status == 0xff); i++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans "cmd polling timed out"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "enable_intr_ppc: called\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
ea20edda2274918c047dc10b52891c14f2afb0besusans * As 1078DE is same as 1078 chip, the interrupt mask
ea20edda2274918c047dc10b52891c14f2afb0besusans * remains the same.
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susans WR_OB_INTR_MASK(~(MFI_REPLY_1078_MESSAGE_INTR), instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans /* WR_OB_INTR_MASK(~0x80000000, instance); */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* dummy read to force PCI flush */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susansdisable_intr_xscale(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: called\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: before : "
6029a2d88c01674debfd7c2e16c941a97302b739susans "outbound_intr_mask = 0x%x\n", RD_OB_INTR_MASK(instance)));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
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 /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* check if it is our interrupt */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* clear the interrupt by writing back the same value */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "intr_ack_ppc: called\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* check if it is our interrupt */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
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 /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* dummy READ */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* LINTED E_BAD_PTR_CAST_ALIGN */
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "intr_ack_ppc: interrupt cleared\n"));