This source file includes following definitions.
- get_ioport_list
- find_gap
- request_region
- release_region
- check_region
- reserve_setup
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
18 typedef struct resource_entry_t {
19 u_long from, num;
20 const char *name;
21 struct resource_entry_t *next;
22 } resource_entry_t;
23
24 static resource_entry_t iolist = { 0, 0, "", NULL };
25
26 static resource_entry_t iotable[IOTABLE_SIZE];
27
28
29
30
31 int 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
47 static 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
72 void 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 void release_region(unsigned int from, unsigned int num)
99 {
100 resource_entry_t *p, *q;
101
102 for (p = &iolist; ; p = q) {
103 q = p->next;
104 if (q == NULL)
105 break;
106 if ((q->from == from) && (q->num == num)) {
107 q->num = 0;
108 p->next = q->next;
109 return;
110 }
111 }
112 }
113
114
115
116
117 int check_region(unsigned int from, unsigned int num)
118 {
119 return (find_gap(&iolist, from, num) == NULL) ? -EBUSY : 0;
120 }
121
122
123 void reserve_setup(char *str, int *ints)
124 {
125 int i;
126
127 for (i = 1; i < ints[0]; i += 2)
128 request_region(ints[i], ints[i+1], "reserved");
129 }