revert between 56095 -> 55830 in arch
[AROS.git] / arch / m68k-amiga / hidd / pci-mediator / pci_resource.c
blobcf45c8dcf25f6aa84449445b37d81faba2e30741
1 /*
2 * Copyright (C) 2012, The AROS Development Team
3 * All right reserved.
4 * Author: Jason S. McMullan <jason.mcmullan@gmail.com>
6 * Licensed under the AROS PUBLIC LICENSE (APL) Version 1.1
7 */
9 #include <proto/exec.h>
11 #include "pci_resource.h"
13 struct MinList *CreatePCIResourceList(IPTR start, IPTR size)
15 struct MinList *ml;
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);
25 return ml;
27 FreeMem(node, sizeof(*node));
30 return NULL;
33 /* Dispose of a resource list */
34 VOID DeletePCIResourceList(struct MinList *reslist)
36 struct PCIResource *node;
37 struct Node *tmp;
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;
57 IPTR alloc = ~0;
58 IPTR start, end;
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) {
65 alloc = start;
66 break;
70 if (alloc == ~0)
71 return alloc;
73 if (node->pr_Start == start && end == node->pr_End) {
74 /* Delete the node */
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;
80 /* Split the node? */
81 tmp = AllocMem(sizeof(*tmp), MEMF_ANY);
82 if (tmp == NULL)
83 return ~0;
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) {
94 /* Trim from end? */
95 node->pr_End = start - 1;
98 return alloc;