00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <agnix/agnix.h>
00015 #include <agnix/adi/adi.h>
00016 #include <agnix/list.h>
00017 #include <agnix/spinlock.h>
00018 #include <agnix/console.h>
00019
00020 #define MOD_NAME "ADI: "
00021 #define MAX_GLOBAL_RESOURCES 16
00022
00023 LIST_HEAD(adi_resources_mem_list);
00024 spinlock_t adi_resources_mem_lock;
00025
00026 LIST_HEAD(adi_resources_io_list);
00027 spinlock_t adi_resources_io_lock;
00028
00029 struct adi_resource_s global_io_resources[MAX_GLOBAL_RESOURCES] = {
00030 { "dma", 0x00, 0x1f, ADI_RES_FLAG_IO },
00031 { "pic", 0x20, 0x3f, ADI_RES_FLAG_IO },
00032 { "pit", 0x40, 0x5f, ADI_RES_FLAG_IO },
00033 { "kbd", 0x60, 0x6f, ADI_RES_FLAG_IO },
00034 { "dma page", 0x80, 0x8f, ADI_RES_FLAG_IO },
00035 { "pic2", 0xa0, 0xbf, ADI_RES_FLAG_IO },
00036 { "dma2", 0xc0, 0xdf, ADI_RES_FLAG_IO },
00037 { NULL, }
00038 };
00039
00040 int adi_register_resource(struct adi_resource_s *adi_resource)
00041 {
00042 struct list_head *tmp;
00043 struct list_head *res_head;
00044 struct adi_resource_s *res;
00045 int ret = 0;
00046 spinlock_t *res_lock;
00047 u32 flags;
00048
00049 if ((adi_resource->res_end - adi_resource->res_start) == 0) {
00050 printk(MOD_NAME "zero size resource adding probe\n");
00051 return -1;
00052 }
00053
00054 if (adi_resource->res_flags & ADI_RES_FLAG_MEM) {
00055 res_head = &adi_resources_mem_list;
00056 res_lock = &adi_resources_mem_lock;
00057 } else {
00058 res_head = &adi_resources_io_list;
00059 res_lock = &adi_resources_io_lock;
00060 }
00061
00062 spin_lock_irqsave(res_lock, flags);
00063
00064 if (!list_empty(res_head)) {
00065 list_for_each(tmp, res_head) {
00066 res = list_entry(tmp, struct adi_resource_s, res_list);
00067
00068 if ((res->res_start > adi_resource->res_start) && (res->res_start <= adi_resource->res_end)) {
00069 ret = -1;
00070 goto register_end;
00071 }
00072 if ((res->res_end >= adi_resource->res_start) && (res->res_end < adi_resource->res_end)) {
00073 ret = -1;
00074 goto register_end;
00075 }
00076
00077 if (res->res_start > adi_resource->res_end) {
00078 __list_add(&adi_resource->res_list, res->res_list.prev, &res->res_list);
00079 ret = 0;
00080 goto register_end;
00081 }
00082 }
00083 } else {
00084 list_add(&(adi_resource->res_list), res_head);
00085 ret = 0;
00086 goto register_end;
00087 }
00088
00089 list_add_tail(&(adi_resource->res_list), res_head);
00090
00091 register_end:
00092 spin_unlock_irqrestore(res_lock, flags);
00093
00094 return ret;
00095 }
00096
00097 int adi_unregister_resource(struct adi_resource_s *adi_resource)
00098 {
00099 return 0;
00100 }
00101
00102 int adi_check_resource(struct adi_resource_s *adi_resource)
00103 {
00104 return 0;
00105 }
00106
00107 int adi_print_resources(int res_flags_mask)
00108 {
00109 struct list_head *tmp;
00110 struct list_head *res_head;
00111 struct adi_resource_s *res;
00112 spinlock_t *res_lock;
00113 u32 flags;
00114
00115 if (res_flags_mask & ADI_RES_FLAG_MEM) {
00116 res_head = &adi_resources_mem_list;
00117 res_lock = &adi_resources_mem_lock;
00118 printk(MOD_NAME "ADI memory resources: \n");
00119 } else {
00120 res_head = &adi_resources_io_list;
00121 res_lock = &adi_resources_io_lock;
00122 printk(MOD_NAME "ADI io resources: \n");
00123 }
00124
00125 spin_lock_irqsave(res_lock, flags);
00126
00127 list_for_each(tmp, res_head) {
00128 res = list_entry(tmp, struct adi_resource_s, res_list);
00129
00130 if (res_flags_mask & ADI_RES_FLAG_MEM)
00131 printk(MOD_NAME "%08x-%08x %s\n", res->res_start, res->res_end, res->res_name);
00132 else
00133 printk(MOD_NAME "%04x-%04x %s\n", res->res_start, res->res_end, res->res_name);
00134 }
00135
00136 spin_unlock_irqrestore(res_lock, flags);
00137
00138 return 0;
00139 }
00140
00141 int adi_print_mem_resources(void)
00142 {
00143 return adi_print_resources(ADI_RES_FLAG_MEM);
00144 }
00145
00146 int adi_print_io_resources(void)
00147 {
00148 return adi_print_resources(ADI_RES_FLAG_IO);
00149 }
00150
00151 int adi_register_global_resources(void)
00152 {
00153 int i = 0;
00154 int ret;
00155
00156 while (global_io_resources[i].res_name != NULL) {
00157 ret = adi_register_resource(&global_io_resources[i]);
00158 if (ret < 0)
00159 return ret;
00160
00161 i++;
00162 }
00163
00164 return 0;
00165 }
00166
00167 int adi_resources_init(void)
00168 {
00169 printk(MOD_NAME "initializing adi resources\n");
00170
00171 spin_lock_init(&adi_resources_io_lock);
00172 spin_lock_init(&adi_resources_mem_lock);
00173
00174 adi_register_global_resources();
00175
00176 return 0;
00177 }