linux-old/kernel/resource.c
<<
>>
Prefs
   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 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 * This generates the report for /proc/ioports
  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 * The workhorse function: find where to put a new entry
  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 * Call this from the device driver to register the ioport region.
  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 * This is for compatibility with older drivers.
  97 * It can be removed when all drivers call the new function.
  98 */
  99void snarf_region(unsigned int from, unsigned int num)
 100{
 101        request_region(from,num,"No name given.");
 102}
 103
 104/* 
 105 * Call this when the device driver is unloaded
 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 * Call this to check the ioport region before probing
 125 */
 126int check_region(unsigned int from, unsigned int num)
 127{
 128        return (find_gap(&iolist, from, num) == NULL) ? -EBUSY : 0;
 129}
 130
 131/* Called from init/main.c to reserve IO ports. */
 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
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.