aboutsummaryrefslogtreecommitdiff
path: root/kernel/drivers/blockdev.c
blob: 5c8eb824063982e15b80c58e79556054badfe4f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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);
}