1 /* 2 * Virtio Block Device 3 * 4 * Copyright IBM, Corp. 2007 5 * 6 * Authors: 7 * Anthony Liguori <aliguori@us.ibm.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2. See 10 * the COPYING file in the top-level directory. 11 * 12 */ 13 14 #ifndef _QEMU_VIRTIO_BLK_H 15 #define _QEMU_VIRTIO_BLK_H 16 17 #include "hw/virtio/virtio.h" 18 #include "hw/block/block.h" 19 #include "sysemu/iothread.h" 20 #include "block/block.h" 21 22 #define TYPE_VIRTIO_BLK "virtio-blk-device" 23 #define VIRTIO_BLK(obj) \ 24 OBJECT_CHECK(VirtIOBlock, (obj), TYPE_VIRTIO_BLK) 25 26 /* from Linux's linux/virtio_blk.h */ 27 28 /* The ID for virtio_block */ 29 #define VIRTIO_ID_BLOCK 2 30 31 /* Feature bits */ 32 #define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */ 33 #define VIRTIO_BLK_F_SIZE_MAX 1 /* Indicates maximum segment size */ 34 #define VIRTIO_BLK_F_SEG_MAX 2 /* Indicates maximum # of segments */ 35 #define VIRTIO_BLK_F_GEOMETRY 4 /* Indicates support of legacy geometry */ 36 #define VIRTIO_BLK_F_RO 5 /* Disk is read-only */ 37 #define VIRTIO_BLK_F_BLK_SIZE 6 /* Block size of disk is available*/ 38 #define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru */ 39 /* #define VIRTIO_BLK_F_IDENTIFY 8 ATA IDENTIFY supported, DEPRECATED */ 40 #define VIRTIO_BLK_F_WCE 9 /* write cache enabled */ 41 #define VIRTIO_BLK_F_TOPOLOGY 10 /* Topology information is available */ 42 #define VIRTIO_BLK_F_CONFIG_WCE 11 /* write cache configurable */ 43 44 #define VIRTIO_BLK_ID_BYTES 20 /* ID string length */ 45 46 struct virtio_blk_config 47 { 48 uint64_t capacity; 49 uint32_t size_max; 50 uint32_t seg_max; 51 uint16_t cylinders; 52 uint8_t heads; 53 uint8_t sectors; 54 uint32_t blk_size; 55 uint8_t physical_block_exp; 56 uint8_t alignment_offset; 57 uint16_t min_io_size; 58 uint32_t opt_io_size; 59 uint8_t wce; 60 } QEMU_PACKED; 61 62 /* These two define direction. */ 63 #define VIRTIO_BLK_T_IN 0 64 #define VIRTIO_BLK_T_OUT 1 65 66 /* This bit says it's a scsi command, not an actual read or write. */ 67 #define VIRTIO_BLK_T_SCSI_CMD 2 68 69 /* Flush the volatile write cache */ 70 #define VIRTIO_BLK_T_FLUSH 4 71 72 /* return the device ID string */ 73 #define VIRTIO_BLK_T_GET_ID 8 74 75 /* Barrier before this op. */ 76 #define VIRTIO_BLK_T_BARRIER 0x80000000 77 78 /* This is the first element of the read scatter-gather list. */ 79 struct virtio_blk_outhdr 80 { 81 /* VIRTIO_BLK_T* */ 82 uint32_t type; 83 /* io priority. */ 84 uint32_t ioprio; 85 /* Sector (ie. 512 byte offset) */ 86 uint64_t sector; 87 }; 88 89 #define VIRTIO_BLK_S_OK 0 90 #define VIRTIO_BLK_S_IOERR 1 91 #define VIRTIO_BLK_S_UNSUPP 2 92 93 /* This is the last element of the write scatter-gather list */ 94 struct virtio_blk_inhdr 95 { 96 unsigned char status; 97 }; 98 99 /* SCSI pass-through header */ 100 struct virtio_scsi_inhdr 101 { 102 uint32_t errors; 103 uint32_t data_len; 104 uint32_t sense_len; 105 uint32_t residual; 106 }; 107 108 struct VirtIOBlkConf 109 { 110 BlockConf conf; 111 IOThread *iothread; 112 char *serial; 113 uint32_t scsi; 114 uint32_t config_wce; 115 uint32_t data_plane; 116 }; 117 118 struct VirtIOBlockDataPlane; 119 120 struct VirtIOBlockReq; 121 typedef struct VirtIOBlock { 122 VirtIODevice parent_obj; 123 BlockDriverState *bs; 124 VirtQueue *vq; 125 void *rq; 126 QEMUBH *bh; 127 BlockConf *conf; 128 VirtIOBlkConf blk; 129 unsigned short sector_mask; 130 bool original_wce; 131 VMChangeStateEntry *change; 132 /* Function to push to vq and notify guest */ 133 void (*complete_request)(struct VirtIOBlockReq *req, unsigned char status); 134 #ifdef CONFIG_VIRTIO_BLK_DATA_PLANE 135 Notifier migration_state_notifier; 136 struct VirtIOBlockDataPlane *dataplane; 137 #endif 138 } VirtIOBlock; 139 140 typedef struct MultiReqBuffer { 141 BlockRequest blkreq[32]; 142 unsigned int num_writes; 143 } MultiReqBuffer; 144 145 typedef struct VirtIOBlockReq { 146 VirtIOBlock *dev; 147 VirtQueueElement *elem; 148 struct virtio_blk_inhdr *in; 149 struct virtio_blk_outhdr out; 150 QEMUIOVector qiov; 151 struct VirtIOBlockReq *next; 152 BlockAcctCookie acct; 153 } VirtIOBlockReq; 154 155 int virtio_blk_handle_scsi_req(VirtIOBlock *blk, 156 VirtQueueElement *elem); 157 158 void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb); 159 160 void virtio_submit_multiwrite(BlockDriverState *bs, MultiReqBuffer *mrb); 161 162 #endif 163