add pci_intr_distribute(9) for x86.
This commit is contained in:
parent
2373b55abc
commit
c65d622dea
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: mi,v 1.1954 2015/04/21 11:10:29 pooka Exp $
|
||||
# $NetBSD: mi,v 1.1955 2015/04/27 06:42:52 knakahara Exp $
|
||||
#
|
||||
# Note: don't delete entries from here - mark them as "obsolete" instead.
|
||||
#
|
||||
|
@ -17131,6 +17131,7 @@
|
|||
./usr/share/man/html9/in_getifa.html comp-sys-htmlman html
|
||||
./usr/share/man/html9/incore.html comp-sys-htmlman html
|
||||
./usr/share/man/html9/inittodr.html comp-sys-htmlman html
|
||||
./usr/share/man/html9/pci_intr_distribute.html comp-sys-htmlman html
|
||||
./usr/share/man/html9/intro.html comp-sys-htmlman html
|
||||
./usr/share/man/html9/ioasic.html comp-sys-htmlman html
|
||||
./usr/share/man/html9/ioasic_attach_devs.html comp-sys-htmlman html
|
||||
|
@ -24063,6 +24064,7 @@
|
|||
./usr/share/man/man9/in_getifa.9 comp-sys-man .man
|
||||
./usr/share/man/man9/incore.9 comp-sys-man .man
|
||||
./usr/share/man/man9/inittodr.9 comp-sys-man .man
|
||||
./usr/share/man/man9/pci_intr_distribute.9 comp-sys-man .man
|
||||
./usr/share/man/man9/intro.9 comp-sys-man .man
|
||||
./usr/share/man/man9/ioasic.9 comp-sys-man .man
|
||||
./usr/share/man/man9/ioasic_attach_devs.9 comp-sys-man .man
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.384 2015/04/21 11:10:29 pooka Exp $
|
||||
# $NetBSD: Makefile,v 1.385 2015/04/27 06:42:52 knakahara Exp $
|
||||
|
||||
# Makefile for section 9 (kernel function and variable) manual pages.
|
||||
|
||||
|
@ -39,10 +39,11 @@ MAN= accept_filter.9 accf_data.9 accf_http.9 \
|
|||
microseq.9 microtime.9 microuptime.9 mi_switch.9 module.9 \
|
||||
mstohz.9 mutex.9 m_tag.9 namecache.9 \
|
||||
namei.9 nullop.9 opencrypto.9 optstr.9 \
|
||||
panic.9 pathbuf.9 pci.9 pci_configure_bus.9 pci_intr.9 pckbport.9 \
|
||||
pcmcia.9 pcq.9 pcu.9 percpu.9 pfil.9 physio.9 pmap.9 pmatch.9 \
|
||||
pmc.9 pmf.9 pool.9 pool_cache.9 powerhook_establish.9 ppi.9 \
|
||||
ppsratecheck.9 preempt.9 proc_find.9 pserialize.9 putter.9 \
|
||||
panic.9 pathbuf.9 pci.9 pci_configure_bus.9 pci_intr.9 \
|
||||
pci_intr_distribute.9 pckbport.9 pcmcia.9 pcq.9 pcu.9 \
|
||||
percpu.9 pfil.9 physio.9 pmap.9 pmatch.9 pmc.9 pmf.9 pool.9 \
|
||||
pool_cache.9 powerhook_establish.9 ppi.9 ppsratecheck.9 preempt.9 \
|
||||
proc_find.9 pserialize.9 putter.9 \
|
||||
radio.9 ras.9 rasops.9 ratecheck.9 resettodr.9 rnd.9 rndsink.9 \
|
||||
roundup.9 rssadapt.9 rt_timer.9 rwlock.9 RUN_ONCE.9 STACK.9 \
|
||||
scanc.9 \
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
.\" $NetBSD: pci_intr_distribute.9,v 1.1 2015/04/27 06:42:52 knakahara Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2015 Internet Initiative Japan Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd April 8, 2015
|
||||
.Dt PCI_INTR_DISTRIBUTE 9
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm pci_intr_distribute
|
||||
.Sh SYNOPSIS
|
||||
.In dev/pci/pcivar.h
|
||||
.Ft int
|
||||
.Fn pci_intr_distribute "void *ich" "const kcpuset_t *newset" \
|
||||
"kcpuset_t *oldset"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
functions exist to assing an interrupt to CPU.
|
||||
.Pp
|
||||
If a driver (or the other kernel component) wishes to assign an
|
||||
interrupt to CPU, it should pass the return value of
|
||||
.Fn pci_intr_establish
|
||||
to the
|
||||
.Ft ich .
|
||||
And it should set kcpuset which want to assign to
|
||||
.Ft newset .
|
||||
If it want to get the assignment before changing, it should be
|
||||
pass non-NULL value to
|
||||
.Ft oldset .
|
||||
If not, it should set NULL to
|
||||
.Ft oldset .
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: intr.h,v 1.45 2014/07/20 15:46:34 uebayasi Exp $ */
|
||||
/* $NetBSD: intr.h,v 1.46 2015/04/27 06:42:52 knakahara Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -42,6 +42,7 @@
|
|||
#endif
|
||||
|
||||
#include <sys/evcnt.h>
|
||||
#include <sys/queue.h>
|
||||
#include <machine/intrdefs.h>
|
||||
|
||||
#ifndef _LOCORE
|
||||
|
@ -71,6 +72,11 @@ struct intrstub {
|
|||
void *ist_resume;
|
||||
};
|
||||
|
||||
struct percpu_evcnt {
|
||||
cpuid_t cpuid;
|
||||
uint64_t count;
|
||||
};
|
||||
|
||||
struct intrsource {
|
||||
int is_maxlevel; /* max. IPL for this source */
|
||||
int is_pin; /* IRQ for legacy; pin for IO APIC,
|
||||
|
@ -86,6 +92,10 @@ struct intrsource {
|
|||
int is_idtvec;
|
||||
int is_minlevel;
|
||||
char is_evname[32]; /* event counter name */
|
||||
char is_intrid[INTRIDBUF]; /* intrid created by create_intrid() */
|
||||
cpuid_t is_active_cpu; /* active cpuid */
|
||||
struct percpu_evcnt *is_saved_evcnt; /* interrupt count of deactivated cpus */
|
||||
SIMPLEQ_ENTRY(intrsource) is_list; /* link of intrsources */
|
||||
};
|
||||
|
||||
#define IS_LEGACY 0x0001 /* legacy ISA irq source */
|
||||
|
@ -182,6 +192,9 @@ int intr_find_mpmapping(int, int, int *);
|
|||
struct pic *intr_findpic(int);
|
||||
void intr_printconfig(void);
|
||||
|
||||
struct intrsource *intr_allocate_io_intrsource(const char *);
|
||||
void intr_free_io_intrsource(const char *);
|
||||
|
||||
int x86_send_ipi(struct cpu_info *, int);
|
||||
void x86_broadcast_ipi(int);
|
||||
void x86_ipi_handler(void);
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/* $NetBSD: intr_distribute.h,v 1.1 2015/04/27 06:42:52 knakahara Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015 Internet Initiative Japan Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _X86_INTR_DISTRIBUTE_H_
|
||||
#define _X86_INTR_DISTRIBUTE_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <sys/kcpuset.h>
|
||||
|
||||
int intr_distribute(struct intrhand *, const kcpuset_t *, kcpuset_t *);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_X86_INTR_DISTRIBUTE_H_ */
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pci_machdep.h,v 1.15 2015/03/04 05:35:50 knakahara Exp $ */
|
||||
/* $NetBSD: pci_machdep.h,v 1.16 2015/04/27 06:42:52 knakahara Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
|
||||
|
@ -33,6 +33,8 @@
|
|||
#ifndef _X86_PCI_MACHDEP_H_
|
||||
#define _X86_PCI_MACHDEP_H_
|
||||
|
||||
#include <x86/intr_distribute.h>
|
||||
|
||||
/*
|
||||
* Types provided to machine-independent PCI code
|
||||
* See also i82093var.h to find out pci_intr_handle_t's bitfield.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pci_machdep_common.h,v 1.13 2014/03/29 19:28:30 christos Exp $ */
|
||||
/* $NetBSD: pci_machdep_common.h,v 1.14 2015/04/27 06:42:52 knakahara Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
|
||||
|
@ -41,6 +41,8 @@
|
|||
#define __HAVE_PCIIDE_MACHDEP_COMPAT_INTR_DISESTABLISH
|
||||
#endif
|
||||
|
||||
#include <sys/kcpuset.h>
|
||||
|
||||
/*
|
||||
* x86-specific PCI structure and type definitions.
|
||||
* NOT TO BE USED DIRECTLY BY MACHINE INDEPENDENT CODE.
|
||||
|
@ -116,6 +118,7 @@ const struct evcnt *pci_intr_evcnt(pci_chipset_tag_t, pci_intr_handle_t);
|
|||
void *pci_intr_establish(pci_chipset_tag_t, pci_intr_handle_t,
|
||||
int, int (*)(void *), void *);
|
||||
void pci_intr_disestablish(pci_chipset_tag_t, void *);
|
||||
int pci_intr_distribute(void *, const kcpuset_t *, kcpuset_t *);
|
||||
|
||||
/* experimental MSI support */
|
||||
void *pci_msi_establish(struct pci_attach_args *, int, int (*)(void *), void *);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pci_intr_machdep.c,v 1.27 2014/03/29 19:28:30 christos Exp $ */
|
||||
/* $NetBSD: pci_intr_machdep.c,v 1.28 2015/04/27 06:42:52 knakahara Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997, 1998, 2009 The NetBSD Foundation, Inc.
|
||||
|
@ -73,15 +73,17 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: pci_intr_machdep.c,v 1.27 2014/03/29 19:28:30 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: pci_intr_machdep.c,v 1.28 2015/04/27 06:42:52 knakahara Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/cpu.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/intr.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
@ -328,6 +330,15 @@ pci_intr_disestablish(pci_chipset_tag_t pc, void *cookie)
|
|||
intr_disestablish(cookie);
|
||||
}
|
||||
|
||||
int
|
||||
pci_intr_distribute(void *cookie, const kcpuset_t *newset, kcpuset_t *oldset)
|
||||
{
|
||||
|
||||
/* XXX Is pc_ov->ov_intr_distribute required? */
|
||||
|
||||
return intr_distribute(cookie, newset, oldset);
|
||||
}
|
||||
|
||||
#if NIOAPIC > 0
|
||||
/*
|
||||
* experimental support for MSI, does support a single vector,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: intr.c,v 1.78 2015/04/08 05:52:41 knakahara Exp $ */
|
||||
/* $NetBSD: intr.c,v 1.79 2015/04/27 06:42:52 knakahara Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
|
||||
|
@ -133,7 +133,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.78 2015/04/08 05:52:41 knakahara Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.79 2015/04/27 06:42:52 knakahara Exp $");
|
||||
|
||||
#include "opt_intrdebug.h"
|
||||
#include "opt_multiprocessor.h"
|
||||
|
@ -180,6 +180,12 @@ __KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.78 2015/04/08 05:52:41 knakahara Exp $");
|
|||
#include <ddb/db_output.h>
|
||||
#endif
|
||||
|
||||
#ifdef INTRDEBUG
|
||||
#define DPRINTF(msg) printf msg
|
||||
#else
|
||||
#define DPRINTF(msg)
|
||||
#endif
|
||||
|
||||
struct pic softintr_pic = {
|
||||
.pic_name = "softintr_fakepic",
|
||||
.pic_type = PIC_SOFT,
|
||||
|
@ -190,6 +196,9 @@ struct pic softintr_pic = {
|
|||
|
||||
static void intr_calculatemasks(struct cpu_info *);
|
||||
|
||||
static SIMPLEQ_HEAD(, intrsource) io_interrupt_sources =
|
||||
SIMPLEQ_HEAD_INITIALIZER(io_interrupt_sources);
|
||||
|
||||
#if NIOAPIC > 0 || NACPICA > 0
|
||||
static int intr_scan_bus(int, int, int *);
|
||||
#if NPCI > 0
|
||||
|
@ -197,9 +206,11 @@ static int intr_find_pcibridge(int, pcitag_t *, pci_chipset_tag_t *);
|
|||
#endif
|
||||
#endif
|
||||
|
||||
static int intr_allocate_slot_cpu(struct cpu_info *, struct pic *, int, int *);
|
||||
static int intr_allocate_slot_cpu(struct cpu_info *, struct pic *, int, int *,
|
||||
struct intrsource *);
|
||||
static int __noinline intr_allocate_slot(struct pic *, int, int,
|
||||
struct cpu_info **, int *, int *);
|
||||
struct cpu_info **, int *, int *,
|
||||
struct intrsource *);
|
||||
|
||||
static void intr_source_free(struct cpu_info *, int, struct pic *, int);
|
||||
|
||||
|
@ -214,6 +225,14 @@ static void intr_redistribute_xc_s1(void *, void *);
|
|||
static void intr_redistribute_xc_s2(void *, void *);
|
||||
static bool intr_redistribute(struct cpu_info *);
|
||||
|
||||
static const char *legacy_intr_string(int, char *, size_t, struct pic *);
|
||||
|
||||
static int intr_find_unused_slot(struct cpu_info *, int *);
|
||||
static void intr_activate_xcall(void *, void *);
|
||||
static void intr_deactivate_xcall(void *, void *);
|
||||
static void intr_get_affinity(struct intrsource *, kcpuset_t *);
|
||||
static int intr_set_affinity(struct intrsource *, const kcpuset_t *);
|
||||
|
||||
/*
|
||||
* Fill in default interrupt table (in case of spurious interrupt
|
||||
* during configuration of kernel), setup interrupt control unit
|
||||
|
@ -432,9 +451,135 @@ intr_scan_bus(int bus, int pin, int *handle)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Create an interrupt id such as "ioapic0 pin 9". This interrupt id is used
|
||||
* by MI code and intrctl(8).
|
||||
*/
|
||||
static const char *
|
||||
create_intrid(int legacy_irq, struct pic *pic, int pin, char *buf, size_t len)
|
||||
{
|
||||
int ih;
|
||||
|
||||
/*
|
||||
* If the device is pci, "legacy_irq" is alway -1. Least 8 bit of "ih"
|
||||
* is only used in intr_string() to show the irq number.
|
||||
* If the device is "legacy"(such as floppy), it should not use
|
||||
* intr_string().
|
||||
*/
|
||||
if (pic->pic_type == PIC_I8259) {
|
||||
ih = legacy_irq;
|
||||
return legacy_intr_string(ih, buf, len, pic);
|
||||
} else {
|
||||
ih = ((pic->pic_apicid << APIC_INT_APIC_SHIFT) & APIC_INT_APIC_MASK) |
|
||||
((pin << APIC_INT_PIN_SHIFT) & APIC_INT_PIN_MASK);
|
||||
if (pic->pic_type == PIC_IOAPIC) {
|
||||
ih |= APIC_INT_VIA_APIC;
|
||||
}
|
||||
ih |= pin;
|
||||
return intr_string(ih, buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Find intrsource from io_interrupt_sources list.
|
||||
*/
|
||||
static struct intrsource *
|
||||
intr_get_io_intrsource(const char *intrid)
|
||||
{
|
||||
struct intrsource *isp;
|
||||
|
||||
KASSERT(mutex_owned(&cpu_lock));
|
||||
|
||||
SIMPLEQ_FOREACH(isp, &io_interrupt_sources, is_list) {
|
||||
KASSERT(isp->is_intrid != NULL);
|
||||
if (strncmp(intrid, isp->is_intrid, INTRIDBUF - 1) == 0) {
|
||||
return isp;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate intrsource and add to io_interrupt_sources list.
|
||||
*/
|
||||
struct intrsource *
|
||||
intr_allocate_io_intrsource(const char *intrid)
|
||||
{
|
||||
CPU_INFO_ITERATOR cii;
|
||||
struct cpu_info *ci;
|
||||
struct intrsource *isp;
|
||||
struct percpu_evcnt *pep;
|
||||
|
||||
KASSERT(mutex_owned(&cpu_lock));
|
||||
|
||||
if (intrid == NULL)
|
||||
return NULL;
|
||||
|
||||
isp = kmem_zalloc(sizeof(*isp), KM_SLEEP);
|
||||
if (isp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pep = kmem_zalloc(sizeof(*pep) * ncpu, KM_SLEEP);
|
||||
if (pep == NULL) {
|
||||
kmem_free(isp, sizeof(*isp));
|
||||
return NULL;
|
||||
}
|
||||
isp->is_saved_evcnt = pep;
|
||||
for (CPU_INFO_FOREACH(cii, ci)) {
|
||||
pep->cpuid = ci->ci_cpuid;
|
||||
pep++;
|
||||
}
|
||||
strncpy(isp->is_intrid, intrid, sizeof(isp->is_intrid));
|
||||
|
||||
SIMPLEQ_INSERT_TAIL(&io_interrupt_sources, isp, is_list);
|
||||
|
||||
return isp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove from io_interrupt_sources list and free by the intrsource pointer.
|
||||
*/
|
||||
static void
|
||||
intr_free_io_intrsource_direct(struct intrsource *isp)
|
||||
{
|
||||
KASSERT(mutex_owned(&cpu_lock));
|
||||
|
||||
SIMPLEQ_REMOVE(&io_interrupt_sources, isp, intrsource, is_list);
|
||||
|
||||
/* Is this interrupt established? */
|
||||
if (isp->is_evname != '\0')
|
||||
evcnt_detach(&isp->is_evcnt);
|
||||
|
||||
kmem_free(isp->is_saved_evcnt,
|
||||
sizeof(*(isp->is_saved_evcnt)) * ncpu);
|
||||
kmem_free(isp, sizeof(*isp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove from io_interrupt_sources list and free by the interrupt id.
|
||||
* This function can be used by MI code.
|
||||
*/
|
||||
void
|
||||
intr_free_io_intrsource(const char *intrid)
|
||||
{
|
||||
struct intrsource *isp;
|
||||
|
||||
KASSERT(mutex_owned(&cpu_lock));
|
||||
|
||||
if (intrid == NULL)
|
||||
return;
|
||||
|
||||
if ((isp = intr_get_io_intrsource(intrid)) == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
intr_free_io_intrsource_direct(isp);
|
||||
}
|
||||
|
||||
static int
|
||||
intr_allocate_slot_cpu(struct cpu_info *ci, struct pic *pic, int pin,
|
||||
int *index)
|
||||
int *index, struct intrsource *chained)
|
||||
{
|
||||
int slot, i;
|
||||
struct intrsource *isp;
|
||||
|
@ -464,14 +609,13 @@ intr_allocate_slot_cpu(struct cpu_info *ci, struct pic *pic, int pin,
|
|||
|
||||
isp = ci->ci_isources[slot];
|
||||
if (isp == NULL) {
|
||||
isp = kmem_zalloc(sizeof(*isp), KM_SLEEP);
|
||||
if (isp == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
isp = chained;
|
||||
KASSERT(isp != NULL);
|
||||
snprintf(isp->is_evname, sizeof (isp->is_evname),
|
||||
"pin %d", pin);
|
||||
evcnt_attach_dynamic(&isp->is_evcnt, EVCNT_TYPE_INTR, NULL,
|
||||
pic->pic_name, isp->is_evname);
|
||||
isp->is_active_cpu = ci->ci_cpuid;
|
||||
ci->ci_isources[slot] = isp;
|
||||
}
|
||||
|
||||
|
@ -484,7 +628,8 @@ intr_allocate_slot_cpu(struct cpu_info *ci, struct pic *pic, int pin,
|
|||
*/
|
||||
static int __noinline
|
||||
intr_allocate_slot(struct pic *pic, int pin, int level,
|
||||
struct cpu_info **cip, int *index, int *idt_slot)
|
||||
struct cpu_info **cip, int *index, int *idt_slot,
|
||||
struct intrsource *chained)
|
||||
{
|
||||
CPU_INFO_ITERATOR cii;
|
||||
struct cpu_info *ci, *lci;
|
||||
|
@ -523,7 +668,7 @@ intr_allocate_slot(struct pic *pic, int pin, int level,
|
|||
* Must be directed to BP.
|
||||
*/
|
||||
ci = &cpu_info_primary;
|
||||
error = intr_allocate_slot_cpu(ci, pic, pin, &slot);
|
||||
error = intr_allocate_slot_cpu(ci, pic, pin, &slot, chained);
|
||||
} else {
|
||||
/*
|
||||
* Find least loaded AP/BP and try to allocate there.
|
||||
|
@ -543,7 +688,7 @@ intr_allocate_slot(struct pic *pic, int pin, int level,
|
|||
#endif
|
||||
}
|
||||
KASSERT(ci != NULL);
|
||||
error = intr_allocate_slot_cpu(ci, pic, pin, &slot);
|
||||
error = intr_allocate_slot_cpu(ci, pic, pin, &slot, chained);
|
||||
|
||||
/*
|
||||
* If that did not work, allocate anywhere.
|
||||
|
@ -555,7 +700,7 @@ intr_allocate_slot(struct pic *pic, int pin, int level,
|
|||
continue;
|
||||
}
|
||||
error = intr_allocate_slot_cpu(ci, pic,
|
||||
pin, &slot);
|
||||
pin, &slot, chained);
|
||||
if (error == 0) {
|
||||
break;
|
||||
}
|
||||
|
@ -578,7 +723,6 @@ intr_allocate_slot(struct pic *pic, int pin, int level,
|
|||
}
|
||||
if (idtvec == 0) {
|
||||
evcnt_detach(&ci->ci_isources[slot]->is_evcnt);
|
||||
kmem_free(ci->ci_isources[slot], sizeof(*(ci->ci_isources[slot])));
|
||||
ci->ci_isources[slot] = NULL;
|
||||
return EBUSY;
|
||||
}
|
||||
|
@ -599,9 +743,6 @@ intr_source_free(struct cpu_info *ci, int slot, struct pic *pic, int idtvec)
|
|||
if (isp->is_handlers != NULL)
|
||||
return;
|
||||
ci->ci_isources[slot] = NULL;
|
||||
evcnt_detach(&isp->is_evcnt);
|
||||
kmem_free(isp, sizeof(*isp));
|
||||
ci->ci_isources[slot] = NULL;
|
||||
if (pic != &i8259_pic)
|
||||
idt_vec_free(idtvec);
|
||||
}
|
||||
|
@ -705,11 +846,13 @@ intr_establish(int legacy_irq, struct pic *pic, int pin, int type, int level,
|
|||
struct intrhand **p, *q, *ih;
|
||||
struct cpu_info *ci;
|
||||
int slot, error, idt_vec;
|
||||
struct intrsource *source;
|
||||
struct intrsource *chained, *source;
|
||||
#ifdef MULTIPROCESSOR
|
||||
bool mpsafe = (known_mpsafe || level != IPL_VM);
|
||||
#endif /* MULTIPROCESSOR */
|
||||
uint64_t where;
|
||||
const char *intrstr;
|
||||
char intrstr_buf[INTRIDBUF];
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (legacy_irq != -1 && (legacy_irq < 0 || legacy_irq > 15))
|
||||
|
@ -725,9 +868,27 @@ intr_establish(int legacy_irq, struct pic *pic, int pin, int type, int level,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
intrstr = create_intrid(legacy_irq, pic, pin, intrstr_buf,
|
||||
sizeof(intrstr_buf));
|
||||
KASSERT(intrstr != NULL);
|
||||
|
||||
mutex_enter(&cpu_lock);
|
||||
error = intr_allocate_slot(pic, pin, level, &ci, &slot, &idt_vec);
|
||||
|
||||
/* allocate intrsource pool, if not yet. */
|
||||
chained = intr_get_io_intrsource(intrstr);
|
||||
if (chained == NULL) {
|
||||
chained = intr_allocate_io_intrsource(intrstr);
|
||||
if (chained == NULL) {
|
||||
mutex_exit(&cpu_lock);
|
||||
printf("%s: can't allocate io_intersource\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
error = intr_allocate_slot(pic, pin, level, &ci, &slot, &idt_vec,
|
||||
chained);
|
||||
if (error != 0) {
|
||||
intr_free_io_intrsource_direct(chained);
|
||||
mutex_exit(&cpu_lock);
|
||||
kmem_free(ih, sizeof(*ih));
|
||||
printf("failed to allocate interrupt slot for PIC %s pin %d\n",
|
||||
|
@ -739,6 +900,7 @@ intr_establish(int legacy_irq, struct pic *pic, int pin, int type, int level,
|
|||
|
||||
if (source->is_handlers != NULL &&
|
||||
source->is_pic->pic_type != pic->pic_type) {
|
||||
intr_free_io_intrsource_direct(chained);
|
||||
mutex_exit(&cpu_lock);
|
||||
kmem_free(ih, sizeof(*ih));
|
||||
printf("%s: can't share intr source between "
|
||||
|
@ -761,9 +923,10 @@ intr_establish(int legacy_irq, struct pic *pic, int pin, int type, int level,
|
|||
/* FALLTHROUGH */
|
||||
case IST_PULSE:
|
||||
if (type != IST_NONE) {
|
||||
intr_source_free(ci, slot, pic, idt_vec);
|
||||
intr_free_io_intrsource_direct(chained);
|
||||
mutex_exit(&cpu_lock);
|
||||
kmem_free(ih, sizeof(*ih));
|
||||
intr_source_free(ci, slot, pic, idt_vec);
|
||||
printf("%s: pic %s pin %d: can't share "
|
||||
"type %d with %d\n",
|
||||
__func__, pic->pic_name, pin,
|
||||
|
@ -902,6 +1065,19 @@ intr_disestablish_xcall(void *arg1, void *arg2)
|
|||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
intr_num_handlers(struct intrsource *isp)
|
||||
{
|
||||
struct intrhand *ih;
|
||||
int num;
|
||||
|
||||
num = 0;
|
||||
for (ih = isp->is_handlers; ih != NULL; ih = ih->ih_next)
|
||||
num++;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deregister an interrupt handler.
|
||||
*/
|
||||
|
@ -909,6 +1085,7 @@ void
|
|||
intr_disestablish(struct intrhand *ih)
|
||||
{
|
||||
struct cpu_info *ci;
|
||||
struct intrsource *isp;
|
||||
uint64_t where;
|
||||
|
||||
/*
|
||||
|
@ -920,16 +1097,39 @@ intr_disestablish(struct intrhand *ih)
|
|||
ci = ih->ih_cpu;
|
||||
(ci->ci_nintrhand)--;
|
||||
KASSERT(ci->ci_nintrhand >= 0);
|
||||
isp = ci->ci_isources[ih->ih_slot];
|
||||
if (ci == curcpu() || !mp_online) {
|
||||
intr_disestablish_xcall(ih, NULL);
|
||||
} else {
|
||||
where = xc_unicast(0, intr_disestablish_xcall, ih, NULL, ci);
|
||||
xc_wait(where);
|
||||
}
|
||||
|
||||
if (intr_num_handlers(isp) < 1) {
|
||||
intr_free_io_intrsource_direct(isp);
|
||||
}
|
||||
|
||||
mutex_exit(&cpu_lock);
|
||||
|
||||
kmem_free(ih, sizeof(*ih));
|
||||
}
|
||||
|
||||
static const char *
|
||||
legacy_intr_string(int ih, char *buf, size_t len, struct pic *pic)
|
||||
{
|
||||
int legacy_irq;
|
||||
|
||||
KASSERT(pic->pic_type == PIC_I8259);
|
||||
KASSERT(APIC_IRQ_ISLEGACY(ih));
|
||||
|
||||
legacy_irq = APIC_IRQ_LEGACY_IRQ(ih);
|
||||
KASSERT(legacy_irq >= 0 && legacy_irq < 16);
|
||||
|
||||
snprintf(buf, len, "%s pin %d", pic->pic_name, legacy_irq);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
const char *
|
||||
intr_string(int ih, char *buf, size_t len)
|
||||
{
|
||||
|
@ -940,7 +1140,6 @@ intr_string(int ih, char *buf, size_t len)
|
|||
if (ih == 0)
|
||||
panic("%s: bogus handle 0x%x", __func__, ih);
|
||||
|
||||
|
||||
#if NIOAPIC > 0
|
||||
if (ih & APIC_INT_VIA_APIC) {
|
||||
pic = ioapic_find(APIC_IRQ_APIC(ih));
|
||||
|
@ -1179,6 +1378,46 @@ softint_init_md(lwp_t *l, u_int level, uintptr_t *machdep)
|
|||
intr_calculatemasks(ci);
|
||||
}
|
||||
|
||||
/*
|
||||
* Save current affinitied cpu's interrupt count.
|
||||
*/
|
||||
static void
|
||||
intr_save_evcnt(struct intrsource *source, cpuid_t cpuid)
|
||||
{
|
||||
struct percpu_evcnt *pep;
|
||||
uint64_t curcnt;
|
||||
int i;
|
||||
|
||||
curcnt = source->is_evcnt.ev_count;
|
||||
pep = source->is_saved_evcnt;
|
||||
|
||||
for (i = 0; i < ncpu; i++) {
|
||||
if (pep[i].cpuid == cpuid) {
|
||||
pep[i].count = curcnt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore current affinitied cpu's interrupt count.
|
||||
*/
|
||||
static void
|
||||
intr_restore_evcnt(struct intrsource *source, cpuid_t cpuid)
|
||||
{
|
||||
struct percpu_evcnt *pep;
|
||||
int i;
|
||||
|
||||
pep = source->is_saved_evcnt;
|
||||
|
||||
for (i = 0; i < ncpu; i++) {
|
||||
if (pep[i].cpuid == cpuid) {
|
||||
source->is_evcnt.ev_count = pep[i].count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
intr_redistribute_xc_t(void *arg1, void *arg2)
|
||||
{
|
||||
|
@ -1352,6 +1591,9 @@ intr_redistribute(struct cpu_info *oci)
|
|||
nci->ci_nintrhand++;
|
||||
ih->ih_cpu = nci;
|
||||
}
|
||||
intr_save_evcnt(isp, oci->ci_cpuid);
|
||||
intr_restore_evcnt(isp, nci->ci_cpuid);
|
||||
isp->is_active_cpu = nci->ci_cpuid;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1386,3 +1628,263 @@ cpu_intr_count(struct cpu_info *ci)
|
|||
|
||||
return ci->ci_nintrhand;
|
||||
}
|
||||
|
||||
static int
|
||||
intr_find_unused_slot(struct cpu_info *ci, int *index)
|
||||
{
|
||||
int slot, i;
|
||||
|
||||
KASSERT(mutex_owned(&cpu_lock));
|
||||
|
||||
slot = -1;
|
||||
for (i = 0; i < MAX_INTR_SOURCES ; i++) {
|
||||
if (ci->ci_isources[i] == NULL) {
|
||||
slot = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (slot == -1) {
|
||||
DPRINTF(("cannot allocate ci_isources\n"));
|
||||
return EBUSY;
|
||||
}
|
||||
|
||||
*index = slot;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Let cpu_info ready to accept the interrupt.
|
||||
*/
|
||||
static void
|
||||
intr_activate_xcall(void *arg1, void *arg2)
|
||||
{
|
||||
struct cpu_info *ci;
|
||||
struct intrsource *source;
|
||||
struct intrstub *stubp;
|
||||
struct intrhand *ih;
|
||||
u_long psl;
|
||||
int idt_vec;
|
||||
int slot;
|
||||
|
||||
ih = arg1;
|
||||
|
||||
kpreempt_disable();
|
||||
|
||||
KASSERT(ih->ih_cpu == curcpu() || !mp_online);
|
||||
|
||||
ci = ih->ih_cpu;
|
||||
slot = ih->ih_slot;
|
||||
source = ci->ci_isources[slot];
|
||||
idt_vec = source->is_idtvec;
|
||||
|
||||
psl = x86_read_psl();
|
||||
x86_disable_intr();
|
||||
|
||||
intr_calculatemasks(ci);
|
||||
|
||||
if (source->is_type == IST_LEVEL) {
|
||||
stubp = &source->is_pic->pic_level_stubs[slot];
|
||||
} else {
|
||||
stubp = &source->is_pic->pic_edge_stubs[slot];
|
||||
}
|
||||
source->is_resume = stubp->ist_resume;
|
||||
source->is_recurse = stubp->ist_recurse;
|
||||
setgate(&idt[idt_vec], stubp->ist_entry, 0, SDT_SYS386IGT,
|
||||
SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
|
||||
|
||||
x86_write_psl(psl);
|
||||
|
||||
kpreempt_enable();
|
||||
}
|
||||
|
||||
/*
|
||||
* Let cpu_info not accept the interrupt.
|
||||
*/
|
||||
static void
|
||||
intr_deactivate_xcall(void *arg1, void *arg2)
|
||||
{
|
||||
struct cpu_info *ci;
|
||||
struct intrhand *ih, *lih;
|
||||
u_long psl;
|
||||
int slot;
|
||||
|
||||
ih = arg1;
|
||||
|
||||
kpreempt_disable();
|
||||
|
||||
KASSERT(ih->ih_cpu == curcpu() || !mp_online);
|
||||
|
||||
ci = ih->ih_cpu;
|
||||
slot = ih->ih_slot;
|
||||
|
||||
psl = x86_read_psl();
|
||||
x86_disable_intr();
|
||||
|
||||
/* Move all devices sharing IRQ number. */
|
||||
ci->ci_isources[slot] = NULL;
|
||||
for (lih = ih; lih != NULL; lih = lih->ih_next) {
|
||||
ci->ci_nintrhand--;
|
||||
}
|
||||
|
||||
intr_calculatemasks(ci);
|
||||
|
||||
/*
|
||||
* Skip unsetgate(), because the same itd[] entry is overwritten in
|
||||
* intr_activate_xcall().
|
||||
*/
|
||||
|
||||
x86_write_psl(psl);
|
||||
|
||||
kpreempt_enable();
|
||||
}
|
||||
|
||||
static void
|
||||
intr_get_affinity(struct intrsource *isp, kcpuset_t *cpuset)
|
||||
{
|
||||
struct cpu_info *ci;
|
||||
|
||||
KASSERT(mutex_owned(&cpu_lock));
|
||||
|
||||
if (isp == NULL) {
|
||||
kcpuset_zero(cpuset);
|
||||
return;
|
||||
}
|
||||
|
||||
ci = isp->is_handlers->ih_cpu;
|
||||
if (ci == NULL) {
|
||||
kcpuset_zero(cpuset);
|
||||
return;
|
||||
}
|
||||
|
||||
kcpuset_set(cpuset, cpu_index(ci));
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
intr_set_affinity(struct intrsource *isp, const kcpuset_t *cpuset)
|
||||
{
|
||||
struct cpu_info *oldci, *newci;
|
||||
struct intrhand *ih, *lih;
|
||||
struct pic *pic;
|
||||
u_int cpu_idx;
|
||||
int idt_vec;
|
||||
int oldslot, newslot;
|
||||
int err;
|
||||
int pin;
|
||||
|
||||
KASSERT(mutex_owned(&cpu_lock));
|
||||
|
||||
/* XXX
|
||||
* logical destination mode is not supported, use lowest index cpu.
|
||||
*/
|
||||
cpu_idx = kcpuset_ffs(cpuset) - 1;
|
||||
newci = cpu_lookup(cpu_idx);
|
||||
if (newci == NULL) {
|
||||
DPRINTF(("invalid cpu index: %u\n", cpu_idx));
|
||||
return EINVAL;
|
||||
}
|
||||
if ((newci->ci_schedstate.spc_flags & SPCF_NOINTR) != 0) {
|
||||
DPRINTF(("the cpu is set nointr shield. index:%u\n", cpu_idx));
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (isp == NULL) {
|
||||
DPRINTF(("invalid intrctl handler\n"));
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* i8259_pic supports only primary cpu, see i8259.c. */
|
||||
pic = isp->is_pic;
|
||||
if (pic == &i8259_pic) {
|
||||
DPRINTF(("i8259 pic does not support set_affinity\n"));
|
||||
return ENOTSUP;
|
||||
}
|
||||
|
||||
ih = isp->is_handlers;
|
||||
oldci = ih->ih_cpu;
|
||||
if (newci == oldci) /* nothing to do */
|
||||
return 0;
|
||||
|
||||
oldslot = ih->ih_slot;
|
||||
idt_vec = isp->is_idtvec;
|
||||
|
||||
err = intr_find_unused_slot(newci, &newslot);
|
||||
if (err) {
|
||||
DPRINTF(("failed to allocate interrupt slot for PIC %s intrid %s\n",
|
||||
isp->is_pic->pic_name, isp->is_intrid));
|
||||
return err;
|
||||
}
|
||||
|
||||
pin = isp->is_pin;
|
||||
(*pic->pic_hwmask)(pic, pin); /* for ci_ipending check */
|
||||
if (oldci->ci_ipending & (1 << oldslot)) {
|
||||
(*pic->pic_hwunmask)(pic, pin);
|
||||
DPRINTF(("pin %d on cpuid %ld has pending interrupts.\n",
|
||||
pin, oldci->ci_cpuid));
|
||||
return EBUSY;
|
||||
}
|
||||
|
||||
kpreempt_disable();
|
||||
|
||||
/* deactivate old interrupt setting */
|
||||
if (oldci == curcpu() || !mp_online) {
|
||||
intr_deactivate_xcall(ih, NULL);
|
||||
} else {
|
||||
uint64_t where;
|
||||
where = xc_unicast(0, intr_deactivate_xcall, ih,
|
||||
NULL, oldci);
|
||||
xc_wait(where);
|
||||
}
|
||||
intr_save_evcnt(isp, oldci->ci_cpuid);
|
||||
(*pic->pic_delroute)(pic, oldci, pin, idt_vec, isp->is_type);
|
||||
|
||||
/* activate new interrupt setting */
|
||||
newci->ci_isources[newslot] = isp;
|
||||
for (lih = ih; lih != NULL; lih = lih->ih_next) {
|
||||
newci->ci_nintrhand++;
|
||||
lih->ih_cpu = newci;
|
||||
lih->ih_slot = newslot;
|
||||
}
|
||||
if (newci == curcpu() || !mp_online) {
|
||||
intr_activate_xcall(ih, NULL);
|
||||
} else {
|
||||
uint64_t where;
|
||||
where = xc_unicast(0, intr_activate_xcall, ih,
|
||||
NULL, newci);
|
||||
xc_wait(where);
|
||||
}
|
||||
intr_restore_evcnt(isp, newci->ci_cpuid);
|
||||
isp->is_active_cpu = newci->ci_cpuid;
|
||||
(*pic->pic_addroute)(pic, newci, pin, idt_vec, isp->is_type);
|
||||
|
||||
kpreempt_enable();
|
||||
|
||||
(*pic->pic_hwunmask)(pic, pin);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
intr_distribute(struct intrhand *ih, const kcpuset_t *newset, kcpuset_t *oldset)
|
||||
{
|
||||
struct intrsource *isp;
|
||||
int ret, slot;
|
||||
|
||||
if (ih == NULL)
|
||||
return EINVAL;
|
||||
|
||||
mutex_enter(&cpu_lock);
|
||||
|
||||
slot = ih->ih_slot;
|
||||
isp = ih->ih_cpu->ci_isources[slot];
|
||||
KASSERT(isp != NULL);
|
||||
|
||||
if (oldset != NULL)
|
||||
intr_get_affinity(isp, oldset);
|
||||
|
||||
ret = intr_set_affinity(isp, newset);
|
||||
|
||||
mutex_exit(&cpu_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_stub.c,v 1.38 2013/12/09 18:06:27 pooka Exp $ */
|
||||
/* $NetBSD: kern_stub.c,v 1.39 2015/04/27 06:42:53 knakahara Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -62,7 +62,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_stub.c,v 1.38 2013/12/09 18:06:27 pooka Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_stub.c,v 1.39 2015/04/27 06:42:53 knakahara Exp $");
|
||||
|
||||
#include "opt_ptrace.h"
|
||||
#include "opt_ktrace.h"
|
||||
|
@ -147,6 +147,8 @@ __weak_alias(userconf_prompt, voidop);
|
|||
|
||||
__weak_alias(kobj_renamespace, nullop);
|
||||
|
||||
__weak_alias(pci_intr_distribute, eopnotsupp);
|
||||
|
||||
/*
|
||||
* Scheduler activations system calls. These need to remain until libc's
|
||||
* major version is bumped.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: intr.h,v 1.17 2014/05/25 15:42:01 rmind Exp $ */
|
||||
/* $NetBSD: intr.h,v 1.18 2015/04/27 06:42:53 knakahara Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007 The NetBSD Foundation, Inc.
|
||||
|
@ -32,6 +32,8 @@
|
|||
#ifndef _SYS_INTR_H_
|
||||
#define _SYS_INTR_H_
|
||||
|
||||
#define INTRIDBUF 64
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <sys/types.h>
|
||||
|
|
Loading…
Reference in New Issue