1#ifdef TEST_BIO
2#include <block/bio.h>
3#include <block/block.h>
4#include <fs/ext2.h>
5#include <fs/vfs.h>
6#include <global.h>
7#include <mem/alloc.h>
8#include <stdbool.h>
9#include <stddef.h>
10#include <stdint.h>
11#include <test.h>
12#include <time/spin_sleep.h>
13
14#include "fs/detect.h"
15
16#define EXT2_INIT \
17 if (global.root_node->fs_type != FS_EXT2) { \
18 test_info("the mounted root is not ext2"); \
19 return TEST_SKIP(TEST_SKIP_NONE); \
20 } \
21 struct vfs_node *root = global.root_node;
22
23static bool done = false;
24
25static void bio_callback(struct bio_request *req) {
26 (void) req;
27 done = true;
28 test_info("blkdev_bio callback succeeded");
29}
30
31TEST_DECLARE(blkdev_bio_test, .tier = TEST_TIER_UNIT) {
32 EXT2_INIT;
33 struct ext2_fs *fs = root->fs_data;
34 struct block_device *d = fs->drive;
35 uint64_t run_times = 1;
36 enable_interrupts();
37
38 for (uint64_t i = 0; i < run_times; i++) {
39 struct bio_request *bio = kmalloc(sizeof(struct bio_request));
40 *bio = (struct bio_request){
41 .lba = 0,
42 .buffer = kmalloc_aligned(64 * PAGE_SIZE, PAGE_SIZE),
43 .size = 512 * 512,
44 .sector_count = 512,
45 .write = false,
46 .done = false,
47 .status = -1,
48 .on_complete = bio_callback,
49 .user_data = NULL,
50 .disk = d,
51 };
52 INIT_LIST_HEAD(list: &bio->list);
53
54 if (!d->submit_bio_async) {
55 test_info("BIO function is NULL");
56 return TEST_SKIP(TEST_SKIP_NONE);
57 }
58
59 bool submitted = d->submit_bio_async(d, bio);
60 if (!submitted) {
61 return TEST_FAIL("submit_bio_async rejected the request");
62 }
63
64 sleep_spin_ms(msec: 100);
65
66 TEST_ASSERT(bio->status == 0);
67 }
68 TEST_ASSERT(done == true);
69 TEST_ASSERT(test_current_message_count() == run_times);
70 return TEST_SUCCESS;
71}
72#endif
73