diff options
Diffstat (limited to 'kernel/drivers/blockdev.c')
-rw-r--r-- | kernel/drivers/blockdev.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/kernel/drivers/blockdev.c b/kernel/drivers/blockdev.c new file mode 100644 index 0000000..5c8eb82 --- /dev/null +++ b/kernel/drivers/blockdev.c @@ -0,0 +1,96 @@ +#include "kernel.h" +#include "util/debug.h" +#include <drivers/disk/sata.h> + +#include "drivers/blockdev.h" + +#include "mm/pframe.h" +#include "fs/s5fs/s5fs.h" + +#ifdef NO +static mobj_ops_t blockdev_mobj_ops = {.get_pframe = NULL, + .fill_pframe = blockdev_fill_pframe, + .flush_pframe = blockdev_flush_pframe, + .destructor = NULL}; +#endif + +static list_t blockdevs = LIST_INITIALIZER(blockdevs); + +void blockdev_init() { sata_init(); } + +long blockdev_register(blockdev_t *dev) +{ + if (!dev || dev->bd_id == NULL_DEVID || !dev->bd_ops) + { + return -1; + } + + list_iterate(&blockdevs, bd, blockdev_t, bd_link) + { + if (dev->bd_id == bd->bd_id) + { + return -1; + } + } + +#ifdef NO + mobj_init(&dev->bd_mobj, MOBJ_BLOCKDEV, &blockdev_mobj_ops); +#endif + + list_insert_tail(&blockdevs, &dev->bd_link); + return 0; +} + +blockdev_t *blockdev_lookup(devid_t id) +{ + list_iterate(&blockdevs, bd, blockdev_t, bd_link) + { + if (id == bd->bd_id) + { + return bd; + } + } + return NULL; +} + +#ifdef NO +static long blockdev_fill_pframe(mobj_t *mobj, pframe_t *pf) +{ + KASSERT(mobj && pf); + KASSERT(pf->pf_pagenum <= (1UL << (8 * sizeof(blocknum_t)))); + blockdev_t *bd = CONTAINER_OF(mobj, blockdev_t, bd_mobj); + return bd->bd_ops->read_block(bd, pf->pf_addr, (blocknum_t)pf->pf_pagenum, + 1); +} + +static long blockdev_flush_pframe(mobj_t *mobj, pframe_t *pf) +{ + KASSERT(mobj && pf); + KASSERT(pf->pf_pagenum <= (1UL << (8 * sizeof(blocknum_t)))); + dbg(DBG_S5FS, "writing disk block %lu\n", pf->pf_pagenum); + blockdev_t *bd = CONTAINER_OF(mobj, blockdev_t, bd_mobj); + return bd->bd_ops->write_block(bd, pf->pf_addr, (blocknum_t)pf->pf_pagenum, + 1); +} +#endif + +long blockdev_fill_pframe(mobj_t *mobj, pframe_t *pf) +{ + KASSERT(mobj && pf); + KASSERT(pf->pf_pagenum <= (1UL << (8 * sizeof(blocknum_t)))); + blockdev_t *bd = CONTAINER_OF(mobj, s5fs_t, s5f_mobj)->s5f_bdev; + KASSERT(pf->pf_loc); + return bd->bd_ops->read_block(bd, pf->pf_addr, (blocknum_t)pf->pf_loc, + 1); +} + +long blockdev_flush_pframe(mobj_t *mobj, pframe_t *pf) +{ + KASSERT(mobj && pf); + KASSERT(pf->pf_pagenum <= (1UL << (8 * sizeof(blocknum_t)))); + dbg(DBG_S5FS, "writing disk block %lu\n", pf->pf_pagenum); + blockdev_t *bd = CONTAINER_OF(mobj, s5fs_t, s5f_mobj)->s5f_bdev; + KASSERT(pf->pf_loc); + return bd->bd_ops->write_block(bd, pf->pf_addr, (blocknum_t)pf->pf_loc, + 1); +}
\ No newline at end of file |