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