00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <agnix/agnix.h>
00015 #include <asm/bitops.h>
00016 #include <agnix/resources.h>
00017 #include <agnix/spinlock.h>
00018 #include <agnix/memory.h>
00019 #include <agnix/console.h>
00020 #include <asm/cpu_ops.h>
00021
00022 #define MOD_NAME "RES: "
00023 #define GLOBAL_RESOURCE_LEN 64
00024 #define GLOBAL_RESOURCE_DESC 0
00025
00026 #define RESOURCES_DEBUG 0
00027
00028 struct resource_s *resources[GLOBAL_RESOURCE_LEN];
00029
00030 u32 global_resource_bitmap[(GLOBAL_RESOURCE_LEN << 5) + 1];
00031
00032 struct resource_s global_resource = {
00033 .resource_name = "global",
00034 .resource_bitmap = global_resource_bitmap,
00035 .resource_len = GLOBAL_RESOURCE_LEN,
00036 };
00037
00038 int get_free_resource(int resource_desc)
00039 {
00040 struct resource_s * resource = resources[resource_desc];
00041 u32 *bitmap;
00042 int bitmap_len;
00043 int zero_bit;
00044 u32 flags;
00045
00046 bitmap = resource->resource_bitmap;
00047 bitmap_len = resource->resource_len << 5;
00048
00049 spin_lock_irqsave(&resource->resource_lock, flags);
00050 if ((zero_bit = find_first_zero_bit(bitmap, bitmap_len)) < bitmap_len)
00051 set_bit(zero_bit, bitmap);
00052 else
00053 zero_bit = -1;
00054
00055 spin_unlock_irqrestore(&resource->resource_lock, flags);
00056
00057 return zero_bit;
00058 }
00059
00060 int put_free_resource(int resource_desc, int resource_bit)
00061 {
00062 struct resource_s * resource = resources[resource_desc];
00063 u32 *bitmap;
00064 u32 flags;
00065 int ret = 0;
00066
00067 if (resource == NULL) {
00068 printk(MOD_NAME "resource is NULL\n");
00069 return -1;
00070 }
00071
00072 bitmap = resource->resource_bitmap;
00073
00074 spin_lock_irqsave(&resource->resource_lock, flags);
00075 if (!test_and_clear_bit(resource_bit, bitmap)) {
00076 printk(MOD_NAME "there is zero bit on %d position in a queue_bitmap", resource_bit);
00077 ret = -1;
00078 }
00079 spin_unlock_irqrestore(&resource->resource_lock, flags);
00080
00081 return ret;
00082 }
00083
00084 int request_resource(int resource_desc, int resource_bit)
00085 {
00086 struct resource_s * resource = resources[resource_desc];
00087 u32 *bitmap;
00088 int bitmap_len;
00089 int ret;
00090 u32 flags;
00091
00092 if (resource == NULL) {
00093 printk(MOD_NAME "resource is NULL\n");
00094 return -1;
00095 }
00096
00097 bitmap = resource->resource_bitmap;
00098 bitmap_len = resource->resource_len << 5;
00099
00100 spin_lock_irqsave(&resource->resource_lock, flags);
00101 if (!test_and_set_bit(resource_bit, bitmap))
00102 {
00103 printk(MOD_NAME "%s requesting %d resource\n", resource->resource_name, resource_bit);
00104 ret = 0;
00105 } else {
00106 printk(MOD_NAME "%s resource %d is busy\n", resource->resource_name, resource_bit);
00107 ret = -1;
00108 }
00109
00110 spin_unlock_irqrestore(&resource->resource_lock, flags);
00111
00112 return ret;
00113 }
00114
00115 int register_resource(struct resource_s *resource)
00116 {
00117 int resource_desc;
00118
00119 #if RESOURCES_DEBUG
00120 printk(MOD_NAME "Registering %s resource\n", resource->resource_name);
00121 #endif
00122
00123 resource_desc = get_free_resource(GLOBAL_RESOURCE_DESC);
00124 resources[resource_desc] = resource;
00125 memset(resource->resource_bitmap, 0, resource->resource_len);
00126
00127 return resource_desc;
00128 }
00129
00130 void unregister_resource(int resource_desc)
00131 {
00132 }
00133
00134 int resources_init(void)
00135 {
00136 int i;
00137
00138 printk(MOD_NAME "Initializing %s resource\n", global_resource.resource_name);
00139
00140 spin_lock_init(&global_resource.resource_lock);
00141
00142
00143 for (i = 0; i < GLOBAL_RESOURCE_LEN; i++) {
00144 resources[i] = NULL;
00145 }
00146 resources[GLOBAL_RESOURCE_DESC] = &global_resource;
00147 set_bit(GLOBAL_RESOURCE_DESC, global_resource_bitmap);
00148
00149 return 0;
00150 }