00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <dr-env.h>
00020 #include <list.h>
00021 #include <slabmem.h>
00022 #include <errno.h>
00023 #include "block.h"
00024
00025
00077
00078 typedef struct BlockDevice BlockDevice;
00079 struct BlockDevice
00080 {
00081 BlockDevice *prev;
00082 BlockDevice *next;
00083 int (*request)(int function, ...);
00084 void *handle;
00085 const char *name;
00086 };
00087
00088
00089 static List list =
00090 {
00091 .begin = NULL,
00092 .end = NULL,
00093 .size = 0
00094 };
00095
00096
00097 static slabmem_t slab =
00098 {
00099 .pages = NULL,
00100 .obj_size = sizeof(BlockDevice),
00101 .free_objs = NULL
00102 };
00103
00104
00119 const char *block_enumerate(void **iterator)
00120 {
00121 BlockDevice *d = (BlockDevice *) *iterator;
00122 if (d) d = d->next;
00123 else d = (BlockDevice *) list.begin;
00124 *iterator = (void *) d;
00125 if (d) return d->name;
00126 return NULL;
00127 }
00128
00129
00147 int block_get(const char *name, int type, void **operations, void **handle)
00148 {
00149 BlockDevice *d;
00150 if (name)
00151 for (d = (BlockDevice *) list.begin; d; d = d->next)
00152 {
00153 assert(d->name);
00154 if (strcasecmp(name, d->name) == 0)
00155 {
00156 assert(d->handle);
00157 assert(d->request);
00158 if (handle) *handle = d->handle;
00159 return d->request(REQ_GET_OPERATIONS, type, operations);
00160 }
00161 }
00162 return -EINVAL;
00163 }
00164
00165
00180 int block_register(const char *name, int (*request)(int function, ...), void *handle)
00181 {
00182 BlockDevice *d;
00183 for (d = (BlockDevice *) list.begin; d; d = d->next)
00184 if (!strcasecmp(d->name, name)) return -EEXIST;
00185 d = (BlockDevice *) slabmem_alloc(&slab);
00186 if (!d) return -ENOMEM;
00187 d->request = request;
00188 d->handle = handle;
00189 d->name = name;
00190 list_push_back(&list, (ListItem *) d);
00191 message("[BLOCK] Device \"%s\" registered\n", name);
00192 return 0;
00193 }
00194
00195
00204 int block_unregister(const char *name)
00205 {
00206 BlockDevice *d;
00207 for (d = (BlockDevice *) list.begin; d; d = d->next)
00208 if (!strcasecmp(d->name, name))
00209 {
00210 assert(d->request);
00211 if (d->request(REQ_GET_REFERENCES) > 0) return -EBUSY;
00212 list_erase(&list, (ListItem *) d);
00213 slabmem_free(&slab, d);
00214 return 0;
00215 }
00216 return -ENOENT;
00217 }
00218
00219
00220
00221
00222
00223
00224
00225 #include <kernel.h>
00226 #include <ll/i386/error.h>
00227 static const struct { const char *name; void *address; } symbols[] =
00228 {
00229 { "block_enumerate", block_enumerate },
00230 { "block_get", block_get },
00231 { "block_register", block_register },
00232 { "block_unregister", block_unregister },
00233 { 0, 0 }
00234 };
00235
00236
00237
00238 void block_init(void)
00239 {
00240 int k;
00241 message("Going to install the Block Device Manager... ");
00242 for (k = 0; symbols[k].name; k++)
00243 if (fd32_add_call(symbols[k].name, symbols[k].address, ADD) == -1)
00244 message("Cannot add %s to the symbol table\n", symbols[k].name);
00245 message("Done\n");
00246 }
00247
00248