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