1 // SPDX-License-Identifier: GPL-2.0
3 * Range add and subtract
5 #include <linux/init.h>
6 #include <linux/minmax.h>
7 #include <linux/printk.h>
8 #include <linux/sort.h>
9 #include <linux/string.h>
10 #include <linux/range.h>
12 int add_range(struct range
*range
, int az
, int nr_range
, u64 start
, u64 end
)
21 range
[nr_range
].start
= start
;
22 range
[nr_range
].end
= end
;
29 int add_range_with_merge(struct range
*range
, int az
, int nr_range
,
37 /* get new start/end: */
38 for (i
= 0; i
< nr_range
; i
++) {
39 u64 common_start
, common_end
;
44 common_start
= max(range
[i
].start
, start
);
45 common_end
= min(range
[i
].end
, end
);
46 if (common_start
> common_end
)
49 /* new start/end, will add it back at last */
50 start
= min(range
[i
].start
, start
);
51 end
= max(range
[i
].end
, end
);
53 memmove(&range
[i
], &range
[i
+ 1],
54 (nr_range
- (i
+ 1)) * sizeof(range
[i
]));
55 range
[nr_range
- 1].start
= 0;
56 range
[nr_range
- 1].end
= 0;
62 return add_range(range
, az
, nr_range
, start
, end
);
65 void subtract_range(struct range
*range
, int az
, u64 start
, u64 end
)
72 for (j
= 0; j
< az
; j
++) {
76 if (start
<= range
[j
].start
&& end
>= range
[j
].end
) {
82 if (start
<= range
[j
].start
&& end
< range
[j
].end
&&
83 range
[j
].start
< end
) {
89 if (start
> range
[j
].start
&& end
>= range
[j
].end
&&
90 range
[j
].end
> start
) {
95 if (start
> range
[j
].start
&& end
< range
[j
].end
) {
96 /* Find the new spare: */
97 for (i
= 0; i
< az
; i
++) {
98 if (range
[i
].end
== 0)
102 range
[i
].end
= range
[j
].end
;
103 range
[i
].start
= end
;
105 pr_err("%s: run out of slot in ranges\n",
108 range
[j
].end
= start
;
114 static int cmp_range(const void *x1
, const void *x2
)
116 const struct range
*r1
= x1
;
117 const struct range
*r2
= x2
;
119 if (r1
->start
< r2
->start
)
121 if (r1
->start
> r2
->start
)
126 int clean_sort_range(struct range
*range
, int az
)
128 int i
, j
, k
= az
- 1, nr_range
= az
;
130 for (i
= 0; i
< k
; i
++) {
133 for (j
= k
; j
> i
; j
--) {
141 range
[i
].start
= range
[k
].start
;
142 range
[i
].end
= range
[k
].end
;
148 for (i
= 0; i
< az
; i
++) {
156 sort(range
, nr_range
, sizeof(struct range
), cmp_range
, NULL
);
161 void sort_range(struct range
*range
, int nr_range
)
164 sort(range
, nr_range
, sizeof(struct range
), cmp_range
, NULL
);