root/kernel/resource.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_ioport_list
  2. find_gap
  3. request_region
  4. release_region
  5. check_region
  6. reserve_setup

   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 
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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,
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 124 {
 125         int i;
 126 
 127         for (i = 1; i < ints[0]; i += 2)
 128                 request_region(ints[i], ints[i+1], "reserved");
 129 }

/* [previous][next][first][last][top][bottom][index][help] */