git: 15be49535dce - main - virtio_scsi: Add modern (V1) support
Bryan Venteicher
bryanv at FreeBSD.org
Tue Jan 19 05:08:14 UTC 2021
The branch main has been updated by bryanv:
URL: https://cgit.FreeBSD.org/src/commit/?id=15be49535dce17e5ad70755491162a8b6e4d5d72
commit 15be49535dce17e5ad70755491162a8b6e4d5d72
Author: Bryan Venteicher <bryanv at FreeBSD.org>
AuthorDate: 2021-01-19 04:55:24 +0000
Commit: Bryan Venteicher <bryanv at FreeBSD.org>
CommitDate: 2021-01-19 04:55:24 +0000
virtio_scsi: Add modern (V1) support
Reviewed by: grehan (mentor)
Differential Revision: https://reviews.freebsd.org/D27903
---
sys/dev/virtio/scsi/virtio_scsi.c | 61 ++++++++++++++++++++++++---------------
sys/dev/virtio/scsi/virtio_scsi.h | 39 ++++++++++++++++++++-----
2 files changed, 69 insertions(+), 31 deletions(-)
diff --git a/sys/dev/virtio/scsi/virtio_scsi.c b/sys/dev/virtio/scsi/virtio_scsi.c
index 332f71ef26bf..f4c716af3725 100644
--- a/sys/dev/virtio/scsi/virtio_scsi.c
+++ b/sys/dev/virtio/scsi/virtio_scsi.c
@@ -135,10 +135,10 @@ static int vtscsi_execute_reset_dev_cmd(struct vtscsi_softc *,
static void vtscsi_get_request_lun(uint8_t [], target_id_t *, lun_id_t *);
static void vtscsi_set_request_lun(struct ccb_hdr *, uint8_t []);
-static void vtscsi_init_scsi_cmd_req(struct ccb_scsiio *,
- struct virtio_scsi_cmd_req *);
-static void vtscsi_init_ctrl_tmf_req(struct ccb_hdr *, uint32_t,
- uintptr_t, struct virtio_scsi_ctrl_tmf_req *);
+static void vtscsi_init_scsi_cmd_req(struct vtscsi_softc *,
+ struct ccb_scsiio *, struct virtio_scsi_cmd_req *);
+static void vtscsi_init_ctrl_tmf_req(struct vtscsi_softc *, struct ccb_hdr *,
+ uint32_t, uintptr_t, struct virtio_scsi_ctrl_tmf_req *);
static void vtscsi_freeze_simq(struct vtscsi_softc *, int);
static int vtscsi_thaw_simq(struct vtscsi_softc *, int);
@@ -189,6 +189,14 @@ static void vtscsi_add_sysctl(struct vtscsi_softc *);
static void vtscsi_printf_req(struct vtscsi_request *, const char *,
const char *, ...);
+#define vtscsi_modern(_sc) (((_sc)->vtscsi_features & VIRTIO_F_VERSION_1) != 0)
+#define vtscsi_htog16(_sc, _val) virtio_htog16(vtscsi_modern(_sc), _val)
+#define vtscsi_htog32(_sc, _val) virtio_htog32(vtscsi_modern(_sc), _val)
+#define vtscsi_htog64(_sc, _val) virtio_htog64(vtscsi_modern(_sc), _val)
+#define vtscsi_gtoh16(_sc, _val) virtio_gtoh16(vtscsi_modern(_sc), _val)
+#define vtscsi_gtoh32(_sc, _val) virtio_gtoh32(vtscsi_modern(_sc), _val)
+#define vtscsi_gtoh64(_sc, _val) virtio_gtoh64(vtscsi_modern(_sc), _val)
+
/* Global tunables. */
/*
* The current QEMU VirtIO SCSI implementation does not cancel in-flight
@@ -206,6 +214,9 @@ TUNABLE_INT("hw.vtscsi.bus_reset_disable", &vtscsi_bus_reset_disable);
static struct virtio_feature_desc vtscsi_feature_desc[] = {
{ VIRTIO_SCSI_F_INOUT, "InOut" },
{ VIRTIO_SCSI_F_HOTPLUG, "Hotplug" },
+ { VIRTIO_SCSI_F_CHANGE, "ChangeEvent" },
+ { VIRTIO_SCSI_F_T10_PI, "T10PI" },
+
{ 0, NULL }
};
@@ -409,8 +420,10 @@ vtscsi_negotiate_features(struct vtscsi_softc *sc)
uint64_t features;
dev = sc->vtscsi_dev;
- features = virtio_negotiate_features(dev, VTSCSI_FEATURES);
- sc->vtscsi_features = features;
+ features = VTSCSI_FEATURES;
+
+ sc->vtscsi_features = virtio_negotiate_features(dev, features);
+ virtio_finalize_features(dev);
}
#define VTSCSI_GET_CONFIG(_dev, _field, _cfg) \
@@ -530,8 +543,8 @@ vtscsi_reinit(struct vtscsi_softc *sc)
error = virtio_reinit(dev, sc->vtscsi_features);
if (error == 0) {
vtscsi_write_device_config(sc);
- vtscsi_reinit_event_vq(sc);
virtio_reinit_complete(dev);
+ vtscsi_reinit_event_vq(sc);
vtscsi_enable_vqs_intr(sc);
}
@@ -1085,7 +1098,7 @@ vtscsi_execute_scsi_cmd(struct vtscsi_softc *sc, struct vtscsi_request *req)
cmd_req = &req->vsr_cmd_req;
cmd_resp = &req->vsr_cmd_resp;
- vtscsi_init_scsi_cmd_req(csio, cmd_req);
+ vtscsi_init_scsi_cmd_req(sc, csio, cmd_req);
error = vtscsi_fill_scsi_cmd_sglist(sc, req, &readable, &writable);
if (error)
@@ -1205,7 +1218,7 @@ vtscsi_abort_timedout_scsi_cmd(struct vtscsi_softc *sc,
tmf_req = &req->vsr_tmf_req;
tmf_resp = &req->vsr_tmf_resp;
- vtscsi_init_ctrl_tmf_req(to_ccbh, VIRTIO_SCSI_T_TMF_ABORT_TASK,
+ vtscsi_init_ctrl_tmf_req(sc, to_ccbh, VIRTIO_SCSI_T_TMF_ABORT_TASK,
(uintptr_t) to_ccbh, tmf_req);
sglist_reset(sg);
@@ -1313,22 +1326,24 @@ static cam_status
vtscsi_complete_scsi_cmd_response(struct vtscsi_softc *sc,
struct ccb_scsiio *csio, struct virtio_scsi_cmd_resp *cmd_resp)
{
+ uint32_t resp_sense_length;
cam_status status;
csio->scsi_status = cmd_resp->status;
- csio->resid = cmd_resp->resid;
+ csio->resid = vtscsi_htog32(sc, cmd_resp->resid);
if (csio->scsi_status == SCSI_STATUS_OK)
status = CAM_REQ_CMP;
else
status = CAM_SCSI_STATUS_ERROR;
- if (cmd_resp->sense_len > 0) {
+ resp_sense_length = vtscsi_htog32(sc, cmd_resp->sense_len);
+
+ if (resp_sense_length > 0) {
status |= CAM_AUTOSNS_VALID;
- if (cmd_resp->sense_len < csio->sense_len)
- csio->sense_resid = csio->sense_len -
- cmd_resp->sense_len;
+ if (resp_sense_length < csio->sense_len)
+ csio->sense_resid = csio->sense_len - resp_sense_length;
else
csio->sense_resid = 0;
@@ -1493,7 +1508,7 @@ vtscsi_execute_abort_task_cmd(struct vtscsi_softc *sc,
if (abort_req->vsr_flags & VTSCSI_REQ_FLAG_TIMEOUT_SET)
callout_stop(&abort_req->vsr_callout);
- vtscsi_init_ctrl_tmf_req(ccbh, VIRTIO_SCSI_T_TMF_ABORT_TASK,
+ vtscsi_init_ctrl_tmf_req(sc, ccbh, VIRTIO_SCSI_T_TMF_ABORT_TASK,
(uintptr_t) abort_ccbh, tmf_req);
sglist_reset(sg);
@@ -1562,7 +1577,7 @@ vtscsi_execute_reset_dev_cmd(struct vtscsi_softc *sc,
else
subtype = VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET;
- vtscsi_init_ctrl_tmf_req(ccbh, subtype, 0, tmf_req);
+ vtscsi_init_ctrl_tmf_req(sc, ccbh, subtype, 0, tmf_req);
sglist_reset(sg);
sglist_append(sg, tmf_req, sizeof(struct virtio_scsi_ctrl_tmf_req));
@@ -1599,7 +1614,7 @@ vtscsi_set_request_lun(struct ccb_hdr *ccbh, uint8_t lun[])
}
static void
-vtscsi_init_scsi_cmd_req(struct ccb_scsiio *csio,
+vtscsi_init_scsi_cmd_req(struct vtscsi_softc *sc, struct ccb_scsiio *csio,
struct virtio_scsi_cmd_req *cmd_req)
{
uint8_t attr;
@@ -1620,7 +1635,7 @@ vtscsi_init_scsi_cmd_req(struct ccb_scsiio *csio,
}
vtscsi_set_request_lun(&csio->ccb_h, cmd_req->lun);
- cmd_req->tag = (uintptr_t) csio;
+ cmd_req->tag = vtscsi_gtoh64(sc, (uintptr_t) csio);
cmd_req->task_attr = attr;
memcpy(cmd_req->cdb,
@@ -1630,15 +1645,15 @@ vtscsi_init_scsi_cmd_req(struct ccb_scsiio *csio,
}
static void
-vtscsi_init_ctrl_tmf_req(struct ccb_hdr *ccbh, uint32_t subtype,
- uintptr_t tag, struct virtio_scsi_ctrl_tmf_req *tmf_req)
+vtscsi_init_ctrl_tmf_req(struct vtscsi_softc *sc, struct ccb_hdr *ccbh,
+ uint32_t subtype, uintptr_t tag, struct virtio_scsi_ctrl_tmf_req *tmf_req)
{
vtscsi_set_request_lun(ccbh, tmf_req->lun);
- tmf_req->type = VIRTIO_SCSI_T_TMF;
- tmf_req->subtype = subtype;
- tmf_req->tag = tag;
+ tmf_req->type = vtscsi_gtoh32(sc, VIRTIO_SCSI_T_TMF);
+ tmf_req->subtype = vtscsi_gtoh32(sc, subtype);
+ tmf_req->tag = vtscsi_gtoh64(sc, tag);
}
static void
diff --git a/sys/dev/virtio/scsi/virtio_scsi.h b/sys/dev/virtio/scsi/virtio_scsi.h
index 9a9c5232dfee..c4435559f4e6 100644
--- a/sys/dev/virtio/scsi/virtio_scsi.h
+++ b/sys/dev/virtio/scsi/virtio_scsi.h
@@ -31,13 +31,7 @@
#ifndef _VIRTIO_SCSI_H
#define _VIRTIO_SCSI_H
-/* Feature bits */
-#define VIRTIO_SCSI_F_INOUT 0x0001 /* Single request can contain both
- * read and write buffers */
-#define VIRTIO_SCSI_F_HOTPLUG 0x0002 /* Host should enable hot plug/unplug
- * of new LUNs and targets.
- */
-
+/* Default values of the CDB and sense data size configuration fields */
#define VIRTIO_SCSI_CDB_SIZE 32
#define VIRTIO_SCSI_SENSE_SIZE 96
@@ -46,8 +40,20 @@ struct virtio_scsi_cmd_req {
uint8_t lun[8]; /* Logical Unit Number */
uint64_t tag; /* Command identifier */
uint8_t task_attr; /* Task attribute */
- uint8_t prio;
+ uint8_t prio; /* SAM command priority field */
+ uint8_t crn;
+ uint8_t cdb[VIRTIO_SCSI_CDB_SIZE];
+} __packed;
+
+/* SCSI command request, followed by protection information */
+struct virtio_scsi_cmd_req_pi {
+ uint8_t lun[8]; /* Logical Unit Number */
+ uint64_t tag; /* Command identifier */
+ uint8_t task_attr; /* Task attribute */
+ uint8_t prio; /* SAM command priority field */
uint8_t crn;
+ uint32_t pi_bytesout; /* DataOUT PI Number of bytes */
+ uint32_t pi_bytesin; /* DataIN PI Number of bytes */
uint8_t cdb[VIRTIO_SCSI_CDB_SIZE];
} __packed;
@@ -104,6 +110,22 @@ struct virtio_scsi_config {
uint32_t max_lun;
} __packed;
+/* Feature bits */
+#define VIRTIO_SCSI_F_INOUT 0x0001 /* Single request can contain both
+ * read and write buffers.
+ */
+#define VIRTIO_SCSI_F_HOTPLUG 0x0002 /* Host should enable hot plug/unplug
+ * of new LUNs and targets.
+ */
+#define VIRTIO_SCSI_F_CHANGE 0x0004 /* Host will report changes to LUN
+ * parameters via a
+ * VIRTIO_SCSI_T_PARAM_CHANGE event.
+ */
+#define VIRTIO_SCSI_F_T10_PI 0x0008 /* Extended fields for T10 protection
+ * information (DIF/DIX) are included
+ * in the SCSI request header.
+ */
+
/* Response codes */
#define VIRTIO_SCSI_S_OK 0
#define VIRTIO_SCSI_S_FUNCTION_COMPLETE 0
@@ -140,6 +162,7 @@ struct virtio_scsi_config {
#define VIRTIO_SCSI_T_NO_EVENT 0
#define VIRTIO_SCSI_T_TRANSPORT_RESET 1
#define VIRTIO_SCSI_T_ASYNC_NOTIFY 2
+#define VIRTIO_SCSI_T_PARAM_CHANGE 3
/* Reasons of transport reset event */
#define VIRTIO_SCSI_EVT_RESET_HARD 0
More information about the dev-commits-src-main
mailing list