Linux Kernel Architecture

(Jacob Rumans) #1
Mauerer app03.tex V1 - 09/04/2008 6:11pm Page 1207

Appendix C: Notes on C


include/asm-x86/io_32.h
#define BUILDIO(bwl,bw,type) \
static inline void out##bwl##_local(unsigned type value, int port) { \
asm volatile("out" #bwl " %" #bw "0, %w1" : : "a"(value), "Nd"(port)); \
}


bwlaccepts one of the three valuesb,l,orwdepending on the data type for which the function is defined.
typespecifies the corresponding C data type. The macro is called as follows to definecharoperations or
byte operations:

BUILDIO(b,b,char)

After processing by the pre-processor, the C file contains the following code (extra line breaks have been
added to improve readability):

static inline void outb_local(unsigned char value, int port) { _
_asm__ __volatile__("out" "b" " %" "b" "0, %w1"
:
: "a"(value), "Nd"(port));
}

C.2.6 Miscellaneous


There are three further items that do not fit into any of the previous categories.

Macros in the kernel very often include constructions of the following kind:

drivers/block/ataflop.c
#define FDC_WRITE(reg,val) \
do { \
dma_wd.dma_mode_status = 0x80 | (reg); \
udelay(25); \
dma_wd.fdc_acces_seccount = (val); \
MFPDELAY(); \
} while(0)

Thedostatement formally ensures that the code is executed just once when the macro is ‘‘called‘‘ and
does not alter the semantics as compared to a variant without an enclosingdoloop. The advantage
of this construction becomes clear when the macro is used inifqueries or similar language elements
as shown here:

if (condition)
FDC_WRITE(a,b);

Atfirstreading,thecodeappearstobecorrectbecausesingle-lineifbodies can — and in the kernel
usually are — used without braces. However, after macro expansion there would be a problem if the
enclosingdoconstruction were not present:

if (condition)
dma_wd.dma_mode_status = 0x80 | (reg);
udelay(25);
dma_wd.fdc_acces_seccount = (val);
MFPDELAY();
Free download pdf