sym_misc.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:9k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family 
  3.  * of PCI-SCSI IO processors.
  4.  *
  5.  * Copyright (C) 1999-2001  Gerard Roudier <groudier@free.fr>
  6.  *
  7.  * This driver is derived from the Linux sym53c8xx driver.
  8.  * Copyright (C) 1998-2000  Gerard Roudier
  9.  *
  10.  * The sym53c8xx driver is derived from the ncr53c8xx driver that had been 
  11.  * a port of the FreeBSD ncr driver to Linux-1.2.13.
  12.  *
  13.  * The original ncr driver has been written for 386bsd and FreeBSD by
  14.  *         Wolfgang Stanglmeier        <wolf@cologne.de>
  15.  *         Stefan Esser                <se@mi.Uni-Koeln.de>
  16.  * Copyright (C) 1994  Wolfgang Stanglmeier
  17.  *
  18.  * Other major contributions:
  19.  *
  20.  * NVRAM detection and reading.
  21.  * Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
  22.  *
  23.  *-----------------------------------------------------------------------------
  24.  *
  25.  * Redistribution and use in source and binary forms, with or without
  26.  * modification, are permitted provided that the following conditions
  27.  * are met:
  28.  * 1. Redistributions of source code must retain the above copyright
  29.  *    notice, this list of conditions and the following disclaimer.
  30.  * 2. The name of the author may not be used to endorse or promote products
  31.  *    derived from this software without specific prior written permission.
  32.  *
  33.  * Where this Software is combined with software released under the terms of 
  34.  * the GNU Public License ("GPL") and the terms of the GPL would require the 
  35.  * combined work to also be released under the terms of the GPL, the terms
  36.  * and conditions of this License will apply in addition to those of the
  37.  * GPL with the exception of any terms or conditions of this License that
  38.  * conflict with, or are expressly prohibited by, the GPL.
  39.  *
  40.  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
  41.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  42.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  43.  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  44.  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  45.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  46.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  48.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  49.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  50.  * SUCH DAMAGE.
  51.  */
  52. #ifndef SYM_MISC_H
  53. #define SYM_MISC_H
  54. /*
  55.  *  A 'read barrier' flushes any data that have been prefetched 
  56.  *  by the processor due to out of order execution. Such a barrier 
  57.  *  must notably be inserted prior to looking at data that have 
  58.  *  been DMAed, assuming that program does memory READs in proper 
  59.  *  order and that the device ensured proper ordering of WRITEs.
  60.  *
  61.  *  A 'write barrier' prevents any previous WRITEs to pass further 
  62.  *  WRITEs. Such barriers must be inserted each time another agent 
  63.  *  relies on ordering of WRITEs.
  64.  *
  65.  *  Note that, due to posting of PCI memory writes, we also must 
  66.  *  insert dummy PCI read transactions when some ordering involving 
  67.  *  both directions over the PCI does matter. PCI transactions are 
  68.  *  fully ordered in each direction.
  69.  *
  70.  *  IA32 processors insert implicit barriers when the processor 
  71.  *  accesses unchacheable either for reading or writing, and 
  72.  *  donnot reorder WRITEs. As a result, some 'read barriers' can 
  73.  *  be avoided (following access to uncacheable), and 'write 
  74.  *  barriers' should be useless (preventing compiler optimizations 
  75.  *  should be enough).
  76.  */
  77. #if defined __i386__
  78. #define __READ_BARRIER()
  79. __asm__ volatile("lock; addl $0,0(%%esp)": : :"memory")
  80. #define __WRITE_BARRIER() __asm__ volatile ("": : :"memory")
  81. #elif defined __powerpc__
  82. #define __READ_BARRIER() __asm__ volatile("eieio; sync" : : : "memory")
  83. #define __WRITE_BARRIER() __asm__ volatile("eieio; sync" : : : "memory")
  84. #elif defined __ia64__
  85. #define __READ_BARRIER() __asm__ volatile("mf.a; mf" : : : "memory")
  86. #define __WRITE_BARRIER() __asm__ volatile("mf.a; mf" : : : "memory")
  87. #elif defined __alpha__
  88. #define __READ_BARRIER() __asm__ volatile("mb": : :"memory")
  89. #define __WRITE_BARRIER() __asm__ volatile("mb": : :"memory")
  90. #else
  91. #define __READ_BARRIER() mb()
  92. #define __WRITE_BARRIER() mb()
  93. #endif
  94. #ifndef MEMORY_READ_BARRIER
  95. #define MEMORY_READ_BARRIER() __READ_BARRIER()
  96. #endif
  97. #ifndef MEMORY_WRITE_BARRIER
  98. #define MEMORY_WRITE_BARRIER() __WRITE_BARRIER()
  99. #endif
  100. /*
  101.  *  A la VMS/CAM-3 queue management.
  102.  */
  103. typedef struct sym_quehead {
  104. struct sym_quehead *flink; /* Forward  pointer */
  105. struct sym_quehead *blink; /* Backward pointer */
  106. } SYM_QUEHEAD;
  107. #define sym_que_init(ptr) do { 
  108. (ptr)->flink = (ptr); (ptr)->blink = (ptr); 
  109. } while (0)
  110. static __inline struct sym_quehead *sym_que_first(struct sym_quehead *head)
  111. {
  112. return (head->flink == head) ? 0 : head->flink;
  113. }
  114. static __inline struct sym_quehead *sym_que_last(struct sym_quehead *head)
  115. {
  116. return (head->blink == head) ? 0 : head->blink;
  117. }
  118. static __inline void __sym_que_add(struct sym_quehead * new,
  119. struct sym_quehead * blink,
  120. struct sym_quehead * flink)
  121. {
  122. flink->blink = new;
  123. new->flink = flink;
  124. new->blink = blink;
  125. blink->flink = new;
  126. }
  127. static __inline void __sym_que_del(struct sym_quehead * blink,
  128. struct sym_quehead * flink)
  129. {
  130. flink->blink = blink;
  131. blink->flink = flink;
  132. }
  133. static __inline int sym_que_empty(struct sym_quehead *head)
  134. {
  135. return head->flink == head;
  136. }
  137. static __inline void sym_que_splice(struct sym_quehead *list,
  138. struct sym_quehead *head)
  139. {
  140. struct sym_quehead *first = list->flink;
  141. if (first != list) {
  142. struct sym_quehead *last = list->blink;
  143. struct sym_quehead *at   = head->flink;
  144. first->blink = head;
  145. head->flink  = first;
  146. last->flink = at;
  147. at->blink   = last;
  148. }
  149. }
  150. static __inline void sym_que_move(struct sym_quehead *orig,
  151. struct sym_quehead *dest)
  152. {
  153. struct sym_quehead *first, *last;
  154. first = orig->flink;
  155. if (first != orig) {
  156. first->blink = dest;
  157. dest->flink  = first;
  158. last = orig->blink;
  159. last->flink  = dest;
  160. dest->blink  = last;
  161. orig->flink  = orig;
  162. orig->blink  = orig;
  163. } else {
  164. dest->flink  = dest;
  165. dest->blink  = dest;
  166. }
  167. }
  168. #define sym_que_entry(ptr, type, member) 
  169. ((type *)((char *)(ptr)-(unsigned int)(&((type *)0)->member)))
  170. #define sym_insque(new, pos) __sym_que_add(new, pos, (pos)->flink)
  171. #define sym_remque(el) __sym_que_del((el)->blink, (el)->flink)
  172. #define sym_insque_head(new, head) __sym_que_add(new, head, (head)->flink)
  173. static __inline struct sym_quehead *sym_remque_head(struct sym_quehead *head)
  174. {
  175. struct sym_quehead *elem = head->flink;
  176. if (elem != head)
  177. __sym_que_del(head, elem->flink);
  178. else
  179. elem = 0;
  180. return elem;
  181. }
  182. #define sym_insque_tail(new, head) __sym_que_add(new, (head)->blink, head)
  183. static __inline struct sym_quehead *sym_remque_tail(struct sym_quehead *head)
  184. {
  185. struct sym_quehead *elem = head->blink;
  186. if (elem != head)
  187. __sym_que_del(elem->blink, head);
  188. else
  189. elem = 0;
  190. return elem;
  191. }
  192. /*
  193.  *  This one may be useful.
  194.  */
  195. #define FOR_EACH_QUEUED_ELEMENT(head, qp) 
  196. for (qp = (head)->flink; qp != (head); qp = qp->flink)
  197. /*
  198.  *  FreeBSD does not offer our kind of queue in the CAM CCB.
  199.  *  So, we have to cast.
  200.  */
  201. #define sym_qptr(p) ((struct sym_quehead *) (p))
  202. /*
  203.  *  Simple bitmap operations.
  204.  */ 
  205. #define sym_set_bit(p, n) (((u32 *)(p))[(n)>>5] |=  (1<<((n)&0x1f)))
  206. #define sym_clr_bit(p, n) (((u32 *)(p))[(n)>>5] &= ~(1<<((n)&0x1f)))
  207. #define sym_is_bit(p, n) (((u32 *)(p))[(n)>>5] &   (1<<((n)&0x1f)))
  208. /*
  209.  *  Portable but silly implemented byte order primitives.
  210.  */
  211. #if BYTE_ORDER == BIG_ENDIAN
  212. #define __revb16(x) ( (((u16)(x) & (u16)0x00ffU) << 8) | 
  213. (((u16)(x) & (u16)0xff00U) >> 8)  )
  214. #define __revb32(x) ( (((u32)(x) & 0x000000ffU) << 24) | 
  215. (((u32)(x) & 0x0000ff00U) <<  8) | 
  216. (((u32)(x) & 0x00ff0000U) >>  8) | 
  217. (((u32)(x) & 0xff000000U) >> 24) )
  218. #define __htole16(v) __revb16(v)
  219. #define __htole32(v) __revb32(v)
  220. #define __le16toh(v) __htole16(v)
  221. #define __le32toh(v) __htole32(v)
  222. static __inline u16 _htole16(u16 v) { return __htole16(v); }
  223. static __inline u32 _htole32(u32 v) { return __htole32(v); }
  224. #define _le16toh _htole16
  225. #define _le32toh _htole32
  226. #else /* LITTLE ENDIAN */
  227. #define __htole16(v) (v)
  228. #define __htole32(v) (v)
  229. #define __le16toh(v) (v)
  230. #define __le32toh(v) (v)
  231. #define _htole16(v) (v)
  232. #define _htole32(v) (v)
  233. #define _le16toh(v) (v)
  234. #define _le32toh(v) (v)
  235. #endif /* BYTE_ORDER */
  236. /*
  237.  * The below round up/down macros are to be used with a constant 
  238.  * as argument (sizeof(...) for example), for the compiler to 
  239.  * optimize the whole thing.
  240.  */
  241. #define _U_(a,m) (a)<=(1<<m)?m:
  242. #define _D_(a,m) (a)<(1<<(m+1))?m:
  243. /*
  244.  * Round up logarithm to base 2 of a 16 bit constant.
  245.  */
  246. #define _LGRU16_(a) 
  247.  _U_(a, 0)_U_(a, 1)_U_(a, 2)_U_(a, 3)_U_(a, 4)_U_(a, 5)_U_(a, 6)_U_(a, 7) 
  248.  _U_(a, 8)_U_(a, 9)_U_(a,10)_U_(a,11)_U_(a,12)_U_(a,13)_U_(a,14)_U_(a,15) 
  249.  16)
  250. /*
  251.  * Round down logarithm to base 2 of a 16 bit constant.
  252.  */
  253. #define _LGRD16_(a) 
  254.  _D_(a, 0)_D_(a, 1)_D_(a, 2)_D_(a, 3)_D_(a, 4)_D_(a, 5)_D_(a, 6)_D_(a, 7) 
  255.  _D_(a, 8)_D_(a, 9)_D_(a,10)_D_(a,11)_D_(a,12)_D_(a,13)_D_(a,14)_D_(a,15) 
  256.  16)
  257. /*
  258.  * Round up a 16 bit constant to the nearest power of 2.
  259.  */
  260. #define _SZRU16_(a) ((a)==0?0:(1<<_LGRU16_(a)))
  261. /*
  262.  * Round down a 16 bit constant to the nearest power of 2.
  263.  */
  264. #define _SZRD16_(a) ((a)==0?0:(1<<_LGRD16_(a)))
  265. #endif /* SYM_MISC_H */