xref: /dragonfly/sys/dev/raid/asr/dptalign.h (revision abf903a5)
1 /*-
2  * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
3  * All rights reserved.
4  *
5  * Redistribution and use in source form, with or without modification, are
6  * permitted provided that redistributions of source code must retain the
7  * above copyright notice, this list of conditions and the following disclaimer.
8  *
9  * This software is provided `as is' by Distributed Processing Technology and
10  * any express or implied warranties, including, but not limited to, the
11  * implied warranties of merchantability and fitness for a particular purpose,
12  * are disclaimed. In no event shall Distributed Processing Technology be
13  * liable for any direct, indirect, incidental, special, exemplary or
14  * consequential damages (including, but not limited to, procurement of
15  * substitute goods or services; loss of use, data, or profits; or business
16  * interruptions) however caused and on any theory of liability, whether in
17  * contract, strict liability, or tort (including negligence or otherwise)
18  * arising in any way out of the use of x driver software, even if advised
19  * of the possibility of such damage.
20  *
21  * DPT Alignment Description File
22  *
23  * $FreeBSD: src/sys/dev/asr/dptalign.h,v 1.6 2005/01/06 01:42:29 imp Exp $
24  */
25 #if (!defined(__DPTALIGN_H))
26 #define	      __DPTALIGN_H
27 
28 /*
29  *	File -	DPTALIGN.H
30  *
31  *	Description:  This file contains basic Alignment support definitions.
32  *
33  *	Copyright Distributed Processing Technology, Corp.
34  *	  140 Candace Dr.
35  *	  Maitland, Fl. 32751	USA
36  *	  Phone: (407) 830-5522	 Fax: (407) 260-5366
37  *	  All Rights Reserved
38  *
39  *	Author: Mark Salyzyn
40  *	Date:	Aug 29 1996
41  *
42  *
43  *	Fifth Gen product enhancements and additions
44  *	Author: Ben Ghofrani
45  *	Date:	April 6 1998
46  */
47 
48 /*
49  *	Description: Support macros for active alignment
50  *	Requires:
51  *		osdLocal2(x)
52  *		osdLocal4(x)
53  *		osdSwap2(x)
54  *		osdSwap4(x)
55  */
56 #if (!defined(__FAR__))
57 # if (defined(__BORLANDC__))
58 #  define __FAR__ far
59 # else
60 #  define __FAR__
61 # endif
62 #endif
63 
64 
65 #if (defined(sun)) && (!defined(_ILP32))
66 #  define DPT_4_BYTES int	/* 64 bit OS */
67 #else
68 #  define DPT_4_BYTES long
69 #endif
70 
71 #if (!defined(osdSwap2))
72 /*
73  *	Name: osdSwap2(value)
74  *	Description: Mandatory byte swapping routine for words. We allow an
75  *	override of x routine if the OS supplies it's own byte swapping
76  *	routine, inline or macro.
77  */
78 # define osdSwap2(x) (((unsigned short)(x) >> 8) \
79 		    | ((unsigned short)((unsigned char)(x)) << 8))
80 #endif
81 #if (!defined(osdSwap4))
82 /*
83  *	Name: osdSwap4(value)
84  *	Description: Mandatory byte swapping routine for DPT_4_BYTES words. We allow
85  *	an override of x routine if the OS supplies it's own byte swapping
86  *	routine, inline or macro. The following is universal, but may be
87  *	more optimally performed by an OS or driver processor dependant
88  *	routine.
89  */
90 # define osdSwap4(x)	 (						     \
91     (((unsigned DPT_4_BYTES)(x)) >> 24L)					    \
92   | ((unsigned DPT_4_BYTES)(((unsigned short)((unsigned DPT_4_BYTES)(x) >> 8L)) & 0xFF00)) \
93   | (((unsigned DPT_4_BYTES)(((unsigned short)(x)) & 0xFF00)) << 8L)		    \
94   | (((unsigned DPT_4_BYTES)((unsigned char)(x))) << 24L))
95 #endif
96 
97 
98 
99 #if (!defined(osdLocal2))
100 /*
101  *	Name: osdLocal2(pointer)
102  *	Description: Local byte order to Big Endian Format for short words.
103  *	Could be replaced with an OS defined localization routine, macro or
104  *	inline.
105  */
106 # if (defined(_DPT_BIG_ENDIAN))
107 #  define osdLocal2(x)	 (*((unsigned short __FAR__ *)(x)))
108 #  if (defined(osdSwap2))
109 #   define osdSLocal2(x) osdSwap2(osdLocal2(x))
110 #  else
111 #   define osdSLocal2(x) ((unsigned short)(((unsigned char __FAR__ *)(x))[1])\
112 	       + ((unsigned int)((unsigned short)(((unsigned char __FAR__ *)(x))[0])) << 8))
113 #  endif
114 # else
115 #  define osdSLocal2(x)	 (*((unsigned short __FAR__ *)(x)))
116 #  if (defined(osdSwap2))
117 #   define osdLocal2(x)	 osdSwap2(osdSLocal2(x))
118 #  else
119 #   define osdLocal2(x)	 ((unsigned short)(((unsigned char __FAR__*)(x))[1]) \
120 		+ (((unsigned short)(((unsigned char __FAR__*)(x))[0])) << 8))
121 #  endif
122 # endif
123 #endif
124 #if (!defined(osdLocal3))
125 /*
126  *	Name: osdLocal3(pointer)
127  *	Description: Local byte order to Big Endian Format for DPT_4_BYTES words.
128  *	Could be replaced with an OS defined localization routine, macro or
129  *	inline.
130  */
131 # if (defined(_DPT_BIG_ENDIAN))
132 #  define osdLocal3(x)	(*((unsigned DPT_4_BYTES __FAR__ *)(x)))
133 # else
134 #  if (defined(osdSwap3))
135 #   define osdLocal3(x) osdSwap3(*((unsigned DPT_4_BYTES __FAR__ *)(x)))
136 #  else
137 #   define osdLocal3(x) ((unsigned DPT_4_BYTES)osdLocal2(((unsigned char __FAR__ *) \
138        (x)+1)) + (((unsigned DPT_4_BYTES)(((unsigned char __FAR__ *)(x))[0])) << 16))
139 #  endif
140 # endif
141 #endif
142 
143 
144 
145 #if (!defined(osdLocal4))
146 /*
147  *	Name: osdLocal4(pointer)
148  *	Description: Local byte order to Big Endian Format for DPT_4_BYTES words.
149  *	Could be replaced with an OS defined localization routine, macro or
150  *	inline.
151  */
152 # if (defined(_DPT_BIG_ENDIAN))
153 #  define osdLocal4(x)	 (*(unsigned DPT_4_BYTES __FAR__ *)(x))
154 #  if (defined(osdSwap4))
155 #   define osdSLocal4(x) osdSwap4(osdLocal4(x))
156 #  else
157 #   define osdSLocal4(x) ((unsigned DPT_4_BYTES)osdSLocal2(((unsigned char __FAR__ *)\
158     (x)+2)) + (((unsigned DPT_4_BYTES)((unsigned char __FAR__ *)(x))[1]) << 16) \
159 	    + (((unsigned DPT_4_BYTES)((unsigned char __FAR__ *)(x))[0]) << 24))
160 #  endif
161 # else
162 #  define osdSLocal4(x) (*(unsigned DPT_4_BYTES __FAR__ *)(x))
163 #  if (defined(osdSwap4))
164 #   define osdLocal4(x) osdSwap4(osdSLocal4(x))
165 #  else
166 #   define osdLocal4(x) ((unsigned DPT_4_BYTES)osdLocal2(((unsigned char __FAR__ *) \
167 	(x)+2)) + (((unsigned DPT_4_BYTES)((unsigned char __FAR__ *)(x))[1]) << 16) \
168 		+ (((unsigned DPT_4_BYTES)((unsigned char __FAR__ *)(x))[0]) << 24))
169 #  endif
170 # endif
171 #endif
172 
173 #define	I2O_TID_MASK	((unsigned DPT_4_BYTES) ((1L<<I2O_TID_SZ)-1))
174 
175 /*
176  *	Now the access macros used throughout in order to methodize the
177  * active alignment.
178  */
179 #define	getUP1(x,y)  (((unsigned char __FAR__ *)(x))+(unsigned DPT_4_BYTES)(y))
180 #define	getU1(x,y)   (*getUP1(x,y))
181 #define	setU1(x,y,z) (*((unsigned char *)getUP1(x,y)) = (unsigned char)(z))
182 #define	orU1(x,y,z)  (*getUP1(x,y) |= (unsigned char)(z))
183 #define	andU1(x,y,z) (*getUP1(x,y) &= (unsigned char)(z))
184 #define	getUP2(x,y)  ((unsigned short __FAR__ *)(((unsigned char __FAR__ *) \
185 				(x))+(unsigned DPT_4_BYTES)(y)))
186 #define	getBU2(x,y)   ((unsigned short)osdLocal2((unsigned short __FAR__ *)  \
187 				getUP1(x,y)))
188 #define	getLU2(x,y)  ((unsigned short)osdSLocal2((unsigned short __FAR__ *) \
189 				getUP1(x,y)))
190 /* to be deleted  */
191 #define	getU2(x,y)   ((unsigned short)osdLocal2((unsigned short __FAR__ *)  \
192 				getUP1(x,y)))
193 #if (!defined(setU2))
194 # define setU2(x,y,z) { unsigned short hold = (unsigned short)(z);  \
195 			*((unsigned short __FAR__ *)getUP1(x,y))    \
196 			  = osdLocal2(&hold);			    \
197 		      }
198 #endif
199 #if (!defined(setBU2))
200 # define setBU2(x,y,z) { unsigned short hold = (unsigned short)(z);  \
201 			*((unsigned short __FAR__ *)getUP1(x,y))    \
202 			  = osdLocal2(&hold);			    \
203 		      }
204 #endif
205 #if (!defined(setLU2))
206 # define setLU2(x,y,z) { unsigned short hold = (unsigned short)(z); \
207 			 *((unsigned short __FAR__ *)getUP1(x,y))   \
208 			   = osdSLocal2(&hold);			    \
209 		       }
210 #endif
211 
212 /* to be deleted */
213 #define	getU3(x,y)   ((unsigned DPT_4_BYTES)osdLocal3((unsigned DPT_4_BYTES __FAR__ *) \
214 				getUP1(x,y)))
215 #if (!defined(setU3))
216 # if (defined(_DPT_BIG_ENDIAN))
217 #  define setU3(x,y,z)					   \
218 	{   unsigned DPT_4_BYTES hold = z;			  \
219 	    *(getUP1(x,y)) = (unsigned char)(hold >> 16L); \
220 	    *((unsigned short __FAR__ *)(getUP1(x,y) + 1)) \
221 	      = (unsigned short)hold;			   \
222 	}
223 # else
224 #  define setU3(x,y,z) \
225 	{   unsigned DPT_4_BYTES hold = z;			      \
226 	    *(getUP1(x,y) + 0) = (unsigned char)(hold >> 16) ; \
227 	    *(getUP1(x,y) + 1) = (unsigned char)(hold >> 8L);  \
228 	    *(getUP1(x,y) + 2) = (unsigned char)(hold);	       \
229 	}
230 # endif
231 #endif
232 /* up to here to be deleted */
233 
234 #define	getBU3(x,y)   ((unsigned DPT_4_BYTES)osdLocal3((unsigned DPT_4_BYTES __FAR__ *) \
235 				getUP1(x,y)))
236 #if (!defined(setBU3))
237 # if (defined(_DPT_BIG_ENDIAN))
238 #  define setBU3(x,y,z)					    \
239 	{   unsigned DPT_4_BYTES hold = z;			  \
240 	    *(getUP1(x,y)) = (unsigned char)(hold >> 16L); \
241 	    *((unsigned short __FAR__ *)(getUP1(x,y) + 1)) \
242 	      = (unsigned short)hold;			   \
243 	}
244 # else
245 #  define setBU3(x,y,z) \
246 	{   unsigned DPT_4_BYTES hold = z;			      \
247 	    *(getUP1(x,y) + 0) = (unsigned char)(hold >> 16) ; \
248 	    *(getUP1(x,y) + 1) = (unsigned char)(hold >> 8L);  \
249 	    *(getUP1(x,y) + 2) = (unsigned char)(hold);	       \
250 	}
251 # endif
252 #endif
253 #define	getUP4(x,y)  ((unsigned DPT_4_BYTES __FAR__ *)(((unsigned char __FAR__ *) \
254 				(x))+(unsigned DPT_4_BYTES)(y)))
255 #define	getBU4(x,y)   ((unsigned DPT_4_BYTES)osdLocal4((unsigned DPT_4_BYTES __FAR__ *)	  \
256 				getUP1(x,y)))
257 #define	getLU4(x,y)  ((unsigned DPT_4_BYTES)osdSLocal4((unsigned DPT_4_BYTES __FAR__ *)	 \
258 				getUP1(x,y)))
259 /* to be deleted */
260 #define	getU4(x,y)  ((unsigned DPT_4_BYTES)osdSLocal4((unsigned DPT_4_BYTES __FAR__ *)	\
261 				getUP1(x,y)))
262 #if (!defined(setU4))
263 # define setU4(x,y,z) { unsigned DPT_4_BYTES hold = z;		       \
264 			*((unsigned DPT_4_BYTES __FAR__ *)getUP1(x,y)) \
265 			  = osdLocal4(&hold);			\
266 		      }
267 #endif
268 /* up to here */
269 #if (!defined(setBU4))
270 # define setBU4(x,y,z) { unsigned DPT_4_BYTES hold = z;			\
271 			*((unsigned DPT_4_BYTES __FAR__ *)getUP1(x,y)) \
272 			  = osdLocal4(&hold);			\
273 		      }
274 #endif
275 #if (!defined(setLU4))
276 # define setLU4(x,y,z) { unsigned DPT_4_BYTES hold = z;			\
277 			 *((unsigned DPT_4_BYTES __FAR__ *)getUP1(x,y)) \
278 			   = osdSLocal4(&hold);			 \
279 		       }
280 #endif
281 
282 
283 #define	osdSwap16bit(x) ( (((unsigned short )x & 0xf000) >> 12) | \
284 			  (((unsigned short )x & 0x0f00) >> 4) | \
285 			  (((unsigned short )x & 0x00f0) << 4)	| \
286 			  (((unsigned short )x & 0x000f) << 12 )   )
287 
288 /*
289  * note that in big endian a 12 bit number (0x123) is stored as	  1203
290  */
291 
292 #define	osdSwap12bit(x) (( (((unsigned short )x & 0x0f00) >> 8) | \
293 			((unsigned short )x & 0x00f0)  | \
294 			(((unsigned short )x & 0x000f) << 8 )  ) )
295 
296 #define	osdSwap8bit(x)	( (((unsigned char )x & 0x0f) << 4) | \
297 			(((unsigned char )x &0xf0) >> 4 ) )
298 
299 #define	getL24bit1(w,x,y)   ((unsigned DPT_4_BYTES)((unsigned char __FAR__ *)(&w->x))[0+(y)] \
300 			+ ((((unsigned DPT_4_BYTES)((unsigned char __FAR__ *)(&w->x))[1+(y)]) << 8) & 0xFF00) \
301 			+ ((((unsigned DPT_4_BYTES)((unsigned char __FAR__ *)(&w->x))[2+(y)]) << 16) & 0xFF0000))
302 
303 #define	setL24bit1(w,x,y,z)  { ((unsigned char __FAR__ *)(&w->x))[0+(y)] = (z); \
304 			   ((unsigned char __FAR__ *)(&w->x))[1+(y)] = ((z) >> 8) & 0xFF; \
305 			   ((unsigned char __FAR__ *)(&w->x))[2+(y)] = ((z) >> 16) & 0xFF; \
306 			   }
307 
308 #define	getL16bit(w,x,y)   ((unsigned short)((unsigned char __FAR__ *)(&w->x))[0+(y)] \
309 			 + ((((unsigned short)((unsigned char __FAR__ *)(&w->x))[1+(y)]) << 8) & 0xFF00))
310 
311 #define	setL16bit(w,x,y,z)  { ((unsigned char __FAR__ *)(&w->x))[0+(y)] = (z); \
312 			   ((unsigned char __FAR__ *)(&w->x))[1+(y)] = ((z) >> 8) & 0xFF; \
313 			   }
314 
315 #define	getL16bit2(w,x,y)   ((unsigned short)((unsigned char __FAR__ *)(&w->x))[2+(y)] \
316 			 + ((((unsigned short)((unsigned char __FAR__ *)(&w->x))[3+(y)]) << 8) & 0xFF00))
317 
318 #define	setL16bit2(w,x,y,z)  { ((unsigned char __FAR__ *)(&w->x))[2+(y)] = (z); \
319 			   ((unsigned char __FAR__ *)(&w->x))[3+(y)] = ((z) >> 8) & 0xFF; \
320 			   }
321 
322 /* y is the number of bytes from beg of DPT_4_BYTES to get upper 4 bit of the addressed byte */
323 #define	getL4bit(w,x,y) \
324 	((unsigned char)(((unsigned char __FAR__ *)(&w->x))[0+(y)] >> 4) & 0x0f)
325 
326 #define	setL4bit(w,x,y,z) { \
327 			   ((unsigned char __FAR__ *)(&w->x))[0+(y)] &= 0xF0; \
328 				((unsigned char __FAR__ *)(&w->x))[0+(y)] |= ((z) << 4) & 0xF0; \
329 				}
330 /* y is number of bytes from beg of DPT_4_BYTES */
331 #define	getL1bit(w,x,y) \
332 	((unsigned char)(((unsigned char __FAR__ *)(&w->x))[0+(y)] ) & 0x01)
333 
334 #define	setL1bit(w,x,y,z) { \
335 			   ((unsigned char __FAR__ *)(&w->x))[0+(y)] &= 0xFE; \
336 				((unsigned char __FAR__ *)(&w->x))[0+(y)] |= (z) & 0x01; \
337 				}
338 #define	getL1bit1(w,x,y) \
339 	((unsigned char)(((unsigned char __FAR__ *)(&w->x))[0+(y)] >> 1) & 0x01)
340 
341 #define	setL1bit1(w,x,y,z) { \
342 			   ((unsigned char __FAR__ *)(&w->x))[0+(y)] &= 0xFD; \
343 				((unsigned char __FAR__ *)(&w->x))[0+(y)] |= (z << 1) & 0x02; \
344 				}
345 
346 
347 
348 /* 12 bit at the first 12 bits of a DPT_4_BYTES word */
349 #define	getL12bit(w,x,y)   ((unsigned short)((unsigned char __FAR__ *)(&w->x))[0+(y)] \
350 			 + ((((unsigned short)((unsigned char __FAR__ *)(&w->x))[1+(y)]) << 8) & 0xF00))
351 
352 #define	setL12bit(w,x,y,z) { ((unsigned char __FAR__ *)(&w->x))[0+(y)] = (z); \
353 			   ((unsigned char __FAR__ *)(&w->x))[1+(y)] &= 0xF0; \
354 			   ((unsigned char __FAR__ *)(&w->x))[1+(y)] |= ((z) >> 8) & 0xF; \
355 			   }
356 /* 12 bit after another 12 bit in DPT_4_BYTES word */
357 #define	getL12bit1(w,x,y)   (((unsigned short)((unsigned char __FAR__ *)(&w->x))[1+(y)]) >> 4 \
358 			 + ((((unsigned short)((unsigned char __FAR__ *)(&w->x))[2+(y)]) << 4) ))
359 
360 #define	setL12bit1(w,x,y,z) { ((unsigned char __FAR__ *)(&w->x))[1+(y)] &= 0x0F; \
361 			   ((unsigned char __FAR__ *)(&w->x))[1+(y)] |= ((z) & 0xF) << 4; \
362 			   ((unsigned char __FAR__ *)(&w->x))[2+(y)] &= 0x00;\
363 			   ((unsigned char __FAR__ *)(&w->x))[2+(y)] |= ((z) >> 8) & 0xff;\
364 			   }
365 
366 /* 12 at the 3rd byte in a DPT_4_BYTES word */
367 #define	getL12bit2(w,x,y)   ((unsigned short)((unsigned char __FAR__ *)(&w->x))[2+(y)] \
368 			 + ((((unsigned short)((unsigned char __FAR__ *)(&w->x))[3+(y)]) << 8) & 0xF00))
369 
370 #define	setL12bit2(w,x,y,z) { ((unsigned char __FAR__ *)(&w->x))[2+(y)] = (z); \
371 			   ((unsigned char __FAR__ *)(&w->x))[3+(y)] &= 0xF0; \
372 			   ((unsigned char __FAR__ *)(&w->x))[3+(y)] |= ((z) >> 8) & 0xF; \
373 			   }
374 
375 #define	getL8bit(w,x,y)	   (\
376 	(*(((unsigned char __FAR__ *)(&((w)->x)))\
377 		+ y)) )
378 
379 #define	setL8bit(w,x,y,z)  {\
380 	(*(((unsigned char __FAR__ *)(&((w)->x)))\
381 		+ y) = (z));\
382 	}
383 
384 
385 #endif /* __DPTALIGN_H */
386