mr_sas.c revision 837c1ac4e72b7d86278cca88b1075af557f7d161
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * mr_sas.c: source for mr_sas driver
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * MegaRAID device driver for SAS2.0 controllers
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Copyright (c) 2008-2009, LSI Logic Corporation.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * All rights reserved.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Version:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Author:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Arun Chandrashekhar
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Manju R
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Rajesh Prabhakaran
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Seokmann Ju
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Redistribution and use in source and binary forms, with or without
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * modification, are permitted provided that the following conditions are met:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * 1. Redistributions of source code must retain the above copyright notice,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * this list of conditions and the following disclaimer.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * 2. Redistributions in binary form must reproduce the above copyright notice,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * this list of conditions and the following disclaimer in the documentation
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * and/or other materials provided with the distribution.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * 3. Neither the name of the author nor the names of its contributors may be
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * used to endorse or promote products derived from this software without
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * specific prior written permission.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * DAMAGE.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Use is subject to license terms.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/types.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/param.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/file.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/errno.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/open.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/cred.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/modctl.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/conf.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/devops.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/cmn_err.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/kmem.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/stat.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/mkdev.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/pci.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/scsi/scsi.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/ddi.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/sunddi.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/atomic.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/signal.h>
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China#include <sys/byteorder.h>
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele#include <sys/sdt.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/fs/dv_node.h> /* devfs_clean */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include "mr_sas.h"
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * FMA header files
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/ddifm.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/fm/protocol.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/fm/util.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#include <sys/fm/io/ddi.h>
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Local static data
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void *mrsas_state = NULL;
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing Chinastatic volatile boolean_t mrsas_relaxed_ordering = B_TRUE;
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing Chinastatic volatile int debug_level_g = CL_NONE;
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing Chinastatic volatile int msi_enable = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#pragma weak scsi_hba_open
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#pragma weak scsi_hba_close
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#pragma weak scsi_hba_ioctl
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic ddi_dma_attr_t mrsas_generic_dma_attr = {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DMA_ATTR_V0, /* dma_attr_version */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 0, /* low DMA address range */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 0xFFFFFFFFU, /* high DMA address range */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 0xFFFFFFFFU, /* DMA counter register */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 8, /* DMA address alignment */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 0x07, /* DMA burstsizes */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 1, /* min DMA size */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 0xFFFFFFFFU, /* max DMA size */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 0xFFFFFFFFU, /* segment boundary */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MRSAS_MAX_SGE_CNT, /* dma_attr_sglen */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 512, /* granularity of device */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 0 /* bus specific DMA flags */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele};
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleint32_t mrsas_max_cap_maxxfer = 0x1000000;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * cb_ops contains base level routines
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic struct cb_ops mrsas_cb_ops = {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_open, /* open */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_close, /* close */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele nodev, /* strategy */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele nodev, /* print */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele nodev, /* dump */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele nodev, /* read */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele nodev, /* write */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_ioctl, /* ioctl */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele nodev, /* devmap */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele nodev, /* mmap */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele nodev, /* segmap */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele nochpoll, /* poll */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele nodev, /* cb_prop_op */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 0, /* streamtab */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele D_NEW | D_HOTPLUG, /* cb_flag */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele CB_REV, /* cb_rev */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele nodev, /* cb_aread */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele nodev /* cb_awrite */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele};
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * dev_ops contains configuration routines
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic struct dev_ops mrsas_ops = {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DEVO_REV, /* rev, */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 0, /* refcnt */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_getinfo, /* getinfo */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele nulldev, /* identify */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele nulldev, /* probe */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_attach, /* attach */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_detach, /* detach */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_reset, /* reset */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &mrsas_cb_ops, /* char/block ops */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele NULL, /* bus ops */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele NULL, /* power */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_quiesce_not_supported, /* quiesce */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele};
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelechar _depends_on[] = "misc/scsi";
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic struct modldrv modldrv = {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &mod_driverops, /* module type - driver */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MRSAS_VERSION,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &mrsas_ops, /* driver ops */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele};
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic struct modlinkage modlinkage = {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MODREV_1, /* ml_rev - must be MODREV_1 */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &modldrv, /* ml_linkage */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele NULL /* end of driver linkage */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele};
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic struct ddi_device_acc_attr endian_attr = {
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson DDI_DEVICE_ATTR_V1,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_STRUCTURE_LE_ACC,
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson DDI_STRICTORDER_ACC,
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson DDI_DEFAULT_ACC
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele};
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * ************************************************************************** *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * common entry points - for loadable kernel modules *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * ************************************************************************** *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleint
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele_init(void)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int ret;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret = ddi_soft_state_init(&mrsas_state,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (struct mrsas_instance), 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ret != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "mr_sas: could not init state"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ret);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((ret = scsi_hba_init(&modlinkage)) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "mr_sas: could not init scsi hba"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_soft_state_fini(&mrsas_state);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ret);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret = mod_install(&modlinkage);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ret != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "mr_sas: mod_install failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele scsi_hba_fini(&modlinkage);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_soft_state_fini(&mrsas_state);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ret);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleint
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele_info(struct modinfo *modinfop)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (mod_info(&modlinkage, modinfop));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleint
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele_fini(void)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int ret;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((ret = mod_remove(&modlinkage)) != DDI_SUCCESS)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ret);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele scsi_hba_fini(&modlinkage);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_soft_state_fini(&mrsas_state);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ret);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * ************************************************************************** *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * common entry points - for autoconfiguration *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * ************************************************************************** *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int instance_no;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int nregs;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint8_t added_isr_f = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint8_t added_soft_isr_f = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint8_t create_devctl_node_f = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint8_t create_scsi_node_f = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint8_t create_ioc_node_f = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint8_t tran_alloc_f = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint8_t irq;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint16_t vendor_id;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint16_t device_id;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint16_t subsysvid;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint16_t subsysid;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint16_t command;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele off_t reglength = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int intr_types = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele char *data;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele scsi_hba_tran_t *tran;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_dma_attr_t tran_dma_attr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_instance *instance;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* CONSTCOND */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ASSERT(NO_COMPETING_THREADS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance_no = ddi_get_instance(dip);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * check to see whether this device is in a DMA-capable slot.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_slaveonly(dip) == DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas%d: Device in slave-only slot, unused",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance_no));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch (cmd) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case DDI_ATTACH:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_DLEVEL1, (CE_NOTE, "mr_sas: DDI_ATTACH"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* allocate the soft state for the instance */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_soft_state_zalloc(mrsas_state, instance_no)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas%d: Failed to allocate soft state",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance_no));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance = (struct mrsas_instance *)ddi_get_soft_state
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (mrsas_state, instance_no);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance == NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas%d: Bad soft state", instance_no));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_soft_state_free(mrsas_state, instance_no);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele bzero((caddr_t)instance,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (struct mrsas_instance));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->func_ptr = kmem_zalloc(
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (struct mrsas_func_ptr), KM_SLEEP);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ASSERT(instance->func_ptr);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Setup the PCI configuration space handles */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (pci_config_setup(dip, &instance->pci_handle) !=
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas%d: pci config setup failed ",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance_no));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_free(instance->func_ptr,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (struct mrsas_func_ptr));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_soft_state_free(mrsas_state, instance_no);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_dev_nregs(dip, &nregs) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: failed to get registers."));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pci_config_teardown(&instance->pci_handle);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_free(instance->func_ptr,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (struct mrsas_func_ptr));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_soft_state_free(mrsas_state, instance_no);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele vendor_id = pci_config_get16(instance->pci_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele PCI_CONF_VENID);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele device_id = pci_config_get16(instance->pci_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele PCI_CONF_DEVID);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele subsysvid = pci_config_get16(instance->pci_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele PCI_CONF_SUBVENID);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele subsysid = pci_config_get16(instance->pci_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele PCI_CONF_SUBSYSID);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pci_config_put16(instance->pci_handle, PCI_CONF_COMM,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (pci_config_get16(instance->pci_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele PCI_CONF_COMM) | PCI_COMM_ME));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele irq = pci_config_get8(instance->pci_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele PCI_CONF_ILINE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_DLEVEL1, (CE_CONT, "mr_sas%d: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "0x%x:0x%x 0x%x:0x%x, irq:%d drv-ver:%s",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance_no, vendor_id, device_id, subsysvid,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele subsysid, irq, MRSAS_VERSION));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* enable bus-mastering */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele command = pci_config_get16(instance->pci_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele PCI_CONF_COMM);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (!(command & PCI_COMM_ME)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele command |= PCI_COMM_ME;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pci_config_put16(instance->pci_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele PCI_CONF_COMM, command);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_CONT, "mr_sas%d: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "enable bus-mastering", instance_no));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_DLEVEL1, (CE_CONT, "mr_sas%d: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "bus-mastering already set", instance_no));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* initialize function pointers */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((device_id == PCI_DEVICE_ID_LSI_2108VDE) ||
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (device_id == PCI_DEVICE_ID_LSI_2108V)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_DLEVEL1, (CE_CONT, "mr_sas%d: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "2108V/DE detected", instance_no));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->func_ptr->read_fw_status_reg =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele read_fw_status_reg_ppc;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->func_ptr->issue_cmd = issue_cmd_ppc;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->func_ptr->issue_cmd_in_sync_mode =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele issue_cmd_in_sync_mode_ppc;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->func_ptr->issue_cmd_in_poll_mode =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele issue_cmd_in_poll_mode_ppc;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->func_ptr->enable_intr =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele enable_intr_ppc;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->func_ptr->disable_intr =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele disable_intr_ppc;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->func_ptr->intr_ack = intr_ack_ppc;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: Invalid device detected"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pci_config_teardown(&instance->pci_handle);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_free(instance->func_ptr,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (struct mrsas_func_ptr));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_soft_state_free(mrsas_state, instance_no);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->baseaddress = pci_config_get32(
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->pci_handle, PCI_CONF_BASE0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->baseaddress &= 0x0fffc;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->dip = dip;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->vendor_id = vendor_id;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->device_id = device_id;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->subsysvid = subsysvid;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->subsysid = subsysid;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->instance = instance_no;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Initialize FMA */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->fm_capabilities = ddi_prop_get_int(
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_DEV_T_ANY, instance->dip, DDI_PROP_DONTPASS,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "fm-capable", DDI_FM_EREPORT_CAPABLE |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele | DDI_FM_ERRCB_CAPABLE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_fm_init(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Initialize Interrupts */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((ddi_dev_regsize(instance->dip,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele REGISTER_SET_IO_2108, &reglength) != DDI_SUCCESS) ||
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele reglength < MINIMUM_MFI_MEM_SZ) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (reglength > DEFAULT_MFI_MEM_SZ) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele reglength = DEFAULT_MFI_MEM_SZ;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_DLEVEL1, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: register length to map is "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "0x%lx bytes", reglength));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_regs_map_setup(instance->dip,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele REGISTER_SET_IO_2108, &instance->regmap, 0,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele reglength, &endian_attr, &instance->regmap_handle)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: couldn't map control registers"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_attach;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Disable Interrupt Now.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Setup Software interrupt
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->func_ptr->disable_intr(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mrsas-enable-msi", &data) == DDI_SUCCESS) {
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China if (strncmp(data, "no", 3) == 0) {
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China msi_enable = 0;
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China con_log(CL_ANN1, (CE_WARN,
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China "msi_enable = %d disabled",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele msi_enable));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_prop_free(data);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_DLEVEL1, (CE_WARN, "msi_enable = %d",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele msi_enable));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Check for all supported interrupt types */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_intr_get_supported_types(
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dip, &intr_types) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "ddi_intr_get_supported_types() failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_attach;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_DLEVEL1, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "ddi_intr_get_supported_types() ret: 0x%x",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele intr_types));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Initialize and Setup Interrupt handler */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (msi_enable && (intr_types & DDI_INTR_TYPE_MSIX)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_add_intrs(instance,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_INTR_TYPE_MSIX) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "MSIX interrupt query failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_attach;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->intr_type = DDI_INTR_TYPE_MSIX;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else if (msi_enable && (intr_types &
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_INTR_TYPE_MSI)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_add_intrs(instance,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_INTR_TYPE_MSI) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "MSI interrupt query failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_attach;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->intr_type = DDI_INTR_TYPE_MSI;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else if (intr_types & DDI_INTR_TYPE_FIXED) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele msi_enable = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_add_intrs(instance,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_INTR_TYPE_FIXED) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "FIXED interrupt query failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_attach;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->intr_type = DDI_INTR_TYPE_FIXED;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "Device cannot "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "suppport either FIXED or MSI/X "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "interrupts"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_attach;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele added_isr_f = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* setup the mfi based low level driver */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (init_mfi(instance) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "mr_sas: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "could not initialize the low level driver"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_attach;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Initialize all Mutex */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele INIT_LIST_HEAD(&instance->completed_pool_list);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mutex_init(&instance->completed_pool_mtx,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "completed_pool_mtx", MUTEX_DRIVER,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_INTR_PRI(instance->intr_pri));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mutex_init(&instance->int_cmd_mtx, "int_cmd_mtx",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cv_init(&instance->int_cmd_cv, NULL, CV_DRIVER, NULL);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mutex_init(&instance->cmd_pool_mtx, "cmd_pool_mtx",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Register our soft-isr for highlevel interrupts. */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->isr_level = instance->intr_pri;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->isr_level == HIGH_LEVEL_INTR) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_add_softintr(dip, DDI_SOFTINT_HIGH,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &instance->soft_intr_id, NULL, NULL,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_softintr, (caddr_t)instance) !=
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele " Software ISR did not register"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_attach;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele added_soft_isr_f = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Allocate a transport structure */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (tran == NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "scsi_hba_tran_alloc failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_attach;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tran_alloc_f = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->tran = tran;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tran->tran_hba_private = instance;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tran->tran_tgt_init = mrsas_tran_tgt_init;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tran->tran_tgt_probe = scsi_hba_probe;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tran->tran_tgt_free = mrsas_tran_tgt_free;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tran->tran_init_pkt = mrsas_tran_init_pkt;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tran->tran_start = mrsas_tran_start;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tran->tran_abort = mrsas_tran_abort;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tran->tran_reset = mrsas_tran_reset;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tran->tran_getcap = mrsas_tran_getcap;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tran->tran_setcap = mrsas_tran_setcap;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tran->tran_destroy_pkt = mrsas_tran_destroy_pkt;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tran->tran_dmafree = mrsas_tran_dmafree;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tran->tran_sync_pkt = mrsas_tran_sync_pkt;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tran->tran_bus_config = mrsas_tran_bus_config;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China if (mrsas_relaxed_ordering)
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China mrsas_generic_dma_attr.dma_attr_flags |=
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China DDI_DMA_RELAXED_ORDERING;
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tran_dma_attr = mrsas_generic_dma_attr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tran_dma_attr.dma_attr_sgllen = instance->max_num_sge;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Attach this instance of the hba */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (scsi_hba_attach_setup(dip, &tran_dma_attr, tran, 0)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "scsi_hba_attach failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_attach;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* create devctl node for cfgadm command */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_create_minor_node(dip, "devctl",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele S_IFCHR, INST2DEVCTL(instance_no),
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_NT_SCSI_NEXUS, 0) == DDI_FAILURE) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: failed to create devctl node."));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_attach;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele create_devctl_node_f = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* create scsi node for cfgadm command */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_create_minor_node(dip, "scsi", S_IFCHR,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele INST2SCSI(instance_no),
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_NT_SCSI_ATTACHMENT_POINT, 0) ==
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_FAILURE) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: failed to create scsi node."));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_attach;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele create_scsi_node_f = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) sprintf(instance->iocnode, "%d:lsirdctl",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance_no);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Create a node for applications
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * for issuing ioctl to the driver.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_create_minor_node(dip, instance->iocnode,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele S_IFCHR, INST2LSIRDCTL(instance_no),
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_PSEUDO, 0) == DDI_FAILURE) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: failed to create ioctl node."));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_attach;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele create_ioc_node_f = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Create a taskq to handle dr events */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((instance->taskq = ddi_taskq_create(dip,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mrsas_dr_taskq", 1,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele TASKQ_DEFAULTPRI, 0)) == NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: failed to create taskq "));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->taskq = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_attach;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* enable interrupt */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->func_ptr->enable_intr(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* initiate AEN */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (start_mfi_aen(instance)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: failed to initiate AEN."));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_initiate_aen;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_DLEVEL1, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "AEN started for instance %d.", instance_no));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Finally! We are on the air. */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_report_dev(dip);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_check_acc_handle(instance->regmap_handle) !=
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_attach;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_check_acc_handle(instance->pci_handle) !=
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_attach;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mr_ld_list =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_zalloc(MRDRV_MAX_LD * sizeof (struct mrsas_ld),
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele KM_SLEEP);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case DDI_PM_RESUME:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: DDI_PM_RESUME"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case DDI_RESUME:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: DDI_RESUME"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele default:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: invalid attach cmd=%x", cmd));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelefail_initiate_aen:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelefail_attach:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (create_devctl_node_f) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_remove_minor_node(dip, "devctl");
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (create_scsi_node_f) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_remove_minor_node(dip, "scsi");
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (create_ioc_node_f) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_remove_minor_node(dip, instance->iocnode);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (tran_alloc_f) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele scsi_hba_tran_free(tran);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (added_soft_isr_f) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_remove_softintr(instance->soft_intr_id);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (added_isr_f) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_rem_intrs(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance && instance->taskq) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_taskq_destroy(instance->taskq);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_fm_fini(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pci_config_teardown(&instance->pci_handle);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_soft_state_free(mrsas_state, instance_no);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: return failure from mrsas_attach"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*ARGSUSED*/
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int rval;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int mrsas_minor = getminor((dev_t)arg);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_instance *instance;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch (cmd) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case DDI_INFO_DEVT2DEVINFO:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance = (struct mrsas_instance *)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_get_soft_state(mrsas_state,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MINOR2INST(mrsas_minor));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance == NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *resultp = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = DDI_FAILURE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *resultp = instance->dip;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = DDI_SUCCESS;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case DDI_INFO_DEVT2INSTANCE:
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China *resultp = (void *)(intptr_t)
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China (MINOR2INST(getminor((dev_t)arg)));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = DDI_SUCCESS;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele default:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *resultp = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = DDI_FAILURE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (rval);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int instance_no;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_instance *instance;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* CONSTCOND */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ASSERT(NO_COMPETING_THREADS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance_no = ddi_get_instance(dip);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance = (struct mrsas_instance *)ddi_get_soft_state(mrsas_state,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance_no);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (!instance) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas:%d could not get instance in detach",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance_no));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas%d: detaching device 0x%4x:0x%4x:0x%4x:0x%4x",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance_no, instance->vendor_id, instance->device_id,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->subsysvid, instance->subsysid));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch (cmd) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case DDI_DETACH:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mrsas_detach: DDI_DETACH"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (scsi_hba_detach(dip) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas:%d failed to detach",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance_no));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele scsi_hba_tran_free(instance->tran);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele flush_cache(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (abort_aen_cmd(instance, instance->aen_cmd)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "mrsas_detach: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "failed to abort prevous AEN command"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->func_ptr->disable_intr(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->isr_level == HIGH_LEVEL_INTR) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_remove_softintr(instance->soft_intr_id);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_rem_intrs(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->taskq) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_taskq_destroy(instance->taskq);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_free(instance->mr_ld_list, MRDRV_MAX_LD
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * sizeof (struct mrsas_ld));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele free_space_for_mfi(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_fm_fini(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pci_config_teardown(&instance->pci_handle);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_free(instance->func_ptr,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (struct mrsas_func_ptr));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_soft_state_free(mrsas_state, instance_no);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case DDI_PM_SUSPEND:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mrsas_detach: DDI_PM_SUSPEND"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case DDI_SUSPEND:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mrsas_detach: DDI_SUSPEND"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele default:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "invalid detach command:0x%x", cmd));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * ************************************************************************** *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * common entry points - for character driver types *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * ************************************************************************** *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_open(dev_t *dev, int openflags, int otyp, cred_t *credp)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int rval = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Check root permissions */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (drv_priv(credp) != 0) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: Non-root ioctl access denied!"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (EPERM);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Verify we are being opened as a character device */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (otyp != OTYP_CHR) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: ioctl node must be a char node"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (EINVAL);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_get_soft_state(mrsas_state, MINOR2INST(getminor(*dev)))
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele == NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ENXIO);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (scsi_hba_open) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = scsi_hba_open(dev, openflags, otyp, credp);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (rval);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_close(dev_t dev, int openflags, int otyp, cred_t *credp)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int rval = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* no need for locks! */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (scsi_hba_close) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = scsi_hba_close(dev, openflags, otyp, credp);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (rval);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int *rvalp)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int rval = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_instance *instance;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_ioctl *ioctl;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_aen aen;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance = ddi_get_soft_state(mrsas_state, MINOR2INST(getminor(dev)));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance == NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* invalid minor number */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "mr_sas: adapter not found."));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ENXIO);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ioctl = (struct mrsas_ioctl *)kmem_zalloc(sizeof (struct mrsas_ioctl),
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele KM_SLEEP);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ASSERT(ioctl);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch ((uint_t)cmd) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MRSAS_IOCTL_FIRMWARE:
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China if (ddi_copyin((void *)arg, ioctl,
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China sizeof (struct mrsas_ioctl), mode)) {
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China con_log(CL_ANN, (CE_WARN, "mrsas_ioctl: "
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China "ERROR IOCTL copyin"));
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China kmem_free(ioctl, sizeof (struct mrsas_ioctl));
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China return (EFAULT);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ioctl->control_code == MRSAS_DRIVER_IOCTL_COMMON) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = handle_drv_ioctl(instance, ioctl, mode);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = handle_mfi_ioctl(instance, ioctl, mode);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China if (ddi_copyout((void *)ioctl, (void *)arg,
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China (sizeof (struct mrsas_ioctl) - 1), mode)) {
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China con_log(CL_ANN, (CE_WARN,
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China "mrsas_ioctl: copy_to_user failed"));
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China rval = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MRSAS_IOCTL_AEN:
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China if (ddi_copyin((void *) arg, &aen,
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China sizeof (struct mrsas_aen), mode)) {
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China con_log(CL_ANN, (CE_WARN,
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China "mrsas_ioctl: ERROR AEN copyin"));
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China kmem_free(ioctl, sizeof (struct mrsas_ioctl));
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China return (EFAULT);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = handle_mfi_aen(instance, &aen);
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China if (ddi_copyout((void *) &aen, (void *)arg,
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China sizeof (struct mrsas_aen), mode)) {
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China con_log(CL_ANN, (CE_WARN,
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China "mrsas_ioctl: copy_to_user failed"));
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China rval = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele default:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = scsi_hba_ioctl(dev, cmd, arg,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mode, credp, rvalp);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_DLEVEL1, (CE_NOTE, "mrsas_ioctl: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "scsi_hba_ioctl called, ret = %x.", rval));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_free(ioctl, sizeof (struct mrsas_ioctl));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (rval);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * ************************************************************************** *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * common entry points - for block driver types *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * ************************************************************************** *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*ARGSUSED*/
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_reset(dev_info_t *dip, ddi_reset_cmd_t cmd)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int instance_no;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_instance *instance;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance_no = ddi_get_instance(dip);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance = (struct mrsas_instance *)ddi_get_soft_state
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (mrsas_state, instance_no);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (!instance) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "mr_sas:%d could not get adapter "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "in reset", instance_no));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->func_ptr->disable_intr(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "flushing cache for instance %d",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance_no));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele flush_cache(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * ************************************************************************** *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * entry points (SCSI HBA) *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * ************************************************************************** *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*ARGSUSED*/
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_tran_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele scsi_hba_tran_t *tran, struct scsi_device *sd)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_instance *instance;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint16_t tgt = sd->sd_address.a_target;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint8_t lun = sd->sd_address.a_lun;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "mrsas_tgt_init target %d lun %d",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tgt, lun));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance = ADDR2MR(&sd->sd_address);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ndi_dev_is_persistent_node(tgt_dip) == 0) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ndi_merge_node(tgt_dip, mrsas_name_node);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_set_name_addr(tgt_dip, NULL);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "mrsas_tgt_init in "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "ndi_dev_is_persistent_node DDI_FAILURE t = %d l = %d",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tgt, lun));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "mrsas_tgt_init dev_dip %p tgt_dip %p",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void *)instance->mr_ld_list[tgt].dip, (void *)tgt_dip));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (tgt < MRDRV_MAX_LD && lun == 0) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->mr_ld_list[tgt].dip == NULL &&
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele strcmp(ddi_driver_name(sd->sd_dev), "sd") == 0) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mr_ld_list[tgt].dip = tgt_dip;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mr_ld_list[tgt].lun_type = MRSAS_LD_LUN;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*ARGSUSED*/
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_tran_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele scsi_hba_tran_t *hba_tran, struct scsi_device *sd)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_instance *instance;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int tgt = sd->sd_address.a_target;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int lun = sd->sd_address.a_lun;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance = ADDR2MR(&sd->sd_address);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "tgt_free t = %d l = %d", tgt, lun));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (tgt < MRDRV_MAX_LD && lun == 0) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->mr_ld_list[tgt].dip == tgt_dip) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mr_ld_list[tgt].dip = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic dev_info_t *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_find_child(struct mrsas_instance *instance, uint16_t tgt, uint8_t lun)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dev_info_t *child = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele char addr[SCSI_MAXNAMELEN];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele char tmp[MAXNAMELEN];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) sprintf(addr, "%x,%x", tgt, lun);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (child = ddi_get_child(instance->dip); child;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele child = ddi_get_next_sibling(child)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_name_node(child, tmp, MAXNAMELEN) !=
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele continue;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (strcmp(addr, tmp) == 0) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "mrsas_find_child: return child = %p",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void *)child));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (child);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_name_node(dev_info_t *dip, char *name, int len)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int tgt, lun;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tgt = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_PROP_DONTPASS, "target", -1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mrsas_name_node: dip %p tgt %d", (void *)dip, tgt));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (tgt == -1) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele lun = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "lun", -1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (CE_NOTE, "mrsas_name_node: tgt %d lun %d", tgt, lun));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (lun == -1) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) snprintf(name, len, "%x,%x", tgt, lun);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic struct scsi_pkt *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_tran_init_pkt(struct scsi_address *ap, register struct scsi_pkt *pkt,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct buf *bp, int cmdlen, int statuslen, int tgtlen,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int flags, int (*callback)(), caddr_t arg)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct scsa_cmd *acmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_instance *instance;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct scsi_pkt *new_pkt;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance = ADDR2MR(ap);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* step #1 : pkt allocation */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (pkt == NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt = scsi_hba_pkt_alloc(instance->dip, ap, cmdlen, statuslen,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tgtlen, sizeof (struct scsa_cmd), callback, arg);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (pkt == NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (NULL);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd = PKT2CMD(pkt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Initialize the new pkt - we redundantly initialize
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * all the fields for illustrative purposes.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_pkt = pkt;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_flags = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_scblen = statuslen;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_cdblen = cmdlen;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_dmahandle = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_ncookies = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_cookie = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_cookiecnt = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_nwin = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_address = *ap;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_comp = (void (*)())NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_flags = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_time = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_resid = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_state = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_statistics = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_reason = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele new_pkt = pkt;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd = PKT2CMD(pkt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele new_pkt = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* step #2 : dma allocation/move */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (bp && bp->b_bcount != 0) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (acmd->cmd_dmahandle == NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_dma_alloc(instance, pkt, bp, flags,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele callback) == DDI_FAILURE) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (new_pkt) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele scsi_hba_pkt_free(ap, new_pkt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return ((struct scsi_pkt *)NULL);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_dma_move(instance, pkt, bp) == DDI_FAILURE) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return ((struct scsi_pkt *)NULL);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (pkt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_tran_start(struct scsi_address *ap, register struct scsi_pkt *pkt)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uchar_t cmd_done = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_instance *instance = ADDR2MR(ap);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d:SCSI CDB[0]=0x%x",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele __func__, __LINE__, pkt->pkt_cdbp[0]));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_reason = CMD_CMPLT;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *pkt->pkt_scbp = STATUS_GOOD; /* clear arq scsi_status */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd = build_cmd(instance, ap, pkt, &cmd_done);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Check if the command is already completed by the mrsas_build_cmd()
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * routine. In which case the busy_flag would be clear and scb will be
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * NULL and appropriate reason provided in pkt_reason field
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (cmd_done) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_reason = CMD_CMPLT;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_scbp[0] = STATUS_GOOD;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele | STATE_SENT_CMD;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (((pkt->pkt_flags & FLAG_NOINTR) == 0) && pkt->pkt_comp) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (*pkt->pkt_comp)(pkt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (TRAN_ACCEPT);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (cmd == NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (TRAN_BUSY);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((pkt->pkt_flags & FLAG_NOINTR) == 0) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->fw_outstanding > instance->max_fw_cmds) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_CONT, "mr_sas:Firmware busy"));
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele DTRACE_PROBE2(start_tran_err,
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele uint16_t, instance->fw_outstanding,
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele uint16_t, instance->max_fw_cmds);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return_mfi_pkt(instance, cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (TRAN_BUSY);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Synchronize the Cmd frame for the controller */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_dma_sync(cmd->frame_dma_obj.dma_handle, 0, 0,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_DMA_SYNC_FORDEV);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->func_ptr->issue_cmd(cmd, instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_header *hdr = &cmd->frame->hdr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->sync_cmd = MRSAS_TRUE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->func_ptr-> issue_cmd_in_poll_mode(instance, cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_reason = CMD_CMPLT;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_statistics = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_state |= STATE_XFERRED_DATA | STATE_GOT_STATUS;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch (ddi_get8(cmd->frame_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &hdr->cmd_status)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_STAT_OK:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_scbp[0] = STATUS_GOOD;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_STAT_SCSI_DONE_WITH_ERROR:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_reason = CMD_CMPLT;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_statistics = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((struct scsi_status *)pkt->pkt_scbp)->sts_chk = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_STAT_DEVICE_NOT_FOUND:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_reason = CMD_DEV_GONE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_statistics = STAT_DISCON;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele default:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((struct scsi_status *)pkt->pkt_scbp)->sts_busy = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) mrsas_common_check(instance, cmd);
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele DTRACE_PROBE2(start_nointr_done, uint8_t, hdr->cmd,
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele uint8_t, hdr->cmd_status);
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China return_mfi_pkt(instance, cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (pkt->pkt_comp) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (*pkt->pkt_comp)(pkt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (TRAN_ACCEPT);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*ARGSUSED*/
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_tran_abort(struct scsi_address *ap, struct scsi_pkt *pkt)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* abort command not supported by H/W */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*ARGSUSED*/
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_tran_reset(struct scsi_address *ap, int level)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* reset command not supported by H/W */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*ARGSUSED*/
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_tran_getcap(struct scsi_address *ap, char *cap, int whom)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int rval = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_instance *instance = ADDR2MR(ap);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* we do allow inquiring about capabilities for other targets */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (cap == NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (-1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch (scsi_hba_lookup_capstr(cap)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_DMA_MAX:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Limit to 16MB max transfer */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = mrsas_max_cap_maxxfer;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_MSG_OUT:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_DISCONNECT:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_SYNCHRONOUS:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_WIDE_XFER:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_TAGGED_QING:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_UNTAGGED_QING:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_PARITY:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_INITIATOR_ID:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = instance->init_id;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_ARQ:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_LINKED_CMDS:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_RESET_NOTIFICATION:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_GEOMETRY:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = -1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele default:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_DLEVEL2, (CE_NOTE, "Default cap coming 0x%x",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele scsi_hba_lookup_capstr(cap)));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = -1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (rval);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*ARGSUSED*/
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_tran_setcap(struct scsi_address *ap, char *cap, int value, int whom)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int rval = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* We don't allow setting capabilities for other targets */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (cap == NULL || whom == 0) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (-1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch (scsi_hba_lookup_capstr(cap)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_DMA_MAX:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_MSG_OUT:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_PARITY:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_LINKED_CMDS:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_RESET_NOTIFICATION:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_DISCONNECT:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_SYNCHRONOUS:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_UNTAGGED_QING:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_WIDE_XFER:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_INITIATOR_ID:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_ARQ:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * None of these are settable via
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * the capability interface.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_TAGGED_QING:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_SECTOR_SIZE:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCSI_CAP_TOTAL_SECTORS:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele default:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = -1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (rval);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_tran_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct scsa_cmd *acmd = PKT2CMD(pkt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (acmd->cmd_flags & CFLAG_DMAVALID) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_flags &= ~CFLAG_DMAVALID;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_dma_unbind_handle(acmd->cmd_dmahandle);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_dma_free_handle(&acmd->cmd_dmahandle);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_dmahandle = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* free the pkt */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele scsi_hba_pkt_free(ap, pkt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*ARGSUSED*/
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_tran_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele register struct scsa_cmd *acmd = PKT2CMD(pkt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (acmd->cmd_flags & CFLAG_DMAVALID) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_flags &= ~CFLAG_DMAVALID;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_dma_unbind_handle(acmd->cmd_dmahandle);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_dma_free_handle(&acmd->cmd_dmahandle);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_dmahandle = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*ARGSUSED*/
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_tran_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele register struct scsa_cmd *acmd = PKT2CMD(pkt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (acmd->cmd_flags & CFLAG_DMAVALID) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_dma_sync(acmd->cmd_dmahandle, acmd->cmd_dma_offset,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_dma_len, (acmd->cmd_flags & CFLAG_DMASEND) ?
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * mrsas_isr(caddr_t)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * The Interrupt Service Routine
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Collect status for all completed commands and do callback
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic uint_t
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_isr(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int need_softintr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t producer;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t consumer;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t context;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ASSERT(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((instance->intr_type == DDI_INTR_TYPE_FIXED) &&
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele !instance->func_ptr->intr_ack(instance)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_INTR_UNCLAIMED);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_dma_sync(instance->mfi_internal_dma_obj.dma_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 0, 0, DDI_DMA_SYNC_FORCPU);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_check_dma_handle(instance->mfi_internal_dma_obj.dma_handle)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China return (DDI_INTR_CLAIMED);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele producer = ddi_get32(instance->mfi_internal_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->producer);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele consumer = ddi_get32(instance->mfi_internal_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->consumer);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_CONT, " producer %x consumer %x ",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele producer, consumer));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (producer == consumer) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_WARN, "producer = consumer case"));
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele DTRACE_PROBE2(isr_pc_err, uint32_t, producer,
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele uint32_t, consumer);
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China return (DDI_INTR_CLAIMED);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mutex_enter(&instance->completed_pool_mtx);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele while (consumer != producer) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele context = ddi_get32(instance->mfi_internal_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &instance->reply_queue[consumer]);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd = instance->cmd_list[context];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mlist_add_tail(&cmd->list, &instance->completed_pool_list);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele consumer++;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (consumer == (instance->max_fw_cmds + 1)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele consumer = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mutex_exit(&instance->completed_pool_mtx);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(instance->mfi_internal_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->consumer, consumer);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_dma_sync(instance->mfi_internal_dma_obj.dma_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 0, 0, DDI_DMA_SYNC_FORDEV);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->softint_running) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele need_softintr = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele need_softintr = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->isr_level == HIGH_LEVEL_INTR) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (need_softintr) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_trigger_softintr(instance->soft_intr_id);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Not a high-level interrupt, therefore call the soft level
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * interrupt explicitly
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) mrsas_softintr(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_INTR_CLAIMED);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * ************************************************************************** *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * libraries *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * ************************************************************************** *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * get_mfi_pkt : Get a command from the free pool
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * After successful allocation, the caller of this routine
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * must clear the frame buffer (memset to zero) before
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * using the packet further.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * ***** Note *****
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * After clearing the frame buffer the context id of the
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * frame buffer SHOULD be restored back.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic struct mrsas_cmd *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleget_mfi_pkt(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mlist_t *head = &instance->cmd_pool_list;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mutex_enter(&instance->cmd_pool_mtx);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ASSERT(mutex_owned(&instance->cmd_pool_mtx));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (!mlist_empty(head)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd = mlist_entry(head->next, struct mrsas_cmd, list);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mlist_del_init(head->next);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (cmd != NULL)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->pkt = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mutex_exit(&instance->cmd_pool_mtx);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * return_mfi_pkt : Return a cmd to free command pool
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelereturn_mfi_pkt(struct mrsas_instance *instance, struct mrsas_cmd *cmd)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mutex_enter(&instance->cmd_pool_mtx);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ASSERT(mutex_owned(&instance->cmd_pool_mtx));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mlist_add(&cmd->list, &instance->cmd_pool_list);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mutex_exit(&instance->cmd_pool_mtx);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * destroy_mfi_frame_pool
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeledestroy_mfi_frame_pool(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t max_cmd = instance->max_fw_cmds;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* return all frames to pool */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < max_cmd+1; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd = instance->cmd_list[i];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (cmd->frame_dma_obj_status == DMA_OBJ_ALLOCATED)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) mrsas_free_dma_obj(instance, cmd->frame_dma_obj);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_dma_obj_status = DMA_OBJ_FREED;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * create_mfi_frame_pool
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelecreate_mfi_frame_pool(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int i = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int cookie_cnt;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint16_t max_cmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint16_t sge_sz;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t sgl_sz;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t tot_frame_size;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele max_cmd = instance->max_fw_cmds;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sge_sz = sizeof (struct mrsas_sge64);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* calculated the number of 64byte frames required for SGL */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sgl_sz = sge_sz * instance->max_num_sge;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tot_frame_size = sgl_sz + MRMFI_FRAME_SIZE + SENSE_LENGTH;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_DLEVEL3, (CE_NOTE, "create_mfi_frame_pool: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "sgl_sz %x tot_frame_size %x", sgl_sz, tot_frame_size));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele while (i < max_cmd+1) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd = instance->cmd_list[i];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_dma_obj.size = tot_frame_size;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_dma_obj.dma_attr = mrsas_generic_dma_attr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_dma_obj.dma_attr.dma_attr_sgllen = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_dma_obj.dma_attr.dma_attr_align = 64;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cookie_cnt = mrsas_alloc_dma_obj(instance, &cmd->frame_dma_obj,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uchar_t)DDI_STRUCTURE_LE_ACC);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (cookie_cnt == -1 || cookie_cnt > 1) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "create_mfi_frame_pool: could not alloc."));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele bzero(cmd->frame_dma_obj.buffer, tot_frame_size);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_dma_obj_status = DMA_OBJ_ALLOCATED;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame = (union mrsas_frame *)cmd->frame_dma_obj.buffer;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_phys_addr =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_dma_obj.dma_cookie[0].dmac_address;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->sense = (uint8_t *)(((unsigned long)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_dma_obj.buffer) +
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tot_frame_size - SENSE_LENGTH);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->sense_phys_addr =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_dma_obj.dma_cookie[0].dmac_address +
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tot_frame_size - SENSE_LENGTH;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (!cmd->frame || !cmd->sense) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: pci_pool_alloc failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ENOMEM);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &cmd->frame->io.context, cmd->index);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele i++;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_DLEVEL3, (CE_NOTE, "[%x]-%x",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->index, cmd->frame_phys_addr));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * free_additional_dma_buffer
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelefree_additional_dma_buffer(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->mfi_internal_dma_obj.status == DMA_OBJ_ALLOCATED) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) mrsas_free_dma_obj(instance,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_internal_dma_obj);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_internal_dma_obj.status = DMA_OBJ_FREED;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->mfi_evt_detail_obj.status == DMA_OBJ_ALLOCATED) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) mrsas_free_dma_obj(instance,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_evt_detail_obj);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_evt_detail_obj.status = DMA_OBJ_FREED;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * alloc_additional_dma_buffer
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelealloc_additional_dma_buffer(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t reply_q_sz;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t internal_buf_size = PAGESIZE*2;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* max cmds plus 1 + producer & consumer */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele reply_q_sz = sizeof (uint32_t) * (instance->max_fw_cmds + 1 + 2);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_internal_dma_obj.size = internal_buf_size;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_internal_dma_obj.dma_attr = mrsas_generic_dma_attr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_internal_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_internal_dma_obj.dma_attr.dma_attr_count_max =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 0xFFFFFFFFU;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_internal_dma_obj.dma_attr.dma_attr_sgllen = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_alloc_dma_obj(instance, &instance->mfi_internal_dma_obj,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: could not alloc reply queue"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele bzero(instance->mfi_internal_dma_obj.buffer, internal_buf_size);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_internal_dma_obj.status |= DMA_OBJ_ALLOCATED;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->producer = (uint32_t *)((unsigned long)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_internal_dma_obj.buffer);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->consumer = (uint32_t *)((unsigned long)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_internal_dma_obj.buffer + 4);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->reply_queue = (uint32_t *)((unsigned long)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_internal_dma_obj.buffer + 8);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->internal_buf = (caddr_t)(((unsigned long)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_internal_dma_obj.buffer) + reply_q_sz + 8);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->internal_buf_dmac_add =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address +
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (reply_q_sz + 8);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->internal_buf_size = internal_buf_size -
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (reply_q_sz + 8);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* allocate evt_detail */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_evt_detail_obj.size = sizeof (struct mrsas_evt_detail);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_evt_detail_obj.dma_attr = mrsas_generic_dma_attr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_evt_detail_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_evt_detail_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_evt_detail_obj.dma_attr.dma_attr_sgllen = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_evt_detail_obj.dma_attr.dma_attr_align = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_alloc_dma_obj(instance, &instance->mfi_evt_detail_obj,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "alloc_additional_dma_buffer: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "could not allocate data transfer buffer."));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele bzero(instance->mfi_evt_detail_obj.buffer,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (struct mrsas_evt_detail));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_evt_detail_obj.status |= DMA_OBJ_ALLOCATED;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * free_space_for_mfi
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelefree_space_for_mfi(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t max_cmd = instance->max_fw_cmds;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* already freed */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->cmd_list == NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele free_additional_dma_buffer(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* first free the MFI frame pool */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele destroy_mfi_frame_pool(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* free all the commands in the cmd_list */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < instance->max_fw_cmds+1; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_free(instance->cmd_list[i],
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (struct mrsas_cmd));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->cmd_list[i] = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* free the cmd_list buffer itself */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_free(instance->cmd_list,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (struct mrsas_cmd *) * (max_cmd+1));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->cmd_list = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele INIT_LIST_HEAD(&instance->cmd_pool_list);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * alloc_space_for_mfi
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelealloc_space_for_mfi(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t max_cmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele size_t sz;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele max_cmd = instance->max_fw_cmds;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* reserve 1 more slot for flush_cache */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sz = sizeof (struct mrsas_cmd *) * (max_cmd+1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * instance->cmd_list is an array of struct mrsas_cmd pointers.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Allocate the dynamic array first and then allocate individual
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * commands.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->cmd_list = kmem_zalloc(sz, KM_SLEEP);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ASSERT(instance->cmd_list);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < max_cmd+1; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->cmd_list[i] = kmem_zalloc(sizeof (struct mrsas_cmd),
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele KM_SLEEP);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ASSERT(instance->cmd_list[i]);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele INIT_LIST_HEAD(&instance->cmd_pool_list);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* add all the commands to command pool (instance->cmd_pool) */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < max_cmd; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd = instance->cmd_list[i];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->index = i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mlist_add_tail(&cmd->list, &instance->cmd_pool_list);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* single slot for flush_cache won't be added in command pool */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd = instance->cmd_list[max_cmd];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->index = i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* create a frame pool and assign one frame to each cmd */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (create_mfi_frame_pool(instance)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE, "error creating frame DMA pool"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* create a frame pool and assign one frame to each cmd */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (alloc_additional_dma_buffer(instance)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE, "error creating frame DMA pool"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * get_ctrl_info
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleget_ctrl_info(struct mrsas_instance *instance,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_ctrl_info *ctrl_info)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int ret = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_dcmd_frame *dcmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_ctrl_info *ci;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd = get_mfi_pkt(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (!cmd) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "Failed to get a cmd for ctrl info"));
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele DTRACE_PROBE2(info_mfi_err, uint16_t, instance->fw_outstanding,
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele uint16_t, instance->max_fw_cmds);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Clear the frame buffer and assign back the context id */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->index);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dcmd = &cmd->frame->dcmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ci = (struct mrsas_ctrl_info *)instance->internal_buf;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (!ci) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "Failed to alloc mem for ctrl info"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return_mfi_pkt(instance, cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memset(ci, 0, sizeof (struct mrsas_ctrl_info));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* for( i = 0; i < DCMD_MBOX_SZ; i++ ) dcmd->mbox.b[i] = 0; */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memset(dcmd->mbox.b, 0, DCMD_MBOX_SZ);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->cmd, MFI_CMD_OP_DCMD);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->cmd_status,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MFI_CMD_STATUS_POLL_MODE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->sge_count, 1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(cmd->frame_dma_obj.acc_handle, &dcmd->flags,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MFI_FRAME_DIR_READ);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(cmd->frame_dma_obj.acc_handle, &dcmd->timeout, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->data_xfer_len,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (struct mrsas_ctrl_info));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->opcode,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MR_DCMD_CTRL_GET_INFO);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->sgl.sge32[0].phys_addr,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->internal_buf_dmac_add);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->sgl.sge32[0].length,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (struct mrsas_ctrl_info));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_count = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (!instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret = 0;
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China ctrl_info->max_request_size = ddi_get32(
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China cmd->frame_dma_obj.acc_handle, &ci->max_request_size);
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China ctrl_info->ld_present_count = ddi_get16(
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China cmd->frame_dma_obj.acc_handle, &ci->ld_present_count);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_rep_get8(cmd->frame_dma_obj.acc_handle,
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China (uint8_t *)(ctrl_info->product_name),
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China (uint8_t *)(ci->product_name), 80 * sizeof (char),
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China DDI_DEV_AUTOINCR);
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China /* should get more members of ci with ddi_get when needed */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "get_ctrl_info: Ctrl info failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret = -1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_common_check(instance, cmd) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret = -1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele return_mfi_pkt(instance, cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ret);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * abort_aen_cmd
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleabort_aen_cmd(struct mrsas_instance *instance,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd_to_abort)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int ret = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_abort_frame *abort_fr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd = get_mfi_pkt(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (!cmd) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "Failed to get a cmd for ctrl info"));
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele DTRACE_PROBE2(abort_mfi_err, uint16_t, instance->fw_outstanding,
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele uint16_t, instance->max_fw_cmds);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Clear the frame buffer and assign back the context id */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->index);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele abort_fr = &cmd->frame->abort;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* prepare and issue the abort frame */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(cmd->frame_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &abort_fr->cmd, MFI_CMD_OP_ABORT);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(cmd->frame_dma_obj.acc_handle, &abort_fr->cmd_status,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MFI_CMD_STATUS_SYNC_MODE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(cmd->frame_dma_obj.acc_handle, &abort_fr->flags, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &abort_fr->abort_context,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd_to_abort->index);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &abort_fr->abort_mfi_phys_addr_lo, cmd_to_abort->frame_phys_addr);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &abort_fr->abort_mfi_phys_addr_hi, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->aen_cmd->abort_aen = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->sync_cmd = MRSAS_TRUE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_count = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "abort_aen_cmd: issue_cmd_in_sync_mode failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret = -1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->aen_cmd->abort_aen = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->aen_cmd = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) mrsas_common_check(instance, cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China return_mfi_pkt(instance, cmd);
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ret);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * init_mfi
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleinit_mfi(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_ctrl_info ctrl_info;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_init_frame *init_frame;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_init_queue_info *initq_info;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* we expect the FW state to be READY */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mfi_state_transition_to_ready(instance)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "mr_sas: F/W is not ready"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_ready_state;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* get various operational parameters from status register */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->max_num_sge =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (instance->func_ptr->read_fw_status_reg(instance) &
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 0xFF0000) >> 0x10;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Reduce the max supported cmds by 1. This is to ensure that the
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * reply_q_sz (1 more than the max cmd that driver may send)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * does not exceed max cmds that the FW can support
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->max_fw_cmds =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->func_ptr->read_fw_status_reg(instance) & 0xFFFF;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->max_fw_cmds = instance->max_fw_cmds - 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->max_num_sge =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (instance->max_num_sge > MRSAS_MAX_SGE_CNT) ?
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MRSAS_MAX_SGE_CNT : instance->max_num_sge;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* create a pool of commands */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (alloc_space_for_mfi(instance) != DDI_SUCCESS)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_alloc_fw_space;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Prepare a init frame. Note the init frame points to queue info
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * structure. Each frame has SGL allocated after first 64 bytes. For
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * this frame - since we don't need any SGL - we use SGL's space as
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * queue info structure
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd = get_mfi_pkt(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Clear the frame buffer and assign back the context id */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->index);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele init_frame = (struct mrsas_init_frame *)cmd->frame;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele initq_info = (struct mrsas_init_queue_info *)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((unsigned long)init_frame + 64);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memset(init_frame, 0, MRMFI_FRAME_SIZE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memset(initq_info, 0, sizeof (struct mrsas_init_queue_info));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &initq_info->init_flags, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &initq_info->reply_queue_entries, instance->max_fw_cmds + 1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &initq_info->producer_index_phys_addr_hi, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &initq_info->producer_index_phys_addr_lo,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &initq_info->consumer_index_phys_addr_hi, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &initq_info->consumer_index_phys_addr_lo,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address + 4);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &initq_info->reply_queue_start_phys_addr_hi, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &initq_info->reply_queue_start_phys_addr_lo,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address + 8);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(cmd->frame_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &init_frame->cmd, MFI_CMD_OP_INIT);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(cmd->frame_dma_obj.acc_handle, &init_frame->cmd_status,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MFI_CMD_STATUS_POLL_MODE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(cmd->frame_dma_obj.acc_handle, &init_frame->flags, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &init_frame->queue_info_new_phys_addr_lo,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_phys_addr + 64);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &init_frame->queue_info_new_phys_addr_hi, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &init_frame->data_xfer_len,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (struct mrsas_init_queue_info));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_count = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* issue the init frame in polled mode */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "failed to init firmware"));
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China return_mfi_pkt(instance, cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_fw_init;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_common_check(instance, cmd) != DDI_SUCCESS) {
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China return_mfi_pkt(instance, cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto fail_fw_init;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China return_mfi_pkt(instance, cmd);
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* gather misc FW related information */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (!get_ctrl_info(instance, &ctrl_info)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->max_sectors_per_req = ctrl_info.max_request_size;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "product name %s ld present %d",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ctrl_info.product_name, ctrl_info.ld_present_count));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->max_sectors_per_req = instance->max_num_sge *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele PAGESIZE / 512;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelefail_fw_init:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelefail_alloc_fw_space:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele free_space_for_mfi(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelefail_ready_state:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_regs_map_free(&instance->regmap_handle);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelefail_mfi_reg_setup:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * mfi_state_transition_to_ready : Move the FW to READY state
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * @reg_set : MFI register set
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemfi_state_transition_to_ready(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint8_t max_wait;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t fw_ctrl;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t fw_state;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t cur_state;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele fw_state =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->func_ptr->read_fw_status_reg(instance) & MFI_STATE_MASK;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mfi_state_transition_to_ready:FW state = 0x%x", fw_state));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele while (fw_state != MFI_STATE_READY) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mfi_state_transition_to_ready:FW state%x", fw_state));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch (fw_state) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_STATE_FAULT:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: FW in FAULT state!!"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ENODEV);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_STATE_WAIT_HANDSHAKE:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* set the CLR bit in IMR0 */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: FW waiting for HANDSHAKE"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * PCI_Hot Plug: MFI F/W requires
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * (MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * to be set
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* WR_IB_MSG_0(MFI_INIT_CLEAR_HANDSHAKE, instance); */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele WR_IB_DOORBELL(MFI_INIT_CLEAR_HANDSHAKE |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MFI_INIT_HOTPLUG, instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele max_wait = 2;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cur_state = MFI_STATE_WAIT_HANDSHAKE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_STATE_BOOT_MESSAGE_PENDING:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* set the CLR bit in IMR0 */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: FW state boot message pending"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * PCI_Hot Plug: MFI F/W requires
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * (MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * to be set
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele WR_IB_DOORBELL(MFI_INIT_HOTPLUG, instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele max_wait = 10;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_STATE_OPERATIONAL:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* bring it to READY state; assuming max wait 2 secs */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->func_ptr->disable_intr(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: FW in OPERATIONAL state"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * PCI_Hot Plug: MFI F/W requires
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * (MFI_INIT_READY | MFI_INIT_MFIMODE | MFI_INIT_ABORT)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * to be set
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* WR_IB_DOORBELL(MFI_INIT_READY, instance); */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele WR_IB_DOORBELL(MFI_RESET_FLAGS, instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele max_wait = 10;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cur_state = MFI_STATE_OPERATIONAL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_STATE_UNDEFINED:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* this state should not last for more than 2 seconds */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE, "FW state undefined"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele max_wait = 2;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cur_state = MFI_STATE_UNDEFINED;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_STATE_BB_INIT:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele max_wait = 2;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cur_state = MFI_STATE_BB_INIT;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_STATE_FW_INIT:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele max_wait = 2;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cur_state = MFI_STATE_FW_INIT;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_STATE_DEVICE_SCAN:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele max_wait = 10;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cur_state = MFI_STATE_DEVICE_SCAN;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele default:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: Unknown state 0x%x", fw_state));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ENODEV);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* the cur_state should not last for more than max_wait secs */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < (max_wait * MILLISEC); i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* fw_state = RD_OB_MSG_0(instance) & MFI_STATE_MASK; */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele fw_state =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->func_ptr->read_fw_status_reg(instance) &
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MFI_STATE_MASK;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (fw_state == cur_state) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele delay(1 * drv_usectohz(MILLISEC));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* return error if fw_state hasn't changed after max_wait */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (fw_state == cur_state) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "FW state hasn't changed in %d secs", max_wait));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ENODEV);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele };
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele fw_ctrl = RD_IB_DOORBELL(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mfi_state_transition_to_ready:FW ctrl = 0x%x", fw_ctrl));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Write 0xF to the doorbell register to do the following.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * - Abort all outstanding commands (bit 0).
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * - Transition from OPERATIONAL to READY state (bit 1).
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * - Discard (possible) low MFA posted in 64-bit mode (bit-2).
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * - Set to release FW to continue running (i.e. BIOS handshake
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * (bit 3).
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele WR_IB_DOORBELL(0xF, instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ENODEV);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * get_seq_num
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleget_seq_num(struct mrsas_instance *instance,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_evt_log_info *eli)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int ret = DDI_SUCCESS;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dma_obj_t dcmd_dma_obj;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_dcmd_frame *dcmd;
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China struct mrsas_evt_log_info *eli_tmp;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd = get_mfi_pkt(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (!cmd) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmn_err(CE_WARN, "mr_sas: failed to get a cmd");
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele DTRACE_PROBE2(seq_num_mfi_err, uint16_t,
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele instance->fw_outstanding, uint16_t, instance->max_fw_cmds);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ENOMEM);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Clear the frame buffer and assign back the context id */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->index);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dcmd = &cmd->frame->dcmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* allocate the data transfer buffer */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dcmd_dma_obj.size = sizeof (struct mrsas_evt_log_info);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dcmd_dma_obj.dma_attr = mrsas_generic_dma_attr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dcmd_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dcmd_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dcmd_dma_obj.dma_attr.dma_attr_sgllen = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dcmd_dma_obj.dma_attr.dma_attr_align = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_alloc_dma_obj(instance, &dcmd_dma_obj,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "get_seq_num: could not allocate data transfer buffer."));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memset(dcmd_dma_obj.buffer, 0,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (struct mrsas_evt_log_info));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memset(dcmd->mbox.b, 0, DCMD_MBOX_SZ);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->cmd, MFI_CMD_OP_DCMD);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->cmd_status, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->sge_count, 1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(cmd->frame_dma_obj.acc_handle, &dcmd->flags,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MFI_FRAME_DIR_READ);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(cmd->frame_dma_obj.acc_handle, &dcmd->timeout, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->data_xfer_len,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (struct mrsas_evt_log_info));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->opcode,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MR_DCMD_CTRL_EVENT_GET_INFO);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->sgl.sge32[0].length,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (struct mrsas_evt_log_info));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->sgl.sge32[0].phys_addr,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dcmd_dma_obj.dma_cookie[0].dmac_address);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->sync_cmd = MRSAS_TRUE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_count = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmn_err(CE_WARN, "get_seq_num: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "failed to issue MRSAS_DCMD_CTRL_EVENT_GET_INFO");
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret = DDI_FAILURE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China eli_tmp = (struct mrsas_evt_log_info *)dcmd_dma_obj.buffer;
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China eli->newest_seq_num = ddi_get32(cmd->frame_dma_obj.acc_handle,
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China &eli_tmp->newest_seq_num);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret = DDI_SUCCESS;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_free_dma_obj(instance, dcmd_dma_obj) != DDI_SUCCESS)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret = DDI_FAILURE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_common_check(instance, cmd) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret = DDI_FAILURE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China return_mfi_pkt(instance, cmd);
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ret);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * start_mfi_aen
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestart_mfi_aen(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int ret = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_evt_log_info eli;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele union mrsas_evt_class_locale class_locale;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* get the latest sequence number from FW */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memset(&eli, 0, sizeof (struct mrsas_evt_log_info));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (get_seq_num(instance, &eli)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmn_err(CE_WARN, "start_mfi_aen: failed to get seq num");
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (-1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* register AEN with FW for latest sequence number plus 1 */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele class_locale.members.reserved = 0;
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China class_locale.members.locale = LE_16(MR_EVT_LOCALE_ALL);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele class_locale.members.class = MR_EVT_CLASS_INFO;
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China class_locale.word = LE_32(class_locale.word);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret = register_mfi_aen(instance, eli.newest_seq_num + 1,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele class_locale.word);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ret) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmn_err(CE_WARN, "start_mfi_aen: aen registration failed");
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (-1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ret);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * flush_cache
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleflush_cache(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_dcmd_frame *dcmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t max_cmd = instance->max_fw_cmds;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd = instance->cmd_list[max_cmd];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (cmd == NULL)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dcmd = &cmd->frame->dcmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memset(dcmd->mbox.b, 0, DCMD_MBOX_SZ);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->cmd, MFI_CMD_OP_DCMD);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->cmd_status, 0x0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->sge_count, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(cmd->frame_dma_obj.acc_handle, &dcmd->flags,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MFI_FRAME_DIR_NONE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(cmd->frame_dma_obj.acc_handle, &dcmd->timeout, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->data_xfer_len, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->opcode,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MR_DCMD_CTRL_CACHE_FLUSH);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->mbox.b[0],
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_count = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "flush_cache: failed to issue MFI_DCMD_CTRL_CACHE_FLUSH"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_DLEVEL1, (CE_NOTE, "done"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * service_mfi_aen- Completes an AEN command
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * @instance: Adapter soft state
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * @cmd: Command to be completed
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleservice_mfi_aen(struct mrsas_instance *instance, struct mrsas_cmd *cmd)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t seq_num;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_evt_detail *evt_detail =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (struct mrsas_evt_detail *)instance->mfi_evt_detail_obj.buffer;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int rval = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int tgt = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_acc_handle_t acc_handle;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acc_handle = cmd->frame_dma_obj.acc_handle;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->cmd_status = ddi_get8(acc_handle, &cmd->frame->io.cmd_status);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (cmd->cmd_status == ENODATA) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->cmd_status = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * log the MFI AEN event to the sysevent queue so that
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * application will get noticed
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_log_sysevent(instance->dip, DDI_VENDOR_LSI, "LSIMEGA", "SAS",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele NULL, NULL, DDI_NOSLEEP) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int instance_no = ddi_get_instance(instance->dip);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas%d: Failed to log AEN event", instance_no));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Check for any ld devices that has changed state. i.e. online
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * or offline.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "AEN: code = %x class = %x locale = %x args = %x",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_get32(acc_handle, &evt_detail->code),
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele evt_detail->cl.members.class,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_get16(acc_handle, &evt_detail->cl.members.locale),
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_get8(acc_handle, &evt_detail->arg_type)));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch (ddi_get32(acc_handle, &evt_detail->code)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MR_EVT_CFG_CLEARED: {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (tgt = 0; tgt < MRDRV_MAX_LD; tgt++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->mr_ld_list[tgt].dip != NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = mrsas_service_evt(instance, tgt, 0,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MRSAS_EVT_UNCONFIG_TGT, NULL);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: CFG CLEARED AEN rval = %d "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "tgt id = %d", rval, tgt));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MR_EVT_LD_DELETED: {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = mrsas_service_evt(instance,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_get16(acc_handle, &evt_detail->args.ld.target_id), 0,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MRSAS_EVT_UNCONFIG_TGT, NULL);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_WARN, "mr_sas: LD DELETED AEN rval = %d "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "tgt id = %d index = %d", rval,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_get16(acc_handle, &evt_detail->args.ld.target_id),
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_get8(acc_handle, &evt_detail->args.ld.ld_index)));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } /* End of MR_EVT_LD_DELETED */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MR_EVT_LD_CREATED: {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = mrsas_service_evt(instance,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_get16(acc_handle, &evt_detail->args.ld.target_id), 0,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MRSAS_EVT_CONFIG_TGT, NULL);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_WARN, "mr_sas: LD CREATED AEN rval = %d "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "tgt id = %d index = %d", rval,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_get16(acc_handle, &evt_detail->args.ld.target_id),
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_get8(acc_handle, &evt_detail->args.ld.ld_index)));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } /* End of MR_EVT_LD_CREATED */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } /* End of Main Switch */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* get copy of seq_num and class/locale for re-registration */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele seq_num = ddi_get32(acc_handle, &evt_detail->seq_num);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele seq_num++;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memset(instance->mfi_evt_detail_obj.buffer, 0,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (struct mrsas_evt_detail));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &cmd->frame->dcmd.cmd_status, 0x0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &cmd->frame->dcmd.mbox.w[0], seq_num);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->aen_seq_num = seq_num;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_count = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Issue the aen registration frame */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->func_ptr->issue_cmd(cmd, instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * complete_cmd_in_sync_mode - Completes an internal command
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * @instance: Adapter soft state
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * @cmd: Command to be completed
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * The issue_cmd_in_sync_mode() function waits for a command to complete
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * after it issues a command. This function wakes up that waiting routine by
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * calling wake_up() on the wait queue.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelecomplete_cmd_in_sync_mode(struct mrsas_instance *instance,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->cmd_status = ddi_get8(cmd->frame_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &cmd->frame->io.cmd_status);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->sync_cmd = MRSAS_FALSE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (cmd->cmd_status == ENODATA) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->cmd_status = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cv_broadcast(&instance->int_cmd_cv);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * mrsas_softintr - The Software ISR
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * @param arg : HBA soft state
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * called from high-level interrupt if hi-level interrupt are not there,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * otherwise triggered as a soft interrupt
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic uint_t
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_softintr(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct scsi_pkt *pkt;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct scsa_cmd *acmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mlist_head *pos, *next;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mlist_t process_list;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_header *hdr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct scsi_arq_status *arqstat;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_CONT, "mrsas_softintr called"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ASSERT(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mutex_enter(&instance->completed_pool_mtx);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mlist_empty(&instance->completed_pool_list)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mutex_exit(&instance->completed_pool_mtx);
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China return (DDI_INTR_CLAIMED);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->softint_running = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele INIT_LIST_HEAD(&process_list);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mlist_splice(&instance->completed_pool_list, &process_list);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele INIT_LIST_HEAD(&instance->completed_pool_list);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mutex_exit(&instance->completed_pool_mtx);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* perform all callbacks first, before releasing the SCBs */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mlist_for_each_safe(pos, next, &process_list) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd = mlist_entry(pos, struct mrsas_cmd, list);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* syncronize the Cmd frame for the controller */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_dma_sync(cmd->frame_dma_obj.dma_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 0, 0, DDI_DMA_SYNC_FORCPU);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_check_dma_handle(cmd->frame_dma_obj.dma_handle) !=
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China return (DDI_INTR_CLAIMED);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele hdr = &cmd->frame->hdr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* remove the internal command from the process list */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mlist_del_init(&cmd->list);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch (ddi_get8(cmd->frame_dma_obj.acc_handle, &hdr->cmd)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_CMD_OP_PD_SCSI:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_CMD_OP_LD_SCSI:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_CMD_OP_LD_READ:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_CMD_OP_LD_WRITE:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * MFI_CMD_OP_PD_SCSI and MFI_CMD_OP_LD_SCSI
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * could have been issued either through an
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * IO path or an IOCTL path. If it was via IOCTL,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * we will send it to internal completion.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (cmd->sync_cmd == MRSAS_TRUE) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele complete_cmd_in_sync_mode(instance, cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* regular commands */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd = cmd->cmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt = CMD2PKT(acmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (acmd->cmd_flags & CFLAG_DMAVALID) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (acmd->cmd_flags & CFLAG_CONSISTENT) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_dma_sync(acmd->cmd_dmahandle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_dma_offset,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_dma_len,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_DMA_SYNC_FORCPU);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_reason = CMD_CMPLT;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_statistics = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_state = STATE_GOT_BUS
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele | STATE_GOT_TARGET | STATE_SENT_CMD
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele | STATE_XFERRED_DATA | STATE_GOT_STATUS;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_CONT,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "CDB[0] = %x completed for %s: size %lx context %x",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_cdbp[0], ((acmd->islogical) ? "LD" : "PD"),
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_dmacount, hdr->context));
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele DTRACE_PROBE3(softintr_cdb, uint8_t, pkt->pkt_cdbp[0],
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele uint_t, acmd->cmd_cdblen, ulong_t,
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele acmd->cmd_dmacount);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (pkt->pkt_cdbp[0] == SCMD_INQUIRY) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct scsi_inquiry *inq;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (acmd->cmd_dmacount != 0) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele bp_mapin(acmd->cmd_buf);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele inq = (struct scsi_inquiry *)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_buf->b_un.b_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* don't expose physical drives to OS */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (acmd->islogical &&
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (hdr->cmd_status == MFI_STAT_OK)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele display_scsi_inquiry(
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (caddr_t)inq);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else if ((hdr->cmd_status ==
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MFI_STAT_OK) && inq->inq_dtype ==
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DTYPE_DIRECT) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele display_scsi_inquiry(
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (caddr_t)inq);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* for physical disk */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele hdr->cmd_status =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MFI_STAT_DEVICE_NOT_FOUND;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele DTRACE_PROBE2(softintr_done, uint8_t, hdr->cmd,
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele uint8_t, hdr->cmd_status);
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch (hdr->cmd_status) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_STAT_OK:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_scbp[0] = STATUS_GOOD;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_STAT_LD_CC_IN_PROGRESS:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_STAT_LD_RECON_IN_PROGRESS:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_scbp[0] = STATUS_GOOD;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_STAT_LD_INIT_IN_PROGRESS:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (CE_WARN, "Initialization in Progress"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_reason = CMD_TRAN_ERR;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_STAT_SCSI_DONE_WITH_ERROR:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_CONT, "scsi_done error"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_reason = CMD_CMPLT;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((struct scsi_status *)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_scbp)->sts_chk = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (pkt->pkt_cdbp[0] == SCMD_TEST_UNIT_READY) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (CE_WARN, "TEST_UNIT_READY fail"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_state |= STATE_ARQ_DONE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele arqstat = (void *)(pkt->pkt_scbp);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele arqstat->sts_rqpkt_reason = CMD_CMPLT;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele arqstat->sts_rqpkt_resid = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele arqstat->sts_rqpkt_state |=
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele STATE_GOT_BUS | STATE_GOT_TARGET
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele | STATE_SENT_CMD
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele | STATE_XFERRED_DATA;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *(uint8_t *)&arqstat->sts_rqpkt_status =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele STATUS_GOOD;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_rep_get8(
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uint8_t *)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &(arqstat->sts_sensedata),
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->sense,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_scblen -
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele offsetof(struct scsi_arq_status,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sts_sensedata), DDI_DEV_AUTOINCR);
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_STAT_LD_OFFLINE:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_STAT_DEVICE_NOT_FOUND:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_CONT,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "device not found error"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_reason = CMD_DEV_GONE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_statistics = STAT_DISCON;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_STAT_LD_LBA_OUT_OF_RANGE:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_state |= STATE_ARQ_DONE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_reason = CMD_CMPLT;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((struct scsi_status *)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_scbp)->sts_chk = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele arqstat = (void *)(pkt->pkt_scbp);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele arqstat->sts_rqpkt_reason = CMD_CMPLT;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele arqstat->sts_rqpkt_resid = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele arqstat->sts_rqpkt_state |= STATE_GOT_BUS
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele | STATE_GOT_TARGET | STATE_SENT_CMD
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele | STATE_XFERRED_DATA;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *(uint8_t *)&arqstat->sts_rqpkt_status =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele STATUS_GOOD;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele arqstat->sts_sensedata.es_valid = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele arqstat->sts_sensedata.es_key =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele KEY_ILLEGAL_REQUEST;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele arqstat->sts_sensedata.es_class =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele CLASS_EXTENDED_SENSE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * LOGICAL BLOCK ADDRESS OUT OF RANGE:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * ASC: 0x21h; ASCQ: 0x00h;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele arqstat->sts_sensedata.es_add_code = 0x21;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele arqstat->sts_sensedata.es_qual_code = 0x00;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele default:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_CONT, "Unknown status!"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_reason = CMD_TRAN_ERR;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele atomic_add_16(&instance->fw_outstanding, (-1));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) mrsas_common_check(instance, cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (acmd->cmd_dmahandle) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_check_dma_handle(
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_dmahandle) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_service_impact(instance->dip,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_SERVICE_UNAFFECTED);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_reason = CMD_TRAN_ERR;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_statistics = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele return_mfi_pkt(instance, cmd);
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Call the callback routine */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (((pkt->pkt_flags & FLAG_NOINTR) == 0) &&
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_comp) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (*pkt->pkt_comp)(pkt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_CMD_OP_SMP:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_CMD_OP_STP:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele complete_cmd_in_sync_mode(instance, cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_CMD_OP_DCMD:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* see if got an event notification */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_get32(cmd->frame_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &cmd->frame->dcmd.opcode) ==
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MR_DCMD_CTRL_EVENT_WAIT) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((instance->aen_cmd == cmd) &&
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (instance->aen_cmd->abort_aen)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mrsas_softintr: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "aborted_aen returned"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele atomic_add_16(&instance->fw_outstanding,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (-1));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele service_mfi_aen(instance, cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele complete_cmd_in_sync_mode(instance, cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_CMD_OP_ABORT:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "MFI_CMD_OP_ABORT complete"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * MFI_CMD_OP_ABORT successfully completed
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * in the synchronous mode
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele complete_cmd_in_sync_mode(instance, cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele default:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (cmd->pkt != NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt = cmd->pkt;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (((pkt->pkt_flags & FLAG_NOINTR) == 0) &&
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_comp) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (*pkt->pkt_comp)(pkt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "Cmd type unknown !"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->softint_running = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_INTR_CLAIMED);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * mrsas_alloc_dma_obj
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Allocate the memory and other resources for an dma object.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_alloc_dma_obj(struct mrsas_instance *instance, dma_obj_t *obj,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uchar_t endian_flags)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele size_t alen = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint_t cookie_cnt;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct ddi_device_acc_attr tmp_endian_attr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tmp_endian_attr = endian_attr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tmp_endian_attr.devacc_attr_endian_flags = endian_flags;
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson tmp_endian_attr.devacc_attr_access = DDI_DEFAULT_ACC;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele i = ddi_dma_alloc_handle(instance->dip, &obj->dma_attr,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_DMA_SLEEP, NULL, &obj->dma_handle);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (i != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch (i) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case DDI_DMA_BADATTR :
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "Failed ddi_dma_alloc_handle- Bad attribute"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case DDI_DMA_NORESOURCES :
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "Failed ddi_dma_alloc_handle- No Resources"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele default :
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "Failed ddi_dma_alloc_handle: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "unknown status %d", i));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (-1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((ddi_dma_mem_alloc(obj->dma_handle, obj->size, &tmp_endian_attr,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &obj->buffer, &alen, &obj->acc_handle) != DDI_SUCCESS) ||
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele alen < obj->size) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_dma_free_handle(&obj->dma_handle);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "Failed : ddi_dma_mem_alloc"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (-1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_dma_addr_bind_handle(obj->dma_handle, NULL, obj->buffer,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele obj->size, DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_SLEEP,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele NULL, &obj->dma_cookie[0], &cookie_cnt) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_dma_mem_free(&obj->acc_handle);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_dma_free_handle(&obj->dma_handle);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "Failed : ddi_dma_addr_bind_handle"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (-1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_check_dma_handle(obj->dma_handle) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (-1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_check_acc_handle(obj->acc_handle) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (-1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (cookie_cnt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * mrsas_free_dma_obj(struct mrsas_instance *, dma_obj_t)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * De-allocate the memory and other resources for an dma object, which must
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * have been alloated by a previous call to mrsas_alloc_dma_obj()
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_free_dma_obj(struct mrsas_instance *instance, dma_obj_t obj)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_check_dma_handle(obj.dma_handle) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_check_acc_handle(obj.acc_handle) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_dma_unbind_handle(obj.dma_handle);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_dma_mem_free(&obj.acc_handle);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_dma_free_handle(&obj.dma_handle);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * mrsas_dma_alloc(instance_t *, struct scsi_pkt *, struct buf *,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * int, int (*)())
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Allocate dma resources for a new scsi command
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_dma_alloc(struct mrsas_instance *instance, struct scsi_pkt *pkt,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct buf *bp, int flags, int (*callback)())
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int dma_flags;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int (*cb)(caddr_t);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_dma_attr_t tmp_dma_attr = mrsas_generic_dma_attr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct scsa_cmd *acmd = PKT2CMD(pkt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_buf = bp;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (bp->b_flags & B_READ) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_flags &= ~CFLAG_DMASEND;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dma_flags = DDI_DMA_READ;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_flags |= CFLAG_DMASEND;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dma_flags = DDI_DMA_WRITE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (flags & PKT_CONSISTENT) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_flags |= CFLAG_CONSISTENT;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dma_flags |= DDI_DMA_CONSISTENT;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (flags & PKT_DMA_PARTIAL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dma_flags |= DDI_DMA_PARTIAL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dma_flags |= DDI_DMA_REDZONE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cb = (callback == NULL_FUNC) ? DDI_DMA_DONTWAIT : DDI_DMA_SLEEP;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tmp_dma_attr.dma_attr_sgllen = instance->max_num_sge;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tmp_dma_attr.dma_attr_addr_hi = 0xffffffffffffffffull;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((i = ddi_dma_alloc_handle(instance->dip, &tmp_dma_attr,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cb, 0, &acmd->cmd_dmahandle)) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch (i) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case DDI_DMA_BADATTR:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele bioerror(bp, EFAULT);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case DDI_DMA_NORESOURCES:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele bioerror(bp, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele default:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_PANIC, "ddi_dma_alloc_handle: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "impossible result (0x%x)", i));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele bioerror(bp, EFAULT);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele i = ddi_dma_buf_bind_handle(acmd->cmd_dmahandle, bp, dma_flags,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cb, 0, &acmd->cmd_dmacookies[0], &acmd->cmd_ncookies);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch (i) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case DDI_DMA_PARTIAL_MAP:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((dma_flags & DDI_DMA_PARTIAL) == 0) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_PANIC, "ddi_dma_buf_bind_handle: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "DDI_DMA_PARTIAL_MAP impossible"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto no_dma_cookies;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_dma_numwin(acmd->cmd_dmahandle, &acmd->cmd_nwin) ==
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_FAILURE) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_PANIC, "ddi_dma_numwin failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto no_dma_cookies;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_dma_getwin(acmd->cmd_dmahandle, acmd->cmd_curwin,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &acmd->cmd_dma_offset, &acmd->cmd_dma_len,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &acmd->cmd_dmacookies[0], &acmd->cmd_ncookies) ==
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_FAILURE) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_PANIC, "ddi_dma_getwin failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto no_dma_cookies;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto get_dma_cookies;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case DDI_DMA_MAPPED:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_nwin = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_dma_len = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_dma_offset = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleget_dma_cookies:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele i = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_dmacount = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (;;) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_dmacount +=
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_dmacookies[i++].dmac_size;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (i == instance->max_num_sge ||
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele i == acmd->cmd_ncookies)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_dma_nextcookie(acmd->cmd_dmahandle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &acmd->cmd_dmacookies[i]);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_cookie = i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_cookiecnt = i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_flags |= CFLAG_DMAVALID;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (bp->b_bcount >= acmd->cmd_dmacount) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_resid = bp->b_bcount - acmd->cmd_dmacount;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_resid = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case DDI_DMA_NORESOURCES:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele bioerror(bp, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case DDI_DMA_NOMAPPING:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele bioerror(bp, EFAULT);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case DDI_DMA_TOOBIG:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele bioerror(bp, EINVAL);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case DDI_DMA_INUSE:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_PANIC, "ddi_dma_buf_bind_handle:"
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele " DDI_DMA_INUSE impossible"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele default:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_PANIC, "ddi_dma_buf_bind_handle: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "impossible result (0x%x)", i));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleno_dma_cookies:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_dma_free_handle(&acmd->cmd_dmahandle);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_dmahandle = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_flags &= ~CFLAG_DMAVALID;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * mrsas_dma_move(struct mrsas_instance *, struct scsi_pkt *, struct buf *)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * move dma resources to next dma window
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_dma_move(struct mrsas_instance *instance, struct scsi_pkt *pkt,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct buf *bp)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int i = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct scsa_cmd *acmd = PKT2CMD(pkt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * If there are no more cookies remaining in this window,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * must move to the next window first.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (acmd->cmd_cookie == acmd->cmd_ncookies) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (acmd->cmd_curwin == acmd->cmd_nwin && acmd->cmd_nwin == 1) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* at last window, cannot move */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (++acmd->cmd_curwin >= acmd->cmd_nwin) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_dma_getwin(acmd->cmd_dmahandle, acmd->cmd_curwin,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &acmd->cmd_dma_offset, &acmd->cmd_dma_len,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &acmd->cmd_dmacookies[0], &acmd->cmd_ncookies) ==
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_FAILURE) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_cookie = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* still more cookies in this window - get the next one */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_dma_nextcookie(acmd->cmd_dmahandle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &acmd->cmd_dmacookies[0]);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* get remaining cookies in this window, up to our maximum */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (;;) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_dmacount += acmd->cmd_dmacookies[i++].dmac_size;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_cookie++;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (i == instance->max_num_sge ||
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_cookie == acmd->cmd_ncookies) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_dma_nextcookie(acmd->cmd_dmahandle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &acmd->cmd_dmacookies[i]);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_cookiecnt = i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (bp->b_bcount >= acmd->cmd_dmacount) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_resid = bp->b_bcount - acmd->cmd_dmacount;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pkt->pkt_resid = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * build_cmd
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic struct mrsas_cmd *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelebuild_cmd(struct mrsas_instance *instance, struct scsi_address *ap,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct scsi_pkt *pkt, uchar_t *cmd_done)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint16_t flags = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t context;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t sge_bytes;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_acc_handle_t acc_handle;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_sge64 *mfi_sgl;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct scsa_cmd *acmd = PKT2CMD(pkt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_pthru_frame *pthru;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_io_frame *ldio;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* find out if this is logical or physical drive command. */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->islogical = MRDRV_IS_LOGICAL(ap);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->device_id = MAP_DEVICE_ID(instance, ap);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *cmd_done = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* get the command packet */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (!(cmd = get_mfi_pkt(instance))) {
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele DTRACE_PROBE2(build_cmd_mfi_err, uint16_t,
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele instance->fw_outstanding, uint16_t, instance->max_fw_cmds);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (NULL);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acc_handle = cmd->frame_dma_obj.acc_handle;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Clear the frame buffer and assign back the context id */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &cmd->frame->hdr.context, cmd->index);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->pkt = pkt;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->cmd = acmd;
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele DTRACE_PROBE3(build_cmds, uint8_t, pkt->pkt_cdbp[0],
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele ulong_t, acmd->cmd_dmacount, ulong_t, acmd->cmd_dma_len);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* lets get the command directions */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (acmd->cmd_flags & CFLAG_DMASEND) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele flags = MFI_FRAME_DIR_WRITE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (acmd->cmd_flags & CFLAG_CONSISTENT) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_dma_sync(acmd->cmd_dmahandle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_dma_offset, acmd->cmd_dma_len,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_DMA_SYNC_FORDEV);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else if (acmd->cmd_flags & ~CFLAG_DMASEND) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele flags = MFI_FRAME_DIR_READ;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (acmd->cmd_flags & CFLAG_CONSISTENT) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_dma_sync(acmd->cmd_dmahandle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_dma_offset, acmd->cmd_dma_len,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_DMA_SYNC_FORCPU);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele flags = MFI_FRAME_DIR_NONE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele flags |= MFI_FRAME_SGL64;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch (pkt->pkt_cdbp[0]) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * case SCMD_SYNCHRONIZE_CACHE:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * flush_cache(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * return_mfi_pkt(instance, cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * *cmd_done = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * return (NULL);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCMD_READ:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCMD_WRITE:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCMD_READ_G1:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCMD_WRITE_G1:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (acmd->islogical) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ldio = (struct mrsas_io_frame *)cmd->frame;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * preare the Logical IO frame:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * 2nd bit is zero for all read cmds
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &ldio->cmd,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (pkt->pkt_cdbp[0] & 0x02) ? MFI_CMD_OP_LD_WRITE
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele : MFI_CMD_OP_LD_READ);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &ldio->cmd_status, 0x0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &ldio->scsi_status, 0x0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &ldio->target_id, acmd->device_id);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(acc_handle, &ldio->timeout, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &ldio->reserved_0, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(acc_handle, &ldio->pad_0, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(acc_handle, &ldio->flags, flags);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Initialize sense Information */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele bzero(cmd->sense, SENSE_LENGTH);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &ldio->sense_len, SENSE_LENGTH);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &ldio->sense_buf_phys_addr_hi, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &ldio->sense_buf_phys_addr_lo,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->sense_phys_addr);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &ldio->start_lba_hi, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &ldio->access_byte,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (acmd->cmd_cdblen != 6) ? pkt->pkt_cdbp[1] : 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &ldio->sge_count,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_cookiecnt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mfi_sgl = (struct mrsas_sge64 *)&ldio->sgl;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele context = ddi_get32(acc_handle, &ldio->context);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (acmd->cmd_cdblen == CDB_GROUP0) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &ldio->lba_count, (
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uint16_t)(pkt->pkt_cdbp[4])));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &ldio->start_lba_lo, (
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint32_t)(pkt->pkt_cdbp[3])) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint32_t)(pkt->pkt_cdbp[2]) << 8) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint32_t)((pkt->pkt_cdbp[1]) & 0x1F)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele << 16)));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else if (acmd->cmd_cdblen == CDB_GROUP1) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &ldio->lba_count, (
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint16_t)(pkt->pkt_cdbp[8])) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint16_t)(pkt->pkt_cdbp[7]) << 8)));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &ldio->start_lba_lo, (
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint32_t)(pkt->pkt_cdbp[5])) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint32_t)(pkt->pkt_cdbp[4]) << 8) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint32_t)(pkt->pkt_cdbp[3]) << 16) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint32_t)(pkt->pkt_cdbp[2]) << 24)));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else if (acmd->cmd_cdblen == CDB_GROUP2) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &ldio->lba_count, (
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint16_t)(pkt->pkt_cdbp[9])) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint16_t)(pkt->pkt_cdbp[8]) << 8) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint16_t)(pkt->pkt_cdbp[7]) << 16) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint16_t)(pkt->pkt_cdbp[6]) << 24)));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &ldio->start_lba_lo, (
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint32_t)(pkt->pkt_cdbp[5])) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint32_t)(pkt->pkt_cdbp[4]) << 8) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint32_t)(pkt->pkt_cdbp[3]) << 16) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint32_t)(pkt->pkt_cdbp[2]) << 24)));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else if (acmd->cmd_cdblen == CDB_GROUP3) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &ldio->lba_count, (
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint16_t)(pkt->pkt_cdbp[13])) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint16_t)(pkt->pkt_cdbp[12]) << 8) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint16_t)(pkt->pkt_cdbp[11]) << 16) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint16_t)(pkt->pkt_cdbp[10]) << 24)));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &ldio->start_lba_lo, (
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint32_t)(pkt->pkt_cdbp[9])) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint32_t)(pkt->pkt_cdbp[8]) << 8) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint32_t)(pkt->pkt_cdbp[7]) << 16) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint32_t)(pkt->pkt_cdbp[6]) << 24)));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &ldio->start_lba_lo, (
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint32_t)(pkt->pkt_cdbp[5])) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint32_t)(pkt->pkt_cdbp[4]) << 8) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint32_t)(pkt->pkt_cdbp[3]) << 16) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((uint32_t)(pkt->pkt_cdbp[2]) << 24)));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* fall through For all non-rd/wr cmds */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele default:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch (pkt->pkt_cdbp[0]) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCMD_MODE_SENSE:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case SCMD_MODE_SENSE_G1: {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele union scsi_cdb *cdbp;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint16_t page_code;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cdbp = (void *)pkt->pkt_cdbp;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele page_code = (uint16_t)cdbp->cdb_un.sg.scsi[0];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch (page_code) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case 0x3:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case 0x4:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) mrsas_mode_sense_build(pkt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return_mfi_pkt(instance, cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *cmd_done = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (NULL);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele default:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pthru = (struct mrsas_pthru_frame *)cmd->frame;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* prepare the DCDB frame */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &pthru->cmd, (acmd->islogical) ?
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MFI_CMD_OP_LD_SCSI : MFI_CMD_OP_PD_SCSI);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &pthru->cmd_status, 0x0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &pthru->scsi_status, 0x0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &pthru->target_id, acmd->device_id);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &pthru->lun, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &pthru->cdb_len, acmd->cmd_cdblen);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(acc_handle, &pthru->timeout, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(acc_handle, &pthru->flags, flags);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &pthru->data_xfer_len,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_dmacount);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &pthru->sge_count, acmd->cmd_cookiecnt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mfi_sgl = (struct mrsas_sge64 *)&pthru->sgl;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele bzero(cmd->sense, SENSE_LENGTH);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &pthru->sense_len, SENSE_LENGTH);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &pthru->sense_buf_phys_addr_hi, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &pthru->sense_buf_phys_addr_lo,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->sense_phys_addr);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele context = ddi_get32(acc_handle, &pthru->context);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_rep_put8(acc_handle, (uint8_t *)pkt->pkt_cdbp,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uint8_t *)pthru->cdb, acmd->cmd_cdblen, DDI_DEV_AUTOINCR);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#ifdef lint
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele context = context;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#endif
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* prepare the scatter-gather list for the firmware */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < acmd->cmd_cookiecnt; i++, mfi_sgl++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put64(acc_handle, &mfi_sgl->phys_addr,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_dmacookies[i].dmac_laddress);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &mfi_sgl->length,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd->cmd_dmacookies[i].dmac_size);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sge_bytes = sizeof (struct mrsas_sge64)*acmd->cmd_cookiecnt;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_count = (sge_bytes / MRMFI_FRAME_SIZE) +
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ((sge_bytes % MRMFI_FRAME_SIZE) ? 1 : 0) + 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (cmd->frame_count >= 8) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_count = 8;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * issue_mfi_pthru
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleissue_mfi_pthru(struct mrsas_instance *instance, struct mrsas_ioctl *ioctl,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd, int mode)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele void *ubuf;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t kphys_addr = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t xferlen = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint_t model;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_acc_handle_t acc_handle = cmd->frame_dma_obj.acc_handle;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dma_obj_t pthru_dma_obj;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_pthru_frame *kpthru;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_pthru_frame *pthru;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pthru = &cmd->frame->pthru;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kpthru = (struct mrsas_pthru_frame *)&ioctl->frame[0];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele model = ddi_model_convert_from(mode & FMODELS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (model == DDI_MODEL_ILP32) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "issue_mfi_pthru: DDI_MODEL_LP32"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele xferlen = kpthru->sgl.sge32[0].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ubuf = (void *)(ulong_t)kpthru->sgl.sge32[0].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#ifdef _ILP32
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "issue_mfi_pthru: DDI_MODEL_LP32"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele xferlen = kpthru->sgl.sge32[0].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ubuf = (void *)(ulong_t)kpthru->sgl.sge32[0].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#else
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "issue_mfi_pthru: DDI_MODEL_LP64"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele xferlen = kpthru->sgl.sge64[0].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ubuf = (void *)(ulong_t)kpthru->sgl.sge64[0].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#endif
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (xferlen) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* means IOCTL requires DMA */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* allocate the data transfer buffer */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pthru_dma_obj.size = xferlen;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pthru_dma_obj.dma_attr = mrsas_generic_dma_attr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pthru_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pthru_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pthru_dma_obj.dma_attr.dma_attr_sgllen = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pthru_dma_obj.dma_attr.dma_attr_align = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* allocate kernel buffer for DMA */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_alloc_dma_obj(instance, &pthru_dma_obj,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "issue_mfi_pthru: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "could not allocate data transfer buffer."));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China (void) memset(pthru_dma_obj.buffer, 0, xferlen);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (kpthru->flags & MFI_FRAME_DIR_WRITE) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < xferlen; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_copyin((uint8_t *)ubuf+i,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uint8_t *)pthru_dma_obj.buffer+i,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 1, mode)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "issue_mfi_pthru : "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "copy from user space failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kphys_addr = pthru_dma_obj.dma_cookie[0].dmac_address;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &pthru->cmd, kpthru->cmd);
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China ddi_put8(acc_handle, &pthru->sense_len, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &pthru->cmd_status, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &pthru->scsi_status, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &pthru->target_id, kpthru->target_id);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &pthru->lun, kpthru->lun);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &pthru->cdb_len, kpthru->cdb_len);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &pthru->sge_count, kpthru->sge_count);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(acc_handle, &pthru->timeout, kpthru->timeout);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &pthru->data_xfer_len, kpthru->data_xfer_len);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &pthru->sense_buf_phys_addr_hi, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr; */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &pthru->sense_buf_phys_addr_lo, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_rep_put8(acc_handle, (uint8_t *)kpthru->cdb, (uint8_t *)pthru->cdb,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pthru->cdb_len, DDI_DEV_AUTOINCR);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(acc_handle, &pthru->flags, kpthru->flags & ~MFI_FRAME_SGL64);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &pthru->sgl.sge32[0].length, xferlen);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &pthru->sgl.sge32[0].phys_addr, kphys_addr);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->sync_cmd = MRSAS_TRUE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_count = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "issue_mfi_pthru: fw_ioctl failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (xferlen && kpthru->flags & MFI_FRAME_DIR_READ) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < xferlen; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_copyout(
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uint8_t *)pthru_dma_obj.buffer+i,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uint8_t *)ubuf+i, 1, mode)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "issue_mfi_pthru : "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "copy to user space failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kpthru->cmd_status = ddi_get8(acc_handle, &pthru->cmd_status);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kpthru->scsi_status = ddi_get8(acc_handle, &pthru->scsi_status);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE, "issue_mfi_pthru: cmd_status %x, "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "scsi_status %x", kpthru->cmd_status, kpthru->scsi_status));
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele DTRACE_PROBE3(issue_pthru, uint8_t, kpthru->cmd, uint8_t,
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele kpthru->cmd_status, uint8_t, kpthru->scsi_status);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (xferlen) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* free kernel buffer */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_free_dma_obj(instance, pthru_dma_obj) != DDI_SUCCESS)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * issue_mfi_dcmd
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleissue_mfi_dcmd(struct mrsas_instance *instance, struct mrsas_ioctl *ioctl,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd, int mode)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele void *ubuf;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t kphys_addr = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t xferlen = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t model;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dma_obj_t dcmd_dma_obj;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_dcmd_frame *kdcmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_dcmd_frame *dcmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_acc_handle_t acc_handle = cmd->frame_dma_obj.acc_handle;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dcmd = &cmd->frame->dcmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kdcmd = (struct mrsas_dcmd_frame *)&ioctl->frame[0];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele model = ddi_model_convert_from(mode & FMODELS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (model == DDI_MODEL_ILP32) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "issue_mfi_dcmd: DDI_MODEL_ILP32"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele xferlen = kdcmd->sgl.sge32[0].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#ifdef _ILP32
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "issue_mfi_dcmd: DDI_MODEL_ILP32"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele xferlen = kdcmd->sgl.sge32[0].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#else
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "issue_mfi_dcmd: DDI_MODEL_LP64"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele xferlen = kdcmd->sgl.sge64[0].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ubuf = (void *)(ulong_t)kdcmd->sgl.sge64[0].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#endif
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (xferlen) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* means IOCTL requires DMA */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* allocate the data transfer buffer */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dcmd_dma_obj.size = xferlen;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dcmd_dma_obj.dma_attr = mrsas_generic_dma_attr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dcmd_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dcmd_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dcmd_dma_obj.dma_attr.dma_attr_sgllen = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dcmd_dma_obj.dma_attr.dma_attr_align = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* allocate kernel buffer for DMA */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_alloc_dma_obj(instance, &dcmd_dma_obj,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "issue_mfi_dcmd: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "could not allocate data transfer buffer."));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China (void) memset(dcmd_dma_obj.buffer, 0, xferlen);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (kdcmd->flags & MFI_FRAME_DIR_WRITE) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < xferlen; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_copyin((uint8_t *)ubuf + i,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uint8_t *)dcmd_dma_obj.buffer + i,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 1, mode)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "issue_mfi_dcmd : "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "copy from user space failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kphys_addr = dcmd_dma_obj.dma_cookie[0].dmac_address;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &dcmd->cmd, kdcmd->cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &dcmd->cmd_status, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &dcmd->sge_count, kdcmd->sge_count);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(acc_handle, &dcmd->timeout, kdcmd->timeout);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &dcmd->data_xfer_len, kdcmd->data_xfer_len);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &dcmd->opcode, kdcmd->opcode);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_rep_put8(acc_handle, (uint8_t *)kdcmd->mbox.b,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uint8_t *)dcmd->mbox.b, DCMD_MBOX_SZ, DDI_DEV_AUTOINCR);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(acc_handle, &dcmd->flags, kdcmd->flags & ~MFI_FRAME_SGL64);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &dcmd->sgl.sge32[0].length, xferlen);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &dcmd->sgl.sge32[0].phys_addr, kphys_addr);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->sync_cmd = MRSAS_TRUE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_count = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "issue_mfi_dcmd: fw_ioctl failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (xferlen && (kdcmd->flags & MFI_FRAME_DIR_READ)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < xferlen; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_copyout(
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uint8_t *)dcmd_dma_obj.buffer + i,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uint8_t *)ubuf + i,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 1, mode)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "issue_mfi_dcmd : "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "copy to user space failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kdcmd->cmd_status = ddi_get8(acc_handle, &dcmd->cmd_status);
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele DTRACE_PROBE3(issue_dcmd, uint32_t, kdcmd->opcode, uint8_t,
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele kdcmd->cmd, uint8_t, kdcmd->cmd_status);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (xferlen) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* free kernel buffer */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_free_dma_obj(instance, dcmd_dma_obj) != DDI_SUCCESS)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * issue_mfi_smp
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleissue_mfi_smp(struct mrsas_instance *instance, struct mrsas_ioctl *ioctl,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd, int mode)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele void *request_ubuf;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele void *response_ubuf;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t request_xferlen = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t response_xferlen = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint_t model;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dma_obj_t request_dma_obj;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dma_obj_t response_dma_obj;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_acc_handle_t acc_handle = cmd->frame_dma_obj.acc_handle;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_smp_frame *ksmp;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_smp_frame *smp;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_sge32 *sge32;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#ifndef _ILP32
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_sge64 *sge64;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#endif
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint64_t tmp_sas_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele smp = &cmd->frame->smp;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ksmp = (struct mrsas_smp_frame *)&ioctl->frame[0];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele model = ddi_model_convert_from(mode & FMODELS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (model == DDI_MODEL_ILP32) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: DDI_MODEL_ILP32"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sge32 = &ksmp->sgl[0].sge32[0];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele response_xferlen = sge32[0].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele request_xferlen = sge32[1].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE, "issue_mfi_smp: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "response_xferlen = %x, request_xferlen = %x",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele response_xferlen, request_xferlen));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele response_ubuf = (void *)(ulong_t)sge32[0].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele request_ubuf = (void *)(ulong_t)sge32[1].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "response_ubuf = %p, request_ubuf = %p",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele response_ubuf, request_ubuf));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#ifdef _ILP32
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: DDI_MODEL_ILP32"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sge32 = &ksmp->sgl[0].sge32[0];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele response_xferlen = sge32[0].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele request_xferlen = sge32[1].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE, "issue_mfi_smp: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "response_xferlen = %x, request_xferlen = %x",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele response_xferlen, request_xferlen));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele response_ubuf = (void *)(ulong_t)sge32[0].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele request_ubuf = (void *)(ulong_t)sge32[1].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "response_ubuf = %p, request_ubuf = %p",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele response_ubuf, request_ubuf));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#else
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: DDI_MODEL_LP64"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sge64 = &ksmp->sgl[0].sge64[0];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele response_xferlen = sge64[0].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele request_xferlen = sge64[1].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele response_ubuf = (void *)(ulong_t)sge64[0].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele request_ubuf = (void *)(ulong_t)sge64[1].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#endif
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (request_xferlen) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* means IOCTL requires DMA */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* allocate the data transfer buffer */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele request_dma_obj.size = request_xferlen;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele request_dma_obj.dma_attr = mrsas_generic_dma_attr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele request_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele request_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele request_dma_obj.dma_attr.dma_attr_sgllen = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele request_dma_obj.dma_attr.dma_attr_align = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* allocate kernel buffer for DMA */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_alloc_dma_obj(instance, &request_dma_obj,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "issue_mfi_smp: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "could not allocate data transfer buffer."));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China (void) memset(request_dma_obj.buffer, 0, request_xferlen);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < request_xferlen; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_copyin((uint8_t *)request_ubuf + i,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uint8_t *)request_dma_obj.buffer + i,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 1, mode)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "issue_mfi_smp: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "copy from user space failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (response_xferlen) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* means IOCTL requires DMA */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* allocate the data transfer buffer */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele response_dma_obj.size = response_xferlen;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele response_dma_obj.dma_attr = mrsas_generic_dma_attr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele response_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele response_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele response_dma_obj.dma_attr.dma_attr_sgllen = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele response_dma_obj.dma_attr.dma_attr_align = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* allocate kernel buffer for DMA */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_alloc_dma_obj(instance, &response_dma_obj,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "issue_mfi_smp: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "could not allocate data transfer buffer."));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China (void) memset(response_dma_obj.buffer, 0, response_xferlen);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < response_xferlen; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_copyin((uint8_t *)response_ubuf + i,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uint8_t *)response_dma_obj.buffer + i,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 1, mode)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "issue_mfi_smp: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "copy from user space failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &smp->cmd, ksmp->cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &smp->cmd_status, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &smp->connection_status, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &smp->sge_count, ksmp->sge_count);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* smp->context = ksmp->context; */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(acc_handle, &smp->timeout, ksmp->timeout);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &smp->data_xfer_len, ksmp->data_xfer_len);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele bcopy((void *)&ksmp->sas_addr, (void *)&tmp_sas_addr,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (uint64_t));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put64(acc_handle, &smp->sas_addr, tmp_sas_addr);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(acc_handle, &smp->flags, ksmp->flags & ~MFI_FRAME_SGL64);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele model = ddi_model_convert_from(mode & FMODELS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (model == DDI_MODEL_ILP32) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE,
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China "issue_mfi_smp: DDI_MODEL_ILP32"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sge32 = &smp->sgl[0].sge32[0];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &sge32[0].length, response_xferlen);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &sge32[0].phys_addr,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele response_dma_obj.dma_cookie[0].dmac_address);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &sge32[1].length, request_xferlen);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &sge32[1].phys_addr,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele request_dma_obj.dma_cookie[0].dmac_address);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#ifdef _ILP32
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE,
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China "issue_mfi_smp: DDI_MODEL_ILP32"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sge32 = &smp->sgl[0].sge32[0];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &sge32[0].length, response_xferlen);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &sge32[0].phys_addr,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele response_dma_obj.dma_cookie[0].dmac_address);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &sge32[1].length, request_xferlen);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &sge32[1].phys_addr,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele request_dma_obj.dma_cookie[0].dmac_address);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#else
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "issue_mfi_smp: DDI_MODEL_LP64"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sge64 = &smp->sgl[0].sge64[0];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &sge64[0].length, response_xferlen);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put64(acc_handle, &sge64[0].phys_addr,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele response_dma_obj.dma_cookie[0].dmac_address);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &sge64[1].length, request_xferlen);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put64(acc_handle, &sge64[1].phys_addr,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele request_dma_obj.dma_cookie[0].dmac_address);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#endif
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp : "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "smp->response_xferlen = %d, smp->request_xferlen = %d "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "smp->data_xfer_len = %d", ddi_get32(acc_handle, &sge32[0].length),
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_get32(acc_handle, &sge32[1].length),
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_get32(acc_handle, &smp->data_xfer_len)));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->sync_cmd = MRSAS_TRUE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_count = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "issue_mfi_smp: fw_ioctl failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "issue_mfi_smp: copy to user space"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (request_xferlen) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < request_xferlen; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_copyout(
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uint8_t *)request_dma_obj.buffer +
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele i, (uint8_t *)request_ubuf + i,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 1, mode)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "issue_mfi_smp : copy to user space"
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele " failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (response_xferlen) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < response_xferlen; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_copyout(
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uint8_t *)response_dma_obj.buffer
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele + i, (uint8_t *)response_ubuf
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele + i, 1, mode)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "issue_mfi_smp : copy to "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "user space failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ksmp->cmd_status = ddi_get8(acc_handle, &smp->cmd_status);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: smp->cmd_status = %d",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_get8(acc_handle, &smp->cmd_status)));
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele DTRACE_PROBE2(issue_smp, uint8_t, ksmp->cmd, uint8_t, ksmp->cmd_status);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (request_xferlen) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* free kernel buffer */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_free_dma_obj(instance, request_dma_obj) !=
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_SUCCESS)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (response_xferlen) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* free kernel buffer */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_free_dma_obj(instance, response_dma_obj) !=
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_SUCCESS)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * issue_mfi_stp
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleissue_mfi_stp(struct mrsas_instance *instance, struct mrsas_ioctl *ioctl,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd, int mode)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele void *fis_ubuf;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele void *data_ubuf;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t fis_xferlen = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t data_xferlen = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint_t model;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dma_obj_t fis_dma_obj;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dma_obj_t data_dma_obj;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_stp_frame *kstp;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_stp_frame *stp;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_acc_handle_t acc_handle = cmd->frame_dma_obj.acc_handle;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele stp = &cmd->frame->stp;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kstp = (struct mrsas_stp_frame *)&ioctl->frame[0];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele model = ddi_model_convert_from(mode & FMODELS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (model == DDI_MODEL_ILP32) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "issue_mfi_stp: DDI_MODEL_ILP32"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele fis_xferlen = kstp->sgl.sge32[0].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele data_xferlen = kstp->sgl.sge32[1].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele fis_ubuf = (void *)(ulong_t)kstp->sgl.sge32[0].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele data_ubuf = (void *)(ulong_t)kstp->sgl.sge32[1].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele else
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#ifdef _ILP32
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "issue_mfi_stp: DDI_MODEL_ILP32"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele fis_xferlen = kstp->sgl.sge32[0].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele data_xferlen = kstp->sgl.sge32[1].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele fis_ubuf = (void *)(ulong_t)kstp->sgl.sge32[0].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele data_ubuf = (void *)(ulong_t)kstp->sgl.sge32[1].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#else
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "issue_mfi_stp: DDI_MODEL_LP64"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele fis_xferlen = kstp->sgl.sge64[0].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele data_xferlen = kstp->sgl.sge64[1].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele fis_ubuf = (void *)(ulong_t)kstp->sgl.sge64[0].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele data_ubuf = (void *)(ulong_t)kstp->sgl.sge64[1].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#endif
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (fis_xferlen) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE, "issue_mfi_stp: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "fis_ubuf = %p fis_xferlen = %x", fis_ubuf, fis_xferlen));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* means IOCTL requires DMA */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* allocate the data transfer buffer */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele fis_dma_obj.size = fis_xferlen;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele fis_dma_obj.dma_attr = mrsas_generic_dma_attr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele fis_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele fis_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele fis_dma_obj.dma_attr.dma_attr_sgllen = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele fis_dma_obj.dma_attr.dma_attr_align = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* allocate kernel buffer for DMA */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_alloc_dma_obj(instance, &fis_dma_obj,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "issue_mfi_stp : "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "could not allocate data transfer buffer."));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China (void) memset(fis_dma_obj.buffer, 0, fis_xferlen);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < fis_xferlen; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_copyin((uint8_t *)fis_ubuf + i,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uint8_t *)fis_dma_obj.buffer + i, 1, mode)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "copy from user space failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (data_xferlen) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE, "issue_mfi_stp: data_ubuf = %p "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "data_xferlen = %x", data_ubuf, data_xferlen));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* means IOCTL requires DMA */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* allocate the data transfer buffer */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele data_dma_obj.size = data_xferlen;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele data_dma_obj.dma_attr = mrsas_generic_dma_attr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele data_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele data_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele data_dma_obj.dma_attr.dma_attr_sgllen = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele data_dma_obj.dma_attr.dma_attr_align = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/* allocate kernel buffer for DMA */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_alloc_dma_obj(instance, &data_dma_obj,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "could not allocate data transfer buffer."));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China (void) memset(data_dma_obj.buffer, 0, data_xferlen);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < data_xferlen; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_copyin((uint8_t *)data_ubuf + i,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uint8_t *)data_dma_obj.buffer + i, 1, mode)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "copy from user space failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &stp->cmd, kstp->cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &stp->cmd_status, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &stp->connection_status, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &stp->target_id, kstp->target_id);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(acc_handle, &stp->sge_count, kstp->sge_count);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(acc_handle, &stp->timeout, kstp->timeout);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &stp->data_xfer_len, kstp->data_xfer_len);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_rep_put8(acc_handle, (uint8_t *)kstp->fis, (uint8_t *)stp->fis, 10,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_DEV_AUTOINCR);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(acc_handle, &stp->flags, kstp->flags & ~MFI_FRAME_SGL64);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &stp->stp_flags, kstp->stp_flags);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &stp->sgl.sge32[0].length, fis_xferlen);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &stp->sgl.sge32[0].phys_addr,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele fis_dma_obj.dma_cookie[0].dmac_address);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &stp->sgl.sge32[1].length, data_xferlen);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(acc_handle, &stp->sgl.sge32[1].phys_addr,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele data_dma_obj.dma_cookie[0].dmac_address);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->sync_cmd = MRSAS_TRUE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_count = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: fw_ioctl failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (fis_xferlen) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < fis_xferlen; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_copyout(
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uint8_t *)fis_dma_obj.buffer + i,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uint8_t *)fis_ubuf + i, 1, mode)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "issue_mfi_stp : copy to "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "user space failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (data_xferlen) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < data_xferlen; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_copyout(
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uint8_t *)data_dma_obj.buffer + i,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uint8_t *)data_ubuf + i, 1, mode)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "issue_mfi_stp : copy to"
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele " user space failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kstp->cmd_status = ddi_get8(acc_handle, &stp->cmd_status);
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele DTRACE_PROBE2(issue_stp, uint8_t, kstp->cmd, uint8_t, kstp->cmd_status);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (fis_xferlen) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* free kernel buffer */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_free_dma_obj(instance, fis_dma_obj) != DDI_SUCCESS)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (data_xferlen) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* free kernel buffer */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_free_dma_obj(instance, data_dma_obj) != DDI_SUCCESS)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * fill_up_drv_ver
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelefill_up_drv_ver(struct mrsas_drv_ver *dv)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memset(dv, 0, sizeof (struct mrsas_drv_ver));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memcpy(dv->signature, "$LSI LOGIC$", strlen("$LSI LOGIC$"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memcpy(dv->os_name, "Solaris", strlen("Solaris"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memcpy(dv->drv_name, "mr_sas", strlen("mr_sas"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memcpy(dv->drv_ver, MRSAS_VERSION, strlen(MRSAS_VERSION));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memcpy(dv->drv_rel_date, MRSAS_RELDATE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele strlen(MRSAS_RELDATE));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * handle_drv_ioctl
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelehandle_drv_ioctl(struct mrsas_instance *instance, struct mrsas_ioctl *ioctl,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int mode)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int rval = DDI_SUCCESS;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int *props = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele void *ubuf;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint8_t *pci_conf_buf;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t xferlen;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t num_props;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint_t model;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_dcmd_frame *kdcmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_drv_ver dv;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_pci_information pi;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kdcmd = (struct mrsas_dcmd_frame *)&ioctl->frame[0];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele model = ddi_model_convert_from(mode & FMODELS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (model == DDI_MODEL_ILP32) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "handle_drv_ioctl: DDI_MODEL_ILP32"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele xferlen = kdcmd->sgl.sge32[0].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#ifdef _ILP32
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "handle_drv_ioctl: DDI_MODEL_ILP32"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele xferlen = kdcmd->sgl.sge32[0].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#else
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "handle_drv_ioctl: DDI_MODEL_LP64"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele xferlen = kdcmd->sgl.sge64[0].length;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ubuf = (void *)(ulong_t)kdcmd->sgl.sge64[0].phys_addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#endif
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "handle_drv_ioctl: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "dataBuf=%p size=%d bytes", ubuf, xferlen));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch (kdcmd->opcode) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MRSAS_DRIVER_IOCTL_DRIVER_VERSION:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "handle_drv_ioctl: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "MRSAS_DRIVER_IOCTL_DRIVER_VERSION"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele fill_up_drv_ver(&dv);
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China if (ddi_copyout(&dv, ubuf, xferlen, mode)) {
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China con_log(CL_ANN, (CE_WARN, "handle_drv_ioctl: "
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China "MRSAS_DRIVER_IOCTL_DRIVER_VERSION : "
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China "copy to user space failed"));
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China kdcmd->cmd_status = 1;
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China rval = 1;
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kdcmd->cmd_status = 0;
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MRSAS_DRIVER_IOCTL_PCI_INFORMATION:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "handle_drv_ioctl: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "MRSAS_DRIVER_IOCTL_PCI_INFORMAITON"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, instance->dip,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 0, "reg", &props, &num_props)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "handle_drv_ioctl: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "MRSAS_DRIVER_IOCTL_PCI_INFORMATION : "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "ddi_prop_look_int_array failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = DDI_FAILURE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pi.busNumber = (props[0] >> 16) & 0xFF;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pi.deviceNumber = (props[0] >> 11) & 0x1f;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pi.functionNumber = (props[0] >> 8) & 0x7;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_prop_free((void *)props);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pci_conf_buf = (uint8_t *)&pi.pciHeaderInfo;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < (sizeof (struct mrsas_pci_information) -
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele offsetof(struct mrsas_pci_information, pciHeaderInfo));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pci_conf_buf[i] =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pci_config_get8(instance->pci_handle, i);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China if (ddi_copyout(&pi, ubuf, xferlen, mode)) {
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China con_log(CL_ANN, (CE_WARN, "handle_drv_ioctl: "
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China "MRSAS_DRIVER_IOCTL_PCI_INFORMATION : "
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China "copy to user space failed"));
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China kdcmd->cmd_status = 1;
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China rval = 1;
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kdcmd->cmd_status = 0;
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele default:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "handle_drv_ioctl: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "invalid driver specific IOCTL opcode = 0x%x",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kdcmd->opcode));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kdcmd->cmd_status = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = DDI_FAILURE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (rval);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * handle_mfi_ioctl
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelehandle_mfi_ioctl(struct mrsas_instance *instance, struct mrsas_ioctl *ioctl,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int mode)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int rval = DDI_SUCCESS;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_header *hdr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd = get_mfi_pkt(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (!cmd) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "mr_sas: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "failed to get a cmd packet"));
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele DTRACE_PROBE2(mfi_ioctl_err, uint16_t,
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele instance->fw_outstanding, uint16_t, instance->max_fw_cmds);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Clear the frame buffer and assign back the context id */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->index);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele hdr = (struct mrsas_header *)&ioctl->frame[0];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China switch (ddi_get8(cmd->frame_dma_obj.acc_handle, &hdr->cmd)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_CMD_OP_DCMD:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = issue_mfi_dcmd(instance, ioctl, cmd, mode);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_CMD_OP_SMP:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = issue_mfi_smp(instance, ioctl, cmd, mode);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_CMD_OP_STP:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = issue_mfi_stp(instance, ioctl, cmd, mode);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_CMD_OP_LD_SCSI:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MFI_CMD_OP_PD_SCSI:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = issue_mfi_pthru(instance, ioctl, cmd, mode);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele default:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "handle_mfi_ioctl: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "invalid mfi ioctl hdr->cmd = %d", hdr->cmd));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = DDI_FAILURE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_common_check(instance, cmd) != DDI_SUCCESS)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = DDI_FAILURE;
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China return_mfi_pkt(instance, cmd);
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (rval);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * AEN
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelehandle_mfi_aen(struct mrsas_instance *instance, struct mrsas_aen *aen)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int rval = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = register_mfi_aen(instance, instance->aen_seq_num,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele aen->class_locale_word);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele aen->cmd_status = (uint8_t)rval;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (rval);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleregister_mfi_aen(struct mrsas_instance *instance, uint32_t seq_num,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t class_locale_word)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int ret_val;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd, *aen_cmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_dcmd_frame *dcmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele union mrsas_evt_class_locale curr_aen;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele union mrsas_evt_class_locale prev_aen;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * If there an AEN pending already (aen_cmd), check if the
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * class_locale of that pending AEN is inclusive of the new
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * AEN request we currently have. If it is, then we don't have
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * to do anything. In other words, whichever events the current
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * AEN request is subscribing to, have already been subscribed
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * to.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * If the old_cmd is _not_ inclusive, then we have to abort
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * that command, form a class_locale that is superset of both
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * old and current and re-issue to the FW
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China curr_aen.word = LE_32(class_locale_word);
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China curr_aen.members.locale = LE_16(curr_aen.members.locale);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele aen_cmd = instance->aen_cmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (aen_cmd) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele prev_aen.word = ddi_get32(aen_cmd->frame_dma_obj.acc_handle,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &aen_cmd->frame->dcmd.mbox.w[1]);
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China prev_aen.word = LE_32(prev_aen.word);
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China prev_aen.members.locale = LE_16(prev_aen.members.locale);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * A class whose enum value is smaller is inclusive of all
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * higher values. If a PROGRESS (= -1) was previously
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * registered, then a new registration requests for higher
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * classes need not be sent to FW. They are automatically
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * included.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Locale numbers don't have such hierarchy. They are bitmap
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * values
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((prev_aen.members.class <= curr_aen.members.class) &&
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele !((prev_aen.members.locale & curr_aen.members.locale) ^
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele curr_aen.members.locale)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Previously issued event registration includes
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * current request. Nothing to do.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele curr_aen.members.locale |= prev_aen.members.locale;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (prev_aen.members.class < curr_aen.members.class)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele curr_aen.members.class = prev_aen.members.class;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret_val = abort_aen_cmd(instance, aen_cmd);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ret_val) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "register_mfi_aen: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "failed to abort prevous AEN command"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ret_val);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China curr_aen.word = LE_32(class_locale_word);
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China curr_aen.members.locale = LE_16(curr_aen.members.locale);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd = get_mfi_pkt(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele if (!cmd) {
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele DTRACE_PROBE2(mfi_aen_err, uint16_t, instance->fw_outstanding,
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele uint16_t, instance->max_fw_cmds);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ENOMEM);
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Clear the frame buffer and assign back the context id */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->index);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dcmd = &cmd->frame->dcmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* for(i = 0; i < DCMD_MBOX_SZ; i++) dcmd->mbox.b[i] = 0; */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memset(dcmd->mbox.b, 0, DCMD_MBOX_SZ);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) memset(instance->mfi_evt_detail_obj.buffer, 0,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (struct mrsas_evt_detail));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Prepare DCMD for aen registration */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->cmd, MFI_CMD_OP_DCMD);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->cmd_status, 0x0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->sge_count, 1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(cmd->frame_dma_obj.acc_handle, &dcmd->flags,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MFI_FRAME_DIR_READ);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(cmd->frame_dma_obj.acc_handle, &dcmd->timeout, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->data_xfer_len,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (struct mrsas_evt_detail));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->opcode,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MR_DCMD_CTRL_EVENT_WAIT);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->mbox.w[0], seq_num);
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China curr_aen.members.locale = LE_16(curr_aen.members.locale);
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China curr_aen.word = LE_32(curr_aen.word);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->mbox.w[1],
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele curr_aen.word);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->sgl.sge32[0].phys_addr,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->mfi_evt_detail_obj.dma_cookie[0].dmac_address);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->sgl.sge32[0].length,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sizeof (struct mrsas_evt_detail));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->aen_seq_num = seq_num;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Store reference to the cmd used to register for AEN. When an
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * application wants us to register for AEN, we have to abort this
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * cmd and re-register with a new EVENT LOCALE supplied by that app
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->aen_cmd = cmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->frame_count = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Issue the aen registration frame */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* atomic_add_16 (&instance->fw_outstanding, 1); */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->func_ptr->issue_cmd(cmd, instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeledisplay_scsi_inquiry(caddr_t scsi_inq)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#define MAX_SCSI_DEVICE_CODE 14
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele char inquiry_buf[256] = {0};
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int len;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele const char *const scsi_device_types[] = {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "Direct-Access ",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "Sequential-Access",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "Printer ",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "Processor ",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "WORM ",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "CD-ROM ",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "Scanner ",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "Optical Device ",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "Medium Changer ",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "Communications ",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "Unknown ",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "Unknown ",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "Unknown ",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "Enclosure ",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele };
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele len = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele len += snprintf(inquiry_buf + len, 265 - len, " Vendor: ");
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 8; i < 16; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele len += snprintf(inquiry_buf + len, 265 - len, "%c",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele scsi_inq[i]);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele len += snprintf(inquiry_buf + len, 265 - len, " Model: ");
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 16; i < 32; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele len += snprintf(inquiry_buf + len, 265 - len, "%c",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele scsi_inq[i]);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele len += snprintf(inquiry_buf + len, 265 - len, " Rev: ");
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 32; i < 36; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele len += snprintf(inquiry_buf + len, 265 - len, "%c",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele scsi_inq[i]);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele len += snprintf(inquiry_buf + len, 265 - len, "\n");
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele i = scsi_inq[0] & 0x1f;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele len += snprintf(inquiry_buf + len, 265 - len, " Type: %s ",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele i < MAX_SCSI_DEVICE_CODE ? scsi_device_types[i] :
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "Unknown ");
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele len += snprintf(inquiry_buf + len, 265 - len,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele " ANSI SCSI revision: %02x", scsi_inq[2] & 0x07);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((scsi_inq[2] & 0x07) == 1 && (scsi_inq[3] & 0x0f) == 1) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele len += snprintf(inquiry_buf + len, 265 - len, " CCS\n");
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele len += snprintf(inquiry_buf + len, 265 - len, "\n");
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_CONT, inquiry_buf));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleread_fw_status_reg_ppc(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return ((int)RD_OB_SCRATCH_PAD_0(instance));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleissue_cmd_ppc(struct mrsas_cmd *cmd, struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele atomic_add_16(&instance->fw_outstanding, 1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Issue the command to the FW */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele WR_IB_QPORT((cmd->frame_phys_addr) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (((cmd->frame_count - 1) << 1) | 1), instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * issue_cmd_in_sync_mode
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleissue_cmd_in_sync_mode_ppc(struct mrsas_instance *instance,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t msecs = MFI_POLL_TIMEOUT_SECS * (10 * MILLISEC);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_sync_mode_ppc: called"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->cmd_status = ENODATA;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele WR_IB_QPORT((cmd->frame_phys_addr) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (((cmd->frame_count - 1) << 1) | 1), instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mutex_enter(&instance->int_cmd_mtx);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < msecs && (cmd->cmd_status == ENODATA); i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cv_wait(&instance->int_cmd_cv, &instance->int_cmd_mtx);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mutex_exit(&instance->int_cmd_mtx);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_sync_mode_ppc: done"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (i < (msecs -1)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * issue_cmd_in_poll_mode
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleissue_cmd_in_poll_mode_ppc(struct mrsas_instance *instance,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint16_t flags;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t msecs = MFI_POLL_TIMEOUT_SECS * MILLISEC;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_header *frame_hdr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_poll_mode_ppc: called"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele frame_hdr = (struct mrsas_header *)cmd->frame;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put8(cmd->frame_dma_obj.acc_handle, &frame_hdr->cmd_status,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MFI_CMD_STATUS_POLL_MODE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele flags = ddi_get16(cmd->frame_dma_obj.acc_handle, &frame_hdr->flags);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_put16(cmd->frame_dma_obj.acc_handle, &frame_hdr->flags, flags);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* issue the frame using inbound queue port */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele WR_IB_QPORT((cmd->frame_phys_addr) |
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (((cmd->frame_count - 1) << 1) | 1), instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* wait for cmd_status to change from 0xFF */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < msecs && (
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_get8(cmd->frame_dma_obj.acc_handle, &frame_hdr->cmd_status)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele == MFI_CMD_STATUS_POLL_MODE); i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele drv_usecwait(MILLISEC); /* wait for 1000 usecs */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_get8(cmd->frame_dma_obj.acc_handle, &frame_hdr->cmd_status)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele == MFI_CMD_STATUS_POLL_MODE) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE, "issue_cmd_in_poll_mode: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "cmd polling timed out"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleenable_intr_ppc(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t mask;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "enable_intr_ppc: called"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* WR_OB_DOORBELL_CLEAR(0xFFFFFFFF, instance); */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele WR_OB_DOORBELL_CLEAR(OB_DOORBELL_CLEAR_MASK, instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* WR_OB_INTR_MASK(~0x80000000, instance); */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele WR_OB_INTR_MASK(~(MFI_REPLY_2108_MESSAGE_INTR_MASK), instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* dummy read to force PCI flush */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mask = RD_OB_INTR_MASK(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "enable_intr_ppc: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "outbound_intr_mask = 0x%x", mask));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeledisable_intr_ppc(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t mask;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: called"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: before : "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "outbound_intr_mask = 0x%x", RD_OB_INTR_MASK(instance)));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* WR_OB_INTR_MASK(0xFFFFFFFF, instance); */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele WR_OB_INTR_MASK(OB_INTR_MASK, instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: after : "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "outbound_intr_mask = 0x%x", RD_OB_INTR_MASK(instance)));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* dummy read to force PCI flush */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mask = RD_OB_INTR_MASK(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#ifdef lint
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mask = mask;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele#endif
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleintr_ack_ppc(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint32_t status;
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China int ret = DDI_INTR_CLAIMED;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "intr_ack_ppc: called"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* check if it is our interrupt */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele status = RD_OB_INTR_STATUS(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "intr_ack_ppc: status = 0x%x", status));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (!(status & MFI_REPLY_2108_MESSAGE_INTR)) {
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China ret = DDI_INTR_UNCLAIMED;
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China }
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China if (mrsas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) {
8a64454cbf6b324db5da2fd42da7dcefe66bcc8aYu Wu - Sun Microsystems - Beijing China ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China ret = DDI_INTR_UNCLAIMED;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China if (ret == DDI_INTR_UNCLAIMED) {
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China return (ret);
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* clear the interrupt by writing back the same value */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele WR_OB_DOORBELL_CLEAR(status, instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* dummy READ */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele status = RD_OB_INTR_STATUS(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "intr_ack_ppc: interrupt cleared"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
34841cc2abc43146ada78560d5f179be666acbdaYu Wu - Sun Microsystems - Beijing China return (ret);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_common_check(struct mrsas_instance *instance,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_cmd *cmd)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int ret = DDI_SUCCESS;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_check_dma_handle(cmd->frame_dma_obj.dma_handle) !=
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (cmd->pkt != NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->pkt->pkt_reason = CMD_TRAN_ERR;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->pkt->pkt_statistics = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret = DDI_FAILURE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_check_dma_handle(instance->mfi_internal_dma_obj.dma_handle)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (cmd->pkt != NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->pkt->pkt_reason = CMD_TRAN_ERR;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->pkt->pkt_statistics = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret = DDI_FAILURE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_check_dma_handle(instance->mfi_evt_detail_obj.dma_handle) !=
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (cmd->pkt != NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->pkt->pkt_reason = CMD_TRAN_ERR;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->pkt->pkt_statistics = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret = DDI_FAILURE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_acc_err_clear(instance->regmap_handle, DDI_FME_VER0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (cmd->pkt != NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->pkt->pkt_reason = CMD_TRAN_ERR;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cmd->pkt->pkt_statistics = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret = DDI_FAILURE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ret);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*ARGSUSED*/
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * as the driver can always deal with an error in any dma or
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * access handle, we can just return the fme_status value.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pci_ereport_post(dip, err, NULL);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (err->fme_status);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_fm_init(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Need to change iblock to priority for new MSI intr */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_iblock_cookie_t fm_ibc;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Only register with IO Fault Services if we have some capability */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->fm_capabilities) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Adjust access and dma attributes for FMA */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele endian_attr.devacc_attr_access = DDI_FLAGERR_ACC;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_generic_dma_attr.dma_attr_flags = DDI_DMA_FLAGERR;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Register capabilities with IO Fault Services.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * fm_capabilities will be updated to indicate
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * capabilities actually supported (not requested.)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_init(instance->dip, &instance->fm_capabilities, &fm_ibc);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Initialize pci ereport capabilities if ereport
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * capable (should always be.)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (DDI_FM_EREPORT_CAP(instance->fm_capabilities) ||
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_FM_ERRCB_CAP(instance->fm_capabilities)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pci_ereport_setup(instance->dip);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Register error callback if error callback capable.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (DDI_FM_ERRCB_CAP(instance->fm_capabilities)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_handler_register(instance->dip,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_fm_error_cb, (void*) instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele endian_attr.devacc_attr_access = DDI_DEFAULT_ACC;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_generic_dma_attr.dma_attr_flags = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_fm_fini(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Only unregister FMA capabilities if registered */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->fm_capabilities) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Un-register error callback if error callback capable.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (DDI_FM_ERRCB_CAP(instance->fm_capabilities)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_handler_unregister(instance->dip);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Release any resources allocated by pci_ereport_setup()
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (DDI_FM_EREPORT_CAP(instance->fm_capabilities) ||
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_FM_ERRCB_CAP(instance->fm_capabilities)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pci_ereport_teardown(instance->dip);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Unregister from IO Fault Services */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_fini(instance->dip);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Adjust access and dma attributes for FMA */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele endian_attr.devacc_attr_access = DDI_DEFAULT_ACC;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrsas_generic_dma_attr.dma_attr_flags = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleint
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_check_acc_handle(ddi_acc_handle_t handle)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_error_t de;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (handle == NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (de.fme_status);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufeleint
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_check_dma_handle(ddi_dma_handle_t handle)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_error_t de;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (handle == NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (de.fme_status);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelevoid
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_fm_ereport(struct mrsas_instance *instance, char *detail)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint64_t ena;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele char buf[FM_MAX_CLASS];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ena = fm_ena_generate(0, FM_ENA_FMT1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (DDI_FM_EREPORT_CAP(instance->fm_capabilities)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_fm_ereport_post(instance->dip, buf, ena, DDI_NOSLEEP,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERSION, NULL);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_add_intrs(struct mrsas_instance *instance, int intr_type)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dev_info_t *dip = instance->dip;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int avail, actual, count;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int i, flag, ret;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_DLEVEL1, (CE_WARN, "mrsas_add_intrs: intr_type = %x",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele intr_type));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Get number of interrupts */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret = ddi_intr_get_nintrs(dip, intr_type, &count);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((ret != DDI_SUCCESS) || (count == 0)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "ddi_intr_get_nintrs() failed:"
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "ret %d count %d", ret, count));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_DLEVEL1, (CE_WARN, "mrsas_add_intrs: count = %d ", count));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Get number of available interrupts */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret = ddi_intr_get_navail(dip, intr_type, &avail);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((ret != DDI_SUCCESS) || (avail == 0)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "ddi_intr_get_navail() failed:"
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "ret %d avail %d", ret, avail));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_DLEVEL1, (CE_WARN, "mrsas_add_intrs: avail = %d ", avail));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Only one interrupt routine. So limit the count to 1 */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (count > 1) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele count = 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Allocate an array of interrupt handlers. Currently we support
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * only one interrupt. The framework can be extended later.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->intr_size = count * sizeof (ddi_intr_handle_t);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->intr_htable = kmem_zalloc(instance->intr_size, KM_SLEEP);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ASSERT(instance->intr_htable);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele flag = ((intr_type == DDI_INTR_TYPE_MSI) || (intr_type ==
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_INTR_TYPE_MSIX)) ? DDI_INTR_ALLOC_STRICT:DDI_INTR_ALLOC_NORMAL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Allocate interrupt */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret = ddi_intr_alloc(dip, instance->intr_htable, intr_type, 0,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele count, &actual, flag);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((ret != DDI_SUCCESS) || (actual == 0)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "mrsas_add_intrs: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "avail = %d", avail));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_free(instance->intr_htable, instance->intr_size);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (actual < count) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "mrsas_add_intrs: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "Requested = %d Received = %d", count, actual));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->intr_cnt = actual;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Get the priority of the interrupt allocated.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((ret = ddi_intr_get_pri(instance->intr_htable[0],
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &instance->intr_pri)) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "mrsas_add_intrs: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "get priority call failed"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < actual; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_intr_free(instance->intr_htable[i]);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_free(instance->intr_htable, instance->intr_size);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /*
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele * Test for high level mutex. we don't support them.
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->intr_pri >= ddi_intr_get_hilevel_pri()) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "mrsas_add_intrs: "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "High level interrupts not supported."));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < actual; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_intr_free(instance->intr_htable[i]);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_free(instance->intr_htable, instance->intr_size);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_DLEVEL1, (CE_NOTE, "mrsas_add_intrs: intr_pri = 0x%x ",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->intr_pri));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Call ddi_intr_add_handler() */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < actual; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret = ddi_intr_add_handler(instance->intr_htable[i],
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (ddi_intr_handler_t *)mrsas_isr, (caddr_t)instance,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (caddr_t)(uintptr_t)i);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ret != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "mrsas_add_intrs:"
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "failed %d", ret));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < actual; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_intr_free(instance->intr_htable[i]);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_free(instance->intr_htable, instance->intr_size);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_DLEVEL1, (CE_WARN, " ddi_intr_add_handler done"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((ret = ddi_intr_get_cap(instance->intr_htable[0],
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele &instance->intr_cap)) != DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "ddi_intr_get_cap() failed %d",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ret));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Free already allocated intr */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < actual; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_intr_remove_handler(
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->intr_htable[i]);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_intr_free(instance->intr_htable[i]);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_free(instance->intr_htable, instance->intr_size);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->intr_cap & DDI_INTR_FLAG_BLOCK) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_WARN, "Calling ddi_intr_block _enable"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_intr_block_enable(instance->intr_htable,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->intr_cnt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE, " calling ddi_intr_enable"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < instance->intr_cnt; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_intr_enable(instance->intr_htable[i]);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE, "ddi intr enable returns "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "%d", i));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_rem_intrs(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int i;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN, (CE_NOTE, "mrsas_rem_intrs called"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Disable all interrupts first */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (instance->intr_cap & DDI_INTR_FLAG_BLOCK) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_intr_block_disable(instance->intr_htable,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele instance->intr_cnt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < instance->intr_cnt; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_intr_disable(instance->intr_htable[i]);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Remove all the handlers */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (i = 0; i < instance->intr_cnt; i++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_intr_remove_handler(instance->intr_htable[i]);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_intr_free(instance->intr_htable[i]);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_free(instance->intr_htable, instance->intr_size);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_tran_bus_config(dev_info_t *parent, uint_t flags,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_bus_config_op_t op, void *arg, dev_info_t **childp)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_instance *instance;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int config;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int rval;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele char *ptr = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int tgt, lun;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "Bus config called for op = %x", op));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((instance = ddi_get_soft_state(mrsas_state,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ddi_get_instance(parent))) == NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (NDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Hold nexus during bus_config */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ndi_devi_enter(parent, &config);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch (op) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case BUS_CONFIG_ONE: {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* parse wwid/target name out of name given */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((ptr = strchr((char *)arg, '@')) == NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = NDI_FAILURE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ptr++;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrsas_parse_devname(arg, &tgt, &lun) != 0) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = NDI_FAILURE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (lun == 0) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = mrsas_config_ld(instance, tgt, lun, childp);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = NDI_FAILURE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case BUS_CONFIG_DRIVER:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case BUS_CONFIG_ALL: {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = mrsas_config_all_devices(instance);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = NDI_SUCCESS;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (rval == NDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = ndi_busop_bus_config(parent, flags, op, arg, childp, 0);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ndi_devi_exit(parent, config);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "mrsas_tran_bus_config: rval = %x",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (rval);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_config_all_devices(struct mrsas_instance *instance)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int rval, tgt;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (tgt = 0; tgt < MRDRV_MAX_LD; tgt++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) mrsas_config_ld(instance, tgt, 0, NULL);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = NDI_SUCCESS;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (rval);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_parse_devname(char *devnm, int *tgt, int *lun)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele char devbuf[SCSI_MAXNAMELEN];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele char *addr;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele char *p, *tp, *lp;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele long num;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Parse dev name and address */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) strcpy(devbuf, devnm);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele addr = "";
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (p = devbuf; *p != '\0'; p++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (*p == '@') {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele addr = p + 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *p = '\0';
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else if (*p == ':') {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *p = '\0';
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Parse target and lun */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele for (p = tp = addr, lp = NULL; *p != '\0'; p++) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (*p == ',') {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele lp = p + 1;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *p = '\0';
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (tgt && tp) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_strtol(tp, NULL, 0x10, &num)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE); /* Can declare this as constant */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *tgt = (int)num;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (lun && lp) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ddi_strtol(lp, NULL, 0x10, &num)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *lun = (int)num;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS); /* Success case */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_config_ld(struct mrsas_instance *instance, uint16_t tgt,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint8_t lun, dev_info_t **ldip)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct scsi_device *sd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dev_info_t *child;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int rval;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "mrsas_config_ld: t = %d l = %d",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tgt, lun));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((child = mrsas_find_child(instance, tgt, lun)) != NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ldip) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *ldip = child;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mrsas_config_ld: Child = %p found t = %d l = %d",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void *)child, tgt, lun));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (NDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sd = kmem_zalloc(sizeof (struct scsi_device), KM_SLEEP);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sd->sd_address.a_hba_tran = instance->tran;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sd->sd_address.a_target = (uint16_t)tgt;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sd->sd_address.a_lun = (uint8_t)lun;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (scsi_hba_probe(sd, NULL) == SCSIPROBE_EXISTS)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = mrsas_config_scsi_device(instance, sd, ldip);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele else
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = NDI_FAILURE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* sd_unprobe is blank now. Free buffer manually */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (sd->sd_inq) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_free(sd->sd_inq, SUN_INQSIZE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele sd->sd_inq = (struct scsi_inquiry *)NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_free(sd, sizeof (struct scsi_device));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "mrsas_config_ld: return rval = %d",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (rval);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_config_scsi_device(struct mrsas_instance *instance,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct scsi_device *sd, dev_info_t **dipp)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele char *nodename = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele char **compatible = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int ncompatible = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele char *childname;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dev_info_t *ldip = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int tgt = sd->sd_address.a_target;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int lun = sd->sd_address.a_lun;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int dtype = sd->sd_inq->inq_dtype & DTYPE_MASK;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int rval;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_WARN, "mr_sas: scsi_device t%dL%d", tgt, lun));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele scsi_hba_nodename_compatible_get(sd->sd_inq, NULL, dtype,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele NULL, &nodename, &compatible, &ncompatible);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (nodename == NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_WARN, "mr_sas: Found no compatible driver "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "for t%dL%d", tgt, lun));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = NDI_FAILURE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto finish;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele childname = (dtype == DTYPE_DIRECT) ? "sd" : nodename;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: Childname = %2s nodename = %s", childname, nodename));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* Create a dev node */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = ndi_devi_alloc(instance->dip, childname, DEVI_SID_NODEID, &ldip);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas_config_scsi_device: ndi_devi_alloc rval = %x", rval));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (rval == NDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ndi_prop_update_int(DDI_DEV_T_NONE, ldip, "target", tgt) !=
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_PROP_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_WARN, "mr_sas: unable to create "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "property for t%dl%d target", tgt, lun));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = NDI_FAILURE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto finish;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ndi_prop_update_int(DDI_DEV_T_NONE, ldip, "lun", lun) !=
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_PROP_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_WARN, "mr_sas: unable to create "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "property for t%dl%d lun", tgt, lun));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = NDI_FAILURE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto finish;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (ndi_prop_update_string_array(DDI_DEV_T_NONE, ldip,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "compatible", compatible, ncompatible) !=
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_PROP_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_WARN, "mr_sas: unable to create "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "property for t%dl%d compatible", tgt, lun));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = NDI_FAILURE;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele goto finish;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval = ndi_devi_online(ldip, NDI_ONLINE_ATTACH);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (rval != NDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_WARN, "mr_sas: unable to online "
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "t%dl%d", tgt, lun));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ndi_prop_remove_all(ldip);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ndi_devi_free(ldip);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_WARN, "mr_sas: online Done :"
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "0 t%dl%d", tgt, lun));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelefinish:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (dipp) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele *dipp = ldip;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_DLEVEL1, (CE_WARN,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: config_scsi_device rval = %d t%dL%d",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele rval, tgt, lun));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele scsi_hba_nodename_compatible_free(nodename, compatible);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (rval);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele/*ARGSUSED*/
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_service_evt(struct mrsas_instance *instance, int tgt, int lun, int event,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint64_t wwn)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_eventinfo *mrevt = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mrsas_service_evt called for t%dl%d event = %d",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tgt, lun, event));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((instance->taskq == NULL) || (mrevt =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_zalloc(sizeof (struct mrsas_eventinfo), KM_NOSLEEP)) == NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (ENOMEM);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrevt->instance = instance;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrevt->tgt = tgt;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrevt->lun = lun;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrevt->event = event;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((ddi_taskq_dispatch(instance->taskq,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void (*)(void *))mrsas_issue_evt_taskq, mrevt, DDI_NOSLEEP)) !=
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DDI_SUCCESS) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: Event task failed for t%dl%d event = %d",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele tgt, lun, event));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_free(mrevt, sizeof (struct mrsas_eventinfo));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_FAILURE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
86e4912a3476b98b8ed9e884e1994b058aff908eSusan Scheufele DTRACE_PROBE3(service_evt, int, tgt, int, lun, int, event);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (DDI_SUCCESS);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic void
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_issue_evt_taskq(struct mrsas_eventinfo *mrevt)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mrsas_instance *instance = mrevt->instance;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dev_info_t *dip, *pdip;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele int circ1 = 0;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele char *devname;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE, "mrsas_issue_evt_taskq: called for"
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele " tgt %d lun %d event %d",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrevt->tgt, mrevt->lun, mrevt->event));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrevt->tgt < MRDRV_MAX_LD && mrevt->lun == 0) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele dip = instance->mr_ld_list[mrevt->tgt].dip;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ndi_devi_enter(instance->dip, &circ1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch (mrevt->event) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MRSAS_EVT_CONFIG_TGT:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (dip == NULL) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (mrevt->lun == 0) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) mrsas_config_ld(instance, mrevt->tgt,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele 0, NULL);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: EVT_CONFIG_TGT called:"
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele " for tgt %d lun %d event %d",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrevt->tgt, mrevt->lun, mrevt->event));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: EVT_CONFIG_TGT dip != NULL:"
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele " for tgt %d lun %d event %d",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrevt->tgt, mrevt->lun, mrevt->event));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case MRSAS_EVT_UNCONFIG_TGT:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (dip) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if (i_ddi_devi_attached(dip)) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele pdip = ddi_get_parent(dip);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele devname = kmem_zalloc(MAXNAMELEN + 1, KM_SLEEP);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ddi_deviname(dip, devname);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) devfs_clean(pdip, devname + 1,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele DV_CLEAN_FORCE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_free(devname, MAXNAMELEN + 1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (void) ndi_devi_offline(dip, NDI_DEVI_REMOVE);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: EVT_UNCONFIG_TGT called:"
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele " for tgt %d lun %d event %d",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrevt->tgt, mrevt->lun, mrevt->event));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele } else {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_NOTE,
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele "mr_sas: EVT_UNCONFIG_TGT dip == NULL:"
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele " for tgt %d lun %d event %d",
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele mrevt->tgt, mrevt->lun, mrevt->event));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele kmem_free(mrevt, sizeof (struct mrsas_eventinfo));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele ndi_devi_exit(instance->dip, circ1);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelestatic int
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufelemrsas_mode_sense_build(struct scsi_pkt *pkt)
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele{
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele union scsi_cdb *cdbp;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele uint16_t page_code;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct scsa_cmd *acmd;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct buf *bp;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mode_header *modehdrp;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele cdbp = (void *)pkt->pkt_cdbp;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele page_code = cdbp->cdb_un.sg.scsi[0];
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele acmd = PKT2CMD(pkt);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele bp = acmd->cmd_buf;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele if ((!bp) && bp->b_un.b_addr && bp->b_bcount && acmd->cmd_dmacount) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele con_log(CL_ANN1, (CE_WARN, "Failing MODESENSE Command"));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele /* ADD pkt statistics as Command failed. */
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (NULL);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele bp_mapin(bp);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele bzero(bp->b_un.b_addr, bp->b_bcount);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele switch (page_code) {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case 0x3: {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mode_format *page3p = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele modehdrp = (struct mode_header *)(bp->b_un.b_addr);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele modehdrp->bdesc_length = MODE_BLK_DESC_LENGTH;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele page3p = (void *)((caddr_t)modehdrp +
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MODE_HEADER_LENGTH + MODE_BLK_DESC_LENGTH);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele page3p->mode_page.code = 0x3;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele page3p->mode_page.length =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uchar_t)(sizeof (struct mode_format));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele page3p->data_bytes_sect = 512;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele page3p->sect_track = 63;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele case 0x4: {
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele struct mode_geometry *page4p = NULL;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele modehdrp = (struct mode_header *)(bp->b_un.b_addr);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele modehdrp->bdesc_length = MODE_BLK_DESC_LENGTH;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele page4p = (void *)((caddr_t)modehdrp +
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele MODE_HEADER_LENGTH + MODE_BLK_DESC_LENGTH);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele page4p->mode_page.code = 0x4;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele page4p->mode_page.length =
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele (uchar_t)(sizeof (struct mode_geometry));
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele page4p->heads = 255;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele page4p->rpm = 10000;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele default:
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele break;
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele }
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele return (NULL);
dcda19f50b2b80bfc622fff718ac04fb0e1cb670Susan Scheufele}