Date: Tue, 19 Jan 2021 05:08:08 GMT From: Bryan Venteicher <bryanv@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 15be49535dce - main - virtio_scsi: Add modern (V1) support Message-ID: <202101190508.10J588ox085701@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by bryanv: URL: https://cgit.FreeBSD.org/src/commit/?id=15be49535dce17e5ad70755491162a8b6e4d5d72 commit 15be49535dce17e5ad70755491162a8b6e4d5d72 Author: Bryan Venteicher <bryanv@FreeBSD.org> AuthorDate: 2021-01-19 04:55:24 +0000 Commit: Bryan Venteicher <bryanv@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202101190508.10J588ox085701>