1*c609719bSwdenk #ifndef _LINUX_BYTEORDER_GENERIC_H
2*c609719bSwdenk #define _LINUX_BYTEORDER_GENERIC_H
3*c609719bSwdenk 
4*c609719bSwdenk /*
5*c609719bSwdenk  * linux/byteorder_generic.h
6*c609719bSwdenk  * Generic Byte-reordering support
7*c609719bSwdenk  *
8*c609719bSwdenk  * Francois-Rene Rideau <fare@tunes.org> 19970707
9*c609719bSwdenk  *    gathered all the good ideas from all asm-foo/byteorder.h into one file,
10*c609719bSwdenk  *    cleaned them up.
11*c609719bSwdenk  *    I hope it is compliant with non-GCC compilers.
12*c609719bSwdenk  *    I decided to put __BYTEORDER_HAS_U64__ in byteorder.h,
13*c609719bSwdenk  *    because I wasn't sure it would be ok to put it in types.h
14*c609719bSwdenk  *    Upgraded it to 2.1.43
15*c609719bSwdenk  * Francois-Rene Rideau <fare@tunes.org> 19971012
16*c609719bSwdenk  *    Upgraded it to 2.1.57
17*c609719bSwdenk  *    to please Linus T., replaced huge #ifdef's between little/big endian
18*c609719bSwdenk  *    by nestedly #include'd files.
19*c609719bSwdenk  * Francois-Rene Rideau <fare@tunes.org> 19971205
20*c609719bSwdenk  *    Made it to 2.1.71; now a facelift:
21*c609719bSwdenk  *    Put files under include/linux/byteorder/
22*c609719bSwdenk  *    Split swab from generic support.
23*c609719bSwdenk  *
24*c609719bSwdenk  * TODO:
25*c609719bSwdenk  *   = Regular kernel maintainers could also replace all these manual
26*c609719bSwdenk  *    byteswap macros that remain, disseminated among drivers,
27*c609719bSwdenk  *    after some grep or the sources...
28*c609719bSwdenk  *   = Linus might want to rename all these macros and files to fit his taste,
29*c609719bSwdenk  *    to fit his personal naming scheme.
30*c609719bSwdenk  *   = it seems that a few drivers would also appreciate
31*c609719bSwdenk  *    nybble swapping support...
32*c609719bSwdenk  *   = every architecture could add their byteswap macro in asm/byteorder.h
33*c609719bSwdenk  *    see how some architectures already do (i386, alpha, ppc, etc)
34*c609719bSwdenk  *   = cpu_to_beXX and beXX_to_cpu might some day need to be well
35*c609719bSwdenk  *    distinguished throughout the kernel. This is not the case currently,
36*c609719bSwdenk  *    since little endian, big endian, and pdp endian machines needn't it.
37*c609719bSwdenk  *    But this might be the case for, say, a port of Linux to 20/21 bit
38*c609719bSwdenk  *    architectures (and F21 Linux addict around?).
39*c609719bSwdenk  */
40*c609719bSwdenk 
41*c609719bSwdenk /*
42*c609719bSwdenk  * The following macros are to be defined by <asm/byteorder.h>:
43*c609719bSwdenk  *
44*c609719bSwdenk  * Conversion of long and short int between network and host format
45*c609719bSwdenk  *	ntohl(__u32 x)
46*c609719bSwdenk  *	ntohs(__u16 x)
47*c609719bSwdenk  *	htonl(__u32 x)
48*c609719bSwdenk  *	htons(__u16 x)
49*c609719bSwdenk  * It seems that some programs (which? where? or perhaps a standard? POSIX?)
50*c609719bSwdenk  * might like the above to be functions, not macros (why?).
51*c609719bSwdenk  * if that's true, then detect them, and take measures.
52*c609719bSwdenk  * Anyway, the measure is: define only ___ntohl as a macro instead,
53*c609719bSwdenk  * and in a separate file, have
54*c609719bSwdenk  * unsigned long inline ntohl(x){return ___ntohl(x);}
55*c609719bSwdenk  *
56*c609719bSwdenk  * The same for constant arguments
57*c609719bSwdenk  *	__constant_ntohl(__u32 x)
58*c609719bSwdenk  *	__constant_ntohs(__u16 x)
59*c609719bSwdenk  *	__constant_htonl(__u32 x)
60*c609719bSwdenk  *	__constant_htons(__u16 x)
61*c609719bSwdenk  *
62*c609719bSwdenk  * Conversion of XX-bit integers (16- 32- or 64-)
63*c609719bSwdenk  * between native CPU format and little/big endian format
64*c609719bSwdenk  * 64-bit stuff only defined for proper architectures
65*c609719bSwdenk  *	cpu_to_[bl]eXX(__uXX x)
66*c609719bSwdenk  *	[bl]eXX_to_cpu(__uXX x)
67*c609719bSwdenk  *
68*c609719bSwdenk  * The same, but takes a pointer to the value to convert
69*c609719bSwdenk  *	cpu_to_[bl]eXXp(__uXX x)
70*c609719bSwdenk  *	[bl]eXX_to_cpup(__uXX x)
71*c609719bSwdenk  *
72*c609719bSwdenk  * The same, but change in situ
73*c609719bSwdenk  *	cpu_to_[bl]eXXs(__uXX x)
74*c609719bSwdenk  *	[bl]eXX_to_cpus(__uXX x)
75*c609719bSwdenk  *
76*c609719bSwdenk  * See asm-foo/byteorder.h for examples of how to provide
77*c609719bSwdenk  * architecture-optimized versions
78*c609719bSwdenk  *
79*c609719bSwdenk  */
80*c609719bSwdenk 
81*c609719bSwdenk 
82*c609719bSwdenk #if defined(__KERNEL__)
83*c609719bSwdenk /*
84*c609719bSwdenk  * inside the kernel, we can use nicknames;
85*c609719bSwdenk  * outside of it, we must avoid POSIX namespace pollution...
86*c609719bSwdenk  */
87*c609719bSwdenk #define cpu_to_le64 __cpu_to_le64
88*c609719bSwdenk #define le64_to_cpu __le64_to_cpu
89*c609719bSwdenk #define cpu_to_le32 __cpu_to_le32
90*c609719bSwdenk #define le32_to_cpu __le32_to_cpu
91*c609719bSwdenk #define cpu_to_le16 __cpu_to_le16
92*c609719bSwdenk #define le16_to_cpu __le16_to_cpu
93*c609719bSwdenk #define cpu_to_be64 __cpu_to_be64
94*c609719bSwdenk #define be64_to_cpu __be64_to_cpu
95*c609719bSwdenk #define cpu_to_be32 __cpu_to_be32
96*c609719bSwdenk #define be32_to_cpu __be32_to_cpu
97*c609719bSwdenk #define cpu_to_be16 __cpu_to_be16
98*c609719bSwdenk #define be16_to_cpu __be16_to_cpu
99*c609719bSwdenk #define cpu_to_le64p __cpu_to_le64p
100*c609719bSwdenk #define le64_to_cpup __le64_to_cpup
101*c609719bSwdenk #define cpu_to_le32p __cpu_to_le32p
102*c609719bSwdenk #define le32_to_cpup __le32_to_cpup
103*c609719bSwdenk #define cpu_to_le16p __cpu_to_le16p
104*c609719bSwdenk #define le16_to_cpup __le16_to_cpup
105*c609719bSwdenk #define cpu_to_be64p __cpu_to_be64p
106*c609719bSwdenk #define be64_to_cpup __be64_to_cpup
107*c609719bSwdenk #define cpu_to_be32p __cpu_to_be32p
108*c609719bSwdenk #define be32_to_cpup __be32_to_cpup
109*c609719bSwdenk #define cpu_to_be16p __cpu_to_be16p
110*c609719bSwdenk #define be16_to_cpup __be16_to_cpup
111*c609719bSwdenk #define cpu_to_le64s __cpu_to_le64s
112*c609719bSwdenk #define le64_to_cpus __le64_to_cpus
113*c609719bSwdenk #define cpu_to_le32s __cpu_to_le32s
114*c609719bSwdenk #define le32_to_cpus __le32_to_cpus
115*c609719bSwdenk #define cpu_to_le16s __cpu_to_le16s
116*c609719bSwdenk #define le16_to_cpus __le16_to_cpus
117*c609719bSwdenk #define cpu_to_be64s __cpu_to_be64s
118*c609719bSwdenk #define be64_to_cpus __be64_to_cpus
119*c609719bSwdenk #define cpu_to_be32s __cpu_to_be32s
120*c609719bSwdenk #define be32_to_cpus __be32_to_cpus
121*c609719bSwdenk #define cpu_to_be16s __cpu_to_be16s
122*c609719bSwdenk #define be16_to_cpus __be16_to_cpus
123*c609719bSwdenk #endif
124*c609719bSwdenk 
125*c609719bSwdenk 
126*c609719bSwdenk /*
127*c609719bSwdenk  * Handle ntohl and suches. These have various compatibility
128*c609719bSwdenk  * issues - like we want to give the prototype even though we
129*c609719bSwdenk  * also have a macro for them in case some strange program
130*c609719bSwdenk  * wants to take the address of the thing or something..
131*c609719bSwdenk  *
132*c609719bSwdenk  * Note that these used to return a "long" in libc5, even though
133*c609719bSwdenk  * long is often 64-bit these days.. Thus the casts.
134*c609719bSwdenk  *
135*c609719bSwdenk  * They have to be macros in order to do the constant folding
136*c609719bSwdenk  * correctly - if the argument passed into a inline function
137*c609719bSwdenk  * it is no longer constant according to gcc..
138*c609719bSwdenk  */
139*c609719bSwdenk 
140*c609719bSwdenk #undef ntohl
141*c609719bSwdenk #undef ntohs
142*c609719bSwdenk #undef htonl
143*c609719bSwdenk #undef htons
144*c609719bSwdenk 
145*c609719bSwdenk /*
146*c609719bSwdenk  * Do the prototypes. Somebody might want to take the
147*c609719bSwdenk  * address or some such sick thing..
148*c609719bSwdenk  */
149*c609719bSwdenk #if defined(__KERNEL__) || (defined (__GLIBC__) && __GLIBC__ >= 2)
150*c609719bSwdenk extern __u32			ntohl(__u32);
151*c609719bSwdenk extern __u32			htonl(__u32);
152*c609719bSwdenk #else
153*c609719bSwdenk extern unsigned long int	ntohl(unsigned long int);
154*c609719bSwdenk extern unsigned long int	htonl(unsigned long int);
155*c609719bSwdenk #endif
156*c609719bSwdenk extern unsigned short int	ntohs(unsigned short int);
157*c609719bSwdenk extern unsigned short int	htons(unsigned short int);
158*c609719bSwdenk 
159*c609719bSwdenk 
160*c609719bSwdenk #if defined(__GNUC__) && (__GNUC__ >= 2)
161*c609719bSwdenk 
162*c609719bSwdenk #define ___htonl(x) __cpu_to_be32(x)
163*c609719bSwdenk #define ___htons(x) __cpu_to_be16(x)
164*c609719bSwdenk #define ___ntohl(x) __be32_to_cpu(x)
165*c609719bSwdenk #define ___ntohs(x) __be16_to_cpu(x)
166*c609719bSwdenk 
167*c609719bSwdenk #if defined(__KERNEL__) || (defined (__GLIBC__) && __GLIBC__ >= 2)
168*c609719bSwdenk #define htonl(x) ___htonl(x)
169*c609719bSwdenk #define ntohl(x) ___ntohl(x)
170*c609719bSwdenk #else
171*c609719bSwdenk #define htonl(x) ((unsigned long)___htonl(x))
172*c609719bSwdenk #define ntohl(x) ((unsigned long)___ntohl(x))
173*c609719bSwdenk #endif
174*c609719bSwdenk #define htons(x) ___htons(x)
175*c609719bSwdenk #define ntohs(x) ___ntohs(x)
176*c609719bSwdenk 
177*c609719bSwdenk #endif /* OPTIMIZE */
178*c609719bSwdenk 
179*c609719bSwdenk 
180*c609719bSwdenk #endif /* _LINUX_BYTEORDER_GENERIC_H */
181