26ba25
From 84621d8aa40cb29508b5730c46666c645851bbfd Mon Sep 17 00:00:00 2001
26ba25
From: Paolo Bonzini <pbonzini@redhat.com>
26ba25
Date: Thu, 20 Dec 2018 12:30:57 +0000
26ba25
Subject: [PATCH 2/8] hw/scsi: centralize SG_IO calls into single function
26ba25
MIME-Version: 1.0
26ba25
Content-Type: text/plain; charset=UTF-8
26ba25
Content-Transfer-Encoding: 8bit
26ba25
26ba25
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
26ba25
Message-id: <20181220123103.29579-3-pbonzini@redhat.com>
26ba25
Patchwork-id: 83711
26ba25
O-Subject: [PATCH 2/8] hw/scsi: centralize SG_IO calls into single function
26ba25
Bugzilla: 1639957
26ba25
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
26ba25
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
26ba25
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
26ba25
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
26ba25
26ba25
From: Daniel Henrique Barboza <danielhb413@gmail.com>
26ba25
26ba25
For the VPD Block Limits emulation with SCSI passthrough,
26ba25
we'll issue an Inquiry request with EVPD set to retrieve
26ba25
the available VPD pages of the device. This would be done in
26ba25
a way similar of what scsi_generic_read_device_identification
26ba25
does: create a SCSI command and a reply buffer, fill in the
26ba25
sg_io_hdr_t structure, call blk_ioctl, check if an error
26ba25
occurred, process the response.
26ba25
26ba25
This same process is done in other 2 functions, get_device_type
26ba25
and get_stream_blocksize. They differ in the command/reply
26ba25
buffer and post-processing, everything else is almost a
26ba25
copy/paste.
26ba25
26ba25
Instead of adding a forth copy/pasted-ish code when adding
26ba25
the passthrough VPD BL emulation, this patch extirpates
26ba25
this repetition of those 3 functions and put it into
26ba25
a new one called scsi_SG_IO_FROM_DEV. Any future code that
26ba25
wants to execute an SG_DXFER_FROM_DEV to the device can
26ba25
use it, avoiding filling sg_io_hdr_t again and et cetera.
26ba25
26ba25
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
26ba25
Message-Id: <20180627172432.11120-3-danielhb413@gmail.com>
26ba25
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
26ba25
(cherry picked from commit a0c7e35b17b3d2cade8a5fc8e57904e02fb91fe4)
26ba25
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
26ba25
---
26ba25
 hw/scsi/scsi-disk.c    | 18 +++------------
26ba25
 hw/scsi/scsi-generic.c | 61 +++++++++++++++++++++++++-------------------------
26ba25
 include/hw/scsi/scsi.h |  2 ++
26ba25
 3 files changed, 36 insertions(+), 45 deletions(-)
26ba25
26ba25
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
26ba25
index ae5b4c0..ea86849 100644
26ba25
--- a/hw/scsi/scsi-disk.c
26ba25
+++ b/hw/scsi/scsi-disk.c
26ba25
@@ -2579,8 +2579,6 @@ static int get_device_type(SCSIDiskState *s)
26ba25
 {
26ba25
     uint8_t cmd[16];
26ba25
     uint8_t buf[36];
26ba25
-    uint8_t sensebuf[8];
26ba25
-    sg_io_hdr_t io_header;
26ba25
     int ret;
26ba25
 
26ba25
     memset(cmd, 0, sizeof(cmd));
26ba25
@@ -2588,19 +2586,9 @@ static int get_device_type(SCSIDiskState *s)
26ba25
     cmd[0] = INQUIRY;
26ba25
     cmd[4] = sizeof(buf);
26ba25
 
26ba25
-    memset(&io_header, 0, sizeof(io_header));
26ba25
-    io_header.interface_id = 'S';
26ba25
-    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
26ba25
-    io_header.dxfer_len = sizeof(buf);
26ba25
-    io_header.dxferp = buf;
26ba25
-    io_header.cmdp = cmd;
26ba25
-    io_header.cmd_len = sizeof(cmd);
26ba25
-    io_header.mx_sb_len = sizeof(sensebuf);
26ba25
-    io_header.sbp = sensebuf;
26ba25
-    io_header.timeout = 6000; /* XXX */
26ba25
-
26ba25
-    ret = blk_ioctl(s->qdev.conf.blk, SG_IO, &io_header);
26ba25
-    if (ret < 0 || io_header.driver_status || io_header.host_status) {
26ba25
+    ret = scsi_SG_IO_FROM_DEV(s->qdev.conf.blk, cmd, sizeof(cmd),
26ba25
+                              buf, sizeof(buf));
26ba25
+    if (ret < 0) {
26ba25
         return -1;
26ba25
     }
26ba25
     s->qdev.type = buf[0];
26ba25
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
26ba25
index 796162c..c6307a8 100644
26ba25
--- a/hw/scsi/scsi-generic.c
26ba25
+++ b/hw/scsi/scsi-generic.c
26ba25
@@ -410,35 +410,48 @@ static int read_naa_id(const uint8_t *p, uint64_t *p_wwn)
26ba25
     return -EINVAL;
26ba25
 }
26ba25
 
26ba25
-void scsi_generic_read_device_identification(SCSIDevice *s)
26ba25
+int scsi_SG_IO_FROM_DEV(BlockBackend *blk, uint8_t *cmd, uint8_t cmd_size,
26ba25
+                        uint8_t *buf, uint8_t buf_size)
26ba25
 {
26ba25
-    uint8_t cmd[6];
26ba25
-    uint8_t buf[250];
26ba25
-    uint8_t sensebuf[8];
26ba25
     sg_io_hdr_t io_header;
26ba25
+    uint8_t sensebuf[8];
26ba25
     int ret;
26ba25
-    int i, len;
26ba25
-
26ba25
-    memset(cmd, 0, sizeof(cmd));
26ba25
-    memset(buf, 0, sizeof(buf));
26ba25
-    cmd[0] = INQUIRY;
26ba25
-    cmd[1] = 1;
26ba25
-    cmd[2] = 0x83;
26ba25
-    cmd[4] = sizeof(buf);
26ba25
 
26ba25
     memset(&io_header, 0, sizeof(io_header));
26ba25
     io_header.interface_id = 'S';
26ba25
     io_header.dxfer_direction = SG_DXFER_FROM_DEV;
26ba25
-    io_header.dxfer_len = sizeof(buf);
26ba25
+    io_header.dxfer_len = buf_size;
26ba25
     io_header.dxferp = buf;
26ba25
     io_header.cmdp = cmd;
26ba25
-    io_header.cmd_len = sizeof(cmd);
26ba25
+    io_header.cmd_len = cmd_size;
26ba25
     io_header.mx_sb_len = sizeof(sensebuf);
26ba25
     io_header.sbp = sensebuf;
26ba25
     io_header.timeout = 6000; /* XXX */
26ba25
 
26ba25
-    ret = blk_ioctl(s->conf.blk, SG_IO, &io_header);
26ba25
+    ret = blk_ioctl(blk, SG_IO, &io_header);
26ba25
     if (ret < 0 || io_header.driver_status || io_header.host_status) {
26ba25
+        return -1;
26ba25
+    }
26ba25
+    return 0;
26ba25
+}
26ba25
+
26ba25
+void scsi_generic_read_device_identification(SCSIDevice *s)
26ba25
+{
26ba25
+    uint8_t cmd[6];
26ba25
+    uint8_t buf[250];
26ba25
+    int ret;
26ba25
+    int i, len;
26ba25
+
26ba25
+    memset(cmd, 0, sizeof(cmd));
26ba25
+    memset(buf, 0, sizeof(buf));
26ba25
+    cmd[0] = INQUIRY;
26ba25
+    cmd[1] = 1;
26ba25
+    cmd[2] = 0x83;
26ba25
+    cmd[4] = sizeof(buf);
26ba25
+
26ba25
+    ret = scsi_SG_IO_FROM_DEV(s->conf.blk, cmd, sizeof(cmd),
26ba25
+                              buf, sizeof(buf));
26ba25
+    if (ret < 0) {
26ba25
         return;
26ba25
     }
26ba25
 
26ba25
@@ -471,8 +484,6 @@ static int get_stream_blocksize(BlockBackend *blk)
26ba25
 {
26ba25
     uint8_t cmd[6];
26ba25
     uint8_t buf[12];
26ba25
-    uint8_t sensebuf[8];
26ba25
-    sg_io_hdr_t io_header;
26ba25
     int ret;
26ba25
 
26ba25
     memset(cmd, 0, sizeof(cmd));
26ba25
@@ -480,21 +491,11 @@ static int get_stream_blocksize(BlockBackend *blk)
26ba25
     cmd[0] = MODE_SENSE;
26ba25
     cmd[4] = sizeof(buf);
26ba25
 
26ba25
-    memset(&io_header, 0, sizeof(io_header));
26ba25
-    io_header.interface_id = 'S';
26ba25
-    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
26ba25
-    io_header.dxfer_len = sizeof(buf);
26ba25
-    io_header.dxferp = buf;
26ba25
-    io_header.cmdp = cmd;
26ba25
-    io_header.cmd_len = sizeof(cmd);
26ba25
-    io_header.mx_sb_len = sizeof(sensebuf);
26ba25
-    io_header.sbp = sensebuf;
26ba25
-    io_header.timeout = 6000; /* XXX */
26ba25
-
26ba25
-    ret = blk_ioctl(blk, SG_IO, &io_header);
26ba25
-    if (ret < 0 || io_header.driver_status || io_header.host_status) {
26ba25
+    ret = scsi_SG_IO_FROM_DEV(blk, cmd, sizeof(cmd), buf, sizeof(buf));
26ba25
+    if (ret < 0) {
26ba25
         return -1;
26ba25
     }
26ba25
+
26ba25
     return (buf[9] << 16) | (buf[10] << 8) | buf[11];
26ba25
 }
26ba25
 
26ba25
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
26ba25
index 5930a43..b6e05c4 100644
26ba25
--- a/include/hw/scsi/scsi.h
26ba25
+++ b/include/hw/scsi/scsi.h
26ba25
@@ -189,6 +189,8 @@ void scsi_device_unit_attention_reported(SCSIDevice *dev);
26ba25
 void scsi_generic_read_device_identification(SCSIDevice *dev);
26ba25
 int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed);
26ba25
 int scsi_disk_emulate_vpd_page(SCSIRequest *req, uint8_t *outbuf);
26ba25
+int scsi_SG_IO_FROM_DEV(BlockBackend *blk, uint8_t *cmd, uint8_t cmd_size,
26ba25
+                        uint8_t *buf, uint8_t buf_size);
26ba25
 SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, int lun);
26ba25
 
26ba25
 /* scsi-generic.c. */
26ba25
-- 
26ba25
1.8.3.1
26ba25