#include #include #include "storedev.h" #include "spinlock/spinlock.h" #include "kprintf.h" #include "errors.h" #include "dlmalloc/malloc.h" #include "ramsd.h" #include "atasd.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"); ata_probe(); } void storedev_register_dev_entry(StoreDev *sd, char *name, int32_t sdtype) { spinlock_acquire(&DEVTABLE.spinlock); Dev *dev = NULL; HSHTB_ALLOC(DEVTABLE.devs, ident, name, 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, char *name, void *extra) { StoreDev *sd = dlmalloc(sizeof(*sd)); if (sd == NULL) { return NULL; } spinlock_acquire(&STOREDEV_LIST.spinlock); sd->_magic = STOREDEV_MAGIC; spinlock_init(&sd->spinlock); switch (sdtype) { case STOREDEV_RAMSD: { sd->sdtype = STOREDEV_RAMSD; sd->init = &ramsd_init; sd->cleanup = &ramsd_cleanup; sd->read = &ramsd_read; sd->write = &ramsd_write; sd->capacity = &ramsd_capacity; sd->sectorsize = STOREDEV_RAMSD_SECTORSIZE; } break; case STOREDEV_ATASD: { sd->sdtype = STOREDEV_ATASD; sd->init = &atasd_init; sd->cleanup = &atasd_cleanup; sd->read = &atasd_read; sd->write = &atasd_write; sd->capacity = &atasd_capacity; sd->sectorsize = STOREDEV_ATASD_SECTORSIZE; } break; case STOREDEV_PARTSD: { sd->sdtype = STOREDEV_PARTSD; sd->init = &partsd_init; sd->cleanup = &partsd_cleanup; sd->read = &partsd_read; sd->write = &partsd_write; sd->capacity = &partsd_capacity; sd->sectorsize = 0; // lazy } break; default: spinlock_release(&STOREDEV_LIST.spinlock); return NULL; } int32_t err = sd->init(sd, extra); if (err != E_OK) { dlfree(sd); spinlock_release(&STOREDEV_LIST.spinlock); return NULL; } LL_APPEND(STOREDEV_LIST.head, sd); spinlock_release(&STOREDEV_LIST.spinlock); storedev_register_dev_entry(sd, name, 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; }