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