lib/smbios: Improve Type9
[coreboot2.git] / src / device / resource_allocator_common.c
blobfe1aae35e5bb0d5f03f5d77f8974bcaf3cb36a2f
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/device.h>
4 #include <stddef.h>
6 struct pick_largest_state {
7 struct resource *last;
8 const struct device *result_dev;
9 struct resource *result;
10 int seen_last;
13 static void pick_largest_resource(void *gp, struct device *dev,
14 struct resource *resource)
16 struct pick_largest_state *state = gp;
17 struct resource *last;
19 last = state->last;
21 /* Be certain to pick the successor to last. */
22 if (resource == last) {
23 state->seen_last = 1;
24 return;
26 if (resource->flags & IORESOURCE_FIXED)
27 return; /* Skip it. */
28 if (last && ((last->align < resource->align) ||
29 ((last->align == resource->align) &&
30 (last->size < resource->size)) ||
31 ((last->align == resource->align) &&
32 (last->size == resource->size) && (!state->seen_last)))) {
33 return;
35 if (!state->result ||
36 (state->result->align < resource->align) ||
37 ((state->result->align == resource->align) &&
38 (state->result->size < resource->size))) {
39 state->result_dev = dev;
40 state->result = resource;
44 const struct device *largest_resource(struct bus *bus,
45 struct resource **result_res,
46 unsigned long type_mask,
47 unsigned long type)
49 struct pick_largest_state state;
51 state.last = *result_res;
52 state.result_dev = NULL;
53 state.result = NULL;
54 state.seen_last = 0;
56 search_bus_resources(bus, type_mask, type, pick_largest_resource,
57 &state);
59 *result_res = state.result;
60 return state.result_dev;