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 /* 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 struct blkif_common_request { 13 char dummy; 14 }; 15 struct blkif_common_response { 16 char dummy; 17 }; 18 19 /* i386 protocol version */ 20 #pragma pack(push, 4) 21 struct blkif_x86_32_request { 22 uint8_t operation; /* BLKIF_OP_??? */ 23 uint8_t nr_segments; /* number of segments */ 24 blkif_vdev_t handle; /* only for read/write requests */ 25 uint64_t id; /* private guest value, echoed in resp */ 26 blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ 27 struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; 28 }; 29 struct blkif_x86_32_response { 30 uint64_t id; /* copied from request */ 31 uint8_t operation; /* copied from request */ 32 int16_t status; /* BLKIF_RSP_??? */ 33 }; 34 typedef struct blkif_x86_32_request blkif_x86_32_request_t; 35 typedef struct blkif_x86_32_response blkif_x86_32_response_t; 36 #pragma pack(pop) 37 38 /* x86_64 protocol version */ 39 struct blkif_x86_64_request { 40 uint8_t operation; /* BLKIF_OP_??? */ 41 uint8_t nr_segments; /* number of segments */ 42 blkif_vdev_t handle; /* only for read/write requests */ 43 uint64_t __attribute__((__aligned__(8))) id; 44 blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ 45 struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; 46 }; 47 struct blkif_x86_64_response { 48 uint64_t __attribute__((__aligned__(8))) id; 49 uint8_t operation; /* copied from request */ 50 int16_t status; /* BLKIF_RSP_??? */ 51 }; 52 typedef struct blkif_x86_64_request blkif_x86_64_request_t; 53 typedef struct blkif_x86_64_response blkif_x86_64_response_t; 54 55 DEFINE_RING_TYPES(blkif_common, struct blkif_common_request, struct blkif_common_response); 56 DEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request, struct blkif_x86_32_response); 57 DEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request, struct blkif_x86_64_response); 58 59 union blkif_back_rings { 60 blkif_back_ring_t native; 61 blkif_common_back_ring_t common; 62 blkif_x86_32_back_ring_t x86_32_part; 63 blkif_x86_64_back_ring_t x86_64_part; 64 }; 65 typedef union blkif_back_rings blkif_back_rings_t; 66 67 enum blkif_protocol { 68 BLKIF_PROTOCOL_NATIVE = 1, 69 BLKIF_PROTOCOL_X86_32 = 2, 70 BLKIF_PROTOCOL_X86_64 = 3, 71 }; 72 73 static inline void blkif_get_x86_32_req(blkif_request_t *dst, blkif_x86_32_request_t *src) 74 { 75 int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST; 76 77 dst->operation = src->operation; 78 dst->nr_segments = src->nr_segments; 79 dst->handle = src->handle; 80 dst->id = src->id; 81 dst->sector_number = src->sector_number; 82 if (src->operation == BLKIF_OP_DISCARD) { 83 struct blkif_request_discard *s = (void *)src; 84 struct blkif_request_discard *d = (void *)dst; 85 d->nr_sectors = s->nr_sectors; 86 return; 87 } 88 /* prevent the compiler from optimizing the code and using src->nr_segments instead */ 89 barrier(); 90 if (n > dst->nr_segments) 91 n = dst->nr_segments; 92 for (i = 0; i < n; i++) 93 dst->seg[i] = src->seg[i]; 94 } 95 96 static inline void blkif_get_x86_64_req(blkif_request_t *dst, blkif_x86_64_request_t *src) 97 { 98 int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST; 99 100 dst->operation = src->operation; 101 dst->nr_segments = src->nr_segments; 102 dst->handle = src->handle; 103 dst->id = src->id; 104 dst->sector_number = src->sector_number; 105 if (src->operation == BLKIF_OP_DISCARD) { 106 struct blkif_request_discard *s = (void *)src; 107 struct blkif_request_discard *d = (void *)dst; 108 d->nr_sectors = s->nr_sectors; 109 return; 110 } 111 /* prevent the compiler from optimizing the code and using src->nr_segments instead */ 112 barrier(); 113 if (n > dst->nr_segments) 114 n = dst->nr_segments; 115 for (i = 0; i < n; i++) 116 dst->seg[i] = src->seg[i]; 117 } 118 119 #endif /* __XEN_BLKIF_H__ */ 120