|
|
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.