home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / lxapi32.zip / Lib32 / lxresource.c < prev    next >
C/C++ Source or Header  |  2002-04-26  |  4KB  |  145 lines

  1. /* $Id: lxresource.c,v 1.2 2002/04/26 23:09:24 smilcke Exp $ */
  2.  
  3. /*
  4.  * resource.c
  5.  * Autor:               Stefan Milcke
  6.  * Erstellt am:         25.10.2001
  7.  * Letzte Aenderung am: 31.12.2001
  8.  *
  9. */
  10.  
  11. #include <linux/types.h>
  12. #include <linux/sched.h>
  13. #include <linux/errno.h>
  14. #include <linux/ioport.h>
  15. #include <linux/init.h>
  16. #include <linux/slab.h>
  17. #include <linux/spinlock.h>
  18. #include <asm/io.h>
  19.  
  20. static rwlock_t resource_lock=RW_LOCK_UNLOCKED;
  21.  
  22. //----------------------------- __request_resource -----------------------------
  23. static struct resource *__request_resource(struct resource *root
  24.                                            ,struct resource *newr)
  25. {
  26.  unsigned long start=newr->start;
  27.  unsigned long end=newr->end;
  28.  struct resource *tmp,**p;
  29.  if(end<start)
  30.   return root;
  31.  if(start<root->start)
  32.   return root;
  33.  if(end>root->end)
  34.   return root;
  35.  p=&root->child;
  36.  for(;;)
  37.  {
  38.   tmp=*p;
  39.   if(!tmp||tmp->start>end)
  40.   {
  41.    newr->sibling=tmp;
  42.    *p=newr;
  43.    newr->parent=root;
  44.    return 0;
  45.   }
  46.   p=&tmp->sibling;
  47.   if(tmp->end<start)
  48.    continue;
  49.   return tmp;
  50.  }
  51. }
  52.  
  53. //----------------------------- __release_resource -----------------------------
  54. static int __release_resource(struct resource *old)
  55. {
  56.  struct resource *tmp,**p;
  57.  p=&old->parent->child;
  58.  for(;;)
  59.  {
  60.   tmp=*p;
  61.   if(!tmp)
  62.    break;
  63.   if(tmp==old)
  64.   {
  65.    *p=tmp->sibling;
  66.    old->parent=0;
  67.    return 0;
  68.   }
  69.   p=&tmp->sibling;
  70.  }
  71.  return -EINVAL;
  72. }
  73.  
  74. //------------------------------ request_resource ------------------------------
  75. int request_resource(struct resource *root,struct resource *newr)
  76. {
  77.  struct resource *conflict;
  78.  write_lock((spinlock_t *)&resource_lock);
  79.  conflict=__request_resource(root,newr);
  80.  write_unlock((spinlock_t *)&resource_lock);
  81.  return conflict ? -EBUSY : 0;
  82. }
  83.  
  84. //------------------------------ release_resource ------------------------------
  85. int release_resource(struct resource *old)
  86. {
  87.  int retval;
  88.  write_lock((spinlock_t *)&resource_lock);
  89.  retval=__release_resource(old);
  90.  write_unlock((spinlock_t *)&resource_lock);
  91.  return retval;
  92. }
  93.  
  94. //------------------------------- find_resource --------------------------------
  95. static int find_resource(struct resource *root,struct resource *newr
  96.                          ,unsigned long size
  97.                          ,unsigned long min,unsigned long max
  98.                          ,unsigned long align
  99.                          ,void (*alignf)(void *,struct resource *,unsigned long)
  100.                          ,void *alignf_data)
  101. {
  102.  struct resource *thisr=root->child;
  103.  newr->start=root->start;
  104.  for(;;)
  105.  {
  106.   if(thisr)
  107.    newr->end=thisr->start;
  108.   else
  109.    newr->end=root->end;
  110.   if(newr->start<min)
  111.    newr->start=min;
  112.   if(newr->end>max)
  113.    newr->end=max;
  114.   newr->start=(newr->start + align-1)&~(align-1);
  115.   if(alignf)
  116.    alignf(alignf_data,newr,size);
  117.   if(newr->start<newr->end && newr->end-newr->start+1>=size)
  118.   {
  119.    newr->end=newr->start+size-1;
  120.    return 0;
  121.   }
  122.   if(!thisr)
  123.    break;
  124.   newr->start=thisr->end+1;
  125.   thisr=thisr->sibling;
  126.  }
  127.  return -EBUSY;
  128. }
  129.  
  130. //----------------------------- allocate_resource ------------------------------
  131. int allocate_resource(struct resource *root,struct resource *newr
  132.                       ,unsigned long size
  133.                       ,unsigned long min,unsigned long max
  134.                       ,unsigned long align
  135.                       ,void (*alignf)(void *,struct resource*,unsigned long)
  136.                       ,void *alignf_data)
  137. {
  138.  int err;
  139.  write_lock((spinlock_t *)&resource_lock);
  140.  err=find_resource(root,newr,size,min,max,align,alignf,alignf_data);
  141.  if(err>=0 && __request_resource(root,newr))
  142.   err=-EBUSY;
  143.  write_unlock((spinlock_t *)&resource_lock);
  144.  return err;
  145. }