1 #include <hal/ahci/hba.h>
2 #include <klibc/stdio.h>
3 #include <klibc/string.h>
5 #include <lunaix/block.h>
6 #include <lunaix/fs/twifs.h>
7 #include <lunaix/mm/cake.h>
8 #include <lunaix/mm/valloc.h>
9 #include <lunaix/syslog.h>
11 #include <lunaix/spike.h>
22 static struct cake_pile* lbd_pile;
23 static struct block_dev** dev_registry;
24 static struct twifs_node* blk_sysroot;
29 __block_mount_partitions(struct hba_device* hd_dev);
32 __block_register(struct block_dev* dev);
37 lbd_pile = cake_new_pile("block_dev", sizeof(struct block_dev), 1, 0);
38 dev_registry = vcalloc(sizeof(struct block_dev*), MAX_DEV);
40 blk_sysroot = twifs_dir_node(NULL, "block");
44 __block_read(struct device* dev, void* buf, size_t offset, size_t len)
47 struct block_dev* bdev = (struct block_dev*)dev->underlay;
48 size_t bsize = bdev->blk_size, rd_block = offset / bsize,
49 r = offset % bsize, rd_size = 0;
51 struct vecbuf* vbuf = vbuf_alloc(NULL, buf, len);
52 struct blkio_req* req;
56 tmp_buf = vzalloc(bsize);
57 rd_size = MIN(len, bsize - r);
58 vbuf->buf.size = rd_size;
59 vbuf->buf.buffer = tmp_buf;
61 vbuf_alloc(vbuf, buf + rd_size, len - rd_size);
64 req = blkio_vrd(vbuf, rd_block, NULL, NULL, 0);
65 blkio_commit(bdev->blkio, req);
66 wait_if(req->flags & BLKIO_PENDING);
68 if (!(errno = req->errcode)) {
69 memcpy(buf, tmp_buf + r, rd_size);
82 __block_write(struct device* dev, void* buf, size_t offset, size_t len)
84 struct block_dev* bdev = (struct block_dev*)dev->underlay;
85 size_t bsize = bdev->blk_size, rd_block = offset / bsize,
88 struct vecbuf* vbuf = vbuf_alloc(NULL, buf, len);
89 struct blkio_req* req;
93 size_t rd_size = MIN(len, bsize - r);
94 tmp_buf = vzalloc(bsize);
95 vbuf->buf.size = bsize;
96 vbuf->buf.buffer = tmp_buf;
98 memcpy(tmp_buf + r, buf, rd_size);
99 vbuf_alloc(vbuf, buf + rd_size, len - rd_size);
102 req = blkio_vwr(vbuf, rd_block, NULL, NULL, 0);
103 blkio_commit(bdev->blkio, req);
104 wait_if(req->flags & BLKIO_PENDING);
106 int errno = req->errcode;
118 block_alloc_dev(const char* blk_id, void* driver, req_handler ioreq_handler)
120 struct block_dev* bdev = cake_grab(lbd_pile);
121 *bdev = (struct block_dev){ .driver = driver };
123 strncpy(bdev->name, blk_id, PARTITION_NAME_SIZE);
125 bdev->blkio = blkio_newctx(ioreq_handler);
131 block_mount(struct block_dev* bdev, devfs_exporter fs_export)
135 if (!__block_register(bdev)) {
140 struct twifs_node* dev_root = twifs_dir_node(blk_sysroot, bdev->bdev_id);
141 blk_set_blkmapping(bdev, dev_root);
142 fs_export(bdev, dev_root);
147 kprintf(KERROR "Fail to mount block device: %s (%x)\n", bdev->name, -errno);
152 __block_register(struct block_dev* bdev)
154 if (free_slot >= MAX_DEV) {
158 struct device* dev = device_addvol(NULL, bdev, "sd%c", 'a' + free_slot);
159 dev->write = __block_write;
160 dev->read = __block_read;
163 strcpy(bdev->bdev_id, dev->name_val);
164 dev_registry[free_slot++] = bdev;