2 * Copyright IBM Corp. 2007, 2012
3 * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
6 #include <linux/vmalloc.h>
7 #include <linux/bitmap.h>
8 #include <linux/bitops.h>
15 unsigned long bitmap
[0];
18 static inline unsigned long bitmap_size(int num_ssid
, int num_id
)
20 return BITS_TO_LONGS(num_ssid
* num_id
) * sizeof(unsigned long);
23 static struct idset
*idset_new(int num_ssid
, int num_id
)
27 set
= vmalloc(sizeof(struct idset
) + bitmap_size(num_ssid
, num_id
));
29 set
->num_ssid
= num_ssid
;
31 memset(set
->bitmap
, 0, bitmap_size(num_ssid
, num_id
));
36 void idset_free(struct idset
*set
)
41 void idset_fill(struct idset
*set
)
43 memset(set
->bitmap
, 0xff, bitmap_size(set
->num_ssid
, set
->num_id
));
46 static inline void idset_add(struct idset
*set
, int ssid
, int id
)
48 set_bit(ssid
* set
->num_id
+ id
, set
->bitmap
);
51 static inline void idset_del(struct idset
*set
, int ssid
, int id
)
53 clear_bit(ssid
* set
->num_id
+ id
, set
->bitmap
);
56 static inline int idset_contains(struct idset
*set
, int ssid
, int id
)
58 return test_bit(ssid
* set
->num_id
+ id
, set
->bitmap
);
61 static inline int idset_get_first(struct idset
*set
, int *ssid
, int *id
)
65 bitnum
= find_first_bit(set
->bitmap
, set
->num_ssid
* set
->num_id
);
66 if (bitnum
>= set
->num_ssid
* set
->num_id
)
68 *ssid
= bitnum
/ set
->num_id
;
69 *id
= bitnum
% set
->num_id
;
73 struct idset
*idset_sch_new(void)
75 return idset_new(max_ssid
+ 1, __MAX_SUBCHANNEL
+ 1);
78 void idset_sch_add(struct idset
*set
, struct subchannel_id schid
)
80 idset_add(set
, schid
.ssid
, schid
.sch_no
);
83 void idset_sch_del(struct idset
*set
, struct subchannel_id schid
)
85 idset_del(set
, schid
.ssid
, schid
.sch_no
);
88 /* Clear ids starting from @schid up to end of subchannel set. */
89 void idset_sch_del_subseq(struct idset
*set
, struct subchannel_id schid
)
91 int pos
= schid
.ssid
* set
->num_id
+ schid
.sch_no
;
93 bitmap_clear(set
->bitmap
, pos
, set
->num_id
- schid
.sch_no
);
96 int idset_sch_contains(struct idset
*set
, struct subchannel_id schid
)
98 return idset_contains(set
, schid
.ssid
, schid
.sch_no
);
101 int idset_is_empty(struct idset
*set
)
103 return bitmap_empty(set
->bitmap
, set
->num_ssid
* set
->num_id
);
106 void idset_add_set(struct idset
*to
, struct idset
*from
)
108 int len
= min(to
->num_ssid
* to
->num_id
, from
->num_ssid
* from
->num_id
);
110 bitmap_or(to
->bitmap
, to
->bitmap
, from
->bitmap
, len
);