4496171313bed39e96f21bc2f9faf2868e267ae3girish/*
4496171313bed39e96f21bc2f9faf2868e267ae3girish * CDDL HEADER START
4496171313bed39e96f21bc2f9faf2868e267ae3girish *
4496171313bed39e96f21bc2f9faf2868e267ae3girish * The contents of this file are subject to the terms of the
4496171313bed39e96f21bc2f9faf2868e267ae3girish * Common Development and Distribution License (the "License").
4496171313bed39e96f21bc2f9faf2868e267ae3girish * You may not use this file except in compliance with the License.
4496171313bed39e96f21bc2f9faf2868e267ae3girish *
4496171313bed39e96f21bc2f9faf2868e267ae3girish * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
4496171313bed39e96f21bc2f9faf2868e267ae3girish * or http://www.opensolaris.org/os/licensing.
4496171313bed39e96f21bc2f9faf2868e267ae3girish * See the License for the specific language governing permissions
4496171313bed39e96f21bc2f9faf2868e267ae3girish * and limitations under the License.
4496171313bed39e96f21bc2f9faf2868e267ae3girish *
4496171313bed39e96f21bc2f9faf2868e267ae3girish * When distributing Covered Code, include this CDDL HEADER in each
4496171313bed39e96f21bc2f9faf2868e267ae3girish * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
4496171313bed39e96f21bc2f9faf2868e267ae3girish * If applicable, add the following below this CDDL HEADER, with the
4496171313bed39e96f21bc2f9faf2868e267ae3girish * fields enclosed by brackets "[]" replaced with your own identifying
4496171313bed39e96f21bc2f9faf2868e267ae3girish * information: Portions Copyright [yyyy] [name of copyright owner]
4496171313bed39e96f21bc2f9faf2868e267ae3girish *
4496171313bed39e96f21bc2f9faf2868e267ae3girish * CDDL HEADER END
4496171313bed39e96f21bc2f9faf2868e267ae3girish */
4496171313bed39e96f21bc2f9faf2868e267ae3girish/*
657f87de670449e1422db4f51fb2880a7cb69d5agongtian zhao - Sun Microsystems - Beijing China * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
4496171313bed39e96f21bc2f9faf2868e267ae3girish */
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish/*
4496171313bed39e96f21bc2f9faf2868e267ae3girish * Niagara2 Network Interface Unit (NIU) Nexus Driver
4496171313bed39e96f21bc2f9faf2868e267ae3girish */
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish#include <sys/conf.h>
4496171313bed39e96f21bc2f9faf2868e267ae3girish#include <sys/modctl.h>
4496171313bed39e96f21bc2f9faf2868e267ae3girish#include <sys/ddi_impldefs.h>
4496171313bed39e96f21bc2f9faf2868e267ae3girish#include <sys/ddi_subrdefs.h>
4496171313bed39e96f21bc2f9faf2868e267ae3girish#include <sys/ddi.h>
4496171313bed39e96f21bc2f9faf2868e267ae3girish#include <sys/sunndi.h>
4496171313bed39e96f21bc2f9faf2868e267ae3girish#include <sys/sunddi.h>
4496171313bed39e96f21bc2f9faf2868e267ae3girish#include <sys/open.h>
4496171313bed39e96f21bc2f9faf2868e267ae3girish#include <sys/stat.h>
4496171313bed39e96f21bc2f9faf2868e267ae3girish#include <sys/file.h>
4496171313bed39e96f21bc2f9faf2868e267ae3girish#include <sys/machsystm.h>
4496171313bed39e96f21bc2f9faf2868e267ae3girish#include <sys/hsvc.h>
4496171313bed39e96f21bc2f9faf2868e267ae3girish#include <sys/sdt.h>
4496171313bed39e96f21bc2f9faf2868e267ae3girish#include <sys/hypervisor_api.h>
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD#include <sys/cpuvar.h>
4496171313bed39e96f21bc2f9faf2868e267ae3girish#include "niumx_var.h"
4496171313bed39e96f21bc2f9faf2868e267ae3girish
8fca05700b4a8225bddecd0ca5028f512f483b36jfstatic int niumx_fm_init_child(dev_info_t *, dev_info_t *, int,
8fca05700b4a8225bddecd0ca5028f512f483b36jf ddi_iblock_cookie_t *);
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic int niumx_intr_ops(dev_info_t *dip, dev_info_t *rdip,
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_intr_op_t intr_op, ddi_intr_handle_impl_t *hdlp, void *result);
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic int niumx_attach(dev_info_t *devi, ddi_attach_cmd_t cmd);
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic int niumx_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic int niumx_set_intr(dev_info_t *dip, dev_info_t *rdip,
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_intr_handle_impl_t *hdlp, int valid);
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic int niumx_add_intr(dev_info_t *dip, dev_info_t *rdip,
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_intr_handle_impl_t *hdlp);
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic int niumx_rem_intr(dev_info_t *dip, dev_info_t *rdip,
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_intr_handle_impl_t *hdlp);
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic uint_t niumx_intr_hdlr(void *arg);
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic int niumx_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
4496171313bed39e96f21bc2f9faf2868e267ae3girish off_t offset, off_t len, caddr_t *addrp);
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic int niumx_dma_allochdl(dev_info_t *dip, dev_info_t *rdip,
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_dma_attr_t *attrp,
4496171313bed39e96f21bc2f9faf2868e267ae3girish int (*waitfp)(caddr_t), caddr_t arg, ddi_dma_handle_t *handlep);
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic int niumx_dma_freehdl(dev_info_t *dip, dev_info_t *rdip,
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_dma_handle_t handlep);
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic int niumx_dma_bindhdl(dev_info_t *dip, dev_info_t *rdip,
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_dma_handle_t handle, ddi_dma_req_t *dmareq,
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_dma_cookie_t *cookiep, uint_t *ccountp);
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic int niumx_dma_unbindhdl(dev_info_t *dip, dev_info_t *rdip,
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_dma_handle_t handle);
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic int niumx_ctlops(dev_info_t *dip, dev_info_t *rdip,
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_ctl_enum_t op, void *arg, void *result);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDint niumxtool_init(dev_info_t *dip);
2de7adab54f9f3d152089a7ff5d6bfad81008231Alan Adamson, SD OSSDvoid niumxtool_uninit(dev_info_t *dip);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDint niumx_get_intr_target(niumx_devstate_t *niumxds_p, niudevino_t ino,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niucpuid_t *cpu_id);
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
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic struct bus_ops niumx_bus_ops = {
4496171313bed39e96f21bc2f9faf2868e267ae3girish BUSO_REV,
4496171313bed39e96f21bc2f9faf2868e267ae3girish niumx_map,
4496171313bed39e96f21bc2f9faf2868e267ae3girish 0,
4496171313bed39e96f21bc2f9faf2868e267ae3girish 0,
4496171313bed39e96f21bc2f9faf2868e267ae3girish 0,
4496171313bed39e96f21bc2f9faf2868e267ae3girish i_ddi_map_fault,
4496171313bed39e96f21bc2f9faf2868e267ae3girish 0,
4496171313bed39e96f21bc2f9faf2868e267ae3girish niumx_dma_allochdl,
4496171313bed39e96f21bc2f9faf2868e267ae3girish niumx_dma_freehdl,
4496171313bed39e96f21bc2f9faf2868e267ae3girish niumx_dma_bindhdl,
4496171313bed39e96f21bc2f9faf2868e267ae3girish niumx_dma_unbindhdl,
4496171313bed39e96f21bc2f9faf2868e267ae3girish 0,
4496171313bed39e96f21bc2f9faf2868e267ae3girish 0,
4496171313bed39e96f21bc2f9faf2868e267ae3girish 0,
4496171313bed39e96f21bc2f9faf2868e267ae3girish niumx_ctlops,
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_bus_prop_op,
4496171313bed39e96f21bc2f9faf2868e267ae3girish 0, /* (*bus_get_eventcookie)(); */
4496171313bed39e96f21bc2f9faf2868e267ae3girish 0, /* (*bus_add_eventcall)(); */
4496171313bed39e96f21bc2f9faf2868e267ae3girish 0, /* (*bus_remove_eventcall)(); */
4496171313bed39e96f21bc2f9faf2868e267ae3girish 0, /* (*bus_post_event)(); */
4496171313bed39e96f21bc2f9faf2868e267ae3girish 0, /* (*bus_intr_ctl)(); */
4496171313bed39e96f21bc2f9faf2868e267ae3girish 0, /* (*bus_config)(); */
4496171313bed39e96f21bc2f9faf2868e267ae3girish 0, /* (*bus_unconfig)(); */
8fca05700b4a8225bddecd0ca5028f512f483b36jf niumx_fm_init_child, /* (*bus_fm_init)(); */
4496171313bed39e96f21bc2f9faf2868e267ae3girish 0, /* (*bus_fm_fini)(); */
4496171313bed39e96f21bc2f9faf2868e267ae3girish 0, /* (*bus_enter)() */
4496171313bed39e96f21bc2f9faf2868e267ae3girish 0, /* (*bus_exit)() */
4496171313bed39e96f21bc2f9faf2868e267ae3girish 0, /* (*bus_power)() */
4496171313bed39e96f21bc2f9faf2868e267ae3girish niumx_intr_ops /* (*bus_intr_op)(); */
4496171313bed39e96f21bc2f9faf2868e267ae3girish};
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDextern struct cb_ops niumx_cb_ops;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic struct dev_ops niumx_ops = {
4496171313bed39e96f21bc2f9faf2868e267ae3girish DEVO_REV, /* devo_rev */
4496171313bed39e96f21bc2f9faf2868e267ae3girish 0, /* refcnt */
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_no_info, /* info */
4496171313bed39e96f21bc2f9faf2868e267ae3girish nulldev, /* identify */
4496171313bed39e96f21bc2f9faf2868e267ae3girish 0, /* probe */
4496171313bed39e96f21bc2f9faf2868e267ae3girish niumx_attach, /* attach */
4496171313bed39e96f21bc2f9faf2868e267ae3girish niumx_detach, /* detach */
4496171313bed39e96f21bc2f9faf2868e267ae3girish nulldev, /* reset */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD &niumx_cb_ops, /* driver operations */
4496171313bed39e96f21bc2f9faf2868e267ae3girish &niumx_bus_ops, /* bus operations */
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, /* power */
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_quiesce_not_supported, /* devo_quiesce */
4496171313bed39e96f21bc2f9faf2868e267ae3girish};
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish/* Module linkage information for the kernel. */
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic struct modldrv modldrv = {
4496171313bed39e96f21bc2f9faf2868e267ae3girish &mod_driverops, /* Type of module */
193974072f41a843678abf5f61979c748687e66bSherry Moore "NIU Nexus Driver",
4496171313bed39e96f21bc2f9faf2868e267ae3girish &niumx_ops, /* driver ops */
4496171313bed39e96f21bc2f9faf2868e267ae3girish};
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic struct modlinkage modlinkage = {
4496171313bed39e96f21bc2f9faf2868e267ae3girish MODREV_1,
4496171313bed39e96f21bc2f9faf2868e267ae3girish (void *)&modldrv,
4496171313bed39e96f21bc2f9faf2868e267ae3girish NULL
4496171313bed39e96f21bc2f9faf2868e267ae3girish};
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDvoid *niumx_state;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish/*
4496171313bed39e96f21bc2f9faf2868e267ae3girish * forward function declarations:
4496171313bed39e96f21bc2f9faf2868e267ae3girish */
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic void niumx_removechild(dev_info_t *);
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic int niumx_initchild(dev_info_t *child);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girishint
4496171313bed39e96f21bc2f9faf2868e267ae3girish_init(void)
4496171313bed39e96f21bc2f9faf2868e267ae3girish{
4496171313bed39e96f21bc2f9faf2868e267ae3girish int e;
d66f83158d97c12b2a78b9363a07d9d365762606jb uint64_t mjrnum;
d66f83158d97c12b2a78b9363a07d9d365762606jb uint64_t mnrnum;
d66f83158d97c12b2a78b9363a07d9d365762606jb
d66f83158d97c12b2a78b9363a07d9d365762606jb /*
d66f83158d97c12b2a78b9363a07d9d365762606jb * Check HV intr group api versioning.
d66f83158d97c12b2a78b9363a07d9d365762606jb * This driver uses the old interrupt routines which are supported
d66f83158d97c12b2a78b9363a07d9d365762606jb * in old firmware in the CORE API group and in newer firmware in
d66f83158d97c12b2a78b9363a07d9d365762606jb * the INTR API group. Support for these calls will be dropped
d66f83158d97c12b2a78b9363a07d9d365762606jb * once the INTR API group major goes to 2.
d66f83158d97c12b2a78b9363a07d9d365762606jb */
d66f83158d97c12b2a78b9363a07d9d365762606jb if ((hsvc_version(HSVC_GROUP_INTR, &mjrnum, &mnrnum) == 0) &&
d66f83158d97c12b2a78b9363a07d9d365762606jb (mjrnum > NIUMX_INTR_MAJOR_VER)) {
d66f83158d97c12b2a78b9363a07d9d365762606jb cmn_err(CE_WARN, "niumx: unsupported intr api group: "
d66f83158d97c12b2a78b9363a07d9d365762606jb "maj:0x%lx, min:0x%lx", mjrnum, mnrnum);
d66f83158d97c12b2a78b9363a07d9d365762606jb return (ENOTSUP);
d66f83158d97c12b2a78b9363a07d9d365762606jb }
d66f83158d97c12b2a78b9363a07d9d365762606jb
4496171313bed39e96f21bc2f9faf2868e267ae3girish if ((e = ddi_soft_state_init(&niumx_state, sizeof (niumx_devstate_t),
4496171313bed39e96f21bc2f9faf2868e267ae3girish 1)) == 0 && (e = mod_install(&modlinkage)) != 0)
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_soft_state_fini(&niumx_state);
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (e);
4496171313bed39e96f21bc2f9faf2868e267ae3girish}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girishint
4496171313bed39e96f21bc2f9faf2868e267ae3girish_fini(void)
4496171313bed39e96f21bc2f9faf2868e267ae3girish{
4496171313bed39e96f21bc2f9faf2868e267ae3girish int e;
4496171313bed39e96f21bc2f9faf2868e267ae3girish if ((e = mod_remove(&modlinkage)) == 0)
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_soft_state_fini(&niumx_state);
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (e);
4496171313bed39e96f21bc2f9faf2868e267ae3girish}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girishint
4496171313bed39e96f21bc2f9faf2868e267ae3girish_info(struct modinfo *modinfop)
4496171313bed39e96f21bc2f9faf2868e267ae3girish{
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (mod_info(&modlinkage, modinfop));
4496171313bed39e96f21bc2f9faf2868e267ae3girish}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
c165966d2681754edbe7637da5adf3e53b3f7132jf
c165966d2681754edbe7637da5adf3e53b3f7132jfhrtime_t niumx_intr_timeout = 2ull * NANOSEC; /* 2 seconds in nanoseconds */
c165966d2681754edbe7637da5adf3e53b3f7132jf
3266dff7c77b314b33c74fa8767437ffad5f4a01jfvoid
3266dff7c77b314b33c74fa8767437ffad5f4a01jfniumx_intr_dist(void *arg)
3266dff7c77b314b33c74fa8767437ffad5f4a01jf{
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu niumx_devstate_t *niumxds_p = (niumx_devstate_t *)arg;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu kmutex_t *lock_p = &niumxds_p->niumx_mutex;
e778ae4497a8de30b58b85bd187bf4ef4ba8cd47Raghuram Kothakota int i;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu niumx_ih_t *ih_p = niumxds_p->niumx_ihtable;
3266dff7c77b314b33c74fa8767437ffad5f4a01jf
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_A_INTX, NULL, "niumx_intr_dist entered\n");
3266dff7c77b314b33c74fa8767437ffad5f4a01jf mutex_enter(lock_p);
e778ae4497a8de30b58b85bd187bf4ef4ba8cd47Raghuram Kothakota for (i = 0; i < NIUMX_MAX_INTRS; i++, ih_p++) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niusysino_t sysino = ih_p->ih_sysino;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niucpuid_t cpuid;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD int state;
c165966d2681754edbe7637da5adf3e53b3f7132jf hrtime_t start;
c165966d2681754edbe7637da5adf3e53b3f7132jf dev_info_t *dip = ih_p->ih_dip;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (!sysino || (cpuid = intr_dist_cpuid()) == ih_p->ih_cpuid)
3266dff7c77b314b33c74fa8767437ffad5f4a01jf continue;
3266dff7c77b314b33c74fa8767437ffad5f4a01jf
3266dff7c77b314b33c74fa8767437ffad5f4a01jf (void) hvio_intr_setvalid(sysino, HV_INTR_NOTVALID);
c165966d2681754edbe7637da5adf3e53b3f7132jf
c165966d2681754edbe7637da5adf3e53b3f7132jf /* check for pending interrupts, busy wait if so */
c165966d2681754edbe7637da5adf3e53b3f7132jf for (start = gethrtime(); !panicstr &&
c165966d2681754edbe7637da5adf3e53b3f7132jf (hvio_intr_getstate(sysino, &state) == H_EOK) &&
c165966d2681754edbe7637da5adf3e53b3f7132jf (state == HV_INTR_DELIVERED_STATE); /* */) {
c165966d2681754edbe7637da5adf3e53b3f7132jf if (gethrtime() - start > niumx_intr_timeout) {
c165966d2681754edbe7637da5adf3e53b3f7132jf cmn_err(CE_WARN, "%s%d: niumx_intr_dist: "
c165966d2681754edbe7637da5adf3e53b3f7132jf "pending interrupt (%x,%lx) timedout\n",
c165966d2681754edbe7637da5adf3e53b3f7132jf ddi_driver_name(dip), ddi_get_instance(dip),
c165966d2681754edbe7637da5adf3e53b3f7132jf ih_p->ih_inum, sysino);
c165966d2681754edbe7637da5adf3e53b3f7132jf (void) hvio_intr_setstate(sysino,
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf HV_INTR_IDLE_STATE);
c165966d2681754edbe7637da5adf3e53b3f7132jf break;
c165966d2681754edbe7637da5adf3e53b3f7132jf }
c165966d2681754edbe7637da5adf3e53b3f7132jf }
3266dff7c77b314b33c74fa8767437ffad5f4a01jf (void) hvio_intr_settarget(sysino, cpuid);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (ih_p->ih_state == HV_INTR_VALID)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD (void) hvio_intr_setvalid(sysino, HV_INTR_VALID);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD else
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD (void) hvio_intr_setvalid(sysino, HV_INTR_NOTVALID);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
3266dff7c77b314b33c74fa8767437ffad5f4a01jf ih_p->ih_cpuid = cpuid;
3266dff7c77b314b33c74fa8767437ffad5f4a01jf }
3266dff7c77b314b33c74fa8767437ffad5f4a01jf mutex_exit(lock_p);
3266dff7c77b314b33c74fa8767437ffad5f4a01jf}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic int
4496171313bed39e96f21bc2f9faf2868e267ae3girishniumx_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
4496171313bed39e96f21bc2f9faf2868e267ae3girish{
4496171313bed39e96f21bc2f9faf2868e267ae3girish int instance = ddi_get_instance(dip);
4496171313bed39e96f21bc2f9faf2868e267ae3girish niumx_devstate_t *niumxds_p; /* devstate pointer */
4496171313bed39e96f21bc2f9faf2868e267ae3girish niu_regspec_t *reg_p;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumx_ih_t *ih_p;
4496171313bed39e96f21bc2f9faf2868e267ae3girish uint_t reglen;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD int i, ret = DDI_SUCCESS;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish switch (cmd) {
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_ATTACH:
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf DDI_PROP_DONTPASS, "reg", (int **)&reg_p, &reglen)
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf != DDI_PROP_SUCCESS) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_ATTACH, dip, "reg lookup failed\n");
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = DDI_FAILURE;
4496171313bed39e96f21bc2f9faf2868e267ae3girish goto done;
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish /*
4496171313bed39e96f21bc2f9faf2868e267ae3girish * Allocate and get soft state structure.
4496171313bed39e96f21bc2f9faf2868e267ae3girish */
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (ddi_soft_state_zalloc(niumx_state, instance)
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf != DDI_SUCCESS) {
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = DDI_FAILURE;
4496171313bed39e96f21bc2f9faf2868e267ae3girish goto prop_free;
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish niumxds_p = (niumx_devstate_t *)ddi_get_soft_state(niumx_state,
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf instance);
4496171313bed39e96f21bc2f9faf2868e267ae3girish niumxds_p->dip = dip;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumxds_p->niumx_open_count = 0;
4496171313bed39e96f21bc2f9faf2868e267ae3girish mutex_init(&niumxds_p->niumx_mutex, NULL, MUTEX_DRIVER, NULL);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_ATTACH, dip, "soft state alloc'd instance = %d, "
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf "niumxds_p = %p\n", instance, niumxds_p);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* hv devhdl: low 28-bit of 1st "reg" entry's addr.hi */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumxds_p->niumx_dev_hdl = (niudevhandle_t)(reg_p->addr_high &
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf NIUMX_DEVHDLE_MASK);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ih_p = niumxds_p->niumx_ihtable;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD for (i = 0; i < NIUMX_MAX_INTRS; i++, ih_p++) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ih_p->ih_sysino = 0;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ih_p->ih_state = HV_INTR_NOTVALID;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
3266dff7c77b314b33c74fa8767437ffad5f4a01jf /* add interrupt redistribution callback */
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu intr_dist_add(niumx_intr_dist, niumxds_p);
3266dff7c77b314b33c74fa8767437ffad5f4a01jf
8fca05700b4a8225bddecd0ca5028f512f483b36jf niumxds_p->niumx_fm_cap = DDI_FM_EREPORT_CAPABLE;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd ddi_fm_init(niumxds_p->dip, &niumxds_p->niumx_fm_cap,
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf &niumxds_p->niumx_fm_ibc);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (niumxtool_init(dip) != DDI_SUCCESS) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ret = DDI_FAILURE;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD goto cleanup;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = DDI_SUCCESS;
4496171313bed39e96f21bc2f9faf2868e267ae3girish goto prop_free;
4496171313bed39e96f21bc2f9faf2868e267ae3girishcleanup:
4496171313bed39e96f21bc2f9faf2868e267ae3girish mutex_destroy(&niumxds_p->niumx_mutex);
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_soft_state_free(niumx_state, ddi_get_instance(dip));
4496171313bed39e96f21bc2f9faf2868e267ae3girishprop_free:
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_prop_free(reg_p);
4496171313bed39e96f21bc2f9faf2868e267ae3girishdone:
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (ret);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_RESUME:
4496171313bed39e96f21bc2f9faf2868e267ae3girish default:
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (ret);
4496171313bed39e96f21bc2f9faf2868e267ae3girish}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic int
4496171313bed39e96f21bc2f9faf2868e267ae3girishniumx_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
4496171313bed39e96f21bc2f9faf2868e267ae3girish{
4496171313bed39e96f21bc2f9faf2868e267ae3girish niumx_devstate_t *niumxds_p;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish switch (cmd) {
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_DETACH:
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish niumxds_p = (niumx_devstate_t *)
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_get_soft_state(niumx_state, ddi_get_instance(dip));
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu intr_dist_rem(niumx_intr_dist, niumxds_p);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd ddi_fm_fini(dip);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumxtool_uninit(dip);
4496171313bed39e96f21bc2f9faf2868e267ae3girish mutex_destroy(&niumxds_p->niumx_mutex);
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_soft_state_free(niumx_state, ddi_get_instance(dip));
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (DDI_SUCCESS);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_SUSPEND:
4496171313bed39e96f21bc2f9faf2868e267ae3girish default:
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (DDI_FAILURE);
4496171313bed39e96f21bc2f9faf2868e267ae3girish}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
8fca05700b4a8225bddecd0ca5028f512f483b36jf
8fca05700b4a8225bddecd0ca5028f512f483b36jf/*
8fca05700b4a8225bddecd0ca5028f512f483b36jf * Function used to initialize FMA for our children nodes. Called
8fca05700b4a8225bddecd0ca5028f512f483b36jf * through pci busops when child node calls ddi_fm_init.
8fca05700b4a8225bddecd0ca5028f512f483b36jf */
8fca05700b4a8225bddecd0ca5028f512f483b36jf/*ARGSUSED*/
8fca05700b4a8225bddecd0ca5028f512f483b36jfint
8fca05700b4a8225bddecd0ca5028f512f483b36jfniumx_fm_init_child(dev_info_t *dip, dev_info_t *cdip, int cap,
8fca05700b4a8225bddecd0ca5028f512f483b36jf ddi_iblock_cookie_t *ibc_p)
8fca05700b4a8225bddecd0ca5028f512f483b36jf{
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumx_devstate_t *niumxds_p = NIUMX_DIP_TO_STATE(dip);
8fca05700b4a8225bddecd0ca5028f512f483b36jf
8fca05700b4a8225bddecd0ca5028f512f483b36jf ASSERT(ibc_p != NULL);
8fca05700b4a8225bddecd0ca5028f512f483b36jf *ibc_p = niumxds_p->niumx_fm_ibc;
8fca05700b4a8225bddecd0ca5028f512f483b36jf
8fca05700b4a8225bddecd0ca5028f512f483b36jf return (niumxds_p->niumx_fm_cap);
8fca05700b4a8225bddecd0ca5028f512f483b36jf}
8fca05700b4a8225bddecd0ca5028f512f483b36jf
8fca05700b4a8225bddecd0ca5028f512f483b36jf
4496171313bed39e96f21bc2f9faf2868e267ae3girish/*ARGSUSED*/
4496171313bed39e96f21bc2f9faf2868e267ae3girishint
4496171313bed39e96f21bc2f9faf2868e267ae3girishniumx_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
4496171313bed39e96f21bc2f9faf2868e267ae3girish off_t offset, off_t len, caddr_t *vaddrp)
4496171313bed39e96f21bc2f9faf2868e267ae3girish{
4496171313bed39e96f21bc2f9faf2868e267ae3girish struct regspec p_regspec;
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_map_req_t p_mapreq;
4496171313bed39e96f21bc2f9faf2868e267ae3girish niu_regspec_t *reg_p;
4496171313bed39e96f21bc2f9faf2868e267ae3girish int i, rn = mp->map_obj.rnumber, reglen, rnglen, rngnum, ret;
4496171313bed39e96f21bc2f9faf2868e267ae3girish niumx_ranges_t *rng_p;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish uint32_t reg_begin, rng_begin;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_MAP, dip, "%s%d: mapping %s%d reg %d\n",
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD NIUMX_NAMEINST(dip), NIUMX_NAMEINST(rdip), rn);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (ddi_getlongprop(DDI_DEV_T_ANY, rdip, DDI_PROP_DONTPASS,
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf "reg", (caddr_t)&reg_p, &reglen) != DDI_SUCCESS)
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (DDI_FAILURE);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (rn < 0 || (rn >= reglen / sizeof (niu_regspec_t))) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_MAP, dip, "rnumber out of range: %d\n", rn);
4496171313bed39e96f21bc2f9faf2868e267ae3girish kmem_free(reg_p, reglen);
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (DDI_ME_RNUMBER_RANGE);
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* build regspec up for parent */
4496171313bed39e96f21bc2f9faf2868e267ae3girish p_mapreq = *mp; /* dup the whole structure */
4496171313bed39e96f21bc2f9faf2868e267ae3girish p_mapreq.map_type = DDI_MT_REGSPEC;
4496171313bed39e96f21bc2f9faf2868e267ae3girish p_mapreq.map_obj.rp = &p_regspec;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "ranges",
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf (caddr_t)&rng_p, &rnglen) != DDI_SUCCESS) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_MAP, dip, "%s%d: no ranges property\n",
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf ddi_driver_name(dip), ddi_get_instance(dip));
4496171313bed39e96f21bc2f9faf2868e267ae3girish kmem_free(reg_p, reglen);
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (DDI_FAILURE);
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* locate matching ranges record */
4496171313bed39e96f21bc2f9faf2868e267ae3girish rngnum = rnglen / sizeof (niumx_ranges_t);
4496171313bed39e96f21bc2f9faf2868e267ae3girish for (i = 0, reg_p += rn; i < rngnum; rng_p++, i++) {
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (reg_p->addr_high == rng_p->child_hi)
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (i >= rngnum) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_MAP, dip, "ranges record for reg[%d] "
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD "not found.\n", rn);
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = DDI_ME_REGSPEC_RANGE;
4496171313bed39e96f21bc2f9faf2868e267ae3girish goto err;
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish /*
4496171313bed39e96f21bc2f9faf2868e267ae3girish * validate request has matching bus type and within 4G
4496171313bed39e96f21bc2f9faf2868e267ae3girish * limit by comparing addr.hi of "ranges" and child "reg".
4496171313bed39e96f21bc2f9faf2868e267ae3girish */
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish ASSERT(reg_p->size_high == 0);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish rng_begin = rng_p->child_lo;
4496171313bed39e96f21bc2f9faf2868e267ae3girish reg_begin = reg_p->addr_low;
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* check to verify reg bounds are within rng bounds */
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (reg_begin < rng_begin || (reg_begin + (reg_p->size_low - 1)) >
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf (rng_begin + (rng_p->size_lo - 1))) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_MAP, dip, "size out of range for reg[%d].\n", rn);
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = DDI_ME_REGSPEC_RANGE;
4496171313bed39e96f21bc2f9faf2868e267ae3girish goto err;
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish p_regspec.regspec_bustype = rng_p->parent_hi;
4496171313bed39e96f21bc2f9faf2868e267ae3girish p_regspec.regspec_addr = reg_begin - rng_begin + rng_p->parent_lo;
4496171313bed39e96f21bc2f9faf2868e267ae3girish p_regspec.regspec_size = reg_p->size_low;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_MAP, dip, "regspec:bus,addr,size = (%x,%x,%x)\n",
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf p_regspec.regspec_bustype, p_regspec.regspec_addr,
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf p_regspec.regspec_size);
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = ddi_map(dip, &p_mapreq, 0, 0, vaddrp);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_MAP, dip, "niumx_map: ret %d.\n", ret);
4496171313bed39e96f21bc2f9faf2868e267ae3girisherr:
4496171313bed39e96f21bc2f9faf2868e267ae3girish kmem_free(rng_p - i, rnglen);
4496171313bed39e96f21bc2f9faf2868e267ae3girish kmem_free(reg_p - rn, reglen);
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (ret);
4496171313bed39e96f21bc2f9faf2868e267ae3girish}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish/*
4496171313bed39e96f21bc2f9faf2868e267ae3girish * niumx_ctlops
4496171313bed39e96f21bc2f9faf2868e267ae3girish */
4496171313bed39e96f21bc2f9faf2868e267ae3girishint
4496171313bed39e96f21bc2f9faf2868e267ae3girishniumx_ctlops(dev_info_t *dip, dev_info_t *rdip,
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_ctl_enum_t ctlop, void *arg, void *result)
4496171313bed39e96f21bc2f9faf2868e267ae3girish{
4496171313bed39e96f21bc2f9faf2868e267ae3girish niu_regspec_t *reg_p;
4496171313bed39e96f21bc2f9faf2868e267ae3girish int reglen, totreg;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_CTLOPS, dip, "niumx_ctlops ctlop=%d.\n", ctlop);
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (rdip == (dev_info_t *)0)
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (DDI_FAILURE);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish switch (ctlop) {
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_CTLOPS_REPORTDEV:
4496171313bed39e96f21bc2f9faf2868e267ae3girish cmn_err(CE_NOTE, "device: %s@%s, %s%d\n",
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_node_name(rdip), ddi_get_name_addr(rdip),
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD NIUMX_NAMEINST(rdip));
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (DDI_SUCCESS);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_CTLOPS_INITCHILD:
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (niumx_initchild((dev_info_t *)arg));
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_CTLOPS_UNINITCHILD:
4496171313bed39e96f21bc2f9faf2868e267ae3girish niumx_removechild((dev_info_t *)arg);
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (DDI_SUCCESS);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_CTLOPS_REGSIZE:
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_CTLOPS_NREGS:
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* fall through */
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish default:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_CTLOPS, dip, "just pass to ddi_cltops.\n");
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (ddi_ctlops(dip, rdip, ctlop, arg, result));
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* REGSIZE/NREGS */
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish *(int *)result = 0;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (ddi_getlongprop(DDI_DEV_T_NONE, rdip, DDI_PROP_DONTPASS |
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf DDI_PROP_CANSLEEP, "reg", (caddr_t)&reg_p, &reglen) != DDI_SUCCESS)
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (DDI_FAILURE);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish totreg = reglen / sizeof (niu_regspec_t);
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (ctlop == DDI_CTLOPS_NREGS) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_CTLOPS, (dev_info_t *)dip,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD "niumx_ctlops NREGS=%d.\n", totreg);
4496171313bed39e96f21bc2f9faf2868e267ae3girish *(int *)result = totreg;
4496171313bed39e96f21bc2f9faf2868e267ae3girish } else if (ctlop == DDI_CTLOPS_REGSIZE) {
4496171313bed39e96f21bc2f9faf2868e267ae3girish int rn;
4496171313bed39e96f21bc2f9faf2868e267ae3girish rn = *(int *)arg;
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (rn >= totreg) {
4496171313bed39e96f21bc2f9faf2868e267ae3girish kmem_free(reg_p, reglen);
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (DDI_FAILURE);
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish *(off_t *)result = (reg_p + rn)->size_low;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_CTLOPS, (dev_info_t *)dip,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD "rn = %d, REGSIZE=%x.\n", rn, *(off_t *)result);
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish kmem_free(reg_p, reglen);
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (DDI_SUCCESS);
4496171313bed39e96f21bc2f9faf2868e267ae3girish}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf/*
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf * niumx_name_child
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf *
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf * This function is called from init_child to name a node. It is
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf * also passed as a callback for node merging functions.
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf *
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf * return value: DDI_SUCCESS, DDI_FAILURE
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf */
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic int
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjfniumx_name_child(dev_info_t *child, char *name, int namelen)
4496171313bed39e96f21bc2f9faf2868e267ae3girish{
4496171313bed39e96f21bc2f9faf2868e267ae3girish niu_regspec_t *r;
4496171313bed39e96f21bc2f9faf2868e267ae3girish uint_t n;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_CHK_MOD, (dev_info_t *)child, "==> niumx_name_child\n");
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf if (ndi_dev_is_persistent_node(child) == 0) {
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf char **unit_addr;
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf /* name .conf nodes by "unit-address" property */
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, child,
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf DDI_PROP_DONTPASS, "unit-address", &unit_addr, &n) !=
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf DDI_PROP_SUCCESS) {
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf cmn_err(CE_WARN, "cannot name node from %s.conf",
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf ddi_driver_name(child));
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf return (DDI_FAILURE);
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf }
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf if (n != 1 || *unit_addr == NULL || **unit_addr == 0) {
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf cmn_err(CE_WARN, "unit-address property in %s.conf"
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf " not well-formed", ddi_driver_name(child));
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf ddi_prop_free(unit_addr);
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf return (DDI_FAILURE);
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf }
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf (void) snprintf(name, namelen, "%s", *unit_addr);
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf ddi_prop_free(unit_addr);
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf return (DDI_SUCCESS);
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf }
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf /* name hardware nodes by "reg" property */
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
4496171313bed39e96f21bc2f9faf2868e267ae3girish "reg", (int **)&r, &n) != DDI_SUCCESS) {
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf cmn_err(CE_WARN, "reg property not well-formed");
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (DDI_FAILURE);
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
678453a8ed49104d8adad58f3ba591bdc39883e8speer (void) snprintf(name, namelen, "%x", (r[0].addr_high));
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_prop_free(r);
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf return (DDI_SUCCESS);
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf}
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjfstatic int
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjfniumx_initchild(dev_info_t *child)
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf{
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf char name[MAXNAMELEN];
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_CHK_MOD, (dev_info_t *)child, "==> niumx_initchild\n");
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf /*
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf * Non-peristent nodes indicate a prototype node with per-instance
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf * properties to be merged into the real h/w device node.
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf */
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf if (ndi_dev_is_persistent_node(child) == 0) {
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf niu_regspec_t *r;
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf uint_t n;
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, child,
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf DDI_PROP_DONTPASS, "reg", (int **)&r, &n) ==
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf DDI_SUCCESS) {
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf cmn_err(CE_WARN,
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf "cannot merge prototype from %s.conf",
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf ddi_driver_name(child));
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf ddi_prop_free(r);
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf return (DDI_NOT_WELL_FORMED);
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf }
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf if (niumx_name_child(child, name, MAXNAMELEN) != DDI_SUCCESS)
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf return (DDI_NOT_WELL_FORMED);
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf ddi_set_name_addr(child, name);
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf ddi_set_parent_data(child, NULL);
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf /*
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf * Try to merge the properties from this prototype
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf * node into real h/w nodes.
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf */
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf if (ndi_merge_node(child, niumx_name_child) == DDI_SUCCESS) {
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf /*
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf * Merged ok - return failure to remove the node.
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf */
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf ddi_set_name_addr(child, NULL);
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf return (DDI_FAILURE);
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf }
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf /*
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf * The child was not merged into a h/w node,
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf * but there's not much we can do with it other
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf * than return failure to cause the node to be removed.
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf */
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf cmn_err(CE_WARN, "!%s@%s: %s.conf properties not merged",
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf ddi_driver_name(child), ddi_get_name_addr(child),
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf ddi_driver_name(child));
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf ddi_set_name_addr(child, NULL);
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf return (DDI_NOT_WELL_FORMED);
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf }
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf /*
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf * Initialize real h/w nodes
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf */
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf if (niumx_name_child(child, name, MAXNAMELEN) != DDI_SUCCESS)
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf return (DDI_FAILURE);
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_set_name_addr(child, name);
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (DDI_SUCCESS);
4496171313bed39e96f21bc2f9faf2868e267ae3girish}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic void
4496171313bed39e96f21bc2f9faf2868e267ae3girishniumx_removechild(dev_info_t *dip)
4496171313bed39e96f21bc2f9faf2868e267ae3girish{
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_set_name_addr(dip, NULL);
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_remove_minor_node(dip, NULL);
4496171313bed39e96f21bc2f9faf2868e267ae3girish impl_rem_dev_props(dip);
4496171313bed39e96f21bc2f9faf2868e267ae3girish}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish/*
4496171313bed39e96f21bc2f9faf2868e267ae3girish * bus dma alloc handle entry point:
4496171313bed39e96f21bc2f9faf2868e267ae3girish */
4496171313bed39e96f21bc2f9faf2868e267ae3girish/*ARGSUSED*/
4496171313bed39e96f21bc2f9faf2868e267ae3girishint
4496171313bed39e96f21bc2f9faf2868e267ae3girishniumx_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_attr_t *attrp,
4496171313bed39e96f21bc2f9faf2868e267ae3girish int (*waitfp)(caddr_t), caddr_t arg, ddi_dma_handle_t *handlep)
4496171313bed39e96f21bc2f9faf2868e267ae3girish{
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_dma_impl_t *mp;
4496171313bed39e96f21bc2f9faf2868e267ae3girish int sleep = (waitfp == DDI_DMA_SLEEP) ? KM_SLEEP : KM_NOSLEEP;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_DMA_ALLOCH, dip, "rdip=%s%d\n", NIUMX_NAMEINST(rdip));
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (attrp->dma_attr_version != DMA_ATTR_V0) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_DMA_ALLOCH,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD (dev_info_t *)dip, "DDI_DMA_BADATTR\n");
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (DDI_DMA_BADATTR);
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* Caution: we don't use zalloc to enhance performance! */
4496171313bed39e96f21bc2f9faf2868e267ae3girish if ((mp = kmem_alloc(sizeof (ddi_dma_impl_t), sleep)) == 0) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_DMA_ALLOCH, dip, "can't alloc ddi_dma_impl_t\n");
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (DDI_FAILURE);
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish mp->dmai_rdip = rdip;
4496171313bed39e96f21bc2f9faf2868e267ae3girish mp->dmai_pfnlst = NULL;
4496171313bed39e96f21bc2f9faf2868e267ae3girish mp->dmai_cookie = NULL;
4496171313bed39e96f21bc2f9faf2868e267ae3girish mp->dmai_fault = 0;
4496171313bed39e96f21bc2f9faf2868e267ae3girish mp->dmai_fault_check = NULL;
4496171313bed39e96f21bc2f9faf2868e267ae3girish mp->dmai_fault_notify = NULL;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish mp->dmai_attr = *attrp; /* set requestors attr info */
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_DMA_ALLOCH, dip, "mp=%p\n", mp);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish *handlep = (ddi_dma_handle_t)mp;
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (DDI_SUCCESS);
4496171313bed39e96f21bc2f9faf2868e267ae3girish}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish/*
4496171313bed39e96f21bc2f9faf2868e267ae3girish * bus dma free handle entry point:
4496171313bed39e96f21bc2f9faf2868e267ae3girish */
4496171313bed39e96f21bc2f9faf2868e267ae3girish/*ARGSUSED*/
4496171313bed39e96f21bc2f9faf2868e267ae3girishint
4496171313bed39e96f21bc2f9faf2868e267ae3girishniumx_dma_freehdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_handle_t handle)
4496171313bed39e96f21bc2f9faf2868e267ae3girish{
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_dma_impl_t *mp = (ddi_dma_impl_t *)handle;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (mp->dmai_cookie)
4496171313bed39e96f21bc2f9faf2868e267ae3girish kmem_free(mp->dmai_cookie, sizeof (ddi_dma_cookie_t));
4496171313bed39e96f21bc2f9faf2868e267ae3girish kmem_free(mp, sizeof (ddi_dma_impl_t));
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (DDI_SUCCESS);
4496171313bed39e96f21bc2f9faf2868e267ae3girish}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish/*
4496171313bed39e96f21bc2f9faf2868e267ae3girish * bus dma bind handle entry point:
4496171313bed39e96f21bc2f9faf2868e267ae3girish *
4496171313bed39e96f21bc2f9faf2868e267ae3girish * check/enforce DMA type, setup pfn0 and some other key pieces
4496171313bed39e96f21bc2f9faf2868e267ae3girish * of this dma request.
4496171313bed39e96f21bc2f9faf2868e267ae3girish * Note: this only works with DMA_OTYP_VADDR, and makes use of the known
4496171313bed39e96f21bc2f9faf2868e267ae3girish * fact that only contiguous memory blocks will be passed in.
4496171313bed39e96f21bc2f9faf2868e267ae3girish * Therefore only one cookie will ever be returned.
4496171313bed39e96f21bc2f9faf2868e267ae3girish *
4496171313bed39e96f21bc2f9faf2868e267ae3girish * return values:
4496171313bed39e96f21bc2f9faf2868e267ae3girish * DDI_DMA_NOMAPPING - can't get valid pfn0, or bad dma type
4496171313bed39e96f21bc2f9faf2868e267ae3girish * DDI_DMA_NORESOURCES
4496171313bed39e96f21bc2f9faf2868e267ae3girish * DDI_SUCCESS
4496171313bed39e96f21bc2f9faf2868e267ae3girish *
4496171313bed39e96f21bc2f9faf2868e267ae3girish * dma handle members affected (set on exit):
4496171313bed39e96f21bc2f9faf2868e267ae3girish * mp->dmai_object - dmareq->dmar_object
4496171313bed39e96f21bc2f9faf2868e267ae3girish * mp->dmai_rflags - dmareq->dmar_flags
4496171313bed39e96f21bc2f9faf2868e267ae3girish * mp->dmai_pfn0 - 1st page pfn (if va/size pair and not shadow)
4496171313bed39e96f21bc2f9faf2868e267ae3girish * mp->dmai_roffset - initialized to starting page offset
4496171313bed39e96f21bc2f9faf2868e267ae3girish * mp->dmai_size - # of total pages of entire object
4496171313bed39e96f21bc2f9faf2868e267ae3girish * mp->dmai_cookie - new cookie alloc'd
4496171313bed39e96f21bc2f9faf2868e267ae3girish */
4496171313bed39e96f21bc2f9faf2868e267ae3girish/*ARGSUSED*/
4496171313bed39e96f21bc2f9faf2868e267ae3girishint
4496171313bed39e96f21bc2f9faf2868e267ae3girishniumx_dma_bindhdl(dev_info_t *dip, dev_info_t *rdip,
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_dma_handle_t handle, ddi_dma_req_t *dmareq,
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_dma_cookie_t *cookiep, uint_t *ccountp)
4496171313bed39e96f21bc2f9faf2868e267ae3girish{
4496171313bed39e96f21bc2f9faf2868e267ae3girish int (*waitfp)(caddr_t) = dmareq->dmar_fp;
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_dma_impl_t *mp = (ddi_dma_impl_t *)handle;
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_dma_obj_t *dobj_p = &dmareq->dmar_object;
4496171313bed39e96f21bc2f9faf2868e267ae3girish uint32_t offset;
4496171313bed39e96f21bc2f9faf2868e267ae3girish pfn_t pfn0;
4496171313bed39e96f21bc2f9faf2868e267ae3girish int ret;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_DMA_BINDH, dip, "rdip=%s%d mp=%p dmareq=%p\n",
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD NIUMX_NAMEINST(rdip), mp, dmareq);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* first check dma type */
4496171313bed39e96f21bc2f9faf2868e267ae3girish mp->dmai_rflags = dmareq->dmar_flags & DMP_DDIFLAGS | DMP_NOSYNC;
4496171313bed39e96f21bc2f9faf2868e267ae3girish switch (dobj_p->dmao_type) {
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DMA_OTYP_VADDR: {
4496171313bed39e96f21bc2f9faf2868e267ae3girish caddr_t vaddr = dobj_p->dmao_obj.virt_obj.v_addr;
4496171313bed39e96f21bc2f9faf2868e267ae3girish struct as *as_p = dobj_p->dmao_obj.virt_obj.v_as;
4496171313bed39e96f21bc2f9faf2868e267ae3girish struct hat *hat_p = as_p ? as_p->a_hat : kas.a_hat;
4496171313bed39e96f21bc2f9faf2868e267ae3girish offset = (ulong_t)vaddr & NIUMX_PAGE_OFFSET;
4496171313bed39e96f21bc2f9faf2868e267ae3girish pfn0 = hat_getpfnum(hat_p, vaddr);
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DMA_OTYP_BUFVADDR:
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DMA_OTYP_PAGES:
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DMA_OTYP_PADDR:
4496171313bed39e96f21bc2f9faf2868e267ae3girish default:
4496171313bed39e96f21bc2f9faf2868e267ae3girish cmn_err(CE_WARN, "%s%d requested unsupported dma type %x",
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD NIUMX_NAMEINST(mp->dmai_rdip), dobj_p->dmao_type);
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = DDI_DMA_NOMAPPING;
4496171313bed39e96f21bc2f9faf2868e267ae3girish goto err;
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (pfn0 == PFN_INVALID) {
4496171313bed39e96f21bc2f9faf2868e267ae3girish cmn_err(CE_WARN, "%s%d: invalid pfn0 for DMA object %p",
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD NIUMX_NAMEINST(dip), (void *)dobj_p);
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = DDI_DMA_NOMAPPING;
4496171313bed39e96f21bc2f9faf2868e267ae3girish goto err;
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish mp->dmai_object = *dobj_p; /* whole object */
4496171313bed39e96f21bc2f9faf2868e267ae3girish mp->dmai_pfn0 = (void *)pfn0; /* cache pfn0 */
4496171313bed39e96f21bc2f9faf2868e267ae3girish mp->dmai_roffset = offset; /* pg0 offset */
4496171313bed39e96f21bc2f9faf2868e267ae3girish mp->dmai_mapping = mp->dmai_roffset | NIUMX_PTOB(pfn0);
4496171313bed39e96f21bc2f9faf2868e267ae3girish mp->dmai_size = mp->dmai_object.dmao_size;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_DMA_BINDH, dip, "check pfn: mp=%p pfn0=%x\n",
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf mp, mp->dmai_pfn0);
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (!(mp->dmai_cookie = kmem_zalloc(sizeof (ddi_dma_cookie_t),
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf waitfp == DDI_DMA_SLEEP ? KM_SLEEP : KM_NOSLEEP))) {
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = DDI_DMA_NORESOURCES;
4496171313bed39e96f21bc2f9faf2868e267ae3girish goto err;
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish mp->dmai_cookie->dmac_laddress = mp->dmai_mapping;
4496171313bed39e96f21bc2f9faf2868e267ae3girish mp->dmai_cookie->dmac_size = mp->dmai_size;
4496171313bed39e96f21bc2f9faf2868e267ae3girish *ccountp = 1;
4496171313bed39e96f21bc2f9faf2868e267ae3girish *cookiep = *mp->dmai_cookie;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_DMA_BINDH, dip, "cookie %" PRIx64 "+%x, count=%d\n",
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf cookiep->dmac_address, cookiep->dmac_size, *ccountp);
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (DDI_DMA_MAPPED);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girisherr:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_DMA_BINDH, (dev_info_t *)dip,
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf "niumx_dma_bindhdl error ret=%d\n", ret);
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (ret);
4496171313bed39e96f21bc2f9faf2868e267ae3girish}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish/*
4496171313bed39e96f21bc2f9faf2868e267ae3girish * bus dma unbind handle entry point:
4496171313bed39e96f21bc2f9faf2868e267ae3girish */
4496171313bed39e96f21bc2f9faf2868e267ae3girish/*ARGSUSED*/
4496171313bed39e96f21bc2f9faf2868e267ae3girishint
4496171313bed39e96f21bc2f9faf2868e267ae3girishniumx_dma_unbindhdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_handle_t handle)
4496171313bed39e96f21bc2f9faf2868e267ae3girish{
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_dma_impl_t *mp = (ddi_dma_impl_t *)handle;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_DMA_UNBINDH, dip, "rdip=%s%d, mp=%p\n",
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf ddi_driver_name(rdip), ddi_get_instance(rdip), handle);
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (mp->dmai_cookie) {
4496171313bed39e96f21bc2f9faf2868e267ae3girish kmem_free(mp->dmai_cookie, sizeof (ddi_dma_cookie_t));
4496171313bed39e96f21bc2f9faf2868e267ae3girish mp->dmai_cookie = NULL;
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (DDI_SUCCESS);
4496171313bed39e96f21bc2f9faf2868e267ae3girish}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish/*ARGSUSED*/
4496171313bed39e96f21bc2f9faf2868e267ae3girishint
4496171313bed39e96f21bc2f9faf2868e267ae3girishniumx_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op,
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_intr_handle_impl_t *hdlp, void *result)
4496171313bed39e96f21bc2f9faf2868e267ae3girish{
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish int ret = DDI_SUCCESS;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_INTROPS, dip, "niumx_intr_ops: dip=%p rdip=%p intr_op=%x "
4496171313bed39e96f21bc2f9faf2868e267ae3girish "handle=%p\n", dip, rdip, intr_op, hdlp);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish switch (intr_op) {
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_INTROP_SUPPORTED_TYPES:
4496171313bed39e96f21bc2f9faf2868e267ae3girish *(int *)result = DDI_INTR_TYPE_FIXED;
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_INTROP_GETCAP:
657f87de670449e1422db4f51fb2880a7cb69d5agongtian zhao - Sun Microsystems - Beijing China *(int *)result = DDI_INTR_FLAG_LEVEL;
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_INTROP_SETCAP:
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = DDI_ENOTSUP;
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_INTROP_ALLOC:
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* scratch1 = count, # of intrs from DDI framework */
4496171313bed39e96f21bc2f9faf2868e267ae3girish *(int *)result = hdlp->ih_scratch1;
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_INTROP_FREE:
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* Do we need to do anything here? */
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_INTROP_GETPRI:
4496171313bed39e96f21bc2f9faf2868e267ae3girish *(int *)result = NIUMX_DEFAULT_PIL;
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_INTROP_SETPRI:
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = DDI_ENOTSUP;
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_INTROP_ADDISR:
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = niumx_add_intr(dip, rdip, hdlp);
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_INTROP_REMISR:
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = niumx_rem_intr(dip, rdip, hdlp);
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_INTROP_ENABLE:
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = niumx_set_intr(dip, rdip, hdlp, HV_INTR_VALID);
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_INTROP_DISABLE:
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = niumx_set_intr(dip, rdip, hdlp, HV_INTR_NOTVALID);
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_INTROP_SETMASK:
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = DDI_ENOTSUP;
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_INTROP_CLRMASK:
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = DDI_ENOTSUP;
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_INTROP_GETPENDING:
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = DDI_ENOTSUP;
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_INTROP_NINTRS:
4496171313bed39e96f21bc2f9faf2868e267ae3girish case DDI_INTROP_NAVAIL: {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niudevino_t *inos_p;
4496171313bed39e96f21bc2f9faf2868e267ae3girish int inoslen;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (ddi_getlongprop(DDI_DEV_T_ANY, rdip, DDI_PROP_DONTPASS,
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf "interrupts", (caddr_t)&inos_p, &inoslen)
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf != DDI_SUCCESS) {
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf ret = DDI_FAILURE;
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish *(int *)result = inoslen / sizeof (uint32_t);
4496171313bed39e96f21bc2f9faf2868e267ae3girish kmem_free(inos_p, inoslen);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD break;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD case DDI_INTROP_GETTARGET: {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumx_devstate_t *niumxds_p;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumxds_p = (niumx_devstate_t *)ddi_get_soft_state(niumx_state,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ddi_get_instance(dip));
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ret = niumx_get_intr_target(niumxds_p, hdlp->ih_vector,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD (niucpuid_t *)result);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD break;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD case DDI_INTROP_SETTARGET: {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumx_devstate_t *niumxds_p;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumxds_p = (niumx_devstate_t *)ddi_get_soft_state(niumx_state,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ddi_get_instance(dip));
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ret = niumx_set_intr_target(niumxds_p, hdlp->ih_vector,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD *(niucpuid_t *)result);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish default:
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = DDI_ENOTSUP;
4496171313bed39e96f21bc2f9faf2868e267ae3girish break;
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_INTROPS, dip, "niumx_intr_ops: ret=%d\n", ret);
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (ret);
4496171313bed39e96f21bc2f9faf2868e267ae3girish}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girishint
4496171313bed39e96f21bc2f9faf2868e267ae3girishniumx_set_intr(dev_info_t *dip, dev_info_t *rdip,
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_intr_handle_impl_t *hdlp, int valid)
4496171313bed39e96f21bc2f9faf2868e267ae3girish{
4496171313bed39e96f21bc2f9faf2868e267ae3girish niumx_ih_t *ih_p;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD int ret = DDI_SUCCESS;
4496171313bed39e96f21bc2f9faf2868e267ae3girish uint64_t hvret;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu niumx_devstate_t *niumxds_p; /* devstate pointer */
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu int instance = ddi_get_instance(dip);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu niumxds_p = (niumx_devstate_t *)ddi_get_soft_state(niumx_state,
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu instance);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish ASSERT(hdlp->ih_inum < NIUMX_MAX_INTRS);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ih_p = niumxds_p->niumx_ihtable + hdlp->ih_vector;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_A_INTX, dip,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD "niumx_set_intr: rdip=%s%d, valid=%d %s (%x,%x)\n",
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD NIUMX_NAMEINST(rdip), valid, valid ? "enabling" : "disabling",
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf ih_p->ih_inum, ih_p->ih_sysino);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
cb343a2e20368d059fdcf8755367f43e747266f2speer if (valid == HV_INTR_VALID)
cb343a2e20368d059fdcf8755367f43e747266f2speer (void) hvio_intr_setstate(ih_p->ih_sysino, HV_INTR_IDLE_STATE);
4496171313bed39e96f21bc2f9faf2868e267ae3girish if ((hvret = hvio_intr_setvalid(ih_p->ih_sysino, valid))
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf != H_EOK) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_A_INTX, dip,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD "hvio_intr_setvalid failed, ret 0x%x\n", hvret);
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = DDI_FAILURE;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD } else
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ih_p->ih_state = valid;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (ret);
4496171313bed39e96f21bc2f9faf2868e267ae3girish}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDint
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDniumx_get_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 OSSD niumx_ih_t *ih_p;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niusysino_t sysino;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD int rval = DDI_SUCCESS;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ih_p = niumxds_p->niumx_ihtable + ino;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD sysino = ih_p->ih_sysino;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (sysino == 0) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = EINVAL;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD goto done;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (hvio_intr_gettarget(sysino, cpu_id) != H_EOK) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = EINVAL;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD goto done;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (ih_p->ih_cpuid != *cpu_id)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD rval = EIO;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDdone:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (rval);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD}
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDint
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDniumx_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 OSSD dev_info_t *dip = niumxds_p->dip;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niumx_ih_t *ih_p;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niucpuid_t old_cpu_id;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niusysino_t sysino;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD int ret = DDI_SUCCESS;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD int state;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD hrtime_t start;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD extern const int _ncpu;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD extern cpu_t *cpu[];
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD mutex_enter(&cpu_lock);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ih_p = niumxds_p->niumx_ihtable + ino;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD sysino = ih_p->ih_sysino;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (sysino == 0) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ret = EINVAL;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD goto done;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (hvio_intr_gettarget(sysino, &old_cpu_id) != H_EOK) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ret = EINVAL;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD goto done;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if ((cpu_id < _ncpu) && (cpu[cpu_id] && cpu_is_online(cpu[cpu_id]))) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (cpu_id == old_cpu_id)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD goto done;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD /* check for pending interrupts, busy wait if so */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD for (start = gethrtime(); !panicstr &&
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD (hvio_intr_getstate(sysino, &state) == H_EOK) &&
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD (state == HV_INTR_DELIVERED_STATE); /* */) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (gethrtime() - start > niumx_intr_timeout) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD cmn_err(CE_WARN, "%s%d: niumx_intr_dist: "
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD "pending interrupt (%x,%lx) timedout\n",
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ddi_driver_name(dip), ddi_get_instance(dip),
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ih_p->ih_inum, sysino);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD (void) hvio_intr_setstate(sysino,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD HV_INTR_IDLE_STATE);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD break;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD (void) hvio_intr_settarget(sysino, cpu_id);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if (ih_p->ih_state == HV_INTR_VALID)
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD (void) hvio_intr_setvalid(sysino, HV_INTR_VALID);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD else
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD (void) hvio_intr_setvalid(sysino, HV_INTR_NOTVALID);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ih_p->ih_cpuid = cpu_id;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD } else {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ret = DDI_EINVAL;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDdone:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD mutex_exit(&cpu_lock);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD return (ret);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish/*
4496171313bed39e96f21bc2f9faf2868e267ae3girish * niumx_add_intr:
4496171313bed39e96f21bc2f9faf2868e267ae3girish *
e778ae4497a8de30b58b85bd187bf4ef4ba8cd47Raghuram Kothakota * This function is called to register interrupts.
4496171313bed39e96f21bc2f9faf2868e267ae3girish */
4496171313bed39e96f21bc2f9faf2868e267ae3girishint
4496171313bed39e96f21bc2f9faf2868e267ae3girishniumx_add_intr(dev_info_t *dip, dev_info_t *rdip,
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_intr_handle_impl_t *hdlp)
4496171313bed39e96f21bc2f9faf2868e267ae3girish{
4496171313bed39e96f21bc2f9faf2868e267ae3girish niumx_ih_t *ih_p;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD int ret = DDI_SUCCESS;
4496171313bed39e96f21bc2f9faf2868e267ae3girish uint64_t hvret;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niusysino_t sysino;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu niumx_devstate_t *niumxds_p; /* devstate pointer */
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu int instance = ddi_get_instance(dip);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu niumxds_p = (niumx_devstate_t *)ddi_get_soft_state(niumx_state,
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu instance);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* get new ino */
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (hdlp->ih_inum >= NIUMX_MAX_INTRS) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_INTR, dip, "error: inum %d out of range\n",
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf hdlp->ih_inum);
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = DDI_FAILURE;
4496171313bed39e96f21bc2f9faf2868e267ae3girish goto done;
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ih_p = niumxds_p->niumx_ihtable + hdlp->ih_vector;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD if ((hvret = hvio_intr_devino_to_sysino(NIUMX_DIP_TO_HANDLE(dip),
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD hdlp->ih_vector, &sysino)) != H_EOK) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_INTR, dip, "hvio_intr_devino_to_sysino failed, "
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf "ret 0x%x\n", hvret);
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = DDI_FAILURE;
4496171313bed39e96f21bc2f9faf2868e267ae3girish goto done;
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish ih_p->ih_sysino = sysino;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ih_p->ih_dip = rdip;
4496171313bed39e96f21bc2f9faf2868e267ae3girish ih_p->ih_inum = hdlp->ih_inum;
4496171313bed39e96f21bc2f9faf2868e267ae3girish ih_p->ih_hdlr = hdlp->ih_cb_func;
4496171313bed39e96f21bc2f9faf2868e267ae3girish ih_p->ih_arg1 = hdlp->ih_cb_arg1;
4496171313bed39e96f21bc2f9faf2868e267ae3girish ih_p->ih_arg2 = hdlp->ih_cb_arg2;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_A_INTX, dip, "niumx_add_intr: rdip=%s%d inum=0x%x "
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD "handler=%p arg1=%p arg2=%p, new ih_p = %p\n", NIUMX_NAMEINST(rdip),
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf hdlp->ih_inum, hdlp->ih_cb_func, hdlp->ih_cb_arg1,
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf hdlp->ih_cb_arg2, ih_p);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (hdlp->ih_pri == 0)
4496171313bed39e96f21bc2f9faf2868e267ae3girish hdlp->ih_pri = NIUMX_DEFAULT_PIL;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ih_p->ih_pri = hdlp->ih_pri;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_A_INTX, dip, "for ino %x adding (%x,%x)\n",
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD hdlp->ih_vector, ih_p->ih_inum, ih_p->ih_sysino);
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* Save sysino value in hdlp */
4496171313bed39e96f21bc2f9faf2868e267ae3girish hdlp->ih_vector = ih_p->ih_sysino;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* swap in our handler & arg */
4496171313bed39e96f21bc2f9faf2868e267ae3girish DDI_INTR_ASSIGN_HDLR_N_ARGS(hdlp, (ddi_intr_handler_t *)niumx_intr_hdlr,
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf (void *)ih_p, NULL);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = i_ddi_add_ivintr(hdlp);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* Restore orig. interrupt handler & args in handle. */
4496171313bed39e96f21bc2f9faf2868e267ae3girish DDI_INTR_ASSIGN_HDLR_N_ARGS(hdlp, ih_p->ih_hdlr, ih_p->ih_arg1,
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf ih_p->ih_arg2);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (ret != DDI_SUCCESS) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_A_INTX, dip, "i_ddi_add_ivintr error ret=%x\n",
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ret);
4496171313bed39e96f21bc2f9faf2868e267ae3girish goto done;
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* select cpu, saving it for removal */
4496171313bed39e96f21bc2f9faf2868e267ae3girish ih_p->ih_cpuid = intr_dist_cpuid();
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish if ((hvret = hvio_intr_settarget(ih_p->ih_sysino, ih_p->ih_cpuid))
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf != H_EOK) {
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_A_INTX, dip,
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD "hvio_intr_settarget failed, ret 0x%x\n", hvret);
4496171313bed39e96f21bc2f9faf2868e267ae3girish ret = DDI_FAILURE;
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girishdone:
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_A_INTX, dip, "done, ret = %d, ih_p 0x%p, hdlp 0x%p\n",
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ih_p, hdlp, ret);
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (ret);
4496171313bed39e96f21bc2f9faf2868e267ae3girish}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish/*
4496171313bed39e96f21bc2f9faf2868e267ae3girish * niumx_rem_intr:
4496171313bed39e96f21bc2f9faf2868e267ae3girish *
4496171313bed39e96f21bc2f9faf2868e267ae3girish * This function is called to unregister interrupts.
4496171313bed39e96f21bc2f9faf2868e267ae3girish */
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD/*ARGSUSED*/
4496171313bed39e96f21bc2f9faf2868e267ae3girishint
4496171313bed39e96f21bc2f9faf2868e267ae3girishniumx_rem_intr(dev_info_t *dip, dev_info_t *rdip,
4496171313bed39e96f21bc2f9faf2868e267ae3girish ddi_intr_handle_impl_t *hdlp)
4496171313bed39e96f21bc2f9faf2868e267ae3girish{
4496171313bed39e96f21bc2f9faf2868e267ae3girish niumx_ih_t *ih_p;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD int ret = DDI_SUCCESS, state;
c165966d2681754edbe7637da5adf3e53b3f7132jf hrtime_t start;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD niusysino_t sysino;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu niumx_devstate_t *niumxds_p; /* devstate pointer */
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu int instance = ddi_get_instance(dip);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu niumxds_p = (niumx_devstate_t *)ddi_get_soft_state(niumx_state,
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu instance);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish ASSERT(hdlp->ih_inum < NIUMX_MAX_INTRS);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD ih_p = niumxds_p->niumx_ihtable + hdlp->ih_vector;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD
c165966d2681754edbe7637da5adf3e53b3f7132jf sysino = ih_p->ih_sysino;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD DBG(NIUMX_DBG_R_INTX, dip, "removing (%x,%x)\n", ih_p->ih_inum, sysino);
c165966d2681754edbe7637da5adf3e53b3f7132jf
c165966d2681754edbe7637da5adf3e53b3f7132jf (void) hvio_intr_setvalid(sysino, HV_INTR_NOTVALID);
c165966d2681754edbe7637da5adf3e53b3f7132jf
c165966d2681754edbe7637da5adf3e53b3f7132jf /* check for pending interrupts, busy wait if so */
c165966d2681754edbe7637da5adf3e53b3f7132jf for (start = gethrtime(); !panicstr &&
c165966d2681754edbe7637da5adf3e53b3f7132jf (hvio_intr_getstate(sysino, &state) == H_EOK) &&
c165966d2681754edbe7637da5adf3e53b3f7132jf (state == HV_INTR_DELIVERED_STATE); /* */) {
c165966d2681754edbe7637da5adf3e53b3f7132jf if (gethrtime() - start > niumx_intr_timeout) {
c165966d2681754edbe7637da5adf3e53b3f7132jf cmn_err(CE_WARN, "%s%d: niumx_intr_dist: "
c165966d2681754edbe7637da5adf3e53b3f7132jf "pending interrupt (%x,%lx) timedout\n",
c165966d2681754edbe7637da5adf3e53b3f7132jf ddi_driver_name(dip), ddi_get_instance(dip),
c165966d2681754edbe7637da5adf3e53b3f7132jf ih_p->ih_inum, sysino);
c165966d2681754edbe7637da5adf3e53b3f7132jf ret = DDI_FAILURE;
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSD goto fail;
c165966d2681754edbe7637da5adf3e53b3f7132jf }
4496171313bed39e96f21bc2f9faf2868e267ae3girish }
4496171313bed39e96f21bc2f9faf2868e267ae3girish
678453a8ed49104d8adad58f3ba591bdc39883e8speer ih_p->ih_sysino = 0;
678453a8ed49104d8adad58f3ba591bdc39883e8speer
c165966d2681754edbe7637da5adf3e53b3f7132jf hdlp->ih_vector = (uint32_t)sysino;
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (hdlp->ih_vector != NULL) i_ddi_rem_ivintr(hdlp);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
500b1e787b108592a37e3d54dc9b5e676de5386dAlan Adamson, SD OSSDfail:
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (ret);
4496171313bed39e96f21bc2f9faf2868e267ae3girish}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish/*
4496171313bed39e96f21bc2f9faf2868e267ae3girish * niumx_intr_hdlr (our interrupt handler)
4496171313bed39e96f21bc2f9faf2868e267ae3girish */
4496171313bed39e96f21bc2f9faf2868e267ae3girishuint_t
4496171313bed39e96f21bc2f9faf2868e267ae3girishniumx_intr_hdlr(void *arg)
4496171313bed39e96f21bc2f9faf2868e267ae3girish{
4496171313bed39e96f21bc2f9faf2868e267ae3girish niumx_ih_t *ih_p = (niumx_ih_t *)arg;
4496171313bed39e96f21bc2f9faf2868e267ae3girish uint_t r;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish DTRACE_PROBE4(interrupt__start, dev_info_t, ih_p->ih_dip, void *,
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf ih_p->ih_hdlr, caddr_t, ih_p->ih_arg1, caddr_t, ih_p->ih_arg2);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish r = (*ih_p->ih_hdlr)(ih_p->ih_arg1, ih_p->ih_arg2);
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish DTRACE_PROBE4(interrupt__complete, dev_info_t, ih_p->ih_dip, void *,
adf6c93b5d9301a4bf74a4110edfd3ab1f94478bjf ih_p->ih_hdlr, caddr_t, ih_p->ih_arg1, int, r);
cb343a2e20368d059fdcf8755367f43e747266f2speer
cb343a2e20368d059fdcf8755367f43e747266f2speer (void) hvio_intr_setstate(ih_p->ih_sysino, HV_INTR_IDLE_STATE);
4496171313bed39e96f21bc2f9faf2868e267ae3girish return (r);
4496171313bed39e96f21bc2f9faf2868e267ae3girish}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish#ifdef DEBUG
4496171313bed39e96f21bc2f9faf2868e267ae3girishuint64_t niumx_debug_flags = 0;
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girishstatic char *niumx_debug_sym [] = { /* same sequence as niumx_debug_bit */
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* 0 */ "attach",
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* 1 */ "map",
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* 2 */ "nex-ctlops",
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* 3 */ "introps",
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* 4 */ "intr-add",
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* 5 */ "intr-rem",
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* 6 */ "intr",
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* 7 */ "dma-alloc",
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* 8 */ "dma-bind",
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* 9 */ "dma-unbind",
4496171313bed39e96f21bc2f9faf2868e267ae3girish /* 10 */ "chk-dma-mode"
4496171313bed39e96f21bc2f9faf2868e267ae3girish};
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish/*ARGSUSED*/
4496171313bed39e96f21bc2f9faf2868e267ae3girishvoid
4496171313bed39e96f21bc2f9faf2868e267ae3girishniumx_dbg(niumx_debug_bit_t bit, dev_info_t *dip, char *fmt, ...)
4496171313bed39e96f21bc2f9faf2868e267ae3girish{
4496171313bed39e96f21bc2f9faf2868e267ae3girish va_list ap;
4496171313bed39e96f21bc2f9faf2868e267ae3girish char msgbuf[1024];
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (!(1ull << bit & niumx_debug_flags))
4496171313bed39e96f21bc2f9faf2868e267ae3girish return;
4496171313bed39e96f21bc2f9faf2868e267ae3girish va_start(ap, fmt);
4496171313bed39e96f21bc2f9faf2868e267ae3girish (void) vsprintf(msgbuf, fmt, ap);
4496171313bed39e96f21bc2f9faf2868e267ae3girish va_end(ap);
4496171313bed39e96f21bc2f9faf2868e267ae3girish cmn_err(CE_NOTE, "%s: %s", niumx_debug_sym[bit], msgbuf);
4496171313bed39e96f21bc2f9faf2868e267ae3girish}
4496171313bed39e96f21bc2f9faf2868e267ae3girish
4496171313bed39e96f21bc2f9faf2868e267ae3girish#endif /* DEBUG */