#include #include #include "storedev.h" #include "spinlock/spinlock.h" #include "kprintf.h" #include "errors.h" #include "dlmalloc/malloc.h" #include "ramsd.h" #include "util/util.h" #include "dev/dev.h" #include "hshtb.h" #include "hal/hal.h" #include "randcrypto/uniqid.h" StoreDevList STOREDEV_LIST; void storedev_init(void) { spinlock_init(&STOREDEV_LIST.spinlock); STOREDEV_LIST.head = NULL; LOG("storedev", "init\n"); } void storedev_register_dev_entry(StoreDev *sd, int32_t sdtype) { char uniq[5]; randcrypto_gen_uniqid(uniq, 4); char key[20]; hal_memset(key, 0, sizeof(key)); if (sdtype == STOREDEV_RAMSD) { ksprintf(key, "ramsd-%s", uniq); } spinlock_acquire(&DEVTABLE.spinlock); Dev *dev = NULL; HSHTB_ALLOC(DEVTABLE.devs, ident, key, dev); spinlock_release(&DEVTABLE.spinlock); if (dev == NULL) { ERR("storedev", "could not register dev entry for storedev"); return; } spinlock_init(&dev->spinlock); dev->extra = (void *)sd; } void storedev_unregister_dev_entry(Dev *dev) { spinlock_acquire(&DEVTABLE.spinlock); HSHTB_DELETE(DEVTABLE.devs, ident, dev->ident); spinlock_release(&DEVTABLE.spinlock); } StoreDev *storedev_create(int32_t sdtype, void *extra) { StoreDev *sd = dlmalloc(sizeof(*sd)); if (sd == NULL) { return NULL; } spinlock_acquire(&STOREDEV_LIST.spinlock); sd->_magic = STOREDEV_MAGIC; switch (sdtype) { case STOREDEV_RAMSD: { spinlock_init(&sd->spinlock); sd->sdtype = STOREDEV_RAMSD; sd->init = &ramsd_init; sd->cleanup = &ramsd_cleanup; sd->read = &ramsd_read; sd->write = &ramsd_write; sd->capacity = &ramsd_capacity; int32_t err = sd->init(sd, extra); if (err != E_OK) { spinlock_release(&STOREDEV_LIST.spinlock); return NULL; } LL_APPEND(STOREDEV_LIST.head, sd); } break; default: spinlock_release(&STOREDEV_LIST.spinlock); return NULL; } spinlock_release(&STOREDEV_LIST.spinlock); storedev_register_dev_entry(sd, sdtype); return sd; } int32_t storedev_delete(StoreDev *sd) { spinlock_acquire(&STOREDEV_LIST.spinlock); LL_REMOVE(STOREDEV_LIST.head, sd); int32_t err = sd->cleanup(sd); if (err < 0) { spinlock_release(&STOREDEV_LIST.spinlock); return err; } spinlock_release(&STOREDEV_LIST.spinlock); return E_OK; }