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
blkif_get_x86_32_req(blkif_request_t * dst,blkif_x86_32_request_t * src)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
blkif_get_x86_64_req(blkif_request_t * dst,blkif_x86_64_request_t * src)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