yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone

Blame SOURCES/kvm-hw-scsi-centralize-SG_IO-calls-into-single-function.patch

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