diff options
author | Andy Pei <andy.pei@intel.com> | 2021-12-07 09:31:07 +0800 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2021-12-18 11:52:36 -0500 |
commit | 815d7498655b8207821d405bc49fa993702f456f (patch) | |
tree | 741d2213dccab49ac13e7c5db1dcd7b0d30532d7 | |
parent | 27b573d4f5a54f48f440ade9bcb5557a7d225979 (diff) | |
download | seabios-815d7498655b8207821d405bc49fa993702f456f.tar.gz |
virtio-blk: abstract a function named virtio_blk_op_one_segment to handle r/w request
abstract virtio-blk queue operation to form a function named virtio_blk_op_one_segment
Signed-off-by: Andy Pei <andy.pei@intel.com>
Signed-off-by: Ding Limin <dinglimin@cmss.chinamobile.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
-rw-r--r-- | src/hw/virtio-blk.c | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c index 2653dad2..82b1d2a8 100644 --- a/src/hw/virtio-blk.c +++ b/src/hw/virtio-blk.c @@ -30,12 +30,38 @@ struct virtiodrive_s { struct vp_device vp; }; +void +virtio_blk_op_one_segment(struct virtiodrive_s *vdrive, + int write, struct vring_list sg[]) +{ + struct vring_virtqueue *vq = vdrive->vq; + + /* Add to virtqueue and kick host */ + if (write) + vring_add_buf(vq, sg, 2, 1, 0, 0); + else + vring_add_buf(vq, sg, 1, 2, 0, 0); + vring_kick(&vdrive->vp, vq, 1); + + /* Wait for reply */ + while (!vring_more_used(vq)) + usleep(5); + + /* Reclaim virtqueue element */ + vring_get_buf(vq, NULL); + + /** + ** Clear interrupt status register. Avoid leaving interrupts stuck + ** if VRING_AVAIL_F_NO_INTERRUPT was ignored and interrupts were raised. + **/ + vp_get_isr(&vdrive->vp); +} + static int virtio_blk_op(struct disk_op_s *op, int write) { struct virtiodrive_s *vdrive = container_of(op->drive_fl, struct virtiodrive_s, drive); - struct vring_virtqueue *vq = vdrive->vq; struct virtio_blk_outhdr hdr = { .type = write ? VIRTIO_BLK_T_OUT : VIRTIO_BLK_T_IN, .ioprio = 0, @@ -57,25 +83,7 @@ virtio_blk_op(struct disk_op_s *op, int write) }, }; - /* Add to virtqueue and kick host */ - if (write) - vring_add_buf(vq, sg, 2, 1, 0, 0); - else - vring_add_buf(vq, sg, 1, 2, 0, 0); - vring_kick(&vdrive->vp, vq, 1); - - /* Wait for reply */ - while (!vring_more_used(vq)) - usleep(5); - - /* Reclaim virtqueue element */ - vring_get_buf(vq, NULL); - - /* Clear interrupt status register. Avoid leaving interrupts stuck if - * VRING_AVAIL_F_NO_INTERRUPT was ignored and interrupts were raised. - */ - vp_get_isr(&vdrive->vp); - + virtio_blk_op_one_segment(vdrive, write, sg); return status == VIRTIO_BLK_S_OK ? DISK_RET_SUCCESS : DISK_RET_EBADTRACK; } |