sysdep.h
上传用户:wudi5211
上传日期:2010-01-21
资源大小:607k
文件大小:8k
源码类别:

嵌入式Linux

开发平台:

C/C++

  1. /*
  2.  * sysdep.h -- fixes some problems of portability in the range 1.2 - 2.0
  3.  *
  4.  * kdev_t                         for kernels < 1.3.28
  5.  * do_gettimeofday                for kernels < 1.3.46
  6.  * request_irq/free_irq/SA_SHIRQ  for kernels < 1.3.70
  7.  * FMODE_READ/FMODE_WRITE         for kernels < 1.3.46
  8.  * ioctl definitions              for kernels < 1.3.42
  9.  * get_user/put_user              for kernels < 1.3.0
  10.  * __*_ENDIAN                     for kernels < 1.3.19
  11.  * put_unaligned etc              for kernels < 1.99.6
  12.  * readb etc.                     for kernels < 1.3.4
  13.  * add_timer                      fir kernels < 1.3.14
  14.  * typing for count in read/write to account for differences in 2.1
  15.  * typing for offset in lseek to account for differences in 2.1
  16.  *
  17.  *********/
  18. #ifndef _ORABOOK_SYSDEP_H
  19. #define _ORABOOK_SYSDEP_H
  20. #ifndef VERSION_CODE
  21. #  define VERSION_CODE(vers,rel,seq) ( ((vers)<<16) | ((rel)<<8) | (seq) )
  22. #endif
  23. #include <linux/sched.h> /* this is needed for functions I use here */
  24. /*
  25.  * Macros to fake kdev_t with old kernels
  26.  */
  27. #if LINUX_VERSION_CODE < VERSION_CODE(1,3,28)
  28. #  define kdev_t dev_t
  29.    /* two conversion functions are defined in newer kernels */
  30. #  define kdev_t_to_nr(dev) (dev)
  31. #  define to_kdev_t(dev)    (dev)
  32. #endif
  33. /*
  34.  * Reimplement do_gettimeofday (with less precision) for versions
  35.  * not exporting the true code
  36.  */
  37. #if LINUX_VERSION_CODE < VERSION_CODE(1,3,46)
  38. /* 
  39.  * kernel headers already declare the function as non-static.
  40.  * We reimplement it with another name, and #define it
  41.  */
  42. extern inline void redo_gettimeofday(struct timeval *tv)
  43. {
  44.     unsigned long flags;
  45.     save_flags(flags);
  46.     cli();
  47.     *tv = xtime;
  48.     restore_flags(flags);
  49. }
  50. #define do_gettimeofday(tv) redo_gettimeofday(tv)
  51. #endif
  52. /*
  53.  * 1.3.70 changed the semantics of irq request/free to allow shared irq's
  54.  */
  55. #if LINUX_VERSION_CODE < VERSION_CODE(1,3,70)
  56.    /* the preprocessor is able to handle recursive definitions */
  57. #  define request_irq(irq,fun,fla,nam,dev) request_irq(irq,fun,fla,nam)
  58. #  define free_irq(irq,dev)                free_irq(irq)
  59. #  define SA_SHIRQ 0 /* doesn't exist */
  60. #endif
  61. /*
  62.  * FMODE_READ was introduced in 1.3.46.
  63.  * Explicit numbers were used before then
  64.  */
  65. #if LINUX_VERSION_CODE < VERSION_CODE(1,3,46)
  66. #  define FMODE_READ 1
  67. #  define FMODE_WRITE 2
  68. #endif
  69. /*
  70.  * 1.3.22 added the full featured ioctl bitmasks and macros
  71.  *        but with _IOC_READ and _IOC_WRITE swapped.
  72.  *        Earlier kernels defined some of them, but not all.
  73.  *        Besides, macros in 1.2.x are really ugly to read.
  74.  * 1.3.32 added _IOC_TYPE
  75.  * 1.3.42 fixed _IOC_READ and _IOC_WRITE
  76.  *
  77.  * The errors are understandable in experimental kernels, but
  78.  * try to fix them here. I, for one, still run 1.3.30 and 1.3.41,
  79.  * which used to be very stable kernels. At the time no drivers used
  80.  * such macros, so nobody noticed the were buggy. Since I uses them here,
  81.  * I want them right.
  82.  */
  83. #if LINUX_VERSION_CODE < VERSION_CODE(1,3,22)
  84. #  define _IOC_NRBITS     8
  85. #  define _IOC_TYPEBITS   8
  86. #  define _IOC_SIZEBITS   14
  87. #  define _IOC_DIRBITS    2
  88. #  define _IOC_NRMASK     ((1 << _IOC_NRBITS)-1)
  89. #  define _IOC_TYPEMASK   ((1 << _IOC_TYPEBITS)-1)
  90. #  define _IOC_SIZEMASK   ((1 << _IOC_SIZEBITS)-1)
  91. #  define _IOC_DIRMASK    ((1 << _IOC_DIRBITS)-1)
  92. #  define _IOC_NRSHIFT    0
  93. #  define _IOC_TYPESHIFT  (_IOC_NRSHIFT+_IOC_NRBITS)
  94. #  define _IOC_SIZESHIFT  (_IOC_TYPESHIFT+_IOC_TYPEBITS)
  95. #  define _IOC_DIRSHIFT   (_IOC_SIZESHIFT+_IOC_SIZEBITS)
  96. #  define _IOC_DIR(nr)            (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
  97. #  define _IOC_NR(nr)             (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
  98. #  define _IOC_SIZE(nr)           (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
  99. #endif
  100. #if LINUX_VERSION_CODE < VERSION_CODE(1,3,32)
  101. #  define _IOC_TYPE(nr)           (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
  102. #endif
  103. #if LINUX_VERSION_CODE < VERSION_CODE(1,3,42)
  104. #  undef _IOC_NONE
  105. #  undef _IOC_WRITE
  106. #  undef _IOC_READ
  107. #  define _IOC_NONE       0U
  108. #  define _IOC_WRITE      1U
  109. #  define _IOC_READ       2U
  110. #endif
  111. /*******************************************************************
  112.  * 1.3.0 added the put_user size-independent macro. Copy it here
  113.  *
  114.  * This code (up to the next line of stars) comes from the kernel headers
  115.  */
  116. #if LINUX_VERSION_CODE < VERSION_CODE(1,3,0)
  117. #define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr)))
  118. #define get_user(ptr) ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr))))
  119. /*
  120.  * This is a silly but good way to make sure that
  121.  * the __put_user function is indeed always optimized,
  122.  * and that we use the correct sizes..
  123.  */
  124. extern int bad_user_access_length(void);
  125. /*
  126.  * dummy pointer type structure.. gcc won't try to do something strange
  127.  * this way..
  128.  */
  129. struct __segment_dummy { unsigned long a[100]; };
  130. #define __sd(x) ((struct __segment_dummy *) (x))
  131. #define __const_sd(x) ((const struct __segment_dummy *) (x))
  132. static inline void __put_user(unsigned long x, void * y, int size)
  133. {
  134.         switch (size) {
  135. case 1:
  136.                         __asm__ ("movb %b1,%%fs:%0"
  137.  :"=m" (*__sd(y))
  138.  :"iq" ((unsigned char) x), "m" (*__sd(y)));
  139.                         break;
  140. case 2:
  141.                         __asm__ ("movw %w1,%%fs:%0"
  142.  :"=m" (*__sd(y))
  143.  :"ir" ((unsigned short) x), "m" (*__sd(y)));
  144.                         break;
  145. case 4:
  146.                         __asm__ ("movl %1,%%fs:%0"
  147.  :"=m" (*__sd(y))
  148.  :"ir" (x), "m" (*__sd(y)));
  149.                         break;
  150. default:
  151.                         bad_user_access_length();
  152. }
  153. }
  154. static inline unsigned long __get_user(const void * y, int size)
  155. {
  156.         unsigned long result;
  157.         switch (size) {
  158. case 1:
  159.                         __asm__ ("movb %%fs:%1,%b0"
  160.  :"=q" (result)
  161.  :"m" (*__const_sd(y)));
  162.                         return (unsigned char) result;
  163. case 2:
  164.                         __asm__ ("movw %%fs:%1,%w0"
  165.  :"=r" (result)
  166.  :"m" (*__const_sd(y)));
  167.                         return (unsigned short) result;
  168. case 4:
  169.                         __asm__ ("movl %%fs:%1,%0"
  170.  :"=r" (result)
  171.  :"m" (*__const_sd(y)));
  172.                         return result;
  173. default:
  174.                         return bad_user_access_length();
  175. }
  176. }
  177. /*******************************************************************/
  178. #endif
  179. /*
  180.  * __LITTLE_ENDIAN and friends missed the underscore before 1.3.19
  181.  */
  182. #if LINUX_VERSION_CODE < VERSION_CODE(1,3,19)
  183. #  ifdef LITTLE_ENDIAN
  184. #    define __LITTLE_ENDIAN
  185. #    define __LITTLE_ENDIAN_BITFIELD
  186. #  endif
  187. #  ifdef BIG_ENDIAN
  188. #    define __BIG_ENDIAN
  189. #    define __BIG_ENDIAN_BITFIELD
  190. #  endif
  191. #endif
  192. /*
  193.  * get_unaligned was only incroduced in 1.99.6, but asm-generic
  194.  * has a C reimplementation for it. Here it is (just copied :)
  195.  */
  196. #if LINUX_VERSION_CODE < VERSION_CODE(1,99,6)
  197. #  ifndef __i386__
  198. #    include <asm/string.h> /* memcpy */
  199. #    define get_unaligned(ptr)                             
  200.        ({ __typeof__(*(ptr)) __tmp;                        
  201.          memcpy(&__tmp, (ptr), sizeof(*(ptr))); __tmp; })
  202. #    define put_unaligned(val, ptr)                        
  203.        ({ __typeof__(*(ptr)) __tmp = (val);                
  204.          memcpy((ptr), &__tmp, sizeof(*(ptr)));            
  205.          (void)0; })
  206. #  else
  207. #    define get_unaligned(ptr) (*(ptr))
  208. #    define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
  209. #  endif /* i386 */
  210. #endif
  211. /*
  212.  * define readb etc. This is only valid for the Intel platform
  213.  */
  214. #if LINUX_VERSION_CODE < VERSION_CODE(1,3,4)
  215. #define readb(addr) (*(volatile unsigned char *) (addr))
  216. #define readw(addr) (*(volatile unsigned short *) (addr))
  217. #define readl(addr) (*(volatile unsigned int *) (addr))
  218. #define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
  219. #define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
  220. #define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
  221. #define memset_io(a,b,c)        memset((void *)(a),(b),(c))
  222. #define memcpy_fromio(a,b,c)    memcpy((a),(void *)(b),(c))
  223. #define memcpy_toio(a,b,c)      memcpy((void *)(a),(b),(c))
  224. #endif
  225. /*
  226.  * 2.1 (and the axp-diffs-2.0.x) changed from `int' to `unsigned long'
  227.  * the count argument to read() and write(). Define a portable count_t
  228.  */
  229. #if defined(__alpha__) || (LINUX_VERSION_CODE >= VERSION_CODE(2,1,0))
  230. # define count_t unsigned long
  231. # define read_write_t long
  232. #else
  233. # define count_t int
  234. # define read_write_t int
  235. #endif
  236. #if LINUX_VERSION_CODE < VERSION_CODE(1,3,14)
  237. # define add_timer(t) do {(t)->expires-=jiffies; add_timer(t);} while(0)
  238. #endif
  239. #endif /* _ORABOOK_SYSDEP_H */