500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD/*
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * CDDL HEADER START
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD *
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * The contents of this file are subject to the terms of the
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * Common Development and Distribution License (the "License").
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * You may not use this file except in compliance with the License.
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD *
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * or http://www.opensolaris.org/os/licensing.
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * See the License for the specific language governing permissions
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * and limitations under the License.
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD *
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * When distributing Covered Code, include this CDDL HEADER in each
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * If applicable, add the following below this CDDL HEADER, with the
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * fields enclosed by brackets "[]" replaced with your own identifying
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * information: Portions Copyright [yyyy] [name of copyright owner]
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD *
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * CDDL HEADER END
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD/*
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * Use is subject to license terms.
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD#include <sys/types.h>
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD#include <sys/stat.h>
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD#include <sys/cpuvar.h>
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD#include <sys/conf.h>
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD#include <sys/kmem.h>
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD#include <sys/async.h>
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD#include <sys/sysmacros.h>
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD#include <sys/sunddi.h>
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD#include <sys/sunndi.h>
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD#include <sys/ddi_impldefs.h>
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD#include <sys/open.h>
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD#include <sys/errno.h>
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD#include <sys/file.h>
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD#include <sys/policy.h>
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD#include <sys/pci_tools.h>
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD#include <sys/pci_impl.h>
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD#include <sys/hypervisor_api.h>
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD#include <sys/hotplug/pci/pcihp.h>
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD#include "niumx_var.h"
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD/*
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * NIUMX PCITool interface
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD/*LINTLIBRARY*/
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDstatic int niumx_open(dev_t *devp, int flags, int otyp, cred_t *credp);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDstatic int niumx_close(dev_t dev, int flags, int otyp, cred_t *credp);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDstatic int niumx_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD cred_t *credp, int *rvalp);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDstatic int niumx_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD int flags, char *name, caddr_t valuep, int *lengthp);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDstruct cb_ops niumx_cb_ops = {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumx_open, /* open */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumx_close, /* close */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD nodev, /* strategy */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD nodev, /* print */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD nodev, /* dump */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD nodev, /* read */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD nodev, /* write */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumx_ioctl, /* ioctl */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD nodev, /* devmap */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD nodev, /* mmap */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD nodev, /* segmap */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD nochpoll, /* poll */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumx_prop_op, /* cb_prop_op */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD NULL, /* streamtab */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD D_NEW | D_MP | D_HOTPLUG, /* Driver compatibility flag */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD CB_REV, /* rev */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD nodev, /* int (*cb_aread)() */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD nodev /* int (*cb_awrite)() */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD};
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDstatic void niumxtool_fill_in_intr_devs(pcitool_intr_dev_t *dev,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD char *driver_name, char *path_name, int instance);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDstatic int niumxtool_intr(dev_info_t *dip, void *arg, int cmd, int mode);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDint niumx_set_intr_target(niumx_devstate_t *niumxds_p, niudevino_t ino,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niucpuid_t cpu_id);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDextern void *niumx_state;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD/* ARGSUSED3 */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDstatic int
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDniumx_open(dev_t *devp, int flags, int otyp, cred_t *credp)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD{
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumx_devstate_t *niumxds_p;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD minor_t minor = getminor(*devp);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /*
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * Make sure the open is for the right file type.
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (otyp != OTYP_CHR)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (EINVAL);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /*
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * Get the soft state structure for the device.
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumxds_p = (niumx_devstate_t *)ddi_get_soft_state(niumx_state,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD PCI_MINOR_NUM_TO_INSTANCE(minor));
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (niumxds_p == NULL)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (ENXIO);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /*
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * Handle the open by tracking the device state.
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD mutex_enter(&niumxds_p->niumx_mutex);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (flags & FEXCL) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (niumxds_p->niumx_soft_state != NIUMX_SOFT_STATE_CLOSED) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD mutex_exit(&niumxds_p->niumx_mutex);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (EBUSY);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumxds_p->niumx_soft_state = NIUMX_SOFT_STATE_OPEN_EXCL;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD } else {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (niumxds_p->niumx_soft_state == NIUMX_SOFT_STATE_OPEN_EXCL) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD mutex_exit(&niumxds_p->niumx_mutex);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (EBUSY);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumxds_p->niumx_soft_state = NIUMX_SOFT_STATE_OPEN;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumxds_p->niumx_open_count++;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD mutex_exit(&niumxds_p->niumx_mutex);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (0);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD}
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD/* ARGSUSED */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDstatic int
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDniumx_close(dev_t dev, int flags, int otyp, cred_t *credp)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD{
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumx_devstate_t *niumxds_p;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD minor_t minor = getminor(dev);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (otyp != OTYP_CHR)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (EINVAL);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /*
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * Get the soft state structure for the device.
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumxds_p = (niumx_devstate_t *)ddi_get_soft_state(niumx_state,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD PCI_MINOR_NUM_TO_INSTANCE(minor));
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (niumxds_p == NULL)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (ENXIO);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD mutex_enter(&niumxds_p->niumx_mutex);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumxds_p->niumx_soft_state = NIUMX_SOFT_STATE_CLOSED;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumxds_p->niumx_open_count = 0;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD mutex_exit(&niumxds_p->niumx_mutex);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (0);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD}
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD/* ARGSUSED */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDint
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDniumx_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD int *rvalp)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD{
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumx_devstate_t *niumxds_p;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD dev_info_t *dip;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD int rv = DDI_SUCCESS;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD int minor = getminor(dev);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /*
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * Get the soft state structure for the device.
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumxds_p = (niumx_devstate_t *)ddi_get_soft_state(niumx_state,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD PCI_MINOR_NUM_TO_INSTANCE(minor));
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (niumxds_p == NULL) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (ENXIO);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD dip = niumxds_p->dip;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD switch (minor & 0xff) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /*
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * PCI tools.
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD case PCI_TOOL_INTR_MINOR_NUM:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD switch (cmd) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD case PCITOOL_DEVICE_SET_INTR:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /* Require full privileges. */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (secpolicy_kmdb(credp)) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rv = EPERM;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD break;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /*FALLTHRU*/
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /* These require no special privileges. */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD case PCITOOL_DEVICE_GET_INTR:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD case PCITOOL_SYSTEM_INTR_INFO:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rv = niumxtool_intr(dip, (void *)arg, cmd, mode);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD break;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD default:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rv = ENOTTY;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (rv);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD default:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD break;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (rv);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD}
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDstatic int niumx_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD int flags, char *name, caddr_t valuep, int *lengthp)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD{
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (ddi_prop_op(dev, dip, prop_op, flags, name, valuep, lengthp));
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD}
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDint
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDniumxtool_init(dev_info_t *dip)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD{
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD int instance = ddi_get_instance(dip);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (ddi_create_minor_node(dip, PCI_MINOR_INTR, S_IFCHR,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD PCI_MINOR_NUM(instance, PCI_TOOL_INTR_MINOR_NUM),
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DDI_NT_INTRCTL, 0) != DDI_SUCCESS) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ddi_remove_minor_node(dip, PCI_MINOR_REG);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (DDI_FAILURE);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (DDI_SUCCESS);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD}
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDvoid
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDniumxtool_uninit(dev_info_t *dip)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD{
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ddi_remove_minor_node(dip, PCI_MINOR_INTR);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD}
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDstatic void
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDniumxtool_fill_in_intr_devs(pcitool_intr_dev_t *dev, char *driver_name,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD char *path_name, int instance)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD{
5963c4f9d1eb33d95ac319791aa1d0b9ea17f154Richard Lowe (void) strlcpy(dev->driver_name, driver_name, MAXMODCONFNAME);
5963c4f9d1eb33d95ac319791aa1d0b9ea17f154Richard Lowe (void) strlcpy(dev->path, path_name, MAXPATHLEN);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD dev->dev_inst = instance;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD}
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD/*ARGSUSED*/
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDstatic int
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDniumxtool_intr_info(dev_info_t *dip, void *arg, int mode)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD{
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD pcitool_intr_info_t intr_info;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD int rval = DDI_SUCCESS;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /* If we need user_version, and to ret same user version as passed in */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (ddi_copyin(arg, &intr_info, sizeof (pcitool_intr_info_t), mode) !=
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DDI_SUCCESS) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (EFAULT);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD intr_info.ctlr_version = 0; /* XXX how to get real version? */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD intr_info.ctlr_type = PCITOOL_CTLR_TYPE_RISC;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (intr_info.flags & PCITOOL_INTR_FLAG_GET_MSI)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD intr_info.num_intr = 0;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD else
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD intr_info.num_intr = NIUMX_MAX_INTRS;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD intr_info.drvr_version = PCITOOL_VERSION;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (ddi_copyout(&intr_info, arg, sizeof (pcitool_intr_info_t), mode) !=
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DDI_SUCCESS) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = EFAULT;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (rval);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD}
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD/*
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * Get interrupt information for a given ino.
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * Returns info only for inos mapped to devices.
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD *
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * Returned info is valid only when iget.num_devs is returned > 0.
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * If ino is not enabled or is not mapped to a device,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * iget.num_devs will be returned as = 0.
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD/*ARGSUSED*/
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDstatic int
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDniumxtool_get_intr(dev_info_t *dip, void *arg, int mode)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD{
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /* Array part isn't used here, but oh well... */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD pcitool_intr_get_t partial_iget;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD pcitool_intr_get_t *iget_p = &partial_iget;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD int copyout_rval;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niusysino_t sysino;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niucpuid_t cpu_id;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumx_devstate_t *niumxds_p;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD dev_info_t *ih_dip;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD size_t iget_kmem_alloc_size = 0;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD char pathname[MAXPATHLEN];
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD int rval = EIO;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumxds_p = (niumx_devstate_t *)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ddi_get_soft_state(niumx_state, ddi_get_instance(dip));
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /* Read in just the header part, no array section. */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (ddi_copyin(arg, &partial_iget, PCITOOL_IGET_SIZE(0), mode) !=
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DDI_SUCCESS)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (EFAULT);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iget_p->status = PCITOOL_IO_ERROR;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iget_p->msi = (uint32_t)-1;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (iget_p->flags & PCITOOL_INTR_FLAG_GET_MSI) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iget_p->status = PCITOOL_INVALID_MSI;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = EINVAL;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD goto done_get_intr;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /* Validate argument. */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (iget_p->ino > NIUMX_MAX_INTRS) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iget_p->status = PCITOOL_INVALID_INO;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = EINVAL;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD goto done_get_intr;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /* Caller wants device information returned. */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (iget_p->num_devs_ret > 0) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /*
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * Allocate room.
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * Note if num_devs == 0 iget_p remains pointing to
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * partial_iget.
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iget_kmem_alloc_size = PCITOOL_IGET_SIZE(iget_p->num_devs_ret);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iget_p = kmem_zalloc(iget_kmem_alloc_size, KM_SLEEP);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /* Read in whole structure to verify there's room. */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (ddi_copyin(arg, iget_p, iget_kmem_alloc_size, mode) !=
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DDI_SUCCESS) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /* Be consistent and just return EFAULT here. */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD kmem_free(iget_p, iget_kmem_alloc_size);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (EFAULT);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD sysino = niumxds_p->niumx_ihtable[iget_p->ino].ih_sysino;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (sysino == 0) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iget_p->status = PCITOOL_IO_ERROR;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = EIO;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD goto done_get_intr;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ih_dip = niumxds_p->niumx_ihtable[iget_p->ino].ih_dip;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ddi_pathname(ih_dip, pathname);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumxtool_fill_in_intr_devs(&iget_p->dev[0],
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD (char *)ddi_driver_name(ih_dip), pathname,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ddi_get_instance(ih_dip));
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (hvio_intr_gettarget(sysino, &cpu_id) != H_EOK) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iget_p->status = PCITOOL_IO_ERROR;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = EIO;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD goto done_get_intr;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (niumxds_p->niumx_ihtable[iget_p->ino].ih_cpuid != cpu_id) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD cmn_err(CE_WARN, "CPU Does not match %x %x", cpu_id,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumxds_p->niumx_ihtable[iget_p->ino].ih_cpuid);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iget_p->status = PCITOOL_IO_ERROR;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = EIO;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD goto done_get_intr;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iget_p->num_devs = 1;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iget_p->cpu_id = niumxds_p->niumx_ihtable[iget_p->ino].ih_cpuid;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iget_p->status = PCITOOL_SUCCESS;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = DDI_SUCCESS;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDdone_get_intr:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iget_p->drvr_version = PCITOOL_VERSION;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD copyout_rval =
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ddi_copyout(iget_p, arg, PCITOOL_IGET_SIZE(iget_p->num_devs_ret),
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD mode);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (iget_kmem_alloc_size > 0)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD kmem_free(iget_p, iget_kmem_alloc_size);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (copyout_rval != DDI_SUCCESS)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = EFAULT;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (rval);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD}
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD/*
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * Associate a new CPU with a given ino.
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD *
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD * Operate only on inos which are already mapped to devices.
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDstatic int
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDniumxtool_set_intr(dev_info_t *dip, void *arg, int mode)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD{
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD pcitool_intr_set_t iset;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niucpuid_t old_cpu_id;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD int rval = EIO;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD int ret = DDI_SUCCESS;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD size_t copyinout_size;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumx_devstate_t *niumxds_p;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumxds_p = (niumx_devstate_t *)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ddi_get_soft_state(niumx_state, ddi_get_instance(dip));
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD bzero(&iset, sizeof (pcitool_intr_set_t));
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /* Version 1 of pcitool_intr_set_t doesn't have flags. */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD copyinout_size = (size_t)&iset.flags - (size_t)&iset;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (ddi_copyin(arg, &iset, copyinout_size, mode) != DDI_SUCCESS)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (EFAULT);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD switch (iset.user_version) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD case PCITOOL_V1:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD break;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD case PCITOOL_V2:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD copyinout_size = sizeof (pcitool_intr_set_t);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (ddi_copyin(arg, &iset, copyinout_size, mode) != DDI_SUCCESS)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (EFAULT);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD break;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD default:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iset.status = PCITOOL_OUT_OF_RANGE;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = ENOTSUP;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD goto done_set_intr;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (iset.flags & PCITOOL_INTR_FLAG_SET_GROUP) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iset.status = PCITOOL_IO_ERROR;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = ENOTSUP;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD goto done_set_intr;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iset.status = PCITOOL_IO_ERROR;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iset.msi = (uint32_t)-1;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /* Validate input argument. */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (iset.ino > NIUMX_MAX_INTRS) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iset.status = PCITOOL_INVALID_INO;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = EINVAL;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD goto done_set_intr;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD old_cpu_id = niumxds_p->niumx_ihtable[iset.ino].ih_cpuid;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if ((ret = niumx_set_intr_target(niumxds_p, iset.ino,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iset.cpu_id)) == DDI_SUCCESS) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iset.cpu_id = old_cpu_id;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iset.status = PCITOOL_SUCCESS;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = DDI_SUCCESS;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD goto done_set_intr;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD switch (ret) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD case DDI_EPENDING:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iset.status = PCITOOL_PENDING_INTRTIMEOUT;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = ETIME;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD break;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD case DDI_EINVAL:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iset.status = PCITOOL_INVALID_CPUID;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = EINVAL;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD break;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD default:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iset.status = PCITOOL_IO_ERROR;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = EIO;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD break;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDdone_set_intr:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD iset.drvr_version = PCITOOL_VERSION;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (ddi_copyout(&iset, arg, copyinout_size, mode) != DDI_SUCCESS)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = EFAULT;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (rval);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD}
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD/* Main function for handling interrupt CPU binding requests and queries. */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDstatic int
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDniumxtool_intr(dev_info_t *dip, void *arg, int cmd, int mode)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD{
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD int rval = DDI_SUCCESS;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD switch (cmd) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /* Get system interrupt information. */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD case PCITOOL_SYSTEM_INTR_INFO:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = niumxtool_intr_info(dip, arg, mode);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD break;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /* Get interrupt information for a given ino. */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD case PCITOOL_DEVICE_GET_INTR:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = niumxtool_get_intr(dip, arg, mode);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD break;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /* Associate a new CPU with a given ino. */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD case PCITOOL_DEVICE_SET_INTR:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = niumxtool_set_intr(dip, arg, mode);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD break;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD default:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = ENOTTY;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (rval);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD}