summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2008-08-02 17:42:38 +0000
committersam <sam@FreeBSD.org>2008-08-02 17:42:38 +0000
commitf28149353a8d84e6d26ce1feac18f3225125ceaf (patch)
tree48979d511003bfcad58592aad5b0356bc70e5cb0
parentdd6ada0389c465aff31058de6e40459dc9fc559b (diff)
downloadFreeBSD-src-f28149353a8d84e6d26ce1feac18f3225125ceaf.zip
FreeBSD-src-f28149353a8d84e6d26ce1feac18f3225125ceaf.tar.gz
add callout_schedule; besides being useful it also improves
compatibility with other systems Reviewed by: ed, battlez
-rw-r--r--share/man/man9/firmware.933
-rw-r--r--share/man/man9/timeout.926
-rw-r--r--sys/kern/kern_timeout.c15
-rw-r--r--sys/sys/callout.h4
4 files changed, 65 insertions, 13 deletions
diff --git a/share/man/man9/firmware.9 b/share/man/man9/firmware.9
index 3dc33f8..e010159 100644
--- a/share/man/man9/firmware.9
+++ b/share/man/man9/firmware.9
@@ -23,7 +23,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 6, 2006
+.Dd May 18, 2008
.Os
.Dt FIRMWARE 9
.Sh NAME
@@ -31,6 +31,7 @@
.Nm firmware_unregister ,
.Nm firmware_get ,
.Nm firmware_put
+.Nm firmware_drain
.Nd firmware image loading and management
.Sh SYNOPSIS
.In sys/param.h
@@ -59,6 +60,8 @@ struct firmware {
.Fn firmware_get "const char *imagename"
.Ft void
.Fn firmware_put "const struct firmware *fp" "int flags"
+.Ft void
+.Fn firmware_drain "void"
.Sh DESCRIPTION
The
.Nm firmware
@@ -137,8 +140,11 @@ This involves the linker subsystem and disk access, so
.Fn firmware_get
must not be called with any locks (except for
.Va Giant ) .
-The caller must also have a process context so filesystem state such as
-the root vnode is defined (e.g. you cannot load from a taskqueue thread).
+Note also that if the firmware image is loaded from a filesystem
+it must already be mounted.
+In particular this means that it may be necessary to defer requests
+from a driver attach method unless it is known the root filesystem is
+already mounted.
.Pp
On success,
.Fn firmware_get
@@ -154,6 +160,21 @@ argument may be set to
to indicate that
firmware_put is free to reclaim resources associated with
the firmware image if this is the last reference.
+By default a firmware image will be deferred to a
+.Xr taskqueue 9
+thread so the call may be done while holding a lock.
+In certain cases, such as on driver detach, this cannot be allowed.
+If the
+.Dv FIRMWARE_WAIT
+flag is or'd into
+.Fa flags
+then
+.Fn firmware_put
+will wait for the asynchronous operation to complete.
+This can also be accomplished by calling the
+.Fn firmware_drain
+routine after
+.Fn firmware_put .
.Sh FIRMWARE LOADING MECHANISMS
As mentioned before, any component of the system can register
firmware images at any time by simply calling
@@ -238,11 +259,7 @@ IxNpeMicrocode.fwo optional npe_fw \\
clean "IxNpeMicrocode.fwo"
IxNpeMicrocode.dat optional npe_fw \\
dependency ".PHONY" \\
- compile-with "if [ -e $S/arm/xscale/ixp425/IxNpeMicrocode.dat ]; \\
- then \\
- ln -sf $S/arm/xscale/ixp425/IxNpeMicrocode.dat .; \\
- else echo 'WARNING, no IxNpeMicrocode.dat file; you must obtain this from the Intel web site'; false; \\
- fi" \\
+ compile-with "uudecode < $S/contrib/dev/npe/IxNpeMicrocode.dat.uu" \\
no-obj no-implicit-rule \\
clean "IxNpeMicrocode.dat"
.Ed
diff --git a/share/man/man9/timeout.9 b/share/man/man9/timeout.9
index 9c37632..e6d911d 100644
--- a/share/man/man9/timeout.9
+++ b/share/man/man9/timeout.9
@@ -36,7 +36,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 20, 2007
+.Dd August 2, 2008
.Dt TIMEOUT 9
.Os
.Sh NAME
@@ -49,6 +49,7 @@
.Nm callout_stop ,
.Nm callout_drain ,
.Nm callout_reset ,
+.Nm callout_schedule ,
.Nm callout_pending ,
.Nm callout_active ,
.Nm callout_deactivate
@@ -83,6 +84,8 @@ struct callout_handle handle = CALLOUT_HANDLE_INITIALIZER(&handle)
.Ft int
.Fn callout_reset "struct callout *c" "int ticks" "timeout_t *func" "void *arg"
.Ft int
+.Fn callout_schedule "struct callout *c" "int ticks"
+.Ft int
.Fn callout_pending "struct callout *c"
.Ft int
.Fn callout_active "struct callout *c"
@@ -191,9 +194,10 @@ The functions
.Fn callout_init_mtx ,
.Fn callout_init_rw ,
.Fn callout_stop ,
-.Fn callout_drain
-and
+.Fn callout_drain ,
.Fn callout_reset
+and
+.Fn callout_schedule
are low-level routines for clients who wish to allocate their own
callout structures.
.Pp
@@ -201,9 +205,10 @@ The function
.Fn callout_init
initializes a callout so it can be passed to
.Fn callout_stop ,
-.Fn callout_drain
+.Fn callout_drain ,
+.Fn callout_reset
or
-.Fn callout_reset
+.Fn callout_schedule
without any side effects.
If the
.Fa mpsafe
@@ -294,6 +299,17 @@ If there was already a pending callout and it was rescheduled, then
will return a non-zero value.
If the callout has an associated mutex, then that mutex must be
held when this function is called.
+The function
+.Fn callout_schedule
+(re)schedules an existing callout for a new period of time;
+it is equivalent to calling
+.Fn callout_reset
+with the
+.Fa func
+and
+.Fa arg
+parameters extracted from the callout structure (though possibly with
+lower overhead).
.Pp
The macros
.Fn callout_pending ,
diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c
index ec540c5..fe05d2c 100644
--- a/sys/kern/kern_timeout.c
+++ b/sys/kern/kern_timeout.c
@@ -616,6 +616,21 @@ retry:
return (cancelled);
}
+/*
+ * Common idioms that can be optimized in the future.
+ */
+int
+callout_schedule_on(struct callout *c, int to_ticks, int cpu)
+{
+ return callout_reset_on(c, to_ticks, c->c_func, c->c_arg, cpu);
+}
+
+int
+callout_schedule(struct callout *c, int to_ticks)
+{
+ return callout_reset_on(c, to_ticks, c->c_func, c->c_arg, c->c_cpu);
+}
+
int
_callout_stop_safe(c, safe)
struct callout *c;
diff --git a/sys/sys/callout.h b/sys/sys/callout.h
index f472839..2d43d14 100644
--- a/sys/sys/callout.h
+++ b/sys/sys/callout.h
@@ -89,6 +89,10 @@ int callout_reset_on(struct callout *, int, void (*)(void *), void *, int);
callout_reset_on((c), (on_tick), (fn), (arg), (c)->c_cpu)
#define callout_reset_curcpu(c, on_tick, fn, arg) \
callout_reset_on((c), (on_tick), (fn), (arg), PCPU_GET(cpuid))
+int callout_schedule(struct callout *, int);
+int callout_schedule_on(struct callout *, int, int);
+#define callout_schedule_curcpu(c, on_tick) \
+ callout_schedule_on((c), (on_tick), PCPU_GET(cpuid))
#define callout_stop(c) _callout_stop_safe(c, 0)
int _callout_stop_safe(struct callout *, int);
void callout_tick(void);
OpenPOWER on IntegriCloud