summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2010-01-21 17:55:47 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2010-01-21 17:55:47 +0000
commitc3895badf7af698d10fdd2c6d3bbb188c8346b02 (patch)
treea245209c1640a0b080e5a0e5f1a25029c890f0c2
parent219503bacf6d613fab7bbd8bc36692f1cdf989c3 (diff)
Notes
-rw-r--r--share/man/man9/BUS_DESCRIBE_INTR.9104
-rw-r--r--share/man/man9/Makefile2
-rw-r--r--sys/amd64/amd64/intr_machdep.c17
-rw-r--r--sys/amd64/amd64/nexus.c12
-rw-r--r--sys/amd64/include/intr_machdep.h1
-rw-r--r--sys/i386/i386/intr_machdep.c17
-rw-r--r--sys/i386/i386/nexus.c12
-rw-r--r--sys/i386/include/intr_machdep.h1
-rw-r--r--sys/kern/bus_if.m20
-rw-r--r--sys/kern/kern_intr.c59
-rw-r--r--sys/kern/subr_bus.c40
-rw-r--r--sys/sparc64/include/intr_machdep.h1
-rw-r--r--sys/sparc64/pci/psycho.c14
-rw-r--r--sys/sparc64/pci/schizo.c14
-rw-r--r--sys/sparc64/sparc64/intr_machdep.c25
-rw-r--r--sys/sparc64/sparc64/nexus.c16
-rw-r--r--sys/sys/bus.h5
-rw-r--r--sys/sys/interrupt.h4
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);