Date: Tue, 29 Mar 2011 00:06:02 +0000 (UTC) From: Marcel Moolenaar <marcel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r220117 - projects/altix/sys/ia64/ia64 Message-ID: <201103290006.p2T062Ea010795@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201103290006.p2T062Ea010795>