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