6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * megaraid_sas.c: source for mega_sas driver
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * MegaRAID device driver for SAS controllers
6029a2d88c01674debfd7c2e16c941a97302b739susans * Copyright (c) 2005-2008, LSI Logic Corporation.
6029a2d88c01674debfd7c2e16c941a97302b739susans * All rights reserved.
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * Version:
6029a2d88c01674debfd7c2e16c941a97302b739susans * Author:
6029a2d88c01674debfd7c2e16c941a97302b739susans * Rajesh Prabhakaran<Rajesh.Prabhakaran@lsil.com>
6029a2d88c01674debfd7c2e16c941a97302b739susans * Seokmann Ju
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * Redistribution and use in source and binary forms, with or without
6029a2d88c01674debfd7c2e16c941a97302b739susans * modification, are permitted provided that the following conditions are met:
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * 1. Redistributions of source code must retain the above copyright notice,
6029a2d88c01674debfd7c2e16c941a97302b739susans * this list of conditions and the following disclaimer.
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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 *
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 *
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 * DAMAGE.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
9c57abc8d70cb139020be846baec0a9c4d9a73cdsrivijitha dugganapalli * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
6029a2d88c01674debfd7c2e16c941a97302b739susans * Use is subject to license terms.
89b43686db1fe9681d80a7cf5662730cb9378caeBayard Bell * Copyright (c) 2011 Bayard G. Bell. All rights reserved.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans#include <sys/types.h>
6029a2d88c01674debfd7c2e16c941a97302b739susans#include <sys/param.h>
6029a2d88c01674debfd7c2e16c941a97302b739susans#include <sys/file.h>
6029a2d88c01674debfd7c2e16c941a97302b739susans#include <sys/errno.h>
6029a2d88c01674debfd7c2e16c941a97302b739susans#include <sys/open.h>
6029a2d88c01674debfd7c2e16c941a97302b739susans#include <sys/cred.h>
6029a2d88c01674debfd7c2e16c941a97302b739susans#include <sys/modctl.h>
6029a2d88c01674debfd7c2e16c941a97302b739susans#include <sys/conf.h>
6029a2d88c01674debfd7c2e16c941a97302b739susans#include <sys/devops.h>
6029a2d88c01674debfd7c2e16c941a97302b739susans#include <sys/cmn_err.h>
6029a2d88c01674debfd7c2e16c941a97302b739susans#include <sys/kmem.h>
6029a2d88c01674debfd7c2e16c941a97302b739susans#include <sys/stat.h>
6029a2d88c01674debfd7c2e16c941a97302b739susans#include <sys/mkdev.h>
6029a2d88c01674debfd7c2e16c941a97302b739susans#include <sys/pci.h>
6029a2d88c01674debfd7c2e16c941a97302b739susans#include <sys/scsi/scsi.h>
6029a2d88c01674debfd7c2e16c941a97302b739susans#include <sys/ddi.h>
6029a2d88c01674debfd7c2e16c941a97302b739susans#include <sys/sunddi.h>
6029a2d88c01674debfd7c2e16c941a97302b739susans#include <sys/atomic.h>
6029a2d88c01674debfd7c2e16c941a97302b739susans#include <sys/signal.h>
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans#include "megaraid_sas.h"
6029a2d88c01674debfd7c2e16c941a97302b739susans
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China/*
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * FMA header files
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China#include <sys/ddifm.h>
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China#include <sys/fm/protocol.h>
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China#include <sys/fm/util.h>
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China#include <sys/fm/io/ddi.h>
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * Local static data
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void *megasas_state = NULL;
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int debug_level_g = CL_ANN;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans#pragma weak scsi_hba_open
6029a2d88c01674debfd7c2e16c941a97302b739susans#pragma weak scsi_hba_close
6029a2d88c01674debfd7c2e16c941a97302b739susans#pragma weak scsi_hba_ioctl
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic ddi_dma_attr_t megasas_generic_dma_attr = {
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele DMA_ATTR_V0, /* dma_attr_version */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele 0, /* low DMA address range */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele 0xFFFFFFFFU, /* high DMA address range */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele 0xFFFFFFFFU, /* DMA counter register */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele 8, /* DMA address alignment */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele 0x07, /* DMA burstsizes */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele 1, /* min DMA size */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele 0xFFFFFFFFU, /* max DMA size */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele 0xFFFFFFFFU, /* segment boundary */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele MEGASAS_MAX_SGE_CNT, /* dma_attr_sglen */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele 512, /* granularity of device */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele 0 /* bus specific DMA flags */
6029a2d88c01674debfd7c2e16c941a97302b739susans};
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansint32_t megasas_max_cap_maxxfer = 0x1000000;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * cb_ops contains base level routines
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic struct cb_ops megasas_cb_ops = {
6029a2d88c01674debfd7c2e16c941a97302b739susans megasas_open, /* open */
6029a2d88c01674debfd7c2e16c941a97302b739susans megasas_close, /* close */
6029a2d88c01674debfd7c2e16c941a97302b739susans nodev, /* strategy */
6029a2d88c01674debfd7c2e16c941a97302b739susans nodev, /* print */
6029a2d88c01674debfd7c2e16c941a97302b739susans nodev, /* dump */
6029a2d88c01674debfd7c2e16c941a97302b739susans nodev, /* read */
6029a2d88c01674debfd7c2e16c941a97302b739susans nodev, /* write */
6029a2d88c01674debfd7c2e16c941a97302b739susans megasas_ioctl, /* ioctl */
6029a2d88c01674debfd7c2e16c941a97302b739susans nodev, /* devmap */
6029a2d88c01674debfd7c2e16c941a97302b739susans nodev, /* mmap */
6029a2d88c01674debfd7c2e16c941a97302b739susans nodev, /* segmap */
6029a2d88c01674debfd7c2e16c941a97302b739susans nochpoll, /* poll */
6029a2d88c01674debfd7c2e16c941a97302b739susans nodev, /* cb_prop_op */
6029a2d88c01674debfd7c2e16c941a97302b739susans 0, /* streamtab */
6029a2d88c01674debfd7c2e16c941a97302b739susans D_NEW | D_HOTPLUG, /* cb_flag */
6029a2d88c01674debfd7c2e16c941a97302b739susans CB_REV, /* cb_rev */
6029a2d88c01674debfd7c2e16c941a97302b739susans nodev, /* cb_aread */
6029a2d88c01674debfd7c2e16c941a97302b739susans nodev /* cb_awrite */
6029a2d88c01674debfd7c2e16c941a97302b739susans};
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * dev_ops contains configuration routines
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic struct dev_ops megasas_ops = {
6029a2d88c01674debfd7c2e16c941a97302b739susans DEVO_REV, /* rev, */
6029a2d88c01674debfd7c2e16c941a97302b739susans 0, /* refcnt */
6029a2d88c01674debfd7c2e16c941a97302b739susans megasas_getinfo, /* getinfo */
6029a2d88c01674debfd7c2e16c941a97302b739susans nulldev, /* identify */
6029a2d88c01674debfd7c2e16c941a97302b739susans nulldev, /* probe */
6029a2d88c01674debfd7c2e16c941a97302b739susans megasas_attach, /* attach */
6029a2d88c01674debfd7c2e16c941a97302b739susans megasas_detach, /* detach */
6029a2d88c01674debfd7c2e16c941a97302b739susans megasas_reset, /* reset */
6029a2d88c01674debfd7c2e16c941a97302b739susans &megasas_cb_ops, /* char/block ops */
193974072f41a843678abf5f61979c748687e66bSherry Moore NULL, /* bus ops */
193974072f41a843678abf5f61979c748687e66bSherry Moore NULL, /* power */
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_quiesce_not_supported, /* devo_quiesce */
6029a2d88c01674debfd7c2e16c941a97302b739susans};
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic struct modldrv modldrv = {
6029a2d88c01674debfd7c2e16c941a97302b739susans &mod_driverops, /* module type - driver */
6029a2d88c01674debfd7c2e16c941a97302b739susans MEGASAS_VERSION,
6029a2d88c01674debfd7c2e16c941a97302b739susans &megasas_ops, /* driver ops */
6029a2d88c01674debfd7c2e16c941a97302b739susans};
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic struct modlinkage modlinkage = {
6029a2d88c01674debfd7c2e16c941a97302b739susans MODREV_1, /* ml_rev - must be MODREV_1 */
6029a2d88c01674debfd7c2e16c941a97302b739susans &modldrv, /* ml_linkage */
6029a2d88c01674debfd7c2e16c941a97302b739susans NULL /* end of driver linkage */
6029a2d88c01674debfd7c2e16c941a97302b739susans};
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic struct ddi_device_acc_attr endian_attr = {
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson DDI_DEVICE_ATTR_V1,
6029a2d88c01674debfd7c2e16c941a97302b739susans DDI_STRUCTURE_LE_ACC,
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson DDI_STRICTORDER_ACC,
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson DDI_DEFAULT_ACC
6029a2d88c01674debfd7c2e16c941a97302b739susans};
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans * *
6029a2d88c01674debfd7c2e16c941a97302b739susans * common entry points - for loadable kernel modules *
6029a2d88c01674debfd7c2e16c941a97302b739susans * *
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * _init - initialize a loadable module
6029a2d88c01674debfd7c2e16c941a97302b739susans * @void
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susansint
6029a2d88c01674debfd7c2e16c941a97302b739susans_init(void)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int ret;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ret = ddi_soft_state_init(&megasas_state,
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_instance), 0);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ret != 0) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "megaraid: could not init state"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (ret);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if ((ret = scsi_hba_init(&modlinkage)) != 0) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "megaraid: could not init scsi hba"));
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_soft_state_fini(&megasas_state);
6029a2d88c01674debfd7c2e16c941a97302b739susans return (ret);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ret = mod_install(&modlinkage);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ret != 0) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "megaraid: mod_install failed"));
6029a2d88c01674debfd7c2e16c941a97302b739susans scsi_hba_fini(&modlinkage);
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_soft_state_fini(&megasas_state);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (ret);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * _info - returns information about a loadable module.
6029a2d88c01674debfd7c2e16c941a97302b739susans * @void
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susansint
6029a2d88c01674debfd7c2e16c941a97302b739susans_info(struct modinfo *modinfop)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (mod_info(&modlinkage, modinfop));
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * _fini - prepare a loadable module for unloading
6029a2d88c01674debfd7c2e16c941a97302b739susans * @void
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susansint
6029a2d88c01674debfd7c2e16c941a97302b739susans_fini(void)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int ret;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if ((ret = mod_remove(&modlinkage)) != 0)
6029a2d88c01674debfd7c2e16c941a97302b739susans return (ret);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans scsi_hba_fini(&modlinkage);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_soft_state_fini(&megasas_state);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (ret);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans * *
6029a2d88c01674debfd7c2e16c941a97302b739susans * common entry points - for autoconfiguration *
6029a2d88c01674debfd7c2e16c941a97302b739susans * *
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * attach - adds a device to the system as part of initialization
6029a2d88c01674debfd7c2e16c941a97302b739susans * @dip:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @cmd:
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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 * attached
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int instance_no;
6029a2d88c01674debfd7c2e16c941a97302b739susans int nregs;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint8_t added_isr_f = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint8_t added_soft_isr_f = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint8_t create_devctl_node_f = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint8_t create_scsi_node_f = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint8_t create_ioc_node_f = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint8_t tran_alloc_f = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint8_t irq;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint16_t vendor_id;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint16_t device_id;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint16_t subsysvid;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint16_t subsysid;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint16_t command;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans scsi_hba_tran_t *tran;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_dma_attr_t tran_dma_attr;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_instance *instance;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele /* CONSTCOND */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele ASSERT(NO_COMPETING_THREADS);
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele
6029a2d88c01674debfd7c2e16c941a97302b739susans instance_no = ddi_get_instance(dip);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_slaveonly(dip) == DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "mega%d: Device in slave-only slot, unused", instance_no));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans switch (cmd) {
6029a2d88c01674debfd7c2e16c941a97302b739susans case DDI_ATTACH:
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw con_log(CL_DLEVEL1, (CE_NOTE, "megasas: DDI_ATTACH"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate the soft state for the instance */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_soft_state_zalloc(megasas_state, instance_no)
6029a2d88c01674debfd7c2e16c941a97302b739susans != DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "mega%d: Failed to allocate soft state",
6029a2d88c01674debfd7c2e16c941a97302b739susans instance_no));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance = (struct megasas_instance *)ddi_get_soft_state
6029a2d88c01674debfd7c2e16c941a97302b739susans (megasas_state, instance_no);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance == NULL) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "mega%d: Bad soft state", instance_no));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_soft_state_free(megasas_state, instance_no);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans bzero((caddr_t)instance,
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_instance));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr = kmem_zalloc(
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_func_ptr), KM_SLEEP);
6029a2d88c01674debfd7c2e16c941a97302b739susans ASSERT(instance->func_ptr);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Setup the PCI configuration space handles */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (pci_config_setup(dip, &instance->pci_handle) !=
6029a2d88c01674debfd7c2e16c941a97302b739susans DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "mega%d: pci config setup failed ",
6029a2d88c01674debfd7c2e16c941a97302b739susans instance_no));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans kmem_free(instance->func_ptr,
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_func_ptr));
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_soft_state_free(megasas_state, instance_no);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_dev_nregs(dip, &nregs) != DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megaraid: failed to get registers."));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans pci_config_teardown(&instance->pci_handle);
6029a2d88c01674debfd7c2e16c941a97302b739susans kmem_free(instance->func_ptr,
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_func_ptr));
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_soft_state_free(megasas_state, instance_no);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans vendor_id = pci_config_get16(instance->pci_handle,
6029a2d88c01674debfd7c2e16c941a97302b739susans PCI_CONF_VENID);
6029a2d88c01674debfd7c2e16c941a97302b739susans device_id = pci_config_get16(instance->pci_handle,
6029a2d88c01674debfd7c2e16c941a97302b739susans PCI_CONF_DEVID);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans subsysvid = pci_config_get16(instance->pci_handle,
6029a2d88c01674debfd7c2e16c941a97302b739susans PCI_CONF_SUBVENID);
6029a2d88c01674debfd7c2e16c941a97302b739susans subsysid = pci_config_get16(instance->pci_handle,
6029a2d88c01674debfd7c2e16c941a97302b739susans PCI_CONF_SUBSYSID);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans pci_config_put16(instance->pci_handle, PCI_CONF_COMM,
6029a2d88c01674debfd7c2e16c941a97302b739susans (pci_config_get16(instance->pci_handle,
6029a2d88c01674debfd7c2e16c941a97302b739susans PCI_CONF_COMM) | PCI_COMM_ME));
6029a2d88c01674debfd7c2e16c941a97302b739susans irq = pci_config_get8(instance->pci_handle,
6029a2d88c01674debfd7c2e16c941a97302b739susans PCI_CONF_ILINE);
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele con_log(CL_DLEVEL1, (CE_CONT, "megasas%d: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "0x%x:0x%x 0x%x:0x%x, irq:%d drv-ver:%s\n",
6029a2d88c01674debfd7c2e16c941a97302b739susans instance_no, vendor_id, device_id, subsysvid,
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele subsysid, irq, MEGASAS_VERSION));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* enable bus-mastering */
6029a2d88c01674debfd7c2e16c941a97302b739susans command = pci_config_get16(instance->pci_handle,
6029a2d88c01674debfd7c2e16c941a97302b739susans PCI_CONF_COMM);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (!(command & PCI_COMM_ME)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans command |= PCI_COMM_ME;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans pci_config_put16(instance->pci_handle,
6029a2d88c01674debfd7c2e16c941a97302b739susans PCI_CONF_COMM, command);
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele con_log(CL_ANN, (CE_CONT, "megaraid%d: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "enable bus-mastering\n", instance_no));
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele con_log(CL_DLEVEL1, (CE_CONT, "megaraid%d: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "bus-mastering already set\n", instance_no));
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* initialize function pointers */
ea20edda2274918c047dc10b52891c14f2afb0besusans if ((device_id == PCI_DEVICE_ID_LSI_1078) ||
ea20edda2274918c047dc10b52891c14f2afb0besusans (device_id == PCI_DEVICE_ID_LSI_1078DE)) {
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele con_log(CL_DLEVEL1, (CE_CONT, "megasas%d: "
ea20edda2274918c047dc10b52891c14f2afb0besusans "1078R/DE detected\n", instance_no));
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->read_fw_status_reg =
6029a2d88c01674debfd7c2e16c941a97302b739susans read_fw_status_reg_ppc;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->issue_cmd = issue_cmd_ppc;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->issue_cmd_in_sync_mode =
6029a2d88c01674debfd7c2e16c941a97302b739susans issue_cmd_in_sync_mode_ppc;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->issue_cmd_in_poll_mode =
6029a2d88c01674debfd7c2e16c941a97302b739susans issue_cmd_in_poll_mode_ppc;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->enable_intr =
6029a2d88c01674debfd7c2e16c941a97302b739susans enable_intr_ppc;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->disable_intr =
6029a2d88c01674debfd7c2e16c941a97302b739susans disable_intr_ppc;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->intr_ack = intr_ack_ppc;
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele con_log(CL_DLEVEL1, (CE_CONT, "megasas%d: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "1064/8R detected\n", instance_no));
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->read_fw_status_reg =
6029a2d88c01674debfd7c2e16c941a97302b739susans read_fw_status_reg_xscale;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->issue_cmd =
6029a2d88c01674debfd7c2e16c941a97302b739susans issue_cmd_xscale;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->issue_cmd_in_sync_mode =
6029a2d88c01674debfd7c2e16c941a97302b739susans issue_cmd_in_sync_mode_xscale;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->issue_cmd_in_poll_mode =
6029a2d88c01674debfd7c2e16c941a97302b739susans issue_cmd_in_poll_mode_xscale;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->enable_intr =
6029a2d88c01674debfd7c2e16c941a97302b739susans enable_intr_xscale;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->disable_intr =
6029a2d88c01674debfd7c2e16c941a97302b739susans disable_intr_xscale;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->intr_ack =
6029a2d88c01674debfd7c2e16c941a97302b739susans intr_ack_xscale;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele instance->baseaddress = pci_config_get32(
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele instance->pci_handle, PCI_CONF_BASE0);
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->baseaddress &= 0x0fffc;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->dip = dip;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->vendor_id = vendor_id;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->device_id = device_id;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->subsysvid = subsysvid;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->subsysid = subsysid;
6029a2d88c01674debfd7c2e16c941a97302b739susans
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China /* Initialize FMA */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China instance->fm_capabilities = ddi_prop_get_int(
6ec0e3088091a677d3f67cf54a25174b0eb6db4aSusan Scheufele DDI_DEV_T_ANY, instance->dip, DDI_PROP_DONTPASS,
6ec0e3088091a677d3f67cf54a25174b0eb6db4aSusan Scheufele "fm-capable", DDI_FM_EREPORT_CAPABLE |
6ec0e3088091a677d3f67cf54a25174b0eb6db4aSusan Scheufele DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE
6ec0e3088091a677d3f67cf54a25174b0eb6db4aSusan Scheufele | DDI_FM_ERRCB_CAPABLE);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_fm_init(instance);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
6029a2d88c01674debfd7c2e16c941a97302b739susans /* setup the mfi based low level driver */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (init_mfi(instance) != DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "megaraid: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "could not initialize the low level driver"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans goto fail_attach;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_get_iblock_cookie(dip, 0,
6029a2d88c01674debfd7c2e16c941a97302b739susans &instance->iblock_cookie) != DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans goto fail_attach;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_get_soft_iblock_cookie(dip, DDI_SOFTINT_HIGH,
6029a2d88c01674debfd7c2e16c941a97302b739susans &instance->soft_iblock_cookie) != DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans goto fail_attach;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
6029a2d88c01674debfd7c2e16c941a97302b739susans * Initialize the driver mutexes common to
6029a2d88c01674debfd7c2e16c941a97302b739susans * normal/high level isr
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_intr_hilevel(dip, 0)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->isr_level = HIGH_LEVEL_INTR;
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_init(&instance->cmd_pool_mtx,
6029a2d88c01674debfd7c2e16c941a97302b739susans "cmd_pool_mtx", MUTEX_DRIVER,
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->soft_iblock_cookie);
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_init(&instance->cmd_pend_mtx,
6029a2d88c01674debfd7c2e16c941a97302b739susans "cmd_pend_mtx", MUTEX_DRIVER,
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->soft_iblock_cookie);
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
6029a2d88c01674debfd7c2e16c941a97302b739susans * Initialize the driver mutexes
6029a2d88c01674debfd7c2e16c941a97302b739susans * specific to soft-isr
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->isr_level = NORMAL_LEVEL_INTR;
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_init(&instance->cmd_pool_mtx,
6029a2d88c01674debfd7c2e16c941a97302b739susans "cmd_pool_mtx", MUTEX_DRIVER,
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->iblock_cookie);
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_init(&instance->cmd_pend_mtx,
6029a2d88c01674debfd7c2e16c941a97302b739susans "cmd_pend_mtx", MUTEX_DRIVER,
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->iblock_cookie);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_init(&instance->completed_pool_mtx,
6029a2d88c01674debfd7c2e16c941a97302b739susans "completed_pool_mtx", MUTEX_DRIVER,
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->iblock_cookie);
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_init(&instance->int_cmd_mtx, "int_cmd_mtx",
6029a2d88c01674debfd7c2e16c941a97302b739susans MUTEX_DRIVER, instance->iblock_cookie);
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_init(&instance->aen_cmd_mtx, "aen_cmd_mtx",
6029a2d88c01674debfd7c2e16c941a97302b739susans MUTEX_DRIVER, instance->iblock_cookie);
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_init(&instance->abort_cmd_mtx, "abort_cmd_mtx",
6029a2d88c01674debfd7c2e16c941a97302b739susans MUTEX_DRIVER, instance->iblock_cookie);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cv_init(&instance->int_cmd_cv, NULL, CV_DRIVER, NULL);
6029a2d88c01674debfd7c2e16c941a97302b739susans cv_init(&instance->abort_cmd_cv, NULL, CV_DRIVER, NULL);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans INIT_LIST_HEAD(&instance->completed_pool_list);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Register our isr. */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_add_intr(dip, 0, NULL, NULL, megasas_isr,
6029a2d88c01674debfd7c2e16c941a97302b739susans (caddr_t)instance) != DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans " ISR did not register"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans goto fail_attach;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans added_isr_f = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Register our soft-isr for highlevel interrupts. */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->isr_level == HIGH_LEVEL_INTR) {
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_add_softintr(dip, DDI_SOFTINT_HIGH,
6029a2d88c01674debfd7c2e16c941a97302b739susans &instance->soft_intr_id, NULL, NULL,
6029a2d88c01674debfd7c2e16c941a97302b739susans megasas_softintr, (caddr_t)instance) !=
6029a2d88c01674debfd7c2e16c941a97302b739susans DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans " Software ISR did not register"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans goto fail_attach;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans added_soft_isr_f = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Allocate a transport structure */
6029a2d88c01674debfd7c2e16c941a97302b739susans tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (tran == NULL) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "scsi_hba_tran_alloc failed"));
6029a2d88c01674debfd7c2e16c941a97302b739susans goto fail_attach;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans tran_alloc_f = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->tran = tran;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans tran->tran_hba_private = instance;
6029a2d88c01674debfd7c2e16c941a97302b739susans tran->tran_tgt_private = NULL;
6029a2d88c01674debfd7c2e16c941a97302b739susans tran->tran_tgt_init = megasas_tran_tgt_init;
6029a2d88c01674debfd7c2e16c941a97302b739susans tran->tran_tgt_probe = scsi_hba_probe;
6029a2d88c01674debfd7c2e16c941a97302b739susans tran->tran_tgt_free = (void (*)())NULL;
6029a2d88c01674debfd7c2e16c941a97302b739susans tran->tran_init_pkt = megasas_tran_init_pkt;
6029a2d88c01674debfd7c2e16c941a97302b739susans tran->tran_start = megasas_tran_start;
6029a2d88c01674debfd7c2e16c941a97302b739susans tran->tran_abort = megasas_tran_abort;
6029a2d88c01674debfd7c2e16c941a97302b739susans tran->tran_reset = megasas_tran_reset;
6029a2d88c01674debfd7c2e16c941a97302b739susans tran->tran_bus_reset = megasas_tran_bus_reset;
6029a2d88c01674debfd7c2e16c941a97302b739susans tran->tran_getcap = megasas_tran_getcap;
6029a2d88c01674debfd7c2e16c941a97302b739susans tran->tran_setcap = megasas_tran_setcap;
6029a2d88c01674debfd7c2e16c941a97302b739susans tran->tran_destroy_pkt = megasas_tran_destroy_pkt;
6029a2d88c01674debfd7c2e16c941a97302b739susans tran->tran_dmafree = megasas_tran_dmafree;
6029a2d88c01674debfd7c2e16c941a97302b739susans tran->tran_sync_pkt = megasas_tran_sync_pkt;
6029a2d88c01674debfd7c2e16c941a97302b739susans tran->tran_reset_notify = NULL;
6029a2d88c01674debfd7c2e16c941a97302b739susans tran->tran_quiesce = megasas_tran_quiesce;
6029a2d88c01674debfd7c2e16c941a97302b739susans tran->tran_unquiesce = megasas_tran_unquiesce;
6029a2d88c01674debfd7c2e16c941a97302b739susans
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China tran_dma_attr = megasas_generic_dma_attr;
6029a2d88c01674debfd7c2e16c941a97302b739susans tran_dma_attr.dma_attr_sgllen = instance->max_num_sge;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Attach this instance of the hba */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (scsi_hba_attach_setup(dip, &tran_dma_attr, tran, 0)
6029a2d88c01674debfd7c2e16c941a97302b739susans != DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "scsi_hba_attach failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans goto fail_attach;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* create devctl node for cfgadm command */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_create_minor_node(dip, "devctl",
6029a2d88c01674debfd7c2e16c941a97302b739susans S_IFCHR, INST2DEVCTL(instance_no),
6029a2d88c01674debfd7c2e16c941a97302b739susans DDI_NT_SCSI_NEXUS, 0) == DDI_FAILURE) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megaraid: failed to create devctl node."));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans goto fail_attach;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans create_devctl_node_f = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* create scsi node for cfgadm command */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_create_minor_node(dip, "scsi", S_IFCHR,
6029a2d88c01674debfd7c2e16c941a97302b739susans INST2SCSI(instance_no),
6029a2d88c01674debfd7c2e16c941a97302b739susans DDI_NT_SCSI_ATTACHMENT_POINT, 0) ==
6029a2d88c01674debfd7c2e16c941a97302b739susans DDI_FAILURE) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megaraid: failed to create scsi node."));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans goto fail_attach;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans create_scsi_node_f = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) sprintf(instance->iocnode, "%d:lsirdctl",
6029a2d88c01674debfd7c2e16c941a97302b739susans instance_no);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
6029a2d88c01674debfd7c2e16c941a97302b739susans * Create a node for applications
6029a2d88c01674debfd7c2e16c941a97302b739susans * for issuing ioctl to the driver.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_create_minor_node(dip, instance->iocnode,
6029a2d88c01674debfd7c2e16c941a97302b739susans S_IFCHR, INST2LSIRDCTL(instance_no),
6029a2d88c01674debfd7c2e16c941a97302b739susans DDI_PSEUDO, 0) == DDI_FAILURE) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megaraid: failed to create ioctl node."));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans goto fail_attach;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans create_ioc_node_f = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* enable interrupt */
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->enable_intr(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* initiate AEN */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (start_mfi_aen(instance)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megaraid: failed to initiate AEN."));
6029a2d88c01674debfd7c2e16c941a97302b739susans goto fail_initiate_aen;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw con_log(CL_DLEVEL1, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "AEN started for instance %d.", instance_no));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Finally! We are on the air. */
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_report_dev(dip);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_acc_handle(instance->regmap_handle) !=
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China goto fail_attach;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_acc_handle(instance->pci_handle) !=
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China goto fail_attach;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case DDI_PM_RESUME:
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: DDI_PM_RESUME"));
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case DDI_RESUME:
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: DDI_RESUME"));
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans default:
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: invalid attach cmd=%x", cmd));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_SUCCESS);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansfail_initiate_aen:
6029a2d88c01674debfd7c2e16c941a97302b739susansfail_attach:
6029a2d88c01674debfd7c2e16c941a97302b739susans if (create_devctl_node_f) {
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_remove_minor_node(dip, "devctl");
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (create_scsi_node_f) {
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_remove_minor_node(dip, "scsi");
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (create_ioc_node_f) {
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_remove_minor_node(dip, instance->iocnode);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (tran_alloc_f) {
6029a2d88c01674debfd7c2e16c941a97302b739susans scsi_hba_tran_free(tran);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (added_soft_isr_f) {
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_remove_softintr(instance->soft_intr_id);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (added_isr_f) {
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_remove_intr(dip, 0, instance->iblock_cookie);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_fm_fini(instance);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
6029a2d88c01674debfd7c2e16c941a97302b739susans pci_config_teardown(&instance->pci_handle);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_soft_state_free(megasas_state, instance_no);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: return failure from mega_attach\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * getinfo - gets device information
6029a2d88c01674debfd7c2e16c941a97302b739susans * @dip:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @cmd:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @arg:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @resultp:
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int rval;
6029a2d88c01674debfd7c2e16c941a97302b739susans int megasas_minor = getminor((dev_t)arg);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_instance *instance;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans switch (cmd) {
6029a2d88c01674debfd7c2e16c941a97302b739susans case DDI_INFO_DEVT2DEVINFO:
6029a2d88c01674debfd7c2e16c941a97302b739susans instance = (struct megasas_instance *)
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_get_soft_state(megasas_state,
6029a2d88c01674debfd7c2e16c941a97302b739susans MINOR2INST(megasas_minor));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance == NULL) {
6029a2d88c01674debfd7c2e16c941a97302b739susans *resultp = NULL;
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = DDI_FAILURE;
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans *resultp = instance->dip;
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = DDI_SUCCESS;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case DDI_INFO_DEVT2INSTANCE:
6029a2d88c01674debfd7c2e16c941a97302b739susans *resultp = (void *)instance;
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = DDI_SUCCESS;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans default:
6029a2d88c01674debfd7c2e16c941a97302b739susans *resultp = NULL;
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = DDI_FAILURE;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (rval);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * detach - detaches a device from the system
6029a2d88c01674debfd7c2e16c941a97302b739susans * @dip: pointer to the device's dev_info structure
6029a2d88c01674debfd7c2e16c941a97302b739susans * @cmd: type of detach
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int instance_no;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_instance *instance;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele /* CONSTCOND */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele ASSERT(NO_COMPETING_THREADS);
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele
6029a2d88c01674debfd7c2e16c941a97302b739susans instance_no = ddi_get_instance(dip);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance = (struct megasas_instance *)ddi_get_soft_state(megasas_state,
6029a2d88c01674debfd7c2e16c941a97302b739susans instance_no);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (!instance) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas:%d could not get instance in detach",
6029a2d88c01674debfd7c2e16c941a97302b739susans instance_no));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE,
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele "megasas%d: detaching device 0x%4x:0x%4x:0x%4x:0x%4x\n",
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele instance_no, instance->vendor_id, instance->device_id,
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele instance->subsysvid, instance->subsysid));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans switch (cmd) {
6029a2d88c01674debfd7c2e16c941a97302b739susans case DDI_DETACH:
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas_detach: DDI_DETACH\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (scsi_hba_detach(dip) != DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas:%d failed to detach",
6029a2d88c01674debfd7c2e16c941a97302b739susans instance_no));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans scsi_hba_tran_free(instance->tran);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (abort_aen_cmd(instance, instance->aen_cmd)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "megasas_detach: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "failed to abort prevous AEN command\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->disable_intr(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->isr_level == HIGH_LEVEL_INTR) {
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_remove_softintr(instance->soft_intr_id);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_remove_intr(dip, 0, instance->iblock_cookie);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans free_space_for_mfi(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_fm_fini(instance);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
6029a2d88c01674debfd7c2e16c941a97302b739susans pci_config_teardown(&instance->pci_handle);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans kmem_free(instance->func_ptr,
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_func_ptr));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_soft_state_free(megasas_state, instance_no);
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case DDI_PM_SUSPEND:
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas_detach: DDI_PM_SUSPEND\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case DDI_SUSPEND:
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas_detach: DDI_SUSPEND\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans default:
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "invalid detach command:0x%x", cmd));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_SUCCESS);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans * *
6029a2d88c01674debfd7c2e16c941a97302b739susans * common entry points - for character driver types *
6029a2d88c01674debfd7c2e16c941a97302b739susans * *
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * open - gets access to a device
6029a2d88c01674debfd7c2e16c941a97302b739susans * @dev:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @openflags:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @otyp:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @credp:
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_open(dev_t *dev, int openflags, int otyp, cred_t *credp)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int rval = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Check root permissions */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (drv_priv(credp) != 0) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megaraid: Non-root ioctl access tried!"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (EPERM);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Verify we are being opened as a character device */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (otyp != OTYP_CHR) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megaraid: ioctl node must be a char node\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (EINVAL);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_get_soft_state(megasas_state, MINOR2INST(getminor(*dev)))
6029a2d88c01674debfd7c2e16c941a97302b739susans == NULL) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (ENXIO);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (scsi_hba_open) {
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = scsi_hba_open(dev, openflags, otyp, credp);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (rval);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * close - gives up access to a device
6029a2d88c01674debfd7c2e16c941a97302b739susans * @dev:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @openflags:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @otyp:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @credp:
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * close() should perform any cleanup necessary to finish using the minor
6029a2d88c01674debfd7c2e16c941a97302b739susans * device, and prepare the device (and driver) to be opened again.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_close(dev_t dev, int openflags, int otyp, cred_t *credp)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int rval = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* no need for locks! */
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (scsi_hba_close) {
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = scsi_hba_close(dev, openflags, otyp, credp);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (rval);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * ioctl - performs a range of I/O commands for character drivers
6029a2d88c01674debfd7c2e16c941a97302b739susans * @dev:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @cmd:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @arg:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @mode:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @credp:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @rvalp:
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
6029a2d88c01674debfd7c2e16c941a97302b739susans int *rvalp)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int rval = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_instance *instance;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_ioctl ioctl;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_aen aen;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance = ddi_get_soft_state(megasas_state, MINOR2INST(getminor(dev)));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance == NULL) {
6029a2d88c01674debfd7c2e16c941a97302b739susans /* invalid minor number */
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "megaraid: adapter not found."));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (ENXIO);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans switch ((uint_t)cmd) {
6029a2d88c01674debfd7c2e16c941a97302b739susans case MEGASAS_IOCTL_FIRMWARE:
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyin((void *) arg, &ioctl,
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_ioctl), mode)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "megasas_ioctl: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "ERROR IOCTL copyin"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (EFAULT);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ioctl.control_code == MR_DRIVER_IOCTL_COMMON) {
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = handle_drv_ioctl(instance, &ioctl, mode);
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = handle_mfi_ioctl(instance, &ioctl, mode);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyout((void *) &ioctl, (void *)arg,
6029a2d88c01674debfd7c2e16c941a97302b739susans (sizeof (struct megasas_ioctl) - 1), mode)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas_ioctl: copy_to_user failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case MEGASAS_IOCTL_AEN:
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyin((void *) arg, &aen,
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_aen), mode)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas_ioctl: ERROR AEN copyin"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (EFAULT);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = handle_mfi_aen(instance, &aen);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyout((void *) &aen, (void *)arg,
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_aen), mode)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas_ioctl: copy_to_user failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans default:
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw rval = scsi_hba_ioctl(dev, cmd, arg,
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw mode, credp, rvalp);
6029a2d88c01674debfd7c2e16c941a97302b739susans
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw con_log(CL_DLEVEL1, (CE_NOTE, "megasas_ioctl: "
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw "scsi_hba_ioctl called, ret = %x.", rval));
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (rval);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans * *
6029a2d88c01674debfd7c2e16c941a97302b739susans * common entry points - for block driver types *
6029a2d88c01674debfd7c2e16c941a97302b739susans * *
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * reset - TBD
6029a2d88c01674debfd7c2e16c941a97302b739susans * @dip:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @cmd:
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * TBD
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_reset(dev_info_t *dip, ddi_reset_cmd_t cmd)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int instance_no;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_instance *instance;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance_no = ddi_get_instance(dip);
6029a2d88c01674debfd7c2e16c941a97302b739susans instance = (struct megasas_instance *)ddi_get_soft_state
6029a2d88c01674debfd7c2e16c941a97302b739susans (megasas_state, instance_no);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (!instance) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megaraid:%d could not get adapter in reset",
6029a2d88c01674debfd7c2e16c941a97302b739susans instance_no));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE, "flushing cache for instance %d ..",
6029a2d88c01674debfd7c2e16c941a97302b739susans instance_no));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans flush_cache(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_SUCCESS);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans * *
6029a2d88c01674debfd7c2e16c941a97302b739susans * entry points (SCSI HBA) *
6029a2d88c01674debfd7c2e16c941a97302b739susans * *
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_tgt_init - initialize a target device instance
6029a2d88c01674debfd7c2e16c941a97302b739susans * @hba_dip:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @tgt_dip:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @tran:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @sd:
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
6029a2d88c01674debfd7c2e16c941a97302b739susans scsi_hba_tran_t *tran, struct scsi_device *sd)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_SUCCESS);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_init_pkt - allocate & initialize a scsi_pkt structure
6029a2d88c01674debfd7c2e16c941a97302b739susans * @ap:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @pkt:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @bp:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @cmdlen:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @statuslen:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @tgtlen:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @flags:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @callback:
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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
6029a2d88c01674debfd7c2e16c941a97302b739susans */
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 int flags, int (*callback)(), caddr_t arg)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans struct scsa_cmd *acmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_instance *instance;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct scsi_pkt *new_pkt;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance = ADDR2MEGA(ap);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* step #1 : pkt allocation */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (pkt == NULL) {
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt = scsi_hba_pkt_alloc(instance->dip, ap, cmdlen, statuslen,
6029a2d88c01674debfd7c2e16c941a97302b739susans tgtlen, sizeof (struct scsa_cmd), callback, arg);
6029a2d88c01674debfd7c2e16c941a97302b739susans if (pkt == NULL) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (NULL);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd = PKT2CMD(pkt);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
6029a2d88c01674debfd7c2e16c941a97302b739susans * Initialize the new pkt - we redundantly initialize
6029a2d88c01674debfd7c2e16c941a97302b739susans * all the fields for illustrative purposes.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_pkt = pkt;
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_flags = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_scblen = statuslen;
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_cdblen = cmdlen;
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_dmahandle = NULL;
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_ncookies = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_cookie = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_cookiecnt = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_nwin = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_address = *ap;
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_comp = (void (*)())NULL;
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_flags = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_time = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_resid = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_state = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_statistics = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_reason = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans new_pkt = pkt;
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd = PKT2CMD(pkt);
6029a2d88c01674debfd7c2e16c941a97302b739susans new_pkt = NULL;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* step #2 : dma allocation/move */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (bp && bp->b_bcount != 0) {
6029a2d88c01674debfd7c2e16c941a97302b739susans if (acmd->cmd_dmahandle == NULL) {
6029a2d88c01674debfd7c2e16c941a97302b739susans if (megasas_dma_alloc(instance, pkt, bp, flags,
6029a2d88c01674debfd7c2e16c941a97302b739susans callback) == -1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans if (new_pkt) {
6029a2d88c01674debfd7c2e16c941a97302b739susans scsi_hba_pkt_free(ap, new_pkt);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return ((struct scsi_pkt *)NULL);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans if (megasas_dma_move(instance, pkt, bp) == -1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return ((struct scsi_pkt *)NULL);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (pkt);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_start - transport a SCSI command to the addressed target
6029a2d88c01674debfd7c2e16c941a97302b739susans * @ap:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @pkt:
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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 *
6029a2d88c01674debfd7c2e16c941a97302b739susans * Return Values :
6029a2d88c01674debfd7c2e16c941a97302b739susans * TRAN_BUSY - request queue is full, no more free scbs
6029a2d88c01674debfd7c2e16c941a97302b739susans * TRAN_ACCEPT - pkt has been submitted to the instance
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_start(struct scsi_address *ap, register struct scsi_pkt *pkt)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans uchar_t cmd_done = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_instance *instance = ADDR2MEGA(ap);
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d:SCSI CDB[0]=0x%x",
6029a2d88c01674debfd7c2e16c941a97302b739susans __func__, __LINE__, pkt->pkt_cdbp[0]));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_reason = CMD_CMPLT;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw *pkt->pkt_scbp = STATUS_GOOD; /* clear arq scsi_status */
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd = build_cmd(instance, ap, pkt, &cmd_done);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (cmd_done) {
9c57abc8d70cb139020be846baec0a9c4d9a73cdsrivijitha dugganapalli if ((pkt->pkt_flags & FLAG_NOINTR) == 0) {
9c57abc8d70cb139020be846baec0a9c4d9a73cdsrivijitha dugganapalli scsi_hba_pkt_comp(pkt);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw pkt->pkt_reason = CMD_CMPLT;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw pkt->pkt_scbp[0] = STATUS_GOOD;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw pkt->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw | STATE_SENT_CMD;
6029a2d88c01674debfd7c2e16c941a97302b739susans return (TRAN_ACCEPT);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (cmd == NULL) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (TRAN_BUSY);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if ((pkt->pkt_flags & FLAG_NOINTR) == 0) {
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->fw_outstanding > instance->max_fw_cmds) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_CONT, "megasas:Firmware busy"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return_mfi_pkt(instance, cmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans return (TRAN_BUSY);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Syncronize the Cmd frame for the controller */
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) ddi_dma_sync(cmd->frame_dma_obj.dma_handle, 0, 0,
6029a2d88c01674debfd7c2e16c941a97302b739susans DDI_DMA_SYNC_FORDEV);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->issue_cmd(cmd, instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_header *hdr = &cmd->frame->hdr;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->sync_cmd = MEGASAS_TRUE;
6029a2d88c01674debfd7c2e16c941a97302b739susans
e7eb627d1ca522096231179b750ce579a5278324yd instance->func_ptr-> issue_cmd_in_poll_mode(instance, cmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_reason = CMD_CMPLT;
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_statistics = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_state |= STATE_XFERRED_DATA | STATE_GOT_STATUS;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans switch (hdr->cmd_status) {
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_STAT_OK:
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_scbp[0] = STATUS_GOOD;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_STAT_SCSI_DONE_WITH_ERROR:
6029a2d88c01674debfd7c2e16c941a97302b739susans
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw pkt->pkt_reason = CMD_CMPLT;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw pkt->pkt_statistics = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ((struct scsi_status *)pkt->pkt_scbp)->sts_chk = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_STAT_DEVICE_NOT_FOUND:
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_reason = CMD_DEV_GONE;
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_statistics = STAT_DISCON;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans default:
6029a2d88c01674debfd7c2e16c941a97302b739susans ((struct scsi_status *)pkt->pkt_scbp)->sts_busy = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return_mfi_pkt(instance, cmd);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China (void) megasas_common_check(instance, cmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans
9c57abc8d70cb139020be846baec0a9c4d9a73cdsrivijitha dugganapalli scsi_hba_pkt_comp(pkt);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (TRAN_ACCEPT);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_abort - Abort any commands that are currently in transport
6029a2d88c01674debfd7c2e16c941a97302b739susans * @ap:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @pkt:
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * The tran_abort() entry point for a SCSI HBA driver is called to abort any
6029a2d88c01674debfd7c2e16c941a97302b739susans * commands that are currently in transport for a particular target. This entry
6029a2d88c01674debfd7c2e16c941a97302b739susans * point is called when a target driver calls scsi_abort(). The tran_abort()
6029a2d88c01674debfd7c2e16c941a97302b739susans * entry point should attempt to abort the command denoted by the pkt
6029a2d88c01674debfd7c2e16c941a97302b739susans * parameter. If the pkt parameter is NULL, tran_abort() should attempt to
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele * abort all outstanding commands in the transport layer for the particular
6029a2d88c01674debfd7c2e16c941a97302b739susans * target or logical unit.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_abort(struct scsi_address *ap, struct scsi_pkt *pkt)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* aborting command not supported by H/W */
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_reset - reset either the SCSI bus or target
6029a2d88c01674debfd7c2e16c941a97302b739susans * @ap:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @level:
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_reset(struct scsi_address *ap, int level)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_instance *instance = ADDR2MEGA(ap);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (wait_for_outstanding(instance)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_SUCCESS);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_bus_reset - reset the SCSI bus
6029a2d88c01674debfd7c2e16c941a97302b739susans * @dip:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @level:
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_bus_reset(dev_info_t *dip, int level)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int instance_no = ddi_get_instance(dip);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_instance *instance = ddi_get_soft_state(megasas_state,
6029a2d88c01674debfd7c2e16c941a97302b739susans instance_no);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (wait_for_outstanding(instance)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_SUCCESS);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_getcap - get one of a set of SCSA-defined capabilities
6029a2d88c01674debfd7c2e16c941a97302b739susans * @ap:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @cap:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @whom:
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_getcap(struct scsi_address *ap, char *cap, int whom)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int rval = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_instance *instance = ADDR2MEGA(ap);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* we do allow inquiring about capabilities for other targets */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (cap == NULL) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans switch (scsi_hba_lookup_capstr(cap)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_DMA_MAX:
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Limit to 16MB max transfer */
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = megasas_max_cap_maxxfer;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_MSG_OUT:
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_DISCONNECT:
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_SYNCHRONOUS:
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_WIDE_XFER:
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_TAGGED_QING:
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_UNTAGGED_QING:
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_PARITY:
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_INITIATOR_ID:
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = instance->init_id;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_ARQ:
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_LINKED_CMDS:
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_RESET_NOTIFICATION:
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_GEOMETRY:
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = -1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans default:
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_DLEVEL2, (CE_NOTE, "Default cap coming 0x%x",
6029a2d88c01674debfd7c2e16c941a97302b739susans scsi_hba_lookup_capstr(cap)));
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = -1;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (rval);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_setcap - set one of a set of SCSA-defined capabilities
6029a2d88c01674debfd7c2e16c941a97302b739susans * @ap:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @cap:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @value:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @whom:
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_setcap(struct scsi_address *ap, char *cap, int value, int whom)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int rval = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* We don't allow setting capabilities for other targets */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (cap == NULL || whom == 0) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans switch (scsi_hba_lookup_capstr(cap)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_DMA_MAX:
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_MSG_OUT:
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_PARITY:
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_LINKED_CMDS:
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_RESET_NOTIFICATION:
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_DISCONNECT:
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_SYNCHRONOUS:
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_UNTAGGED_QING:
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_WIDE_XFER:
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_INITIATOR_ID:
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_ARQ:
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
6029a2d88c01674debfd7c2e16c941a97302b739susans * None of these are settable via
6029a2d88c01674debfd7c2e16c941a97302b739susans * the capability interface.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_TAGGED_QING:
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_SECTOR_SIZE:
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCSI_CAP_TOTAL_SECTORS:
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans default:
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = -1;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (rval);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_destroy_pkt - deallocate scsi_pkt structure
6029a2d88c01674debfd7c2e16c941a97302b739susans * @ap:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @pkt:
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans struct scsa_cmd *acmd = PKT2CMD(pkt);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (acmd->cmd_flags & CFLAG_DMAVALID) {
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_flags &= ~CFLAG_DMAVALID;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) ddi_dma_unbind_handle(acmd->cmd_dmahandle);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_dma_free_handle(&acmd->cmd_dmahandle);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_dmahandle = NULL;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free the pkt */
6029a2d88c01674debfd7c2e16c941a97302b739susans scsi_hba_pkt_free(ap, pkt);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_dmafree - deallocates DMA resources
6029a2d88c01674debfd7c2e16c941a97302b739susans * @ap:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @pkt:
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans register struct scsa_cmd *acmd = PKT2CMD(pkt);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (acmd->cmd_flags & CFLAG_DMAVALID) {
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_flags &= ~CFLAG_DMAVALID;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) ddi_dma_unbind_handle(acmd->cmd_dmahandle);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_dma_free_handle(&acmd->cmd_dmahandle);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_dmahandle = NULL;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * tran_sync_pkt - synchronize the DMA object allocated
6029a2d88c01674debfd7c2e16c941a97302b739susans * @ap:
6029a2d88c01674debfd7c2e16c941a97302b739susans * @pkt:
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
6029a2d88c01674debfd7c2e16c941a97302b739susans * following 'ddi_dma_sync()' API call
6029a2d88c01674debfd7c2e16c941a97302b739susans * already called for each I/O in the ISR
6029a2d88c01674debfd7c2e16c941a97302b739susans */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele#if 0
6029a2d88c01674debfd7c2e16c941a97302b739susans int i;
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele register struct scsa_cmd *acmd = PKT2CMD(pkt);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (acmd->cmd_flags & CFLAG_DMAVALID) {
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) ddi_dma_sync(acmd->cmd_dmahandle, acmd->cmd_dma_offset,
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_dma_len, (acmd->cmd_flags & CFLAG_DMASEND) ?
6029a2d88c01674debfd7c2e16c941a97302b739susans DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele#endif
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_quiesce(dev_info_t *dip)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*ARGSUSED*/
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_tran_unquiesce(dev_info_t *dip)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * megasas_isr(caddr_t)
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * The Interrupt Service Routine
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * Collect status for all completed commands and do callback
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic uint_t
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufelemegasas_isr(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int need_softintr;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t producer;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t consumer;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t context;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele ASSERT(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans if (!instance->func_ptr->intr_ack(instance)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_INTR_UNCLAIMED);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) ddi_dma_sync(instance->mfi_internal_dma_obj.dma_handle,
6029a2d88c01674debfd7c2e16c941a97302b739susans 0, 0, DDI_DMA_SYNC_FORCPU);
6029a2d88c01674debfd7c2e16c941a97302b739susans
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_dma_handle(instance->mfi_internal_dma_obj.dma_handle)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China != DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (DDI_INTR_UNCLAIMED);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
6029a2d88c01674debfd7c2e16c941a97302b739susans producer = *instance->producer;
6029a2d88c01674debfd7c2e16c941a97302b739susans consumer = *instance->consumer;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_CONT, " producer %x consumer %x ",
6029a2d88c01674debfd7c2e16c941a97302b739susans producer, consumer));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_enter(&instance->completed_pool_mtx);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans while (consumer != producer) {
6029a2d88c01674debfd7c2e16c941a97302b739susans context = instance->reply_queue[consumer];
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd = instance->cmd_list[context];
6029a2d88c01674debfd7c2e16c941a97302b739susans mlist_add_tail(&cmd->list, &instance->completed_pool_list);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans consumer++;
6029a2d88c01674debfd7c2e16c941a97302b739susans if (consumer == (instance->max_fw_cmds + 1)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans consumer = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_exit(&instance->completed_pool_mtx);
6029a2d88c01674debfd7c2e16c941a97302b739susans
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw *instance->consumer = consumer;
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) ddi_dma_sync(instance->mfi_internal_dma_obj.dma_handle,
6029a2d88c01674debfd7c2e16c941a97302b739susans 0, 0, DDI_DMA_SYNC_FORDEV);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->softint_running) {
6029a2d88c01674debfd7c2e16c941a97302b739susans need_softintr = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans need_softintr = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->isr_level == HIGH_LEVEL_INTR) {
6029a2d88c01674debfd7c2e16c941a97302b739susans if (need_softintr) {
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_trigger_softintr(instance->soft_intr_id);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
6029a2d88c01674debfd7c2e16c941a97302b739susans * Not a high-level interrupt, therefore call the soft level
6029a2d88c01674debfd7c2e16c941a97302b739susans * interrupt explicitly
6029a2d88c01674debfd7c2e16c941a97302b739susans */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele (void) megasas_softintr(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_INTR_CLAIMED);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans * *
6029a2d88c01674debfd7c2e16c941a97302b739susans * libraries *
6029a2d88c01674debfd7c2e16c941a97302b739susans * *
6029a2d88c01674debfd7c2e16c941a97302b739susans * ************************************************************************** *
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * get_mfi_pkt : Get a command from the free pool
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic struct megasas_cmd *
6029a2d88c01674debfd7c2e16c941a97302b739susansget_mfi_pkt(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans mlist_t *head = &instance->cmd_pool_list;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd = NULL;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_enter(&instance->cmd_pool_mtx);
6029a2d88c01674debfd7c2e16c941a97302b739susans ASSERT(mutex_owned(&instance->cmd_pool_mtx));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (!mlist_empty(head)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd = mlist_entry(head->next, struct megasas_cmd, list);
6029a2d88c01674debfd7c2e16c941a97302b739susans mlist_del_init(head->next);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (cmd != NULL)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China cmd->pkt = NULL;
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_exit(&instance->cmd_pool_mtx);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (cmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * return_mfi_pkt : Return a cmd to free command pool
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void
6029a2d88c01674debfd7c2e16c941a97302b739susansreturn_mfi_pkt(struct megasas_instance *instance, struct megasas_cmd *cmd)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_enter(&instance->cmd_pool_mtx);
6029a2d88c01674debfd7c2e16c941a97302b739susans ASSERT(mutex_owned(&instance->cmd_pool_mtx));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans mlist_add(&cmd->list, &instance->cmd_pool_list);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_exit(&instance->cmd_pool_mtx);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * destroy_mfi_frame_pool
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void
6029a2d88c01674debfd7c2e16c941a97302b739susansdestroy_mfi_frame_pool(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int i;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t max_cmd = instance->max_fw_cmds;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* return all frames to pool */
6029a2d88c01674debfd7c2e16c941a97302b739susans for (i = 0; i < max_cmd; i++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd = instance->cmd_list[i];
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (cmd->frame_dma_obj_status == DMA_OBJ_ALLOCATED)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China (void) mega_free_dma_obj(instance, cmd->frame_dma_obj);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_dma_obj_status = DMA_OBJ_FREED;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * create_mfi_frame_pool
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susanscreate_mfi_frame_pool(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int i = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans int cookie_cnt;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint16_t max_cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint16_t sge_sz;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t sgl_sz;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t tot_frame_size;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans max_cmd = instance->max_fw_cmds;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans sge_sz = sizeof (struct megasas_sge64);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* calculated the number of 64byte frames required for SGL */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele sgl_sz = sge_sz * instance->max_num_sge;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele tot_frame_size = sgl_sz + MEGAMFI_FRAME_SIZE + SENSE_LENGTH;
6029a2d88c01674debfd7c2e16c941a97302b739susans
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
6029a2d88c01674debfd7c2e16c941a97302b739susans while (i < max_cmd) {
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd = instance->cmd_list[i];
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_dma_obj.size = tot_frame_size;
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_dma_obj.dma_attr = megasas_generic_dma_attr;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele cmd->frame_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele cmd->frame_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_dma_obj.dma_attr.dma_attr_sgllen = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_dma_obj.dma_attr.dma_attr_align = 64;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cookie_cnt = mega_alloc_dma_obj(instance, &cmd->frame_dma_obj);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (cookie_cnt == -1 || cookie_cnt > 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "create_mfi_frame_pool: could not alloc."));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans bzero(cmd->frame_dma_obj.buffer, tot_frame_size);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_dma_obj_status = DMA_OBJ_ALLOCATED;
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame = (union megasas_frame *)cmd->frame_dma_obj.buffer;
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_phys_addr =
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_dma_obj.dma_cookie[0].dmac_address;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->sense = (uint8_t *)(((unsigned long)
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_dma_obj.buffer) +
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw tot_frame_size - SENSE_LENGTH);
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->sense_phys_addr =
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_dma_obj.dma_cookie[0].dmac_address +
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw tot_frame_size - SENSE_LENGTH;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (!cmd->frame || !cmd->sense) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: pci_pool_alloc failed \n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-ENOMEM);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame->io.context = cmd->index;
6029a2d88c01674debfd7c2e16c941a97302b739susans i++;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_DLEVEL3, (CE_NOTE, "[%x]-%x",
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame->io.context, cmd->frame_phys_addr));
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_SUCCESS);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * free_additional_dma_buffer
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void
6029a2d88c01674debfd7c2e16c941a97302b739susansfree_additional_dma_buffer(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->mfi_internal_dma_obj.status == DMA_OBJ_ALLOCATED) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China (void) mega_free_dma_obj(instance,
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China instance->mfi_internal_dma_obj);
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.status = DMA_OBJ_FREED;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->mfi_evt_detail_obj.status == DMA_OBJ_ALLOCATED) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China (void) mega_free_dma_obj(instance,
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China instance->mfi_evt_detail_obj);
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_evt_detail_obj.status = DMA_OBJ_FREED;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * alloc_additional_dma_buffer
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansalloc_additional_dma_buffer(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t reply_q_sz;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t internal_buf_size = PAGESIZE*2;
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele /* max cmds plus 1 + producer & consumer */
6029a2d88c01674debfd7c2e16c941a97302b739susans reply_q_sz = sizeof (uint32_t) * (instance->max_fw_cmds + 1 + 2);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.size = internal_buf_size;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.dma_attr = megasas_generic_dma_attr;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele instance->mfi_internal_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele instance->mfi_internal_dma_obj.dma_attr.dma_attr_count_max =
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele 0xFFFFFFFFU;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.dma_attr.dma_attr_sgllen = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (mega_alloc_dma_obj(instance, &instance->mfi_internal_dma_obj)
6029a2d88c01674debfd7c2e16c941a97302b739susans != 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "megaraid: could not alloc reply Q"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans bzero(instance->mfi_internal_dma_obj.buffer, internal_buf_size);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.status |= DMA_OBJ_ALLOCATED;
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele instance->producer = (uint32_t *)((unsigned long)
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele instance->mfi_internal_dma_obj.buffer);
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->consumer = (uint32_t *)((unsigned long)
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.buffer + 4);
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->reply_queue = (uint32_t *)((unsigned long)
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.buffer + 8);
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->internal_buf = (caddr_t)(((unsigned long)
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.buffer) + reply_q_sz + 8);
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->internal_buf_dmac_add =
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address +
6029a2d88c01674debfd7c2e16c941a97302b739susans reply_q_sz;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->internal_buf_size = internal_buf_size -
6029a2d88c01674debfd7c2e16c941a97302b739susans (reply_q_sz + 8);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate evt_detail */
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_evt_detail_obj.size = sizeof (struct megasas_evt_detail);
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_evt_detail_obj.dma_attr = megasas_generic_dma_attr;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele instance->mfi_evt_detail_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele instance->mfi_evt_detail_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_evt_detail_obj.dma_attr.dma_attr_sgllen = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_evt_detail_obj.dma_attr.dma_attr_align = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
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 return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans bzero(instance->mfi_evt_detail_obj.buffer,
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_evt_detail));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_evt_detail_obj.status |= DMA_OBJ_ALLOCATED;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_SUCCESS);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * free_space_for_mfi
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void
6029a2d88c01674debfd7c2e16c941a97302b739susansfree_space_for_mfi(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int i;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t max_cmd = instance->max_fw_cmds;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* already freed */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->cmd_list == NULL) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans free_additional_dma_buffer(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* first free the MFI frame pool */
6029a2d88c01674debfd7c2e16c941a97302b739susans destroy_mfi_frame_pool(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free all the commands in the cmd_list */
6029a2d88c01674debfd7c2e16c941a97302b739susans for (i = 0; i < instance->max_fw_cmds; i++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans kmem_free(instance->cmd_list[i],
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_cmd));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->cmd_list[i] = NULL;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free the cmd_list buffer itself */
6029a2d88c01674debfd7c2e16c941a97302b739susans kmem_free(instance->cmd_list,
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_cmd *) * max_cmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->cmd_list = NULL;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans INIT_LIST_HEAD(&instance->cmd_pool_list);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * alloc_space_for_mfi
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansalloc_space_for_mfi(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int i;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t max_cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans size_t sz;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans max_cmd = instance->max_fw_cmds;
6029a2d88c01674debfd7c2e16c941a97302b739susans sz = sizeof (struct megasas_cmd *) * max_cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->cmd_list = kmem_zalloc(sz, KM_SLEEP);
6029a2d88c01674debfd7c2e16c941a97302b739susans ASSERT(instance->cmd_list);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans for (i = 0; i < max_cmd; i++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->cmd_list[i] = kmem_zalloc(sizeof (struct megasas_cmd),
6029a2d88c01674debfd7c2e16c941a97302b739susans KM_SLEEP);
6029a2d88c01674debfd7c2e16c941a97302b739susans ASSERT(instance->cmd_list[i]);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans INIT_LIST_HEAD(&instance->cmd_pool_list);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* add all the commands to command pool (instance->cmd_pool) */
6029a2d88c01674debfd7c2e16c941a97302b739susans for (i = 0; i < max_cmd; i++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd = instance->cmd_list[i];
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->index = i;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans mlist_add_tail(&cmd->list, &instance->cmd_pool_list);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* create a frame pool and assign one frame to each cmd */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (create_mfi_frame_pool(instance)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE, "error creating frame DMA pool\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* create a frame pool and assign one frame to each cmd */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (alloc_additional_dma_buffer(instance)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE, "error creating frame DMA pool\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_SUCCESS);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * get_ctrl_info
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansget_ctrl_info(struct megasas_instance *instance,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_ctrl_info *ctrl_info)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int ret = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_dcmd_frame *dcmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_ctrl_info *ci;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd = get_mfi_pkt(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (!cmd) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "Failed to get a cmd for ctrl info\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd = &cmd->frame->dcmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ci = (struct megasas_ctrl_info *)instance->internal_buf;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (!ci) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "Failed to alloc mem for ctrl info\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return_mfi_pkt(instance, cmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memset(ci, 0, sizeof (struct megasas_ctrl_info));
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele /* for( i = 0; i < DCMD_MBOX_SZ; i++ ) dcmd->mbox.b[i] = 0; */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele (void) memset(dcmd->mbox.b, 0, DCMD_MBOX_SZ);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->cmd = MFI_CMD_OP_DCMD;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele dcmd->cmd_status = MFI_CMD_STATUS_POLL_MODE;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->sge_count = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->flags = MFI_FRAME_DIR_READ;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->timeout = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->data_xfer_len = sizeof (struct megasas_ctrl_info);
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->opcode = MR_DCMD_CTRL_GET_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
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_count = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (!instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans ret = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memcpy(ctrl_info, ci, sizeof (struct megasas_ctrl_info));
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "get_ctrl_info: Ctrl info failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans ret = -1;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return_mfi_pkt(instance, cmd);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_common_check(instance, cmd) != DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ret = -1;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (ret);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * abort_aen_cmd
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansabort_aen_cmd(struct megasas_instance *instance,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd_to_abort)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int ret = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_abort_frame *abort_fr;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd = get_mfi_pkt(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (!cmd) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "Failed to get a cmd for ctrl info\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans abort_fr = &cmd->frame->abort;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* prepare and issue the abort frame */
6029a2d88c01674debfd7c2e16c941a97302b739susans abort_fr->cmd = MFI_CMD_OP_ABORT;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele abort_fr->cmd_status = MFI_CMD_STATUS_SYNC_MODE;
6029a2d88c01674debfd7c2e16c941a97302b739susans abort_fr->flags = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans abort_fr->abort_context = cmd_to_abort->index;
6029a2d88c01674debfd7c2e16c941a97302b739susans abort_fr->abort_mfi_phys_addr_lo = cmd_to_abort->frame_phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans abort_fr->abort_mfi_phys_addr_hi = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->aen_cmd->abort_aen = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->sync_cmd = MEGASAS_TRUE;
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_count = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "abort_aen_cmd: issue_cmd_in_sync_mode failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans ret = -1;
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans ret = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->aen_cmd->abort_aen = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->aen_cmd = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return_mfi_pkt(instance, cmd);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China (void) megasas_common_check(instance, cmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (ret);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * init_mfi
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansinit_mfi(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans off_t reglength;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_ctrl_info ctrl_info;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_init_frame *init_frame;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_init_queue_info *initq_info;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if ((ddi_dev_regsize(instance->dip, REGISTER_SET_IO, &reglength)
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele != DDI_SUCCESS) || reglength < MINIMUM_MFI_MEM_SZ) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele if (reglength > DEFAULT_MFI_MEM_SZ) {
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele reglength = DEFAULT_MFI_MEM_SZ;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw con_log(CL_DLEVEL1, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "mega: register length to map is 0x%lx bytes", reglength));
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_regs_map_setup(instance->dip, REGISTER_SET_IO,
6029a2d88c01674debfd7c2e16c941a97302b739susans &instance->regmap, 0, reglength, &endian_attr,
6029a2d88c01674debfd7c2e16c941a97302b739susans &instance->regmap_handle) != DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megaraid: couldn't map control registers"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans goto fail_mfi_reg_setup;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* we expect the FW state to be READY */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (mfi_state_transition_to_ready(instance)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "megaraid: F/W is not ready"));
6029a2d88c01674debfd7c2e16c941a97302b739susans goto fail_ready_state;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* get various operational parameters from status register */
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->max_num_sge =
6029a2d88c01674debfd7c2e16c941a97302b739susans (instance->func_ptr->read_fw_status_reg(instance) &
6029a2d88c01674debfd7c2e16c941a97302b739susans 0xFF0000) >> 0x10;
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->max_fw_cmds =
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->read_fw_status_reg(instance) & 0xFFFF;
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->max_fw_cmds = instance->max_fw_cmds - 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->max_num_sge =
6029a2d88c01674debfd7c2e16c941a97302b739susans (instance->max_num_sge > MEGASAS_MAX_SGE_CNT) ?
6029a2d88c01674debfd7c2e16c941a97302b739susans MEGASAS_MAX_SGE_CNT : instance->max_num_sge;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* create a pool of commands */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (alloc_space_for_mfi(instance))
6029a2d88c01674debfd7c2e16c941a97302b739susans goto fail_alloc_fw_space;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* disable interrupt for initial preparation */
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->disable_intr(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd = get_mfi_pkt(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans init_frame = (struct megasas_init_frame *)cmd->frame;
6029a2d88c01674debfd7c2e16c941a97302b739susans initq_info = (struct megasas_init_queue_info *)
6029a2d88c01674debfd7c2e16c941a97302b739susans ((unsigned long)init_frame + 64);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memset(init_frame, 0, MEGAMFI_FRAME_SIZE);
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memset(initq_info, 0, sizeof (struct megasas_init_queue_info));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans initq_info->init_flags = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans initq_info->reply_queue_entries = instance->max_fw_cmds + 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans initq_info->producer_index_phys_addr_hi = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans initq_info->producer_index_phys_addr_lo =
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans initq_info->consumer_index_phys_addr_hi = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans initq_info->consumer_index_phys_addr_lo =
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address + 4;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans initq_info->reply_queue_start_phys_addr_hi = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans initq_info->reply_queue_start_phys_addr_lo =
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address + 8;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans init_frame->cmd = MFI_CMD_OP_INIT;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele init_frame->cmd_status = MFI_CMD_STATUS_POLL_MODE;
6029a2d88c01674debfd7c2e16c941a97302b739susans init_frame->flags = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans init_frame->queue_info_new_phys_addr_lo =
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_phys_addr + 64;
6029a2d88c01674debfd7c2e16c941a97302b739susans init_frame->queue_info_new_phys_addr_hi = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans init_frame->data_xfer_len = sizeof (struct megasas_init_queue_info);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_count = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
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 goto fail_fw_init;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return_mfi_pkt(instance, cmd);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_common_check(instance, cmd) != DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China goto fail_fw_init;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* gather misc FW related information */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (!get_ctrl_info(instance, &ctrl_info)) {
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 } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->max_sectors_per_req = instance->max_num_sge *
6029a2d88c01674debfd7c2e16c941a97302b739susans PAGESIZE / 512;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China goto fail_fw_init;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansfail_fw_init:
6029a2d88c01674debfd7c2e16c941a97302b739susansfail_alloc_fw_space:
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans free_space_for_mfi(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansfail_ready_state:
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_regs_map_free(&instance->regmap_handle);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansfail_mfi_reg_setup:
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * mfi_state_transition_to_ready : Move the FW to READY state
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * @reg_set : MFI register set
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansmfi_state_transition_to_ready(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int i;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint8_t max_wait;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t fw_ctrl;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t fw_state;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t cur_state;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans fw_state =
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->read_fw_status_reg(instance) & MFI_STATE_MASK;
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "mfi_state_transition_to_ready:FW state = 0x%x", fw_state));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans while (fw_state != MFI_STATE_READY) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "mfi_state_transition_to_ready:FW state%x", fw_state));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans switch (fw_state) {
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_STATE_FAULT:
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: FW in FAULT state!!"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-ENODEV);
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_STATE_WAIT_HANDSHAKE:
6029a2d88c01674debfd7c2e16c941a97302b739susans /* set the CLR bit in IMR0 */
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: FW waiting for HANDSHAKE"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
6029a2d88c01674debfd7c2e16c941a97302b739susans * PCI_Hot Plug: MFI F/W requires
6029a2d88c01674debfd7c2e16c941a97302b739susans * (MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG)
6029a2d88c01674debfd7c2e16c941a97302b739susans * to be set
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* WR_IB_MSG_0(MFI_INIT_CLEAR_HANDSHAKE, instance); */
6029a2d88c01674debfd7c2e16c941a97302b739susans WR_IB_DOORBELL(MFI_INIT_CLEAR_HANDSHAKE |
6029a2d88c01674debfd7c2e16c941a97302b739susans MFI_INIT_HOTPLUG, instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans max_wait = 2;
6029a2d88c01674debfd7c2e16c941a97302b739susans cur_state = MFI_STATE_WAIT_HANDSHAKE;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_STATE_BOOT_MESSAGE_PENDING:
6029a2d88c01674debfd7c2e16c941a97302b739susans /* set the CLR bit in IMR0 */
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: FW state boot message pending"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
6029a2d88c01674debfd7c2e16c941a97302b739susans * PCI_Hot Plug: MFI F/W requires
6029a2d88c01674debfd7c2e16c941a97302b739susans * (MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG)
6029a2d88c01674debfd7c2e16c941a97302b739susans * to be set
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans WR_IB_DOORBELL(MFI_INIT_HOTPLUG, instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans max_wait = 10;
6029a2d88c01674debfd7c2e16c941a97302b739susans cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_STATE_OPERATIONAL:
6029a2d88c01674debfd7c2e16c941a97302b739susans /* bring it to READY state; assuming max wait 2 secs */
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->disable_intr(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: FW in OPERATIONAL state"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
6029a2d88c01674debfd7c2e16c941a97302b739susans * PCI_Hot Plug: MFI F/W requires
6029a2d88c01674debfd7c2e16c941a97302b739susans * (MFI_INIT_READY | MFI_INIT_MFIMODE | MFI_INIT_ABORT)
6029a2d88c01674debfd7c2e16c941a97302b739susans * to be set
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* WR_IB_DOORBELL(MFI_INIT_READY, instance); */
6029a2d88c01674debfd7c2e16c941a97302b739susans WR_IB_DOORBELL(MFI_RESET_FLAGS, instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans max_wait = 10;
6029a2d88c01674debfd7c2e16c941a97302b739susans cur_state = MFI_STATE_OPERATIONAL;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_STATE_UNDEFINED:
6029a2d88c01674debfd7c2e16c941a97302b739susans /* this state should not last for more than 2 seconds */
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE, "FW state undefined\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans max_wait = 2;
6029a2d88c01674debfd7c2e16c941a97302b739susans cur_state = MFI_STATE_UNDEFINED;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_STATE_BB_INIT:
6029a2d88c01674debfd7c2e16c941a97302b739susans max_wait = 2;
6029a2d88c01674debfd7c2e16c941a97302b739susans cur_state = MFI_STATE_BB_INIT;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_STATE_FW_INIT:
6029a2d88c01674debfd7c2e16c941a97302b739susans max_wait = 2;
6029a2d88c01674debfd7c2e16c941a97302b739susans cur_state = MFI_STATE_FW_INIT;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_STATE_DEVICE_SCAN:
6029a2d88c01674debfd7c2e16c941a97302b739susans max_wait = 10;
6029a2d88c01674debfd7c2e16c941a97302b739susans cur_state = MFI_STATE_DEVICE_SCAN;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans default:
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas: Unknown state 0x%x\n", fw_state));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-ENODEV);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* the cur_state should not last for more than max_wait secs */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele for (i = 0; i < (max_wait * MILLISEC); i++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans /* fw_state = RD_OB_MSG_0(instance) & MFI_STATE_MASK; */
6029a2d88c01674debfd7c2e16c941a97302b739susans fw_state =
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->read_fw_status_reg(instance) &
6029a2d88c01674debfd7c2e16c941a97302b739susans MFI_STATE_MASK;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (fw_state == cur_state) {
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele delay(1 * drv_usectohz(MILLISEC));
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* return error if fw_state hasn't changed after max_wait */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (fw_state == cur_state) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "FW state hasn't changed in %d secs\n", max_wait));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-ENODEV);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans };
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans fw_ctrl = RD_IB_DOORBELL(instance);
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "mfi_state_transition_to_ready:FW ctrl = 0x%x", fw_ctrl));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
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 * (bit 3).
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans WR_IB_DOORBELL(0xF, instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (-ENODEV);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * get_seq_num
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansget_seq_num(struct megasas_instance *instance,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_evt_log_info *eli)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int ret = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans dma_obj_t dcmd_dma_obj;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_dcmd_frame *dcmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd = get_mfi_pkt(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (!cmd) {
6029a2d88c01674debfd7c2e16c941a97302b739susans cmn_err(CE_WARN, "megasas: failed to get a cmd\n");
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-ENOMEM);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd = &cmd->frame->dcmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate the data transfer buffer */
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd_dma_obj.size = sizeof (struct megasas_evt_log_info);
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd_dma_obj.dma_attr = megasas_generic_dma_attr;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele dcmd_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele dcmd_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd_dma_obj.dma_attr.dma_attr_sgllen = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd_dma_obj.dma_attr.dma_attr_align = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (mega_alloc_dma_obj(instance, &dcmd_dma_obj) != 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "get_seq_num: could not data transfer buffer alloc."));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memset(dcmd_dma_obj.buffer, 0,
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_evt_log_info));
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele (void) memset(dcmd->mbox.b, 0, DCMD_MBOX_SZ);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->cmd = MFI_CMD_OP_DCMD;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->cmd_status = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->sge_count = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->flags = MFI_FRAME_DIR_READ;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->timeout = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->data_xfer_len = sizeof (struct megasas_evt_log_info);
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->opcode = MR_DCMD_CTRL_EVENT_GET_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
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->sync_cmd = MEGASAS_TRUE;
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_count = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans cmn_err(CE_WARN, "get_seq_num: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "failed to issue MR_DCMD_CTRL_EVENT_GET_INFO\n");
6029a2d88c01674debfd7c2e16c941a97302b739susans ret = -1;
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans /* copy the data back into callers buffer */
6029a2d88c01674debfd7c2e16c941a97302b739susans bcopy(dcmd_dma_obj.buffer, eli,
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_evt_log_info));
6029a2d88c01674debfd7c2e16c941a97302b739susans ret = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (mega_free_dma_obj(instance, dcmd_dma_obj) != DDI_SUCCESS)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ret = -1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return_mfi_pkt(instance, cmd);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_common_check(instance, cmd) != DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ret = -1;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
6029a2d88c01674debfd7c2e16c941a97302b739susans return (ret);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * start_mfi_aen
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansstart_mfi_aen(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int ret = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_evt_log_info eli;
6029a2d88c01674debfd7c2e16c941a97302b739susans union megasas_evt_class_locale class_locale;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* get the latest sequence number from FW */
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memset(&eli, 0, sizeof (struct megasas_evt_log_info));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (get_seq_num(instance, &eli)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans cmn_err(CE_WARN, "start_mfi_aen: failed to get seq num\n");
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* register AEN with FW for latest sequence number plus 1 */
6029a2d88c01674debfd7c2e16c941a97302b739susans class_locale.members.reserved = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans class_locale.members.locale = MR_EVT_LOCALE_ALL;
6029a2d88c01674debfd7c2e16c941a97302b739susans class_locale.members.class = MR_EVT_CLASS_CRITICAL;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ret = register_mfi_aen(instance, eli.newest_seq_num + 1,
6029a2d88c01674debfd7c2e16c941a97302b739susans class_locale.word);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ret) {
6029a2d88c01674debfd7c2e16c941a97302b739susans cmn_err(CE_WARN, "start_mfi_aen: aen registration failed\n");
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (ret);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * flush_cache
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void
6029a2d88c01674debfd7c2e16c941a97302b739susansflush_cache(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_dcmd_frame *dcmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (!(cmd = get_mfi_pkt(instance)))
6029a2d88c01674debfd7c2e16c941a97302b739susans return;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd = &cmd->frame->dcmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele (void) memset(dcmd->mbox.b, 0, DCMD_MBOX_SZ);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->cmd = MFI_CMD_OP_DCMD;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->cmd_status = 0x0;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->sge_count = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->flags = MFI_FRAME_DIR_NONE;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->timeout = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->data_xfer_len = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->opcode = MR_DCMD_CTRL_CACHE_FLUSH;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_count = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans cmn_err(CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "flush_cache: failed to issue MFI_DCMD_CTRL_CACHE_FLUSH\n");
6029a2d88c01674debfd7c2e16c941a97302b739susans }
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw con_log(CL_DLEVEL1, (CE_NOTE, "done"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return_mfi_pkt(instance, cmd);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China (void) megasas_common_check(instance, cmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * service_mfi_aen- Completes an AEN command
6029a2d88c01674debfd7c2e16c941a97302b739susans * @instance: Adapter soft state
6029a2d88c01674debfd7c2e16c941a97302b739susans * @cmd: Command to be completed
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void
6029a2d88c01674debfd7c2e16c941a97302b739susansservice_mfi_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t seq_num;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_evt_detail *evt_detail =
6029a2d88c01674debfd7c2e16c941a97302b739susans (struct megasas_evt_detail *)instance->mfi_evt_detail_obj.buffer;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->cmd_status = cmd->frame->io.cmd_status;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (cmd->cmd_status == ENODATA) {
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->cmd_status = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
6029a2d88c01674debfd7c2e16c941a97302b739susans * log the MFI AEN event to the sysevent queue so that
6029a2d88c01674debfd7c2e16c941a97302b739susans * application will get noticed
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_log_sysevent(instance->dip, DDI_VENDOR_LSI, "LSIMEGA", "SAS",
6029a2d88c01674debfd7c2e16c941a97302b739susans NULL, NULL, DDI_NOSLEEP) != DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans int instance_no = ddi_get_instance(instance->dip);
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "mega%d: Failed to log AEN event", instance_no));
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* get copy of seq_num and class/locale for re-registration */
6029a2d88c01674debfd7c2e16c941a97302b739susans seq_num = evt_detail->seq_num;
6029a2d88c01674debfd7c2e16c941a97302b739susans seq_num++;
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memset(instance->mfi_evt_detail_obj.buffer, 0,
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_evt_detail));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame->dcmd.cmd_status = 0x0;
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame->dcmd.mbox.w[0] = seq_num;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->aen_seq_num = seq_num;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_count = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Issue the aen registration frame */
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->issue_cmd(cmd, instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * complete_cmd_in_sync_mode - Completes an internal command
6029a2d88c01674debfd7c2e16c941a97302b739susans * @instance: Adapter soft state
6029a2d88c01674debfd7c2e16c941a97302b739susans * @cmd: Command to be completed
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void
6029a2d88c01674debfd7c2e16c941a97302b739susanscomplete_cmd_in_sync_mode(struct megasas_instance *instance,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->cmd_status = cmd->frame->io.cmd_status;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->sync_cmd = MEGASAS_FALSE;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (cmd->cmd_status == ENODATA) {
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->cmd_status = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cv_broadcast(&instance->int_cmd_cv);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * megasas_softintr - The Software ISR
6029a2d88c01674debfd7c2e16c941a97302b739susans * @param arg : HBA soft state
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * called from high-level interrupt if hi-level interrupt are not there,
6029a2d88c01674debfd7c2e16c941a97302b739susans * otherwise triggered as a soft interrupt
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic uint_t
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufelemegasas_softintr(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans struct scsi_pkt *pkt;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct scsa_cmd *acmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct mlist_head *pos, *next;
6029a2d88c01674debfd7c2e16c941a97302b739susans mlist_t process_list;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_header *hdr;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele struct scsi_arq_status *arqstat;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_CONT, "megasas_softintr called"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele ASSERT(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_enter(&instance->completed_pool_mtx);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (mlist_empty(&instance->completed_pool_list)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_exit(&instance->completed_pool_mtx);
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_INTR_UNCLAIMED);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->softint_running = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans INIT_LIST_HEAD(&process_list);
6029a2d88c01674debfd7c2e16c941a97302b739susans mlist_splice(&instance->completed_pool_list, &process_list);
6029a2d88c01674debfd7c2e16c941a97302b739susans INIT_LIST_HEAD(&instance->completed_pool_list);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_exit(&instance->completed_pool_mtx);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* perform all callbacks first, before releasing the SCBs */
6029a2d88c01674debfd7c2e16c941a97302b739susans mlist_for_each_safe(pos, next, &process_list) {
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd = mlist_entry(pos, struct megasas_cmd, list);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* syncronize the Cmd frame for the controller */
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) ddi_dma_sync(cmd->frame_dma_obj.dma_handle,
6029a2d88c01674debfd7c2e16c941a97302b739susans 0, 0, DDI_DMA_SYNC_FORCPU);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_dma_handle(cmd->frame_dma_obj.dma_handle) !=
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (DDI_INTR_UNCLAIMED);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
6029a2d88c01674debfd7c2e16c941a97302b739susans hdr = &cmd->frame->hdr;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* remove the internal command from the process list */
6029a2d88c01674debfd7c2e16c941a97302b739susans mlist_del_init(&cmd->list);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans switch (hdr->cmd) {
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_CMD_OP_PD_SCSI:
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_CMD_OP_LD_SCSI:
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_CMD_OP_LD_READ:
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_CMD_OP_LD_WRITE:
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (cmd->sync_cmd == MEGASAS_TRUE) {
6029a2d88c01674debfd7c2e16c941a97302b739susans complete_cmd_in_sync_mode(instance, cmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* regular commands */
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd = cmd->cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt = CMD2PKT(acmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (acmd->cmd_flags & CFLAG_DMAVALID) {
6029a2d88c01674debfd7c2e16c941a97302b739susans if (acmd->cmd_flags & CFLAG_CONSISTENT) {
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) ddi_dma_sync(acmd->cmd_dmahandle,
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_dma_offset,
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_dma_len,
6029a2d88c01674debfd7c2e16c941a97302b739susans DDI_DMA_SYNC_FORCPU);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_reason = CMD_CMPLT;
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_statistics = 0;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw pkt->pkt_state = STATE_GOT_BUS
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw | STATE_GOT_TARGET | STATE_SENT_CMD
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw | STATE_XFERRED_DATA | STATE_GOT_STATUS;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_CONT,
6029a2d88c01674debfd7c2e16c941a97302b739susans "CDB[0] = %x completed for %s: size %lx context %x",
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_cdbp[0], ((acmd->islogical) ? "LD" : "PD"),
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_dmacount, hdr->context));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (pkt->pkt_cdbp[0] == SCMD_INQUIRY) {
6029a2d88c01674debfd7c2e16c941a97302b739susans struct scsi_inquiry *inq;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (acmd->cmd_dmacount != 0) {
6029a2d88c01674debfd7c2e16c941a97302b739susans bp_mapin(acmd->cmd_buf);
6029a2d88c01674debfd7c2e16c941a97302b739susans inq = (struct scsi_inquiry *)
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_buf->b_un.b_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* don't expose physical drives to OS */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (acmd->islogical &&
6029a2d88c01674debfd7c2e16c941a97302b739susans (hdr->cmd_status == MFI_STAT_OK)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans display_scsi_inquiry(
6029a2d88c01674debfd7c2e16c941a97302b739susans (caddr_t)inq);
6029a2d88c01674debfd7c2e16c941a97302b739susans } else if ((hdr->cmd_status ==
6029a2d88c01674debfd7c2e16c941a97302b739susans MFI_STAT_OK) && inq->inq_dtype ==
6029a2d88c01674debfd7c2e16c941a97302b739susans DTYPE_DIRECT) {
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans display_scsi_inquiry(
6029a2d88c01674debfd7c2e16c941a97302b739susans (caddr_t)inq);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* for physical disk */
6029a2d88c01674debfd7c2e16c941a97302b739susans hdr->cmd_status =
6029a2d88c01674debfd7c2e16c941a97302b739susans MFI_STAT_DEVICE_NOT_FOUND;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans switch (hdr->cmd_status) {
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_STAT_OK:
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_scbp[0] = STATUS_GOOD;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_STAT_LD_CC_IN_PROGRESS:
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_STAT_LD_RECON_IN_PROGRESS:
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ - these are not correct way */
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_scbp[0] = STATUS_GOOD;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw break;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw case MFI_STAT_LD_INIT_IN_PROGRESS:
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw con_log(CL_ANN,
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw (CE_WARN, "Initialization in Progress"));
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw pkt->pkt_reason = CMD_TRAN_ERR;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_STAT_SCSI_DONE_WITH_ERROR:
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_CONT, "scsi_done error"));
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw pkt->pkt_reason = CMD_CMPLT;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw ((struct scsi_status *)
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw pkt->pkt_scbp)->sts_chk = 1;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw if (pkt->pkt_cdbp[0] == SCMD_TEST_UNIT_READY) {
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw con_log(CL_ANN,
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw (CE_WARN, "TEST_UNIT_READY fail"));
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw pkt->pkt_state |= STATE_ARQ_DONE;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw arqstat = (void *)(pkt->pkt_scbp);
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw arqstat->sts_rqpkt_reason = CMD_CMPLT;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw arqstat->sts_rqpkt_resid = 0;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw arqstat->sts_rqpkt_state |=
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw STATE_GOT_BUS | STATE_GOT_TARGET
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw | STATE_SENT_CMD
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw | STATE_XFERRED_DATA;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw *(uint8_t *)&arqstat->sts_rqpkt_status =
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw STATUS_GOOD;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw bcopy(cmd->sense,
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw &(arqstat->sts_sensedata),
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele acmd->cmd_scblen -
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw offsetof(struct scsi_arq_status,
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw sts_sensedata));
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw case MFI_STAT_LD_OFFLINE:
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_STAT_DEVICE_NOT_FOUND:
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_CONT,
6029a2d88c01674debfd7c2e16c941a97302b739susans "device not found error"));
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_reason = CMD_DEV_GONE;
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_statistics = STAT_DISCON;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw case MFI_STAT_LD_LBA_OUT_OF_RANGE:
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw pkt->pkt_state |= STATE_ARQ_DONE;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw pkt->pkt_reason = CMD_CMPLT;
6029a2d88c01674debfd7c2e16c941a97302b739susans ((struct scsi_status *)
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw pkt->pkt_scbp)->sts_chk = 1;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw arqstat = (void *)(pkt->pkt_scbp);
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw arqstat->sts_rqpkt_reason = CMD_CMPLT;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw arqstat->sts_rqpkt_resid = 0;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw arqstat->sts_rqpkt_state |= STATE_GOT_BUS
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw | STATE_GOT_TARGET | STATE_SENT_CMD
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw | STATE_XFERRED_DATA;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw *(uint8_t *)&arqstat->sts_rqpkt_status =
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw STATUS_GOOD;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw arqstat->sts_sensedata.es_valid = 1;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw arqstat->sts_sensedata.es_key =
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw KEY_ILLEGAL_REQUEST;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw arqstat->sts_sensedata.es_class =
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw CLASS_EXTENDED_SENSE;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw /*
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw * LOGICAL BLOCK ADDRESS OUT OF RANGE:
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw * ASC: 0x21h; ASCQ: 0x00h;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw */
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw arqstat->sts_sensedata.es_add_code = 0x21;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw arqstat->sts_sensedata.es_qual_code = 0x00;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw break;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw default:
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw con_log(CL_ANN, (CE_CONT, "Unknown status!"));
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw pkt->pkt_reason = CMD_TRAN_ERR;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans atomic_add_16(&instance->fw_outstanding, (-1));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return_mfi_pkt(instance, cmd);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China (void) megasas_common_check(instance, cmd);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (acmd->cmd_dmahandle) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_dma_handle(
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China acmd->cmd_dmahandle) != DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip,
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China DDI_SERVICE_UNAFFECTED);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China pkt->pkt_reason = CMD_TRAN_ERR;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China pkt->pkt_statistics = 0;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Call the callback routine */
9c57abc8d70cb139020be846baec0a9c4d9a73cdsrivijitha dugganapalli if ((pkt->pkt_flags & FLAG_NOINTR) == 0) {
9c57abc8d70cb139020be846baec0a9c4d9a73cdsrivijitha dugganapalli scsi_hba_pkt_comp(pkt);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_CMD_OP_SMP:
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_CMD_OP_STP:
6029a2d88c01674debfd7c2e16c941a97302b739susans complete_cmd_in_sync_mode(instance, cmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_CMD_OP_DCMD:
6029a2d88c01674debfd7c2e16c941a97302b739susans /* see if got an event notification */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (cmd->frame->dcmd.opcode ==
6029a2d88c01674debfd7c2e16c941a97302b739susans MR_DCMD_CTRL_EVENT_WAIT) {
6029a2d88c01674debfd7c2e16c941a97302b739susans if ((instance->aen_cmd == cmd) &&
6029a2d88c01674debfd7c2e16c941a97302b739susans (instance->aen_cmd->abort_aen)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "megasas_softintr: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "aborted_aen returned"));
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans service_mfi_aen(instance, cmd);
14cd9973e77e9bfa1eca7f8e24ff5786853576c5Susan Scheufele
14cd9973e77e9bfa1eca7f8e24ff5786853576c5Susan Scheufele atomic_add_16(&instance->fw_outstanding,
14cd9973e77e9bfa1eca7f8e24ff5786853576c5Susan Scheufele (-1));
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans complete_cmd_in_sync_mode(instance, cmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_CMD_OP_ABORT:
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "MFI_CMD_OP_ABORT complete"));
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
6029a2d88c01674debfd7c2e16c941a97302b739susans * MFI_CMD_OP_ABORT successfully completed
6029a2d88c01674debfd7c2e16c941a97302b739susans * in the synchronous mode
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans complete_cmd_in_sync_mode(instance, cmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans default:
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (cmd->pkt != NULL) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China pkt = cmd->pkt;
9c57abc8d70cb139020be846baec0a9c4d9a73cdsrivijitha dugganapalli if ((pkt->pkt_flags & FLAG_NOINTR) == 0) {
9c57abc8d70cb139020be846baec0a9c4d9a73cdsrivijitha dugganapalli scsi_hba_pkt_comp(pkt);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China con_log(CL_ANN, (CE_WARN, "Cmd type unknown !!"));
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->softint_running = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_INTR_CLAIMED);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * mega_alloc_dma_obj
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * Allocate the memory and other resources for an dma object.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansmega_alloc_dma_obj(struct megasas_instance *instance, dma_obj_t *obj)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int i;
6029a2d88c01674debfd7c2e16c941a97302b739susans size_t alen = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint_t cookie_cnt;
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson struct ddi_device_acc_attr tmp_endian_attr;
6029a2d88c01674debfd7c2e16c941a97302b739susans
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson tmp_endian_attr = endian_attr;
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson tmp_endian_attr.devacc_attr_access = DDI_DEFAULT_ACC;
6029a2d88c01674debfd7c2e16c941a97302b739susans i = ddi_dma_alloc_handle(instance->dip, &obj->dma_attr,
6029a2d88c01674debfd7c2e16c941a97302b739susans DDI_DMA_SLEEP, NULL, &obj->dma_handle);
6029a2d88c01674debfd7c2e16c941a97302b739susans if (i != DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans switch (i) {
6029a2d88c01674debfd7c2e16c941a97302b739susans case DDI_DMA_BADATTR :
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "Failed ddi_dma_alloc_handle- Bad atrib"));
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case DDI_DMA_NORESOURCES :
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "Failed ddi_dma_alloc_handle- No Resources"));
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans default :
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "Failed ddi_dma_alloc_handle :unknown %d", i));
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson if ((ddi_dma_mem_alloc(obj->dma_handle, obj->size, &tmp_endian_attr,
6029a2d88c01674debfd7c2e16c941a97302b739susans DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL,
6029a2d88c01674debfd7c2e16c941a97302b739susans &obj->buffer, &alen, &obj->acc_handle) != DDI_SUCCESS) ||
6029a2d88c01674debfd7c2e16c941a97302b739susans alen < obj->size) {
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_dma_free_handle(&obj->dma_handle);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "Failed : ddi_dma_mem_alloc"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
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
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_dma_mem_free(&obj->acc_handle);
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_dma_free_handle(&obj->dma_handle);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "Failed : ddi_dma_addr_bind_handle"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_dma_handle(obj->dma_handle) != DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (-1);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_acc_handle(obj->acc_handle) != DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (-1);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
6029a2d88c01674debfd7c2e16c941a97302b739susans return (cookie_cnt);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * mega_free_dma_obj(struct megasas_instance *, dma_obj_t)
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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 */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinastatic int
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinamega_free_dma_obj(struct megasas_instance *instance, dma_obj_t obj)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_dma_handle(obj.dma_handle) != DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (DDI_FAILURE);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_acc_handle(obj.acc_handle) != DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (DDI_FAILURE);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) ddi_dma_unbind_handle(obj.dma_handle);
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_dma_mem_free(&obj.acc_handle);
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_dma_free_handle(&obj.dma_handle);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (DDI_SUCCESS);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * megasas_dma_alloc(instance_t *, struct scsi_pkt *, struct buf *,
6029a2d88c01674debfd7c2e16c941a97302b739susans * int, int (*)())
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * Allocate dma resources for a new scsi command
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_dma_alloc(struct megasas_instance *instance, struct scsi_pkt *pkt,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct buf *bp, int flags, int (*callback)())
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int dma_flags;
6029a2d88c01674debfd7c2e16c941a97302b739susans int (*cb)(caddr_t);
6029a2d88c01674debfd7c2e16c941a97302b739susans int i;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_dma_attr_t tmp_dma_attr = megasas_generic_dma_attr;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct scsa_cmd *acmd = PKT2CMD(pkt);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_buf = bp;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (bp->b_flags & B_READ) {
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_flags &= ~CFLAG_DMASEND;
6029a2d88c01674debfd7c2e16c941a97302b739susans dma_flags = DDI_DMA_READ;
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_flags |= CFLAG_DMASEND;
6029a2d88c01674debfd7c2e16c941a97302b739susans dma_flags = DDI_DMA_WRITE;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (flags & PKT_CONSISTENT) {
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_flags |= CFLAG_CONSISTENT;
6029a2d88c01674debfd7c2e16c941a97302b739susans dma_flags |= DDI_DMA_CONSISTENT;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (flags & PKT_DMA_PARTIAL) {
6029a2d88c01674debfd7c2e16c941a97302b739susans dma_flags |= DDI_DMA_PARTIAL;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans dma_flags |= DDI_DMA_REDZONE;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cb = (callback == NULL_FUNC) ? DDI_DMA_DONTWAIT : DDI_DMA_SLEEP;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans tmp_dma_attr.dma_attr_sgllen = instance->max_num_sge;
03b14217e5b4702d6fc4b2ef4ece78b0cc99fc31Yu Wu - Sun Microsystems - Beijing China tmp_dma_attr.dma_attr_addr_hi = 0xffffffffffffffffull;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if ((i = ddi_dma_alloc_handle(instance->dip, &tmp_dma_attr,
6029a2d88c01674debfd7c2e16c941a97302b739susans cb, 0, &acmd->cmd_dmahandle)) != DDI_SUCCESS) {
6029a2d88c01674debfd7c2e16c941a97302b739susans switch (i) {
6029a2d88c01674debfd7c2e16c941a97302b739susans case DDI_DMA_BADATTR:
6029a2d88c01674debfd7c2e16c941a97302b739susans bioerror(bp, EFAULT);
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans case DDI_DMA_NORESOURCES:
6029a2d88c01674debfd7c2e16c941a97302b739susans bioerror(bp, 0);
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans default:
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_PANIC, "ddi_dma_alloc_handle: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "0x%x impossible\n", i));
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele bioerror(bp, EFAULT);
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans i = ddi_dma_buf_bind_handle(acmd->cmd_dmahandle, bp, dma_flags,
6029a2d88c01674debfd7c2e16c941a97302b739susans cb, 0, &acmd->cmd_dmacookies[0], &acmd->cmd_ncookies);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans switch (i) {
6029a2d88c01674debfd7c2e16c941a97302b739susans case DDI_DMA_PARTIAL_MAP:
6029a2d88c01674debfd7c2e16c941a97302b739susans if ((dma_flags & DDI_DMA_PARTIAL) == 0) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_PANIC, "ddi_dma_buf_bind_handle: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "DDI_DMA_PARTIAL_MAP impossible\n"));
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele goto no_dma_cookies;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_dma_numwin(acmd->cmd_dmahandle, &acmd->cmd_nwin) ==
6029a2d88c01674debfd7c2e16c941a97302b739susans DDI_FAILURE) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_PANIC, "ddi_dma_numwin failed\n"));
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele goto no_dma_cookies;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_dma_getwin(acmd->cmd_dmahandle, acmd->cmd_curwin,
6029a2d88c01674debfd7c2e16c941a97302b739susans &acmd->cmd_dma_offset, &acmd->cmd_dma_len,
6029a2d88c01674debfd7c2e16c941a97302b739susans &acmd->cmd_dmacookies[0], &acmd->cmd_ncookies) ==
6029a2d88c01674debfd7c2e16c941a97302b739susans DDI_FAILURE) {
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_PANIC, "ddi_dma_getwin failed\n"));
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele goto no_dma_cookies;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans goto get_dma_cookies;
6029a2d88c01674debfd7c2e16c941a97302b739susans case DDI_DMA_MAPPED:
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_nwin = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_dma_len = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_dma_offset = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansget_dma_cookies:
6029a2d88c01674debfd7c2e16c941a97302b739susans i = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_dmacount = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans for (;;) {
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_dmacount +=
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_dmacookies[i++].dmac_size;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (i == instance->max_num_sge ||
6029a2d88c01674debfd7c2e16c941a97302b739susans i == acmd->cmd_ncookies)
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_dma_nextcookie(acmd->cmd_dmahandle,
6029a2d88c01674debfd7c2e16c941a97302b739susans &acmd->cmd_dmacookies[i]);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_cookie = i;
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_cookiecnt = i;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_flags |= CFLAG_DMAVALID;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (bp->b_bcount >= acmd->cmd_dmacount) {
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_resid = bp->b_bcount - acmd->cmd_dmacount;
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_resid = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans case DDI_DMA_NORESOURCES:
6029a2d88c01674debfd7c2e16c941a97302b739susans bioerror(bp, 0);
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case DDI_DMA_NOMAPPING:
6029a2d88c01674debfd7c2e16c941a97302b739susans bioerror(bp, EFAULT);
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case DDI_DMA_TOOBIG:
6029a2d88c01674debfd7c2e16c941a97302b739susans bioerror(bp, EINVAL);
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case DDI_DMA_INUSE:
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_PANIC, "ddi_dma_buf_bind_handle:"
6029a2d88c01674debfd7c2e16c941a97302b739susans " DDI_DMA_INUSE impossible\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans default:
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_PANIC, "ddi_dma_buf_bind_handle: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "0x%x impossible\n", i));
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufeleno_dma_cookies:
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_dma_free_handle(&acmd->cmd_dmahandle);
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_dmahandle = NULL;
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_flags &= ~CFLAG_DMAVALID;
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * megasas_dma_move(struct megasas_instance *, struct scsi_pkt *, struct buf *)
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * move dma resources to next dma window
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansmegasas_dma_move(struct megasas_instance *instance, struct scsi_pkt *pkt,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct buf *bp)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int i = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans struct scsa_cmd *acmd = PKT2CMD(pkt);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
6029a2d88c01674debfd7c2e16c941a97302b739susans * If there are no more cookies remaining in this window,
6029a2d88c01674debfd7c2e16c941a97302b739susans * must move to the next window first.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (acmd->cmd_cookie == acmd->cmd_ncookies) {
6029a2d88c01674debfd7c2e16c941a97302b739susans if (acmd->cmd_curwin == acmd->cmd_nwin && acmd->cmd_nwin == 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* at last window, cannot move */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (++acmd->cmd_curwin >= acmd->cmd_nwin) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_dma_getwin(acmd->cmd_dmahandle, acmd->cmd_curwin,
6029a2d88c01674debfd7c2e16c941a97302b739susans &acmd->cmd_dma_offset, &acmd->cmd_dma_len,
6029a2d88c01674debfd7c2e16c941a97302b739susans &acmd->cmd_dmacookies[0], &acmd->cmd_ncookies) ==
6029a2d88c01674debfd7c2e16c941a97302b739susans DDI_FAILURE) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_cookie = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans /* still more cookies in this window - get the next one */
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_dma_nextcookie(acmd->cmd_dmahandle,
6029a2d88c01674debfd7c2e16c941a97302b739susans &acmd->cmd_dmacookies[0]);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* get remaining cookies in this window, up to our maximum */
6029a2d88c01674debfd7c2e16c941a97302b739susans for (;;) {
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_dmacount += acmd->cmd_dmacookies[i++].dmac_size;
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_cookie++;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (i == instance->max_num_sge ||
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_cookie == acmd->cmd_ncookies) {
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_dma_nextcookie(acmd->cmd_dmahandle,
6029a2d88c01674debfd7c2e16c941a97302b739susans &acmd->cmd_dmacookies[i]);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_cookiecnt = i;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (bp->b_bcount >= acmd->cmd_dmacount) {
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_resid = bp->b_bcount - acmd->cmd_dmacount;
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_resid = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * build_cmd
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic struct megasas_cmd *
6029a2d88c01674debfd7c2e16c941a97302b739susansbuild_cmd(struct megasas_instance *instance, struct scsi_address *ap,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct scsi_pkt *pkt, uchar_t *cmd_done)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans uint16_t flags = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t i;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t context;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t sge_bytes;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd;
03b14217e5b4702d6fc4b2ef4ece78b0cc99fc31Yu Wu - Sun Microsystems - Beijing China struct megasas_sge64 *mfi_sgl;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct scsa_cmd *acmd = PKT2CMD(pkt);
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_pthru_frame *pthru;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_io_frame *ldio;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* find out if this is logical or physical drive command. */
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->islogical = MEGADRV_IS_LOGICAL(ap);
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->device_id = MAP_DEVICE_ID(instance, ap);
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw *cmd_done = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* get the command packet */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (!(cmd = get_mfi_pkt(instance))) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (NULL);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->pkt = pkt;
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->cmd = acmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* lets get the command directions */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (acmd->cmd_flags & CFLAG_DMASEND) {
6029a2d88c01674debfd7c2e16c941a97302b739susans flags = MFI_FRAME_DIR_WRITE;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (acmd->cmd_flags & CFLAG_CONSISTENT) {
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) ddi_dma_sync(acmd->cmd_dmahandle,
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_dma_offset, acmd->cmd_dma_len,
6029a2d88c01674debfd7c2e16c941a97302b739susans DDI_DMA_SYNC_FORDEV);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans } else if (acmd->cmd_flags & ~CFLAG_DMASEND) {
6029a2d88c01674debfd7c2e16c941a97302b739susans flags = MFI_FRAME_DIR_READ;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (acmd->cmd_flags & CFLAG_CONSISTENT) {
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) ddi_dma_sync(acmd->cmd_dmahandle,
6029a2d88c01674debfd7c2e16c941a97302b739susans acmd->cmd_dma_offset, acmd->cmd_dma_len,
6029a2d88c01674debfd7c2e16c941a97302b739susans DDI_DMA_SYNC_FORCPU);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans flags = MFI_FRAME_DIR_NONE;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
03b14217e5b4702d6fc4b2ef4ece78b0cc99fc31Yu Wu - Sun Microsystems - Beijing China flags |= MFI_FRAME_SGL64;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans switch (pkt->pkt_cdbp[0]) {
6029a2d88c01674debfd7c2e16c941a97302b739susans
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw /*
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw * case SCMD_SYNCHRONIZE_CACHE:
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw * flush_cache(instance);
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw * return_mfi_pkt(instance, cmd);
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw * *cmd_done = 1;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw *
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw * return (NULL);
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw */
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCMD_READ:
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCMD_WRITE:
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCMD_READ_G1:
6029a2d88c01674debfd7c2e16c941a97302b739susans case SCMD_WRITE_G1:
6029a2d88c01674debfd7c2e16c941a97302b739susans if (acmd->islogical) {
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio = (struct megasas_io_frame *)cmd->frame;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
6029a2d88c01674debfd7c2e16c941a97302b739susans * preare the Logical IO frame:
6029a2d88c01674debfd7c2e16c941a97302b739susans * 2nd bit is zero for all read cmds
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio->cmd = (pkt->pkt_cdbp[0] & 0x02) ?
6029a2d88c01674debfd7c2e16c941a97302b739susans MFI_CMD_OP_LD_WRITE : MFI_CMD_OP_LD_READ;
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio->cmd_status = 0x0;
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio->scsi_status = 0x0;
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio->target_id = acmd->device_id;
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio->timeout = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio->reserved_0 = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio->pad_0 = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio->flags = flags;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw /* Initialize sense Information */
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw bzero(cmd->sense, SENSE_LENGTH);
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw ldio->sense_len = SENSE_LENGTH;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw ldio->sense_buf_phys_addr_hi = 0;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw ldio->sense_buf_phys_addr_lo = cmd->sense_phys_addr;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio->start_lba_hi = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio->access_byte = (acmd->cmd_cdblen != 6) ?
6029a2d88c01674debfd7c2e16c941a97302b739susans pkt->pkt_cdbp[1] : 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio->sge_count = acmd->cmd_cookiecnt;
03b14217e5b4702d6fc4b2ef4ece78b0cc99fc31Yu Wu - Sun Microsystems - Beijing China mfi_sgl = (struct megasas_sge64 *)&ldio->sgl;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans context = ldio->context;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (acmd->cmd_cdblen == CDB_GROUP0) {
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio->lba_count = host_to_le16(
6029a2d88c01674debfd7c2e16c941a97302b739susans (uint16_t)(pkt->pkt_cdbp[4]));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio->start_lba_lo = host_to_le32(
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint32_t)(pkt->pkt_cdbp[3])) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint32_t)(pkt->pkt_cdbp[2]) << 8) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint32_t)((pkt->pkt_cdbp[1]) & 0x1F)
6029a2d88c01674debfd7c2e16c941a97302b739susans << 16));
6029a2d88c01674debfd7c2e16c941a97302b739susans } else if (acmd->cmd_cdblen == CDB_GROUP1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio->lba_count = host_to_le16(
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint16_t)(pkt->pkt_cdbp[8])) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint16_t)(pkt->pkt_cdbp[7]) << 8));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio->start_lba_lo = host_to_le32(
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint32_t)(pkt->pkt_cdbp[5])) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint32_t)(pkt->pkt_cdbp[4]) << 8) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint32_t)(pkt->pkt_cdbp[3]) << 16) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint32_t)(pkt->pkt_cdbp[2]) << 24));
6029a2d88c01674debfd7c2e16c941a97302b739susans } else if (acmd->cmd_cdblen == CDB_GROUP2) {
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio->lba_count = host_to_le16(
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint16_t)(pkt->pkt_cdbp[9])) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint16_t)(pkt->pkt_cdbp[8]) << 8) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint16_t)(pkt->pkt_cdbp[7]) << 16) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint16_t)(pkt->pkt_cdbp[6]) << 24));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio->start_lba_lo = host_to_le32(
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint32_t)(pkt->pkt_cdbp[5])) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint32_t)(pkt->pkt_cdbp[4]) << 8) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint32_t)(pkt->pkt_cdbp[3]) << 16) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint32_t)(pkt->pkt_cdbp[2]) << 24));
6029a2d88c01674debfd7c2e16c941a97302b739susans } else if (acmd->cmd_cdblen == CDB_GROUP3) {
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio->lba_count = host_to_le16(
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint16_t)(pkt->pkt_cdbp[13])) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint16_t)(pkt->pkt_cdbp[12]) << 8) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint16_t)(pkt->pkt_cdbp[11]) << 16) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint16_t)(pkt->pkt_cdbp[10]) << 24));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio->start_lba_lo = host_to_le32(
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint32_t)(pkt->pkt_cdbp[9])) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint32_t)(pkt->pkt_cdbp[8]) << 8) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint32_t)(pkt->pkt_cdbp[7]) << 16) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint32_t)(pkt->pkt_cdbp[6]) << 24));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ldio->start_lba_lo = host_to_le32(
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint32_t)(pkt->pkt_cdbp[5])) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint32_t)(pkt->pkt_cdbp[4]) << 8) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint32_t)(pkt->pkt_cdbp[3]) << 16) |
6029a2d88c01674debfd7c2e16c941a97302b739susans ((uint32_t)(pkt->pkt_cdbp[2]) << 24));
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans /* fall through For all non-rd/wr cmds */
6029a2d88c01674debfd7c2e16c941a97302b739susans default:
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru = (struct megasas_pthru_frame *)cmd->frame;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* prepare the DCDB frame */
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->cmd = (acmd->islogical) ?
6029a2d88c01674debfd7c2e16c941a97302b739susans MFI_CMD_OP_LD_SCSI : MFI_CMD_OP_PD_SCSI;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->cmd_status = 0x0;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->scsi_status = 0x0;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->target_id = acmd->device_id;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->lun = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->cdb_len = acmd->cmd_cdblen;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->timeout = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->flags = flags;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->data_xfer_len = acmd->cmd_dmacount;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->sge_count = acmd->cmd_cookiecnt;
03b14217e5b4702d6fc4b2ef4ece78b0cc99fc31Yu Wu - Sun Microsystems - Beijing China mfi_sgl = (struct megasas_sge64 *)&pthru->sgl;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw bzero(cmd->sense, SENSE_LENGTH);
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw pthru->sense_len = SENSE_LENGTH;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->sense_buf_phys_addr_hi = 0;
3ddf1763bcdffce8506ef0f2b7db0e860039e58byw pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans context = pthru->context;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans bcopy(pkt->pkt_cdbp, pthru->cdb, acmd->cmd_cdblen);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans#ifdef lint
6029a2d88c01674debfd7c2e16c941a97302b739susans context = context;
6029a2d88c01674debfd7c2e16c941a97302b739susans#endif
6029a2d88c01674debfd7c2e16c941a97302b739susans /* bzero(mfi_sgl, sizeof (struct megasas_sge64) * MAX_SGL); */
6029a2d88c01674debfd7c2e16c941a97302b739susans
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 mfi_sgl->length = acmd->cmd_dmacookies[i].dmac_size;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
03b14217e5b4702d6fc4b2ef4ece78b0cc99fc31Yu Wu - Sun Microsystems - Beijing China sge_bytes = sizeof (struct megasas_sge64)*acmd->cmd_cookiecnt;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) +
6029a2d88c01674debfd7c2e16c941a97302b739susans ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) + 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (cmd->frame_count >= 8) {
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_count = 8;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (cmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * wait_for_outstanding - Wait for all outstanding cmds
6029a2d88c01674debfd7c2e16c941a97302b739susans * @instance: Adapter soft state
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susanswait_for_outstanding(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int i;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t wait_time = 90;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans for (i = 0; i < wait_time; i++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans if (!instance->fw_outstanding) {
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele drv_usecwait(MILLISEC); /* wait for 1000 usecs */;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->fw_outstanding) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_acc_err_clear(instance->regmap_handle, DDI_FME_VERSION);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * issue_mfi_pthru
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_mfi_pthru(struct megasas_instance *instance, struct megasas_ioctl *ioctl,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd, int mode)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans void *ubuf;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t kphys_addr = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t xferlen = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint_t model;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans dma_obj_t pthru_dma_obj;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_pthru_frame *kpthru;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_pthru_frame *pthru;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru = &cmd->frame->pthru;
6029a2d88c01674debfd7c2e16c941a97302b739susans kpthru = (struct megasas_pthru_frame *)&ioctl->frame[0];
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans model = ddi_model_convert_from(mode & FMODELS);
6029a2d88c01674debfd7c2e16c941a97302b739susans if (model == DDI_MODEL_ILP32) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_pthru: DDI_MODEL_LP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans xferlen = kpthru->sgl.sge32[0].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans ubuf = (void *)(ulong_t)kpthru->sgl.sge32[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans#ifdef _ILP32
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_pthru: DDI_MODEL_LP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans xferlen = kpthru->sgl.sge32[0].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans ubuf = (void *)(ulong_t)kpthru->sgl.sge32[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans#else
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_pthru: DDI_MODEL_LP64"));
6029a2d88c01674debfd7c2e16c941a97302b739susans xferlen = kpthru->sgl.sge64[0].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans ubuf = (void *)(ulong_t)kpthru->sgl.sge64[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans#endif
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (xferlen) {
6029a2d88c01674debfd7c2e16c941a97302b739susans /* means IOCTL requires DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate the data transfer buffer */
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru_dma_obj.size = xferlen;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru_dma_obj.dma_attr = megasas_generic_dma_attr;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele pthru_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele pthru_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru_dma_obj.dma_attr.dma_attr_sgllen = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru_dma_obj.dma_attr.dma_attr_align = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate kernel buffer for DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (mega_alloc_dma_obj(instance, &pthru_dma_obj) != 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "issue_mfi_pthru: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "could not data transfer buffer alloc."));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (kpthru->flags & MFI_FRAME_DIR_WRITE) {
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyin(ubuf, (void *)pthru_dma_obj.buffer,
6029a2d88c01674debfd7c2e16c941a97302b739susans xferlen, mode)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "issue_mfi_pthru: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy from user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans kphys_addr = pthru_dma_obj.dma_cookie[0].dmac_address;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->cmd = kpthru->cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->sense_len = kpthru->sense_len;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->cmd_status = kpthru->cmd_status;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->scsi_status = kpthru->scsi_status;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->target_id = kpthru->target_id;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->lun = kpthru->lun;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->cdb_len = kpthru->cdb_len;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->sge_count = kpthru->sge_count;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->timeout = kpthru->timeout;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->data_xfer_len = kpthru->data_xfer_len;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->sense_buf_phys_addr_hi = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr; */
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->sense_buf_phys_addr_lo = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans bcopy((void *)kpthru->cdb, (void *)pthru->cdb, pthru->cdb_len);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->flags = kpthru->flags & ~MFI_FRAME_SGL64;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->sgl.sge32[0].length = xferlen;
6029a2d88c01674debfd7c2e16c941a97302b739susans pthru->sgl.sge32[0].phys_addr = kphys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->sync_cmd = MEGASAS_TRUE;
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_count = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "issue_mfi_pthru: fw_ioctl failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans if (xferlen && (kpthru->flags & MFI_FRAME_DIR_READ)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyout(pthru_dma_obj.buffer, ubuf,
6029a2d88c01674debfd7c2e16c941a97302b739susans xferlen, mode)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "issue_mfi_pthru: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy to user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans kpthru->cmd_status = pthru->cmd_status;
6029a2d88c01674debfd7c2e16c941a97302b739susans kpthru->scsi_status = pthru->scsi_status;
6029a2d88c01674debfd7c2e16c941a97302b739susans
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
6029a2d88c01674debfd7c2e16c941a97302b739susans if (xferlen) {
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free kernel buffer */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (mega_free_dma_obj(instance, pthru_dma_obj) != DDI_SUCCESS)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * issue_mfi_dcmd
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_mfi_dcmd(struct megasas_instance *instance, struct megasas_ioctl *ioctl,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd, int mode)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans void *ubuf;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t kphys_addr = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t xferlen = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t model;
6029a2d88c01674debfd7c2e16c941a97302b739susans dma_obj_t dcmd_dma_obj;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_dcmd_frame *kdcmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_dcmd_frame *dcmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd = &cmd->frame->dcmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans kdcmd = (struct megasas_dcmd_frame *)&ioctl->frame[0];
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans model = ddi_model_convert_from(mode & FMODELS);
6029a2d88c01674debfd7c2e16c941a97302b739susans if (model == DDI_MODEL_ILP32) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_dcmd: DDI_MODEL_ILP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans xferlen = kdcmd->sgl.sge32[0].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans else
6029a2d88c01674debfd7c2e16c941a97302b739susans {
6029a2d88c01674debfd7c2e16c941a97302b739susans#ifdef _ILP32
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_dcmd: DDI_MODEL_ILP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans xferlen = kdcmd->sgl.sge32[0].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans#else
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_dcmd: DDI_MODEL_LP64"));
6029a2d88c01674debfd7c2e16c941a97302b739susans xferlen = kdcmd->sgl.sge64[0].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans ubuf = (void *)(ulong_t)dcmd->sgl.sge64[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans#endif
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans if (xferlen) {
6029a2d88c01674debfd7c2e16c941a97302b739susans /* means IOCTL requires DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate the data transfer buffer */
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd_dma_obj.size = xferlen;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd_dma_obj.dma_attr = megasas_generic_dma_attr;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele dcmd_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele dcmd_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd_dma_obj.dma_attr.dma_attr_sgllen = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd_dma_obj.dma_attr.dma_attr_align = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate kernel buffer for DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (mega_alloc_dma_obj(instance, &dcmd_dma_obj) != 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "issue_mfi_dcmd: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "could not data transfer buffer alloc."));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (kdcmd->flags & MFI_FRAME_DIR_WRITE) {
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyin(ubuf, (void *)dcmd_dma_obj.buffer,
6029a2d88c01674debfd7c2e16c941a97302b739susans xferlen, mode)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "issue_mfi_dcmd: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy from user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans kphys_addr = dcmd_dma_obj.dma_cookie[0].dmac_address;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->cmd = kdcmd->cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->cmd_status = kdcmd->cmd_status;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->sge_count = kdcmd->sge_count;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->timeout = kdcmd->timeout;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->data_xfer_len = kdcmd->data_xfer_len;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->opcode = kdcmd->opcode;
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele bcopy((void *)kdcmd->mbox.b, (void *)dcmd->mbox.b, DCMD_MBOX_SZ);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->flags = kdcmd->flags & ~MFI_FRAME_SGL64;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->sgl.sge32[0].length = xferlen;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->sgl.sge32[0].phys_addr = kphys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->sync_cmd = MEGASAS_TRUE;
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_count = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
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 } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans if (xferlen && (kdcmd->flags & MFI_FRAME_DIR_READ)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyout(dcmd_dma_obj.buffer, ubuf,
6029a2d88c01674debfd7c2e16c941a97302b739susans xferlen, mode)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "issue_mfi_dcmd: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy to user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans kdcmd->cmd_status = dcmd->cmd_status;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (xferlen) {
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free kernel buffer */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (mega_free_dma_obj(instance, dcmd_dma_obj) != DDI_SUCCESS)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * issue_mfi_smp
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_mfi_smp(struct megasas_instance *instance, struct megasas_ioctl *ioctl,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd, int mode)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans void *request_ubuf;
6029a2d88c01674debfd7c2e16c941a97302b739susans void *response_ubuf;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t request_xferlen = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t response_xferlen = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint_t model;
6029a2d88c01674debfd7c2e16c941a97302b739susans dma_obj_t request_dma_obj;
6029a2d88c01674debfd7c2e16c941a97302b739susans dma_obj_t response_dma_obj;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_smp_frame *ksmp;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_smp_frame *smp;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_sge32 *sge32;
6029a2d88c01674debfd7c2e16c941a97302b739susans#ifndef _ILP32
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_sge64 *sge64;
6029a2d88c01674debfd7c2e16c941a97302b739susans#endif
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans smp = &cmd->frame->smp;
6029a2d88c01674debfd7c2e16c941a97302b739susans ksmp = (struct megasas_smp_frame *)&ioctl->frame[0];
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans model = ddi_model_convert_from(mode & FMODELS);
6029a2d88c01674debfd7c2e16c941a97302b739susans if (model == DDI_MODEL_ILP32) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: DDI_MODEL_ILP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans sge32 = &ksmp->sgl[0].sge32[0];
6029a2d88c01674debfd7c2e16c941a97302b739susans response_xferlen = sge32[0].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans request_xferlen = sge32[1].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE, "issue_mfi_smp: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "response_xferlen = %x, request_xferlen = %x",
6029a2d88c01674debfd7c2e16c941a97302b739susans response_xferlen, request_xferlen));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans response_ubuf = (void *)(ulong_t)sge32[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans request_ubuf = (void *)(ulong_t)sge32[1].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "response_ubuf = %p, request_ubuf = %p",
6029a2d88c01674debfd7c2e16c941a97302b739susans response_ubuf, request_ubuf));
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans#ifdef _ILP32
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: DDI_MODEL_ILP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans sge32 = &ksmp->sgl[0].sge32[0];
6029a2d88c01674debfd7c2e16c941a97302b739susans response_xferlen = sge32[0].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans request_xferlen = sge32[1].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE, "issue_mfi_smp: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "response_xferlen = %x, request_xferlen = %x",
6029a2d88c01674debfd7c2e16c941a97302b739susans response_xferlen, request_xferlen));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans response_ubuf = (void *)(ulong_t)sge32[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans request_ubuf = (void *)(ulong_t)sge32[1].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "response_ubuf = %p, request_ubuf = %p",
6029a2d88c01674debfd7c2e16c941a97302b739susans response_ubuf, request_ubuf));
6029a2d88c01674debfd7c2e16c941a97302b739susans#else
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: DDI_MODEL_LP64"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans sge64 = &ksmp->sgl[0].sge64[0];
6029a2d88c01674debfd7c2e16c941a97302b739susans response_xferlen = sge64[0].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans request_xferlen = sge64[1].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans response_ubuf = (void *)(ulong_t)sge64[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans request_ubuf = (void *)(ulong_t)sge64[1].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans#endif
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans if (request_xferlen) {
6029a2d88c01674debfd7c2e16c941a97302b739susans /* means IOCTL requires DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate the data transfer buffer */
6029a2d88c01674debfd7c2e16c941a97302b739susans request_dma_obj.size = request_xferlen;
6029a2d88c01674debfd7c2e16c941a97302b739susans request_dma_obj.dma_attr = megasas_generic_dma_attr;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele request_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele request_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
6029a2d88c01674debfd7c2e16c941a97302b739susans request_dma_obj.dma_attr.dma_attr_sgllen = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans request_dma_obj.dma_attr.dma_attr_align = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate kernel buffer for DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (mega_alloc_dma_obj(instance, &request_dma_obj) != 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "issue_mfi_smp: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "could not data transfer buffer alloc."));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyin(request_ubuf, (void *) request_dma_obj.buffer,
6029a2d88c01674debfd7c2e16c941a97302b739susans request_xferlen, mode)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "issue_mfi_smp: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy from user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (response_xferlen) {
6029a2d88c01674debfd7c2e16c941a97302b739susans /* means IOCTL requires DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate the data transfer buffer */
6029a2d88c01674debfd7c2e16c941a97302b739susans response_dma_obj.size = response_xferlen;
6029a2d88c01674debfd7c2e16c941a97302b739susans response_dma_obj.dma_attr = megasas_generic_dma_attr;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele response_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele response_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
6029a2d88c01674debfd7c2e16c941a97302b739susans response_dma_obj.dma_attr.dma_attr_sgllen = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans response_dma_obj.dma_attr.dma_attr_align = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate kernel buffer for DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (mega_alloc_dma_obj(instance, &response_dma_obj) != 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "issue_mfi_smp: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "could not data transfer buffer alloc."));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyin(response_ubuf, (void *) response_dma_obj.buffer,
6029a2d88c01674debfd7c2e16c941a97302b739susans response_xferlen, mode)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "issue_mfi_smp: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy from user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans smp->cmd = ksmp->cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans smp->cmd_status = ksmp->cmd_status;
6029a2d88c01674debfd7c2e16c941a97302b739susans smp->connection_status = ksmp->connection_status;
6029a2d88c01674debfd7c2e16c941a97302b739susans smp->sge_count = ksmp->sge_count;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* smp->context = ksmp->context; */
6029a2d88c01674debfd7c2e16c941a97302b739susans smp->timeout = ksmp->timeout;
6029a2d88c01674debfd7c2e16c941a97302b739susans smp->data_xfer_len = ksmp->data_xfer_len;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans bcopy((void *)&ksmp->sas_addr, (void *)&smp->sas_addr,
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (uint64_t));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans smp->flags = ksmp->flags & ~MFI_FRAME_SGL64;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans model = ddi_model_convert_from(mode & FMODELS);
6029a2d88c01674debfd7c2e16c941a97302b739susans if (model == DDI_MODEL_ILP32) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "handle_drv_ioctl: DDI_MODEL_ILP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans sge32 = &smp->sgl[0].sge32[0];
6029a2d88c01674debfd7c2e16c941a97302b739susans sge32[0].length = response_xferlen;
6029a2d88c01674debfd7c2e16c941a97302b739susans sge32[0].phys_addr =
6029a2d88c01674debfd7c2e16c941a97302b739susans response_dma_obj.dma_cookie[0].dmac_address;
6029a2d88c01674debfd7c2e16c941a97302b739susans sge32[1].length = request_xferlen;
6029a2d88c01674debfd7c2e16c941a97302b739susans sge32[1].phys_addr =
6029a2d88c01674debfd7c2e16c941a97302b739susans request_dma_obj.dma_cookie[0].dmac_address;
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans#ifdef _ILP32
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "handle_drv_ioctl: DDI_MODEL_ILP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans sge32 = &smp->sgl[0].sge32[0];
6029a2d88c01674debfd7c2e16c941a97302b739susans sge32[0].length = response_xferlen;
6029a2d88c01674debfd7c2e16c941a97302b739susans sge32[0].phys_addr =
6029a2d88c01674debfd7c2e16c941a97302b739susans response_dma_obj.dma_cookie[0].dmac_address;
6029a2d88c01674debfd7c2e16c941a97302b739susans sge32[1].length = request_xferlen;
6029a2d88c01674debfd7c2e16c941a97302b739susans sge32[1].phys_addr =
6029a2d88c01674debfd7c2e16c941a97302b739susans request_dma_obj.dma_cookie[0].dmac_address;
6029a2d88c01674debfd7c2e16c941a97302b739susans#else
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "issue_mfi_smp: DDI_MODEL_LP64"));
6029a2d88c01674debfd7c2e16c941a97302b739susans sge64 = &smp->sgl[0].sge64[0];
6029a2d88c01674debfd7c2e16c941a97302b739susans sge64[0].length = response_xferlen;
6029a2d88c01674debfd7c2e16c941a97302b739susans sge64[0].phys_addr =
6029a2d88c01674debfd7c2e16c941a97302b739susans response_dma_obj.dma_cookie[0].dmac_address;
6029a2d88c01674debfd7c2e16c941a97302b739susans sge64[1].length = request_xferlen;
6029a2d88c01674debfd7c2e16c941a97302b739susans sge64[1].phys_addr =
6029a2d88c01674debfd7c2e16c941a97302b739susans request_dma_obj.dma_cookie[0].dmac_address;
6029a2d88c01674debfd7c2e16c941a97302b739susans#endif
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "smp->response_xferlen = %d, smp->request_xferlen = %d "
6029a2d88c01674debfd7c2e16c941a97302b739susans "smp->data_xfer_len = %d", sge32[0].length, sge32[1].length,
6029a2d88c01674debfd7c2e16c941a97302b739susans smp->data_xfer_len));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->sync_cmd = MEGASAS_TRUE;
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_count = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN,
6029a2d88c01674debfd7c2e16c941a97302b739susans "issue_mfi_smp: fw_ioctl failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "issue_mfi_smp: copy to user space\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (request_xferlen) {
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyout(request_dma_obj.buffer, request_ubuf,
6029a2d88c01674debfd7c2e16c941a97302b739susans request_xferlen, mode)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "issue_mfi_smp: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy to user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (response_xferlen) {
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyout(response_dma_obj.buffer, response_ubuf,
6029a2d88c01674debfd7c2e16c941a97302b739susans response_xferlen, mode)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "issue_mfi_smp: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy to user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ksmp->cmd_status = smp->cmd_status;
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: smp->cmd_status = %d",
6029a2d88c01674debfd7c2e16c941a97302b739susans smp->cmd_status));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (request_xferlen) {
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free kernel buffer */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (mega_free_dma_obj(instance, request_dma_obj) != DDI_SUCCESS)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (response_xferlen) {
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free kernel buffer */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (mega_free_dma_obj(instance, response_dma_obj) !=
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China DDI_SUCCESS)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * issue_mfi_stp
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_mfi_stp(struct megasas_instance *instance, struct megasas_ioctl *ioctl,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd, int mode)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans void *fis_ubuf;
6029a2d88c01674debfd7c2e16c941a97302b739susans void *data_ubuf;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t fis_xferlen = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t data_xferlen = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint_t model;
6029a2d88c01674debfd7c2e16c941a97302b739susans dma_obj_t fis_dma_obj;
6029a2d88c01674debfd7c2e16c941a97302b739susans dma_obj_t data_dma_obj;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_stp_frame *kstp;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_stp_frame *stp;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans stp = &cmd->frame->stp;
6029a2d88c01674debfd7c2e16c941a97302b739susans kstp = (struct megasas_stp_frame *)&ioctl->frame[0];
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans model = ddi_model_convert_from(mode & FMODELS);
6029a2d88c01674debfd7c2e16c941a97302b739susans if (model == DDI_MODEL_ILP32) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_stp: DDI_MODEL_ILP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans fis_xferlen = kstp->sgl.sge32[0].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans data_xferlen = kstp->sgl.sge32[1].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans
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 }
6029a2d88c01674debfd7c2e16c941a97302b739susans else
6029a2d88c01674debfd7c2e16c941a97302b739susans {
6029a2d88c01674debfd7c2e16c941a97302b739susans#ifdef _ILP32
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_stp: DDI_MODEL_ILP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans fis_xferlen = kstp->sgl.sge32[0].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans data_xferlen = kstp->sgl.sge32[1].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans
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#else
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_mfi_stp: DDI_MODEL_LP64"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans fis_xferlen = kstp->sgl.sge64[0].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans data_xferlen = kstp->sgl.sge64[1].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans
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#endif
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (fis_xferlen) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE, "issue_mfi_stp: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "fis_ubuf = %p fis_xferlen = %x", fis_ubuf, fis_xferlen));
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele
6029a2d88c01674debfd7c2e16c941a97302b739susans /* means IOCTL requires DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate the data transfer buffer */
6029a2d88c01674debfd7c2e16c941a97302b739susans fis_dma_obj.size = fis_xferlen;
6029a2d88c01674debfd7c2e16c941a97302b739susans fis_dma_obj.dma_attr = megasas_generic_dma_attr;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele fis_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele fis_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
6029a2d88c01674debfd7c2e16c941a97302b739susans fis_dma_obj.dma_attr.dma_attr_sgllen = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans fis_dma_obj.dma_attr.dma_attr_align = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate kernel buffer for DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (mega_alloc_dma_obj(instance, &fis_dma_obj) != 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "could not data transfer buffer alloc."));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyin(fis_ubuf, (void *)fis_dma_obj.buffer,
6029a2d88c01674debfd7c2e16c941a97302b739susans fis_xferlen, mode)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy from user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (data_xferlen) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE, "issue_mfi_stp: data_ubuf = %p "
6029a2d88c01674debfd7c2e16c941a97302b739susans "data_xferlen = %x", data_ubuf, data_xferlen));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* means IOCTL requires DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate the data transfer buffer */
6029a2d88c01674debfd7c2e16c941a97302b739susans data_dma_obj.size = data_xferlen;
6029a2d88c01674debfd7c2e16c941a97302b739susans data_dma_obj.dma_attr = megasas_generic_dma_attr;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele data_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele data_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
6029a2d88c01674debfd7c2e16c941a97302b739susans data_dma_obj.dma_attr.dma_attr_sgllen = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans data_dma_obj.dma_attr.dma_attr_align = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* allocate kernel buffer for DMA */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (mega_alloc_dma_obj(instance, &data_dma_obj) != 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "could not data transfer buffer alloc."));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyin(data_ubuf, (void *) data_dma_obj.buffer,
6029a2d88c01674debfd7c2e16c941a97302b739susans data_xferlen, mode)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy from user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans stp->cmd = kstp->cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans stp->cmd_status = kstp->cmd_status;
6029a2d88c01674debfd7c2e16c941a97302b739susans stp->connection_status = kstp->connection_status;
6029a2d88c01674debfd7c2e16c941a97302b739susans stp->target_id = kstp->target_id;
6029a2d88c01674debfd7c2e16c941a97302b739susans stp->sge_count = kstp->sge_count;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* stp->context = kstp->context; */
6029a2d88c01674debfd7c2e16c941a97302b739susans stp->timeout = kstp->timeout;
6029a2d88c01674debfd7c2e16c941a97302b739susans stp->data_xfer_len = kstp->data_xfer_len;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans bcopy((void *)kstp->fis, (void *)stp->fis, 10);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans stp->flags = kstp->flags & ~MFI_FRAME_SGL64;
6029a2d88c01674debfd7c2e16c941a97302b739susans stp->stp_flags = kstp->stp_flags;
6029a2d88c01674debfd7c2e16c941a97302b739susans stp->sgl.sge32[0].length = fis_xferlen;
6029a2d88c01674debfd7c2e16c941a97302b739susans stp->sgl.sge32[0].phys_addr = fis_dma_obj.dma_cookie[0].dmac_address;
6029a2d88c01674debfd7c2e16c941a97302b739susans stp->sgl.sge32[1].length = data_xferlen;
6029a2d88c01674debfd7c2e16c941a97302b739susans stp->sgl.sge32[1].phys_addr = data_dma_obj.dma_cookie[0].dmac_address;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->sync_cmd = MEGASAS_TRUE;
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_count = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
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 } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (fis_xferlen) {
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyout(fis_dma_obj.buffer, fis_ubuf,
6029a2d88c01674debfd7c2e16c941a97302b739susans fis_xferlen, mode)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy to user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (data_xferlen) {
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyout(data_dma_obj.buffer, data_ubuf,
6029a2d88c01674debfd7c2e16c941a97302b739susans data_xferlen, mode)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy to user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans kstp->cmd_status = stp->cmd_status;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (fis_xferlen) {
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free kernel buffer */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (mega_free_dma_obj(instance, fis_dma_obj) != DDI_SUCCESS)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (data_xferlen) {
6029a2d88c01674debfd7c2e16c941a97302b739susans /* free kernel buffer */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (mega_free_dma_obj(instance, data_dma_obj) != DDI_SUCCESS)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * fill_up_drv_ver
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void
6029a2d88c01674debfd7c2e16c941a97302b739susansfill_up_drv_ver(struct megasas_drv_ver *dv)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memset(dv, 0, sizeof (struct megasas_drv_ver));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memcpy(dv->signature, "$LSI LOGIC$", strlen("$LSI LOGIC$"));
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memcpy(dv->os_name, "Solaris", strlen("Solaris"));
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memcpy(dv->drv_name, "megaraid_sas", strlen("megaraid_sas"));
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memcpy(dv->drv_ver, MEGASAS_VERSION, strlen(MEGASAS_VERSION));
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memcpy(dv->drv_rel_date, MEGASAS_RELDATE,
6029a2d88c01674debfd7c2e16c941a97302b739susans strlen(MEGASAS_RELDATE));
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * handle_drv_ioctl
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susanshandle_drv_ioctl(struct megasas_instance *instance, struct megasas_ioctl *ioctl,
6029a2d88c01674debfd7c2e16c941a97302b739susans int mode)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int i;
6029a2d88c01674debfd7c2e16c941a97302b739susans int rval = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans int *props = NULL;
6029a2d88c01674debfd7c2e16c941a97302b739susans void *ubuf;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans uint8_t *pci_conf_buf;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t xferlen;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t num_props;
6029a2d88c01674debfd7c2e16c941a97302b739susans uint_t model;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_dcmd_frame *kdcmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_drv_ver dv;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_pci_information pi;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans kdcmd = (struct megasas_dcmd_frame *)&ioctl->frame[0];
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans model = ddi_model_convert_from(mode & FMODELS);
6029a2d88c01674debfd7c2e16c941a97302b739susans if (model == DDI_MODEL_ILP32) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "handle_drv_ioctl: DDI_MODEL_ILP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans xferlen = kdcmd->sgl.sge32[0].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans#ifdef _ILP32
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "handle_drv_ioctl: DDI_MODEL_ILP32"));
6029a2d88c01674debfd7c2e16c941a97302b739susans xferlen = kdcmd->sgl.sge32[0].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans#else
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE,
6029a2d88c01674debfd7c2e16c941a97302b739susans "handle_drv_ioctl: DDI_MODEL_LP64"));
6029a2d88c01674debfd7c2e16c941a97302b739susans xferlen = kdcmd->sgl.sge64[0].length;
6029a2d88c01674debfd7c2e16c941a97302b739susans /* SJ! - ubuf needs to be virtual address. */
6029a2d88c01674debfd7c2e16c941a97302b739susans ubuf = (void *)(ulong_t)kdcmd->sgl.sge64[0].phys_addr;
6029a2d88c01674debfd7c2e16c941a97302b739susans#endif
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "handle_drv_ioctl: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "dataBuf=%p size=%d bytes", ubuf, xferlen));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans switch (kdcmd->opcode) {
6029a2d88c01674debfd7c2e16c941a97302b739susans case MR_DRIVER_IOCTL_DRIVER_VERSION:
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "handle_drv_ioctl: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "MR_DRIVER_IOCTL_DRIVER_VERSION"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans fill_up_drv_ver(&dv);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyout(&dv, ubuf, xferlen, mode)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "handle_drv_ioctl: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "MR_DRIVER_IOCTL_DRIVER_VERSION : "
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy to user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans kdcmd->cmd_status = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans kdcmd->cmd_status = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case MR_DRIVER_IOCTL_PCI_INFORMATION:
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "handle_drv_ioctl: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "MR_DRIVER_IOCTL_PCI_INFORMAITON"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, instance->dip,
6029a2d88c01674debfd7c2e16c941a97302b739susans 0, "reg", &props, &num_props)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "handle_drv_ioctl: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "MR_DRIVER_IOCTL_PCI_INFORMATION : "
6029a2d88c01674debfd7c2e16c941a97302b739susans "ddi_prop_look_int_array failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans pi.busNumber = (props[0] >> 16) & 0xFF;
6029a2d88c01674debfd7c2e16c941a97302b739susans pi.deviceNumber = (props[0] >> 11) & 0x1f;
6029a2d88c01674debfd7c2e16c941a97302b739susans pi.functionNumber = (props[0] >> 8) & 0x7;
6029a2d88c01674debfd7c2e16c941a97302b739susans ddi_prop_free((void *)props);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans pci_conf_buf = (uint8_t *)&pi.pciHeaderInfo;
6029a2d88c01674debfd7c2e16c941a97302b739susans
2fbba054b269361b33411621fca09b77f0b7a30fyd for (i = 0; i < (sizeof (struct megasas_pci_information) -
2fbba054b269361b33411621fca09b77f0b7a30fyd offsetof(struct megasas_pci_information, pciHeaderInfo));
2fbba054b269361b33411621fca09b77f0b7a30fyd i++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans pci_conf_buf[i] =
6029a2d88c01674debfd7c2e16c941a97302b739susans pci_config_get8(instance->pci_handle, i);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ddi_copyout(&pi, ubuf, xferlen, mode)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "handle_drv_ioctl: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "MR_DRIVER_IOCTL_PCI_INFORMATION : "
6029a2d88c01674debfd7c2e16c941a97302b739susans "copy to user space failed\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans kdcmd->cmd_status = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans kdcmd->cmd_status = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans default:
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "handle_drv_ioctl: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "invalid driver specific IOCTL opcode = 0x%x",
6029a2d88c01674debfd7c2e16c941a97302b739susans kdcmd->opcode));
6029a2d88c01674debfd7c2e16c941a97302b739susans kdcmd->cmd_status = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (rval);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * handle_mfi_ioctl
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susanshandle_mfi_ioctl(struct megasas_instance *instance, struct megasas_ioctl *ioctl,
6029a2d88c01674debfd7c2e16c941a97302b739susans int mode)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int rval = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_header *hdr;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd = get_mfi_pkt(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (!cmd) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "megasas: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "failed to get a cmd packet\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans hdr = (struct megasas_header *)&ioctl->frame[0];
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans switch (hdr->cmd) {
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_CMD_OP_DCMD:
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = issue_mfi_dcmd(instance, ioctl, cmd, mode);
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_CMD_OP_SMP:
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = issue_mfi_smp(instance, ioctl, cmd, mode);
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_CMD_OP_STP:
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = issue_mfi_stp(instance, ioctl, cmd, mode);
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_CMD_OP_LD_SCSI:
6029a2d88c01674debfd7c2e16c941a97302b739susans case MFI_CMD_OP_PD_SCSI:
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = issue_mfi_pthru(instance, ioctl, cmd, mode);
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans default:
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "handle_mfi_ioctl: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "invalid mfi ioctl hdr->cmd = %d\n", hdr->cmd));
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans break;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return_mfi_pkt(instance, cmd);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_common_check(instance, cmd) != DDI_SUCCESS)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China rval = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans return (rval);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * AEN
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susanshandle_mfi_aen(struct megasas_instance *instance, struct megasas_aen *aen)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int rval = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans rval = register_mfi_aen(instance, instance->aen_seq_num,
6029a2d88c01674debfd7c2e16c941a97302b739susans aen->class_locale_word);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans aen->cmd_status = (uint8_t)rval;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (rval);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansregister_mfi_aen(struct megasas_instance *instance, uint32_t seq_num,
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t class_locale_word)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int ret_val;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_dcmd_frame *dcmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans union megasas_evt_class_locale curr_aen;
6029a2d88c01674debfd7c2e16c941a97302b739susans union megasas_evt_class_locale prev_aen;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
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 * to.
6029a2d88c01674debfd7c2e16c941a97302b739susans *
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans curr_aen.word = class_locale_word;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (instance->aen_cmd) {
6029a2d88c01674debfd7c2e16c941a97302b739susans prev_aen.word = instance->aen_cmd->frame->dcmd.mbox.w[1];
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
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 *
6029a2d88c01674debfd7c2e16c941a97302b739susans * Locale numbers don't have such hierarchy. They are bitmap
6029a2d88c01674debfd7c2e16c941a97302b739susans * values
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans if ((prev_aen.members.class <= curr_aen.members.class) &&
6029a2d88c01674debfd7c2e16c941a97302b739susans !((prev_aen.members.locale & curr_aen.members.locale) ^
6029a2d88c01674debfd7c2e16c941a97302b739susans curr_aen.members.locale)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
6029a2d88c01674debfd7c2e16c941a97302b739susans * Previously issued event registration includes
6029a2d88c01674debfd7c2e16c941a97302b739susans * current request. Nothing to do.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans curr_aen.members.locale |= prev_aen.members.locale;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (prev_aen.members.class < curr_aen.members.class)
6029a2d88c01674debfd7c2e16c941a97302b739susans curr_aen.members.class = prev_aen.members.class;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans ret_val = abort_aen_cmd(instance, instance->aen_cmd);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (ret_val) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_WARN, "register_mfi_aen: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "failed to abort prevous AEN command\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (ret_val);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans curr_aen.word = class_locale_word;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd = get_mfi_pkt(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (!cmd)
6029a2d88c01674debfd7c2e16c941a97302b739susans return (-ENOMEM);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd = &cmd->frame->dcmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele /* for(i = 0; i < DCMD_MBOX_SZ; i++) dcmd->mbox.b[i] = 0; */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele (void) memset(dcmd->mbox.b, 0, DCMD_MBOX_SZ);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans (void) memset(instance->mfi_evt_detail_obj.buffer, 0,
6029a2d88c01674debfd7c2e16c941a97302b739susans sizeof (struct megasas_evt_detail));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Prepare DCMD for aen registration */
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->cmd = MFI_CMD_OP_DCMD;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->cmd_status = 0x0;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->sge_count = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->flags = MFI_FRAME_DIR_READ;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->timeout = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->data_xfer_len = sizeof (struct megasas_evt_detail);
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->opcode = MR_DCMD_CTRL_EVENT_WAIT;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->mbox.w[0] = seq_num;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->mbox.w[1] = curr_aen.word;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->sgl.sge32[0].phys_addr =
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->mfi_evt_detail_obj.dma_cookie[0].dmac_address;
6029a2d88c01674debfd7c2e16c941a97302b739susans dcmd->sgl.sge32[0].length = sizeof (struct megasas_evt_detail);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->aen_seq_num = seq_num;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /*
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 */
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->aen_cmd = cmd;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->frame_count = 1;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Issue the aen registration frame */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* atomic_add_16 (&instance->fw_outstanding, 1); */
6029a2d88c01674debfd7c2e16c941a97302b739susans instance->func_ptr->issue_cmd(cmd, instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void
6029a2d88c01674debfd7c2e16c941a97302b739susansdisplay_scsi_inquiry(caddr_t scsi_inq)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans#define MAX_SCSI_DEVICE_CODE 14
6029a2d88c01674debfd7c2e16c941a97302b739susans int i;
6029a2d88c01674debfd7c2e16c941a97302b739susans char inquiry_buf[256] = {0};
6029a2d88c01674debfd7c2e16c941a97302b739susans int len;
6029a2d88c01674debfd7c2e16c941a97302b739susans const char *const scsi_device_types[] = {
6029a2d88c01674debfd7c2e16c941a97302b739susans "Direct-Access ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Sequential-Access",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Printer ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Processor ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "WORM ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "CD-ROM ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Scanner ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Optical Device ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Medium Changer ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Communications ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Unknown ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Unknown ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Unknown ",
6029a2d88c01674debfd7c2e16c941a97302b739susans "Enclosure ",
6029a2d88c01674debfd7c2e16c941a97302b739susans };
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans len = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans len += snprintf(inquiry_buf + len, 265 - len, " Vendor: ");
6029a2d88c01674debfd7c2e16c941a97302b739susans for (i = 8; i < 16; i++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans len += snprintf(inquiry_buf + len, 265 - len, "%c",
6029a2d88c01674debfd7c2e16c941a97302b739susans scsi_inq[i]);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans len += snprintf(inquiry_buf + len, 265 - len, " Model: ");
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans for (i = 16; i < 32; i++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans len += snprintf(inquiry_buf + len, 265 - len, "%c",
6029a2d88c01674debfd7c2e16c941a97302b739susans scsi_inq[i]);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans len += snprintf(inquiry_buf + len, 265 - len, " Rev: ");
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans for (i = 32; i < 36; i++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans len += snprintf(inquiry_buf + len, 265 - len, "%c",
6029a2d88c01674debfd7c2e16c941a97302b739susans scsi_inq[i]);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans len += snprintf(inquiry_buf + len, 265 - len, "\n");
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans i = scsi_inq[0] & 0x1f;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans len += snprintf(inquiry_buf + len, 265 - len, " Type: %s ",
6029a2d88c01674debfd7c2e16c941a97302b739susans i < MAX_SCSI_DEVICE_CODE ? scsi_device_types[i] :
6029a2d88c01674debfd7c2e16c941a97302b739susans "Unknown ");
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans len += snprintf(inquiry_buf + len, 265 - len,
6029a2d88c01674debfd7c2e16c941a97302b739susans " ANSI SCSI revision: %02x", scsi_inq[2] & 0x07);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if ((scsi_inq[2] & 0x07) == 1 && (scsi_inq[3] & 0x0f) == 1) {
6029a2d88c01674debfd7c2e16c941a97302b739susans len += snprintf(inquiry_buf + len, 265 - len, " CCS\n");
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans len += snprintf(inquiry_buf + len, 265 - len, "\n");
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_CONT, inquiry_buf));
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansread_fw_status_reg_xscale(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans return ((int)RD_OB_MSG_0(instance));
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansread_fw_status_reg_ppc(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans return ((int)RD_OB_SCRATCH_PAD_0(instance));
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_cmd_xscale(struct megasas_cmd *cmd, struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_16(&instance->fw_outstanding);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Issue the command to the FW */
6029a2d88c01674debfd7c2e16c941a97302b739susans WR_IB_QPORT((host_to_le32(cmd->frame_phys_addr) >> 3) |
6029a2d88c01674debfd7c2e16c941a97302b739susans (cmd->frame_count - 1), instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_cmd_ppc(struct megasas_cmd *cmd, struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_16(&instance->fw_outstanding);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* Issue the command to the FW */
6029a2d88c01674debfd7c2e16c941a97302b739susans WR_IB_QPORT((host_to_le32(cmd->frame_phys_addr)) |
6029a2d88c01674debfd7c2e16c941a97302b739susans (((cmd->frame_count - 1) << 1) | 1), instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * issue_cmd_in_sync_mode
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_cmd_in_sync_mode_xscale(struct megasas_instance *instance,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int i;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele uint32_t msecs = MFI_POLL_TIMEOUT_SECS * (10 * MILLISEC);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->cmd_status = ENODATA;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans WR_IB_QPORT((host_to_le32(cmd->frame_phys_addr) >> 3) |
6029a2d88c01674debfd7c2e16c941a97302b739susans (cmd->frame_count - 1), instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_enter(&instance->int_cmd_mtx);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans for (i = 0; i < msecs && (cmd->cmd_status == ENODATA); i++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans cv_wait(&instance->int_cmd_cv, &instance->int_cmd_mtx);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_exit(&instance->int_cmd_mtx);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (i < (msecs -1)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_cmd_in_sync_mode_ppc(struct megasas_instance *instance,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int i;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele uint32_t msecs = MFI_POLL_TIMEOUT_SECS * (10 * MILLISEC);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_sync_mode_ppc: called\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans cmd->cmd_status = ENODATA;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans WR_IB_QPORT((host_to_le32(cmd->frame_phys_addr)) |
6029a2d88c01674debfd7c2e16c941a97302b739susans (((cmd->frame_count - 1) << 1) | 1), instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_enter(&instance->int_cmd_mtx);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans for (i = 0; i < msecs && (cmd->cmd_status == ENODATA); i++) {
6029a2d88c01674debfd7c2e16c941a97302b739susans cv_wait(&instance->int_cmd_cv, &instance->int_cmd_mtx);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans mutex_exit(&instance->int_cmd_mtx);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_sync_mode_ppc: done\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (i < (msecs -1)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (0);
6029a2d88c01674debfd7c2e16c941a97302b739susans } else {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (1);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * issue_cmd_in_poll_mode
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_cmd_in_poll_mode_xscale(struct megasas_instance *instance,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int i;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele uint32_t msecs = MFI_POLL_TIMEOUT_SECS * MILLISEC;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele struct megasas_header *frame_hdr;
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele frame_hdr = (struct megasas_header *)cmd->frame;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele frame_hdr->cmd_status = MFI_CMD_STATUS_POLL_MODE;
6029a2d88c01674debfd7c2e16c941a97302b739susans frame_hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* issue the frame using inbound queue port */
6029a2d88c01674debfd7c2e16c941a97302b739susans WR_IB_QPORT((host_to_le32(cmd->frame_phys_addr) >> 3) |
6029a2d88c01674debfd7c2e16c941a97302b739susans (cmd->frame_count - 1), instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele /* wait for cmd_status to change from 0xFF */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele for (i = 0; i < msecs && (frame_hdr->cmd_status ==
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele MFI_CMD_STATUS_POLL_MODE); i++) {
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele drv_usecwait(MILLISEC); /* wait for 1000 usecs */
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele if (frame_hdr->cmd_status == MFI_CMD_STATUS_POLL_MODE) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE, "issue_cmd_in_poll_mode: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "cmd polling timed out"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_SUCCESS);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansissue_cmd_in_poll_mode_ppc(struct megasas_instance *instance,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct megasas_cmd *cmd)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans int i;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele uint32_t msecs = MFI_POLL_TIMEOUT_SECS * MILLISEC;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele struct megasas_header *frame_hdr;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_poll_mode_ppc: called\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele frame_hdr = (struct megasas_header *)cmd->frame;
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele frame_hdr->cmd_status = MFI_CMD_STATUS_POLL_MODE;
6029a2d88c01674debfd7c2e16c941a97302b739susans frame_hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* issue the frame using inbound queue port */
6029a2d88c01674debfd7c2e16c941a97302b739susans WR_IB_QPORT((host_to_le32(cmd->frame_phys_addr)) |
6029a2d88c01674debfd7c2e16c941a97302b739susans (((cmd->frame_count - 1) << 1) | 1), instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele /* wait for cmd_status to change from 0xFF */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele for (i = 0; i < msecs && (frame_hdr->cmd_status ==
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele MFI_CMD_STATUS_POLL_MODE); i++) {
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele drv_usecwait(MILLISEC); /* wait for 1000 usecs */
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele if (frame_hdr->cmd_status == MFI_CMD_STATUS_POLL_MODE) {
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN, (CE_NOTE, "issue_cmd_in_poll_mode: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "cmd polling timed out"));
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_FAILURE);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_SUCCESS);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void
6029a2d88c01674debfd7c2e16c941a97302b739susansenable_intr_xscale(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans MFI_ENABLE_INTR(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void
6029a2d88c01674debfd7c2e16c941a97302b739susansenable_intr_ppc(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t mask;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "enable_intr_ppc: called\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele /* WR_OB_DOORBELL_CLEAR(0xFFFFFFFF, instance); */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele WR_OB_DOORBELL_CLEAR(OB_DOORBELL_CLEAR_MASK, instance);
ea20edda2274918c047dc10b52891c14f2afb0besusans
ea20edda2274918c047dc10b52891c14f2afb0besusans /*
ea20edda2274918c047dc10b52891c14f2afb0besusans * As 1078DE is same as 1078 chip, the interrupt mask
ea20edda2274918c047dc10b52891c14f2afb0besusans * remains the same.
ea20edda2274918c047dc10b52891c14f2afb0besusans */
6029a2d88c01674debfd7c2e16c941a97302b739susans /* WR_OB_INTR_MASK(~0x80000000, instance); */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele WR_OB_INTR_MASK(~(MFI_REPLY_1078_MESSAGE_INTR), instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* dummy read to force PCI flush */
6029a2d88c01674debfd7c2e16c941a97302b739susans mask = RD_OB_INTR_MASK(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "enable_intr_ppc: "
6029a2d88c01674debfd7c2e16c941a97302b739susans "outbound_intr_mask = 0x%x\n", mask));
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void
6029a2d88c01674debfd7c2e16c941a97302b739susansdisable_intr_xscale(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans MFI_DISABLE_INTR(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void
6029a2d88c01674debfd7c2e16c941a97302b739susansdisable_intr_ppc(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t mask;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: called\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: before : "
6029a2d88c01674debfd7c2e16c941a97302b739susans "outbound_intr_mask = 0x%x\n", RD_OB_INTR_MASK(instance)));
6029a2d88c01674debfd7c2e16c941a97302b739susans
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele /* WR_OB_INTR_MASK(0xFFFFFFFF, instance); */
7ddfa2acf3cfb8a6397a0fb7b4dcd2ce701cc293Susan Scheufele WR_OB_INTR_MASK(OB_INTR_MASK, instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: after : "
6029a2d88c01674debfd7c2e16c941a97302b739susans "outbound_intr_mask = 0x%x\n", RD_OB_INTR_MASK(instance)));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* dummy read to force PCI flush */
6029a2d88c01674debfd7c2e16c941a97302b739susans mask = RD_OB_INTR_MASK(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans#ifdef lint
6029a2d88c01674debfd7c2e16c941a97302b739susans mask = mask;
6029a2d88c01674debfd7c2e16c941a97302b739susans#endif
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansintr_ack_xscale(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t status;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* check if it is our interrupt */
6029a2d88c01674debfd7c2e16c941a97302b739susans status = RD_OB_INTR_STATUS(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (!(status & MFI_OB_INTR_STATUS_MASK)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_INTR_UNCLAIMED);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* clear the interrupt by writing back the same value */
6029a2d88c01674debfd7c2e16c941a97302b739susans WR_OB_INTR_STATUS(status, instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_INTR_CLAIMED);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int
6029a2d88c01674debfd7c2e16c941a97302b739susansintr_ack_ppc(struct megasas_instance *instance)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans uint32_t status;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "intr_ack_ppc: called\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* check if it is our interrupt */
6029a2d88c01674debfd7c2e16c941a97302b739susans status = RD_OB_INTR_STATUS(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "intr_ack_ppc: status = 0x%x\n", status));
6029a2d88c01674debfd7c2e16c941a97302b739susans
ea20edda2274918c047dc10b52891c14f2afb0besusans /*
ea20edda2274918c047dc10b52891c14f2afb0besusans * As 1078DE is same as 1078 chip, the status field
ea20edda2274918c047dc10b52891c14f2afb0besusans * remains the same.
ea20edda2274918c047dc10b52891c14f2afb0besusans */
6029a2d88c01674debfd7c2e16c941a97302b739susans if (!(status & MFI_REPLY_1078_MESSAGE_INTR)) {
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_INTR_UNCLAIMED);
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* clear the interrupt by writing back the same value */
6029a2d88c01674debfd7c2e16c941a97302b739susans WR_OB_DOORBELL_CLEAR(status, instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans /* dummy READ */
6029a2d88c01674debfd7c2e16c941a97302b739susans status = RD_OB_INTR_STATUS(instance);
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans con_log(CL_ANN1, (CE_NOTE, "intr_ack_ppc: interrupt cleared\n"));
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans return (DDI_INTR_CLAIMED);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinastatic int
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinamegasas_common_check(struct megasas_instance *instance,
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China struct megasas_cmd *cmd)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China{
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China int ret = DDI_SUCCESS;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_dma_handle(cmd->frame_dma_obj.dma_handle) !=
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (cmd->pkt != NULL) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China cmd->pkt->pkt_reason = CMD_TRAN_ERR;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China cmd->pkt->pkt_statistics = 0;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ret = DDI_FAILURE;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_dma_handle(instance->mfi_internal_dma_obj.dma_handle)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China != DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (cmd->pkt != NULL) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China cmd->pkt->pkt_reason = CMD_TRAN_ERR;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China cmd->pkt->pkt_statistics = 0;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ret = DDI_FAILURE;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_dma_handle(instance->mfi_evt_detail_obj.dma_handle) !=
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (cmd->pkt != NULL) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China cmd->pkt->pkt_reason = CMD_TRAN_ERR;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China cmd->pkt->pkt_statistics = 0;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ret = DDI_FAILURE;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (megasas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_acc_err_clear(instance->regmap_handle, DDI_FME_VER0);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (cmd->pkt != NULL) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China cmd->pkt->pkt_reason = CMD_TRAN_ERR;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China cmd->pkt->pkt_statistics = 0;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ret = DDI_FAILURE;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (ret);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China}
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China/*ARGSUSED*/
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinastatic int
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinamegasas_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China{
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China /*
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * as the driver can always deal with an error in any dma or
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * access handle, we can just return the fme_status value.
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China pci_ereport_post(dip, err, NULL);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (err->fme_status);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China}
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinastatic void
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinamegasas_fm_init(struct megasas_instance *instance)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China{
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China /* Need to change iblock to priority for new MSI intr */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_iblock_cookie_t fm_ibc;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China /* Only register with IO Fault Services if we have some capability */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (instance->fm_capabilities) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China /* Adjust access and dma attributes for FMA */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China endian_attr.devacc_attr_access = DDI_FLAGERR_ACC;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_generic_dma_attr.dma_attr_flags = DDI_DMA_FLAGERR;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China /*
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * Register capabilities with IO Fault Services.
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * fm_capabilities will be updated to indicate
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * capabilities actually supported (not requested.)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_init(instance->dip, &instance->fm_capabilities, &fm_ibc);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China /*
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * Initialize pci ereport capabilities if ereport
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * capable (should always be.)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (DDI_FM_EREPORT_CAP(instance->fm_capabilities) ||
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China DDI_FM_ERRCB_CAP(instance->fm_capabilities)) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China pci_ereport_setup(instance->dip);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China /*
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * Register error callback if error callback capable.
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (DDI_FM_ERRCB_CAP(instance->fm_capabilities)) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_handler_register(instance->dip,
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_fm_error_cb, (void*) instance);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China } else {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China endian_attr.devacc_attr_access = DDI_DEFAULT_ACC;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_generic_dma_attr.dma_attr_flags = 0;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China}
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinastatic void
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinamegasas_fm_fini(struct megasas_instance *instance)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China{
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China /* Only unregister FMA capabilities if registered */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (instance->fm_capabilities) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China /*
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * Un-register error callback if error callback capable.
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (DDI_FM_ERRCB_CAP(instance->fm_capabilities)) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_handler_unregister(instance->dip);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China /*
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China * Release any resources allocated by pci_ereport_setup()
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (DDI_FM_EREPORT_CAP(instance->fm_capabilities) ||
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China DDI_FM_ERRCB_CAP(instance->fm_capabilities)) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China pci_ereport_teardown(instance->dip);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China /* Unregister from IO Fault Services */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_fini(instance->dip);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China /* Adjust access and dma attributes for FMA */
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China endian_attr.devacc_attr_access = DDI_DEFAULT_ACC;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China megasas_generic_dma_attr.dma_attr_flags = 0;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China}
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinaint
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinamegasas_check_acc_handle(ddi_acc_handle_t handle)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China{
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_error_t de;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (handle == NULL) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (DDI_FAILURE);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (de.fme_status);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China}
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinaint
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinamegasas_check_dma_handle(ddi_dma_handle_t handle)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China{
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_error_t de;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (handle == NULL) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (DDI_FAILURE);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China return (de.fme_status);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China}
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinavoid
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing Chinamegasas_fm_ereport(struct megasas_instance *instance, char *detail)
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China{
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China uint64_t ena;
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China char buf[FM_MAX_CLASS];
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ena = fm_ena_generate(0, FM_ENA_FMT1);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China if (DDI_FM_EREPORT_CAP(instance->fm_capabilities)) {
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China ddi_fm_ereport_post(instance->dip, buf, ena, DDI_NOSLEEP,
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERSION, NULL);
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China }
2fa451d9fff38ef869918fcfb1d61717fdb3cf7cYu Wu - Sun Microsystems - Beijing China}