aboutsummaryrefslogtreecommitdiffstats
path: root/lib/bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/bitmap.c')
-rw-r--r--lib/bitmap.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/lib/bitmap.c b/lib/bitmap.c
index 814814397cce..c66da508cbf7 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -12,6 +12,8 @@
12#include <linux/bitmap.h> 12#include <linux/bitmap.h>
13#include <linux/bitops.h> 13#include <linux/bitops.h>
14#include <linux/bug.h> 14#include <linux/bug.h>
15#include <linux/kernel.h>
16#include <linux/string.h>
15 17
16#include <asm/page.h> 18#include <asm/page.h>
17#include <asm/uaccess.h> 19#include <asm/uaccess.h>
@@ -1060,6 +1062,93 @@ int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order)
1060EXPORT_SYMBOL(bitmap_allocate_region); 1062EXPORT_SYMBOL(bitmap_allocate_region);
1061 1063
1062/** 1064/**
1065 * bitmap_from_u32array - copy the contents of a u32 array of bits to bitmap
1066 * @bitmap: array of unsigned longs, the destination bitmap, non NULL
1067 * @nbits: number of bits in @bitmap
1068 * @buf: array of u32 (in host byte order), the source bitmap, non NULL
1069 * @nwords: number of u32 words in @buf
1070 *
1071 * copy min(nbits, 32*nwords) bits from @buf to @bitmap, remaining
1072 * bits between nword and nbits in @bitmap (if any) are cleared. In
1073 * last word of @bitmap, the bits beyond nbits (if any) are kept
1074 * unchanged.
1075 *
1076 * Return the number of bits effectively copied.
1077 */
1078unsigned int
1079bitmap_from_u32array(unsigned long *bitmap, unsigned int nbits,
1080 const u32 *buf, unsigned int nwords)
1081{
1082 unsigned int dst_idx, src_idx;
1083
1084 for (src_idx = dst_idx = 0; dst_idx < BITS_TO_LONGS(nbits); ++dst_idx) {
1085 unsigned long part = 0;
1086
1087 if (src_idx < nwords)
1088 part = buf[src_idx++];
1089
1090#if BITS_PER_LONG == 64
1091 if (src_idx < nwords)
1092 part |= ((unsigned long) buf[src_idx++]) << 32;
1093#endif
1094
1095 if (dst_idx < nbits/BITS_PER_LONG)
1096 bitmap[dst_idx] = part;
1097 else {
1098 unsigned long mask = BITMAP_LAST_WORD_MASK(nbits);
1099
1100 bitmap[dst_idx] = (bitmap[dst_idx] & ~mask)
1101 | (part & mask);
1102 }
1103 }
1104
1105 return min_t(unsigned int, nbits, 32*nwords);
1106}
1107EXPORT_SYMBOL(bitmap_from_u32array);
1108
1109/**
1110 * bitmap_to_u32array - copy the contents of bitmap to a u32 array of bits
1111 * @buf: array of u32 (in host byte order), the dest bitmap, non NULL
1112 * @nwords: number of u32 words in @buf
1113 * @bitmap: array of unsigned longs, the source bitmap, non NULL
1114 * @nbits: number of bits in @bitmap
1115 *
1116 * copy min(nbits, 32*nwords) bits from @bitmap to @buf. Remaining
1117 * bits after nbits in @buf (if any) are cleared.
1118 *
1119 * Return the number of bits effectively copied.
1120 */
1121unsigned int
1122bitmap_to_u32array(u32 *buf, unsigned int nwords,
1123 const unsigned long *bitmap, unsigned int nbits)
1124{
1125 unsigned int dst_idx = 0, src_idx = 0;
1126
1127 while (dst_idx < nwords) {
1128 unsigned long part = 0;
1129
1130 if (src_idx < BITS_TO_LONGS(nbits)) {
1131 part = bitmap[src_idx];
1132 if (src_idx >= nbits/BITS_PER_LONG)
1133 part &= BITMAP_LAST_WORD_MASK(nbits);
1134 src_idx++;
1135 }
1136
1137 buf[dst_idx++] = part & 0xffffffffUL;
1138
1139#if BITS_PER_LONG == 64
1140 if (dst_idx < nwords) {
1141 part >>= 32;
1142 buf[dst_idx++] = part & 0xffffffffUL;
1143 }
1144#endif
1145 }
1146
1147 return min_t(unsigned int, nbits, 32*nwords);
1148}
1149EXPORT_SYMBOL(bitmap_to_u32array);
1150
1151/**
1063 * bitmap_copy_le - copy a bitmap, putting the bits into little-endian order. 1152 * bitmap_copy_le - copy a bitmap, putting the bits into little-endian order.
1064 * @dst: destination buffer 1153 * @dst: destination buffer
1065 * @src: bitmap to copy 1154 * @src: bitmap to copy