diff options
| author | John Baldwin <jhb@FreeBSD.org> | 2010-01-21 17:55:47 +0000 |
|---|---|---|
| committer | John Baldwin <jhb@FreeBSD.org> | 2010-01-21 17:55:47 +0000 |
| commit | c3895badf7af698d10fdd2c6d3bbb188c8346b02 (patch) | |
| tree | a245209c1640a0b080e5a0e5f1a25029c890f0c2 | |
| parent | 219503bacf6d613fab7bbd8bc36692f1cdf989c3 (diff) | |
Notes
| -rw-r--r-- | share/man/man9/BUS_DESCRIBE_INTR.9 | 104 | ||||
| -rw-r--r-- | share/man/man9/Makefile | 2 | ||||
| -rw-r--r-- | sys/amd64/amd64/intr_machdep.c | 17 | ||||
| -rw-r--r-- | sys/amd64/amd64/nexus.c | 12 | ||||
| -rw-r--r-- | sys/amd64/include/intr_machdep.h | 1 | ||||
| -rw-r--r-- | sys/i386/i386/intr_machdep.c | 17 | ||||
| -rw-r--r-- | sys/i386/i386/nexus.c | 12 | ||||
| -rw-r--r-- | sys/i386/include/intr_machdep.h | 1 | ||||
| -rw-r--r-- | sys/kern/bus_if.m | 20 | ||||
| -rw-r--r-- | sys/kern/kern_intr.c | 59 | ||||
| -rw-r--r-- | sys/kern/subr_bus.c | 40 | ||||
| -rw-r--r-- | sys/sparc64/include/intr_machdep.h | 1 | ||||
| -rw-r--r-- | sys/sparc64/pci/psycho.c | 14 | ||||
| -rw-r--r-- | sys/sparc64/pci/schizo.c | 14 | ||||
| -rw-r--r-- | sys/sparc64/sparc64/intr_machdep.c | 25 | ||||
| -rw-r--r-- | sys/sparc64/sparc64/nexus.c | 16 | ||||
| -rw-r--r-- | sys/sys/bus.h | 5 | ||||
| -rw-r--r-- | sys/sys/interrupt.h | 4 |
18 files changed, 357 insertions, 7 deletions
diff --git a/share/man/man9/BUS_DESCRIBE_INTR.9 b/share/man/man9/BUS_DESCRIBE_INTR.9 new file mode 100644 index 000000000000..989780fdc609 --- /dev/null +++ b/share/man/man9/BUS_DESCRIBE_INTR.9 @@ -0,0 +1,104 @@ +.\" -*- nroff -*- +.\" +.\" Copyright (c) 2009 Advanced Computing Technologies LLC +.\" Written by: John H. Baldwin <jhb@FreeBSD.org> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd October 14, 2009 +.Dt BUS_DESCRIBE_INTR 9 +.Os +.Sh NAME +.Nm BUS_DESCRIBE_INTR , +.Nm bus_describe_intr +.Nd "associate a description with an active interrupt handler" +.Sh SYNOPSIS +.In sys/param.h +.In sys/bus.h +.Ft int +.Fo BUS_BIND_INTR +.Fa "device_t dev" "device_t child" "struct resource *irq" "void *cookie" +.Fa "const char *descr" +.Fc +.Ft int +.Fo bus_describe_intr +.Fa "device_t dev" "struct resource *irq" "void *cookie" "const char *fmt" +.Fa ... +.Fc +.Sh DESCRIPTION +The +.Fn BUS_DESCRIBE_INTR +method associates a description with an active interrupt handler. +The +.Fa cookie +parameter must be the value returned by a successful call to +.Xr BUS_SETUP_INTR 9 +for the interrupt +.Fa irq . +.Pp +The +.Fn bus_describe_intr +function is a simple wrapper around +.Fn BUS_DESCRIBE_INTR . +As a convenience, +.Fn bus_describe_intr +allows the caller to use +.Xr printf 9 +style formatting to build the description string using +.Fa fmt . +.Pp +When an interrupt handler is established by +.Xr BUS_SETUP_INTR 9 , +the handler is named after the device the handler is established for. +This name is then used in various places such as interrupt statistics +displayed by +.Xr systat 1 +and +.Xr vmstat 8 . +For devices that use a single interrupt, +the device name is sufficiently unique to identify the interrupt handler. +However, for devices that use multiple interrupts it can be useful to +distinguish the interrupt handlers. +When a description is set for an active interrupt handler, +a colon followed by the description is appended to the device name to form +the interrupt handler name. +.Sh RETURN VALUES +Zero is returned on success, otherwise an appropriate error is returned. +.Sh SEE ALSO +.Xr BUS_SETUP_INTR 9 , +.Xr systat 1 , +.Xr vmstat 8 , +.Xr device 9 , +.Xr printf 9 +.Sh HISTORY +The +.Fn BUS_DESCRIBE_INTR +method and +.Fn bus_describe_intr +functions first appeared in +.Fx 9.0 . +.Sh BUGS +It is not currently possible to remove a description from an active interrupt +handler. diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index bb57c774feef..57622fa248a0 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -24,6 +24,7 @@ MAN= accept_filter.9 \ BUS_BIND_INTR.9 \ bus_child_present.9 \ BUS_CONFIG_INTR.9 \ + BUS_DESCRIBE_INTR.9 \ bus_dma.9 \ bus_generic_attach.9 \ bus_generic_detach.9 \ @@ -379,6 +380,7 @@ MLINKS+=buf.9 bp.9 MLINKS+=bus_activate_resource.9 bus_deactivate_resource.9 MLINKS+=bus_alloc_resource.9 bus_alloc_resource_any.9 MLINKS+=BUS_BIND_INTR.9 bus_bind_intr.9 +MLINKS+=BUS_DESCRIBE_INTR.9 bus_describe_intr.9 MLINKS+=bus_dma.9 busdma.9 \ bus_dma.9 bus_dmamap_create.9 \ bus_dma.9 bus_dmamap_destroy.9 \ diff --git a/sys/amd64/amd64/intr_machdep.c b/sys/amd64/amd64/intr_machdep.c index 0563ea9d977f..83e1e2623b1d 100644 --- a/sys/amd64/amd64/intr_machdep.c +++ b/sys/amd64/amd64/intr_machdep.c @@ -405,6 +405,23 @@ atpic_reset(void) } #endif +/* Add a description to an active interrupt handler. */ +int +intr_describe(u_int vector, void *ih, const char *descr) +{ + struct intsrc *isrc; + int error; + + isrc = intr_lookup_source(vector); + if (isrc == NULL) + return (EINVAL); + error = intr_event_describe_handler(isrc->is_event, ih, descr); + if (error) + return (error); + intrcnt_updatename(isrc); + return (0); +} + #ifdef DDB /* * Dump data about interrupt handlers diff --git a/sys/amd64/amd64/nexus.c b/sys/amd64/amd64/nexus.c index f40d8d30f6ed..4dea8c73a69d 100644 --- a/sys/amd64/amd64/nexus.c +++ b/sys/amd64/amd64/nexus.c @@ -94,6 +94,9 @@ static int nexus_bind_intr(device_t, device_t, struct resource *, int); #endif static int nexus_config_intr(device_t, int, enum intr_trigger, enum intr_polarity); +static int nexus_describe_intr(device_t dev, device_t child, + struct resource *irq, void *cookie, + const char *descr); static int nexus_activate_resource(device_t, device_t, int, int, struct resource *); static int nexus_deactivate_resource(device_t, device_t, int, int, @@ -137,6 +140,7 @@ static device_method_t nexus_methods[] = { DEVMETHOD(bus_bind_intr, nexus_bind_intr), #endif DEVMETHOD(bus_config_intr, nexus_config_intr), + DEVMETHOD(bus_describe_intr, nexus_describe_intr), DEVMETHOD(bus_get_resource_list, nexus_get_reslist), DEVMETHOD(bus_set_resource, nexus_set_resource), DEVMETHOD(bus_get_resource, nexus_get_resource), @@ -472,6 +476,14 @@ nexus_config_intr(device_t dev, int irq, enum intr_trigger trig, return (intr_config_intr(irq, trig, pol)); } +static int +nexus_describe_intr(device_t dev, device_t child, struct resource *irq, + void *cookie, const char *descr) +{ + + return (intr_describe(rman_get_start(irq), cookie, descr)); +} + static struct resource_list * nexus_get_reslist(device_t dev, device_t child) { diff --git a/sys/amd64/include/intr_machdep.h b/sys/amd64/include/intr_machdep.h index 0613b12afa84..9fbb327ee506 100644 --- a/sys/amd64/include/intr_machdep.h +++ b/sys/amd64/include/intr_machdep.h @@ -151,6 +151,7 @@ int intr_bind(u_int vector, u_char cpu); #endif int intr_config_intr(int vector, enum intr_trigger trig, enum intr_polarity pol); +int intr_describe(u_int vector, void *ih, const char *descr); void intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame); struct intsrc *intr_lookup_source(int vector); int intr_register_pic(struct pic *pic); diff --git a/sys/i386/i386/intr_machdep.c b/sys/i386/i386/intr_machdep.c index 1c045604983e..0aa4560d5e7e 100644 --- a/sys/i386/i386/intr_machdep.c +++ b/sys/i386/i386/intr_machdep.c @@ -374,6 +374,23 @@ intr_init(void *dummy __unused) } SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL); +/* Add a description to an active interrupt handler. */ +int +intr_describe(u_int vector, void *ih, const char *descr) +{ + struct intsrc *isrc; + int error; + + isrc = intr_lookup_source(vector); + if (isrc == NULL) + return (EINVAL); + error = intr_event_describe_handler(isrc->is_event, ih, descr); + if (error) + return (error); + intrcnt_updatename(isrc); + return (0); +} + #ifdef DDB /* * Dump data about interrupt handlers diff --git a/sys/i386/i386/nexus.c b/sys/i386/i386/nexus.c index 21f9afb3e9fb..812e7f7b7265 100644 --- a/sys/i386/i386/nexus.c +++ b/sys/i386/i386/nexus.c @@ -98,6 +98,9 @@ static int nexus_bind_intr(device_t, device_t, struct resource *, int); #endif static int nexus_config_intr(device_t, int, enum intr_trigger, enum intr_polarity); +static int nexus_describe_intr(device_t dev, device_t child, + struct resource *irq, void *cookie, + const char *descr); static int nexus_activate_resource(device_t, device_t, int, int, struct resource *); static int nexus_deactivate_resource(device_t, device_t, int, int, @@ -143,6 +146,7 @@ static device_method_t nexus_methods[] = { DEVMETHOD(bus_bind_intr, nexus_bind_intr), #endif DEVMETHOD(bus_config_intr, nexus_config_intr), + DEVMETHOD(bus_describe_intr, nexus_describe_intr), DEVMETHOD(bus_get_resource_list, nexus_get_reslist), DEVMETHOD(bus_set_resource, nexus_set_resource), DEVMETHOD(bus_get_resource, nexus_get_resource), @@ -519,6 +523,14 @@ nexus_config_intr(device_t dev, int irq, enum intr_trigger trig, return (intr_config_intr(irq, trig, pol)); } +static int +nexus_describe_intr(device_t dev, device_t child, struct resource *irq, + void *cookie, const char *descr) +{ + + return (intr_describe(rman_get_start(irq), cookie, descr)); +} + static struct resource_list * nexus_get_reslist(device_t dev, device_t child) { diff --git a/sys/i386/include/intr_machdep.h b/sys/i386/include/intr_machdep.h index 2aeb0c9932a8..ec6a23ac83e7 100644 --- a/sys/i386/include/intr_machdep.h +++ b/sys/i386/include/intr_machdep.h @@ -138,6 +138,7 @@ int intr_bind(u_int vector, u_char cpu); #endif int intr_config_intr(int vector, enum intr_trigger trig, enum intr_polarity pol); +int intr_describe(u_int vector, void *ih, const char *descr); void intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame); struct intsrc *intr_lookup_source(int vector); int intr_register_pic(struct pic *pic); diff --git a/sys/kern/bus_if.m b/sys/kern/bus_if.m index 72817e72f7b8..3e23a8b915f3 100644 --- a/sys/kern/bus_if.m +++ b/sys/kern/bus_if.m @@ -509,7 +509,6 @@ METHOD int bind_intr { int _cpu; } DEFAULT bus_generic_bind_intr; - /** * @brief Allow (bus) drivers to specify the trigger mode and polarity * of the specified interrupt. @@ -527,6 +526,25 @@ METHOD int config_intr { } DEFAULT bus_generic_config_intr; /** + * @brief Allow drivers to associate a description with an active + * interrupt handler. + * + * @param _dev the parent device of @p _child + * @param _child the device which allocated the resource + * @param _irq the resource representing the interrupt + * @param _cookie the cookie value returned when the interrupt + * was originally registered + * @param _descr the description to associate with the interrupt + */ +METHOD int describe_intr { + device_t _dev; + device_t _child; + struct resource *_irq; + void *_cookie; + const char *_descr; +} DEFAULT bus_generic_describe_intr; + +/** * @brief Notify a (bus) driver about a child that the hints mechanism * believes it has discovered. * diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c index e2bf380ecc2d..b09fe829337c 100644 --- a/sys/kern/kern_intr.c +++ b/sys/kern/kern_intr.c @@ -506,7 +506,7 @@ intr_event_add_handler(struct intr_event *ie, const char *name, ih->ih_filter = filter; ih->ih_handler = handler; ih->ih_argument = arg; - ih->ih_name = name; + strlcpy(ih->ih_name, name, sizeof(ih->ih_name)); ih->ih_event = ie; ih->ih_pri = pri; if (flags & INTR_EXCL) @@ -579,7 +579,7 @@ intr_event_add_handler(struct intr_event *ie, const char *name, ih->ih_filter = filter; ih->ih_handler = handler; ih->ih_argument = arg; - ih->ih_name = name; + strlcpy(ih->ih_name, name, sizeof(ih->ih_name)); ih->ih_event = ie; ih->ih_pri = pri; if (flags & INTR_EXCL) @@ -647,6 +647,61 @@ intr_event_add_handler(struct intr_event *ie, const char *name, #endif /* + * Append a description preceded by a ':' to the name of the specified + * interrupt handler. + */ +int +intr_event_describe_handler(struct intr_event *ie, void *cookie, + const char *descr) +{ + struct intr_handler *ih; + size_t space; + char *start; + + mtx_lock(&ie->ie_lock); +#ifdef INVARIANTS + TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) { + if (ih == cookie) + break; + } + if (ih == NULL) { + mtx_unlock(&ie->ie_lock); + panic("handler %p not found in interrupt event %p", cookie, ie); + } +#endif + ih = cookie; + + /* + * Look for an existing description by checking for an + * existing ":". This assumes device names do not include + * colons. If one is found, prepare to insert the new + * description at that point. If one is not found, find the + * end of the name to use as the insertion point. + */ + start = index(ih->ih_name, ':'); + if (start == NULL) + start = index(ih->ih_name, 0); + + /* + * See if there is enough remaining room in the string for the + * description + ":". The "- 1" leaves room for the trailing + * '\0'. The "+ 1" accounts for the colon. + */ + space = sizeof(ih->ih_name) - (start - ih->ih_name) - 1; + if (strlen(descr) + 1 > space) { + mtx_unlock(&ie->ie_lock); + return (ENOSPC); + } + + /* Append a colon followed by the description. */ + *start = ':'; + strcpy(start + 1, descr); + intr_event_update(ie); + mtx_unlock(&ie->ie_lock); + return (0); +} + +/* * Return the ie_source field from the intr_event an intr_handler is * associated with. */ diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index 127691e94af1..7bcaf92fb546 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -3264,6 +3264,24 @@ bus_generic_config_intr(device_t dev, int irq, enum intr_trigger trig, } /** + * @brief Helper function for implementing BUS_DESCRIBE_INTR(). + * + * This simple implementation of BUS_DESCRIBE_INTR() simply calls the + * BUS_DESCRIBE_INTR() method of the parent of @p dev. + */ +int +bus_generic_describe_intr(device_t dev, device_t child, struct resource *irq, + void *cookie, const char *descr) +{ + + /* Propagate up the bus hierarchy until someone handles it. */ + if (dev->parent) + return (BUS_DESCRIBE_INTR(dev->parent, child, irq, cookie, + descr)); + return (EINVAL); +} + +/** * @brief Helper function for implementing BUS_GET_DMA_TAG(). * * This simple implementation of BUS_GET_DMA_TAG() simply calls the @@ -3569,6 +3587,28 @@ bus_bind_intr(device_t dev, struct resource *r, int cpu) } /** + * @brief Wrapper function for BUS_DESCRIBE_INTR(). + * + * This function first formats the requested description into a + * temporary buffer and then calls the BUS_DESCRIBE_INTR() method of + * the parent of @p dev. + */ +int +bus_describe_intr(device_t dev, struct resource *irq, void *cookie, + const char *fmt, ...) +{ + char descr[MAXCOMLEN]; + va_list ap; + + if (dev->parent == NULL) + return (EINVAL); + va_start(ap, fmt); + vsnprintf(descr, sizeof(descr), fmt, ap); + va_end(ap); + return (BUS_DESCRIBE_INTR(dev->parent, dev, irq, cookie, descr)); +} + +/** * @brief Wrapper function for BUS_SET_RESOURCE(). * * This function simply calls the BUS_SET_RESOURCE() method of the diff --git a/sys/sparc64/include/intr_machdep.h b/sys/sparc64/include/intr_machdep.h index ef24d187ae18..46a619693892 100644 --- a/sys/sparc64/include/intr_machdep.h +++ b/sys/sparc64/include/intr_machdep.h @@ -93,6 +93,7 @@ extern struct intr_vector intr_vectors[]; void intr_add_cpu(u_int cpu); #endif int intr_bind(int vec, u_char cpu); +int intr_describe(int vec, void *ih, const char *descr); void intr_setup(int level, ih_func_t *ihf, int pri, iv_func_t *ivf, void *iva); void intr_init1(void); diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c index a00e6c4cc6e0..ac563fd195a7 100644 --- a/sys/sparc64/pci/psycho.c +++ b/sys/sparc64/pci/psycho.c @@ -116,6 +116,7 @@ static bus_alloc_resource_t psycho_alloc_resource; static bus_activate_resource_t psycho_activate_resource; static bus_deactivate_resource_t psycho_deactivate_resource; static bus_release_resource_t psycho_release_resource; +static bus_describe_intr_t psycho_describe_intr; static bus_get_dma_tag_t psycho_get_dma_tag; static pcib_maxslots_t psycho_maxslots; static pcib_read_config_t psycho_read_config; @@ -140,6 +141,7 @@ static device_method_t psycho_methods[] = { DEVMETHOD(bus_activate_resource, psycho_activate_resource), DEVMETHOD(bus_deactivate_resource, psycho_deactivate_resource), DEVMETHOD(bus_release_resource, psycho_release_resource), + DEVMETHOD(bus_describe_intr, psycho_describe_intr), DEVMETHOD(bus_get_dma_tag, psycho_get_dma_tag), /* pcib interface */ @@ -1262,6 +1264,18 @@ psycho_teardown_intr(device_t dev, device_t child, struct resource *vec, return (bus_generic_teardown_intr(dev, child, vec, cookie)); } +static int +psycho_describe_intr(device_t dev, device_t child, struct resource *vec, + void *cookie, const char *descr) +{ + struct psycho_softc *sc; + + sc = device_get_softc(dev); + if (sc->sc_mode == PSYCHO_MODE_SABRE) + cookie = ((struct psycho_dma_sync *)cookie)->pds_cookie; + return (bus_generic_describe_intr(dev, child, vec, cookie, descr)); +} + static struct resource * psycho_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) diff --git a/sys/sparc64/pci/schizo.c b/sys/sparc64/pci/schizo.c index 303d3a02fd38..221881f5db74 100644 --- a/sys/sparc64/pci/schizo.c +++ b/sys/sparc64/pci/schizo.c @@ -114,6 +114,7 @@ static bus_alloc_resource_t schizo_alloc_resource; static bus_activate_resource_t schizo_activate_resource; static bus_deactivate_resource_t schizo_deactivate_resource; static bus_release_resource_t schizo_release_resource; +static bus_describe_intr_t schizo_describe_intr; static bus_get_dma_tag_t schizo_get_dma_tag; static pcib_maxslots_t schizo_maxslots; static pcib_read_config_t schizo_read_config; @@ -138,6 +139,7 @@ static device_method_t schizo_methods[] = { DEVMETHOD(bus_activate_resource, schizo_activate_resource), DEVMETHOD(bus_deactivate_resource, schizo_deactivate_resource), DEVMETHOD(bus_release_resource, schizo_release_resource), + DEVMETHOD(bus_describe_intr, schizo_describe_intr), DEVMETHOD(bus_get_dma_tag, schizo_get_dma_tag), /* pcib interface */ @@ -1283,6 +1285,18 @@ schizo_teardown_intr(device_t dev, device_t child, struct resource *vec, return (bus_generic_teardown_intr(dev, child, vec, cookie)); } +static int +schizo_describe_intr(device_t dev, device_t child, struct resource *vec, + void *cookie, const char *descr) +{ + struct schizo_softc *sc; + + sc = device_get_softc(dev); + if ((sc->sc_flags & SCHIZO_FLAGS_CDMA) != 0) + cookie = ((struct schizo_dma_sync *)cookie)->sds_cookie; + return (bus_generic_describe_intr(dev, child, vec, cookie, descr)); +} + static struct resource * schizo_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) diff --git a/sys/sparc64/sparc64/intr_machdep.c b/sys/sparc64/sparc64/intr_machdep.c index 74e1a43ced5f..137bd7e79086 100644 --- a/sys/sparc64/sparc64/intr_machdep.c +++ b/sys/sparc64/sparc64/intr_machdep.c @@ -414,6 +414,31 @@ inthand_remove(int vec, void *cookie) return (error); } +/* Add a description to an active interrupt handler. */ +int +intr_describe(int vec, void *ih, const char *descr) +{ + struct intr_vector *iv; + int error; + + if (vec < 0 || vec >= IV_MAX) + return (EINVAL); + sx_xlock(&intr_table_lock); + iv = &intr_vectors[vec]; + if (iv == NULL) { + sx_xunlock(&intr_table_lock); + return (EINVAL); + } + error = intr_event_describe_handler(iv->iv_event, ih, descr); + if (error) { + sx_xunlock(&intr_table_lock); + return (error); + } + intrcnt_updatename(vec, iv->iv_event->ie_fullname, 0); + sx_xunlock(&intr_table_lock); + return (error); +} + #ifdef SMP /* * Support for balancing interrupt sources across CPUs. For now we just diff --git a/sys/sparc64/sparc64/nexus.c b/sys/sparc64/sparc64/nexus.c index 798eec9eed06..413cc56dad37 100644 --- a/sys/sparc64/sparc64/nexus.c +++ b/sys/sparc64/sparc64/nexus.c @@ -90,12 +90,13 @@ static bus_activate_resource_t nexus_activate_resource; static bus_deactivate_resource_t nexus_deactivate_resource; static bus_release_resource_t nexus_release_resource; static bus_get_resource_list_t nexus_get_resource_list; +#ifdef SMP +static bus_bind_intr_t nexus_bind_intr; +#endif +static bus_describe_intr_t nexus_describe_intr; static bus_get_dma_tag_t nexus_get_dma_tag; static ofw_bus_get_devinfo_t nexus_get_devinfo; -#ifdef SMP -static int nexus_bind_intr(device_t, device_t, struct resource *, int); -#endif static int nexus_inlist(const char *, const char *const *); static struct nexus_devinfo * nexus_setup_dinfo(device_t, phandle_t); static void nexus_destroy_dinfo(struct nexus_devinfo *); @@ -128,6 +129,7 @@ static device_method_t nexus_methods[] = { #ifdef SMP DEVMETHOD(bus_bind_intr, nexus_bind_intr), #endif + DEVMETHOD(bus_describe_intr, nexus_describe_intr), DEVMETHOD(bus_get_dma_tag, nexus_get_dma_tag), /* ofw_bus interface */ @@ -328,6 +330,14 @@ nexus_bind_intr(device_t dev, device_t child, struct resource *r, int cpu) } #endif +static int +nexus_describe_intr(device_t dev, device_t child, struct resource *r, + void *cookie, const char *descr) +{ + + return (intr_describe(rman_get_start(r), cookie, descr)); +} + static struct resource * nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) diff --git a/sys/sys/bus.h b/sys/sys/bus.h index 55e6c200675a..caaab98de4ad 100644 --- a/sys/sys/bus.h +++ b/sys/sys/bus.h @@ -291,6 +291,9 @@ int bus_generic_bind_intr(device_t dev, device_t child, int bus_generic_child_present(device_t dev, device_t child); int bus_generic_config_intr(device_t, int, enum intr_trigger, enum intr_polarity); +int bus_generic_describe_intr(device_t dev, device_t child, + struct resource *irq, void *cookie, + const char *descr); int bus_generic_deactivate_resource(device_t dev, device_t child, int type, int rid, struct resource *r); int bus_generic_detach(device_t dev); @@ -361,6 +364,8 @@ int bus_setup_intr(device_t dev, struct resource *r, int flags, void *arg, void **cookiep); int bus_teardown_intr(device_t dev, struct resource *r, void *cookie); int bus_bind_intr(device_t dev, struct resource *r, int cpu); +int bus_describe_intr(device_t dev, struct resource *irq, void *cookie, + const char *fmt, ...); int bus_set_resource(device_t dev, int type, int rid, u_long start, u_long count); int bus_get_resource(device_t dev, int type, int rid, diff --git a/sys/sys/interrupt.h b/sys/sys/interrupt.h index be5d0f4710f7..3207afff582e 100644 --- a/sys/sys/interrupt.h +++ b/sys/sys/interrupt.h @@ -47,7 +47,7 @@ struct intr_handler { driver_intr_t *ih_handler; /* Handler function. */ void *ih_argument; /* Argument to pass to handler. */ int ih_flags; - const char *ih_name; /* Name of handler. */ + char ih_name[MAXCOMLEN]; /* Name of handler. */ struct intr_event *ih_event; /* Event we are connected to. */ int ih_need; /* Needs service. */ TAILQ_ENTRY(intr_handler) ih_next; /* Next handler for this event. */ @@ -156,6 +156,8 @@ int intr_event_create(struct intr_event **event, void *source, void (*post_ithread)(void *), void (*post_filter)(void *), int (*assign_cpu)(void *, u_char), const char *fmt, ...) __printflike(9, 10); +int intr_event_describe_handler(struct intr_event *ie, void *cookie, + const char *descr); int intr_event_destroy(struct intr_event *ie); int intr_event_handle(struct intr_event *ie, struct trapframe *frame); int intr_event_remove_handler(void *cookie); |
