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