This article serves as a sort of final resting place for various small
changes in the kernel programming API which do not fit elsewhere.
No more kdev_t
The kdev_t type has been removed from the kernel; everything which
works with device numbers should now use the dev_t type. As part
of this change, dev_t has been expanded to 32 bits; 12 bits for
the major number, and 20 for the minor number.
If your driver uses the i_rdev field of the inode
structure, there are a couple of new macros you can use:
unsigned int iminor(struct inode *inode);
unsigned int imajor(struct inode *inode);
Consider using these while fixing your code; the next time the type of
i_rdev changes, you will be happier.
malloc.h
The include file <linux/malloc.h> has long been a synonym for
<linux/slab.h>. In 2.5, malloc.h was removed, and
all code should include slab.h directly.
Designated initializers
In the 2.3 development cycle, much effort went into converting code to the
(non-standard) gcc designated initializer format for structures:
static struct some_structure = {
field1: value,
field2: value
};
In 2.5, the decision was made to go to the ANSI C standard initializer
format, and all of that code was reworked again. The non-standard format
still works, for now, but it is worth the effort to make the change
anyway. The standard format looks like:
static struct some_structure = {
.field1 = value,
.field2 = value,
...
};
The min() and max() macros
A common step in the development of most C programmers, shortly after they
learn to include stdio.h seems to be the definition of macros
like:
#define max(a,b) ((a) > (b) ? (a) : (b))
In 2.5, it was noted that a number of kernel developers had seemingly not
moved beyond that
stage, and there was an unbelievable number of min() and
max() definitions sprinkled throughout the kernel source. These
definitions were not only redundant - they were unsafe. A max()
macro as defined above has the usual problem with side effects; it also is
not type-safe, especially when signed and unsigned values are used.
Linus initially added his own definition of min() and
max() which added a third argument - an explicit type. That
change upset people badly enough that some put substantial amounts of time
into developing two-argument versions that are type and side-effect safe.
The result now lives in <linux/kernel.h>, and should be used
in preference to any locally-defined version.
Dependent read barriers
(Added February 24, 2003).
On most architectures, reads from memory will not be reordered across a
data dependency. Consider this code fragment:
int *a, *b, x;
a = b;
x = *a;
Here, you would expect that *a would yield the value pointed to by
b; it would be surprising to have the read of *a
reordered in front of the assignment to a. Some architectures can
do just that sort of reordering, however. One could ensure that such
reordering does not happen by inserting a rmb() (read memory
barrier) between the two assignment. But that would reduce performance
needlessly on many systems. So a new barrier,
read_barrier_depends(), has been added in this case. It should
only be used in situations where data dependencies exist. On architectures
where data dependencies will force ordering,
read_barrier_depends() will do nothing. On other architectures,
it expands into a regular read barrier. See this
patch posting for more information.
User-mode helpers
(Added February 28, 2003).
The prototype of call_usermodehelper() has changed:
int call_usermodehelper(char *path, char **argv, char **envp,
int wait);
The new wait flag controls whether call_usermodehelper()
returns before the user-mode process exits. If wait is set to a non-zero
value, the function will wait for the process to finish its work, and the
return value will be what the process itself returned. Otherwise the
return is immediate, and the return value only indicates whether the
user-mode process was successfully started or not.
Note that the older exec_usermodehelper() function has been
removed from the 2.5 kernel.
New request_module() prototype
(Added May 20, 2003).
As of 2.5.70, the prototype of request_module() has changed. This
function now takes a printf-style argument list. As a result, code which
used to look like:
char module_name[32];
sprintf(module_name, "foo-device-%d", number);
request_module(module_name);
can now be rewritten as:
request_module("foo-device-%d", number);
Most in-kernel code has already been changed to do things the new way.
devfs
We'll not go into the details here, but it is worth noting that devfs has
been through extensive changes, and will likely see more changes yet before
2.6.0 is released. If your driver uses devfs, it will certainly need
updating.
Note also that devfs has been officially marked as "deprecated."
Post a comment
|