12a6a4076SMarkus Armbruster #ifndef XEN_BLKIF_H
22a6a4076SMarkus Armbruster #define XEN_BLKIF_H
347b43a1fSPaolo Bonzini
4*a3434a2dSAnthony PERARD #include "hw/xen/interface/io/blkif.h"
5*a3434a2dSAnthony PERARD #include "hw/xen/interface/io/protocols.h"
647b43a1fSPaolo Bonzini
70d8e5894SJuergen Gross /*
80d8e5894SJuergen Gross * Not a real protocol. Used to generate ring structs which contain
947b43a1fSPaolo Bonzini * the elements common to all protocols only. This way we get a
1047b43a1fSPaolo Bonzini * compiler-checkable way to use common struct elements, so we can
110d8e5894SJuergen Gross * avoid using switch(protocol) in a number of places.
120d8e5894SJuergen Gross */
1347b43a1fSPaolo Bonzini struct blkif_common_request {
1447b43a1fSPaolo Bonzini char dummy;
1547b43a1fSPaolo Bonzini };
1647b43a1fSPaolo Bonzini struct blkif_common_response {
1747b43a1fSPaolo Bonzini char dummy;
1847b43a1fSPaolo Bonzini };
1947b43a1fSPaolo Bonzini
2047b43a1fSPaolo Bonzini /* i386 protocol version */
2147b43a1fSPaolo Bonzini #pragma pack(push, 4)
2247b43a1fSPaolo Bonzini struct blkif_x86_32_request {
2347b43a1fSPaolo Bonzini uint8_t operation; /* BLKIF_OP_??? */
2447b43a1fSPaolo Bonzini uint8_t nr_segments; /* number of segments */
2547b43a1fSPaolo Bonzini blkif_vdev_t handle; /* only for read/write requests */
2647b43a1fSPaolo Bonzini uint64_t id; /* private guest value, echoed in resp */
2747b43a1fSPaolo Bonzini blkif_sector_t sector_number; /* start sector idx on disk (r/w only) */
2847b43a1fSPaolo Bonzini struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
2947b43a1fSPaolo Bonzini };
3016246018SJuergen Gross struct blkif_x86_32_request_discard {
3116246018SJuergen Gross uint8_t operation; /* BLKIF_OP_DISCARD */
3216246018SJuergen Gross uint8_t flag; /* nr_segments in request struct */
3316246018SJuergen Gross blkif_vdev_t handle; /* only for read/write requests */
3416246018SJuergen Gross uint64_t id; /* private guest value, echoed in resp */
3516246018SJuergen Gross blkif_sector_t sector_number; /* start sector idx on disk (r/w only) */
3616246018SJuergen Gross uint64_t nr_sectors; /* # of contiguous sectors to discard */
3716246018SJuergen Gross };
3847b43a1fSPaolo Bonzini struct blkif_x86_32_response {
3947b43a1fSPaolo Bonzini uint64_t id; /* copied from request */
4047b43a1fSPaolo Bonzini uint8_t operation; /* copied from request */
4147b43a1fSPaolo Bonzini int16_t status; /* BLKIF_RSP_??? */
4247b43a1fSPaolo Bonzini };
4347b43a1fSPaolo Bonzini typedef struct blkif_x86_32_request blkif_x86_32_request_t;
4447b43a1fSPaolo Bonzini typedef struct blkif_x86_32_response blkif_x86_32_response_t;
4547b43a1fSPaolo Bonzini #pragma pack(pop)
4647b43a1fSPaolo Bonzini
4747b43a1fSPaolo Bonzini /* x86_64 protocol version */
4847b43a1fSPaolo Bonzini struct blkif_x86_64_request {
4947b43a1fSPaolo Bonzini uint8_t operation; /* BLKIF_OP_??? */
5047b43a1fSPaolo Bonzini uint8_t nr_segments; /* number of segments */
5147b43a1fSPaolo Bonzini blkif_vdev_t handle; /* only for read/write requests */
5247b43a1fSPaolo Bonzini uint64_t __attribute__((__aligned__(8))) id;
5347b43a1fSPaolo Bonzini blkif_sector_t sector_number; /* start sector idx on disk (r/w only) */
5447b43a1fSPaolo Bonzini struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
5547b43a1fSPaolo Bonzini };
5616246018SJuergen Gross struct blkif_x86_64_request_discard {
5716246018SJuergen Gross uint8_t operation; /* BLKIF_OP_DISCARD */
5816246018SJuergen Gross uint8_t flag; /* nr_segments in request struct */
5916246018SJuergen Gross blkif_vdev_t handle; /* only for read/write requests */
6016246018SJuergen Gross uint64_t __attribute__((__aligned__(8))) id;
6116246018SJuergen Gross blkif_sector_t sector_number; /* start sector idx on disk (r/w only) */
6216246018SJuergen Gross uint64_t nr_sectors; /* # of contiguous sectors to discard */
6316246018SJuergen Gross };
6447b43a1fSPaolo Bonzini struct blkif_x86_64_response {
6547b43a1fSPaolo Bonzini uint64_t __attribute__((__aligned__(8))) id;
6647b43a1fSPaolo Bonzini uint8_t operation; /* copied from request */
6747b43a1fSPaolo Bonzini int16_t status; /* BLKIF_RSP_??? */
6847b43a1fSPaolo Bonzini };
6947b43a1fSPaolo Bonzini typedef struct blkif_x86_64_request blkif_x86_64_request_t;
7047b43a1fSPaolo Bonzini typedef struct blkif_x86_64_response blkif_x86_64_response_t;
7147b43a1fSPaolo Bonzini
720d8e5894SJuergen Gross DEFINE_RING_TYPES(blkif_common, struct blkif_common_request,
730d8e5894SJuergen Gross struct blkif_common_response);
740d8e5894SJuergen Gross DEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request,
750d8e5894SJuergen Gross struct blkif_x86_32_response);
760d8e5894SJuergen Gross DEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request,
770d8e5894SJuergen Gross struct blkif_x86_64_response);
7847b43a1fSPaolo Bonzini
7947b43a1fSPaolo Bonzini union blkif_back_rings {
8047b43a1fSPaolo Bonzini blkif_back_ring_t native;
8147b43a1fSPaolo Bonzini blkif_common_back_ring_t common;
8247b43a1fSPaolo Bonzini blkif_x86_32_back_ring_t x86_32_part;
8347b43a1fSPaolo Bonzini blkif_x86_64_back_ring_t x86_64_part;
8447b43a1fSPaolo Bonzini };
8547b43a1fSPaolo Bonzini typedef union blkif_back_rings blkif_back_rings_t;
8647b43a1fSPaolo Bonzini
8747b43a1fSPaolo Bonzini enum blkif_protocol {
8847b43a1fSPaolo Bonzini BLKIF_PROTOCOL_NATIVE = 1,
8947b43a1fSPaolo Bonzini BLKIF_PROTOCOL_X86_32 = 2,
9047b43a1fSPaolo Bonzini BLKIF_PROTOCOL_X86_64 = 3,
9147b43a1fSPaolo Bonzini };
9247b43a1fSPaolo Bonzini
blkif_get_x86_32_req(blkif_request_t * dst,blkif_x86_32_request_t * src)930d8e5894SJuergen Gross static inline void blkif_get_x86_32_req(blkif_request_t *dst,
940d8e5894SJuergen Gross blkif_x86_32_request_t *src)
9547b43a1fSPaolo Bonzini {
9647b43a1fSPaolo Bonzini int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
9747b43a1fSPaolo Bonzini
9847b43a1fSPaolo Bonzini dst->operation = src->operation;
9947b43a1fSPaolo Bonzini dst->nr_segments = src->nr_segments;
10047b43a1fSPaolo Bonzini dst->handle = src->handle;
10147b43a1fSPaolo Bonzini dst->id = src->id;
10247b43a1fSPaolo Bonzini dst->sector_number = src->sector_number;
1034837a1a5SJan Beulich /* Prevent the compiler from using src->... instead. */
1044837a1a5SJan Beulich barrier();
1054837a1a5SJan Beulich if (dst->operation == BLKIF_OP_DISCARD) {
10616246018SJuergen Gross struct blkif_x86_32_request_discard *s = (void *)src;
107f3135204SOlaf Hering struct blkif_request_discard *d = (void *)dst;
108f3135204SOlaf Hering d->nr_sectors = s->nr_sectors;
109f3135204SOlaf Hering return;
110f3135204SOlaf Hering }
1110d8e5894SJuergen Gross if (n > dst->nr_segments) {
112f9e98e5dSStefano Stabellini n = dst->nr_segments;
1130d8e5894SJuergen Gross }
1140d8e5894SJuergen Gross for (i = 0; i < n; i++) {
11547b43a1fSPaolo Bonzini dst->seg[i] = src->seg[i];
11647b43a1fSPaolo Bonzini }
1170d8e5894SJuergen Gross }
11847b43a1fSPaolo Bonzini
blkif_get_x86_64_req(blkif_request_t * dst,blkif_x86_64_request_t * src)1190d8e5894SJuergen Gross static inline void blkif_get_x86_64_req(blkif_request_t *dst,
1200d8e5894SJuergen Gross blkif_x86_64_request_t *src)
12147b43a1fSPaolo Bonzini {
12247b43a1fSPaolo Bonzini int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
12347b43a1fSPaolo Bonzini
12447b43a1fSPaolo Bonzini dst->operation = src->operation;
12547b43a1fSPaolo Bonzini dst->nr_segments = src->nr_segments;
12647b43a1fSPaolo Bonzini dst->handle = src->handle;
12747b43a1fSPaolo Bonzini dst->id = src->id;
12847b43a1fSPaolo Bonzini dst->sector_number = src->sector_number;
1294837a1a5SJan Beulich /* Prevent the compiler from using src->... instead. */
1304837a1a5SJan Beulich barrier();
1314837a1a5SJan Beulich if (dst->operation == BLKIF_OP_DISCARD) {
13216246018SJuergen Gross struct blkif_x86_64_request_discard *s = (void *)src;
133f3135204SOlaf Hering struct blkif_request_discard *d = (void *)dst;
134f3135204SOlaf Hering d->nr_sectors = s->nr_sectors;
135f3135204SOlaf Hering return;
136f3135204SOlaf Hering }
1370d8e5894SJuergen Gross if (n > dst->nr_segments) {
138f9e98e5dSStefano Stabellini n = dst->nr_segments;
1390d8e5894SJuergen Gross }
1400d8e5894SJuergen Gross for (i = 0; i < n; i++) {
14147b43a1fSPaolo Bonzini dst->seg[i] = src->seg[i];
14247b43a1fSPaolo Bonzini }
1430d8e5894SJuergen Gross }
14447b43a1fSPaolo Bonzini
1452bcd05cfSPaul Durrant #define XEN_BLKIF_SECTOR_SIZE 512
1462bcd05cfSPaul Durrant
1472a6a4076SMarkus Armbruster #endif /* XEN_BLKIF_H */
148