49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/*
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Copyright (c) 2008-2016 Solarflare Communications Inc.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * All rights reserved.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Redistribution and use in source and binary forms, with or without
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * modification, are permitted provided that the following conditions are met:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * 1. Redistributions of source code must retain the above copyright notice,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * this list of conditions and the following disclaimer.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * 2. Redistributions in binary form must reproduce the above copyright notice,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * this list of conditions and the following disclaimer in the documentation
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * and/or other materials provided with the distribution.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * The views and conclusions contained in the software and documentation are
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * those of the authors and should not be interpreted as representing official
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * policies, either expressed or implied, of the FreeBSD Project.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include <sys/types.h>
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include <sys/ddi.h>
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include <sys/sunddi.h>
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include <sys/atomic.h>
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include <sys/modctl.h>
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include <sys/conf.h>
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include <sys/ethernet.h>
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include <sys/pci.h>
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include <sys/pcie.h>
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include "sfxge.h"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include "efx.h"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/* Interrupt table DMA attributes */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic ddi_device_acc_attr_t sfxge_intr_devacc = {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DDI_DEVICE_ATTR_V0, /* devacc_attr_version */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DDI_NEVERSWAP_ACC, /* devacc_attr_endian_flags */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DDI_STRICTORDER_ACC /* devacc_attr_dataorder */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore};
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic ddi_dma_attr_t sfxge_intr_dma_attr = {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DMA_ATTR_V0, /* dma_attr_version */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 0, /* dma_attr_addr_lo */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 0xffffffffffffffffull, /* dma_attr_addr_hi */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 0xffffffffffffffffull, /* dma_attr_count_max */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore EFX_INTR_SIZE, /* dma_attr_align */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 0xffffffff, /* dma_attr_burstsizes */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 1, /* dma_attr_minxfer */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 0xffffffffffffffffull, /* dma_attr_maxxfer */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 0xffffffffffffffffull, /* dma_attr_seg */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 1, /* dma_attr_sgllen */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 1, /* dma_attr_granular */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 0 /* dma_attr_flags */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore};
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic unsigned int
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_intr_line(caddr_t arg1, caddr_t arg2)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_t *sp = (void *)arg1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efx_nic_t *enp = sp->s_enp;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_intr_t *sip = &(sp->s_intr);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore unsigned int index;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore boolean_t fatal;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore uint32_t qmask;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int rc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore _NOTE(ARGUNUSED(arg2))
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ASSERT3U(sip->si_type, ==, EFX_INTR_LINE);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (sip->si_state != SFXGE_INTR_STARTED &&
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_state != SFXGE_INTR_TESTING) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = DDI_INTR_UNCLAIMED;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto done;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (sip->si_state == SFXGE_INTR_TESTING) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_mask |= 1; /* only one interrupt */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = DDI_INTR_CLAIMED;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto done;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efx_intr_status_line(enp, &fatal, &qmask);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (fatal) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_intr_fatal(sp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = DDI_INTR_CLAIMED;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto done;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (qmask != 0) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore for (index = 0; index < EFX_INTR_NEVQS; index++) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (qmask & (1 << index))
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (void) sfxge_ev_qpoll(sp, index);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_zero_count = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_gld_rx_push(sp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = DDI_INTR_CLAIMED;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto done;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /*
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * bug15671/bug17203 workaround. Return CLAIMED for the first ISR=0
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * interrupt, and poll all evqs for work. For subsequent ISR=0
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * interrupts (the line must be shared in this case), just rearm the
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * event queues to ensure we don't miss an interrupt.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (sip->si_zero_count++ == 0) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore for (index = 0; index < EFX_INTR_NEVQS; index++) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (sp->s_sep[index] != NULL)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (void) sfxge_ev_qpoll(sp, index);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = DDI_INTR_CLAIMED;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore } else {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore for (index = 0; index < EFX_INTR_NEVQS; index++) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (sp->s_sep[index] != NULL)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (void) sfxge_ev_qprime(sp, index);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = DDI_INTR_UNCLAIMED;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoredone:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic unsigned int
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_intr_message(caddr_t arg1, caddr_t arg2)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_t *sp = (void *)arg1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efx_nic_t *enp = sp->s_enp;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_intr_t *sip = &(sp->s_intr);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore unsigned int index = (unsigned int)(uintptr_t)arg2;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore boolean_t fatal;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int rc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ASSERT3U(sip->si_type, ==, EFX_INTR_MESSAGE);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (sip->si_state != SFXGE_INTR_STARTED &&
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_state != SFXGE_INTR_TESTING) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = DDI_INTR_UNCLAIMED;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto done;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (sip->si_state == SFXGE_INTR_TESTING) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore uint64_t mask;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore do {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mask = sip->si_mask;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore } while (atomic_cas_64(&(sip->si_mask), mask,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mask | (1 << index)) != mask);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = DDI_INTR_CLAIMED;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto done;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efx_intr_status_message(enp, index, &fatal);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (fatal) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_intr_fatal(sp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = DDI_INTR_CLAIMED;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto done;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (void) sfxge_ev_qpoll(sp, index);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_gld_rx_push(sp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = DDI_INTR_CLAIMED;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoredone:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_intr_bus_enable(sfxge_t *sp)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_intr_t *sip = &(sp->s_intr);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ddi_intr_handler_t *handler;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int add_index;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int en_index;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int err;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int rc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Serialise all instances to avoid problems seen in bug31184. */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_enter(&sfxge_global_lock);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore switch (sip->si_type) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore case EFX_INTR_MESSAGE:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore handler = sfxge_intr_message;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore break;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore case EFX_INTR_LINE:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore handler = sfxge_intr_line;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore break;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore default:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev_err(sp->s_dip, CE_WARN, SFXGE_CMN_ERR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "bus_enable: unknown intr type (si_type=%d nalloc=%d)",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_type, sip->si_nalloc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ASSERT(B_FALSE);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = EINVAL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Try to add the handlers */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore for (add_index = 0; add_index < sip->si_nalloc; add_index++) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore unsigned int pri;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* This cannot fail unless given invalid inputs. */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err = ddi_intr_get_pri(sip->si_table[add_index], &pri);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ASSERT(err == DDI_SUCCESS);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE2(pri, unsigned int, add_index, unsigned int, pri);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err = ddi_intr_add_handler(sip->si_table[add_index], handler,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (caddr_t)sp, (caddr_t)(uintptr_t)add_index);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (err != DDI_SUCCESS) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev_err(sp->s_dip, CE_WARN, SFXGE_CMN_ERR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "bus_enable: ddi_intr_add_handler failed"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore " err=%d (h=%p idx=%d nalloc=%d)",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err, (void *)sip->si_table[add_index], add_index,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_nalloc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = (err == DDI_EINVAL) ? EINVAL : EFAULT;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail2;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Get interrupt capabilities */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err = ddi_intr_get_cap(sip->si_table[0], &(sip->si_cap));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (err != DDI_SUCCESS) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev_err(sp->s_dip, CE_WARN, SFXGE_CMN_ERR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "bus_enable: ddi_intr_get_cap failed"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore " err=%d (h=%p idx=%d nalloc=%d)",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err, (void *)sip->si_table[0], 0, sip->si_nalloc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (err == DDI_EINVAL)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = EINVAL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore else if (err == DDI_ENOTSUP)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = ENOTSUP;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore else
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = EFAULT;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail3;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Enable interrupts at the bus */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (sip->si_cap & DDI_INTR_FLAG_BLOCK) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore en_index = 0; /* Silence gcc */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err = ddi_intr_block_enable(sip->si_table, sip->si_nalloc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (err != DDI_SUCCESS) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev_err(sp->s_dip, CE_WARN, SFXGE_CMN_ERR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "bus_enable: ddi_intr_block_enable failed"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore " err=%d (table=%p nalloc=%d)",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err, (void *)sip->si_table, sip->si_nalloc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = (err == DDI_EINVAL) ? EINVAL : EFAULT;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail4;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore } else {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore for (en_index = 0; en_index < sip->si_nalloc; en_index++) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err = ddi_intr_enable(sip->si_table[en_index]);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (err != DDI_SUCCESS) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev_err(sp->s_dip, CE_WARN, SFXGE_CMN_ERR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "bus_enable: ddi_intr_enable failed"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore " err=%d (h=%p idx=%d nalloc=%d)",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err, (void *)sip->si_table[en_index],
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore en_index, sip->si_nalloc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = (err == DDI_EINVAL) ? EINVAL : EFAULT;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail4;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_exit(&sfxge_global_lock);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (0);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail4:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE(fail4);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Disable the enabled handlers */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (!(sip->si_cap & DDI_INTR_FLAG_BLOCK)) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore while (--en_index >= 0) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err = ddi_intr_disable(sip->si_table[en_index]);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (err != DDI_SUCCESS) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev_err(sp->s_dip, CE_WARN, SFXGE_CMN_ERR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "bus_enable: ddi_intr_disable"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore " failed err=%d (h=%p idx=%d nalloc=%d)",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err, (void *)sip->si_table[en_index],
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore en_index, sip->si_nalloc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail3:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE(fail3);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Remove all handlers */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore add_index = sip->si_nalloc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail2:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE(fail2);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Remove remaining handlers */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore while (--add_index >= 0) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err = ddi_intr_remove_handler(sip->si_table[add_index]);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (err != DDI_SUCCESS) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev_err(sp->s_dip, CE_WARN, SFXGE_CMN_ERR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "bus_enable: ddi_intr_remove_handler"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore " failed err=%d (h=%p idx=%d nalloc=%d)",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err, (void *)sip->si_table[add_index], add_index,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_nalloc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail1:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE1(fail1, int, rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_exit(&sfxge_global_lock);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic void
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_intr_bus_disable(sfxge_t *sp)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_intr_t *sip = &(sp->s_intr);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int index;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int err;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Serialise all instances to avoid problems seen in bug31184. */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_enter(&sfxge_global_lock);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Disable interrupts at the bus */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (sip->si_cap & DDI_INTR_FLAG_BLOCK) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err = ddi_intr_block_disable(sip->si_table, sip->si_nalloc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (err != DDI_SUCCESS) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev_err(sp->s_dip, CE_WARN, SFXGE_CMN_ERR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "bus_disable: ddi_intr_block_disable"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore " failed err=%d (table=%p nalloc=%d)",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err, (void *)sip->si_table, sip->si_nalloc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore } else {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore index = sip->si_nalloc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore while (--index >= 0) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err = ddi_intr_disable(sip->si_table[index]);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (err != DDI_SUCCESS) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev_err(sp->s_dip, CE_WARN, SFXGE_CMN_ERR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "bus_disable: ddi_intr_disable"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore " failed err=%d (h=%p idx=%d nalloc=%d)",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err, (void *)sip->si_table[index], index,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_nalloc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_cap = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Remove all handlers */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore index = sip->si_nalloc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore while (--index >= 0) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err = ddi_intr_remove_handler(sip->si_table[index]);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (err != DDI_SUCCESS) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev_err(sp->s_dip, CE_WARN, SFXGE_CMN_ERR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "bus_disable: ddi_intr_remove_handler"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore " failed err=%d (h=%p idx=%d nalloc=%d)",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err, (void *)sip->si_table[index], index,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_nalloc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_exit(&sfxge_global_lock);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_intr_nic_enable(sfxge_t *sp)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_intr_t *sip = &(sp->s_intr);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efsys_mem_t *esmp = &(sip->si_mem);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efx_nic_t *enp = sp->s_enp;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore unsigned int index;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore uint64_t mask;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore unsigned int count;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int rc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Zero the memory */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore bzero(esmp->esm_base, EFX_INTR_SIZE);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Enable interrupts at the NIC */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if ((rc = efx_intr_init(enp, sip->si_type, esmp)) != 0)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efx_intr_enable(enp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* FIXME FIXME FIXME */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (sp->s_family == EFX_FAMILY_HUNTINGTON) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Disable interrupt test until supported on Huntington. */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (0);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* FIXME FIXME FIXME */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Test the interrupts */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mask = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore for (index = 0; index < sip->si_nalloc; index++) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mask |= (1 << index);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = efx_intr_trigger(enp, index);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ASSERT3U(rc, ==, 0);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Wait for the tests to complete */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore count = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore do {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE1(wait, unsigned int, count);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Spin for 1 ms */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore drv_usecwait(1000);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /*
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Check to see that all the test interrupts have been
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * processed.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if ((mask & sip->si_mask) == mask)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto done;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore } while (++count < 20);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = ETIMEDOUT;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail2;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoredone:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (0);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail2:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE(fail2);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev_err(sp->s_dip, CE_WARN, SFXGE_CMN_ERR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "Interrupt test failed (mask=%"PRIx64" got=%"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore PRIx64"). NIC is disabled",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mask, sip->si_mask);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE2(int_test_fail, uint64_t, mask, uint64_t, sip->si_mask);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_mask = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Disable interrupts at the NIC */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efx_intr_disable(enp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efx_intr_fini(enp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail1:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE1(fail1, int, rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic void
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_intr_nic_disable(sfxge_t *sp)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_intr_t *sip = &(sp->s_intr);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efx_nic_t *enp = sp->s_enp;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_mask = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Disable interrupts at the NIC */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efx_intr_disable(enp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efx_intr_fini(enp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic inline unsigned
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorepow2_le(unsigned long n)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore unsigned int order = 1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ASSERT3U(n, >, 0);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore while ((1ul << order) <= n) ++order;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (1ul << (order - 1));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreint
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_intr_init(sfxge_t *sp)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev_info_t *dip = sp->s_dip;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_intr_t *sip = &(sp->s_intr);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efsys_mem_t *esmp = &(sip->si_mem);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_dma_buffer_attr_t dma_attr;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int err;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int rc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int types;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int type;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int index;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore unsigned int nalloc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int navail;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore SFXGE_OBJ_CHECK(sip, sfxge_intr_t);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ASSERT3U(sip->si_state, ==, SFXGE_INTR_UNINITIALIZED);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#ifdef __sparc
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* PSARC 2007/453 */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (void) ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "#msix-request", NULL, 0);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#endif
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Get the map of supported interrupt types */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err = ddi_intr_get_supported_types(dip, &types);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (err != DDI_SUCCESS) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev_err(dip, CE_WARN, SFXGE_CMN_ERR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "intr_init: ddi_intr_get_supported_types failed err=%d",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (err == DDI_EINVAL)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = EINVAL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore else if (err == DDI_INTR_NOTFOUND)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = ENOENT;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore else
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = EFAULT;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Choose most favourable type */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (types & DDI_INTR_TYPE_MSIX) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE(msix);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore type = DDI_INTR_TYPE_MSIX;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_type = EFX_INTR_MESSAGE;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore } else {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE(fixed);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ASSERT(types & DDI_INTR_TYPE_FIXED);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore type = DDI_INTR_TYPE_FIXED;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_type = EFX_INTR_LINE;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Get the number of available interrupts */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore navail = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err = ddi_intr_get_navail(dip, type, &navail);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (err != DDI_SUCCESS) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev_err(dip, CE_WARN, SFXGE_CMN_ERR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "intr_init: ddi_intr_get_navail failed err=%d", err);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (err == DDI_EINVAL)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = EINVAL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore else if (err == DDI_INTR_NOTFOUND)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = ENOENT;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore else
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = EFAULT;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail2;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Double-check */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (navail == 0) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = ENOENT;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail2;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /*
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Allow greater number of MSI-X interrupts than CPUs.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * This can be useful to prevent RX no desc drops; See task 32179.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Limit non MSI-X interrupts to a single instance.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (type != DDI_INTR_TYPE_MSIX)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore navail = 1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore else
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore navail = min(navail, sfxge_rx_scale_prop_get(sp));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE1(navail, unsigned int, navail);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Allocate a handle table */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_table_size = navail * sizeof (ddi_intr_handle_t);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_table = kmem_zalloc(sip->si_table_size, KM_SLEEP);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /*
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Allocate interrupt handles.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Serialise all device instances to avoid problems seen in bug31184.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_enter(&sfxge_global_lock);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err = ddi_intr_alloc(dip, sip->si_table, type, 0,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore navail, &(sip->si_nalloc), DDI_INTR_ALLOC_NORMAL);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_exit(&sfxge_global_lock);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (err != DDI_SUCCESS) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev_err(dip, CE_WARN, SFXGE_CMN_ERR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "intr_init: ddi_intr_alloc failed err=%d"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore " (navail=%d nalloc=%d)",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err, navail, sip->si_nalloc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (err == DDI_EINVAL)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = EINVAL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore else if (err == DDI_EAGAIN)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = EAGAIN;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore else if (err == DDI_INTR_NOTFOUND)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = ENOENT;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore else
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = EFAULT;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail3;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Double-check */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (sip->si_nalloc == 0) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = ENOENT;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail3;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Round down to a power of 2 */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore nalloc = pow2_le(sip->si_nalloc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Free off any excess handles */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_enter(&sfxge_global_lock);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore index = sip->si_nalloc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore while (--index >= nalloc) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (void) ddi_intr_free(sip->si_table[index]);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_table[index] = NULL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_exit(&sfxge_global_lock);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_nalloc = nalloc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE1(nalloc, unsigned int, sip->si_nalloc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dma_attr.sdba_dip = sp->s_dip;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dma_attr.sdba_dattrp = &sfxge_intr_dma_attr;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dma_attr.sdba_callback = DDI_DMA_SLEEP;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dma_attr.sdba_length = EFX_INTR_SIZE;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dma_attr.sdba_memflags = DDI_DMA_CONSISTENT;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dma_attr.sdba_devaccp = &sfxge_intr_devacc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dma_attr.sdba_bindflags = DDI_DMA_RDWR | DDI_DMA_CONSISTENT;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dma_attr.sdba_maxcookies = 1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dma_attr.sdba_zeroinit = B_TRUE;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if ((rc = sfxge_dma_buffer_create(esmp, &dma_attr)) != 0)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail4;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Store the highest priority for convenience */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_intr_pri = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore for (index = 0; index < sip->si_nalloc; index++) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore uint_t pri;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if ((rc = ddi_intr_get_pri(sip->si_table[index], &pri)) != 0)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail5;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (pri > sip->si_intr_pri)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_intr_pri = pri;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_state = SFXGE_INTR_INITIALIZED;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (0);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail5:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE(fail5);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail4:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE(fail4);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Free interrupt handles */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_exit(&sfxge_global_lock);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore index = sip->si_nalloc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore while (--index >= 0) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err = ddi_intr_free(sip->si_table[index]);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (err != DDI_SUCCESS) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev_err(dip, CE_WARN, SFXGE_CMN_ERR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "intr_init: ddi_intr_free failed err=%d"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore " (h=%p idx=%d nalloc=%d)",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err, (void *)sip->si_table[index], index,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_nalloc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_table[index] = NULL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_nalloc = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_exit(&sfxge_global_lock);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail3:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE(fail3);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Free the handle table */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore kmem_free(sip->si_table, sip->si_table_size);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_table = NULL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_table_size = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail2:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE(fail2);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Clear the interrupt type */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_type = EFX_INTR_INVALID;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail1:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE1(fail1, int, rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore SFXGE_OBJ_CHECK(sip, sfxge_intr_t);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreint
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_intr_start(sfxge_t *sp)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_intr_t *sip = &(sp->s_intr);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int rc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ASSERT3U(sip->si_state, ==, SFXGE_INTR_INITIALIZED);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Enable interrupts at the bus */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if ((rc = sfxge_intr_bus_enable(sp)) != 0)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_state = SFXGE_INTR_TESTING;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Enable interrupts at the NIC */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if ((rc = sfxge_intr_nic_enable(sp)) != 0)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail2;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_state = SFXGE_INTR_STARTED;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (0);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail2:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE(fail2);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Disable interrupts at the bus */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_intr_bus_disable(sp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail1:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE1(fail1, int, rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_state = SFXGE_INTR_INITIALIZED;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorevoid
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_intr_stop(sfxge_t *sp)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_intr_t *sip = &(sp->s_intr);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ASSERT3U(sip->si_state, ==, SFXGE_INTR_STARTED);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_state = SFXGE_INTR_INITIALIZED;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Disable interrupts at the NIC */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_intr_nic_disable(sp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Disable interrupts at the bus */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_intr_bus_disable(sp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorevoid
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_intr_fini(sfxge_t *sp)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_intr_t *sip = &(sp->s_intr);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore efsys_mem_t *esmp = &(sip->si_mem);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int index;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int err;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ASSERT3U(sip->si_state, ==, SFXGE_INTR_INITIALIZED);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_state = SFXGE_INTR_UNINITIALIZED;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Tear down dma setup */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sfxge_dma_buffer_destroy(esmp);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Free interrupt handles */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_enter(&sfxge_global_lock);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore index = sip->si_nalloc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore while (--index >= 0) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err = ddi_intr_free(sip->si_table[index]);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (err != DDI_SUCCESS) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev_err(sp->s_dip, CE_WARN, SFXGE_CMN_ERR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "intr_fini: ddi_intr_free failed err=%d"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore " (h=%p idx=%d nalloc=%d)",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore err, (void *)sip->si_table[index],
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore index, sip->si_nalloc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_table[index] = NULL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_nalloc = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mutex_exit(&sfxge_global_lock);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Free the handle table */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore kmem_free(sip->si_table, sip->si_table_size);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_table = NULL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_table_size = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Clear the interrupt type */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sip->si_type = EFX_INTR_INVALID;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore SFXGE_OBJ_CHECK(sip, sfxge_intr_t);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}