Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Add a mechanism to defer configuration of children until...
details: https://anonhg.NetBSD.org/src/rev/b2f50ce410b9
branches: trunk
changeset: 476392:b2f50ce410b9
user: thorpej <thorpej%NetBSD.org@localhost>
date: Wed Sep 15 19:37:08 1999 +0000
description:
Add a mechanism to defer configuration of children until interrupts
are enabled.
diffstat:
sys/kern/subr_autoconf.c | 76 ++++++++++++++++++++++++++++++++++++++++-------
sys/sys/device.h | 3 +-
2 files changed, 66 insertions(+), 13 deletions(-)
diffs (155 lines):
diff -r f8aadcf58766 -r b2f50ce410b9 sys/kern/subr_autoconf.c
--- a/sys/kern/subr_autoconf.c Wed Sep 15 19:35:53 1999 +0000
+++ b/sys/kern/subr_autoconf.c Wed Sep 15 19:37:08 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_autoconf.c,v 1.41 1999/09/15 18:10:34 thorpej Exp $ */
+/* $NetBSD: subr_autoconf.c,v 1.42 1999/09/15 19:37:08 thorpej Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -83,14 +83,25 @@
void (*dc_func) __P((struct device *));
};
-TAILQ_HEAD(, deferred_config) deferred_config_queue;
+TAILQ_HEAD(deferred_config_head, deferred_config);
-static void config_process_deferred_children __P((struct device *));
+struct deferred_config_head deferred_config_queue;
+struct deferred_config_head interrupt_config_queue;
+
+static void config_process_deferred __P((struct deferred_config_head *,
+ struct device *));
struct devicelist alldevs; /* list of all devices */
struct evcntlist allevents; /* list of all event counters */
/*
+ * This variable indicates, from the configuration machinery's point of
+ * view, if interrupts are enabled. They start disabled, and are
+ * considered enabled once cpu_configure() returns.
+ */
+int config_interrupts_enabled;
+
+/*
* Configure the system's hardware.
*/
void
@@ -98,6 +109,7 @@
{
TAILQ_INIT(&deferred_config_queue);
+ TAILQ_INIT(&interrupt_config_queue);
TAILQ_INIT(&alldevs);
TAILQ_INIT(&allevents);
@@ -108,6 +120,13 @@
* to be enabled.
*/
cpu_configure();
+ config_interrupts_enabled = 1;
+
+ /*
+ * Now callback to finish configuration for devices which want
+ * to do this once interrupts are enabled.
+ */
+ config_process_deferred(&interrupt_config_queue, NULL);
}
/*
@@ -372,7 +391,7 @@
device_register(dev, aux);
#endif
(*ca->ca_attach)(parent, dev, aux);
- config_process_deferred_children(dev);
+ config_process_deferred(&deferred_config_queue, dev);
return (dev);
}
@@ -559,8 +578,7 @@
}
#endif
- if ((dc = malloc(sizeof(*dc), M_DEVBUF, M_NOWAIT)) == NULL)
- panic("config_defer: can't allocate defer structure");
+ dc = malloc(sizeof(*dc), M_DEVBUF, M_WAITOK);
dc->dc_dev = dev;
dc->dc_func = func;
@@ -568,19 +586,53 @@
}
/*
- * Process the deferred configuration queue for a device.
+ * Defer some autoconfiguration for a device until after interrupts
+ * are enabled.
+ */
+void
+config_interrupts(dev, func)
+ struct device *dev;
+ void (*func) __P((struct device *));
+{
+ struct deferred_config *dc;
+
+ /*
+ * If interrupts are enabled, callback now.
+ */
+ if (config_interrupts_enabled) {
+ (*func)(dev);
+ return;
+ }
+
+#ifdef DIAGNOSTIC
+ for (dc = TAILQ_FIRST(&interrupt_config_queue); dc != NULL;
+ dc = TAILQ_NEXT(dc, dc_queue)) {
+ if (dc->dc_dev == dev)
+ panic("config_interrupts: deferred twice");
+ }
+#endif
+
+ dc = malloc(sizeof(*dc), M_DEVBUF, M_WAITOK);
+
+ dc->dc_dev = dev;
+ dc->dc_func = func;
+ TAILQ_INSERT_TAIL(&interrupt_config_queue, dc, dc_queue);
+}
+
+/*
+ * Process a deferred configuration queue.
*/
static void
-config_process_deferred_children(parent)
+config_process_deferred(queue, parent)
+ struct deferred_config_head *queue;
struct device *parent;
{
struct deferred_config *dc, *ndc;
- for (dc = TAILQ_FIRST(&deferred_config_queue);
- dc != NULL; dc = ndc) {
+ for (dc = TAILQ_FIRST(queue); dc != NULL; dc = ndc) {
ndc = TAILQ_NEXT(dc, dc_queue);
- if (dc->dc_dev->dv_parent == parent) {
- TAILQ_REMOVE(&deferred_config_queue, dc, dc_queue);
+ if (parent == NULL || dc->dc_dev->dv_parent == parent) {
+ TAILQ_REMOVE(queue, dc, dc_queue);
(*dc->dc_func)(dc->dc_dev);
free(dc, M_DEVBUF);
}
diff -r f8aadcf58766 -r b2f50ce410b9 sys/sys/device.h
--- a/sys/sys/device.h Wed Sep 15 19:35:53 1999 +0000
+++ b/sys/sys/device.h Wed Sep 15 19:37:08 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: device.h,v 1.33 1999/09/15 18:10:33 thorpej Exp $ */
+/* $NetBSD: device.h,v 1.34 1999/09/15 19:37:08 thorpej Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -183,6 +183,7 @@
int config_activate __P((struct device *));
int config_deactivate __P((struct device *));
void config_defer __P((struct device *, void (*)(struct device *)));
+void config_interrupts __P((struct device *, void (*)(struct device *)));
#if defined(__alpha__) || defined(hp300) || defined(__i386__) || \
defined(__sparc__) || defined(__vax__)
void device_register __P((struct device *, void *));
Home |
Main Index |
Thread Index |
Old Index