1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2021-9-16      GuEe-GUI     the first version
9  * 2021-11-11     GuEe-GUI     using virtio common interface
10  */
11 
12 #ifndef __VIRTIO_BLK_H__
13 #define __VIRTIO_BLK_H__
14 
15 #include <rtdef.h>
16 
17 #include <virtio.h>
18 
19 #define VIRTIO_BLK_QUEUE            0
20 #define VIRTIO_BLK_BYTES_PER_SECTOR 512
21 #define VIRTIO_BLK_QUEUE_RING_SIZE  4
22 
23 #define VIRTIO_BLK_F_RO             5   /* Disk is read-only */
24 #define VIRTIO_BLK_F_SCSI           7   /* Supports scsi command passthru */
25 #define VIRTIO_BLK_F_CONFIG_WCE     11  /* Writeback mode available in config */
26 #define VIRTIO_BLK_F_MQ             12  /* Support more than one vq */
27 
28 #define VIRTIO_BLK_T_IN             0   /* Read the blk */
29 #define VIRTIO_BLK_T_OUT            1   /* Write the blk */
30 #define VIRTIO_BLK_T_SCSI_CMD       2
31 #define VIRTIO_BLK_T_SCSI_CMD_OUT   3
32 #define VIRTIO_BLK_T_FLUSH          4
33 #define VIRTIO_BLK_T_FLUSH_OUT      5
34 
35 struct virtio_blk_req
36 {
37     rt_uint32_t type;
38     rt_uint32_t ioprio;
39     rt_uint64_t sector;
40 };
41 
42 struct virtio_blk_config
43 {
44     rt_uint64_t capacity;           /* The capacity (in 512-byte sectors). */
45     rt_uint32_t size_max;           /* The maximum segment size (if VIRTIO_BLK_F_SIZE_MAX) */
46     rt_uint32_t seg_max;            /* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */
47 
48     /* Geometry of the device (if VIRTIO_BLK_F_GEOMETRY) */
49     struct virtio_blk_geometry
50     {
51         rt_uint16_t cylinders;
52         rt_uint8_t heads;
53         rt_uint8_t sectors;
54     } geometry;
55 
56     rt_uint32_t blk_size;           /* Block size of device (if VIRTIO_BLK_F_BLK_SIZE) */
57 
58     struct virtio_blk_topology
59     {
60         /* # Of logical blocks per physical block (log2) */
61         rt_uint8_t physical_block_exp;
62         /* Offset of first aligned logical block */
63         rt_uint8_t alignment_offset;
64         /* Suggested minimum I/O size in blocks */
65         rt_uint16_t min_io_size;
66         /* Optimal (suggested maximum) I/O size in blocks */
67         rt_uint32_t opt_io_size;
68     } topology;
69 
70     rt_uint8_t writeback;
71     rt_uint8_t unused0;
72     rt_uint16_t num_queues;
73     rt_uint32_t max_discard_sectors;
74     rt_uint32_t max_discard_seg;
75     rt_uint32_t discard_sector_alignment;
76     rt_uint32_t max_write_zeroes_sectors;
77     rt_uint32_t max_write_zeroes_seg;
78     rt_uint8_t write_zeroes_may_unmap;
79     rt_uint8_t unused1[3];
80     rt_uint32_t max_secure_erase_sectors;
81     rt_uint32_t max_secure_erase_seg;
82     rt_uint32_t secure_erase_sector_alignment;
83 } __attribute__((packed));
84 
85 struct virtio_blk_device
86 {
87     struct rt_device parent;
88 
89     struct virtio_device virtio_dev;
90 
91     struct virtio_blk_config *config;
92 
93     struct
94     {
95         rt_bool_t valid;
96         rt_uint8_t status;
97 
98         struct virtio_blk_req req;
99 
100     } info[VIRTIO_BLK_QUEUE_RING_SIZE];
101 };
102 
103 rt_err_t rt_virtio_blk_init(rt_ubase_t *mmio_base, rt_uint32_t irq);
104 
105 #endif /* __VIRTIO_BLK_H__ */
106