aboutsummaryrefslogtreecommitdiffstats
path: root/lib/bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/bitmap.c')
-rw-r--r--lib/bitmap.c137
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)
1106EXPORT_SYMBOL(bitmap_allocate_region); 1106EXPORT_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 */
1122unsigned int 1116#ifdef __BIG_ENDIAN
1123bitmap_from_u32array(unsigned long *bitmap, unsigned int nbits, 1117void 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}
1151EXPORT_SYMBOL(bitmap_from_u32array); 1128EXPORT_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 */
1165unsigned int 1138void bitmap_from_arr32(unsigned long *bitmap, const u32 *buf,
1166bitmap_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}
1193EXPORT_SYMBOL(bitmap_to_u32array); 1157EXPORT_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 1165void bitmap_to_arr32(u32 *buf, const unsigned long *bitmap, unsigned int nbits)
1204void 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}
1215EXPORT_SYMBOL(bitmap_copy_le); 1183EXPORT_SYMBOL(bitmap_to_arr32);
1184
1216#endif 1185#endif