Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

virtio_blk: v1.0 support

Based on patch by Cornelia Huck.

Note: for consistency, and to avoid sparse errors,
convert all fields, even those no longer in use
for virtio v1.0.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>




+49 -36
+41 -29
drivers/block/virtio_blk.c
··· 80 80 { 81 81 struct scatterlist hdr, status, cmd, sense, inhdr, *sgs[6]; 82 82 unsigned int num_out = 0, num_in = 0; 83 - int type = vbr->out_hdr.type & ~VIRTIO_BLK_T_OUT; 83 + __virtio32 type = vbr->out_hdr.type & ~cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_OUT); 84 84 85 85 sg_init_one(&hdr, &vbr->out_hdr, sizeof(vbr->out_hdr)); 86 86 sgs[num_out++] = &hdr; ··· 91 91 * block, and before the normal inhdr we put the sense data and the 92 92 * inhdr with additional status information. 93 93 */ 94 - if (type == VIRTIO_BLK_T_SCSI_CMD) { 94 + if (type == cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_SCSI_CMD)) { 95 95 sg_init_one(&cmd, vbr->req->cmd, vbr->req->cmd_len); 96 96 sgs[num_out++] = &cmd; 97 97 } 98 98 99 99 if (have_data) { 100 - if (vbr->out_hdr.type & VIRTIO_BLK_T_OUT) 100 + if (vbr->out_hdr.type & cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_OUT)) 101 101 sgs[num_out++] = data_sg; 102 102 else 103 103 sgs[num_out + num_in++] = data_sg; 104 104 } 105 105 106 - if (type == VIRTIO_BLK_T_SCSI_CMD) { 106 + if (type == cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_SCSI_CMD)) { 107 107 sg_init_one(&sense, vbr->req->sense, SCSI_SENSE_BUFFERSIZE); 108 108 sgs[num_out + num_in++] = &sense; 109 109 sg_init_one(&inhdr, &vbr->in_hdr, sizeof(vbr->in_hdr)); ··· 119 119 static inline void virtblk_request_done(struct request *req) 120 120 { 121 121 struct virtblk_req *vbr = blk_mq_rq_to_pdu(req); 122 + struct virtio_blk *vblk = req->q->queuedata; 122 123 int error = virtblk_result(vbr); 123 124 124 125 if (req->cmd_type == REQ_TYPE_BLOCK_PC) { 125 - req->resid_len = vbr->in_hdr.residual; 126 - req->sense_len = vbr->in_hdr.sense_len; 127 - req->errors = vbr->in_hdr.errors; 126 + req->resid_len = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.residual); 127 + req->sense_len = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.sense_len); 128 + req->errors = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.errors); 128 129 } else if (req->cmd_type == REQ_TYPE_SPECIAL) { 129 130 req->errors = (error != 0); 130 131 } ··· 174 173 175 174 vbr->req = req; 176 175 if (req->cmd_flags & REQ_FLUSH) { 177 - vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH; 176 + vbr->out_hdr.type = cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_FLUSH); 178 177 vbr->out_hdr.sector = 0; 179 - vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); 178 + vbr->out_hdr.ioprio = cpu_to_virtio32(vblk->vdev, req_get_ioprio(vbr->req)); 180 179 } else { 181 180 switch (req->cmd_type) { 182 181 case REQ_TYPE_FS: 183 182 vbr->out_hdr.type = 0; 184 - vbr->out_hdr.sector = blk_rq_pos(vbr->req); 185 - vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); 183 + vbr->out_hdr.sector = cpu_to_virtio64(vblk->vdev, blk_rq_pos(vbr->req)); 184 + vbr->out_hdr.ioprio = cpu_to_virtio32(vblk->vdev, req_get_ioprio(vbr->req)); 186 185 break; 187 186 case REQ_TYPE_BLOCK_PC: 188 - vbr->out_hdr.type = VIRTIO_BLK_T_SCSI_CMD; 187 + vbr->out_hdr.type = cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_SCSI_CMD); 189 188 vbr->out_hdr.sector = 0; 190 - vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); 189 + vbr->out_hdr.ioprio = cpu_to_virtio32(vblk->vdev, req_get_ioprio(vbr->req)); 191 190 break; 192 191 case REQ_TYPE_SPECIAL: 193 - vbr->out_hdr.type = VIRTIO_BLK_T_GET_ID; 192 + vbr->out_hdr.type = cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_GET_ID); 194 193 vbr->out_hdr.sector = 0; 195 - vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); 194 + vbr->out_hdr.ioprio = cpu_to_virtio32(vblk->vdev, req_get_ioprio(vbr->req)); 196 195 break; 197 196 default: 198 197 /* We don't put anything else in the queue. */ ··· 205 204 num = blk_rq_map_sg(hctx->queue, vbr->req, vbr->sg); 206 205 if (num) { 207 206 if (rq_data_dir(vbr->req) == WRITE) 208 - vbr->out_hdr.type |= VIRTIO_BLK_T_OUT; 207 + vbr->out_hdr.type |= cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_OUT); 209 208 else 210 - vbr->out_hdr.type |= VIRTIO_BLK_T_IN; 209 + vbr->out_hdr.type |= cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_IN); 211 210 } 212 211 213 212 spin_lock_irqsave(&vblk->vqs[qid].lock, flags); ··· 477 476 struct virtio_blk_config, wce, 478 477 &writeback); 479 478 if (err) 480 - writeback = virtio_has_feature(vdev, VIRTIO_BLK_F_WCE); 479 + writeback = virtio_has_feature(vdev, VIRTIO_BLK_F_WCE) || 480 + virtio_has_feature(vdev, VIRTIO_F_VERSION_1); 481 481 482 482 return writeback; 483 483 } ··· 823 821 { 0 }, 824 822 }; 825 823 826 - static unsigned int features[] = { 824 + static unsigned int features_legacy[] = { 827 825 VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_GEOMETRY, 828 826 VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE, VIRTIO_BLK_F_SCSI, 829 827 VIRTIO_BLK_F_WCE, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE, 830 828 VIRTIO_BLK_F_MQ, 829 + } 830 + ; 831 + static unsigned int features[] = { 832 + VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_GEOMETRY, 833 + VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE, 834 + VIRTIO_BLK_F_TOPOLOGY, 835 + VIRTIO_BLK_F_MQ, 836 + VIRTIO_F_VERSION_1, 831 837 }; 832 838 833 839 static struct virtio_driver virtio_blk = { 834 - .feature_table = features, 835 - .feature_table_size = ARRAY_SIZE(features), 836 - .driver.name = KBUILD_MODNAME, 837 - .driver.owner = THIS_MODULE, 838 - .id_table = id_table, 839 - .probe = virtblk_probe, 840 - .remove = virtblk_remove, 841 - .config_changed = virtblk_config_changed, 840 + .feature_table = features, 841 + .feature_table_size = ARRAY_SIZE(features), 842 + .feature_table_legacy = features_legacy, 843 + .feature_table_size_legacy = ARRAY_SIZE(features_legacy), 844 + .driver.name = KBUILD_MODNAME, 845 + .driver.owner = THIS_MODULE, 846 + .id_table = id_table, 847 + .probe = virtblk_probe, 848 + .remove = virtblk_remove, 849 + .config_changed = virtblk_config_changed, 842 850 #ifdef CONFIG_PM_SLEEP 843 - .freeze = virtblk_freeze, 844 - .restore = virtblk_restore, 851 + .freeze = virtblk_freeze, 852 + .restore = virtblk_restore, 845 853 #endif 846 854 }; 847 855
+8 -7
include/uapi/linux/virtio_blk.h
··· 28 28 #include <linux/types.h> 29 29 #include <linux/virtio_ids.h> 30 30 #include <linux/virtio_config.h> 31 + #include <linux/virtio_types.h> 31 32 32 33 /* Feature bits */ 33 34 #define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */ ··· 115 114 /* This is the first element of the read scatter-gather list. */ 116 115 struct virtio_blk_outhdr { 117 116 /* VIRTIO_BLK_T* */ 118 - __u32 type; 117 + __virtio32 type; 119 118 /* io priority. */ 120 - __u32 ioprio; 119 + __virtio32 ioprio; 121 120 /* Sector (ie. 512 byte offset) */ 122 - __u64 sector; 121 + __virtio64 sector; 123 122 }; 124 123 125 124 struct virtio_scsi_inhdr { 126 - __u32 errors; 127 - __u32 data_len; 128 - __u32 sense_len; 129 - __u32 residual; 125 + __virtio32 errors; 126 + __virtio32 data_len; 127 + __virtio32 sense_len; 128 + __virtio32 residual; 130 129 }; 131 130 132 131 /* And this is the final byte of the write scatter-gather list. */