1 #ifndef XEN_BLKIF_H 2 #define XEN_BLKIF_H 3 4 #include <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