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 struct cake_pile* lbd_pile;
23 struct block_dev** dev_registry;
28 __block_mount_partitions(struct hba_device* hd_dev);
31 __block_register(struct block_dev* dev);
36 lbd_pile = cake_new_pile("block_dev", sizeof(struct block_dev), 1, 0);
37 dev_registry = vcalloc(sizeof(struct block_dev*), MAX_DEV);
42 __block_read(struct v_file* file, void* buffer, size_t len);
45 __block_write(struct v_file* file, void* buffer, size_t len);
50 struct twifs_node* dev = twifs_toplevel_node("dev", 3);
51 struct twifs_node* dev_block = twifs_dir_node(dev, "block", 5);
54 kprintf(KERROR "fail to create twifs node");
58 struct block_dev* bdev;
59 struct twifs_node* bdev_node;
60 for (size_t i = 0; i < MAX_DEV; i++) {
61 if (!(bdev = dev_registry[i])) {
66 twifs_dir_node(dev_block, bdev->bdev_id, strlen(bdev->bdev_id));
67 bdev_node->fops.read = __block_read;
68 bdev_node->fops.write = __block_write;
70 bdev_node->inode->fsize = bdev->hd_dev->max_lba;
75 __block_read(struct v_file* file, void* buffer, size_t len)
77 int index = (int)((struct twifs_node*)file->inode->data)->data;
79 struct block_dev* bdev;
80 if (index < 0 || index >= MAX_DEV || !(bdev = dev_registry[index])) {
83 size_t acc_size = 0, rd_size = 0, bsize = bdev->hd_dev->block_size,
85 void* block = valloc(bsize);
87 while (acc_size < len) {
88 if (!bdev->hd_dev->ops.read_buffer(
89 bdev->hd_dev, file->f_pos + rd_block, block, bsize)) {
93 rd_size = MIN(len - acc_size, bsize);
94 memcpy(buffer + acc_size, block, rd_size);
108 __block_write(struct v_file* file, void* buffer, size_t len)
110 int index = (int)((struct twifs_node*)file->inode->data)->data;
112 struct block_dev* bdev;
113 if (index < 0 || index >= MAX_DEV || !(bdev = dev_registry[index])) {
116 size_t acc_size = 0, wr_size = 0, bsize = bdev->hd_dev->block_size,
118 void* block = valloc(bsize);
120 while (acc_size < len) {
121 wr_size = MIN(len - acc_size, bsize);
122 memcpy(block, buffer + acc_size, wr_size);
123 if (!bdev->hd_dev->ops.write_buffer(
124 bdev->hd_dev, file->f_pos + wr_block, block, bsize)) {
141 block_mount_disk(struct hba_device* hd_dev)
144 struct block_dev* dev = cake_grab(lbd_pile);
145 strncpy(dev->name, hd_dev->model, PARTITION_NAME_SIZE);
146 dev->hd_dev = hd_dev;
148 dev->end_lba = hd_dev->max_lba;
149 if (!__block_register(dev)) {
157 kprintf(KERROR "Fail to mount hd: %s[%s] (%x)\n",
163 // FIXME make it more general, manipulate the device through vfs mapping
165 __block_mount_partitions(struct hba_device* hd_dev)
168 void* buffer = valloc_dma(hd_dev->block_size);
169 if (!hd_dev->ops.read_buffer(hd_dev, 1, buffer, hd_dev->block_size)) {
174 struct lpt_header* header = (struct lpt_header*)buffer;
175 if (header->signature != LPT_SIG) {
180 if (header->crc != crc32b(buffer, sizeof(*header))) {
185 uint64_t lba = header->pt_start_lba;
187 int count_per_sector = hd_dev->block_size / sizeof(struct lpt_entry);
188 while (lba < header->pt_end_lba) {
189 if (!hd_dev->ops.read_buffer(hd_dev, lba, buffer, hd_dev->block_size)) {
193 struct lpt_entry* entry = (struct lpt_entry*)buffer;
194 for (int i = 0; i < count_per_sector; i++, j++) {
195 struct block_dev* dev = cake_grab(lbd_pile);
196 strncpy(dev->name, entry->part_name, PARTITION_NAME_SIZE);
197 dev->hd_dev = hd_dev;
198 dev->base_lba = entry->base_lba;
199 dev->end_lba = entry->end_lba;
200 __block_register(dev);
202 if (j >= header->table_len) {
214 __block_register(struct block_dev* dev)
216 if (free_slot >= MAX_DEV) {
219 snprintf(dev->bdev_id, DEV_ID_SIZE, "bd%x", free_slot);
220 dev_registry[free_slot++] = dev;