aboutsummaryrefslogtreecommitdiff
path: root/sys/amd64/amd64/nexus.c
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/amd64/nexus.c
parentd287f590628fdf4fbdef05005ce3c2f9c0dc5a8f (diff)
downloadsrc-fb610ca1f90722fd133172ac73ab45c7980ea6e9.tar.gz
src-fb610ca1f90722fd133172ac73ab45c7980ea6e9.zip
Minor fixes and tweaks to the x86 interrupt code:
- Split the intr_table_lock into an sx lock used for most things, and a spin lock to protect intrcnt_index. Originally I had this as a spin lock so interrupt code could use it to lookup sources. However, we don't actually do that because it would add a lot of overhead to interrupts, and if we ever do support removing interrupt sources, we can use other means to safely do so w/o locking in the interrupt handling code. - Replace is_enabled (boolean) with is_handlers (a count of handlers) to determine if a source is enabled or not. This allows us to notice when a source is no longer in use. When that happens, we now invoke a new PIC method (pic_disable_intr()) to inform the PIC driver that the source is no longer in use. The I/O APIC driver frees the APIC IDT vector when this happens. The MSI driver no longer needs to have a hack to clear is_enabled during msi_alloc() and msix_alloc() as a result of this change as well. - Add an apic_disable_vector() to reset an IDT vector back to Xrsvd to complement apic_enable_vector() and use it in the I/O APIC and MSI code when freeing an IDT vector. - Add a new nexus hook: nexus_add_irq() to ask the nexus driver to add an IRQ to its irq_rman. The MSI code uses this when it creates new interrupt sources to let the nexus know about newly valid IRQs. Previously the msi_alloc() and msix_alloc() passed some extra stuff back to the nexus methods which then added the IRQs. This approach is a bit cleaner. - Change the MSI sx lock to a mutex. If we need to create new sources, drop the lock, create the required number of sources, then get the lock and try the allocation again.
Notes
Notes: svn path=/head/; revision=169391
Diffstat (limited to 'sys/amd64/amd64/nexus.c')
-rw-r--r--sys/amd64/amd64/nexus.c26
1 files changed, 11 insertions, 15 deletions
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