|
|
1.1 root 1: /*
2: * linux/kernel/resource.c
3: *
4: * Copyright (C) 1995 Linus Torvalds
5: * David Hinds
6: *
7: * Kernel io-region resource management
8: */
9:
10: #include <sys/types.h>
11:
12: #define MACH_INCLUDE
13: #include <linux/sched.h>
14: #include <linux/kernel.h>
15: #include <linux/errno.h>
16: #include <linux/types.h>
17: #include <linux/ioport.h>
18:
19: #define IOTABLE_SIZE 128
20:
21: typedef struct resource_entry_t
22: {
23: u_long from, num;
24: const char *name;
25: struct resource_entry_t *next;
26: } resource_entry_t;
27:
28: static resource_entry_t iolist = { 0, 0, "", NULL };
29:
30: static resource_entry_t iotable[IOTABLE_SIZE];
31:
32: /*
33: * This generates the report for /proc/ioports
34: */
35: #ifndef MACH
36: int
37: get_ioport_list (char *buf)
38: {
39: resource_entry_t *p;
40: int len = 0;
41:
42: for (p = iolist.next; (p) && (len < 4000); p = p->next)
43: len += linux_sprintf (buf+len, "%04lx-%04lx : %s\n",
44: p->from, p->from+p->num-1, p->name);
45: if (p)
46: len += linux_sprintf (buf+len, "4K limit reached!\n");
47: return len;
48: }
49: #endif
50:
51: /*
52: * The workhorse function: find where to put a new entry
53: */
54: static resource_entry_t *
55: find_gap (resource_entry_t *root, u_long from, u_long num)
56: {
57: unsigned long flags;
58: resource_entry_t *p;
59:
60: if (from > from+num-1)
61: return NULL;
62: save_flags (flags);
63: cli ();
64: for (p = root; ; p = p->next)
65: {
66: if ((p != root) && (p->from+p->num-1 >= from))
67: {
68: p = NULL;
69: break;
70: }
71: if ((p->next == NULL) || (p->next->from > from+num-1))
72: break;
73: }
74: restore_flags (flags);
75: return p;
76: }
77:
78: /*
79: * Call this from the device driver to register the ioport region.
80: */
81: void
82: request_region (unsigned int from, unsigned int num, const char *name)
83: {
84: resource_entry_t *p;
85: int i;
86:
87: for (i = 0; i < IOTABLE_SIZE; i++)
88: if (iotable[i].num == 0)
89: break;
90: if (i == IOTABLE_SIZE)
91: printk ("warning: ioport table is full\n");
92: else
93: {
94: p = find_gap (&iolist, from, num);
95: if (p == NULL)
96: return;
97: iotable[i].name = name;
98: iotable[i].from = from;
99: iotable[i].num = num;
100: iotable[i].next = p->next;
101: p->next = &iotable[i];
102: return;
103: }
104: }
105:
106: /*
107: * Call this when the device driver is unloaded
108: */
109: void
110: release_region (unsigned int from, unsigned int num)
111: {
112: resource_entry_t *p, *q;
113:
114: for (p = &iolist; ; p = q)
115: {
116: q = p->next;
117: if (q == NULL)
118: break;
119: if ((q->from == from) && (q->num == num))
120: {
121: q->num = 0;
122: p->next = q->next;
123: return;
124: }
125: }
126: }
127:
128: /*
129: * Call this to check the ioport region before probing
130: */
131: int
132: check_region (unsigned int from, unsigned int num)
133: {
134: return (find_gap (&iolist, from, num) == NULL) ? -LINUX_EBUSY : 0;
135: }
136:
137: /* Called from init/main.c to reserve IO ports. */
138: void
139: reserve_setup(char *str, int *ints)
140: {
141: int i;
142:
143: for (i = 1; i < ints[0]; i += 2)
144: request_region (ints[i], ints[i+1], "reserved");
145: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.