kernel-doc syntax

The format of a block comment is like this:

/**
 * (data-type|DOC)? name(:)? (- short description)?
(* @x: (description of parameter/member x)?)*
(* a blank line)?
 * (Description of function or data structure)?
(* a blank line)?
 * (sub-section header:
 * (sub-section description) )*
 (*)?*/
  • (...)? signifies optional structure and
  • (...)* signifies 0 or more structure elements

The name of the function, data-type respectively DOC is used as the section header. The names of section headers must be unique per source file.

functions

/**
 * function_name(:)? (- short description)?
(* @parameterx: (description of parameter x)?)*
(* a blank line)?
 * (Description of function)?
(* a blank line)?
 * (sub-section header:
 * (sub-section description) )*
 (*)?*/

All description text can span multiple lines, although the function_name & its short description are traditionally on a single line. Description text may also contain blank lines (i.e., lines that contain only a “*”).

So, the trivial example would be:

/**
 * my_function
 */

If the Description: header tag is omitted, then there must be a blank line after the last parameter specification.:

/**
 * my_function - does my stuff
 * @my_arg: its mine damnit
 *
 * Does my stuff explained.
 */

or, could also use:

/**
 * my_function - does my stuff
 * @my_arg: its mine damnit
 * Description:
 * Does my stuff explained.
 */

You can also add additional sections. When documenting kernel functions you should document the Context: of the function, e.g. whether the functions can be called form interrupts. Unlike other sections you can end it with an empty line.

A non-void function should have a Return: section describing the return value(s). Example-sections should contain the string EXAMPLE so that they are marked appropriately in the output format.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
/**
 * user_function() - function that can only be called in user context
 * @a: some argument
 * @...: ellipsis operator
 *
 * This function makes no sense, it's only a kernel-doc demonstration.
 *
 * Example:
 * x = user_function(22);
 *
 * Return:
 * Returns first argument
 */
int
user_function(int a, ...)
{
        return a;
}

Rendered example: user_function

structs, unions

Beside functions you can also write documentation for structs, unions. Instead of the function name you must write the name of the declaration; the struct or union must always precede the name. Nesting of declarations is supported. Use the @argument mechanism to document members or constants.

Inside a struct description, you can use the ‘private:’ and ‘public:’ comment tags. Structure fields that are inside a ‘private:’ area are not listed in the generated output documentation. The ‘private:’ and ‘public:’ tags must begin immediately following a /* comment marker. They may optionally include comments between the : and the ending */ marker.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/**
* struct my_struct - a struct with nested unions and structs
* @arg1: first argument of anonymous union/anonymous struct
* @arg2: second argument of anonymous union/anonymous struct
* @arg1b: first argument of anonymous union/anonymous struct
* @arg2b: second argument of anonymous union/anonymous struct
* @arg3: third argument of anonymous union/anonymous struct
* @arg4: fourth argument of anonymous union/anonymous struct
* @bar: non-anonymous union
* @bar.st1: struct st1 inside @bar
* @bar.st1.arg1: first argument of struct st1 on union bar
* @bar.st1.arg2: second argument of struct st1 on union bar
* @bar.st2: struct st2 inside @bar
* @bar.st2.arg1: first argument of struct st2 on union bar
* @bar.st2.arg2: second argument of struct st2 on union bar
* @bar.st3: struct st3 inside @bar
* @bar.st3.arg2: second argument of struct st3 on union bar
* @f1: nested function on anonimous union/struct
* @bar.st2.f2: nested function on named union/struct
*/
struct my_struct {
  /* Anonymous union/struct*/
  union {
        struct {
            char arg1 : 1;
            char arg2 : 3;
        };
      struct {
          int arg1b;
          int arg2b;
      };
      struct {
          void *arg3;
          int arg4;
          int (*f1)(char foo, int bar);
      };
  };
  union {
      struct {
          int arg1;
          int arg2;
      } st1;
      struct {
          void *arg1;  /* bar.st3.arg1 is undocumented, cause a warning */
            int arg2;
         int (*f2)(char foo, int bar); /* bar.st3.fn2 is undocumented, cause a warning */
      } st2, st3;
      int (*f3)(char foo, int bar); /* f3 is undocumented, cause a warning */
  } bar;               /* bar is undocumented, cause a warning */

  /* private: */
  int undoc_privat;    /* is undocumented but private, no warning */

  /* public: */
  enum {
      FOO,
      BAR,
  } undoc_public;      /* is undocumented, cause a warning */

};

Rendered example: struct my_struct

All descriptions can be multi-line, except the short function description. For really longs structs, you can also describe arguments inside the body of the struct. There are two styles, single-line comments where both the opening /** and closing */ are on the same line, and multi-line comments where they are each on a line of their own, like all other kernel-doc comments:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
 * struct my_long_struct - short description with &my_struct->a and &my_struct->b
 * @foo: The Foo member.
 *
 * Longer description
 */
struct my_long_struct {
        int foo;
        /**
         * @bar: The Bar member.
         */
        int bar;
        /**
         * @baz: The Baz member.
         *
         * Here, the member description may contain several paragraphs.
         */
        int baz;
        union {
                /** @foobar: Single line description. */
                int foobar;
        };
        /** @bar2: Description for struct @bar2 inside @my_long_struct */
        struct {
                /**
                 * @bar2.barbar: Description for @barbar inside @my_long_struct.bar2
                 */
                int barbar;
        } bar2;
};

Rendered example: struct my_long_struct

enums, typedefs

To write documentation for enums and typedefs, you must write the name of the declaration; the enum or typedef must always precede the name.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
/**
 * enum my_enum - log level
 * @QUIET: logs nothing
 * @INFO: logs info messages
 * @WARN: logs warn and info messages
 * @DEBUG: logs debug, warn and info messages
 */

enum my_enum {
  QUIET,
  INFO,
  WARN,
  DEBUG
};

Rendered example: enum my_enum

1
2
3
4
5
/**
 * typedef my_typedef - useless typdef of int
 *
 */
typedef int my_typedef;

Rendered example: typedef my_typedef

documentation blocks

To facilitate having source code and comments close together, you can include kernel-doc documentation blocks that are free-form comments instead of being kernel-doc for functions, structures, unions, enumerations, or typedefs. This could be used for something like a theory of operation for a driver or library code, for example.

This is done by using a DOC: section keyword with a section title. A small example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
/**
 * DOC: Theory of Operation
 *
 * The whizbang foobar is a dilly of a gizmo.  It can do whatever you
 * want it to do, at any time.  It reads your mind.  Here's how it works.
 *
 * foo bar splat
 * -------------
 *
 * The only drawback to this gizmo is that it can sometimes damage hardware,
 * software, or its subject(s).
 *
 * DOC: multiple DOC sections
 *
 * It's not recommended to place more than one "DOC:" section in the same
 * comment block. To insert a new "DOC:" section, create a new comment block and
 * to create a sub-section use the reST markup for headings, see documentation
 * of function rst_mode()
 */

Rendered example: Theory of Operation

highlight pattern

All kernel-doc markup is processed as described above, all descriptive text is further processed, scanning for the following special patterns, which are highlighted appropriately.

  • user_function() : function
  • @a : name of a parameter
  • &struct my_struct : name of a structure (including the word struct)
  • &union my_union : name of a union
  • &my_struct->a or &my_struct.b - member of a struct or union.
  • &enum my_enum : name of a enum
  • &typedef my_typedef : name of a typedef
  • %CONST : name of a constant.
  • $ENVVAR : environmental variable

The kernel-doc parser translates the pattern above to the corresponding reST markups (sphinx domains):

- :c:func:`user_function` : function
- ``a`` : name of a parameter
- :c:type:`struct my_struct <my_struct>` : name of a structure (including the word struct)
- :c:type:`union my_union <my_union>` : name of a union
- :c:type:`my_struct->a <my_struct>` or :c:type:`my_struct.b <my_struct>` -  member of a struct or union.
- :c:type:`enum my_enum <my_enum>` : name of a enum
- :c:type:`typedef my_typedef <my_typedef>` : name of a typedef
- ``CONST`` : name of a constant.
- ``$ENVVAR`` : environmental variable

The sphinx-doc generator highlights these markups and tries to cross referencing to arbitrary locations (sphinx cross references). The result of a cross reference depends on the context of the document which includes the kernel-doc comment. You don’t have to use the highlight pattern, if you prefer pure reST, use the reST markup.

Since the prefixes $..., &... and @... are used to markup the highlight pattern, you have to escape them in other uses: \$..., \&... and \@....

Hint

The highlight pattern, are non regular reST markups. They are only available within kernel-doc comments, helping C developers to write short and compact documentation in source code comments. You can’t use them in plain reST files (“.rst”). If you are editing “.rst” files (e.g. files under Documentation) please use the corresponding reST markups (sphinx domains).

Snippets

The kernel-doc Parser supports a comment-markup for snippets out of the source code. To start a region to snip insert:

/* parse-SNIP: <snippet-name> */

The snippet region stops with a new snippet region or at the next:

/* parse-SNAP: */

Jump to Snippets to see an example.