00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <agnix/agnix.h>
00015 #include <agnix/memory.h>
00016 #include <agnix/queues.h>
00017 #include <agnix/spinlock.h>
00018 #include <agnix/resources.h>
00019 #include <agnix/console.h>
00020 #include <asm/cpu_ops.h>
00021
00022 #define QUEUES_DEBUG 0
00023 #define MOD_NAME "QUEUES: "
00024
00025 struct queue_type_s *queue_types[MAX_QUEUE_TYPES];
00026 struct queue_s queues[MAX_QUEUES];
00027
00028 u32 queue_bitmap[QUEUE_BITMAP_LEN];
00029
00030 int queues_resource_desc;
00031 struct resource_s queues_resource = {
00032 .resource_name = "queues",
00033 .resource_bitmap = queue_bitmap,
00034 .resource_len = QUEUE_BITMAP_LEN,
00035 };
00036
00037 int queue_enqueue(int queue_desc, struct queue_entry_s *queue_entry)
00038 {
00039 struct queue_s *queue = &queues[queue_desc];
00040 u32 flags;
00041
00042 spin_lock_irqsave(&queue->queue_lock, flags);
00043 queue->queue_ops->enqueue(queue, queue_entry);
00044 spin_unlock_irqrestore(&queue->queue_lock, flags);
00045
00046 return 0;
00047 }
00048
00049 struct queue_entry_s *queue_dequeue(int queue_desc)
00050 {
00051 struct queue_entry_s *queue_entry;
00052 struct queue_s *queue = &queues[queue_desc];
00053 u32 flags;
00054
00055 spin_lock_irqsave(&queue->queue_lock, flags);
00056 queue_entry = queue->queue_ops->dequeue(queue);
00057 spin_unlock_irqrestore(&queue->queue_lock, flags);
00058
00059 return queue_entry;
00060 }
00061
00062 int queue_empty(int queue_desc)
00063 {
00064 struct queue_s *queue = &queues[queue_desc];
00065 int empty;
00066 u32 flags;
00067
00068 spin_lock_irqsave(&queue->queue_lock, flags);
00069 empty = list_empty(&queue->queue_list);
00070 spin_unlock_irqrestore(&queue->queue_lock, flags);
00071
00072 return empty;
00073 }
00074
00075 void queue_free(int queue_desc)
00076 {
00077 struct queue_s *queue = &queues[queue_desc];
00078 u32 flags;
00079
00080 spin_lock_irqsave(&queue->queue_lock, flags);
00081 INIT_LIST_HEAD(&queue->queue_list);
00082 spin_unlock_irqrestore(&queue->queue_lock, flags);
00083 }
00084
00085 int put_free_queue(int queue_desc)
00086 {
00087 return put_free_resource(queues_resource_desc, queue_desc);
00088 }
00089
00090 int get_free_queue(void)
00091 {
00092 return get_free_resource(queues_resource_desc);
00093 }
00094
00095 int register_queue(int queue_type, const char *queue_name)
00096 {
00097 struct queue_s *queue;
00098 int queue_desc = 0;
00099
00100 if (queue_types[queue_type] == NULL) {
00101 printk(MOD_NAME "queue type %d not registered...\n", queue_type);
00102 return -1;
00103 }
00104
00105 if ((queue_desc = get_free_queue()) < 0) {
00106 printk(MOD_NAME "can not register %s queue, type %d\n", queue_name, queue_type);
00107 return -1;
00108 }
00109 #if QUEUES_DEBUG
00110 else
00111 printk(MOD_NAME "registering %s queue, type %s\n", queue_name, queue_types[queue_type]->queue_type_name);
00112 #endif
00113
00114 queue = &queues[queue_type];
00115 queue->queue_name = queue_name;
00116 queue->queue_type = queue_type;
00117 queue->queue_ops = queue_types[queue_type]->queue_type_ops->queue_ops;
00118 INIT_LIST_HEAD(&queue->queue_list);
00119
00120 if (queue->queue_ops && queue->queue_ops->init)
00121 queue->queue_ops->init(queue);
00122
00123 atomic_inc(&queue_types[queue_type]->queue_type_count);
00124
00125 return queue_desc;
00126 }
00127
00128 int unregister_queue(int queue_desc)
00129 {
00130 struct queue_s *queue;
00131 const char *queue_name;
00132 int queue_type;
00133 int ret;
00134
00135 queue = &queues[queue_desc];
00136
00137 queue_name = queue->queue_name;
00138 queue_type = queue->queue_type;
00139
00140 if ((ret = put_free_queue(queue_desc)) < 0) {
00141 printk(MOD_NAME "can not unregister %s queue, type %d\n", queue_name, queue_type);
00142 return -1;
00143 }
00144 #if QUEUES_DEBUG
00145 else
00146 printk(MOD_NAME "unregistering %s queue, type %s\n", queue_name, queue_types[queue_type]->queue_type_name);
00147 #endif
00148
00149 if (queue->queue_ops && queue->queue_ops->remove)
00150 queue->queue_ops->remove(queue);
00151
00152 atomic_dec(&queue_types[queue_type]->queue_type_count);
00153
00154 return 0;
00155 }
00156
00157 int register_queue_type(struct queue_type_s *queue)
00158 {
00159 struct queue_type_ops_s *queue_type_ops;
00160 int queue_type;
00161 int ret = 0;
00162
00163 if (queue == NULL) {
00164 printk(MOD_NAME "can not register queue_type with NULL pointer...\n");
00165 return -1;
00166 }
00167
00168 queue_type = queue->queue_type;
00169
00170 if (queue_types[queue_type]) {
00171 printk(MOD_NAME "queue_type %d already registered...\n", queue_type);
00172 return -1;
00173 }
00174 #if QUEUES_DEBUG
00175 else
00176 printk(MOD_NAME "registering %s queue type (%d)\n", queue->queue_type_name, queue_type);
00177 #endif
00178
00179 queue_types[queue_type] = queue;
00180 queue_type_ops = queue->queue_type_ops;
00181
00182 if (queue_type_ops && queue_type_ops->init) {
00183 ret = queue_type_ops->init(queue);
00184 }
00185
00186 return ret;
00187 }
00188
00189 int unregister_queue_type(int queue_type)
00190 {
00191 struct queue_type_s *queue;
00192 struct queue_type_ops_s *queue_type_ops;
00193 int ret = 0;
00194
00195 queue = queue_types[queue_type];
00196
00197 if (queue == NULL) {
00198 printk(MOD_NAME "queue type %d not registered...\n", queue_type);
00199 return -1;
00200 }
00201
00202 if (atomic_read(&queue->queue_type_count) == 0) {
00203
00204 #if QUEUES_DEBUG
00205 printk(MOD_NAME "unregistering %s queue type (%d)\n", queue->queue_type_name, queue_type);
00206 #endif
00207 queue_type_ops = queue->queue_type_ops;
00208 if (queue_type_ops && queue_type_ops->remove) {
00209 ret = queue_type_ops->remove(queue);
00210 }
00211 } else {
00212 printk(MOD_NAME "queue type %d already in use...\n", queue_type);
00213 ret = -1;
00214 }
00215
00216 return ret;
00217 }
00218
00219 int queues_init(void)
00220 {
00221 int i;
00222
00223 printk(MOD_NAME "initializing queues\n");
00224
00225 queues_resource_desc = register_resource(&queues_resource);
00226 memset(queue_types, 0, MAX_QUEUE_TYPES * sizeof(struct queue_type_s));
00227
00228 for (i = 0; i < MAX_QUEUES; i++) {
00229 INIT_LIST_HEAD(&queues[i].queue_list);
00230 spin_lock_init(&queues[i].queue_lock);
00231 }
00232
00233 queues_fifo_init();
00234 queues_lifo_init();
00235
00236 return 0;
00237 }