2 * Copyright IBM Corp. 2007
3 * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
6 #include <linux/vmalloc.h>
7 #include <linux/bitops.h>
14 unsigned long bitmap
[0];
17 static inline unsigned long bitmap_size(int num_ssid
, int num_id
)
19 return __BITOPS_WORDS(num_ssid
* num_id
) * sizeof(unsigned long);
22 static struct idset
*idset_new(int num_ssid
, int num_id
)
26 set
= vmalloc(sizeof(struct idset
) + bitmap_size(num_ssid
, num_id
));
28 set
->num_ssid
= num_ssid
;
30 memset(set
->bitmap
, 0, bitmap_size(num_ssid
, num_id
));
35 void idset_free(struct idset
*set
)
40 void idset_clear(struct idset
*set
)
42 memset(set
->bitmap
, 0, bitmap_size(set
->num_ssid
, set
->num_id
));
45 void idset_fill(struct idset
*set
)
47 memset(set
->bitmap
, 0xff, bitmap_size(set
->num_ssid
, set
->num_id
));
50 static inline void idset_add(struct idset
*set
, int ssid
, int id
)
52 set_bit(ssid
* set
->num_id
+ id
, set
->bitmap
);
55 static inline void idset_del(struct idset
*set
, int ssid
, int id
)
57 clear_bit(ssid
* set
->num_id
+ id
, set
->bitmap
);
60 static inline int idset_contains(struct idset
*set
, int ssid
, int id
)
62 return test_bit(ssid
* set
->num_id
+ id
, set
->bitmap
);
65 static inline int idset_get_first(struct idset
*set
, int *ssid
, int *id
)
69 bitnum
= find_first_bit(set
->bitmap
, set
->num_ssid
* set
->num_id
);
70 if (bitnum
>= set
->num_ssid
* set
->num_id
)
72 *ssid
= bitnum
/ set
->num_id
;
73 *id
= bitnum
% set
->num_id
;
77 struct idset
*idset_sch_new(void)
79 return idset_new(max_ssid
+ 1, __MAX_SUBCHANNEL
+ 1);
82 void idset_sch_add(struct idset
*set
, struct subchannel_id schid
)
84 idset_add(set
, schid
.ssid
, schid
.sch_no
);
87 void idset_sch_del(struct idset
*set
, struct subchannel_id schid
)
89 idset_del(set
, schid
.ssid
, schid
.sch_no
);
92 int idset_sch_contains(struct idset
*set
, struct subchannel_id schid
)
94 return idset_contains(set
, schid
.ssid
, schid
.sch_no
);
97 int idset_sch_get_first(struct idset
*set
, struct subchannel_id
*schid
)
103 rc
= idset_get_first(set
, &ssid
, &id
);
105 init_subchannel_id(schid
);
112 int idset_is_empty(struct idset
*set
)
116 bitnum
= find_first_bit(set
->bitmap
, set
->num_ssid
* set
->num_id
);
117 if (bitnum
>= set
->num_ssid
* set
->num_id
)
122 void idset_add_set(struct idset
*to
, struct idset
*from
)
124 unsigned long i
, len
;
126 len
= min(__BITOPS_WORDS(to
->num_ssid
* to
->num_id
),
127 __BITOPS_WORDS(from
->num_ssid
* from
->num_id
));
128 for (i
= 0; i
< len
; i
++)
129 to
->bitmap
[i
] |= from
->bitmap
[i
];