1 // SPDX-License-Identifier: GPL-2.0+
2 // Copyright 2017 IBM Corp.
3 #include "ocxl_internal.h"
13 static void dump_list(struct list_head
*head
, char *type_str
)
17 pr_debug("%s ranges allocated:\n", type_str
);
18 list_for_each_entry(cur
, head
, list
) {
19 pr_debug("Range %d->%d\n", cur
->start
, cur
->end
);
24 static int range_alloc(struct list_head
*head
, u32 size
, int max_id
,
27 struct list_head
*pos
;
28 struct id_range
*cur
, *new;
31 new = kmalloc(sizeof(struct id_range
), GFP_KERNEL
);
37 list_for_each_entry(cur
, head
, list
) {
38 if ((cur
->start
- last_end
) > size
)
44 new->start
= last_end
+ 1;
45 new->end
= new->start
+ size
- 1;
47 if (new->end
> max_id
) {
51 list_add(&new->list
, pos
);
56 dump_list(head
, type_str
);
61 static void range_free(struct list_head
*head
, u32 start
, u32 size
,
65 struct id_range
*cur
, *tmp
;
67 list_for_each_entry_safe(cur
, tmp
, head
, list
) {
68 if (cur
->start
== start
&& cur
->end
== (start
+ size
- 1)) {
77 dump_list(head
, type_str
);
81 int ocxl_pasid_afu_alloc(struct ocxl_fn
*fn
, u32 size
)
85 if (fn
->config
.max_pasid_log
< 0)
87 max_pasid
= 1 << fn
->config
.max_pasid_log
;
88 return range_alloc(&fn
->pasid_list
, size
, max_pasid
, "afu pasid");
91 void ocxl_pasid_afu_free(struct ocxl_fn
*fn
, u32 start
, u32 size
)
93 return range_free(&fn
->pasid_list
, start
, size
, "afu pasid");
96 int ocxl_actag_afu_alloc(struct ocxl_fn
*fn
, u32 size
)
100 max_actag
= fn
->actag_enabled
;
101 return range_alloc(&fn
->actag_list
, size
, max_actag
, "afu actag");
104 void ocxl_actag_afu_free(struct ocxl_fn
*fn
, u32 start
, u32 size
)
106 return range_free(&fn
->actag_list
, start
, size
, "afu actag");