[SeaBIOS] [PATCH 12/17] virtio-scsi: Handle virtio drives directly via 'struct disk_op_s' requests
Kevin O'Connor
kevin at koconnor.net
Tue Jul 7 21:26:16 CEST 2015
Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
src/block.c | 2 ++
src/hw/blockcmd.c | 4 ----
src/hw/virtio-scsi.c | 37 +++++++++++++++----------------------
src/hw/virtio-scsi.h | 2 +-
4 files changed, 18 insertions(+), 27 deletions(-)
diff --git a/src/block.c b/src/block.c
index d4bf029..422e2a2 100644
--- a/src/block.c
+++ b/src/block.c
@@ -18,6 +18,7 @@
#include "hw/usb-msc.h" // usb_process_op
#include "hw/usb-uas.h" // uas_process_op
#include "hw/virtio-blk.h" // process_virtio_blk_op
+#include "hw/virtio-scsi.h" // virtio_scsi_process_op
#include "malloc.h" // malloc_low
#include "output.h" // dprintf
#include "stacks.h" // stack_hop
@@ -535,6 +536,7 @@ process_op_32(struct disk_op_s *op)
case DTYPE_UAS_32:
return uas_process_op(op);
case DTYPE_VIRTIO_SCSI:
+ return virtio_scsi_process_op(op);
case DTYPE_PVSCSI:
return scsi_process_op(op);
default:
diff --git a/src/hw/blockcmd.c b/src/hw/blockcmd.c
index b0a512b..684f420 100644
--- a/src/hw/blockcmd.c
+++ b/src/hw/blockcmd.c
@@ -14,7 +14,6 @@
#include "std/disk.h" // DISK_RET_EPARAM
#include "string.h" // memset
#include "util.h" // timer_calc
-#include "virtio-scsi.h" // virtio_scsi_cmd_data
// Route command to low-level handler.
static int
@@ -22,9 +21,6 @@ cdb_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize)
{
u8 type = GET_GLOBALFLAT(op->drive_gf->type);
switch (type) {
- case DTYPE_VIRTIO_SCSI:
- if (!MODESEGMENT)
- return virtio_scsi_cmd_data(op, cdbcmd, blocksize);
case DTYPE_PVSCSI:
if (!MODESEGMENT)
return pvscsi_cmd_data(op, cdbcmd, blocksize);
diff --git a/src/hw/virtio-scsi.c b/src/hw/virtio-scsi.c
index cb825d4..8cdcfd0 100644
--- a/src/hw/virtio-scsi.c
+++ b/src/hw/virtio-scsi.c
@@ -32,24 +32,30 @@ struct virtio_lun_s {
u16 lun;
};
-static int
-virtio_scsi_cmd(struct vp_device *vp, struct vring_virtqueue *vq,
- struct disk_op_s *op, void *cdbcmd, u16 target, u16 lun,
- u16 blocksize)
+int
+virtio_scsi_process_op(struct disk_op_s *op)
{
+ if (! CONFIG_VIRTIO_SCSI)
+ return 0;
+ struct virtio_lun_s *vlun =
+ container_of(op->drive_gf, struct virtio_lun_s, drive);
+ struct vp_device *vp = vlun->vp;
+ struct vring_virtqueue *vq = vlun->vq;
struct virtio_scsi_req_cmd req;
struct virtio_scsi_resp_cmd resp;
struct vring_list sg[3];
memset(&req, 0, sizeof(req));
+ int blocksize = scsi_fill_cmd(op, req.cdb, 16);
+ if (blocksize < 0)
+ return default_process_op(op);
req.lun[0] = 1;
- req.lun[1] = target;
- req.lun[2] = (lun >> 8) | 0x40;
- req.lun[3] = (lun & 0xff);
- memcpy(req.cdb, cdbcmd, 16);
+ req.lun[1] = vlun->target;
+ req.lun[2] = (vlun->lun >> 8) | 0x40;
+ req.lun[3] = (vlun->lun & 0xff);
u32 len = op->count * blocksize;
- int datain = cdb_is_read(cdbcmd, blocksize);
+ int datain = cdb_is_read((u8*)req.cdb, blocksize);
int in_num = (datain ? 2 : 1);
int out_num = (len ? 3 : 2) - in_num;
@@ -87,19 +93,6 @@ virtio_scsi_cmd(struct vp_device *vp, struct vring_virtqueue *vq,
return DISK_RET_EBADTRACK;
}
-int
-virtio_scsi_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize)
-{
- struct virtio_lun_s *vlun_gf =
- container_of(op->drive_gf, struct virtio_lun_s, drive);
-
- return virtio_scsi_cmd(vlun_gf->vp,
- vlun_gf->vq, op, cdbcmd,
- vlun_gf->target,
- vlun_gf->lun,
- blocksize);
-}
-
static int
virtio_scsi_add_lun(struct pci_device *pci, struct vp_device *vp,
struct vring_virtqueue *vq, u16 target, u16 lun)
diff --git a/src/hw/virtio-scsi.h b/src/hw/virtio-scsi.h
index 96c3701..7532cc9 100644
--- a/src/hw/virtio-scsi.h
+++ b/src/hw/virtio-scsi.h
@@ -41,7 +41,7 @@ struct virtio_scsi_resp_cmd {
#define VIRTIO_SCSI_S_OK 0
struct disk_op_s;
-int virtio_scsi_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize);
+int virtio_scsi_process_op(struct disk_op_s *op);
void virtio_scsi_setup(void);
#endif /* _VIRTIO_SCSI_H */
--
1.9.3
More information about the SeaBIOS
mailing list