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$
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