xref: /openbmc/qemu/hw/block/xen_blkif.h (revision 7d87775f)
1 #ifndef XEN_BLKIF_H
2 #define XEN_BLKIF_H
3 
4 #include "hw/xen/interface/io/blkif.h"
5 #include "hw/xen/interface/io/protocols.h"
6 
7 /*
8  * Not a real protocol.  Used to generate ring structs which contain
9  * the elements common to all protocols only.  This way we get a
10  * compiler-checkable way to use common struct elements, so we can
11  * avoid using switch(protocol) in a number of places.
12  */
13 struct blkif_common_request {
14     char dummy;
15 };
16 struct blkif_common_response {
17     char dummy;
18 };
19 
20 /* i386 protocol version */
21 #pragma pack(push, 4)
22 struct blkif_x86_32_request {
23     uint8_t        operation;        /* BLKIF_OP_???                         */
24     uint8_t        nr_segments;      /* number of segments                   */
25     blkif_vdev_t   handle;           /* only for read/write requests         */
26     uint64_t       id;               /* private guest value, echoed in resp  */
27     blkif_sector_t sector_number;    /* start sector idx on disk (r/w only)  */
28     struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
29 };
30 struct blkif_x86_32_request_discard {
31     uint8_t        operation;        /* BLKIF_OP_DISCARD                     */
32     uint8_t        flag;             /* nr_segments in request struct        */
33     blkif_vdev_t   handle;           /* only for read/write requests         */
34     uint64_t       id;               /* private guest value, echoed in resp  */
35     blkif_sector_t sector_number;    /* start sector idx on disk (r/w only)  */
36     uint64_t       nr_sectors;       /* # of contiguous sectors to discard   */
37 };
38 struct blkif_x86_32_response {
39     uint64_t        id;              /* copied from request */
40     uint8_t         operation;       /* copied from request */
41     int16_t         status;          /* BLKIF_RSP_???       */
42 };
43 typedef struct blkif_x86_32_request blkif_x86_32_request_t;
44 typedef struct blkif_x86_32_response blkif_x86_32_response_t;
45 #pragma pack(pop)
46 
47 /* x86_64 protocol version */
48 struct blkif_x86_64_request {
49     uint8_t        operation;        /* BLKIF_OP_???                         */
50     uint8_t        nr_segments;      /* number of segments                   */
51     blkif_vdev_t   handle;           /* only for read/write requests         */
52     uint64_t       __attribute__((__aligned__(8))) id;
53     blkif_sector_t sector_number;    /* start sector idx on disk (r/w only)  */
54     struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
55 };
56 struct blkif_x86_64_request_discard {
57     uint8_t        operation;        /* BLKIF_OP_DISCARD                     */
58     uint8_t        flag;             /* nr_segments in request struct        */
59     blkif_vdev_t   handle;           /* only for read/write requests         */
60     uint64_t       __attribute__((__aligned__(8))) id;
61     blkif_sector_t sector_number;    /* start sector idx on disk (r/w only)  */
62     uint64_t       nr_sectors;       /* # of contiguous sectors to discard   */
63 };
64 struct blkif_x86_64_response {
65     uint64_t       __attribute__((__aligned__(8))) id;
66     uint8_t         operation;       /* copied from request */
67     int16_t         status;          /* BLKIF_RSP_???       */
68 };
69 typedef struct blkif_x86_64_request blkif_x86_64_request_t;
70 typedef struct blkif_x86_64_response blkif_x86_64_response_t;
71 
72 DEFINE_RING_TYPES(blkif_common, struct blkif_common_request,
73                   struct blkif_common_response);
74 DEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request,
75                   struct blkif_x86_32_response);
76 DEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request,
77                   struct blkif_x86_64_response);
78 
79 union blkif_back_rings {
80     blkif_back_ring_t        native;
81     blkif_common_back_ring_t common;
82     blkif_x86_32_back_ring_t x86_32_part;
83     blkif_x86_64_back_ring_t x86_64_part;
84 };
85 typedef union blkif_back_rings blkif_back_rings_t;
86 
87 enum blkif_protocol {
88     BLKIF_PROTOCOL_NATIVE = 1,
89     BLKIF_PROTOCOL_X86_32 = 2,
90     BLKIF_PROTOCOL_X86_64 = 3,
91 };
92 
93 static inline void blkif_get_x86_32_req(blkif_request_t *dst,
94                                         blkif_x86_32_request_t *src)
95 {
96     int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
97 
98     dst->operation = src->operation;
99     dst->nr_segments = src->nr_segments;
100     dst->handle = src->handle;
101     dst->id = src->id;
102     dst->sector_number = src->sector_number;
103     /* Prevent the compiler from using src->... instead. */
104     barrier();
105     if (dst->operation == BLKIF_OP_DISCARD) {
106         struct blkif_x86_32_request_discard *s = (void *)src;
107         struct blkif_request_discard *d = (void *)dst;
108         d->nr_sectors = s->nr_sectors;
109         return;
110     }
111     if (n > dst->nr_segments) {
112         n = dst->nr_segments;
113     }
114     for (i = 0; i < n; i++) {
115         dst->seg[i] = src->seg[i];
116     }
117 }
118 
119 static inline void blkif_get_x86_64_req(blkif_request_t *dst,
120                                         blkif_x86_64_request_t *src)
121 {
122     int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
123 
124     dst->operation = src->operation;
125     dst->nr_segments = src->nr_segments;
126     dst->handle = src->handle;
127     dst->id = src->id;
128     dst->sector_number = src->sector_number;
129     /* Prevent the compiler from using src->... instead. */
130     barrier();
131     if (dst->operation == BLKIF_OP_DISCARD) {
132         struct blkif_x86_64_request_discard *s = (void *)src;
133         struct blkif_request_discard *d = (void *)dst;
134         d->nr_sectors = s->nr_sectors;
135         return;
136     }
137     if (n > dst->nr_segments) {
138         n = dst->nr_segments;
139     }
140     for (i = 0; i < n; i++) {
141         dst->seg[i] = src->seg[i];
142     }
143 }
144 
145 #define XEN_BLKIF_SECTOR_SIZE 512
146 
147 #endif /* XEN_BLKIF_H */
148