1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36#include <linux/init.h>
37#include <linux/slab.h>
38#include <linux/errno.h>
39
40#include "c2.h"
41#include "c2_provider.h"
42
43int c2_pd_alloc(struct c2_dev *c2dev, int privileged, struct c2_pd *pd)
44{
45 u32 obj;
46 int ret = 0;
47
48 spin_lock(&c2dev->pd_table.lock);
49 obj = find_next_zero_bit(c2dev->pd_table.table, c2dev->pd_table.max,
50 c2dev->pd_table.last);
51 if (obj >= c2dev->pd_table.max)
52 obj = find_first_zero_bit(c2dev->pd_table.table,
53 c2dev->pd_table.max);
54 if (obj < c2dev->pd_table.max) {
55 pd->pd_id = obj;
56 __set_bit(obj, c2dev->pd_table.table);
57 c2dev->pd_table.last = obj+1;
58 if (c2dev->pd_table.last >= c2dev->pd_table.max)
59 c2dev->pd_table.last = 0;
60 } else
61 ret = -ENOMEM;
62 spin_unlock(&c2dev->pd_table.lock);
63 return ret;
64}
65
66void c2_pd_free(struct c2_dev *c2dev, struct c2_pd *pd)
67{
68 spin_lock(&c2dev->pd_table.lock);
69 __clear_bit(pd->pd_id, c2dev->pd_table.table);
70 spin_unlock(&c2dev->pd_table.lock);
71}
72
73int c2_init_pd_table(struct c2_dev *c2dev)
74{
75
76 c2dev->pd_table.last = 0;
77 c2dev->pd_table.max = c2dev->props.max_pd;
78 spin_lock_init(&c2dev->pd_table.lock);
79 c2dev->pd_table.table = kmalloc(BITS_TO_LONGS(c2dev->props.max_pd) *
80 sizeof(long), GFP_KERNEL);
81 if (!c2dev->pd_table.table)
82 return -ENOMEM;
83 bitmap_zero(c2dev->pd_table.table, c2dev->props.max_pd);
84 return 0;
85}
86
87void c2_cleanup_pd_table(struct c2_dev *c2dev)
88{
89 kfree(c2dev->pd_table.table);
90}
91