| Index: emcore/trunk/util.h | 
| — | — | @@ -1,227 +1,227 @@ | 
| 2 |  | -//
 | 
| 3 |  | -//
 | 
| 4 |  | -//    Copyright 2010 TheSeven
 | 
| 5 |  | -//
 | 
| 6 |  | -//
 | 
| 7 |  | -//    This file is part of emCORE.
 | 
| 8 |  | -//
 | 
| 9 |  | -//    emCORE is free software: you can redistribute it and/or
 | 
| 10 |  | -//    modify it under the terms of the GNU General Public License as
 | 
| 11 |  | -//    published by the Free Software Foundation, either version 2 of the
 | 
| 12 |  | -//    License, or (at your option) any later version.
 | 
| 13 |  | -//
 | 
| 14 |  | -//    emCORE is distributed in the hope that it will be useful,
 | 
| 15 |  | -//    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
| 16 |  | -//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | 
| 17 |  | -//    See the GNU General Public License for more details.
 | 
| 18 |  | -//
 | 
| 19 |  | -//    You should have received a copy of the GNU General Public License along
 | 
| 20 |  | -//    with emCORE.  If not, see <http://www.gnu.org/licenses/>.
 | 
| 21 |  | -//
 | 
| 22 |  | -//
 | 
| 23 |  | -
 | 
| 24 |  | -
 | 
| 25 |  | -#ifndef __UTIL_H__
 | 
| 26 |  | -#define __UTIL_H__
 | 
| 27 |  | -
 | 
| 28 |  | -
 | 
| 29 |  | -#include "global.h"
 | 
| 30 |  | -
 | 
| 31 |  | -
 | 
| 32 |  | -#ifndef NULL
 | 
| 33 |  | -#define NULL ((void*)0)
 | 
| 34 |  | -#endif
 | 
| 35 |  | -
 | 
| 36 |  | -#ifndef MIN
 | 
| 37 |  | -#define MIN(a, b) (((a)<(b))?(a):(b))
 | 
| 38 |  | -#endif
 | 
| 39 |  | -
 | 
| 40 |  | -#ifndef MAX
 | 
| 41 |  | -#define MAX(a, b) (((a)>(b))?(a):(b))
 | 
| 42 |  | -#endif
 | 
| 43 |  | -
 | 
| 44 |  | -/* return number of elements in array a */
 | 
| 45 |  | -#define ARRAYLEN(a) (sizeof(a)/sizeof((a)[0]))
 | 
| 46 |  | -
 | 
| 47 |  | -/* return p incremented by specified number of bytes */
 | 
| 48 |  | -#define SKIPBYTES(p, count) ((typeof (p))((char *)(p) + (count)))
 | 
| 49 |  | -
 | 
| 50 |  | -#define BIT(x) (1 << (x))
 | 
| 51 |  | -#define BITRANGE(x, y) ((0xfffffffful >> (31 + (x) - (y))) << (x))
 | 
| 52 |  | -
 | 
| 53 |  | -#define ERR_RC(val) (BIT(31) | (val))
 | 
| 54 |  | -#define IS_ERR(val) (val & BIT(31))
 | 
| 55 |  | -#define RET_ERR(val)                                           \
 | 
| 56 |  | -{                                                              \
 | 
| 57 |  | -    return ERR_RC(val);                                        \
 | 
| 58 |  | -}
 | 
| 59 |  | -#define RET_ERR_MTX(val, mutex)                                \
 | 
| 60 |  | -{                                                              \
 | 
| 61 |  | -    mutex_unlock(mutex);                                       \
 | 
| 62 |  | -    return ERR_RC(val);                                        \
 | 
| 63 |  | -}
 | 
| 64 |  | -#define PASS_RC(expr, bits, val)                               \
 | 
| 65 |  | -{                                                              \
 | 
| 66 |  | -    int PASS_RC_rc = (expr);                                   \
 | 
| 67 |  | -    if (IS_ERR(PASS_RC_rc))                                    \
 | 
| 68 |  | -        return ERR_RC((PASS_RC_rc << (bits)) | (val));         \
 | 
| 69 |  | -}
 | 
| 70 |  | -#define PASS_RC_MTX(expr, bits, val, mutex)                    \
 | 
| 71 |  | -{                                                              \
 | 
| 72 |  | -    int PASS_RC_MTX_rc = (expr);                               \
 | 
| 73 |  | -    if (IS_ERR(PASS_RC_MTX_rc))                                \
 | 
| 74 |  | -    {                                                          \
 | 
| 75 |  | -        mutex_unlock(mutex);                                   \
 | 
| 76 |  | -        return ERR_RC((PASS_RC_MTX_rc << (bits)) | (val));     \
 | 
| 77 |  | -    }                                                          \
 | 
| 78 |  | -}
 | 
| 79 |  | -
 | 
| 80 |  | -#define P2_M1(p2)  ((1 << (p2))-1)
 | 
| 81 |  | -
 | 
| 82 |  | -/* align up or down to nearest 2^p2 */
 | 
| 83 |  | -#define ALIGN_DOWN_P2(n, p2) ((n) & ~P2_M1(p2))
 | 
| 84 |  | -#define ALIGN_UP_P2(n, p2)   ALIGN_DOWN_P2((n) + P2_M1(p2),p2)
 | 
| 85 |  | -
 | 
| 86 |  | -/* align up or down to nearest integer multiple of a */
 | 
| 87 |  | -#define ALIGN_DOWN(n, a)     ((n)/(a)*(a))
 | 
| 88 |  | -#define ALIGN_UP(n, a)       ALIGN_DOWN((n)+((a)-1),a)
 | 
| 89 |  | -
 | 
| 90 |  | -/* align start and end of buffer to nearest integer multiple of a */
 | 
| 91 |  | -#define ALIGN_BUFFER(ptr,len,align) \
 | 
| 92 |  | -{\
 | 
| 93 |  | -    uintptr_t tmp_ptr1 = (uintptr_t)ptr; \
 | 
| 94 |  | -    uintptr_t tmp_ptr2 = tmp_ptr1 + len;\
 | 
| 95 |  | -    tmp_ptr1 = ALIGN_UP(tmp_ptr1,align); \
 | 
| 96 |  | -    tmp_ptr2 = ALIGN_DOWN(tmp_ptr2,align); \
 | 
| 97 |  | -    len = tmp_ptr2 - tmp_ptr1; \
 | 
| 98 |  | -    ptr = (typeof(ptr))tmp_ptr1; \
 | 
| 99 |  | -}
 | 
| 100 |  | -
 | 
| 101 |  | -
 | 
| 102 |  | -/* live endianness conversion */
 | 
| 103 |  | -#ifdef LITTLE_ENDIAN
 | 
| 104 |  | -#define letoh16(x) (x)
 | 
| 105 |  | -#define letoh32(x) (x)
 | 
| 106 |  | -#define htole16(x) (x)
 | 
| 107 |  | -#define htole32(x) (x)
 | 
| 108 |  | -#define betoh16(x) swap16(x)
 | 
| 109 |  | -#define betoh32(x) swap32(x)
 | 
| 110 |  | -#define htobe16(x) swap16(x)
 | 
| 111 |  | -#define htobe32(x) swap32(x)
 | 
| 112 |  | -#define swap_odd_even_be32(x) (x)
 | 
| 113 |  | -#define swap_odd_even_le32(x) swap_odd_even32(x)
 | 
| 114 |  | -#else
 | 
| 115 |  | -#define letoh16(x) swap16(x)
 | 
| 116 |  | -#define letoh32(x) swap32(x)
 | 
| 117 |  | -#define htole16(x) swap16(x)
 | 
| 118 |  | -#define htole32(x) swap32(x)
 | 
| 119 |  | -#define betoh16(x) (x)
 | 
| 120 |  | -#define betoh32(x) (x)
 | 
| 121 |  | -#define htobe16(x) (x)
 | 
| 122 |  | -#define htobe32(x) (x)
 | 
| 123 |  | -#define swap_odd_even_be32(x) swap_odd_even32(x)
 | 
| 124 |  | -#define swap_odd_even_le32(x) (x)
 | 
| 125 |  | -#endif
 | 
| 126 |  | -
 | 
| 127 |  | -
 | 
| 128 |  | -/* static endianness conversion */
 | 
| 129 |  | -#define SWAP_16(x) ((typeof(x))(unsigned short)(((unsigned short)(x) >> 8) | \
 | 
| 130 |  | -                                                ((unsigned short)(x) << 8)))
 | 
| 131 |  | -
 | 
| 132 |  | -#define SWAP_32(x) ((typeof(x))(unsigned long)( ((unsigned long)(x) >> 24) | \
 | 
| 133 |  | -                                               (((unsigned long)(x) & 0xff0000ul) >> 8) | \
 | 
| 134 |  | -                                               (((unsigned long)(x) & 0xff00ul) << 8) | \
 | 
| 135 |  | -                                                ((unsigned long)(x) << 24)))
 | 
| 136 |  | -
 | 
| 137 |  | -#ifdef RLITTLE_ENDIAN
 | 
| 138 |  | -#define LE_TO_H16(x) (x)
 | 
| 139 |  | -#define LE_TO_H32(x) (x)
 | 
| 140 |  | -#define H_TO_LE16(x) (x)
 | 
| 141 |  | -#define H_TO_LE32(x) (x)
 | 
| 142 |  | -#define BE_TO_H16(x) SWAP_16(x)
 | 
| 143 |  | -#define BE_TO_H32(x) SWAP_32(x)
 | 
| 144 |  | -#define H_TO_BE16(x) SWAP_16(x)
 | 
| 145 |  | -#define H_TO_BE32(x) SWAP_32(x)
 | 
| 146 |  | -#else
 | 
| 147 |  | -#define LE_TO_H16(x) SWAP_16(x)
 | 
| 148 |  | -#define LE_TO_H32(x) SWAP_32(x)
 | 
| 149 |  | -#define H_TO_LE16(x) SWAP_16(x)
 | 
| 150 |  | -#define H_TO_LE32(x) SWAP_32(x)
 | 
| 151 |  | -#define BE_TO_H16(x) (x)
 | 
| 152 |  | -#define BE_TO_H32(x) (x)
 | 
| 153 |  | -#define H_TO_BE16(x) (x)
 | 
| 154 |  | -#define H_TO_BE32(x) (x)
 | 
| 155 |  | -#endif
 | 
| 156 |  | -
 | 
| 157 |  | -/* Get the byte offset of a type's member */
 | 
| 158 |  | -#define OFFSETOF(type, membername) ((off_t)&((type *)0)->membername)
 | 
| 159 |  | -
 | 
| 160 |  | -/* Get the type pointer from one of its members */
 | 
| 161 |  | -#define TYPE_FROM_MEMBER(type, memberptr, membername) \
 | 
| 162 |  | -    ((type *)((intptr_t)(memberptr) - OFFSETOF(type, membername)))
 | 
| 163 |  | -
 | 
| 164 |  | -static inline uint16_t swap16(uint16_t value)
 | 
| 165 |  | -    /*
 | 
| 166 |  | -      result[15..8] = value[ 7..0];
 | 
| 167 |  | -      result[ 7..0] = value[15..8];
 | 
| 168 |  | -    */
 | 
| 169 |  | -{
 | 
| 170 |  | -    return (value >> 8) | (value << 8);
 | 
| 171 |  | -}
 | 
| 172 |  | -
 | 
| 173 |  | -static inline uint32_t swap32(uint32_t value)
 | 
| 174 |  | -    /*
 | 
| 175 |  | -      result[31..24] = value[ 7.. 0];
 | 
| 176 |  | -      result[23..16] = value[15.. 8];
 | 
| 177 |  | -      result[15.. 8] = value[23..16];
 | 
| 178 |  | -      result[ 7.. 0] = value[31..24];
 | 
| 179 |  | -    */
 | 
| 180 |  | -{
 | 
| 181 |  | -    uint32_t hi = swap16(value >> 16);
 | 
| 182 |  | -    uint32_t lo = swap16(value & 0xffff);
 | 
| 183 |  | -    return (lo << 16) | hi;
 | 
| 184 |  | -}
 | 
| 185 |  | -
 | 
| 186 |  | -static inline uint32_t swap_odd_even32(uint32_t value)
 | 
| 187 |  | -{
 | 
| 188 |  | -    /*
 | 
| 189 |  | -      result[31..24],[15.. 8] = value[23..16],[ 7.. 0]
 | 
| 190 |  | -      result[23..16],[ 7.. 0] = value[31..24],[15.. 8]
 | 
| 191 |  | -    */
 | 
| 192 |  | -    uint32_t t = value & 0xff00ff00;
 | 
| 193 |  | -    return (t >> 8) | ((t ^ value) << 8);
 | 
| 194 |  | -}
 | 
| 195 |  | -
 | 
| 196 |  | -#ifndef BIT_N
 | 
| 197 |  | -#define BIT_N(n) (1U << (n))
 | 
| 198 |  | -#endif
 | 
| 199 |  | -
 | 
| 200 |  | -#ifndef CACHEALIGN_SIZE /* could be elsewhere for a particular reason */
 | 
| 201 |  | -#ifdef CACHEALIGN_BITS
 | 
| 202 |  | -/* 2^CACHEALIGN_BITS = the byte size */
 | 
| 203 |  | -#define CACHEALIGN_SIZE (1u << CACHEALIGN_BITS)
 | 
| 204 |  | -#else
 | 
| 205 |  | -#define CACHEALIGN_SIZE 16  /* FIXME */
 | 
| 206 |  | -#endif
 | 
| 207 |  | -#endif /* CACHEALIGN_SIZE */
 | 
| 208 |  | -
 | 
| 209 |  | -#define CACHEALIGN_ATTR __attribute__((aligned(CACHEALIGN_SIZE)))
 | 
| 210 |  | -/* Aligns x up to a CACHEALIGN_SIZE boundary */
 | 
| 211 |  | -#define CACHEALIGN_UP(x) \
 | 
| 212 |  | -    ((typeof (x))ALIGN_UP_P2((uintptr_t)(x), CACHEALIGN_BITS))
 | 
| 213 |  | -/* Aligns x down to a CACHEALIGN_SIZE boundary */
 | 
| 214 |  | -#define CACHEALIGN_DOWN(x) \
 | 
| 215 |  | -    ((typeof (x))ALIGN_DOWN_P2((uintptr_t)(x), CACHEALIGN_BITS))
 | 
| 216 |  | -/* Aligns at least to the greater of size x or CACHEALIGN_SIZE */
 | 
| 217 |  | -#define CACHEALIGN_AT_LEAST_ATTR(x) \
 | 
| 218 |  | -    __attribute__((aligned(CACHEALIGN_UP(x))))
 | 
| 219 |  | -/* Aligns a buffer pointer and size to proper boundaries */
 | 
| 220 |  | -#define CACHEALIGN_BUFFER(start, size) \
 | 
| 221 |  | -    ALIGN_BUFFER((start), (size), CACHEALIGN_SIZE)
 | 
| 222 |  | -
 | 
| 223 |  | -/* Double-cast to avoid 'dereferencing type-punned pointer will
 | 
| 224 |  | - * break strict aliasing rules' B.S. */
 | 
| 225 |  | -#define PUN_PTR(type, p) ((type)(intptr_t)(p))
 | 
| 226 |  | -
 | 
| 227 |  | -
 | 
| 228 |  | -#endif
 | 
|  | 2 | +// | 
|  | 3 | +// | 
|  | 4 | +//    Copyright 2010 TheSeven | 
|  | 5 | +// | 
|  | 6 | +// | 
|  | 7 | +//    This file is part of emCORE. | 
|  | 8 | +// | 
|  | 9 | +//    emCORE is free software: you can redistribute it and/or | 
|  | 10 | +//    modify it under the terms of the GNU General Public License as | 
|  | 11 | +//    published by the Free Software Foundation, either version 2 of the | 
|  | 12 | +//    License, or (at your option) any later version. | 
|  | 13 | +// | 
|  | 14 | +//    emCORE is distributed in the hope that it will be useful, | 
|  | 15 | +//    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 16 | +//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 
|  | 17 | +//    See the GNU General Public License for more details. | 
|  | 18 | +// | 
|  | 19 | +//    You should have received a copy of the GNU General Public License along | 
|  | 20 | +//    with emCORE.  If not, see <http://www.gnu.org/licenses/>. | 
|  | 21 | +// | 
|  | 22 | +// | 
|  | 23 | + | 
|  | 24 | + | 
|  | 25 | +#ifndef __UTIL_H__ | 
|  | 26 | +#define __UTIL_H__ | 
|  | 27 | + | 
|  | 28 | + | 
|  | 29 | +#include "global.h" | 
|  | 30 | + | 
|  | 31 | + | 
|  | 32 | +#ifndef NULL | 
|  | 33 | +#define NULL ((void*)0) | 
|  | 34 | +#endif | 
|  | 35 | + | 
|  | 36 | +#ifndef MIN | 
|  | 37 | +#define MIN(a, b) (((a)<(b))?(a):(b)) | 
|  | 38 | +#endif | 
|  | 39 | + | 
|  | 40 | +#ifndef MAX | 
|  | 41 | +#define MAX(a, b) (((a)>(b))?(a):(b)) | 
|  | 42 | +#endif | 
|  | 43 | + | 
|  | 44 | +/* return number of elements in array a */ | 
|  | 45 | +#define ARRAYLEN(a) (sizeof(a)/sizeof((a)[0])) | 
|  | 46 | + | 
|  | 47 | +/* return p incremented by specified number of bytes */ | 
|  | 48 | +#define SKIPBYTES(p, count) ((typeof (p))((char *)(p) + (count))) | 
|  | 49 | + | 
|  | 50 | +#define BIT(x) (1 << (x)) | 
|  | 51 | +#define BITRANGE(x, y) ((0xfffffffful >> (31 + (x) - (y))) << (x)) | 
|  | 52 | + | 
|  | 53 | +#define ERR_RC(val) (BIT(31) | (val)) | 
|  | 54 | +#define IS_ERR(val) (val & BIT(31)) | 
|  | 55 | +#define RET_ERR(val)                                           \ | 
|  | 56 | +{                                                              \ | 
|  | 57 | +    return ERR_RC(val);                                        \ | 
|  | 58 | +} | 
|  | 59 | +#define RET_ERR_MTX(val, mutex)                                \ | 
|  | 60 | +{                                                              \ | 
|  | 61 | +    mutex_unlock(mutex);                                       \ | 
|  | 62 | +    return ERR_RC(val);                                        \ | 
|  | 63 | +} | 
|  | 64 | +#define PASS_RC(expr, bits, val)                               \ | 
|  | 65 | +{                                                              \ | 
|  | 66 | +    int PASS_RC_rc = (expr);                                   \ | 
|  | 67 | +    if (IS_ERR(PASS_RC_rc))                                    \ | 
|  | 68 | +        return ERR_RC((PASS_RC_rc << (bits)) | (val));         \ | 
|  | 69 | +} | 
|  | 70 | +#define PASS_RC_MTX(expr, bits, val, mutex)                    \ | 
|  | 71 | +{                                                              \ | 
|  | 72 | +    int PASS_RC_MTX_rc = (expr);                               \ | 
|  | 73 | +    if (IS_ERR(PASS_RC_MTX_rc))                                \ | 
|  | 74 | +    {                                                          \ | 
|  | 75 | +        mutex_unlock(mutex);                                   \ | 
|  | 76 | +        return ERR_RC((PASS_RC_MTX_rc << (bits)) | (val));     \ | 
|  | 77 | +    }                                                          \ | 
|  | 78 | +} | 
|  | 79 | + | 
|  | 80 | +#define P2_M1(p2)  ((1 << (p2))-1) | 
|  | 81 | + | 
|  | 82 | +/* align up or down to nearest 2^p2 */ | 
|  | 83 | +#define ALIGN_DOWN_P2(n, p2) ((n) & ~P2_M1(p2)) | 
|  | 84 | +#define ALIGN_UP_P2(n, p2)   ALIGN_DOWN_P2((n) + P2_M1(p2),p2) | 
|  | 85 | + | 
|  | 86 | +/* align up or down to nearest integer multiple of a */ | 
|  | 87 | +#define ALIGN_DOWN(n, a)     ((n)/(a)*(a)) | 
|  | 88 | +#define ALIGN_UP(n, a)       ALIGN_DOWN((n)+((a)-1),a) | 
|  | 89 | + | 
|  | 90 | +/* align start and end of buffer to nearest integer multiple of a */ | 
|  | 91 | +#define ALIGN_BUFFER(ptr,len,align) \ | 
|  | 92 | +{\ | 
|  | 93 | +    uintptr_t tmp_ptr1 = (uintptr_t)ptr; \ | 
|  | 94 | +    uintptr_t tmp_ptr2 = tmp_ptr1 + len;\ | 
|  | 95 | +    tmp_ptr1 = ALIGN_UP(tmp_ptr1,align); \ | 
|  | 96 | +    tmp_ptr2 = ALIGN_DOWN(tmp_ptr2,align); \ | 
|  | 97 | +    len = tmp_ptr2 - tmp_ptr1; \ | 
|  | 98 | +    ptr = (typeof(ptr))tmp_ptr1; \ | 
|  | 99 | +} | 
|  | 100 | + | 
|  | 101 | + | 
|  | 102 | +/* live endianness conversion */ | 
|  | 103 | +#ifdef LITTLE_ENDIAN | 
|  | 104 | +#define letoh16(x) (x) | 
|  | 105 | +#define letoh32(x) (x) | 
|  | 106 | +#define htole16(x) (x) | 
|  | 107 | +#define htole32(x) (x) | 
|  | 108 | +#define betoh16(x) swap16(x) | 
|  | 109 | +#define betoh32(x) swap32(x) | 
|  | 110 | +#define htobe16(x) swap16(x) | 
|  | 111 | +#define htobe32(x) swap32(x) | 
|  | 112 | +#define swap_odd_even_be32(x) (x) | 
|  | 113 | +#define swap_odd_even_le32(x) swap_odd_even32(x) | 
|  | 114 | +#else | 
|  | 115 | +#define letoh16(x) swap16(x) | 
|  | 116 | +#define letoh32(x) swap32(x) | 
|  | 117 | +#define htole16(x) swap16(x) | 
|  | 118 | +#define htole32(x) swap32(x) | 
|  | 119 | +#define betoh16(x) (x) | 
|  | 120 | +#define betoh32(x) (x) | 
|  | 121 | +#define htobe16(x) (x) | 
|  | 122 | +#define htobe32(x) (x) | 
|  | 123 | +#define swap_odd_even_be32(x) swap_odd_even32(x) | 
|  | 124 | +#define swap_odd_even_le32(x) (x) | 
|  | 125 | +#endif | 
|  | 126 | + | 
|  | 127 | + | 
|  | 128 | +/* static endianness conversion */ | 
|  | 129 | +#define SWAP_16(x) ((typeof(x))(unsigned short)(((unsigned short)(x) >> 8) | \ | 
|  | 130 | +                                                ((unsigned short)(x) << 8))) | 
|  | 131 | + | 
|  | 132 | +#define SWAP_32(x) ((typeof(x))(unsigned long)( ((unsigned long)(x) >> 24) | \ | 
|  | 133 | +                                               (((unsigned long)(x) & 0xff0000ul) >> 8) | \ | 
|  | 134 | +                                               (((unsigned long)(x) & 0xff00ul) << 8) | \ | 
|  | 135 | +                                                ((unsigned long)(x) << 24))) | 
|  | 136 | + | 
|  | 137 | +#ifdef RLITTLE_ENDIAN | 
|  | 138 | +#define LE_TO_H16(x) (x) | 
|  | 139 | +#define LE_TO_H32(x) (x) | 
|  | 140 | +#define H_TO_LE16(x) (x) | 
|  | 141 | +#define H_TO_LE32(x) (x) | 
|  | 142 | +#define BE_TO_H16(x) SWAP_16(x) | 
|  | 143 | +#define BE_TO_H32(x) SWAP_32(x) | 
|  | 144 | +#define H_TO_BE16(x) SWAP_16(x) | 
|  | 145 | +#define H_TO_BE32(x) SWAP_32(x) | 
|  | 146 | +#else | 
|  | 147 | +#define LE_TO_H16(x) SWAP_16(x) | 
|  | 148 | +#define LE_TO_H32(x) SWAP_32(x) | 
|  | 149 | +#define H_TO_LE16(x) SWAP_16(x) | 
|  | 150 | +#define H_TO_LE32(x) SWAP_32(x) | 
|  | 151 | +#define BE_TO_H16(x) (x) | 
|  | 152 | +#define BE_TO_H32(x) (x) | 
|  | 153 | +#define H_TO_BE16(x) (x) | 
|  | 154 | +#define H_TO_BE32(x) (x) | 
|  | 155 | +#endif | 
|  | 156 | + | 
|  | 157 | +/* Get the byte offset of a type's member */ | 
|  | 158 | +#define OFFSETOF(type, membername) ((off_t)&((type *)0)->membername) | 
|  | 159 | + | 
|  | 160 | +/* Get the type pointer from one of its members */ | 
|  | 161 | +#define TYPE_FROM_MEMBER(type, memberptr, membername) \ | 
|  | 162 | +    ((type *)((intptr_t)(memberptr) - OFFSETOF(type, membername))) | 
|  | 163 | + | 
|  | 164 | +static inline uint16_t swap16(uint16_t value) | 
|  | 165 | +    /* | 
|  | 166 | +      result[15..8] = value[ 7..0]; | 
|  | 167 | +      result[ 7..0] = value[15..8]; | 
|  | 168 | +    */ | 
|  | 169 | +{ | 
|  | 170 | +    return (value >> 8) | (value << 8); | 
|  | 171 | +} | 
|  | 172 | + | 
|  | 173 | +static inline uint32_t swap32(uint32_t value) | 
|  | 174 | +    /* | 
|  | 175 | +      result[31..24] = value[ 7.. 0]; | 
|  | 176 | +      result[23..16] = value[15.. 8]; | 
|  | 177 | +      result[15.. 8] = value[23..16]; | 
|  | 178 | +      result[ 7.. 0] = value[31..24]; | 
|  | 179 | +    */ | 
|  | 180 | +{ | 
|  | 181 | +    uint32_t hi = swap16(value >> 16); | 
|  | 182 | +    uint32_t lo = swap16(value & 0xffff); | 
|  | 183 | +    return (lo << 16) | hi; | 
|  | 184 | +} | 
|  | 185 | + | 
|  | 186 | +static inline uint32_t swap_odd_even32(uint32_t value) | 
|  | 187 | +{ | 
|  | 188 | +    /* | 
|  | 189 | +      result[31..24],[15.. 8] = value[23..16],[ 7.. 0] | 
|  | 190 | +      result[23..16],[ 7.. 0] = value[31..24],[15.. 8] | 
|  | 191 | +    */ | 
|  | 192 | +    uint32_t t = value & 0xff00ff00; | 
|  | 193 | +    return (t >> 8) | ((t ^ value) << 8); | 
|  | 194 | +} | 
|  | 195 | + | 
|  | 196 | +#ifndef BIT_N | 
|  | 197 | +#define BIT_N(n) (1U << (n)) | 
|  | 198 | +#endif | 
|  | 199 | + | 
|  | 200 | +#ifndef CACHEALIGN_SIZE /* could be elsewhere for a particular reason */ | 
|  | 201 | +#ifdef CACHEALIGN_BITS | 
|  | 202 | +/* 2^CACHEALIGN_BITS = the byte size */ | 
|  | 203 | +#define CACHEALIGN_SIZE (1u << CACHEALIGN_BITS) | 
|  | 204 | +#else | 
|  | 205 | +#define CACHEALIGN_SIZE 16  /* FIXME */ | 
|  | 206 | +#endif | 
|  | 207 | +#endif /* CACHEALIGN_SIZE */ | 
|  | 208 | + | 
|  | 209 | +#define CACHEALIGN_ATTR __attribute__((aligned(CACHEALIGN_SIZE))) | 
|  | 210 | +/* Aligns x up to a CACHEALIGN_SIZE boundary */ | 
|  | 211 | +#define CACHEALIGN_UP(x) \ | 
|  | 212 | +    ((typeof (x))ALIGN_UP_P2((uintptr_t)(x), CACHEALIGN_BITS)) | 
|  | 213 | +/* Aligns x down to a CACHEALIGN_SIZE boundary */ | 
|  | 214 | +#define CACHEALIGN_DOWN(x) \ | 
|  | 215 | +    ((typeof (x))ALIGN_DOWN_P2((uintptr_t)(x), CACHEALIGN_BITS)) | 
|  | 216 | +/* Aligns at least to the greater of size x or CACHEALIGN_SIZE */ | 
|  | 217 | +#define CACHEALIGN_AT_LEAST_ATTR(x) \ | 
|  | 218 | +    __attribute__((aligned(CACHEALIGN_UP(x)))) | 
|  | 219 | +/* Aligns a buffer pointer and size to proper boundaries */ | 
|  | 220 | +#define CACHEALIGN_BUFFER(start, size) \ | 
|  | 221 | +    ALIGN_BUFFER((start), (size), CACHEALIGN_SIZE) | 
|  | 222 | + | 
|  | 223 | +/* Double-cast to avoid 'dereferencing type-punned pointer will | 
|  | 224 | + * break strict aliasing rules' B.S. */ | 
|  | 225 | +#define PUN_PTR(type, p) ((type)(intptr_t)(p)) | 
|  | 226 | + | 
|  | 227 | + | 
|  | 228 | +#endif | 
| Index: emcore/trunk/target/ipodclassic/storage_ata.c | 
| — | — | @@ -977,24 +977,24 @@ | 
| 978 | 978 |  | 
| 979 | 979 | void ata_sleep(void) | 
| 980 | 980 | { | 
| 981 |  | -    mutex_lock(&ata_mutex, TIMEOUT_BLOCK); | 
| 982 |  | -    ata_power_down(); | 
| 983 |  | -    mutex_unlock(&ata_mutex); | 
|  | 981 | +    ata_last_activity_value = USEC_TIMER - ata_sleep_timeout + 200000; | 
| 984 | 982 | } | 
| 985 | 983 |  | 
| 986 | 984 | void ata_sleepnow(void) | 
| 987 | 985 | { | 
| 988 |  | -    ata_sleep(); | 
|  | 986 | +    mutex_lock(&ata_mutex, TIMEOUT_BLOCK); | 
|  | 987 | +    ata_power_down(); | 
|  | 988 | +    mutex_unlock(&ata_mutex); | 
| 989 | 989 | } | 
| 990 | 990 |  | 
| 991 | 991 | void ata_close(void) | 
| 992 | 992 | { | 
| 993 |  | -    ata_sleep(); | 
|  | 993 | +    ata_sleepnow(); | 
| 994 | 994 | } | 
| 995 | 995 |  | 
| 996 | 996 | void ata_spin(void) | 
| 997 | 997 | { | 
| 998 |  | -    ata_power_up(); | 
|  | 998 | +    ata_set_active(); | 
| 999 | 999 | } | 
| 1000 | 1000 |  | 
| 1001 | 1001 | void ata_get_info(IF_MD2(int drive,) struct storage_info *info) | 
| Index: emcore/trunk/timer.h | 
| — | — | @@ -1,54 +1,54 @@ | 
| 2 |  | -//
 | 
| 3 |  | -//
 | 
| 4 |  | -//    Copyright 2010 TheSeven
 | 
| 5 |  | -//
 | 
| 6 |  | -//
 | 
| 7 |  | -//    This file is part of emCORE.
 | 
| 8 |  | -//
 | 
| 9 |  | -//    emCORE is free software: you can redistribute it and/or
 | 
| 10 |  | -//    modify it under the terms of the GNU General Public License as
 | 
| 11 |  | -//    published by the Free Software Foundation, either version 2 of the
 | 
| 12 |  | -//    License, or (at your option) any later version.
 | 
| 13 |  | -//
 | 
| 14 |  | -//    emCORE is distributed in the hope that it will be useful,
 | 
| 15 |  | -//    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
| 16 |  | -//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | 
| 17 |  | -//    See the GNU General Public License for more details.
 | 
| 18 |  | -//
 | 
| 19 |  | -//    You should have received a copy of the GNU General Public License along
 | 
| 20 |  | -//    with emCORE.  If not, see <http://www.gnu.org/licenses/>.
 | 
| 21 |  | -//
 | 
| 22 |  | -//
 | 
| 23 |  | -
 | 
| 24 |  | -
 | 
| 25 |  | -#ifndef __TIMER_H__
 | 
| 26 |  | -#define __TIMER_H__
 | 
| 27 |  | -
 | 
| 28 |  | -#include "global.h"
 | 
| 29 |  | -
 | 
| 30 |  | -
 | 
| 31 |  | -#define TIME_AFTER(a,b)         ((long)(b) - (long)(a) < 0)
 | 
| 32 |  | -#define TIME_BEFORE(a,b)        TIME_AFTER(b,a)
 | 
| 33 |  | -#define TIMEOUT_EXPIRED(a,b)    TIME_AFTER(USEC_TIMER,a + b)
 | 
| 34 |  | -
 | 
| 35 |  | -
 | 
| 36 |  | -uint64_t read_native_timer();
 | 
| 37 |  | -#define NATIVE_TIMER (read_native_timer())
 | 
| 38 |  | -uint32_t read_usec_timer();
 | 
| 39 |  | -#define USEC_TIMER (read_usec_timer())
 | 
| 40 |  | -
 | 
| 41 |  | -
 | 
| 42 |  | -#define udelay(duration)                                   \
 | 
| 43 |  | -{                                                          \
 | 
| 44 |  | -    long timestamp = USEC_TIMER;                           \
 | 
| 45 |  | -    while (!TIMEOUT_EXPIRED(timestamp, (long)(duration))); \
 | 
| 46 |  | -}
 | 
| 47 |  | -
 | 
| 48 |  | -
 | 
| 49 |  | -void timer_init() INITCODE_ATTR;
 | 
| 50 |  | -void timer_schedule_wakeup(uint32_t usecs) ICODE_ATTR;
 | 
| 51 |  | -void timer_kill_wakeup() ICODE_ATTR;
 | 
| 52 |  | -void INT_TIMERB() ICODE_ATTR;
 | 
| 53 |  | -
 | 
| 54 |  | -
 | 
| 55 |  | -#endif
 | 
|  | 2 | +// | 
|  | 3 | +// | 
|  | 4 | +//    Copyright 2010 TheSeven | 
|  | 5 | +// | 
|  | 6 | +// | 
|  | 7 | +//    This file is part of emCORE. | 
|  | 8 | +// | 
|  | 9 | +//    emCORE is free software: you can redistribute it and/or | 
|  | 10 | +//    modify it under the terms of the GNU General Public License as | 
|  | 11 | +//    published by the Free Software Foundation, either version 2 of the | 
|  | 12 | +//    License, or (at your option) any later version. | 
|  | 13 | +// | 
|  | 14 | +//    emCORE is distributed in the hope that it will be useful, | 
|  | 15 | +//    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 16 | +//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 
|  | 17 | +//    See the GNU General Public License for more details. | 
|  | 18 | +// | 
|  | 19 | +//    You should have received a copy of the GNU General Public License along | 
|  | 20 | +//    with emCORE.  If not, see <http://www.gnu.org/licenses/>. | 
|  | 21 | +// | 
|  | 22 | +// | 
|  | 23 | + | 
|  | 24 | + | 
|  | 25 | +#ifndef __TIMER_H__ | 
|  | 26 | +#define __TIMER_H__ | 
|  | 27 | + | 
|  | 28 | +#include "global.h" | 
|  | 29 | + | 
|  | 30 | + | 
|  | 31 | +#define TIME_AFTER(a,b)         ((long)(b) - (long)(a) < 0) | 
|  | 32 | +#define TIME_BEFORE(a,b)        TIME_AFTER(b,a) | 
|  | 33 | +#define TIMEOUT_EXPIRED(a,b)    TIME_AFTER(USEC_TIMER,a + b) | 
|  | 34 | + | 
|  | 35 | + | 
|  | 36 | +uint64_t read_native_timer(); | 
|  | 37 | +#define NATIVE_TIMER (read_native_timer()) | 
|  | 38 | +uint32_t read_usec_timer(); | 
|  | 39 | +#define USEC_TIMER (read_usec_timer()) | 
|  | 40 | + | 
|  | 41 | + | 
|  | 42 | +#define udelay(duration)                                   \ | 
|  | 43 | +{                                                          \ | 
|  | 44 | +    long timestamp = USEC_TIMER;                           \ | 
|  | 45 | +    while (!TIMEOUT_EXPIRED(timestamp, (long)(duration))); \ | 
|  | 46 | +} | 
|  | 47 | + | 
|  | 48 | + | 
|  | 49 | +void timer_init() INITCODE_ATTR; | 
|  | 50 | +void timer_schedule_wakeup(uint32_t usecs) ICODE_ATTR; | 
|  | 51 | +void timer_kill_wakeup() ICODE_ATTR; | 
|  | 52 | +void INT_TIMERB() ICODE_ATTR; | 
|  | 53 | + | 
|  | 54 | + | 
|  | 55 | +#endif |