home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / kernel / resource.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-13  |  2.7 KB  |  139 lines

  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 32
  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.  * This is for compatibility with older drivers.
  97.  * It can be removed when all drivers call the new function.
  98.  */
  99. void 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.  */
  107. void 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.  */
  126. int 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. */
  132. void 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.