162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * lib/bitmap.c 462306a36Sopenharmony_ci * Helper functions for bitmap.h. 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <linux/bitmap.h> 862306a36Sopenharmony_ci#include <linux/bitops.h> 962306a36Sopenharmony_ci#include <linux/bug.h> 1062306a36Sopenharmony_ci#include <linux/ctype.h> 1162306a36Sopenharmony_ci#include <linux/device.h> 1262306a36Sopenharmony_ci#include <linux/errno.h> 1362306a36Sopenharmony_ci#include <linux/export.h> 1462306a36Sopenharmony_ci#include <linux/kernel.h> 1562306a36Sopenharmony_ci#include <linux/mm.h> 1662306a36Sopenharmony_ci#include <linux/slab.h> 1762306a36Sopenharmony_ci#include <linux/string.h> 1862306a36Sopenharmony_ci#include <linux/thread_info.h> 1962306a36Sopenharmony_ci#include <linux/uaccess.h> 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#include <asm/page.h> 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#include "kstrtox.h" 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci/** 2662306a36Sopenharmony_ci * DOC: bitmap introduction 2762306a36Sopenharmony_ci * 2862306a36Sopenharmony_ci * bitmaps provide an array of bits, implemented using an 2962306a36Sopenharmony_ci * array of unsigned longs. The number of valid bits in a 3062306a36Sopenharmony_ci * given bitmap does _not_ need to be an exact multiple of 3162306a36Sopenharmony_ci * BITS_PER_LONG. 3262306a36Sopenharmony_ci * 3362306a36Sopenharmony_ci * The possible unused bits in the last, partially used word 3462306a36Sopenharmony_ci * of a bitmap are 'don't care'. The implementation makes 3562306a36Sopenharmony_ci * no particular effort to keep them zero. It ensures that 3662306a36Sopenharmony_ci * their value will not affect the results of any operation. 3762306a36Sopenharmony_ci * The bitmap operations that return Boolean (bitmap_empty, 3862306a36Sopenharmony_ci * for example) or scalar (bitmap_weight, for example) results 3962306a36Sopenharmony_ci * carefully filter out these unused bits from impacting their 4062306a36Sopenharmony_ci * results. 4162306a36Sopenharmony_ci * 4262306a36Sopenharmony_ci * The byte ordering of bitmaps is more natural on little 4362306a36Sopenharmony_ci * endian architectures. See the big-endian headers 4462306a36Sopenharmony_ci * include/asm-ppc64/bitops.h and include/asm-s390/bitops.h 4562306a36Sopenharmony_ci * for the best explanations of this ordering. 4662306a36Sopenharmony_ci */ 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_cibool __bitmap_equal(const unsigned long *bitmap1, 4962306a36Sopenharmony_ci const unsigned long *bitmap2, unsigned int bits) 5062306a36Sopenharmony_ci{ 5162306a36Sopenharmony_ci unsigned int k, lim = bits/BITS_PER_LONG; 5262306a36Sopenharmony_ci for (k = 0; k < lim; ++k) 5362306a36Sopenharmony_ci if (bitmap1[k] != bitmap2[k]) 5462306a36Sopenharmony_ci return false; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci if (bits % BITS_PER_LONG) 5762306a36Sopenharmony_ci if ((bitmap1[k] ^ bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) 5862306a36Sopenharmony_ci return false; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci return true; 6162306a36Sopenharmony_ci} 6262306a36Sopenharmony_ciEXPORT_SYMBOL(__bitmap_equal); 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cibool __bitmap_or_equal(const unsigned long *bitmap1, 6562306a36Sopenharmony_ci const unsigned long *bitmap2, 6662306a36Sopenharmony_ci const unsigned long *bitmap3, 6762306a36Sopenharmony_ci unsigned int bits) 6862306a36Sopenharmony_ci{ 6962306a36Sopenharmony_ci unsigned int k, lim = bits / BITS_PER_LONG; 7062306a36Sopenharmony_ci unsigned long tmp; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci for (k = 0; k < lim; ++k) { 7362306a36Sopenharmony_ci if ((bitmap1[k] | bitmap2[k]) != bitmap3[k]) 7462306a36Sopenharmony_ci return false; 7562306a36Sopenharmony_ci } 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci if (!(bits % BITS_PER_LONG)) 7862306a36Sopenharmony_ci return true; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci tmp = (bitmap1[k] | bitmap2[k]) ^ bitmap3[k]; 8162306a36Sopenharmony_ci return (tmp & BITMAP_LAST_WORD_MASK(bits)) == 0; 8262306a36Sopenharmony_ci} 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_civoid __bitmap_complement(unsigned long *dst, const unsigned long *src, unsigned int bits) 8562306a36Sopenharmony_ci{ 8662306a36Sopenharmony_ci unsigned int k, lim = BITS_TO_LONGS(bits); 8762306a36Sopenharmony_ci for (k = 0; k < lim; ++k) 8862306a36Sopenharmony_ci dst[k] = ~src[k]; 8962306a36Sopenharmony_ci} 9062306a36Sopenharmony_ciEXPORT_SYMBOL(__bitmap_complement); 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci/** 9362306a36Sopenharmony_ci * __bitmap_shift_right - logical right shift of the bits in a bitmap 9462306a36Sopenharmony_ci * @dst : destination bitmap 9562306a36Sopenharmony_ci * @src : source bitmap 9662306a36Sopenharmony_ci * @shift : shift by this many bits 9762306a36Sopenharmony_ci * @nbits : bitmap size, in bits 9862306a36Sopenharmony_ci * 9962306a36Sopenharmony_ci * Shifting right (dividing) means moving bits in the MS -> LS bit 10062306a36Sopenharmony_ci * direction. Zeros are fed into the vacated MS positions and the 10162306a36Sopenharmony_ci * LS bits shifted off the bottom are lost. 10262306a36Sopenharmony_ci */ 10362306a36Sopenharmony_civoid __bitmap_shift_right(unsigned long *dst, const unsigned long *src, 10462306a36Sopenharmony_ci unsigned shift, unsigned nbits) 10562306a36Sopenharmony_ci{ 10662306a36Sopenharmony_ci unsigned k, lim = BITS_TO_LONGS(nbits); 10762306a36Sopenharmony_ci unsigned off = shift/BITS_PER_LONG, rem = shift % BITS_PER_LONG; 10862306a36Sopenharmony_ci unsigned long mask = BITMAP_LAST_WORD_MASK(nbits); 10962306a36Sopenharmony_ci for (k = 0; off + k < lim; ++k) { 11062306a36Sopenharmony_ci unsigned long upper, lower; 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci /* 11362306a36Sopenharmony_ci * If shift is not word aligned, take lower rem bits of 11462306a36Sopenharmony_ci * word above and make them the top rem bits of result. 11562306a36Sopenharmony_ci */ 11662306a36Sopenharmony_ci if (!rem || off + k + 1 >= lim) 11762306a36Sopenharmony_ci upper = 0; 11862306a36Sopenharmony_ci else { 11962306a36Sopenharmony_ci upper = src[off + k + 1]; 12062306a36Sopenharmony_ci if (off + k + 1 == lim - 1) 12162306a36Sopenharmony_ci upper &= mask; 12262306a36Sopenharmony_ci upper <<= (BITS_PER_LONG - rem); 12362306a36Sopenharmony_ci } 12462306a36Sopenharmony_ci lower = src[off + k]; 12562306a36Sopenharmony_ci if (off + k == lim - 1) 12662306a36Sopenharmony_ci lower &= mask; 12762306a36Sopenharmony_ci lower >>= rem; 12862306a36Sopenharmony_ci dst[k] = lower | upper; 12962306a36Sopenharmony_ci } 13062306a36Sopenharmony_ci if (off) 13162306a36Sopenharmony_ci memset(&dst[lim - off], 0, off*sizeof(unsigned long)); 13262306a36Sopenharmony_ci} 13362306a36Sopenharmony_ciEXPORT_SYMBOL(__bitmap_shift_right); 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci/** 13762306a36Sopenharmony_ci * __bitmap_shift_left - logical left shift of the bits in a bitmap 13862306a36Sopenharmony_ci * @dst : destination bitmap 13962306a36Sopenharmony_ci * @src : source bitmap 14062306a36Sopenharmony_ci * @shift : shift by this many bits 14162306a36Sopenharmony_ci * @nbits : bitmap size, in bits 14262306a36Sopenharmony_ci * 14362306a36Sopenharmony_ci * Shifting left (multiplying) means moving bits in the LS -> MS 14462306a36Sopenharmony_ci * direction. Zeros are fed into the vacated LS bit positions 14562306a36Sopenharmony_ci * and those MS bits shifted off the top are lost. 14662306a36Sopenharmony_ci */ 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_civoid __bitmap_shift_left(unsigned long *dst, const unsigned long *src, 14962306a36Sopenharmony_ci unsigned int shift, unsigned int nbits) 15062306a36Sopenharmony_ci{ 15162306a36Sopenharmony_ci int k; 15262306a36Sopenharmony_ci unsigned int lim = BITS_TO_LONGS(nbits); 15362306a36Sopenharmony_ci unsigned int off = shift/BITS_PER_LONG, rem = shift % BITS_PER_LONG; 15462306a36Sopenharmony_ci for (k = lim - off - 1; k >= 0; --k) { 15562306a36Sopenharmony_ci unsigned long upper, lower; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci /* 15862306a36Sopenharmony_ci * If shift is not word aligned, take upper rem bits of 15962306a36Sopenharmony_ci * word below and make them the bottom rem bits of result. 16062306a36Sopenharmony_ci */ 16162306a36Sopenharmony_ci if (rem && k > 0) 16262306a36Sopenharmony_ci lower = src[k - 1] >> (BITS_PER_LONG - rem); 16362306a36Sopenharmony_ci else 16462306a36Sopenharmony_ci lower = 0; 16562306a36Sopenharmony_ci upper = src[k] << rem; 16662306a36Sopenharmony_ci dst[k + off] = lower | upper; 16762306a36Sopenharmony_ci } 16862306a36Sopenharmony_ci if (off) 16962306a36Sopenharmony_ci memset(dst, 0, off*sizeof(unsigned long)); 17062306a36Sopenharmony_ci} 17162306a36Sopenharmony_ciEXPORT_SYMBOL(__bitmap_shift_left); 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci/** 17462306a36Sopenharmony_ci * bitmap_cut() - remove bit region from bitmap and right shift remaining bits 17562306a36Sopenharmony_ci * @dst: destination bitmap, might overlap with src 17662306a36Sopenharmony_ci * @src: source bitmap 17762306a36Sopenharmony_ci * @first: start bit of region to be removed 17862306a36Sopenharmony_ci * @cut: number of bits to remove 17962306a36Sopenharmony_ci * @nbits: bitmap size, in bits 18062306a36Sopenharmony_ci * 18162306a36Sopenharmony_ci * Set the n-th bit of @dst iff the n-th bit of @src is set and 18262306a36Sopenharmony_ci * n is less than @first, or the m-th bit of @src is set for any 18362306a36Sopenharmony_ci * m such that @first <= n < nbits, and m = n + @cut. 18462306a36Sopenharmony_ci * 18562306a36Sopenharmony_ci * In pictures, example for a big-endian 32-bit architecture: 18662306a36Sopenharmony_ci * 18762306a36Sopenharmony_ci * The @src bitmap is:: 18862306a36Sopenharmony_ci * 18962306a36Sopenharmony_ci * 31 63 19062306a36Sopenharmony_ci * | | 19162306a36Sopenharmony_ci * 10000000 11000001 11110010 00010101 10000000 11000001 01110010 00010101 19262306a36Sopenharmony_ci * | | | | 19362306a36Sopenharmony_ci * 16 14 0 32 19462306a36Sopenharmony_ci * 19562306a36Sopenharmony_ci * if @cut is 3, and @first is 14, bits 14-16 in @src are cut and @dst is:: 19662306a36Sopenharmony_ci * 19762306a36Sopenharmony_ci * 31 63 19862306a36Sopenharmony_ci * | | 19962306a36Sopenharmony_ci * 10110000 00011000 00110010 00010101 00010000 00011000 00101110 01000010 20062306a36Sopenharmony_ci * | | | 20162306a36Sopenharmony_ci * 14 (bit 17 0 32 20262306a36Sopenharmony_ci * from @src) 20362306a36Sopenharmony_ci * 20462306a36Sopenharmony_ci * Note that @dst and @src might overlap partially or entirely. 20562306a36Sopenharmony_ci * 20662306a36Sopenharmony_ci * This is implemented in the obvious way, with a shift and carry 20762306a36Sopenharmony_ci * step for each moved bit. Optimisation is left as an exercise 20862306a36Sopenharmony_ci * for the compiler. 20962306a36Sopenharmony_ci */ 21062306a36Sopenharmony_civoid bitmap_cut(unsigned long *dst, const unsigned long *src, 21162306a36Sopenharmony_ci unsigned int first, unsigned int cut, unsigned int nbits) 21262306a36Sopenharmony_ci{ 21362306a36Sopenharmony_ci unsigned int len = BITS_TO_LONGS(nbits); 21462306a36Sopenharmony_ci unsigned long keep = 0, carry; 21562306a36Sopenharmony_ci int i; 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci if (first % BITS_PER_LONG) { 21862306a36Sopenharmony_ci keep = src[first / BITS_PER_LONG] & 21962306a36Sopenharmony_ci (~0UL >> (BITS_PER_LONG - first % BITS_PER_LONG)); 22062306a36Sopenharmony_ci } 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci memmove(dst, src, len * sizeof(*dst)); 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci while (cut--) { 22562306a36Sopenharmony_ci for (i = first / BITS_PER_LONG; i < len; i++) { 22662306a36Sopenharmony_ci if (i < len - 1) 22762306a36Sopenharmony_ci carry = dst[i + 1] & 1UL; 22862306a36Sopenharmony_ci else 22962306a36Sopenharmony_ci carry = 0; 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci dst[i] = (dst[i] >> 1) | (carry << (BITS_PER_LONG - 1)); 23262306a36Sopenharmony_ci } 23362306a36Sopenharmony_ci } 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci dst[first / BITS_PER_LONG] &= ~0UL << (first % BITS_PER_LONG); 23662306a36Sopenharmony_ci dst[first / BITS_PER_LONG] |= keep; 23762306a36Sopenharmony_ci} 23862306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_cut); 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_cibool __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, 24162306a36Sopenharmony_ci const unsigned long *bitmap2, unsigned int bits) 24262306a36Sopenharmony_ci{ 24362306a36Sopenharmony_ci unsigned int k; 24462306a36Sopenharmony_ci unsigned int lim = bits/BITS_PER_LONG; 24562306a36Sopenharmony_ci unsigned long result = 0; 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci for (k = 0; k < lim; k++) 24862306a36Sopenharmony_ci result |= (dst[k] = bitmap1[k] & bitmap2[k]); 24962306a36Sopenharmony_ci if (bits % BITS_PER_LONG) 25062306a36Sopenharmony_ci result |= (dst[k] = bitmap1[k] & bitmap2[k] & 25162306a36Sopenharmony_ci BITMAP_LAST_WORD_MASK(bits)); 25262306a36Sopenharmony_ci return result != 0; 25362306a36Sopenharmony_ci} 25462306a36Sopenharmony_ciEXPORT_SYMBOL(__bitmap_and); 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_civoid __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, 25762306a36Sopenharmony_ci const unsigned long *bitmap2, unsigned int bits) 25862306a36Sopenharmony_ci{ 25962306a36Sopenharmony_ci unsigned int k; 26062306a36Sopenharmony_ci unsigned int nr = BITS_TO_LONGS(bits); 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci for (k = 0; k < nr; k++) 26362306a36Sopenharmony_ci dst[k] = bitmap1[k] | bitmap2[k]; 26462306a36Sopenharmony_ci} 26562306a36Sopenharmony_ciEXPORT_SYMBOL(__bitmap_or); 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_civoid __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, 26862306a36Sopenharmony_ci const unsigned long *bitmap2, unsigned int bits) 26962306a36Sopenharmony_ci{ 27062306a36Sopenharmony_ci unsigned int k; 27162306a36Sopenharmony_ci unsigned int nr = BITS_TO_LONGS(bits); 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci for (k = 0; k < nr; k++) 27462306a36Sopenharmony_ci dst[k] = bitmap1[k] ^ bitmap2[k]; 27562306a36Sopenharmony_ci} 27662306a36Sopenharmony_ciEXPORT_SYMBOL(__bitmap_xor); 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_cibool __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, 27962306a36Sopenharmony_ci const unsigned long *bitmap2, unsigned int bits) 28062306a36Sopenharmony_ci{ 28162306a36Sopenharmony_ci unsigned int k; 28262306a36Sopenharmony_ci unsigned int lim = bits/BITS_PER_LONG; 28362306a36Sopenharmony_ci unsigned long result = 0; 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci for (k = 0; k < lim; k++) 28662306a36Sopenharmony_ci result |= (dst[k] = bitmap1[k] & ~bitmap2[k]); 28762306a36Sopenharmony_ci if (bits % BITS_PER_LONG) 28862306a36Sopenharmony_ci result |= (dst[k] = bitmap1[k] & ~bitmap2[k] & 28962306a36Sopenharmony_ci BITMAP_LAST_WORD_MASK(bits)); 29062306a36Sopenharmony_ci return result != 0; 29162306a36Sopenharmony_ci} 29262306a36Sopenharmony_ciEXPORT_SYMBOL(__bitmap_andnot); 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_civoid __bitmap_replace(unsigned long *dst, 29562306a36Sopenharmony_ci const unsigned long *old, const unsigned long *new, 29662306a36Sopenharmony_ci const unsigned long *mask, unsigned int nbits) 29762306a36Sopenharmony_ci{ 29862306a36Sopenharmony_ci unsigned int k; 29962306a36Sopenharmony_ci unsigned int nr = BITS_TO_LONGS(nbits); 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci for (k = 0; k < nr; k++) 30262306a36Sopenharmony_ci dst[k] = (old[k] & ~mask[k]) | (new[k] & mask[k]); 30362306a36Sopenharmony_ci} 30462306a36Sopenharmony_ciEXPORT_SYMBOL(__bitmap_replace); 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_cibool __bitmap_intersects(const unsigned long *bitmap1, 30762306a36Sopenharmony_ci const unsigned long *bitmap2, unsigned int bits) 30862306a36Sopenharmony_ci{ 30962306a36Sopenharmony_ci unsigned int k, lim = bits/BITS_PER_LONG; 31062306a36Sopenharmony_ci for (k = 0; k < lim; ++k) 31162306a36Sopenharmony_ci if (bitmap1[k] & bitmap2[k]) 31262306a36Sopenharmony_ci return true; 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci if (bits % BITS_PER_LONG) 31562306a36Sopenharmony_ci if ((bitmap1[k] & bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) 31662306a36Sopenharmony_ci return true; 31762306a36Sopenharmony_ci return false; 31862306a36Sopenharmony_ci} 31962306a36Sopenharmony_ciEXPORT_SYMBOL(__bitmap_intersects); 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_cibool __bitmap_subset(const unsigned long *bitmap1, 32262306a36Sopenharmony_ci const unsigned long *bitmap2, unsigned int bits) 32362306a36Sopenharmony_ci{ 32462306a36Sopenharmony_ci unsigned int k, lim = bits/BITS_PER_LONG; 32562306a36Sopenharmony_ci for (k = 0; k < lim; ++k) 32662306a36Sopenharmony_ci if (bitmap1[k] & ~bitmap2[k]) 32762306a36Sopenharmony_ci return false; 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci if (bits % BITS_PER_LONG) 33062306a36Sopenharmony_ci if ((bitmap1[k] & ~bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) 33162306a36Sopenharmony_ci return false; 33262306a36Sopenharmony_ci return true; 33362306a36Sopenharmony_ci} 33462306a36Sopenharmony_ciEXPORT_SYMBOL(__bitmap_subset); 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci#define BITMAP_WEIGHT(FETCH, bits) \ 33762306a36Sopenharmony_ci({ \ 33862306a36Sopenharmony_ci unsigned int __bits = (bits), idx, w = 0; \ 33962306a36Sopenharmony_ci \ 34062306a36Sopenharmony_ci for (idx = 0; idx < __bits / BITS_PER_LONG; idx++) \ 34162306a36Sopenharmony_ci w += hweight_long(FETCH); \ 34262306a36Sopenharmony_ci \ 34362306a36Sopenharmony_ci if (__bits % BITS_PER_LONG) \ 34462306a36Sopenharmony_ci w += hweight_long((FETCH) & BITMAP_LAST_WORD_MASK(__bits)); \ 34562306a36Sopenharmony_ci \ 34662306a36Sopenharmony_ci w; \ 34762306a36Sopenharmony_ci}) 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ciunsigned int __bitmap_weight(const unsigned long *bitmap, unsigned int bits) 35062306a36Sopenharmony_ci{ 35162306a36Sopenharmony_ci return BITMAP_WEIGHT(bitmap[idx], bits); 35262306a36Sopenharmony_ci} 35362306a36Sopenharmony_ciEXPORT_SYMBOL(__bitmap_weight); 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ciunsigned int __bitmap_weight_and(const unsigned long *bitmap1, 35662306a36Sopenharmony_ci const unsigned long *bitmap2, unsigned int bits) 35762306a36Sopenharmony_ci{ 35862306a36Sopenharmony_ci return BITMAP_WEIGHT(bitmap1[idx] & bitmap2[idx], bits); 35962306a36Sopenharmony_ci} 36062306a36Sopenharmony_ciEXPORT_SYMBOL(__bitmap_weight_and); 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_civoid __bitmap_set(unsigned long *map, unsigned int start, int len) 36362306a36Sopenharmony_ci{ 36462306a36Sopenharmony_ci unsigned long *p = map + BIT_WORD(start); 36562306a36Sopenharmony_ci const unsigned int size = start + len; 36662306a36Sopenharmony_ci int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG); 36762306a36Sopenharmony_ci unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start); 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci while (len - bits_to_set >= 0) { 37062306a36Sopenharmony_ci *p |= mask_to_set; 37162306a36Sopenharmony_ci len -= bits_to_set; 37262306a36Sopenharmony_ci bits_to_set = BITS_PER_LONG; 37362306a36Sopenharmony_ci mask_to_set = ~0UL; 37462306a36Sopenharmony_ci p++; 37562306a36Sopenharmony_ci } 37662306a36Sopenharmony_ci if (len) { 37762306a36Sopenharmony_ci mask_to_set &= BITMAP_LAST_WORD_MASK(size); 37862306a36Sopenharmony_ci *p |= mask_to_set; 37962306a36Sopenharmony_ci } 38062306a36Sopenharmony_ci} 38162306a36Sopenharmony_ciEXPORT_SYMBOL(__bitmap_set); 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_civoid __bitmap_clear(unsigned long *map, unsigned int start, int len) 38462306a36Sopenharmony_ci{ 38562306a36Sopenharmony_ci unsigned long *p = map + BIT_WORD(start); 38662306a36Sopenharmony_ci const unsigned int size = start + len; 38762306a36Sopenharmony_ci int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG); 38862306a36Sopenharmony_ci unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start); 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci while (len - bits_to_clear >= 0) { 39162306a36Sopenharmony_ci *p &= ~mask_to_clear; 39262306a36Sopenharmony_ci len -= bits_to_clear; 39362306a36Sopenharmony_ci bits_to_clear = BITS_PER_LONG; 39462306a36Sopenharmony_ci mask_to_clear = ~0UL; 39562306a36Sopenharmony_ci p++; 39662306a36Sopenharmony_ci } 39762306a36Sopenharmony_ci if (len) { 39862306a36Sopenharmony_ci mask_to_clear &= BITMAP_LAST_WORD_MASK(size); 39962306a36Sopenharmony_ci *p &= ~mask_to_clear; 40062306a36Sopenharmony_ci } 40162306a36Sopenharmony_ci} 40262306a36Sopenharmony_ciEXPORT_SYMBOL(__bitmap_clear); 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci/** 40562306a36Sopenharmony_ci * bitmap_find_next_zero_area_off - find a contiguous aligned zero area 40662306a36Sopenharmony_ci * @map: The address to base the search on 40762306a36Sopenharmony_ci * @size: The bitmap size in bits 40862306a36Sopenharmony_ci * @start: The bitnumber to start searching at 40962306a36Sopenharmony_ci * @nr: The number of zeroed bits we're looking for 41062306a36Sopenharmony_ci * @align_mask: Alignment mask for zero area 41162306a36Sopenharmony_ci * @align_offset: Alignment offset for zero area. 41262306a36Sopenharmony_ci * 41362306a36Sopenharmony_ci * The @align_mask should be one less than a power of 2; the effect is that 41462306a36Sopenharmony_ci * the bit offset of all zero areas this function finds plus @align_offset 41562306a36Sopenharmony_ci * is multiple of that power of 2. 41662306a36Sopenharmony_ci */ 41762306a36Sopenharmony_ciunsigned long bitmap_find_next_zero_area_off(unsigned long *map, 41862306a36Sopenharmony_ci unsigned long size, 41962306a36Sopenharmony_ci unsigned long start, 42062306a36Sopenharmony_ci unsigned int nr, 42162306a36Sopenharmony_ci unsigned long align_mask, 42262306a36Sopenharmony_ci unsigned long align_offset) 42362306a36Sopenharmony_ci{ 42462306a36Sopenharmony_ci unsigned long index, end, i; 42562306a36Sopenharmony_ciagain: 42662306a36Sopenharmony_ci index = find_next_zero_bit(map, size, start); 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ci /* Align allocation */ 42962306a36Sopenharmony_ci index = __ALIGN_MASK(index + align_offset, align_mask) - align_offset; 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci end = index + nr; 43262306a36Sopenharmony_ci if (end > size) 43362306a36Sopenharmony_ci return end; 43462306a36Sopenharmony_ci i = find_next_bit(map, end, index); 43562306a36Sopenharmony_ci if (i < end) { 43662306a36Sopenharmony_ci start = i + 1; 43762306a36Sopenharmony_ci goto again; 43862306a36Sopenharmony_ci } 43962306a36Sopenharmony_ci return index; 44062306a36Sopenharmony_ci} 44162306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_find_next_zero_area_off); 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci/* 44462306a36Sopenharmony_ci * Bitmap printing & parsing functions: first version by Nadia Yvette Chambers, 44562306a36Sopenharmony_ci * second version by Paul Jackson, third by Joe Korty. 44662306a36Sopenharmony_ci */ 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_ci/** 44962306a36Sopenharmony_ci * bitmap_parse_user - convert an ASCII hex string in a user buffer into a bitmap 45062306a36Sopenharmony_ci * 45162306a36Sopenharmony_ci * @ubuf: pointer to user buffer containing string. 45262306a36Sopenharmony_ci * @ulen: buffer size in bytes. If string is smaller than this 45362306a36Sopenharmony_ci * then it must be terminated with a \0. 45462306a36Sopenharmony_ci * @maskp: pointer to bitmap array that will contain result. 45562306a36Sopenharmony_ci * @nmaskbits: size of bitmap, in bits. 45662306a36Sopenharmony_ci */ 45762306a36Sopenharmony_ciint bitmap_parse_user(const char __user *ubuf, 45862306a36Sopenharmony_ci unsigned int ulen, unsigned long *maskp, 45962306a36Sopenharmony_ci int nmaskbits) 46062306a36Sopenharmony_ci{ 46162306a36Sopenharmony_ci char *buf; 46262306a36Sopenharmony_ci int ret; 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_ci buf = memdup_user_nul(ubuf, ulen); 46562306a36Sopenharmony_ci if (IS_ERR(buf)) 46662306a36Sopenharmony_ci return PTR_ERR(buf); 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ci ret = bitmap_parse(buf, UINT_MAX, maskp, nmaskbits); 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ci kfree(buf); 47162306a36Sopenharmony_ci return ret; 47262306a36Sopenharmony_ci} 47362306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_parse_user); 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci/** 47662306a36Sopenharmony_ci * bitmap_print_to_pagebuf - convert bitmap to list or hex format ASCII string 47762306a36Sopenharmony_ci * @list: indicates whether the bitmap must be list 47862306a36Sopenharmony_ci * @buf: page aligned buffer into which string is placed 47962306a36Sopenharmony_ci * @maskp: pointer to bitmap to convert 48062306a36Sopenharmony_ci * @nmaskbits: size of bitmap, in bits 48162306a36Sopenharmony_ci * 48262306a36Sopenharmony_ci * Output format is a comma-separated list of decimal numbers and 48362306a36Sopenharmony_ci * ranges if list is specified or hex digits grouped into comma-separated 48462306a36Sopenharmony_ci * sets of 8 digits/set. Returns the number of characters written to buf. 48562306a36Sopenharmony_ci * 48662306a36Sopenharmony_ci * It is assumed that @buf is a pointer into a PAGE_SIZE, page-aligned 48762306a36Sopenharmony_ci * area and that sufficient storage remains at @buf to accommodate the 48862306a36Sopenharmony_ci * bitmap_print_to_pagebuf() output. Returns the number of characters 48962306a36Sopenharmony_ci * actually printed to @buf, excluding terminating '\0'. 49062306a36Sopenharmony_ci */ 49162306a36Sopenharmony_ciint bitmap_print_to_pagebuf(bool list, char *buf, const unsigned long *maskp, 49262306a36Sopenharmony_ci int nmaskbits) 49362306a36Sopenharmony_ci{ 49462306a36Sopenharmony_ci ptrdiff_t len = PAGE_SIZE - offset_in_page(buf); 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_ci return list ? scnprintf(buf, len, "%*pbl\n", nmaskbits, maskp) : 49762306a36Sopenharmony_ci scnprintf(buf, len, "%*pb\n", nmaskbits, maskp); 49862306a36Sopenharmony_ci} 49962306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_print_to_pagebuf); 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_ci/** 50262306a36Sopenharmony_ci * bitmap_print_to_buf - convert bitmap to list or hex format ASCII string 50362306a36Sopenharmony_ci * @list: indicates whether the bitmap must be list 50462306a36Sopenharmony_ci * true: print in decimal list format 50562306a36Sopenharmony_ci * false: print in hexadecimal bitmask format 50662306a36Sopenharmony_ci * @buf: buffer into which string is placed 50762306a36Sopenharmony_ci * @maskp: pointer to bitmap to convert 50862306a36Sopenharmony_ci * @nmaskbits: size of bitmap, in bits 50962306a36Sopenharmony_ci * @off: in the string from which we are copying, We copy to @buf 51062306a36Sopenharmony_ci * @count: the maximum number of bytes to print 51162306a36Sopenharmony_ci */ 51262306a36Sopenharmony_cistatic int bitmap_print_to_buf(bool list, char *buf, const unsigned long *maskp, 51362306a36Sopenharmony_ci int nmaskbits, loff_t off, size_t count) 51462306a36Sopenharmony_ci{ 51562306a36Sopenharmony_ci const char *fmt = list ? "%*pbl\n" : "%*pb\n"; 51662306a36Sopenharmony_ci ssize_t size; 51762306a36Sopenharmony_ci void *data; 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_ci data = kasprintf(GFP_KERNEL, fmt, nmaskbits, maskp); 52062306a36Sopenharmony_ci if (!data) 52162306a36Sopenharmony_ci return -ENOMEM; 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci size = memory_read_from_buffer(buf, count, &off, data, strlen(data) + 1); 52462306a36Sopenharmony_ci kfree(data); 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_ci return size; 52762306a36Sopenharmony_ci} 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci/** 53062306a36Sopenharmony_ci * bitmap_print_bitmask_to_buf - convert bitmap to hex bitmask format ASCII string 53162306a36Sopenharmony_ci * @buf: buffer into which string is placed 53262306a36Sopenharmony_ci * @maskp: pointer to bitmap to convert 53362306a36Sopenharmony_ci * @nmaskbits: size of bitmap, in bits 53462306a36Sopenharmony_ci * @off: in the string from which we are copying, We copy to @buf 53562306a36Sopenharmony_ci * @count: the maximum number of bytes to print 53662306a36Sopenharmony_ci * 53762306a36Sopenharmony_ci * The bitmap_print_to_pagebuf() is used indirectly via its cpumap wrapper 53862306a36Sopenharmony_ci * cpumap_print_to_pagebuf() or directly by drivers to export hexadecimal 53962306a36Sopenharmony_ci * bitmask and decimal list to userspace by sysfs ABI. 54062306a36Sopenharmony_ci * Drivers might be using a normal attribute for this kind of ABIs. A 54162306a36Sopenharmony_ci * normal attribute typically has show entry as below:: 54262306a36Sopenharmony_ci * 54362306a36Sopenharmony_ci * static ssize_t example_attribute_show(struct device *dev, 54462306a36Sopenharmony_ci * struct device_attribute *attr, char *buf) 54562306a36Sopenharmony_ci * { 54662306a36Sopenharmony_ci * ... 54762306a36Sopenharmony_ci * return bitmap_print_to_pagebuf(true, buf, &mask, nr_trig_max); 54862306a36Sopenharmony_ci * } 54962306a36Sopenharmony_ci * 55062306a36Sopenharmony_ci * show entry of attribute has no offset and count parameters and this 55162306a36Sopenharmony_ci * means the file is limited to one page only. 55262306a36Sopenharmony_ci * bitmap_print_to_pagebuf() API works terribly well for this kind of 55362306a36Sopenharmony_ci * normal attribute with buf parameter and without offset, count:: 55462306a36Sopenharmony_ci * 55562306a36Sopenharmony_ci * bitmap_print_to_pagebuf(bool list, char *buf, const unsigned long *maskp, 55662306a36Sopenharmony_ci * int nmaskbits) 55762306a36Sopenharmony_ci * { 55862306a36Sopenharmony_ci * } 55962306a36Sopenharmony_ci * 56062306a36Sopenharmony_ci * The problem is once we have a large bitmap, we have a chance to get a 56162306a36Sopenharmony_ci * bitmask or list more than one page. Especially for list, it could be 56262306a36Sopenharmony_ci * as complex as 0,3,5,7,9,... We have no simple way to know it exact size. 56362306a36Sopenharmony_ci * It turns out bin_attribute is a way to break this limit. bin_attribute 56462306a36Sopenharmony_ci * has show entry as below:: 56562306a36Sopenharmony_ci * 56662306a36Sopenharmony_ci * static ssize_t 56762306a36Sopenharmony_ci * example_bin_attribute_show(struct file *filp, struct kobject *kobj, 56862306a36Sopenharmony_ci * struct bin_attribute *attr, char *buf, 56962306a36Sopenharmony_ci * loff_t offset, size_t count) 57062306a36Sopenharmony_ci * { 57162306a36Sopenharmony_ci * ... 57262306a36Sopenharmony_ci * } 57362306a36Sopenharmony_ci * 57462306a36Sopenharmony_ci * With the new offset and count parameters, this makes sysfs ABI be able 57562306a36Sopenharmony_ci * to support file size more than one page. For example, offset could be 57662306a36Sopenharmony_ci * >= 4096. 57762306a36Sopenharmony_ci * bitmap_print_bitmask_to_buf(), bitmap_print_list_to_buf() wit their 57862306a36Sopenharmony_ci * cpumap wrapper cpumap_print_bitmask_to_buf(), cpumap_print_list_to_buf() 57962306a36Sopenharmony_ci * make those drivers be able to support large bitmask and list after they 58062306a36Sopenharmony_ci * move to use bin_attribute. In result, we have to pass the corresponding 58162306a36Sopenharmony_ci * parameters such as off, count from bin_attribute show entry to this API. 58262306a36Sopenharmony_ci * 58362306a36Sopenharmony_ci * The role of cpumap_print_bitmask_to_buf() and cpumap_print_list_to_buf() 58462306a36Sopenharmony_ci * is similar with cpumap_print_to_pagebuf(), the difference is that 58562306a36Sopenharmony_ci * bitmap_print_to_pagebuf() mainly serves sysfs attribute with the assumption 58662306a36Sopenharmony_ci * the destination buffer is exactly one page and won't be more than one page. 58762306a36Sopenharmony_ci * cpumap_print_bitmask_to_buf() and cpumap_print_list_to_buf(), on the other 58862306a36Sopenharmony_ci * hand, mainly serves bin_attribute which doesn't work with exact one page, 58962306a36Sopenharmony_ci * and it can break the size limit of converted decimal list and hexadecimal 59062306a36Sopenharmony_ci * bitmask. 59162306a36Sopenharmony_ci * 59262306a36Sopenharmony_ci * WARNING! 59362306a36Sopenharmony_ci * 59462306a36Sopenharmony_ci * This function is not a replacement for sprintf() or bitmap_print_to_pagebuf(). 59562306a36Sopenharmony_ci * It is intended to workaround sysfs limitations discussed above and should be 59662306a36Sopenharmony_ci * used carefully in general case for the following reasons: 59762306a36Sopenharmony_ci * 59862306a36Sopenharmony_ci * - Time complexity is O(nbits^2/count), comparing to O(nbits) for snprintf(). 59962306a36Sopenharmony_ci * - Memory complexity is O(nbits), comparing to O(1) for snprintf(). 60062306a36Sopenharmony_ci * - @off and @count are NOT offset and number of bits to print. 60162306a36Sopenharmony_ci * - If printing part of bitmap as list, the resulting string is not a correct 60262306a36Sopenharmony_ci * list representation of bitmap. Particularly, some bits within or out of 60362306a36Sopenharmony_ci * related interval may be erroneously set or unset. The format of the string 60462306a36Sopenharmony_ci * may be broken, so bitmap_parselist-like parser may fail parsing it. 60562306a36Sopenharmony_ci * - If printing the whole bitmap as list by parts, user must ensure the order 60662306a36Sopenharmony_ci * of calls of the function such that the offset is incremented linearly. 60762306a36Sopenharmony_ci * - If printing the whole bitmap as list by parts, user must keep bitmap 60862306a36Sopenharmony_ci * unchanged between the very first and very last call. Otherwise concatenated 60962306a36Sopenharmony_ci * result may be incorrect, and format may be broken. 61062306a36Sopenharmony_ci * 61162306a36Sopenharmony_ci * Returns the number of characters actually printed to @buf 61262306a36Sopenharmony_ci */ 61362306a36Sopenharmony_ciint bitmap_print_bitmask_to_buf(char *buf, const unsigned long *maskp, 61462306a36Sopenharmony_ci int nmaskbits, loff_t off, size_t count) 61562306a36Sopenharmony_ci{ 61662306a36Sopenharmony_ci return bitmap_print_to_buf(false, buf, maskp, nmaskbits, off, count); 61762306a36Sopenharmony_ci} 61862306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_print_bitmask_to_buf); 61962306a36Sopenharmony_ci 62062306a36Sopenharmony_ci/** 62162306a36Sopenharmony_ci * bitmap_print_list_to_buf - convert bitmap to decimal list format ASCII string 62262306a36Sopenharmony_ci * @buf: buffer into which string is placed 62362306a36Sopenharmony_ci * @maskp: pointer to bitmap to convert 62462306a36Sopenharmony_ci * @nmaskbits: size of bitmap, in bits 62562306a36Sopenharmony_ci * @off: in the string from which we are copying, We copy to @buf 62662306a36Sopenharmony_ci * @count: the maximum number of bytes to print 62762306a36Sopenharmony_ci * 62862306a36Sopenharmony_ci * Everything is same with the above bitmap_print_bitmask_to_buf() except 62962306a36Sopenharmony_ci * the print format. 63062306a36Sopenharmony_ci */ 63162306a36Sopenharmony_ciint bitmap_print_list_to_buf(char *buf, const unsigned long *maskp, 63262306a36Sopenharmony_ci int nmaskbits, loff_t off, size_t count) 63362306a36Sopenharmony_ci{ 63462306a36Sopenharmony_ci return bitmap_print_to_buf(true, buf, maskp, nmaskbits, off, count); 63562306a36Sopenharmony_ci} 63662306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_print_list_to_buf); 63762306a36Sopenharmony_ci 63862306a36Sopenharmony_ci/* 63962306a36Sopenharmony_ci * Region 9-38:4/10 describes the following bitmap structure: 64062306a36Sopenharmony_ci * 0 9 12 18 38 N 64162306a36Sopenharmony_ci * .........****......****......****.................. 64262306a36Sopenharmony_ci * ^ ^ ^ ^ ^ 64362306a36Sopenharmony_ci * start off group_len end nbits 64462306a36Sopenharmony_ci */ 64562306a36Sopenharmony_cistruct region { 64662306a36Sopenharmony_ci unsigned int start; 64762306a36Sopenharmony_ci unsigned int off; 64862306a36Sopenharmony_ci unsigned int group_len; 64962306a36Sopenharmony_ci unsigned int end; 65062306a36Sopenharmony_ci unsigned int nbits; 65162306a36Sopenharmony_ci}; 65262306a36Sopenharmony_ci 65362306a36Sopenharmony_cistatic void bitmap_set_region(const struct region *r, unsigned long *bitmap) 65462306a36Sopenharmony_ci{ 65562306a36Sopenharmony_ci unsigned int start; 65662306a36Sopenharmony_ci 65762306a36Sopenharmony_ci for (start = r->start; start <= r->end; start += r->group_len) 65862306a36Sopenharmony_ci bitmap_set(bitmap, start, min(r->end - start + 1, r->off)); 65962306a36Sopenharmony_ci} 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_cistatic int bitmap_check_region(const struct region *r) 66262306a36Sopenharmony_ci{ 66362306a36Sopenharmony_ci if (r->start > r->end || r->group_len == 0 || r->off > r->group_len) 66462306a36Sopenharmony_ci return -EINVAL; 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_ci if (r->end >= r->nbits) 66762306a36Sopenharmony_ci return -ERANGE; 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_ci return 0; 67062306a36Sopenharmony_ci} 67162306a36Sopenharmony_ci 67262306a36Sopenharmony_cistatic const char *bitmap_getnum(const char *str, unsigned int *num, 67362306a36Sopenharmony_ci unsigned int lastbit) 67462306a36Sopenharmony_ci{ 67562306a36Sopenharmony_ci unsigned long long n; 67662306a36Sopenharmony_ci unsigned int len; 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_ci if (str[0] == 'N') { 67962306a36Sopenharmony_ci *num = lastbit; 68062306a36Sopenharmony_ci return str + 1; 68162306a36Sopenharmony_ci } 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_ci len = _parse_integer(str, 10, &n); 68462306a36Sopenharmony_ci if (!len) 68562306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 68662306a36Sopenharmony_ci if (len & KSTRTOX_OVERFLOW || n != (unsigned int)n) 68762306a36Sopenharmony_ci return ERR_PTR(-EOVERFLOW); 68862306a36Sopenharmony_ci 68962306a36Sopenharmony_ci *num = n; 69062306a36Sopenharmony_ci return str + len; 69162306a36Sopenharmony_ci} 69262306a36Sopenharmony_ci 69362306a36Sopenharmony_cistatic inline bool end_of_str(char c) 69462306a36Sopenharmony_ci{ 69562306a36Sopenharmony_ci return c == '\0' || c == '\n'; 69662306a36Sopenharmony_ci} 69762306a36Sopenharmony_ci 69862306a36Sopenharmony_cistatic inline bool __end_of_region(char c) 69962306a36Sopenharmony_ci{ 70062306a36Sopenharmony_ci return isspace(c) || c == ','; 70162306a36Sopenharmony_ci} 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_cistatic inline bool end_of_region(char c) 70462306a36Sopenharmony_ci{ 70562306a36Sopenharmony_ci return __end_of_region(c) || end_of_str(c); 70662306a36Sopenharmony_ci} 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_ci/* 70962306a36Sopenharmony_ci * The format allows commas and whitespaces at the beginning 71062306a36Sopenharmony_ci * of the region. 71162306a36Sopenharmony_ci */ 71262306a36Sopenharmony_cistatic const char *bitmap_find_region(const char *str) 71362306a36Sopenharmony_ci{ 71462306a36Sopenharmony_ci while (__end_of_region(*str)) 71562306a36Sopenharmony_ci str++; 71662306a36Sopenharmony_ci 71762306a36Sopenharmony_ci return end_of_str(*str) ? NULL : str; 71862306a36Sopenharmony_ci} 71962306a36Sopenharmony_ci 72062306a36Sopenharmony_cistatic const char *bitmap_find_region_reverse(const char *start, const char *end) 72162306a36Sopenharmony_ci{ 72262306a36Sopenharmony_ci while (start <= end && __end_of_region(*end)) 72362306a36Sopenharmony_ci end--; 72462306a36Sopenharmony_ci 72562306a36Sopenharmony_ci return end; 72662306a36Sopenharmony_ci} 72762306a36Sopenharmony_ci 72862306a36Sopenharmony_cistatic const char *bitmap_parse_region(const char *str, struct region *r) 72962306a36Sopenharmony_ci{ 73062306a36Sopenharmony_ci unsigned int lastbit = r->nbits - 1; 73162306a36Sopenharmony_ci 73262306a36Sopenharmony_ci if (!strncasecmp(str, "all", 3)) { 73362306a36Sopenharmony_ci r->start = 0; 73462306a36Sopenharmony_ci r->end = lastbit; 73562306a36Sopenharmony_ci str += 3; 73662306a36Sopenharmony_ci 73762306a36Sopenharmony_ci goto check_pattern; 73862306a36Sopenharmony_ci } 73962306a36Sopenharmony_ci 74062306a36Sopenharmony_ci str = bitmap_getnum(str, &r->start, lastbit); 74162306a36Sopenharmony_ci if (IS_ERR(str)) 74262306a36Sopenharmony_ci return str; 74362306a36Sopenharmony_ci 74462306a36Sopenharmony_ci if (end_of_region(*str)) 74562306a36Sopenharmony_ci goto no_end; 74662306a36Sopenharmony_ci 74762306a36Sopenharmony_ci if (*str != '-') 74862306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 74962306a36Sopenharmony_ci 75062306a36Sopenharmony_ci str = bitmap_getnum(str + 1, &r->end, lastbit); 75162306a36Sopenharmony_ci if (IS_ERR(str)) 75262306a36Sopenharmony_ci return str; 75362306a36Sopenharmony_ci 75462306a36Sopenharmony_cicheck_pattern: 75562306a36Sopenharmony_ci if (end_of_region(*str)) 75662306a36Sopenharmony_ci goto no_pattern; 75762306a36Sopenharmony_ci 75862306a36Sopenharmony_ci if (*str != ':') 75962306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 76062306a36Sopenharmony_ci 76162306a36Sopenharmony_ci str = bitmap_getnum(str + 1, &r->off, lastbit); 76262306a36Sopenharmony_ci if (IS_ERR(str)) 76362306a36Sopenharmony_ci return str; 76462306a36Sopenharmony_ci 76562306a36Sopenharmony_ci if (*str != '/') 76662306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 76762306a36Sopenharmony_ci 76862306a36Sopenharmony_ci return bitmap_getnum(str + 1, &r->group_len, lastbit); 76962306a36Sopenharmony_ci 77062306a36Sopenharmony_cino_end: 77162306a36Sopenharmony_ci r->end = r->start; 77262306a36Sopenharmony_cino_pattern: 77362306a36Sopenharmony_ci r->off = r->end + 1; 77462306a36Sopenharmony_ci r->group_len = r->end + 1; 77562306a36Sopenharmony_ci 77662306a36Sopenharmony_ci return end_of_str(*str) ? NULL : str; 77762306a36Sopenharmony_ci} 77862306a36Sopenharmony_ci 77962306a36Sopenharmony_ci/** 78062306a36Sopenharmony_ci * bitmap_parselist - convert list format ASCII string to bitmap 78162306a36Sopenharmony_ci * @buf: read user string from this buffer; must be terminated 78262306a36Sopenharmony_ci * with a \0 or \n. 78362306a36Sopenharmony_ci * @maskp: write resulting mask here 78462306a36Sopenharmony_ci * @nmaskbits: number of bits in mask to be written 78562306a36Sopenharmony_ci * 78662306a36Sopenharmony_ci * Input format is a comma-separated list of decimal numbers and 78762306a36Sopenharmony_ci * ranges. Consecutively set bits are shown as two hyphen-separated 78862306a36Sopenharmony_ci * decimal numbers, the smallest and largest bit numbers set in 78962306a36Sopenharmony_ci * the range. 79062306a36Sopenharmony_ci * Optionally each range can be postfixed to denote that only parts of it 79162306a36Sopenharmony_ci * should be set. The range will divided to groups of specific size. 79262306a36Sopenharmony_ci * From each group will be used only defined amount of bits. 79362306a36Sopenharmony_ci * Syntax: range:used_size/group_size 79462306a36Sopenharmony_ci * Example: 0-1023:2/256 ==> 0,1,256,257,512,513,768,769 79562306a36Sopenharmony_ci * The value 'N' can be used as a dynamically substituted token for the 79662306a36Sopenharmony_ci * maximum allowed value; i.e (nmaskbits - 1). Keep in mind that it is 79762306a36Sopenharmony_ci * dynamic, so if system changes cause the bitmap width to change, such 79862306a36Sopenharmony_ci * as more cores in a CPU list, then any ranges using N will also change. 79962306a36Sopenharmony_ci * 80062306a36Sopenharmony_ci * Returns: 0 on success, -errno on invalid input strings. Error values: 80162306a36Sopenharmony_ci * 80262306a36Sopenharmony_ci * - ``-EINVAL``: wrong region format 80362306a36Sopenharmony_ci * - ``-EINVAL``: invalid character in string 80462306a36Sopenharmony_ci * - ``-ERANGE``: bit number specified too large for mask 80562306a36Sopenharmony_ci * - ``-EOVERFLOW``: integer overflow in the input parameters 80662306a36Sopenharmony_ci */ 80762306a36Sopenharmony_ciint bitmap_parselist(const char *buf, unsigned long *maskp, int nmaskbits) 80862306a36Sopenharmony_ci{ 80962306a36Sopenharmony_ci struct region r; 81062306a36Sopenharmony_ci long ret; 81162306a36Sopenharmony_ci 81262306a36Sopenharmony_ci r.nbits = nmaskbits; 81362306a36Sopenharmony_ci bitmap_zero(maskp, r.nbits); 81462306a36Sopenharmony_ci 81562306a36Sopenharmony_ci while (buf) { 81662306a36Sopenharmony_ci buf = bitmap_find_region(buf); 81762306a36Sopenharmony_ci if (buf == NULL) 81862306a36Sopenharmony_ci return 0; 81962306a36Sopenharmony_ci 82062306a36Sopenharmony_ci buf = bitmap_parse_region(buf, &r); 82162306a36Sopenharmony_ci if (IS_ERR(buf)) 82262306a36Sopenharmony_ci return PTR_ERR(buf); 82362306a36Sopenharmony_ci 82462306a36Sopenharmony_ci ret = bitmap_check_region(&r); 82562306a36Sopenharmony_ci if (ret) 82662306a36Sopenharmony_ci return ret; 82762306a36Sopenharmony_ci 82862306a36Sopenharmony_ci bitmap_set_region(&r, maskp); 82962306a36Sopenharmony_ci } 83062306a36Sopenharmony_ci 83162306a36Sopenharmony_ci return 0; 83262306a36Sopenharmony_ci} 83362306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_parselist); 83462306a36Sopenharmony_ci 83562306a36Sopenharmony_ci 83662306a36Sopenharmony_ci/** 83762306a36Sopenharmony_ci * bitmap_parselist_user() - convert user buffer's list format ASCII 83862306a36Sopenharmony_ci * string to bitmap 83962306a36Sopenharmony_ci * 84062306a36Sopenharmony_ci * @ubuf: pointer to user buffer containing string. 84162306a36Sopenharmony_ci * @ulen: buffer size in bytes. If string is smaller than this 84262306a36Sopenharmony_ci * then it must be terminated with a \0. 84362306a36Sopenharmony_ci * @maskp: pointer to bitmap array that will contain result. 84462306a36Sopenharmony_ci * @nmaskbits: size of bitmap, in bits. 84562306a36Sopenharmony_ci * 84662306a36Sopenharmony_ci * Wrapper for bitmap_parselist(), providing it with user buffer. 84762306a36Sopenharmony_ci */ 84862306a36Sopenharmony_ciint bitmap_parselist_user(const char __user *ubuf, 84962306a36Sopenharmony_ci unsigned int ulen, unsigned long *maskp, 85062306a36Sopenharmony_ci int nmaskbits) 85162306a36Sopenharmony_ci{ 85262306a36Sopenharmony_ci char *buf; 85362306a36Sopenharmony_ci int ret; 85462306a36Sopenharmony_ci 85562306a36Sopenharmony_ci buf = memdup_user_nul(ubuf, ulen); 85662306a36Sopenharmony_ci if (IS_ERR(buf)) 85762306a36Sopenharmony_ci return PTR_ERR(buf); 85862306a36Sopenharmony_ci 85962306a36Sopenharmony_ci ret = bitmap_parselist(buf, maskp, nmaskbits); 86062306a36Sopenharmony_ci 86162306a36Sopenharmony_ci kfree(buf); 86262306a36Sopenharmony_ci return ret; 86362306a36Sopenharmony_ci} 86462306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_parselist_user); 86562306a36Sopenharmony_ci 86662306a36Sopenharmony_cistatic const char *bitmap_get_x32_reverse(const char *start, 86762306a36Sopenharmony_ci const char *end, u32 *num) 86862306a36Sopenharmony_ci{ 86962306a36Sopenharmony_ci u32 ret = 0; 87062306a36Sopenharmony_ci int c, i; 87162306a36Sopenharmony_ci 87262306a36Sopenharmony_ci for (i = 0; i < 32; i += 4) { 87362306a36Sopenharmony_ci c = hex_to_bin(*end--); 87462306a36Sopenharmony_ci if (c < 0) 87562306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 87662306a36Sopenharmony_ci 87762306a36Sopenharmony_ci ret |= c << i; 87862306a36Sopenharmony_ci 87962306a36Sopenharmony_ci if (start > end || __end_of_region(*end)) 88062306a36Sopenharmony_ci goto out; 88162306a36Sopenharmony_ci } 88262306a36Sopenharmony_ci 88362306a36Sopenharmony_ci if (hex_to_bin(*end--) >= 0) 88462306a36Sopenharmony_ci return ERR_PTR(-EOVERFLOW); 88562306a36Sopenharmony_ciout: 88662306a36Sopenharmony_ci *num = ret; 88762306a36Sopenharmony_ci return end; 88862306a36Sopenharmony_ci} 88962306a36Sopenharmony_ci 89062306a36Sopenharmony_ci/** 89162306a36Sopenharmony_ci * bitmap_parse - convert an ASCII hex string into a bitmap. 89262306a36Sopenharmony_ci * @start: pointer to buffer containing string. 89362306a36Sopenharmony_ci * @buflen: buffer size in bytes. If string is smaller than this 89462306a36Sopenharmony_ci * then it must be terminated with a \0 or \n. In that case, 89562306a36Sopenharmony_ci * UINT_MAX may be provided instead of string length. 89662306a36Sopenharmony_ci * @maskp: pointer to bitmap array that will contain result. 89762306a36Sopenharmony_ci * @nmaskbits: size of bitmap, in bits. 89862306a36Sopenharmony_ci * 89962306a36Sopenharmony_ci * Commas group hex digits into chunks. Each chunk defines exactly 32 90062306a36Sopenharmony_ci * bits of the resultant bitmask. No chunk may specify a value larger 90162306a36Sopenharmony_ci * than 32 bits (%-EOVERFLOW), and if a chunk specifies a smaller value 90262306a36Sopenharmony_ci * then leading 0-bits are prepended. %-EINVAL is returned for illegal 90362306a36Sopenharmony_ci * characters. Grouping such as "1,,5", ",44", "," or "" is allowed. 90462306a36Sopenharmony_ci * Leading, embedded and trailing whitespace accepted. 90562306a36Sopenharmony_ci */ 90662306a36Sopenharmony_ciint bitmap_parse(const char *start, unsigned int buflen, 90762306a36Sopenharmony_ci unsigned long *maskp, int nmaskbits) 90862306a36Sopenharmony_ci{ 90962306a36Sopenharmony_ci const char *end = strnchrnul(start, buflen, '\n') - 1; 91062306a36Sopenharmony_ci int chunks = BITS_TO_U32(nmaskbits); 91162306a36Sopenharmony_ci u32 *bitmap = (u32 *)maskp; 91262306a36Sopenharmony_ci int unset_bit; 91362306a36Sopenharmony_ci int chunk; 91462306a36Sopenharmony_ci 91562306a36Sopenharmony_ci for (chunk = 0; ; chunk++) { 91662306a36Sopenharmony_ci end = bitmap_find_region_reverse(start, end); 91762306a36Sopenharmony_ci if (start > end) 91862306a36Sopenharmony_ci break; 91962306a36Sopenharmony_ci 92062306a36Sopenharmony_ci if (!chunks--) 92162306a36Sopenharmony_ci return -EOVERFLOW; 92262306a36Sopenharmony_ci 92362306a36Sopenharmony_ci#if defined(CONFIG_64BIT) && defined(__BIG_ENDIAN) 92462306a36Sopenharmony_ci end = bitmap_get_x32_reverse(start, end, &bitmap[chunk ^ 1]); 92562306a36Sopenharmony_ci#else 92662306a36Sopenharmony_ci end = bitmap_get_x32_reverse(start, end, &bitmap[chunk]); 92762306a36Sopenharmony_ci#endif 92862306a36Sopenharmony_ci if (IS_ERR(end)) 92962306a36Sopenharmony_ci return PTR_ERR(end); 93062306a36Sopenharmony_ci } 93162306a36Sopenharmony_ci 93262306a36Sopenharmony_ci unset_bit = (BITS_TO_U32(nmaskbits) - chunks) * 32; 93362306a36Sopenharmony_ci if (unset_bit < nmaskbits) { 93462306a36Sopenharmony_ci bitmap_clear(maskp, unset_bit, nmaskbits - unset_bit); 93562306a36Sopenharmony_ci return 0; 93662306a36Sopenharmony_ci } 93762306a36Sopenharmony_ci 93862306a36Sopenharmony_ci if (find_next_bit(maskp, unset_bit, nmaskbits) != unset_bit) 93962306a36Sopenharmony_ci return -EOVERFLOW; 94062306a36Sopenharmony_ci 94162306a36Sopenharmony_ci return 0; 94262306a36Sopenharmony_ci} 94362306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_parse); 94462306a36Sopenharmony_ci 94562306a36Sopenharmony_ci/** 94662306a36Sopenharmony_ci * bitmap_pos_to_ord - find ordinal of set bit at given position in bitmap 94762306a36Sopenharmony_ci * @buf: pointer to a bitmap 94862306a36Sopenharmony_ci * @pos: a bit position in @buf (0 <= @pos < @nbits) 94962306a36Sopenharmony_ci * @nbits: number of valid bit positions in @buf 95062306a36Sopenharmony_ci * 95162306a36Sopenharmony_ci * Map the bit at position @pos in @buf (of length @nbits) to the 95262306a36Sopenharmony_ci * ordinal of which set bit it is. If it is not set or if @pos 95362306a36Sopenharmony_ci * is not a valid bit position, map to -1. 95462306a36Sopenharmony_ci * 95562306a36Sopenharmony_ci * If for example, just bits 4 through 7 are set in @buf, then @pos 95662306a36Sopenharmony_ci * values 4 through 7 will get mapped to 0 through 3, respectively, 95762306a36Sopenharmony_ci * and other @pos values will get mapped to -1. When @pos value 7 95862306a36Sopenharmony_ci * gets mapped to (returns) @ord value 3 in this example, that means 95962306a36Sopenharmony_ci * that bit 7 is the 3rd (starting with 0th) set bit in @buf. 96062306a36Sopenharmony_ci * 96162306a36Sopenharmony_ci * The bit positions 0 through @bits are valid positions in @buf. 96262306a36Sopenharmony_ci */ 96362306a36Sopenharmony_cistatic int bitmap_pos_to_ord(const unsigned long *buf, unsigned int pos, unsigned int nbits) 96462306a36Sopenharmony_ci{ 96562306a36Sopenharmony_ci if (pos >= nbits || !test_bit(pos, buf)) 96662306a36Sopenharmony_ci return -1; 96762306a36Sopenharmony_ci 96862306a36Sopenharmony_ci return bitmap_weight(buf, pos); 96962306a36Sopenharmony_ci} 97062306a36Sopenharmony_ci 97162306a36Sopenharmony_ci/** 97262306a36Sopenharmony_ci * bitmap_remap - Apply map defined by a pair of bitmaps to another bitmap 97362306a36Sopenharmony_ci * @dst: remapped result 97462306a36Sopenharmony_ci * @src: subset to be remapped 97562306a36Sopenharmony_ci * @old: defines domain of map 97662306a36Sopenharmony_ci * @new: defines range of map 97762306a36Sopenharmony_ci * @nbits: number of bits in each of these bitmaps 97862306a36Sopenharmony_ci * 97962306a36Sopenharmony_ci * Let @old and @new define a mapping of bit positions, such that 98062306a36Sopenharmony_ci * whatever position is held by the n-th set bit in @old is mapped 98162306a36Sopenharmony_ci * to the n-th set bit in @new. In the more general case, allowing 98262306a36Sopenharmony_ci * for the possibility that the weight 'w' of @new is less than the 98362306a36Sopenharmony_ci * weight of @old, map the position of the n-th set bit in @old to 98462306a36Sopenharmony_ci * the position of the m-th set bit in @new, where m == n % w. 98562306a36Sopenharmony_ci * 98662306a36Sopenharmony_ci * If either of the @old and @new bitmaps are empty, or if @src and 98762306a36Sopenharmony_ci * @dst point to the same location, then this routine copies @src 98862306a36Sopenharmony_ci * to @dst. 98962306a36Sopenharmony_ci * 99062306a36Sopenharmony_ci * The positions of unset bits in @old are mapped to themselves 99162306a36Sopenharmony_ci * (the identify map). 99262306a36Sopenharmony_ci * 99362306a36Sopenharmony_ci * Apply the above specified mapping to @src, placing the result in 99462306a36Sopenharmony_ci * @dst, clearing any bits previously set in @dst. 99562306a36Sopenharmony_ci * 99662306a36Sopenharmony_ci * For example, lets say that @old has bits 4 through 7 set, and 99762306a36Sopenharmony_ci * @new has bits 12 through 15 set. This defines the mapping of bit 99862306a36Sopenharmony_ci * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other 99962306a36Sopenharmony_ci * bit positions unchanged. So if say @src comes into this routine 100062306a36Sopenharmony_ci * with bits 1, 5 and 7 set, then @dst should leave with bits 1, 100162306a36Sopenharmony_ci * 13 and 15 set. 100262306a36Sopenharmony_ci */ 100362306a36Sopenharmony_civoid bitmap_remap(unsigned long *dst, const unsigned long *src, 100462306a36Sopenharmony_ci const unsigned long *old, const unsigned long *new, 100562306a36Sopenharmony_ci unsigned int nbits) 100662306a36Sopenharmony_ci{ 100762306a36Sopenharmony_ci unsigned int oldbit, w; 100862306a36Sopenharmony_ci 100962306a36Sopenharmony_ci if (dst == src) /* following doesn't handle inplace remaps */ 101062306a36Sopenharmony_ci return; 101162306a36Sopenharmony_ci bitmap_zero(dst, nbits); 101262306a36Sopenharmony_ci 101362306a36Sopenharmony_ci w = bitmap_weight(new, nbits); 101462306a36Sopenharmony_ci for_each_set_bit(oldbit, src, nbits) { 101562306a36Sopenharmony_ci int n = bitmap_pos_to_ord(old, oldbit, nbits); 101662306a36Sopenharmony_ci 101762306a36Sopenharmony_ci if (n < 0 || w == 0) 101862306a36Sopenharmony_ci set_bit(oldbit, dst); /* identity map */ 101962306a36Sopenharmony_ci else 102062306a36Sopenharmony_ci set_bit(find_nth_bit(new, nbits, n % w), dst); 102162306a36Sopenharmony_ci } 102262306a36Sopenharmony_ci} 102362306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_remap); 102462306a36Sopenharmony_ci 102562306a36Sopenharmony_ci/** 102662306a36Sopenharmony_ci * bitmap_bitremap - Apply map defined by a pair of bitmaps to a single bit 102762306a36Sopenharmony_ci * @oldbit: bit position to be mapped 102862306a36Sopenharmony_ci * @old: defines domain of map 102962306a36Sopenharmony_ci * @new: defines range of map 103062306a36Sopenharmony_ci * @bits: number of bits in each of these bitmaps 103162306a36Sopenharmony_ci * 103262306a36Sopenharmony_ci * Let @old and @new define a mapping of bit positions, such that 103362306a36Sopenharmony_ci * whatever position is held by the n-th set bit in @old is mapped 103462306a36Sopenharmony_ci * to the n-th set bit in @new. In the more general case, allowing 103562306a36Sopenharmony_ci * for the possibility that the weight 'w' of @new is less than the 103662306a36Sopenharmony_ci * weight of @old, map the position of the n-th set bit in @old to 103762306a36Sopenharmony_ci * the position of the m-th set bit in @new, where m == n % w. 103862306a36Sopenharmony_ci * 103962306a36Sopenharmony_ci * The positions of unset bits in @old are mapped to themselves 104062306a36Sopenharmony_ci * (the identify map). 104162306a36Sopenharmony_ci * 104262306a36Sopenharmony_ci * Apply the above specified mapping to bit position @oldbit, returning 104362306a36Sopenharmony_ci * the new bit position. 104462306a36Sopenharmony_ci * 104562306a36Sopenharmony_ci * For example, lets say that @old has bits 4 through 7 set, and 104662306a36Sopenharmony_ci * @new has bits 12 through 15 set. This defines the mapping of bit 104762306a36Sopenharmony_ci * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other 104862306a36Sopenharmony_ci * bit positions unchanged. So if say @oldbit is 5, then this routine 104962306a36Sopenharmony_ci * returns 13. 105062306a36Sopenharmony_ci */ 105162306a36Sopenharmony_ciint bitmap_bitremap(int oldbit, const unsigned long *old, 105262306a36Sopenharmony_ci const unsigned long *new, int bits) 105362306a36Sopenharmony_ci{ 105462306a36Sopenharmony_ci int w = bitmap_weight(new, bits); 105562306a36Sopenharmony_ci int n = bitmap_pos_to_ord(old, oldbit, bits); 105662306a36Sopenharmony_ci if (n < 0 || w == 0) 105762306a36Sopenharmony_ci return oldbit; 105862306a36Sopenharmony_ci else 105962306a36Sopenharmony_ci return find_nth_bit(new, bits, n % w); 106062306a36Sopenharmony_ci} 106162306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_bitremap); 106262306a36Sopenharmony_ci 106362306a36Sopenharmony_ci#ifdef CONFIG_NUMA 106462306a36Sopenharmony_ci/** 106562306a36Sopenharmony_ci * bitmap_onto - translate one bitmap relative to another 106662306a36Sopenharmony_ci * @dst: resulting translated bitmap 106762306a36Sopenharmony_ci * @orig: original untranslated bitmap 106862306a36Sopenharmony_ci * @relmap: bitmap relative to which translated 106962306a36Sopenharmony_ci * @bits: number of bits in each of these bitmaps 107062306a36Sopenharmony_ci * 107162306a36Sopenharmony_ci * Set the n-th bit of @dst iff there exists some m such that the 107262306a36Sopenharmony_ci * n-th bit of @relmap is set, the m-th bit of @orig is set, and 107362306a36Sopenharmony_ci * the n-th bit of @relmap is also the m-th _set_ bit of @relmap. 107462306a36Sopenharmony_ci * (If you understood the previous sentence the first time your 107562306a36Sopenharmony_ci * read it, you're overqualified for your current job.) 107662306a36Sopenharmony_ci * 107762306a36Sopenharmony_ci * In other words, @orig is mapped onto (surjectively) @dst, 107862306a36Sopenharmony_ci * using the map { <n, m> | the n-th bit of @relmap is the 107962306a36Sopenharmony_ci * m-th set bit of @relmap }. 108062306a36Sopenharmony_ci * 108162306a36Sopenharmony_ci * Any set bits in @orig above bit number W, where W is the 108262306a36Sopenharmony_ci * weight of (number of set bits in) @relmap are mapped nowhere. 108362306a36Sopenharmony_ci * In particular, if for all bits m set in @orig, m >= W, then 108462306a36Sopenharmony_ci * @dst will end up empty. In situations where the possibility 108562306a36Sopenharmony_ci * of such an empty result is not desired, one way to avoid it is 108662306a36Sopenharmony_ci * to use the bitmap_fold() operator, below, to first fold the 108762306a36Sopenharmony_ci * @orig bitmap over itself so that all its set bits x are in the 108862306a36Sopenharmony_ci * range 0 <= x < W. The bitmap_fold() operator does this by 108962306a36Sopenharmony_ci * setting the bit (m % W) in @dst, for each bit (m) set in @orig. 109062306a36Sopenharmony_ci * 109162306a36Sopenharmony_ci * Example [1] for bitmap_onto(): 109262306a36Sopenharmony_ci * Let's say @relmap has bits 30-39 set, and @orig has bits 109362306a36Sopenharmony_ci * 1, 3, 5, 7, 9 and 11 set. Then on return from this routine, 109462306a36Sopenharmony_ci * @dst will have bits 31, 33, 35, 37 and 39 set. 109562306a36Sopenharmony_ci * 109662306a36Sopenharmony_ci * When bit 0 is set in @orig, it means turn on the bit in 109762306a36Sopenharmony_ci * @dst corresponding to whatever is the first bit (if any) 109862306a36Sopenharmony_ci * that is turned on in @relmap. Since bit 0 was off in the 109962306a36Sopenharmony_ci * above example, we leave off that bit (bit 30) in @dst. 110062306a36Sopenharmony_ci * 110162306a36Sopenharmony_ci * When bit 1 is set in @orig (as in the above example), it 110262306a36Sopenharmony_ci * means turn on the bit in @dst corresponding to whatever 110362306a36Sopenharmony_ci * is the second bit that is turned on in @relmap. The second 110462306a36Sopenharmony_ci * bit in @relmap that was turned on in the above example was 110562306a36Sopenharmony_ci * bit 31, so we turned on bit 31 in @dst. 110662306a36Sopenharmony_ci * 110762306a36Sopenharmony_ci * Similarly, we turned on bits 33, 35, 37 and 39 in @dst, 110862306a36Sopenharmony_ci * because they were the 4th, 6th, 8th and 10th set bits 110962306a36Sopenharmony_ci * set in @relmap, and the 4th, 6th, 8th and 10th bits of 111062306a36Sopenharmony_ci * @orig (i.e. bits 3, 5, 7 and 9) were also set. 111162306a36Sopenharmony_ci * 111262306a36Sopenharmony_ci * When bit 11 is set in @orig, it means turn on the bit in 111362306a36Sopenharmony_ci * @dst corresponding to whatever is the twelfth bit that is 111462306a36Sopenharmony_ci * turned on in @relmap. In the above example, there were 111562306a36Sopenharmony_ci * only ten bits turned on in @relmap (30..39), so that bit 111662306a36Sopenharmony_ci * 11 was set in @orig had no affect on @dst. 111762306a36Sopenharmony_ci * 111862306a36Sopenharmony_ci * Example [2] for bitmap_fold() + bitmap_onto(): 111962306a36Sopenharmony_ci * Let's say @relmap has these ten bits set:: 112062306a36Sopenharmony_ci * 112162306a36Sopenharmony_ci * 40 41 42 43 45 48 53 61 74 95 112262306a36Sopenharmony_ci * 112362306a36Sopenharmony_ci * (for the curious, that's 40 plus the first ten terms of the 112462306a36Sopenharmony_ci * Fibonacci sequence.) 112562306a36Sopenharmony_ci * 112662306a36Sopenharmony_ci * Further lets say we use the following code, invoking 112762306a36Sopenharmony_ci * bitmap_fold() then bitmap_onto, as suggested above to 112862306a36Sopenharmony_ci * avoid the possibility of an empty @dst result:: 112962306a36Sopenharmony_ci * 113062306a36Sopenharmony_ci * unsigned long *tmp; // a temporary bitmap's bits 113162306a36Sopenharmony_ci * 113262306a36Sopenharmony_ci * bitmap_fold(tmp, orig, bitmap_weight(relmap, bits), bits); 113362306a36Sopenharmony_ci * bitmap_onto(dst, tmp, relmap, bits); 113462306a36Sopenharmony_ci * 113562306a36Sopenharmony_ci * Then this table shows what various values of @dst would be, for 113662306a36Sopenharmony_ci * various @orig's. I list the zero-based positions of each set bit. 113762306a36Sopenharmony_ci * The tmp column shows the intermediate result, as computed by 113862306a36Sopenharmony_ci * using bitmap_fold() to fold the @orig bitmap modulo ten 113962306a36Sopenharmony_ci * (the weight of @relmap): 114062306a36Sopenharmony_ci * 114162306a36Sopenharmony_ci * =============== ============== ================= 114262306a36Sopenharmony_ci * @orig tmp @dst 114362306a36Sopenharmony_ci * 0 0 40 114462306a36Sopenharmony_ci * 1 1 41 114562306a36Sopenharmony_ci * 9 9 95 114662306a36Sopenharmony_ci * 10 0 40 [#f1]_ 114762306a36Sopenharmony_ci * 1 3 5 7 1 3 5 7 41 43 48 61 114862306a36Sopenharmony_ci * 0 1 2 3 4 0 1 2 3 4 40 41 42 43 45 114962306a36Sopenharmony_ci * 0 9 18 27 0 9 8 7 40 61 74 95 115062306a36Sopenharmony_ci * 0 10 20 30 0 40 115162306a36Sopenharmony_ci * 0 11 22 33 0 1 2 3 40 41 42 43 115262306a36Sopenharmony_ci * 0 12 24 36 0 2 4 6 40 42 45 53 115362306a36Sopenharmony_ci * 78 102 211 1 2 8 41 42 74 [#f1]_ 115462306a36Sopenharmony_ci * =============== ============== ================= 115562306a36Sopenharmony_ci * 115662306a36Sopenharmony_ci * .. [#f1] 115762306a36Sopenharmony_ci * 115862306a36Sopenharmony_ci * For these marked lines, if we hadn't first done bitmap_fold() 115962306a36Sopenharmony_ci * into tmp, then the @dst result would have been empty. 116062306a36Sopenharmony_ci * 116162306a36Sopenharmony_ci * If either of @orig or @relmap is empty (no set bits), then @dst 116262306a36Sopenharmony_ci * will be returned empty. 116362306a36Sopenharmony_ci * 116462306a36Sopenharmony_ci * If (as explained above) the only set bits in @orig are in positions 116562306a36Sopenharmony_ci * m where m >= W, (where W is the weight of @relmap) then @dst will 116662306a36Sopenharmony_ci * once again be returned empty. 116762306a36Sopenharmony_ci * 116862306a36Sopenharmony_ci * All bits in @dst not set by the above rule are cleared. 116962306a36Sopenharmony_ci */ 117062306a36Sopenharmony_civoid bitmap_onto(unsigned long *dst, const unsigned long *orig, 117162306a36Sopenharmony_ci const unsigned long *relmap, unsigned int bits) 117262306a36Sopenharmony_ci{ 117362306a36Sopenharmony_ci unsigned int n, m; /* same meaning as in above comment */ 117462306a36Sopenharmony_ci 117562306a36Sopenharmony_ci if (dst == orig) /* following doesn't handle inplace mappings */ 117662306a36Sopenharmony_ci return; 117762306a36Sopenharmony_ci bitmap_zero(dst, bits); 117862306a36Sopenharmony_ci 117962306a36Sopenharmony_ci /* 118062306a36Sopenharmony_ci * The following code is a more efficient, but less 118162306a36Sopenharmony_ci * obvious, equivalent to the loop: 118262306a36Sopenharmony_ci * for (m = 0; m < bitmap_weight(relmap, bits); m++) { 118362306a36Sopenharmony_ci * n = find_nth_bit(orig, bits, m); 118462306a36Sopenharmony_ci * if (test_bit(m, orig)) 118562306a36Sopenharmony_ci * set_bit(n, dst); 118662306a36Sopenharmony_ci * } 118762306a36Sopenharmony_ci */ 118862306a36Sopenharmony_ci 118962306a36Sopenharmony_ci m = 0; 119062306a36Sopenharmony_ci for_each_set_bit(n, relmap, bits) { 119162306a36Sopenharmony_ci /* m == bitmap_pos_to_ord(relmap, n, bits) */ 119262306a36Sopenharmony_ci if (test_bit(m, orig)) 119362306a36Sopenharmony_ci set_bit(n, dst); 119462306a36Sopenharmony_ci m++; 119562306a36Sopenharmony_ci } 119662306a36Sopenharmony_ci} 119762306a36Sopenharmony_ci 119862306a36Sopenharmony_ci/** 119962306a36Sopenharmony_ci * bitmap_fold - fold larger bitmap into smaller, modulo specified size 120062306a36Sopenharmony_ci * @dst: resulting smaller bitmap 120162306a36Sopenharmony_ci * @orig: original larger bitmap 120262306a36Sopenharmony_ci * @sz: specified size 120362306a36Sopenharmony_ci * @nbits: number of bits in each of these bitmaps 120462306a36Sopenharmony_ci * 120562306a36Sopenharmony_ci * For each bit oldbit in @orig, set bit oldbit mod @sz in @dst. 120662306a36Sopenharmony_ci * Clear all other bits in @dst. See further the comment and 120762306a36Sopenharmony_ci * Example [2] for bitmap_onto() for why and how to use this. 120862306a36Sopenharmony_ci */ 120962306a36Sopenharmony_civoid bitmap_fold(unsigned long *dst, const unsigned long *orig, 121062306a36Sopenharmony_ci unsigned int sz, unsigned int nbits) 121162306a36Sopenharmony_ci{ 121262306a36Sopenharmony_ci unsigned int oldbit; 121362306a36Sopenharmony_ci 121462306a36Sopenharmony_ci if (dst == orig) /* following doesn't handle inplace mappings */ 121562306a36Sopenharmony_ci return; 121662306a36Sopenharmony_ci bitmap_zero(dst, nbits); 121762306a36Sopenharmony_ci 121862306a36Sopenharmony_ci for_each_set_bit(oldbit, orig, nbits) 121962306a36Sopenharmony_ci set_bit(oldbit % sz, dst); 122062306a36Sopenharmony_ci} 122162306a36Sopenharmony_ci#endif /* CONFIG_NUMA */ 122262306a36Sopenharmony_ci 122362306a36Sopenharmony_ci/* 122462306a36Sopenharmony_ci * Common code for bitmap_*_region() routines. 122562306a36Sopenharmony_ci * bitmap: array of unsigned longs corresponding to the bitmap 122662306a36Sopenharmony_ci * pos: the beginning of the region 122762306a36Sopenharmony_ci * order: region size (log base 2 of number of bits) 122862306a36Sopenharmony_ci * reg_op: operation(s) to perform on that region of bitmap 122962306a36Sopenharmony_ci * 123062306a36Sopenharmony_ci * Can set, verify and/or release a region of bits in a bitmap, 123162306a36Sopenharmony_ci * depending on which combination of REG_OP_* flag bits is set. 123262306a36Sopenharmony_ci * 123362306a36Sopenharmony_ci * A region of a bitmap is a sequence of bits in the bitmap, of 123462306a36Sopenharmony_ci * some size '1 << order' (a power of two), aligned to that same 123562306a36Sopenharmony_ci * '1 << order' power of two. 123662306a36Sopenharmony_ci * 123762306a36Sopenharmony_ci * Returns 1 if REG_OP_ISFREE succeeds (region is all zero bits). 123862306a36Sopenharmony_ci * Returns 0 in all other cases and reg_ops. 123962306a36Sopenharmony_ci */ 124062306a36Sopenharmony_ci 124162306a36Sopenharmony_cienum { 124262306a36Sopenharmony_ci REG_OP_ISFREE, /* true if region is all zero bits */ 124362306a36Sopenharmony_ci REG_OP_ALLOC, /* set all bits in region */ 124462306a36Sopenharmony_ci REG_OP_RELEASE, /* clear all bits in region */ 124562306a36Sopenharmony_ci}; 124662306a36Sopenharmony_ci 124762306a36Sopenharmony_cistatic int __reg_op(unsigned long *bitmap, unsigned int pos, int order, int reg_op) 124862306a36Sopenharmony_ci{ 124962306a36Sopenharmony_ci int nbits_reg; /* number of bits in region */ 125062306a36Sopenharmony_ci int index; /* index first long of region in bitmap */ 125162306a36Sopenharmony_ci int offset; /* bit offset region in bitmap[index] */ 125262306a36Sopenharmony_ci int nlongs_reg; /* num longs spanned by region in bitmap */ 125362306a36Sopenharmony_ci int nbitsinlong; /* num bits of region in each spanned long */ 125462306a36Sopenharmony_ci unsigned long mask; /* bitmask for one long of region */ 125562306a36Sopenharmony_ci int i; /* scans bitmap by longs */ 125662306a36Sopenharmony_ci int ret = 0; /* return value */ 125762306a36Sopenharmony_ci 125862306a36Sopenharmony_ci /* 125962306a36Sopenharmony_ci * Either nlongs_reg == 1 (for small orders that fit in one long) 126062306a36Sopenharmony_ci * or (offset == 0 && mask == ~0UL) (for larger multiword orders.) 126162306a36Sopenharmony_ci */ 126262306a36Sopenharmony_ci nbits_reg = 1 << order; 126362306a36Sopenharmony_ci index = pos / BITS_PER_LONG; 126462306a36Sopenharmony_ci offset = pos - (index * BITS_PER_LONG); 126562306a36Sopenharmony_ci nlongs_reg = BITS_TO_LONGS(nbits_reg); 126662306a36Sopenharmony_ci nbitsinlong = min(nbits_reg, BITS_PER_LONG); 126762306a36Sopenharmony_ci 126862306a36Sopenharmony_ci /* 126962306a36Sopenharmony_ci * Can't do "mask = (1UL << nbitsinlong) - 1", as that 127062306a36Sopenharmony_ci * overflows if nbitsinlong == BITS_PER_LONG. 127162306a36Sopenharmony_ci */ 127262306a36Sopenharmony_ci mask = (1UL << (nbitsinlong - 1)); 127362306a36Sopenharmony_ci mask += mask - 1; 127462306a36Sopenharmony_ci mask <<= offset; 127562306a36Sopenharmony_ci 127662306a36Sopenharmony_ci switch (reg_op) { 127762306a36Sopenharmony_ci case REG_OP_ISFREE: 127862306a36Sopenharmony_ci for (i = 0; i < nlongs_reg; i++) { 127962306a36Sopenharmony_ci if (bitmap[index + i] & mask) 128062306a36Sopenharmony_ci goto done; 128162306a36Sopenharmony_ci } 128262306a36Sopenharmony_ci ret = 1; /* all bits in region free (zero) */ 128362306a36Sopenharmony_ci break; 128462306a36Sopenharmony_ci 128562306a36Sopenharmony_ci case REG_OP_ALLOC: 128662306a36Sopenharmony_ci for (i = 0; i < nlongs_reg; i++) 128762306a36Sopenharmony_ci bitmap[index + i] |= mask; 128862306a36Sopenharmony_ci break; 128962306a36Sopenharmony_ci 129062306a36Sopenharmony_ci case REG_OP_RELEASE: 129162306a36Sopenharmony_ci for (i = 0; i < nlongs_reg; i++) 129262306a36Sopenharmony_ci bitmap[index + i] &= ~mask; 129362306a36Sopenharmony_ci break; 129462306a36Sopenharmony_ci } 129562306a36Sopenharmony_cidone: 129662306a36Sopenharmony_ci return ret; 129762306a36Sopenharmony_ci} 129862306a36Sopenharmony_ci 129962306a36Sopenharmony_ci/** 130062306a36Sopenharmony_ci * bitmap_find_free_region - find a contiguous aligned mem region 130162306a36Sopenharmony_ci * @bitmap: array of unsigned longs corresponding to the bitmap 130262306a36Sopenharmony_ci * @bits: number of bits in the bitmap 130362306a36Sopenharmony_ci * @order: region size (log base 2 of number of bits) to find 130462306a36Sopenharmony_ci * 130562306a36Sopenharmony_ci * Find a region of free (zero) bits in a @bitmap of @bits bits and 130662306a36Sopenharmony_ci * allocate them (set them to one). Only consider regions of length 130762306a36Sopenharmony_ci * a power (@order) of two, aligned to that power of two, which 130862306a36Sopenharmony_ci * makes the search algorithm much faster. 130962306a36Sopenharmony_ci * 131062306a36Sopenharmony_ci * Return the bit offset in bitmap of the allocated region, 131162306a36Sopenharmony_ci * or -errno on failure. 131262306a36Sopenharmony_ci */ 131362306a36Sopenharmony_ciint bitmap_find_free_region(unsigned long *bitmap, unsigned int bits, int order) 131462306a36Sopenharmony_ci{ 131562306a36Sopenharmony_ci unsigned int pos, end; /* scans bitmap by regions of size order */ 131662306a36Sopenharmony_ci 131762306a36Sopenharmony_ci for (pos = 0 ; (end = pos + (1U << order)) <= bits; pos = end) { 131862306a36Sopenharmony_ci if (!__reg_op(bitmap, pos, order, REG_OP_ISFREE)) 131962306a36Sopenharmony_ci continue; 132062306a36Sopenharmony_ci __reg_op(bitmap, pos, order, REG_OP_ALLOC); 132162306a36Sopenharmony_ci return pos; 132262306a36Sopenharmony_ci } 132362306a36Sopenharmony_ci return -ENOMEM; 132462306a36Sopenharmony_ci} 132562306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_find_free_region); 132662306a36Sopenharmony_ci 132762306a36Sopenharmony_ci/** 132862306a36Sopenharmony_ci * bitmap_release_region - release allocated bitmap region 132962306a36Sopenharmony_ci * @bitmap: array of unsigned longs corresponding to the bitmap 133062306a36Sopenharmony_ci * @pos: beginning of bit region to release 133162306a36Sopenharmony_ci * @order: region size (log base 2 of number of bits) to release 133262306a36Sopenharmony_ci * 133362306a36Sopenharmony_ci * This is the complement to __bitmap_find_free_region() and releases 133462306a36Sopenharmony_ci * the found region (by clearing it in the bitmap). 133562306a36Sopenharmony_ci * 133662306a36Sopenharmony_ci * No return value. 133762306a36Sopenharmony_ci */ 133862306a36Sopenharmony_civoid bitmap_release_region(unsigned long *bitmap, unsigned int pos, int order) 133962306a36Sopenharmony_ci{ 134062306a36Sopenharmony_ci __reg_op(bitmap, pos, order, REG_OP_RELEASE); 134162306a36Sopenharmony_ci} 134262306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_release_region); 134362306a36Sopenharmony_ci 134462306a36Sopenharmony_ci/** 134562306a36Sopenharmony_ci * bitmap_allocate_region - allocate bitmap region 134662306a36Sopenharmony_ci * @bitmap: array of unsigned longs corresponding to the bitmap 134762306a36Sopenharmony_ci * @pos: beginning of bit region to allocate 134862306a36Sopenharmony_ci * @order: region size (log base 2 of number of bits) to allocate 134962306a36Sopenharmony_ci * 135062306a36Sopenharmony_ci * Allocate (set bits in) a specified region of a bitmap. 135162306a36Sopenharmony_ci * 135262306a36Sopenharmony_ci * Return 0 on success, or %-EBUSY if specified region wasn't 135362306a36Sopenharmony_ci * free (not all bits were zero). 135462306a36Sopenharmony_ci */ 135562306a36Sopenharmony_ciint bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order) 135662306a36Sopenharmony_ci{ 135762306a36Sopenharmony_ci if (!__reg_op(bitmap, pos, order, REG_OP_ISFREE)) 135862306a36Sopenharmony_ci return -EBUSY; 135962306a36Sopenharmony_ci return __reg_op(bitmap, pos, order, REG_OP_ALLOC); 136062306a36Sopenharmony_ci} 136162306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_allocate_region); 136262306a36Sopenharmony_ci 136362306a36Sopenharmony_ci/** 136462306a36Sopenharmony_ci * bitmap_copy_le - copy a bitmap, putting the bits into little-endian order. 136562306a36Sopenharmony_ci * @dst: destination buffer 136662306a36Sopenharmony_ci * @src: bitmap to copy 136762306a36Sopenharmony_ci * @nbits: number of bits in the bitmap 136862306a36Sopenharmony_ci * 136962306a36Sopenharmony_ci * Require nbits % BITS_PER_LONG == 0. 137062306a36Sopenharmony_ci */ 137162306a36Sopenharmony_ci#ifdef __BIG_ENDIAN 137262306a36Sopenharmony_civoid bitmap_copy_le(unsigned long *dst, const unsigned long *src, unsigned int nbits) 137362306a36Sopenharmony_ci{ 137462306a36Sopenharmony_ci unsigned int i; 137562306a36Sopenharmony_ci 137662306a36Sopenharmony_ci for (i = 0; i < nbits/BITS_PER_LONG; i++) { 137762306a36Sopenharmony_ci if (BITS_PER_LONG == 64) 137862306a36Sopenharmony_ci dst[i] = cpu_to_le64(src[i]); 137962306a36Sopenharmony_ci else 138062306a36Sopenharmony_ci dst[i] = cpu_to_le32(src[i]); 138162306a36Sopenharmony_ci } 138262306a36Sopenharmony_ci} 138362306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_copy_le); 138462306a36Sopenharmony_ci#endif 138562306a36Sopenharmony_ci 138662306a36Sopenharmony_ciunsigned long *bitmap_alloc(unsigned int nbits, gfp_t flags) 138762306a36Sopenharmony_ci{ 138862306a36Sopenharmony_ci return kmalloc_array(BITS_TO_LONGS(nbits), sizeof(unsigned long), 138962306a36Sopenharmony_ci flags); 139062306a36Sopenharmony_ci} 139162306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_alloc); 139262306a36Sopenharmony_ci 139362306a36Sopenharmony_ciunsigned long *bitmap_zalloc(unsigned int nbits, gfp_t flags) 139462306a36Sopenharmony_ci{ 139562306a36Sopenharmony_ci return bitmap_alloc(nbits, flags | __GFP_ZERO); 139662306a36Sopenharmony_ci} 139762306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_zalloc); 139862306a36Sopenharmony_ci 139962306a36Sopenharmony_ciunsigned long *bitmap_alloc_node(unsigned int nbits, gfp_t flags, int node) 140062306a36Sopenharmony_ci{ 140162306a36Sopenharmony_ci return kmalloc_array_node(BITS_TO_LONGS(nbits), sizeof(unsigned long), 140262306a36Sopenharmony_ci flags, node); 140362306a36Sopenharmony_ci} 140462306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_alloc_node); 140562306a36Sopenharmony_ci 140662306a36Sopenharmony_ciunsigned long *bitmap_zalloc_node(unsigned int nbits, gfp_t flags, int node) 140762306a36Sopenharmony_ci{ 140862306a36Sopenharmony_ci return bitmap_alloc_node(nbits, flags | __GFP_ZERO, node); 140962306a36Sopenharmony_ci} 141062306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_zalloc_node); 141162306a36Sopenharmony_ci 141262306a36Sopenharmony_civoid bitmap_free(const unsigned long *bitmap) 141362306a36Sopenharmony_ci{ 141462306a36Sopenharmony_ci kfree(bitmap); 141562306a36Sopenharmony_ci} 141662306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_free); 141762306a36Sopenharmony_ci 141862306a36Sopenharmony_cistatic void devm_bitmap_free(void *data) 141962306a36Sopenharmony_ci{ 142062306a36Sopenharmony_ci unsigned long *bitmap = data; 142162306a36Sopenharmony_ci 142262306a36Sopenharmony_ci bitmap_free(bitmap); 142362306a36Sopenharmony_ci} 142462306a36Sopenharmony_ci 142562306a36Sopenharmony_ciunsigned long *devm_bitmap_alloc(struct device *dev, 142662306a36Sopenharmony_ci unsigned int nbits, gfp_t flags) 142762306a36Sopenharmony_ci{ 142862306a36Sopenharmony_ci unsigned long *bitmap; 142962306a36Sopenharmony_ci int ret; 143062306a36Sopenharmony_ci 143162306a36Sopenharmony_ci bitmap = bitmap_alloc(nbits, flags); 143262306a36Sopenharmony_ci if (!bitmap) 143362306a36Sopenharmony_ci return NULL; 143462306a36Sopenharmony_ci 143562306a36Sopenharmony_ci ret = devm_add_action_or_reset(dev, devm_bitmap_free, bitmap); 143662306a36Sopenharmony_ci if (ret) 143762306a36Sopenharmony_ci return NULL; 143862306a36Sopenharmony_ci 143962306a36Sopenharmony_ci return bitmap; 144062306a36Sopenharmony_ci} 144162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(devm_bitmap_alloc); 144262306a36Sopenharmony_ci 144362306a36Sopenharmony_ciunsigned long *devm_bitmap_zalloc(struct device *dev, 144462306a36Sopenharmony_ci unsigned int nbits, gfp_t flags) 144562306a36Sopenharmony_ci{ 144662306a36Sopenharmony_ci return devm_bitmap_alloc(dev, nbits, flags | __GFP_ZERO); 144762306a36Sopenharmony_ci} 144862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(devm_bitmap_zalloc); 144962306a36Sopenharmony_ci 145062306a36Sopenharmony_ci#if BITS_PER_LONG == 64 145162306a36Sopenharmony_ci/** 145262306a36Sopenharmony_ci * bitmap_from_arr32 - copy the contents of u32 array of bits to bitmap 145362306a36Sopenharmony_ci * @bitmap: array of unsigned longs, the destination bitmap 145462306a36Sopenharmony_ci * @buf: array of u32 (in host byte order), the source bitmap 145562306a36Sopenharmony_ci * @nbits: number of bits in @bitmap 145662306a36Sopenharmony_ci */ 145762306a36Sopenharmony_civoid bitmap_from_arr32(unsigned long *bitmap, const u32 *buf, unsigned int nbits) 145862306a36Sopenharmony_ci{ 145962306a36Sopenharmony_ci unsigned int i, halfwords; 146062306a36Sopenharmony_ci 146162306a36Sopenharmony_ci halfwords = DIV_ROUND_UP(nbits, 32); 146262306a36Sopenharmony_ci for (i = 0; i < halfwords; i++) { 146362306a36Sopenharmony_ci bitmap[i/2] = (unsigned long) buf[i]; 146462306a36Sopenharmony_ci if (++i < halfwords) 146562306a36Sopenharmony_ci bitmap[i/2] |= ((unsigned long) buf[i]) << 32; 146662306a36Sopenharmony_ci } 146762306a36Sopenharmony_ci 146862306a36Sopenharmony_ci /* Clear tail bits in last word beyond nbits. */ 146962306a36Sopenharmony_ci if (nbits % BITS_PER_LONG) 147062306a36Sopenharmony_ci bitmap[(halfwords - 1) / 2] &= BITMAP_LAST_WORD_MASK(nbits); 147162306a36Sopenharmony_ci} 147262306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_from_arr32); 147362306a36Sopenharmony_ci 147462306a36Sopenharmony_ci/** 147562306a36Sopenharmony_ci * bitmap_to_arr32 - copy the contents of bitmap to a u32 array of bits 147662306a36Sopenharmony_ci * @buf: array of u32 (in host byte order), the dest bitmap 147762306a36Sopenharmony_ci * @bitmap: array of unsigned longs, the source bitmap 147862306a36Sopenharmony_ci * @nbits: number of bits in @bitmap 147962306a36Sopenharmony_ci */ 148062306a36Sopenharmony_civoid bitmap_to_arr32(u32 *buf, const unsigned long *bitmap, unsigned int nbits) 148162306a36Sopenharmony_ci{ 148262306a36Sopenharmony_ci unsigned int i, halfwords; 148362306a36Sopenharmony_ci 148462306a36Sopenharmony_ci halfwords = DIV_ROUND_UP(nbits, 32); 148562306a36Sopenharmony_ci for (i = 0; i < halfwords; i++) { 148662306a36Sopenharmony_ci buf[i] = (u32) (bitmap[i/2] & UINT_MAX); 148762306a36Sopenharmony_ci if (++i < halfwords) 148862306a36Sopenharmony_ci buf[i] = (u32) (bitmap[i/2] >> 32); 148962306a36Sopenharmony_ci } 149062306a36Sopenharmony_ci 149162306a36Sopenharmony_ci /* Clear tail bits in last element of array beyond nbits. */ 149262306a36Sopenharmony_ci if (nbits % BITS_PER_LONG) 149362306a36Sopenharmony_ci buf[halfwords - 1] &= (u32) (UINT_MAX >> ((-nbits) & 31)); 149462306a36Sopenharmony_ci} 149562306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_to_arr32); 149662306a36Sopenharmony_ci#endif 149762306a36Sopenharmony_ci 149862306a36Sopenharmony_ci#if BITS_PER_LONG == 32 149962306a36Sopenharmony_ci/** 150062306a36Sopenharmony_ci * bitmap_from_arr64 - copy the contents of u64 array of bits to bitmap 150162306a36Sopenharmony_ci * @bitmap: array of unsigned longs, the destination bitmap 150262306a36Sopenharmony_ci * @buf: array of u64 (in host byte order), the source bitmap 150362306a36Sopenharmony_ci * @nbits: number of bits in @bitmap 150462306a36Sopenharmony_ci */ 150562306a36Sopenharmony_civoid bitmap_from_arr64(unsigned long *bitmap, const u64 *buf, unsigned int nbits) 150662306a36Sopenharmony_ci{ 150762306a36Sopenharmony_ci int n; 150862306a36Sopenharmony_ci 150962306a36Sopenharmony_ci for (n = nbits; n > 0; n -= 64) { 151062306a36Sopenharmony_ci u64 val = *buf++; 151162306a36Sopenharmony_ci 151262306a36Sopenharmony_ci *bitmap++ = val; 151362306a36Sopenharmony_ci if (n > 32) 151462306a36Sopenharmony_ci *bitmap++ = val >> 32; 151562306a36Sopenharmony_ci } 151662306a36Sopenharmony_ci 151762306a36Sopenharmony_ci /* 151862306a36Sopenharmony_ci * Clear tail bits in the last word beyond nbits. 151962306a36Sopenharmony_ci * 152062306a36Sopenharmony_ci * Negative index is OK because here we point to the word next 152162306a36Sopenharmony_ci * to the last word of the bitmap, except for nbits == 0, which 152262306a36Sopenharmony_ci * is tested implicitly. 152362306a36Sopenharmony_ci */ 152462306a36Sopenharmony_ci if (nbits % BITS_PER_LONG) 152562306a36Sopenharmony_ci bitmap[-1] &= BITMAP_LAST_WORD_MASK(nbits); 152662306a36Sopenharmony_ci} 152762306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_from_arr64); 152862306a36Sopenharmony_ci 152962306a36Sopenharmony_ci/** 153062306a36Sopenharmony_ci * bitmap_to_arr64 - copy the contents of bitmap to a u64 array of bits 153162306a36Sopenharmony_ci * @buf: array of u64 (in host byte order), the dest bitmap 153262306a36Sopenharmony_ci * @bitmap: array of unsigned longs, the source bitmap 153362306a36Sopenharmony_ci * @nbits: number of bits in @bitmap 153462306a36Sopenharmony_ci */ 153562306a36Sopenharmony_civoid bitmap_to_arr64(u64 *buf, const unsigned long *bitmap, unsigned int nbits) 153662306a36Sopenharmony_ci{ 153762306a36Sopenharmony_ci const unsigned long *end = bitmap + BITS_TO_LONGS(nbits); 153862306a36Sopenharmony_ci 153962306a36Sopenharmony_ci while (bitmap < end) { 154062306a36Sopenharmony_ci *buf = *bitmap++; 154162306a36Sopenharmony_ci if (bitmap < end) 154262306a36Sopenharmony_ci *buf |= (u64)(*bitmap++) << 32; 154362306a36Sopenharmony_ci buf++; 154462306a36Sopenharmony_ci } 154562306a36Sopenharmony_ci 154662306a36Sopenharmony_ci /* Clear tail bits in the last element of array beyond nbits. */ 154762306a36Sopenharmony_ci if (nbits % 64) 154862306a36Sopenharmony_ci buf[-1] &= GENMASK_ULL((nbits - 1) % 64, 0); 154962306a36Sopenharmony_ci} 155062306a36Sopenharmony_ciEXPORT_SYMBOL(bitmap_to_arr64); 155162306a36Sopenharmony_ci#endif 1552