aboutsummaryrefslogtreecommitdiff
path: root/sys/amd64
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2007-05-08 21:29:14 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2007-05-08 21:29:14 +0000
commitfb610ca1f90722fd133172ac73ab45c7980ea6e9 (patch)
treeb0dfc79e653fe3855596822772a53089b1187f41 /sys/amd64
parentd287f590628fdf4fbdef05005ce3c2f9c0dc5a8f (diff)
Notes
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/amd64/intr_machdep.c65
-rw-r--r--sys/amd64/amd64/io_apic.c22
-rw-r--r--sys/amd64/amd64/local_apic.c12
-rw-r--r--sys/amd64/amd64/msi.c128
-rw-r--r--sys/amd64/amd64/nexus.c26
-rw-r--r--sys/amd64/include/apicvar.h1
-rw-r--r--sys/amd64/include/intr_machdep.h9
-rw-r--r--sys/amd64/isa/atpic.c14
8 files changed, 169 insertions, 108 deletions
diff --git a/sys/amd64/amd64/intr_machdep.c b/sys/amd64/amd64/intr_machdep.c
index 12191db74825..2864868d731d 100644
--- a/sys/amd64/amd64/intr_machdep.c
+++ b/sys/amd64/amd64/intr_machdep.c
@@ -43,13 +43,14 @@
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/interrupt.h>
-#include <sys/lock.h>
#include <sys/ktr.h>
#include <sys/kernel.h>
+#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/syslog.h>
#include <sys/systm.h>
+#include <sys/sx.h>
#include <machine/clock.h>
#include <machine/intr_machdep.h>
#include <machine/smp.h>
@@ -71,7 +72,8 @@ typedef void (*mask_fn)(void *);
static int intrcnt_index;
static struct intsrc *interrupt_sources[NUM_IO_INTS];
-static struct mtx intr_table_lock;
+static struct sx intr_table_lock;
+static struct mtx intrcnt_lock;
static STAILQ_HEAD(, pic) pics;
#ifdef INTR_FILTER
@@ -115,14 +117,14 @@ intr_register_pic(struct pic *pic)
{
int error;
- mtx_lock_spin(&intr_table_lock);
+ sx_xlock(&intr_table_lock);
if (intr_pic_registered(pic))
error = EBUSY;
else {
STAILQ_INSERT_TAIL(&pics, pic, pics);
error = 0;
}
- mtx_unlock_spin(&intr_table_lock);
+ sx_xunlock(&intr_table_lock);
return (error);
}
@@ -150,16 +152,16 @@ intr_register_source(struct intsrc *isrc)
#endif
if (error)
return (error);
- mtx_lock_spin(&intr_table_lock);
+ sx_xlock(&intr_table_lock);
if (interrupt_sources[vector] != NULL) {
- mtx_unlock_spin(&intr_table_lock);
+ sx_xunlock(&intr_table_lock);
intr_event_destroy(isrc->is_event);
return (EEXIST);
}
intrcnt_register(isrc);
interrupt_sources[vector] = isrc;
- isrc->is_enabled = 0;
- mtx_unlock_spin(&intr_table_lock);
+ isrc->is_handlers = 0;
+ sx_xunlock(&intr_table_lock);
return (0);
}
@@ -183,19 +185,18 @@ intr_add_handler(const char *name, int vector, driver_filter_t filter,
error = intr_event_add_handler(isrc->is_event, name, filter, handler,
arg, intr_priority(flags), flags, cookiep);
if (error == 0) {
+ sx_xlock(&intr_table_lock);
intrcnt_updatename(isrc);
- mtx_lock_spin(&intr_table_lock);
- if (!isrc->is_enabled) {
- isrc->is_enabled = 1;
+ isrc->is_handlers++;
+ if (isrc->is_handlers == 1) {
#ifdef SMP
if (assign_cpu)
intr_assign_next_cpu(isrc);
#endif
- mtx_unlock_spin(&intr_table_lock);
isrc->is_pic->pic_enable_intr(isrc);
- } else
- mtx_unlock_spin(&intr_table_lock);
- isrc->is_pic->pic_enable_source(isrc);
+ isrc->is_pic->pic_enable_source(isrc);
+ }
+ sx_xunlock(&intr_table_lock);
}
return (error);
}
@@ -208,8 +209,16 @@ intr_remove_handler(void *cookie)
isrc = intr_handler_source(cookie);
error = intr_event_remove_handler(cookie);
- if (error == 0)
+ if (error == 0) {
+ sx_xlock(&intr_table_lock);
+ isrc->is_handlers--;
+ if (isrc->is_handlers == 0) {
+ isrc->is_pic->pic_disable_source(isrc, PIC_NO_EOI);
+ isrc->is_pic->pic_disable_intr(isrc);
+ }
intrcnt_updatename(isrc);
+ sx_xunlock(&intr_table_lock);
+ }
return (error);
}
@@ -391,12 +400,12 @@ intr_resume(void)
#ifndef DEV_ATPIC
atpic_reset();
#endif
- mtx_lock_spin(&intr_table_lock);
+ sx_xlock(&intr_table_lock);
STAILQ_FOREACH(pic, &pics, pics) {
if (pic->pic_resume != NULL)
pic->pic_resume(pic);
}
- mtx_unlock_spin(&intr_table_lock);
+ sx_xunlock(&intr_table_lock);
}
void
@@ -404,12 +413,12 @@ intr_suspend(void)
{
struct pic *pic;
- mtx_lock_spin(&intr_table_lock);
+ sx_xlock(&intr_table_lock);
STAILQ_FOREACH(pic, &pics, pics) {
if (pic->pic_suspend != NULL)
pic->pic_suspend(pic);
}
- mtx_unlock_spin(&intr_table_lock);
+ sx_xunlock(&intr_table_lock);
}
static void
@@ -432,8 +441,8 @@ intrcnt_register(struct intsrc *is)
{
char straystr[MAXCOMLEN + 1];
- /* mtx_assert(&intr_table_lock, MA_OWNED); */
KASSERT(is->is_event != NULL, ("%s: isrc with no event", __func__));
+ mtx_lock_spin(&intrcnt_lock);
is->is_index = intrcnt_index;
intrcnt_index += 2;
snprintf(straystr, MAXCOMLEN + 1, "stray irq%d",
@@ -442,17 +451,18 @@ intrcnt_register(struct intsrc *is)
is->is_count = &intrcnt[is->is_index];
intrcnt_setname(straystr, is->is_index + 1);
is->is_straycount = &intrcnt[is->is_index + 1];
+ mtx_unlock_spin(&intrcnt_lock);
}
void
intrcnt_add(const char *name, u_long **countp)
{
- mtx_lock_spin(&intr_table_lock);
+ mtx_lock_spin(&intrcnt_lock);
*countp = &intrcnt[intrcnt_index];
intrcnt_setname(name, intrcnt_index);
intrcnt_index++;
- mtx_unlock_spin(&intr_table_lock);
+ mtx_unlock_spin(&intrcnt_lock);
}
static void
@@ -462,7 +472,8 @@ intr_init(void *dummy __unused)
intrcnt_setname("???", 0);
intrcnt_index = 1;
STAILQ_INIT(&pics);
- mtx_init(&intr_table_lock, "intr table", NULL, MTX_SPIN);
+ sx_init(&intr_table_lock, "intr sources");
+ mtx_init(&intrcnt_lock, "intrcnt", NULL, MTX_SPIN);
}
SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL)
@@ -570,14 +581,14 @@ intr_shuffle_irqs(void *arg __unused)
return;
/* Round-robin assign a CPU to each enabled source. */
- mtx_lock_spin(&intr_table_lock);
+ sx_xlock(&intr_table_lock);
assign_cpu = 1;
for (i = 0; i < NUM_IO_INTS; i++) {
isrc = interrupt_sources[i];
- if (isrc != NULL && isrc->is_enabled)
+ if (isrc != NULL && isrc->is_handlers > 0)
intr_assign_next_cpu(isrc);
}
- mtx_unlock_spin(&intr_table_lock);
+ sx_xunlock(&intr_table_lock);
}
SYSINIT(intr_shuffle_irqs, SI_SUB_SMP, SI_ORDER_SECOND, intr_shuffle_irqs, NULL)
#endif
diff --git a/sys/amd64/amd64/io_apic.c b/sys/amd64/amd64/io_apic.c
index 88b8d4c8fbf5..05b93ce656ba 100644
--- a/sys/amd64/amd64/io_apic.c
+++ b/sys/amd64/amd64/io_apic.c
@@ -114,6 +114,7 @@ static void ioapic_enable_source(struct intsrc *isrc);
static void ioapic_disable_source(struct intsrc *isrc, int eoi);
static void ioapic_eoi_source(struct intsrc *isrc);
static void ioapic_enable_intr(struct intsrc *isrc);
+static void ioapic_disable_intr(struct intsrc *isrc);
static int ioapic_vector(struct intsrc *isrc);
static int ioapic_source_pending(struct intsrc *isrc);
static int ioapic_config_intr(struct intsrc *isrc, enum intr_trigger trig,
@@ -125,8 +126,8 @@ static void ioapic_program_intpin(struct ioapic_intsrc *intpin);
static STAILQ_HEAD(,ioapic) ioapic_list = STAILQ_HEAD_INITIALIZER(ioapic_list);
struct pic ioapic_template = { ioapic_enable_source, ioapic_disable_source,
ioapic_eoi_source, ioapic_enable_intr,
- ioapic_vector, ioapic_source_pending,
- NULL, ioapic_resume,
+ ioapic_disable_intr, ioapic_vector,
+ ioapic_source_pending, NULL, ioapic_resume,
ioapic_config_intr, ioapic_assign_cpu };
static int next_ioapic_base;
@@ -359,6 +360,23 @@ ioapic_enable_intr(struct intsrc *isrc)
}
}
+static void
+ioapic_disable_intr(struct intsrc *isrc)
+{
+ struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc;
+ u_int vector;
+
+ if (intpin->io_vector != 0) {
+ /* Mask this interrupt pin and free its APIC vector. */
+ vector = intpin->io_vector;
+ apic_disable_vector(vector);
+ intpin->io_masked = 1;
+ intpin->io_vector = 0;
+ ioapic_program_intpin(intpin);
+ apic_free_vector(vector, intpin->io_irq);
+ }
+}
+
static int
ioapic_vector(struct intsrc *isrc)
{
diff --git a/sys/amd64/amd64/local_apic.c b/sys/amd64/amd64/local_apic.c
index df038f8aeaa1..fa46c9597609 100644
--- a/sys/amd64/amd64/local_apic.c
+++ b/sys/amd64/amd64/local_apic.c
@@ -147,6 +147,8 @@ static u_int32_t lapic_timer_divisors[] = {
APIC_TDCR_32, APIC_TDCR_64, APIC_TDCR_128
};
+extern inthand_t IDTVEC(rsvd);
+
volatile lapic_t *lapic;
vm_paddr_t lapic_paddr;
static u_long lapic_timer_divisor, lapic_timer_period, lapic_timer_hz;
@@ -837,6 +839,16 @@ apic_enable_vector(u_int vector)
setidt(vector, ioint_handlers[vector / 32], SDT_SYSIGT, SEL_KPL, 0);
}
+void
+apic_disable_vector(u_int vector)
+{
+
+ KASSERT(vector != IDT_SYSCALL, ("Attempt to overwrite syscall entry"));
+ KASSERT(ioint_handlers[vector / 32] != NULL,
+ ("No ISR handler for vector %u", vector));
+ setidt(vector, &IDTVEC(rsvd), SDT_SYSIGT, SEL_KPL, 0);
+}
+
/* Release an APIC vector when it's no longer in use. */
void
apic_free_vector(u_int vector, u_int irq)
diff --git a/sys/amd64/amd64/msi.c b/sys/amd64/amd64/msi.c
index 3bb184c274f5..6440852375c2 100644
--- a/sys/amd64/amd64/msi.c
+++ b/sys/amd64/amd64/msi.c
@@ -112,11 +112,12 @@ struct msi_intsrc {
u_int msi_count:8; /* Messages in this group. (g) */
};
-static struct msi_intsrc *msi_create_source(u_int irq);
+static void msi_create_source(void);
static void msi_enable_source(struct intsrc *isrc);
static void msi_disable_source(struct intsrc *isrc, int eoi);
static void msi_eoi_source(struct intsrc *isrc);
static void msi_enable_intr(struct intsrc *isrc);
+static void msi_disable_intr(struct intsrc *isrc);
static int msi_vector(struct intsrc *isrc);
static int msi_source_pending(struct intsrc *isrc);
static int msi_config_intr(struct intsrc *isrc, enum intr_trigger trig,
@@ -124,11 +125,13 @@ static int msi_config_intr(struct intsrc *isrc, enum intr_trigger trig,
static void msi_assign_cpu(struct intsrc *isrc, u_int apic_id);
struct pic msi_pic = { msi_enable_source, msi_disable_source, msi_eoi_source,
- msi_enable_intr, msi_vector, msi_source_pending,
- NULL, NULL, msi_config_intr, msi_assign_cpu };
+ msi_enable_intr, msi_disable_intr, msi_vector,
+ msi_source_pending, NULL, NULL, msi_config_intr,
+ msi_assign_cpu };
static int msi_enabled;
-static struct sx msi_sx;
+static int msi_last_irq;
+static struct mtx msi_lock;
static void
msi_enable_source(struct intsrc *isrc)
@@ -158,6 +161,14 @@ msi_enable_intr(struct intsrc *isrc)
apic_enable_vector(msi->msi_vector);
}
+static void
+msi_disable_intr(struct intsrc *isrc)
+{
+ struct msi_intsrc *msi = (struct msi_intsrc *)isrc;
+
+ apic_disable_vector(msi->msi_vector);
+}
+
static int
msi_vector(struct intsrc *isrc)
{
@@ -191,8 +202,7 @@ msi_assign_cpu(struct intsrc *isrc, u_int apic_id)
printf("msi: Assigning %s IRQ %d to local APIC %u\n",
msi->msi_msix ? "MSI-X" : "MSI", msi->msi_irq,
msi->msi_cpu);
- if (isrc->is_enabled)
- pci_remap_msi_irq(msi->msi_dev, msi->msi_irq);
+ pci_remap_msi_irq(msi->msi_dev, msi->msi_irq);
}
void
@@ -206,19 +216,29 @@ msi_init(void)
msi_enabled = 1;
intr_register_pic(&msi_pic);
- sx_init(&msi_sx, "msi");
+ mtx_init(&msi_lock, "msi", NULL, MTX_DEF);
}
-struct msi_intsrc *
-msi_create_source(u_int irq)
+void
+msi_create_source(void)
{
struct msi_intsrc *msi;
+ u_int irq;
+
+ mtx_lock(&msi_lock);
+ if (msi_last_irq >= NUM_MSI_INTS) {
+ mtx_unlock(&msi_lock);
+ return;
+ }
+ irq = msi_last_irq + FIRST_MSI_INT;
+ msi_last_irq++;
+ mtx_unlock(&msi_lock);
- msi = malloc(sizeof(struct msi_intsrc), M_MSI, M_WAITOK | M_ZERO);
+ msi = malloc(sizeof(struct msi_intsrc), M_MSI, M_WAITOK | M_ZERO);
msi->msi_intsrc.is_pic = &msi_pic;
msi->msi_irq = irq;
intr_register_source(&msi->msi_intsrc);
- return (msi);
+ nexus_add_irq(irq);
}
/*
@@ -228,18 +248,16 @@ msi_create_source(u_int irq)
* and *newcount being the number of new IRQ values added.
*/
int
-msi_alloc(device_t dev, int count, int maxcount, int *irqs, int *newirq,
- int *newcount)
+msi_alloc(device_t dev, int count, int maxcount, int *irqs)
{
struct msi_intsrc *msi, *fsrc;
- int cnt, i, j, vector;
+ int cnt, i, vector;
- *newirq = 0;
- *newcount = 0;
if (!msi_enabled)
return (ENXIO);
- sx_xlock(&msi_sx);
+again:
+ mtx_lock(&msi_lock);
/* Try to find 'count' free IRQs. */
cnt = 0;
@@ -263,20 +281,17 @@ msi_alloc(device_t dev, int count, int maxcount, int *irqs, int *newirq,
if (cnt < count) {
/* If we would exceed the max, give up. */
if (i + (count - cnt) > FIRST_MSI_INT + NUM_MSI_INTS) {
- sx_xunlock(&msi_sx);
+ mtx_unlock(&msi_lock);
return (ENXIO);
}
+ mtx_unlock(&msi_lock);
- /* We need count - cnt more sources starting at index 'cnt'. */
- *newirq = cnt;
- *newcount = count - cnt;
- for (j = 0; j < *newcount; j++) {
-
- /* Create a new MSI source and add it to our array. */
- msi_create_source(i + j);
- irqs[cnt] = i + j;
+ /* We need count - cnt more sources. */
+ while (cnt < count) {
+ msi_create_source();
cnt++;
}
+ goto again;
}
/* Ok, we now have the IRQs allocated. */
@@ -285,7 +300,7 @@ msi_alloc(device_t dev, int count, int maxcount, int *irqs, int *newirq,
/* Allocate 'count' IDT vectors. */
vector = apic_alloc_vectors(irqs, count, maxcount);
if (vector == 0) {
- sx_xunlock(&msi_sx);
+ mtx_unlock(&msi_lock);
return (ENOSPC);
}
@@ -299,12 +314,11 @@ msi_alloc(device_t dev, int count, int maxcount, int *irqs, int *newirq,
printf("msi: routing MSI IRQ %d to vector %u\n",
msi->msi_irq, msi->msi_vector);
msi->msi_first = fsrc;
-
- /* XXX: Somewhat gross. */
- msi->msi_intsrc.is_enabled = 0;
+ KASSERT(msi->msi_intsrc.is_handlers == 0,
+ ("dead MSI has handlers"));
}
fsrc->msi_count = count;
- sx_xunlock(&msi_sx);
+ mtx_unlock(&msi_lock);
return (0);
}
@@ -315,22 +329,22 @@ msi_release(int *irqs, int count)
struct msi_intsrc *msi, *first;
int i;
- sx_xlock(&msi_sx);
+ mtx_lock(&msi_lock);
first = (struct msi_intsrc *)intr_lookup_source(irqs[0]);
if (first == NULL) {
- sx_xunlock(&msi_sx);
+ mtx_unlock(&msi_lock);
return (ENOENT);
}
/* Make sure this isn't an MSI-X message. */
if (first->msi_msix) {
- sx_xunlock(&msi_sx);
+ mtx_unlock(&msi_lock);
return (EINVAL);
}
/* Make sure this message is allocated to a group. */
if (first->msi_first == NULL) {
- sx_xunlock(&msi_sx);
+ mtx_unlock(&msi_lock);
return (ENXIO);
}
@@ -339,7 +353,7 @@ msi_release(int *irqs, int count)
* the entire group.
*/
if (first->msi_first != first || first->msi_count != count) {
- sx_xunlock(&msi_sx);
+ mtx_unlock(&msi_lock);
return (EINVAL);
}
KASSERT(first->msi_dev != NULL, ("unowned group"));
@@ -362,7 +376,7 @@ msi_release(int *irqs, int count)
first->msi_vector = 0;
first->msi_count = 0;
- sx_xunlock(&msi_sx);
+ mtx_unlock(&msi_lock);
return (0);
}
@@ -371,27 +385,27 @@ msi_map(int irq, uint64_t *addr, uint32_t *data)
{
struct msi_intsrc *msi;
- sx_slock(&msi_sx);
+ mtx_lock(&msi_lock);
msi = (struct msi_intsrc *)intr_lookup_source(irq);
if (msi == NULL) {
- sx_sunlock(&msi_sx);
+ mtx_unlock(&msi_lock);
return (ENOENT);
}
/* Make sure this message is allocated to a device. */
if (msi->msi_dev == NULL) {
- sx_sunlock(&msi_sx);
+ mtx_unlock(&msi_lock);
return (ENXIO);
}
/*
* If this message isn't an MSI-X message, make sure it's part
- * of a gruop, and switch to the first message in the
+ * of a group, and switch to the first message in the
* group.
*/
if (!msi->msi_msix) {
if (msi->msi_first == NULL) {
- sx_sunlock(&msi_sx);
+ mtx_unlock(&msi_lock);
return (ENXIO);
}
msi = msi->msi_first;
@@ -399,21 +413,21 @@ msi_map(int irq, uint64_t *addr, uint32_t *data)
*addr = INTEL_ADDR(msi);
*data = INTEL_DATA(msi);
- sx_sunlock(&msi_sx);
+ mtx_unlock(&msi_lock);
return (0);
}
int
-msix_alloc(device_t dev, int *irq, int *new)
+msix_alloc(device_t dev, int *irq)
{
struct msi_intsrc *msi;
int i, vector;
- *new = 0;
if (!msi_enabled)
return (ENXIO);
- sx_xlock(&msi_sx);
+again:
+ mtx_lock(&msi_lock);
/* Find a free IRQ. */
for (i = FIRST_MSI_INT; i < FIRST_MSI_INT + NUM_MSI_INTS; i++) {
@@ -423,7 +437,7 @@ msix_alloc(device_t dev, int *irq, int *new)
if (msi == NULL)
break;
- /* If this is a free one, start or continue a run. */
+ /* Stop at the first free source. */
if (msi->msi_dev == NULL)
break;
}
@@ -432,13 +446,14 @@ msix_alloc(device_t dev, int *irq, int *new)
if (msi == NULL) {
/* If we would exceed the max, give up. */
if (i + 1 > FIRST_MSI_INT + NUM_MSI_INTS) {
- sx_xunlock(&msi_sx);
+ mtx_unlock(&msi_lock);
return (ENXIO);
}
+ mtx_unlock(&msi_lock);
/* Create a new source. */
- *new = 1;
- msi = msi_create_source(i);
+ msi_create_source();
+ goto again;
}
/* Allocate an IDT vector. */
@@ -452,9 +467,8 @@ msix_alloc(device_t dev, int *irq, int *new)
msi->msi_vector = vector;
msi->msi_msix = 1;
- /* XXX: Somewhat gross. */
- msi->msi_intsrc.is_enabled = 0;
- sx_xunlock(&msi_sx);
+ KASSERT(msi->msi_intsrc.is_handlers == 0, ("dead MSI-X has handlers"));
+ mtx_unlock(&msi_lock);
*irq = i;
return (0);
@@ -465,16 +479,16 @@ msix_release(int irq)
{
struct msi_intsrc *msi;
- sx_xlock(&msi_sx);
+ mtx_lock(&msi_lock);
msi = (struct msi_intsrc *)intr_lookup_source(irq);
if (msi == NULL) {
- sx_xunlock(&msi_sx);
+ mtx_unlock(&msi_lock);
return (ENOENT);
}
/* Make sure this is an MSI-X message. */
if (!msi->msi_msix) {
- sx_xunlock(&msi_sx);
+ mtx_unlock(&msi_lock);
return (EINVAL);
}
@@ -486,6 +500,6 @@ msix_release(int irq)
msi->msi_vector = 0;
msi->msi_msix = 0;
- sx_xunlock(&msi_sx);
+ mtx_unlock(&msi_lock);
return (0);
}
diff --git a/sys/amd64/amd64/nexus.c b/sys/amd64/amd64/nexus.c
index 108abc117969..b5498b7d1e18 100644
--- a/sys/amd64/amd64/nexus.c
+++ b/sys/amd64/amd64/nexus.c
@@ -503,15 +503,20 @@ nexus_delete_resource(device_t dev, device_t child, int type, int rid)
resource_list_delete(rl, type, rid);
}
+/* Called from the MSI code to add new IRQs to the IRQ rman. */
+void
+nexus_add_irq(u_long irq)
+{
+
+ if (rman_manage_region(&irq_rman, irq, irq) != 0)
+ panic("%s: failed", __func__);
+}
+
static int
nexus_alloc_msix(device_t pcib, device_t dev, int *irq)
{
- int error, new;
- error = msix_alloc(dev, irq, &new);
- if (new)
- rman_manage_region(&irq_rman, *irq, *irq);
- return (error);
+ return (msix_alloc(dev, irq));
}
static int
@@ -524,17 +529,8 @@ nexus_release_msix(device_t pcib, device_t dev, int irq)
static int
nexus_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs)
{
- int error, i, newirq, newcount;
-
- /* First alloc the messages. */
- error = msi_alloc(dev, count, maxcount, irqs, &newirq, &newcount);
- /* Always add any new IRQs to the rman, even on failure. */
- for (i = 0; i < newcount; i++)
- rman_manage_region(&irq_rman, irqs[newirq + i],
- irqs[newirq + i]);
-
- return (error);
+ return (msi_alloc(dev, count, maxcount, irqs));
}
static int
diff --git a/sys/amd64/include/apicvar.h b/sys/amd64/include/apicvar.h
index 9ffe17c56e52..107656b687d7 100644
--- a/sys/amd64/include/apicvar.h
+++ b/sys/amd64/include/apicvar.h
@@ -178,6 +178,7 @@ extern vm_paddr_t lapic_paddr;
u_int apic_alloc_vector(u_int irq);
u_int apic_alloc_vectors(u_int *irqs, u_int count, u_int align);
+void apic_disable_vector(u_int vector);
void apic_enable_vector(u_int vector);
void apic_free_vector(u_int vector, u_int irq);
u_int apic_idt_to_irq(u_int vector);
diff --git a/sys/amd64/include/intr_machdep.h b/sys/amd64/include/intr_machdep.h
index fd7fa3c49165..8b16c5e2fabc 100644
--- a/sys/amd64/include/intr_machdep.h
+++ b/sys/amd64/include/intr_machdep.h
@@ -86,6 +86,7 @@ struct pic {
void (*pic_disable_source)(struct intsrc *, int);
void (*pic_eoi_source)(struct intsrc *);
void (*pic_enable_intr)(struct intsrc *);
+ void (*pic_disable_intr)(struct intsrc *);
int (*pic_vector)(struct intsrc *);
int (*pic_source_pending)(struct intsrc *);
void (*pic_suspend)(struct pic *);
@@ -114,7 +115,7 @@ struct intsrc {
u_long *is_count;
u_long *is_straycount;
u_int is_index;
- u_int is_enabled:1;
+ u_int is_handlers;
};
struct trapframe;
@@ -146,12 +147,12 @@ int intr_remove_handler(void *cookie);
void intr_resume(void);
void intr_suspend(void);
void intrcnt_add(const char *name, u_long **countp);
-int msi_alloc(device_t dev, int count, int maxcount, int *irqs, int *newirq,
- int *newcount);
+void nexus_add_irq(u_long irq);
+int msi_alloc(device_t dev, int count, int maxcount, int *irqs);
void msi_init(void);
int msi_map(int irq, uint64_t *addr, uint32_t *data);
int msi_release(int *irqs, int count);
-int msix_alloc(device_t dev, int *irq, int *new);
+int msix_alloc(device_t dev, int *irq);
int msix_release(int irq);
#endif /* !LOCORE */
diff --git a/sys/amd64/isa/atpic.c b/sys/amd64/isa/atpic.c
index 3a88eda4ef10..d9792eb8fcde 100644
--- a/sys/amd64/isa/atpic.c
+++ b/sys/amd64/isa/atpic.c
@@ -107,9 +107,10 @@ inthand_t
#define ATPIC(io, base, eoi, imenptr) \
{ { atpic_enable_source, atpic_disable_source, (eoi), \
- atpic_enable_intr, atpic_vector, atpic_source_pending, NULL, \
- atpic_resume, atpic_config_intr, atpic_assign_cpu }, (io), \
- (base), IDT_IO_INTS + (base), (imenptr) }
+ atpic_enable_intr, atpic_disable_intr, atpic_vector, \
+ atpic_source_pending, NULL, atpic_resume, atpic_config_intr,\
+ atpic_assign_cpu }, (io), (base), IDT_IO_INTS + (base), \
+ (imenptr) }
#define INTSRC(irq) \
{ { &atpics[(irq) / 8].at_pic }, IDTVEC(atpic_intr ## irq ), \
@@ -137,6 +138,7 @@ static void atpic_disable_source(struct intsrc *isrc, int eoi);
static void atpic_eoi_master(struct intsrc *isrc);
static void atpic_eoi_slave(struct intsrc *isrc);
static void atpic_enable_intr(struct intsrc *isrc);
+static void atpic_disable_intr(struct intsrc *isrc);
static int atpic_vector(struct intsrc *isrc);
static void atpic_resume(struct pic *pic);
static int atpic_source_pending(struct intsrc *isrc);
@@ -266,6 +268,12 @@ atpic_enable_intr(struct intsrc *isrc)
{
}
+static void
+atpic_disable_intr(struct intsrc *isrc)
+{
+}
+
+
static int
atpic_vector(struct intsrc *isrc)
{