diff options
author | John Baldwin <jhb@FreeBSD.org> | 2007-05-08 21:29:14 +0000 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2007-05-08 21:29:14 +0000 |
commit | fb610ca1f90722fd133172ac73ab45c7980ea6e9 (patch) | |
tree | b0dfc79e653fe3855596822772a53089b1187f41 /sys/amd64/amd64/nexus.c | |
parent | d287f590628fdf4fbdef05005ce3c2f9c0dc5a8f (diff) | |
download | src-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.c | 26 |
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 |