1
2
3
4
5
6
7
8
9
10#include <linux/sched.h>
11#include <linux/kernel.h>
12#include <linux/errno.h>
13#include <linux/types.h>
14#include <linux/ioport.h>
15
16#define IOTABLE_SIZE 64
17
18typedef struct resource_entry_t {
19 u_long from, num;
20 const char *name;
21 struct resource_entry_t *next;
22} resource_entry_t;
23
24static resource_entry_t iolist = { 0, 0, "", NULL };
25
26static resource_entry_t iotable[IOTABLE_SIZE];
27
28
29
30
31int get_ioport_list(char *buf)
32{
33 resource_entry_t *p;
34 int len = 0;
35
36 for (p = iolist.next; (p) && (len < 4000); p = p->next)
37 len += sprintf(buf+len, "%04lx-%04lx : %s\n",
38 p->from, p->from+p->num-1, p->name);
39 if (p)
40 len += sprintf(buf+len, "4K limit reached!\n");
41 return len;
42}
43
44
45
46
47static resource_entry_t *find_gap(resource_entry_t *root,
48 u_long from, u_long num)
49{
50 unsigned long flags;
51 resource_entry_t *p;
52
53 if (from > from+num-1)
54 return NULL;
55 save_flags(flags);
56 cli();
57 for (p = root; ; p = p->next) {
58 if ((p != root) && (p->from+p->num-1 >= from)) {
59 p = NULL;
60 break;
61 }
62 if ((p->next == NULL) || (p->next->from > from+num-1))
63 break;
64 }
65 restore_flags(flags);
66 return p;
67}
68
69
70
71
72void request_region(unsigned int from, unsigned int num, const char *name)
73{
74 resource_entry_t *p;
75 int i;
76
77 for (i = 0; i < IOTABLE_SIZE; i++)
78 if (iotable[i].num == 0)
79 break;
80 if (i == IOTABLE_SIZE)
81 printk("warning: ioport table is full\n");
82 else {
83 p = find_gap(&iolist, from, num);
84 if (p == NULL)
85 return;
86 iotable[i].name = name;
87 iotable[i].from = from;
88 iotable[i].num = num;
89 iotable[i].next = p->next;
90 p->next = &iotable[i];
91 return;
92 }
93}
94
95
96
97
98
99void snarf_region(unsigned int from, unsigned int num)
100{
101 request_region(from,num,"No name given.");
102}
103
104
105
106
107void release_region(unsigned int from, unsigned int num)
108{
109 resource_entry_t *p, *q;
110
111 for (p = &iolist; ; p = q) {
112 q = p->next;
113 if (q == NULL)
114 break;
115 if ((q->from == from) && (q->num == num)) {
116 q->num = 0;
117 p->next = q->next;
118 return;
119 }
120 }
121}
122
123
124
125
126int check_region(unsigned int from, unsigned int num)
127{
128 return (find_gap(&iolist, from, num) == NULL) ? -EBUSY : 0;
129}
130
131
132void reserve_setup(char *str, int *ints)
133{
134 int i;
135
136 for (i = 1; i < ints[0]; i += 2)
137 request_region(ints[i], ints[i+1], "reserved");
138}
139