|
|
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 <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 128 ! 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: * This generates the report for /proc/ioports ! 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: * The workhorse function: find where to put a new entry ! 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: * Call this from the device driver to register the ioport region. ! 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: * Call this when the device driver is unloaded ! 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: * Call this to check the ioport region before probing ! 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: /* Called from init/main.c to reserve IO ports. */ ! 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.