1/* @title: Block Devices */
2#pragma once
3#include <block/bcache.h>
4#include <fs/detect.h>
5#include <sch/sched.h>
6#include <stdatomic.h>
7#include <stdbool.h>
8#include <stdint.h>
9#include <sync/spinlock.h>
10
11struct block_device;
12struct bio_request;
13
14enum bdev_type {
15 BDEV_IDE_DRIVE,
16 BDEV_NVME_DRIVE,
17 BDEV_AHCI_DRIVE,
18 BDEV_ATAPI_DRIVE,
19};
20
21static inline const char *get_block_device_str(enum bdev_type type) {
22 switch (type) {
23 case BDEV_IDE_DRIVE: return "IDE DRIVE";
24 case BDEV_NVME_DRIVE: return "NVME DRIVE";
25 case BDEV_AHCI_DRIVE: return "AHCI CONTROLLER";
26 case BDEV_ATAPI_DRIVE: return "ATAPI DRIVE";
27 }
28 return "UNKNOWN DEVICE";
29}
30
31struct partition {
32 struct block_device *disk;
33 uint64_t start_lba;
34 uint64_t sector_count;
35 enum fs_type fs_type;
36 void *fs_data;
37 char name[16];
38 bool mounted;
39
40 struct vfs_node *(*mount)(struct partition *);
41};
42
43enum bdev_flags {
44 /* queue reordering is skipped */
45 BDEV_FLAG_NO_REORDER = 1,
46
47 /* coalescing is skipped */
48 BDEV_FLAG_NO_COALESCE = 1 << 1,
49
50 /* scheduling doesn't happen.
51 * this will just call sync
52 * requests, and immediately
53 * trigger the callback - used
54 * in things like RAMdisk. */
55 BDEV_FLAG_NO_SCHED = 1 << 2,
56};
57
58struct block_device {
59 enum bdev_flags flags;
60 enum bdev_type type;
61 enum fs_type fs_type;
62 void *fs_data;
63 char name[16];
64 uint64_t total_sectors;
65 bool is_removable;
66 void *driver_data;
67 uint32_t sector_size;
68
69 /* both of these take full priority over the async operations.
70 * do not pass go, do not collect two hundred dollars, submit instantly.
71 *
72 * these are sync and blocking
73 *
74 * these are not used in many areas though, and such, we can get away
75 * with instant submission for the most part*/
76 bool (*read_sector)(struct block_device *disk, uint64_t lba,
77 uint8_t *buffer, uint64_t sector_count);
78
79 bool (*write_sector)(struct block_device *disk, uint64_t lba,
80 const uint8_t *buffer, uint64_t sector_count);
81
82 /* immediate asynchronous submission */
83 bool (*submit_bio_async)(struct block_device *disk,
84 struct bio_request *bio);
85
86 struct bio_scheduler_ops *ops;
87 struct bio_scheduler *scheduler;
88 struct bcache *cache;
89 uint64_t partition_count;
90 struct partition *partitions;
91};
92
93static inline bool bdev_skip_coalesce(struct block_device *disk) {
94 return disk->flags & BDEV_FLAG_NO_COALESCE;
95}
96
97static inline bool bdev_skip_sched(struct block_device *disk) {
98 return disk->flags & BDEV_FLAG_NO_SCHED;
99}
100
101static inline bool bdev_skip_reorder(struct block_device *disk) {
102 return disk->flags & BDEV_FLAG_NO_REORDER;
103}
104