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