svn commit: r220117 - projects/altix/sys/ia64/ia64
Marcel Moolenaar
marcel at FreeBSD.org
Tue Mar 29 00:06:02 UTC 2011
Author: marcel
Date: Tue Mar 29 00:06:02 2011
New Revision: 220117
URL: http://svn.freebsd.org/changeset/base/220117
Log:
Slightly rework the interrupt setup code to eliminate the hard
dependency on I/O SAPICs.
Modified:
projects/altix/sys/ia64/ia64/interrupt.c
Modified: projects/altix/sys/ia64/ia64/interrupt.c
==============================================================================
--- projects/altix/sys/ia64/ia64/interrupt.c Mon Mar 28 23:08:18 2011 (r220116)
+++ projects/altix/sys/ia64/ia64/interrupt.c Tue Mar 29 00:06:02 2011 (r220117)
@@ -190,13 +190,35 @@ ia64_intr_unmask(void *arg)
sapic_unmask(i->sapic, i->irq);
}
+static int
+ia64_create_event(struct ia64_intr *i, u_int xiv, const char *name)
+{
+ char *intrname;
+ int error;
+
+ error = intr_event_create(&i->event, (void *)(uintptr_t)xiv, 0,
+ i->irq, ia64_intr_mask, ia64_intr_unmask, ia64_intr_eoi, NULL,
+ "irq%u:", i->irq);
+ if (error)
+ return (error);
+
+ i->cntp = intrcnt + xiv;
+ if (name != NULL && *name != '\0') {
+ /* XXX needs abstraction. Too error prone. */
+ intrname = intrnames + xiv * INTRNAME_LEN;
+ memset(intrname, ' ', INTRNAME_LEN - 1);
+ bcopy(name, intrname, strlen(name));
+ }
+
+ return (0);
+}
+
int
ia64_setup_intr(const char *name, int irq, driver_filter_t filter,
driver_intr_t handler, void *arg, enum intr_type flags, void **cookiep)
{
struct ia64_intr *i;
struct sapic *sa;
- char *intrname;
u_int prio, xiv;
int error;
@@ -209,65 +231,94 @@ ia64_setup_intr(const char *name, int ir
/* Get the I/O SAPIC and XIV that corresponds to the IRQ. */
sa = sapic_lookup(irq, &xiv);
if (sa == NULL) {
- /* XXX unlock */
- printf("XXX %s: no I/O SAPIC -- can't setup IRQ %u\n",
- __func__, irq);
- return (0);
- }
-
- if (xiv == 0) {
- /* XXX unlock */
- i = malloc(sizeof(struct ia64_intr), M_DEVBUF,
- M_ZERO | M_WAITOK);
- /* XXX lock */
- sa = sapic_lookup(irq, &xiv);
- KASSERT(sa != NULL, ("sapic_lookup"));
- if (xiv != 0)
- free(i, M_DEVBUF);
- }
-
- /*
- * If the IRQ has no XIV assigned to it yet, assign one based
- * on the priority.
- */
- if (xiv == 0) {
- xiv = ia64_xiv_alloc(prio, IA64_XIV_IRQ, ia64_ih_irq);
- if (xiv == 0) {
+ /* XXX assume SGI Altix... */
+ xiv = irq;
+ i = ia64_intrs[xiv];
+ if (i == NULL) {
/* XXX unlock */
- free(i, M_DEVBUF);
- return (ENOSPC);
- }
- error = intr_event_create(&i->event, (void *)(uintptr_t)xiv,
- 0, irq, ia64_intr_mask, ia64_intr_unmask, ia64_intr_eoi,
- NULL, "irq%u:", irq);
- if (error) {
- ia64_xiv_free(xiv, IA64_XIV_IRQ);
- /* XXX unlock */
- free(i, M_DEVBUF);
- return (error);
- }
+ i = malloc(sizeof(struct ia64_intr), M_DEVBUF,
+ M_ZERO | M_WAITOK);
- i->sapic = sa;
- i->irq = irq;
- i->cntp = intrcnt + xiv;
- ia64_intrs[xiv] = i;
-
- /* XXX unlock */
-
- sapic_enable(sa, irq, xiv);
-
- if (name != NULL && *name != '\0') {
- /* XXX needs abstraction. Too error prone. */
- intrname = intrnames + xiv * INTRNAME_LEN;
- memset(intrname, ' ', INTRNAME_LEN - 1);
- bcopy(name, intrname, strlen(name));
+ /* XXX lock */
+
+ if (ia64_intrs[xiv] == NULL) {
+ error = ia64_xiv_reserve(xiv, IA64_XIV_IRQ,
+ ia64_ih_irq);
+ if (error) {
+ /* XXX unlock */
+
+ free(i, M_DEVBUF);
+ return (error);
+ }
+
+ i->irq = irq;
+ error = ia64_create_event(i, xiv, name);
+ if (error != 0) {
+ ia64_xiv_free(xiv, IA64_XIV_IRQ);
+
+ /* XXX unlock */
+
+ free(i, M_DEVBUF);
+ return (error);
+ }
+
+ // sgisn_register_intr();
+ ia64_intrs[xiv] = i;
+ } else {
+ free(i, M_DEVBUF);
+ i = ia64_intrs[xiv];
+ }
}
} else {
- i = ia64_intrs[xiv];
- /* XXX unlock */
+ if (xiv == 0) {
+ /* XXX unlock */
+
+ i = malloc(sizeof(struct ia64_intr), M_DEVBUF,
+ M_ZERO | M_WAITOK);
+
+ /* XXX lock */
+
+ /*
+ * Make sure some other thread hasn't registered an
+ * event for the same IRQ while the window was open.
+ */
+ sa = sapic_lookup(irq, &xiv);
+ KASSERT(sa != NULL, ("sapic_lookup"));
+ if (xiv != 0) {
+ free(i, M_DEVBUF);
+ i = ia64_intrs[xiv];
+ } else {
+ xiv = ia64_xiv_alloc(prio, IA64_XIV_IRQ,
+ ia64_ih_irq);
+ if (xiv == 0) {
+ /* XXX unlock */
+
+ free(i, M_DEVBUF);
+ return (ENOSPC);
+ }
+
+ i->irq = irq;
+ error = ia64_create_event(i, xiv, name);
+ if (error != 0) {
+ ia64_xiv_free(xiv, IA64_XIV_IRQ);
+
+ /* XXX unlock */
+
+ free(i, M_DEVBUF);
+ return (error);
+ }
+
+ i->sapic = sa;
+ sapic_enable(sa, irq, xiv);
+ ia64_intrs[xiv] = i;
+ }
+ } else
+ i = ia64_intrs[xiv];
}
+ /* XXX unlock */
+
KASSERT(i != NULL, ("XIV mapping bug"));
error = intr_event_add_handler(i->event, name, filter, handler, arg,
More information about the svn-src-projects
mailing list