diff options
Diffstat (limited to 'lib/bitmap.c')
-rw-r--r-- | lib/bitmap.c | 137 |
1 files changed, 53 insertions, 84 deletions
diff --git a/lib/bitmap.c b/lib/bitmap.c index d8f0c094b18e..9e498c77ed0e 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c | |||
@@ -1106,111 +1106,80 @@ int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order) | |||
1106 | EXPORT_SYMBOL(bitmap_allocate_region); | 1106 | EXPORT_SYMBOL(bitmap_allocate_region); |
1107 | 1107 | ||
1108 | /** | 1108 | /** |
1109 | * bitmap_from_u32array - copy the contents of a u32 array of bits to bitmap | 1109 | * bitmap_copy_le - copy a bitmap, putting the bits into little-endian order. |
1110 | * @bitmap: array of unsigned longs, the destination bitmap, non NULL | 1110 | * @dst: destination buffer |
1111 | * @nbits: number of bits in @bitmap | 1111 | * @src: bitmap to copy |
1112 | * @buf: array of u32 (in host byte order), the source bitmap, non NULL | 1112 | * @nbits: number of bits in the bitmap |
1113 | * @nwords: number of u32 words in @buf | ||
1114 | * | ||
1115 | * copy min(nbits, 32*nwords) bits from @buf to @bitmap, remaining | ||
1116 | * bits between nword and nbits in @bitmap (if any) are cleared. In | ||
1117 | * last word of @bitmap, the bits beyond nbits (if any) are kept | ||
1118 | * unchanged. | ||
1119 | * | 1113 | * |
1120 | * Return the number of bits effectively copied. | 1114 | * Require nbits % BITS_PER_LONG == 0. |
1121 | */ | 1115 | */ |
1122 | unsigned int | 1116 | #ifdef __BIG_ENDIAN |
1123 | bitmap_from_u32array(unsigned long *bitmap, unsigned int nbits, | 1117 | void bitmap_copy_le(unsigned long *dst, const unsigned long *src, unsigned int nbits) |
1124 | const u32 *buf, unsigned int nwords) | ||
1125 | { | 1118 | { |
1126 | unsigned int dst_idx, src_idx; | 1119 | unsigned int i; |
1127 | |||
1128 | for (src_idx = dst_idx = 0; dst_idx < BITS_TO_LONGS(nbits); ++dst_idx) { | ||
1129 | unsigned long part = 0; | ||
1130 | |||
1131 | if (src_idx < nwords) | ||
1132 | part = buf[src_idx++]; | ||
1133 | |||
1134 | #if BITS_PER_LONG == 64 | ||
1135 | if (src_idx < nwords) | ||
1136 | part |= ((unsigned long) buf[src_idx++]) << 32; | ||
1137 | #endif | ||
1138 | |||
1139 | if (dst_idx < nbits/BITS_PER_LONG) | ||
1140 | bitmap[dst_idx] = part; | ||
1141 | else { | ||
1142 | unsigned long mask = BITMAP_LAST_WORD_MASK(nbits); | ||
1143 | 1120 | ||
1144 | bitmap[dst_idx] = (bitmap[dst_idx] & ~mask) | 1121 | for (i = 0; i < nbits/BITS_PER_LONG; i++) { |
1145 | | (part & mask); | 1122 | if (BITS_PER_LONG == 64) |
1146 | } | 1123 | dst[i] = cpu_to_le64(src[i]); |
1124 | else | ||
1125 | dst[i] = cpu_to_le32(src[i]); | ||
1147 | } | 1126 | } |
1148 | |||
1149 | return min_t(unsigned int, nbits, 32*nwords); | ||
1150 | } | 1127 | } |
1151 | EXPORT_SYMBOL(bitmap_from_u32array); | 1128 | EXPORT_SYMBOL(bitmap_copy_le); |
1129 | #endif | ||
1152 | 1130 | ||
1131 | #if BITS_PER_LONG == 64 | ||
1153 | /** | 1132 | /** |
1154 | * bitmap_to_u32array - copy the contents of bitmap to a u32 array of bits | 1133 | * bitmap_from_arr32 - copy the contents of u32 array of bits to bitmap |
1155 | * @buf: array of u32 (in host byte order), the dest bitmap, non NULL | 1134 | * @bitmap: array of unsigned longs, the destination bitmap |
1156 | * @nwords: number of u32 words in @buf | 1135 | * @buf: array of u32 (in host byte order), the source bitmap |
1157 | * @bitmap: array of unsigned longs, the source bitmap, non NULL | ||
1158 | * @nbits: number of bits in @bitmap | 1136 | * @nbits: number of bits in @bitmap |
1159 | * | ||
1160 | * copy min(nbits, 32*nwords) bits from @bitmap to @buf. Remaining | ||
1161 | * bits after nbits in @buf (if any) are cleared. | ||
1162 | * | ||
1163 | * Return the number of bits effectively copied. | ||
1164 | */ | 1137 | */ |
1165 | unsigned int | 1138 | void bitmap_from_arr32(unsigned long *bitmap, const u32 *buf, |
1166 | bitmap_to_u32array(u32 *buf, unsigned int nwords, | 1139 | unsigned int nbits) |
1167 | const unsigned long *bitmap, unsigned int nbits) | ||
1168 | { | 1140 | { |
1169 | unsigned int dst_idx = 0, src_idx = 0; | 1141 | unsigned int i, halfwords; |
1170 | |||
1171 | while (dst_idx < nwords) { | ||
1172 | unsigned long part = 0; | ||
1173 | |||
1174 | if (src_idx < BITS_TO_LONGS(nbits)) { | ||
1175 | part = bitmap[src_idx]; | ||
1176 | if (src_idx >= nbits/BITS_PER_LONG) | ||
1177 | part &= BITMAP_LAST_WORD_MASK(nbits); | ||
1178 | src_idx++; | ||
1179 | } | ||
1180 | 1142 | ||
1181 | buf[dst_idx++] = part & 0xffffffffUL; | 1143 | if (!nbits) |
1144 | return; | ||
1182 | 1145 | ||
1183 | #if BITS_PER_LONG == 64 | 1146 | halfwords = DIV_ROUND_UP(nbits, 32); |
1184 | if (dst_idx < nwords) { | 1147 | for (i = 0; i < halfwords; i++) { |
1185 | part >>= 32; | 1148 | bitmap[i/2] = (unsigned long) buf[i]; |
1186 | buf[dst_idx++] = part & 0xffffffffUL; | 1149 | if (++i < halfwords) |
1187 | } | 1150 | bitmap[i/2] |= ((unsigned long) buf[i]) << 32; |
1188 | #endif | ||
1189 | } | 1151 | } |
1190 | 1152 | ||
1191 | return min_t(unsigned int, nbits, 32*nwords); | 1153 | /* Clear tail bits in last word beyond nbits. */ |
1154 | if (nbits % BITS_PER_LONG) | ||
1155 | bitmap[(halfwords - 1) / 2] &= BITMAP_LAST_WORD_MASK(nbits); | ||
1192 | } | 1156 | } |
1193 | EXPORT_SYMBOL(bitmap_to_u32array); | 1157 | EXPORT_SYMBOL(bitmap_from_arr32); |
1194 | 1158 | ||
1195 | /** | 1159 | /** |
1196 | * bitmap_copy_le - copy a bitmap, putting the bits into little-endian order. | 1160 | * bitmap_to_arr32 - copy the contents of bitmap to a u32 array of bits |
1197 | * @dst: destination buffer | 1161 | * @buf: array of u32 (in host byte order), the dest bitmap |
1198 | * @src: bitmap to copy | 1162 | * @bitmap: array of unsigned longs, the source bitmap |
1199 | * @nbits: number of bits in the bitmap | 1163 | * @nbits: number of bits in @bitmap |
1200 | * | ||
1201 | * Require nbits % BITS_PER_LONG == 0. | ||
1202 | */ | 1164 | */ |
1203 | #ifdef __BIG_ENDIAN | 1165 | void bitmap_to_arr32(u32 *buf, const unsigned long *bitmap, unsigned int nbits) |
1204 | void bitmap_copy_le(unsigned long *dst, const unsigned long *src, unsigned int nbits) | ||
1205 | { | 1166 | { |
1206 | unsigned int i; | 1167 | unsigned int i, halfwords; |
1207 | 1168 | ||
1208 | for (i = 0; i < nbits/BITS_PER_LONG; i++) { | 1169 | if (!nbits) |
1209 | if (BITS_PER_LONG == 64) | 1170 | return; |
1210 | dst[i] = cpu_to_le64(src[i]); | 1171 | |
1211 | else | 1172 | halfwords = DIV_ROUND_UP(nbits, 32); |
1212 | dst[i] = cpu_to_le32(src[i]); | 1173 | for (i = 0; i < halfwords; i++) { |
1174 | buf[i] = (u32) (bitmap[i/2] & UINT_MAX); | ||
1175 | if (++i < halfwords) | ||
1176 | buf[i] = (u32) (bitmap[i/2] >> 32); | ||
1213 | } | 1177 | } |
1178 | |||
1179 | /* Clear tail bits in last element of array beyond nbits. */ | ||
1180 | if (nbits % BITS_PER_LONG) | ||
1181 | buf[halfwords - 1] &= (u32) (UINT_MAX >> ((-nbits) & 31)); | ||
1214 | } | 1182 | } |
1215 | EXPORT_SYMBOL(bitmap_copy_le); | 1183 | EXPORT_SYMBOL(bitmap_to_arr32); |
1184 | |||
1216 | #endif | 1185 | #endif |