add callout_schedule; besides being useful it also improves

compatibility with other systems

Reviewed by:	ed, battlez
This commit is contained in:
Sam Leffler 2008-08-02 17:42:38 +00:00
parent 372e9a288d
commit 6e0186d5ee
4 changed files with 65 additions and 13 deletions

View file

@ -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

View file

@ -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 ,

View file

@ -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;

View file

@ -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);