Date: Mon, 13 Oct 2003 23:48:38 -0400 From: Ken Smith <kensmith@cse.Buffalo.EDU> To: freebsd-doc@freebsd.org Subject: SYSINIT() fixes for Architecture Manual Message-ID: <20031014034838.GA20484@electra.cse.Buffalo.EDU>
next in thread | raw e-mail | index | archive | help
Murray suggested I just send this here, and he'd chime in if nobody else feels like enough of an authority to say whether or not I'm lying. :-) While working on PR docs/57568 to fix the SYSINIT() examples I decided to try and clarify a little bit what SYSINIT() is/isn't used for. Can anyone say one way or another if I hit the target? Thanks. --- chapter.sgml_orig Sat Oct 11 20:07:09 2003 +++ chapter.sgml Mon Oct 13 21:23:37 2003 @@ -49,17 +49,27 @@ <para>Sysinit uses two priorities when ordering the functions for execution. The first priority is a subsystem ID giving an - overall order Sysinit's dispatch of functions. Current predeclared - ID's are in <filename><sys/kernel.h></filename> in the enum + overall order for Sysinit's dispatch of functions. Current predeclared + ID's are in <filename><sys/kernel.h></filename> in the enum list <literal>sysinit_sub_id</literal>. The second priority used is an element order within the subsystem. Current predeclared subsystem element orders are in - <filename><sys/kernel.h></filename> in the enum list + <filename><sys/kernel.h></filename> in the enum list <literal>sysinit_elem_order</literal>.</para> <para>There are currently two uses for Sysinit. Function dispatch at system startup and kernel module loads, and function dispatch - at system shutdown and kernel module unload.</para> + at system shutdown and kernel module unload. Kernel subsystems + often use system startup Sysinits to initialize data structures, + for example the process scheduling subsystem uses a Sysinit to + initialize the run queue data structures. Device drivers + should avoid using <literal>SYSINIT()</literal> directly. + Instead drivers for real devices that are part of a bus structure + should use <literal>DRIVER_MODULE()</literal> to provide a + function that detects the device and, if it is present, initializes + the device. It will do a few things specific to devices and then calls + <literal>SYSINIT()</literal> itself. For pseudo-devices, which are + not part of a bus structure, use <literal>DEV_MODULE()</literal>.</para> </sect1> @@ -72,14 +82,14 @@ <sect3> <title>Headers</title> - <programlisting><sys/kernel.h></programlisting> + <programlisting><sys/kernel.h></programlisting> </sect3> <sect3> <title>Macros</title> <programlisting>SYSINIT(uniquifier, subsystem, order, func, ident) - SYSUNINIT(uniquifier, subsystem, order, func, ident)</programlisting> +SYSUNINIT(uniquifier, subsystem, order, func, ident)</programlisting> </sect3> </sect2> @@ -90,21 +100,22 @@ necessary sysinit data in Sysinit's startup data set for Sysinit to sort and dispatch a function at system startup and module load. <literal>SYSINIT()</literal> takes a uniquifier - that Sysinit uses identify the particular function dispatch + that Sysinit uses to identify the particular function dispatch data, the subsystem order, the subsystem element order, the function to call, and the data to pass the function. All functions must take a constant pointer argument. </para> - <para>For example:</para> + <example> + <title>Example of a <literal>SYSINIT()</literal></title> - <programlisting>#include <sys/kernel.h> + <programlisting>#include <sys/kernel.h> void foo_null(void *unused) { foo_doo(); } -SYSINIT(foo_null, SI_SUB_FOO, SI_ORDER_FOO, NULL); +SYSINIT(foo, SI_SUB_FOO, SI_ORDER_FOO, foo_null, NULL); struct foo foo_voodoo = { FOO_VOODOO; @@ -115,26 +126,34 @@ struct foo *foo = (struct foo *)vdata; foo_data(foo); } -SYSINIT(foo_arg, SI_SUB_FOO, SI_ORDER_FOO, foo_voodoo); - </programlisting> +SYSINIT(foo, SI_SUB_FOO, SI_ORDER_FOO, foo_arg, foo_voodoo); + </programlisting> + </example> + + <para>Note that <literal>SI_SUB_FOO</literal> and + <literal>SI_ORDER_FOO</literal> need to be in the + <literal>sysinit_sub_id</literal> and + <literal>sysinit_elem_order</literal> enum's as mentioned above. + Either use existing ones or add your own to the enum's.</para> </sect2> <sect2> <title>Shutdown</title> - <para>The <literal>SYSUNINIT()</literal> macro behaves similarly + <para>The <literal>SYSUNINIT()</literal> macro behaves similar to the <literal>SYSINIT()</literal> macro except that it adds the Sysinit data to Sysinit's shutdown data set.</para> - <para>For example:</para> + <example> + <title>Example of a <literal>SYSUNINIT()</literal></title> - <programlisting>#include <sys/kernel.h> + <programlisting>#include <sys/kernel.h> void foo_cleanup(void *unused) { foo_kill(); } -SYSUNINIT(foo_cleanup, SI_SUB_FOO, SI_ORDER_FOO, NULL); +SYSUNINIT(foo, SI_SUB_FOO, SI_ORDER_FOO, foo_cleanup, NULL); struct foo_stack foo_stack = { FOO_STACK_VOODOO; @@ -143,8 +162,9 @@ void foo_flush(void *vdata) { } -SYSUNINIT(foo_flush, SI_SUB_FOO, SI_ORDER_FOO, foo_stack); - </programlisting> +SYSUNINIT(foo, SI_SUB_FOO, SI_ORDER_FOO, foo_flush, foo_stack); + </programlisting> + </example> </sect2> </sect1> </chapter> -- Ken Smith - From there to here, from here to | kensmith@cse.buffalo.edu there, funny things are everywhere. | - Theodore Geisel |
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20031014034838.GA20484>