2 * Copyright (C) 2012, The AROS Development Team
4 * Author: Jason S. McMullan <jason.mcmullan@gmail.com>
6 * Licensed under the AROS PUBLIC LICENSE (APL) Version 1.1
9 #include <proto/exec.h>
11 #include "pci_resource.h"
13 struct MinList
*CreatePCIResourceList(IPTR start
, IPTR size
)
16 struct PCIResource
*node
;
18 if ((node
= AllocMem(sizeof(*node
), MEMF_ANY
))) {
19 if ((ml
= AllocMem(sizeof(*ml
), MEMF_ANY
))) {
20 NEWLIST((struct List
*)ml
);
22 node
->pr_Start
= start
;
23 node
->pr_End
= start
+ size
- 1;
24 AddTail((struct List
*)ml
, (struct Node
*)node
);
27 FreeMem(node
, sizeof(*node
));
33 /* Dispose of a resource list */
34 VOID
DeletePCIResourceList(struct MinList
*reslist
)
36 struct PCIResource
*node
;
39 ForeachNodeSafe((struct List
*)reslist
, node
, tmp
) {
40 FreeMem(node
, sizeof(*node
));
43 FreeMem(reslist
, sizeof(*reslist
));
46 /* Allocates some size aligned space from the resource
47 * list. Modifies the list (by removing the allocated chunk),
48 * and returns the new start.
50 * 'size' must be a power of 2!
52 * Returns ~0 if no allocation was available.
54 IPTR
AllocPCIResource(struct MinList
*reslist
, IPTR size
)
56 struct PCIResource
*node
;
60 ForeachNode((struct List
*)reslist
, node
) {
61 /* Aligned start to size */
62 start
= (node
->pr_Start
+ size
- 1) & ~(size
- 1);
63 end
= start
+ size
- 1;
64 if (end
<= node
->pr_End
) {
73 if (node
->pr_Start
== start
&& end
== node
->pr_End
) {
75 Remove((struct Node
*)node
);
76 FreeMem(node
, sizeof(*node
));
77 } else if (node
->pr_Start
< start
&& end
< node
->pr_End
) {
78 struct PCIResource
*tmp
;
81 tmp
= AllocMem(sizeof(*tmp
), MEMF_ANY
);
85 tmp
->pr_Start
= end
+ 1;
86 tmp
->pr_End
= node
->pr_End
;
88 node
->pr_End
= start
- 1;
89 Insert((struct List
*)reslist
, (struct Node
*)tmp
, (struct Node
*)node
);
90 } else if (start
== node
->pr_Start
) {
91 /* Trim from front? */
92 node
->pr_Start
= end
+ 1;
93 } else if (end
== node
->pr_End
) {
95 node
->pr_End
= start
- 1;