aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2020-10-25 19:34:02 +0000
committerAlexander Motin <mav@FreeBSD.org>2020-10-25 19:34:02 +0000
commit883649681528398dc227778882830fc9da0ce58c (patch)
treee723924a03b24e3f8e7969d4016ff5c79df76e94 /sys
parent98b04ac35965fa0735c06a4966c6939f8009509e (diff)
downloadsrc-883649681528398dc227778882830fc9da0ce58c.tar.gz
src-883649681528398dc227778882830fc9da0ce58c.zip
Introduce support of SCSI Command Priority.
SAM-3 specification introduced concept of Task Priority, that was renamed to Command Priority in SAM-4, and supported by all modern SCSI transports. It provides 15 levels of relative priorities: 1 - highest, 15 - lowest and 0 - default. SAT specification for SATA devices translates priorities 1-3 into NCQ high priority. This change adds new "priority" field into empty spots of struct ccb_scsiio and struct ccb_accept_tio of CAM and struct ctl_scsiio of CTL. Respective support is added into iscsi(4), isp(4), mpr(4), mps(4) and ocs_fc(4) drivers for both initiator and where applicable target roles. Minimal support was added to CTL to receive the priority value from different frontends, pass it between HA controllers and report in few places. This patch does not add consumers of this functionality, so nothing should really change yet, since the field is still set to 0 (default) on initiator and not actively used on target. Those are to be implemented separately. I've confirmed priority working on WD Red SATA disks connected via mpr(4) and properly transferred to CTL target via iscsi(4), isp(4) and ocs_fc(4). While there, added missing tag_action support to ocs_fc(4) initiator role. MFC after: 1 month Relnotes: yes Sponsored by: iXsystems, Inc.
Notes
Notes: svn path=/head/; revision=367044
Diffstat (limited to 'sys')
-rw-r--r--sys/cam/cam_ccb.h4
-rw-r--r--sys/cam/ctl/ctl.c22
-rw-r--r--sys/cam/ctl/ctl_frontend_cam_sim.c1
-rw-r--r--sys/cam/ctl/ctl_frontend_iscsi.c2
-rw-r--r--sys/cam/ctl/ctl_io.h2
-rw-r--r--sys/cam/ctl/ctl_util.c5
-rw-r--r--sys/cam/ctl/scsi_ctl.c1
-rw-r--r--sys/dev/iscsi/iscsi.c5
-rw-r--r--sys/dev/isp/isp.c4
-rw-r--r--sys/dev/isp/isp_freebsd.c2
-rw-r--r--sys/dev/isp/isp_freebsd.h3
-rw-r--r--sys/dev/isp/isp_stds.h3
-rw-r--r--sys/dev/isp/ispvar.h1
-rw-r--r--sys/dev/mpr/mpr_sas.c2
-rw-r--r--sys/dev/mps/mps_sas.c2
-rw-r--r--sys/dev/ocs_fc/ocs_cam.c33
-rw-r--r--sys/dev/ocs_fc/ocs_scsi.c34
-rw-r--r--sys/dev/ocs_fc/ocs_scsi.h11
-rw-r--r--sys/dev/ocs_fc/ocs_unsol.c1
19 files changed, 105 insertions, 33 deletions
diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h
index 3ec0c5fc74ed..5fe6422ecc70 100644
--- a/sys/cam/cam_ccb.h
+++ b/sys/cam/cam_ccb.h
@@ -758,6 +758,7 @@ struct ccb_scsiio {
* from scsi_message.h.
*/
#define CAM_TAG_ACTION_NONE 0x00
+ uint8_t priority; /* Command priority for SIMPLE tag */
u_int tag_id; /* tag id from initator (target mode) */
u_int init_id; /* initiator id of who selected */
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
@@ -805,6 +806,7 @@ struct ccb_accept_tio {
u_int8_t cdb_len; /* Number of bytes for the CDB */
u_int8_t tag_action; /* What to do for tag queueing */
u_int8_t sense_len; /* Number of bytes of Sense Data */
+ uint8_t priority; /* Command priority for SIMPLE tag */
u_int tag_id; /* tag id from initator (target mode) */
u_int init_id; /* initiator id of who selected */
struct scsi_sense_data sense_data;
@@ -1392,6 +1394,7 @@ cam_fill_csio(struct ccb_scsiio *csio, u_int32_t retries,
csio->sense_len = sense_len;
csio->cdb_len = cdb_len;
csio->tag_action = tag_action;
+ csio->priority = 0;
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
csio->bio = NULL;
#endif
@@ -1414,6 +1417,7 @@ cam_fill_ctio(struct ccb_scsiio *csio, u_int32_t retries,
csio->dxfer_len = dxfer_len;
csio->scsi_status = scsi_status;
csio->tag_action = tag_action;
+ csio->priority = 0;
csio->tag_id = tag_id;
csio->init_id = init_id;
}
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index 7887009d351c..37962eb3522c 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -1457,6 +1457,7 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param)
if (softc->ha_mode != CTL_HA_MODE_XFER)
io->io_hdr.flags |= CTL_FLAG_INT_COPY;
io->io_hdr.nexus = msg->hdr.nexus;
+ io->scsiio.priority = msg->scsi.priority;
io->scsiio.tag_num = msg->scsi.tag_num;
io->scsiio.tag_type = msg->scsi.tag_type;
#ifdef CTL_TIME_IO
@@ -11603,8 +11604,9 @@ ctl_scsiio_precheck(struct ctl_softc *softc, struct ctl_scsiio *ctsio)
msg_info.hdr.nexus = ctsio->io_hdr.nexus;
msg_info.scsi.tag_num = ctsio->tag_num;
msg_info.scsi.tag_type = ctsio->tag_type;
- msg_info.scsi.cdb_len = ctsio->cdb_len;
memcpy(msg_info.scsi.cdb, ctsio->cdb, CTL_MAX_CDBLEN);
+ msg_info.scsi.cdb_len = ctsio->cdb_len;
+ msg_info.scsi.priority = ctsio->priority;
if ((isc_retval = ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
sizeof(msg_info.scsi) - sizeof(msg_info.scsi.sense_data),
@@ -12480,12 +12482,13 @@ ctl_datamove(union ctl_io *io)
ctl_scsi_command_string(&io->scsiio, NULL, &sb);
sbuf_printf(&sb, "\n");
sbuf_cat(&sb, path_str);
- sbuf_printf(&sb, "Tag: 0x%04x, type %d\n",
- io->scsiio.tag_num, io->scsiio.tag_type);
+ sbuf_printf(&sb, "Tag: 0x%04x/%d, Prio: %d\n",
+ io->scsiio.tag_num, io->scsiio.tag_type,
+ io->scsiio.priority);
break;
case CTL_IO_TASK:
- sbuf_printf(&sb, "Task I/O type: %d, Tag: 0x%04x, "
- "Tag Type: %d\n", io->taskio.task_action,
+ sbuf_printf(&sb, "Task Action: %d Tag: 0x%04x/%d\n",
+ io->taskio.task_action,
io->taskio.tag_num, io->taskio.tag_type);
break;
default:
@@ -12978,12 +12981,13 @@ ctl_process_done(union ctl_io *io)
ctl_scsi_command_string(&io->scsiio, NULL, &sb);
sbuf_printf(&sb, "\n");
sbuf_cat(&sb, path_str);
- sbuf_printf(&sb, "Tag: 0x%04x, type %d\n",
- io->scsiio.tag_num, io->scsiio.tag_type);
+ sbuf_printf(&sb, "Tag: 0x%04x/%d, Prio: %d\n",
+ io->scsiio.tag_num, io->scsiio.tag_type,
+ io->scsiio.priority);
break;
case CTL_IO_TASK:
- sbuf_printf(&sb, "Task I/O type: %d, Tag: 0x%04x, "
- "Tag Type: %d\n", io->taskio.task_action,
+ sbuf_printf(&sb, "Task Action: %d Tag: 0x%04x/%d\n",
+ io->taskio.task_action,
io->taskio.tag_num, io->taskio.tag_type);
break;
default:
diff --git a/sys/cam/ctl/ctl_frontend_cam_sim.c b/sys/cam/ctl/ctl_frontend_cam_sim.c
index 319c8069fbdc..fdcccee2f569 100644
--- a/sys/cam/ctl/ctl_frontend_cam_sim.c
+++ b/sys/cam/ctl/ctl_frontend_cam_sim.c
@@ -539,6 +539,7 @@ cfcs_action(struct cam_sim *sim, union ccb *ccb)
io->io_hdr.nexus.targ_port = softc->port.targ_port;
io->io_hdr.nexus.targ_lun = ctl_decode_lun(
CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun));
+ io->scsiio.priority = csio->priority;
/*
* This tag scheme isn't the best, since we could in theory
* have a very long-lived I/O and tag collision, especially
diff --git a/sys/cam/ctl/ctl_frontend_iscsi.c b/sys/cam/ctl/ctl_frontend_iscsi.c
index 0b91d4fd39c1..694ce99763f6 100644
--- a/sys/cam/ctl/ctl_frontend_iscsi.c
+++ b/sys/cam/ctl/ctl_frontend_iscsi.c
@@ -530,6 +530,8 @@ cfiscsi_pdu_handle_scsi_command(struct icl_pdu *request)
io->io_hdr.nexus.initid = cs->cs_ctl_initid;
io->io_hdr.nexus.targ_port = cs->cs_target->ct_port.targ_port;
io->io_hdr.nexus.targ_lun = ctl_decode_lun(be64toh(bhssc->bhssc_lun));
+ io->scsiio.priority = (bhssc->bhssc_pri & BHSSC_PRI_MASK) >>
+ BHSSC_PRI_SHIFT;
io->scsiio.tag_num = bhssc->bhssc_initiator_task_tag;
switch ((bhssc->bhssc_flags & BHSSC_FLAGS_ATTR)) {
case BHSSC_FLAGS_ATTR_UNTAGGED:
diff --git a/sys/cam/ctl/ctl_io.h b/sys/cam/ctl/ctl_io.h
index 6427685f99a8..2ad499f7f147 100644
--- a/sys/cam/ctl/ctl_io.h
+++ b/sys/cam/ctl/ctl_io.h
@@ -323,6 +323,7 @@ struct ctl_scsiio {
uint8_t sense_len; /* Returned sense length */
uint8_t scsi_status; /* SCSI status byte */
uint8_t sense_residual; /* Unused. */
+ uint8_t priority; /* Command priority */
uint32_t residual; /* Unused */
uint32_t tag_num; /* tag number */
ctl_tag_type tag_type; /* simple, ordered, head of queue,etc.*/
@@ -484,6 +485,7 @@ struct ctl_ha_msg_scsi {
uint8_t cdb_len; /* CDB length */
uint8_t scsi_status; /* SCSI status byte */
uint8_t sense_len; /* Returned sense length */
+ uint8_t priority; /* Command priority */
uint32_t port_status; /* trans status, set by FETD,
0 = good*/
uint32_t kern_data_resid; /* for DATAMOVE_DONE */
diff --git a/sys/cam/ctl/ctl_util.c b/sys/cam/ctl/ctl_util.c
index d00b96527b07..245c3e89dfb9 100644
--- a/sys/cam/ctl/ctl_util.c
+++ b/sys/cam/ctl/ctl_util.c
@@ -740,8 +740,9 @@ ctl_io_sbuf(union ctl_io *io, struct sbuf *sb)
case CTL_IO_SCSI:
sbuf_cat(sb, path_str);
ctl_scsi_command_string(&io->scsiio, NULL, sb);
- sbuf_printf(sb, " Tag: %#x/%d\n",
- io->scsiio.tag_num, io->scsiio.tag_type);
+ sbuf_printf(sb, " Tag: %#x/%d, Prio: %d\n",
+ io->scsiio.tag_num, io->scsiio.tag_type,
+ io->scsiio.priority);
break;
case CTL_IO_TASK:
sbuf_cat(sb, path_str);
diff --git a/sys/cam/ctl/scsi_ctl.c b/sys/cam/ctl/scsi_ctl.c
index 569923f9be70..074ac4cd1894 100644
--- a/sys/cam/ctl/scsi_ctl.c
+++ b/sys/cam/ctl/scsi_ctl.c
@@ -1151,6 +1151,7 @@ ctlfedone(struct cam_periph *periph, union ccb *done_ccb)
} else {
io->io_hdr.nexus.targ_lun = atio->ccb_h.target_lun;
}
+ io->scsiio.priority = atio->priority;
io->scsiio.tag_num = atio->tag_id;
switch (atio->tag_action) {
case CAM_TAG_ACTION_NONE:
diff --git a/sys/dev/iscsi/iscsi.c b/sys/dev/iscsi/iscsi.c
index c0fa3115d64a..466d4541dbc9 100644
--- a/sys/dev/iscsi/iscsi.c
+++ b/sys/dev/iscsi/iscsi.c
@@ -2299,6 +2299,11 @@ iscsi_action_scsiio(struct iscsi_session *is, union ccb *ccb)
} else
bhssc->bhssc_flags |= BHSSC_FLAGS_ATTR_UNTAGGED;
+ if (is->is_protocol_level >= 2) {
+ bhssc->bhssc_pri = (csio->priority << BHSSC_PRI_SHIFT) &
+ BHSSC_PRI_MASK;
+ }
+
bhssc->bhssc_lun = htobe64(CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun));
bhssc->bhssc_initiator_task_tag = initiator_task_tag;
bhssc->bhssc_expected_data_transfer_length = htonl(csio->dxfer_len);
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index b81e3de28022..fe50aab77d43 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -4554,7 +4554,9 @@ isp_start(XS_T *xs)
} else {
ttype = FCP_CMND_TASK_ATTR_SIMPLE;
}
- ((ispreqt7_t *)reqp)->req_task_attribute = ttype;
+ ((ispreqt7_t *)reqp)->req_task_attribute = ttype |
+ ((XS_PRIORITY(xs) << FCP_CMND_PRIO_SHIFT) &
+ FCP_CMND_PRIO_MASK);
} else if (IS_FC(isp)) {
/*
* See comment in isp_intr_respq
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index 3857d52bc0b0..f381f9f4f6f6 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -1917,6 +1917,8 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep)
atiop->tag_action = 0;
break;
}
+ atiop->priority = (aep->at_cmnd.fcp_cmnd_task_attribute &
+ FCP_CMND_PRIO_MASK) >> FCP_CMND_PRIO_SHIFT;
atp->orig_datalen = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl;
atp->bytes_xfered = 0;
atp->lun = lun;
diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h
index 971fc0b05d84..a19c10e2b157 100644
--- a/sys/dev/isp/isp_freebsd.h
+++ b/sys/dev/isp/isp_freebsd.h
@@ -546,7 +546,8 @@ default: \
#define XS_TAG_TYPE(ccb) \
((ccb->tag_action == MSG_SIMPLE_Q_TAG)? REQFLAG_STAG : \
((ccb->tag_action == MSG_HEAD_OF_Q_TAG)? REQFLAG_HTAG : REQFLAG_OTAG))
-
+
+#define XS_PRIORITY(ccb) (ccb)->priority
#define XS_SETERR(ccb, v) (ccb)->ccb_h.status &= ~CAM_STATUS_MASK, \
(ccb)->ccb_h.status |= v
diff --git a/sys/dev/isp/isp_stds.h b/sys/dev/isp/isp_stds.h
index 197962f2cee0..2dfea07cf55d 100644
--- a/sys/dev/isp/isp_stds.h
+++ b/sys/dev/isp/isp_stds.h
@@ -89,6 +89,9 @@ typedef struct {
#define FCP_CMND_TASK_ATTR_UNTAGGED 0x05
#define FCP_CMND_TASK_ATTR_MASK 0x07
+#define FCP_CMND_PRIO_MASK 0x78
+#define FCP_CMND_PRIO_SHIFT 3
+
#define FCP_CMND_ADDTL_CDBLEN_SHIFT 2
#define FCP_CMND_DATA_WRITE 0x01
diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h
index 45513a3b6871..5ff34e829eb3 100644
--- a/sys/dev/isp/ispvar.h
+++ b/sys/dev/isp/ispvar.h
@@ -1036,6 +1036,7 @@ void isp_async(ispsoftc_t *, ispasync_t, ...);
* XS_SNSASCQ(xs) dereferences XS_SNSP to get the current stored Additional Sense Code Qualifier
* XS_TAG_P(xs) predicate of whether this command should be tagged
* XS_TAG_TYPE(xs) which type of tag to use
+ * XS_PRIORITY(xs) command priority for SIMPLE tag
* XS_SETERR(xs) set error state
*
* HBA_NOERROR command has no erros
diff --git a/sys/dev/mpr/mpr_sas.c b/sys/dev/mpr/mpr_sas.c
index 400aa86e0fc0..de61ac7b8dd8 100644
--- a/sys/dev/mpr/mpr_sas.c
+++ b/sys/dev/mpr/mpr_sas.c
@@ -1997,6 +1997,8 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb)
mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
break;
}
+ mpi_control |= (csio->priority << MPI2_SCSIIO_CONTROL_CMDPRI_SHIFT) &
+ MPI2_SCSIIO_CONTROL_CMDPRI_MASK;
mpi_control |= sc->mapping_table[csio->ccb_h.target_id].TLR_bits;
req->Control = htole32(mpi_control);
diff --git a/sys/dev/mps/mps_sas.c b/sys/dev/mps/mps_sas.c
index e1e507590f49..97160a40ce08 100644
--- a/sys/dev/mps/mps_sas.c
+++ b/sys/dev/mps/mps_sas.c
@@ -1786,6 +1786,8 @@ mpssas_action_scsiio(struct mpssas_softc *sassc, union ccb *ccb)
mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
break;
}
+ mpi_control |= (csio->priority << MPI2_SCSIIO_CONTROL_TASKPRI_SHIFT) &
+ MPI2_SCSIIO_CONTROL_TASKPRI_MASK;
mpi_control |= sc->mapping_table[csio->ccb_h.target_id].TLR_bits;
req->Control = htole32(mpi_control);
if (MPS_SET_LUN(req->LUN, csio->ccb_h.target_lun) != 0) {
diff --git a/sys/dev/ocs_fc/ocs_cam.c b/sys/dev/ocs_fc/ocs_cam.c
index e098997025c9..d3c275920c4b 100644
--- a/sys/dev/ocs_fc/ocs_cam.c
+++ b/sys/dev/ocs_fc/ocs_cam.c
@@ -580,8 +580,12 @@ int32_t ocs_scsi_recv_cmd(ocs_io_t *io, uint64_t lun, uint8_t *cdb,
atio->tag_action = MSG_HEAD_OF_Q_TAG;
else if (flags & OCS_SCSI_CMD_ORDERED)
atio->tag_action = MSG_ORDERED_Q_TAG;
+ else if (flags & OCS_SCSI_CMD_ACA)
+ atio->tag_action = MSG_ACA_TASK;
else
- atio->tag_action = 0;
+ atio->tag_action = CAM_TAG_ACTION_NONE;
+ atio->priority = (flags & OCS_SCSI_PRIORITY_MASK) >>
+ OCS_SCSI_PRIORITY_SHIFT;
atio->cdb_len = cdb_len;
ocs_memcpy(atio->cdb_io.cdb_bytes, cdb, cdb_len);
@@ -1782,7 +1786,7 @@ ocs_initiator_io(struct ocs_softc *ocs, union ccb *ccb)
ocs_node_t *node = NULL;
ocs_io_t *io = NULL;
ocs_scsi_sgl_t sgl[OCS_FC_MAX_SGL];
- int32_t sgl_count;
+ int32_t flags, sgl_count;
ocs_fcport *fcp;
fcp = FCPORT(ocs, cam_sim_bus(xpt_path_sim((ccb)->ccb_h.path)));
@@ -1840,13 +1844,32 @@ ocs_initiator_io(struct ocs_softc *ocs, union ccb *ccb)
io->timeout = ccb->ccb_h.timeout;
}
+ switch (csio->tag_action) {
+ case MSG_HEAD_OF_Q_TAG:
+ flags = OCS_SCSI_CMD_HEAD_OF_QUEUE;
+ break;
+ case MSG_ORDERED_Q_TAG:
+ flags = OCS_SCSI_CMD_ORDERED;
+ break;
+ case MSG_ACA_TASK:
+ flags = OCS_SCSI_CMD_ACA;
+ break;
+ case CAM_TAG_ACTION_NONE:
+ case MSG_SIMPLE_Q_TAG:
+ default:
+ flags = OCS_SCSI_CMD_SIMPLE;
+ break;
+ }
+ flags |= (csio->priority << OCS_SCSI_PRIORITY_SHIFT) &
+ OCS_SCSI_PRIORITY_MASK;
+
switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
case CAM_DIR_NONE:
rc = ocs_scsi_send_nodata_io(node, io, ccb_h->target_lun,
ccb->ccb_h.flags & CAM_CDB_POINTER ?
csio->cdb_io.cdb_ptr: csio->cdb_io.cdb_bytes,
csio->cdb_len,
- ocs_scsi_initiator_io_cb, ccb);
+ ocs_scsi_initiator_io_cb, ccb, flags);
break;
case CAM_DIR_IN:
rc = ocs_scsi_send_rd_io(node, io, ccb_h->target_lun,
@@ -1855,7 +1878,7 @@ ocs_initiator_io(struct ocs_softc *ocs, union ccb *ccb)
csio->cdb_len,
NULL,
sgl, sgl_count, csio->dxfer_len,
- ocs_scsi_initiator_io_cb, ccb);
+ ocs_scsi_initiator_io_cb, ccb, flags);
break;
case CAM_DIR_OUT:
rc = ocs_scsi_send_wr_io(node, io, ccb_h->target_lun,
@@ -1864,7 +1887,7 @@ ocs_initiator_io(struct ocs_softc *ocs, union ccb *ccb)
csio->cdb_len,
NULL,
sgl, sgl_count, csio->dxfer_len,
- ocs_scsi_initiator_io_cb, ccb);
+ ocs_scsi_initiator_io_cb, ccb, flags);
break;
default:
panic("%s invalid data direction %08x\n", __func__,
diff --git a/sys/dev/ocs_fc/ocs_scsi.c b/sys/dev/ocs_fc/ocs_scsi.c
index 1477771cc220..c2df898bda4b 100644
--- a/sys/dev/ocs_fc/ocs_scsi.c
+++ b/sys/dev/ocs_fc/ocs_scsi.c
@@ -297,7 +297,7 @@ ocs_scsi_send_io(ocs_hw_io_type_e type, ocs_node_t *node, ocs_io_t *io, uint64_t
ocs_scsi_tmf_cmd_e tmf, uint8_t *cdb, uint32_t cdb_len,
ocs_scsi_dif_info_t *dif_info,
ocs_scsi_sgl_t *sgl, uint32_t sgl_count, uint32_t wire_len, uint32_t first_burst,
- ocs_scsi_rsp_io_cb_t cb, void *arg);
+ ocs_scsi_rsp_io_cb_t cb, void *arg, uint32_t flags);
/**
* @brief Target response completion callback.
@@ -2263,12 +2263,12 @@ int32_t
ocs_scsi_send_rd_io(ocs_node_t *node, ocs_io_t *io, uint64_t lun, void *cdb, uint32_t cdb_len,
ocs_scsi_dif_info_t *dif_info,
ocs_scsi_sgl_t *sgl, uint32_t sgl_count, uint32_t wire_len,
- ocs_scsi_rsp_io_cb_t cb, void *arg)
+ ocs_scsi_rsp_io_cb_t cb, void *arg, uint32_t flags)
{
int32_t rc;
rc = ocs_scsi_send_io(OCS_HW_IO_INITIATOR_READ, node, io, lun, 0, cdb, cdb_len, dif_info, sgl, sgl_count,
- wire_len, 0, cb, arg);
+ wire_len, 0, cb, arg, flags);
return rc;
}
@@ -2302,12 +2302,12 @@ ocs_scsi_send_rd_io(ocs_node_t *node, ocs_io_t *io, uint64_t lun, void *cdb, uin
int32_t ocs_scsi_send_wr_io(ocs_node_t *node, ocs_io_t *io, uint64_t lun, void *cdb, uint32_t cdb_len,
ocs_scsi_dif_info_t *dif_info,
ocs_scsi_sgl_t *sgl, uint32_t sgl_count, uint32_t wire_len,
- ocs_scsi_rsp_io_cb_t cb, void *arg)
+ ocs_scsi_rsp_io_cb_t cb, void *arg, uint32_t flags)
{
int32_t rc;
rc = ocs_scsi_send_io(OCS_HW_IO_INITIATOR_WRITE, node, io, lun, 0, cdb, cdb_len, dif_info, sgl, sgl_count,
- wire_len, 0, cb, arg);
+ wire_len, 0, cb, arg, flags);
return rc;
}
@@ -2343,12 +2343,12 @@ int32_t
ocs_scsi_send_wr_io_first_burst(ocs_node_t *node, ocs_io_t *io, uint64_t lun, void *cdb, uint32_t cdb_len,
ocs_scsi_dif_info_t *dif_info,
ocs_scsi_sgl_t *sgl, uint32_t sgl_count, uint32_t wire_len, uint32_t first_burst,
- ocs_scsi_rsp_io_cb_t cb, void *arg)
+ ocs_scsi_rsp_io_cb_t cb, void *arg, uint32_t flags)
{
int32_t rc;
rc = ocs_scsi_send_io(OCS_HW_IO_INITIATOR_WRITE, node, io, lun, 0, cdb, cdb_len, dif_info, sgl, sgl_count,
- wire_len, 0, cb, arg);
+ wire_len, 0, cb, arg, flags);
return rc;
}
@@ -2374,11 +2374,11 @@ ocs_scsi_send_wr_io_first_burst(ocs_node_t *node, ocs_io_t *io, uint64_t lun, vo
* @return Returns 0 on success, or a negative error code value on failure.
*/
int32_t ocs_scsi_send_nodata_io(ocs_node_t *node, ocs_io_t *io, uint64_t lun, void *cdb, uint32_t cdb_len,
- ocs_scsi_rsp_io_cb_t cb, void *arg)
+ ocs_scsi_rsp_io_cb_t cb, void *arg, uint32_t flags)
{
int32_t rc;
- rc = ocs_scsi_send_io(OCS_HW_IO_INITIATOR_NODATA, node, io, lun, 0, cdb, cdb_len, NULL, NULL, 0, 0, 0, cb, arg);
+ rc = ocs_scsi_send_io(OCS_HW_IO_INITIATOR_NODATA, node, io, lun, 0, cdb, cdb_len, NULL, NULL, 0, 0, 0, cb, arg, flags);
return rc;
}
@@ -2444,7 +2444,7 @@ ocs_scsi_send_tmf(ocs_node_t *node, ocs_io_t *io, ocs_io_t *io_to_abort, uint64_
} else {
io->display_name = "tmf";
rc = ocs_scsi_send_io(OCS_HW_IO_INITIATOR_READ, node, io, lun, tmf, NULL, 0, NULL,
- sgl, sgl_count, len, 0, cb, arg);
+ sgl, sgl_count, len, 0, cb, arg, 0);
}
return rc;
@@ -2481,7 +2481,7 @@ static int32_t ocs_scsi_send_io(ocs_hw_io_type_e type, ocs_node_t *node, ocs_io_
ocs_scsi_tmf_cmd_e tmf, uint8_t *cdb, uint32_t cdb_len,
ocs_scsi_dif_info_t *dif_info,
ocs_scsi_sgl_t *sgl, uint32_t sgl_count, uint32_t wire_len, uint32_t first_burst,
- ocs_scsi_rsp_io_cb_t cb, void *arg)
+ ocs_scsi_rsp_io_cb_t cb, void *arg, uint32_t flags)
{
int32_t rc;
ocs_t *ocs;
@@ -2565,6 +2565,18 @@ static int32_t ocs_scsi_send_io(ocs_hw_io_type_e type, ocs_node_t *node, ocs_io_
return -1;
}
}
+ if (flags & OCS_SCSI_CMD_HEAD_OF_QUEUE)
+ cmnd->task_attribute = FCP_TASK_ATTR_HEAD_OF_QUEUE;
+ else if (flags & OCS_SCSI_CMD_ORDERED)
+ cmnd->task_attribute = FCP_TASK_ATTR_ORDERED;
+ else if (flags & OCS_SCSI_CMD_UNTAGGED)
+ cmnd->task_attribute = FCP_TASK_ATTR_UNTAGGED;
+ else if (flags & OCS_SCSI_CMD_ACA)
+ cmnd->task_attribute = FCP_TASK_ATTR_ACA;
+ else
+ cmnd->task_attribute = FCP_TASK_ATTR_SIMPLE;
+ cmnd->command_priority = (flags & OCS_SCSI_PRIORITY_MASK) >>
+ OCS_SCSI_PRIORITY_SHIFT;
switch (tmf) {
case OCS_SCSI_TMF_QUERY_TASK_SET:
diff --git a/sys/dev/ocs_fc/ocs_scsi.h b/sys/dev/ocs_fc/ocs_scsi.h
index aa4f96c070e6..9f5b8a935385 100644
--- a/sys/dev/ocs_fc/ocs_scsi.h
+++ b/sys/dev/ocs_fc/ocs_scsi.h
@@ -54,6 +54,8 @@
#define OCS_SCSI_CMD_ACA (1U << 6)
#define OCS_SCSI_FIRST_BURST_ERR (1U << 7)
#define OCS_SCSI_FIRST_BURST_ABORTED (1U << 8)
+#define OCS_SCSI_PRIORITY_MASK 0xf0000
+#define OCS_SCSI_PRIORITY_SHIFT 16
/* ocs_scsi_send_rd_data/recv_wr_data/send_resp flags */
#define OCS_SCSI_LAST_DATAPHASE (1U << 0)
@@ -347,17 +349,18 @@ extern int32_t ocs_scsi_del_target(ocs_node_t *node, ocs_scsi_del_target_reason_
extern int32_t ocs_scsi_send_rd_io(ocs_node_t *node, ocs_io_t *io, uint64_t lun, void *cdb, uint32_t cdb_len,
ocs_scsi_dif_info_t *dif_info,
- ocs_scsi_sgl_t *sgl, uint32_t sgl_count, uint32_t wire_len, ocs_scsi_rsp_io_cb_t cb, void *arg);
+ ocs_scsi_sgl_t *sgl, uint32_t sgl_count, uint32_t wire_len, ocs_scsi_rsp_io_cb_t cb, void *arg, uint32_t flags);
extern int32_t ocs_scsi_send_wr_io(ocs_node_t *node, ocs_io_t *io, uint64_t lun, void *cdb, uint32_t cdb_len,
ocs_scsi_dif_info_t *dif_info,
- ocs_scsi_sgl_t *sgl, uint32_t sgl_count, uint32_t wire_len, ocs_scsi_rsp_io_cb_t cb, void *arg);
+ ocs_scsi_sgl_t *sgl, uint32_t sgl_count, uint32_t wire_len, ocs_scsi_rsp_io_cb_t cb, void *arg, uint32_t flags);
extern int32_t ocs_scsi_send_wr_io_first_burst(ocs_node_t *node, ocs_io_t *io, uint64_t lun, void *cdb, uint32_t cdb_len,
ocs_scsi_dif_info_t *dif_info,
ocs_scsi_sgl_t *sgl, uint32_t sgl_count, uint32_t wire_len, uint32_t first_burst,
- ocs_scsi_rsp_io_cb_t cb, void *arg);
+ ocs_scsi_rsp_io_cb_t cb, void *arg, uint32_t flags);
extern int32_t ocs_scsi_send_tmf(ocs_node_t *node, ocs_io_t *io, ocs_io_t *io_to_abort, uint64_t lun,
ocs_scsi_tmf_cmd_e tmf, ocs_scsi_sgl_t *sgl, uint32_t sgl_count, uint32_t len, ocs_scsi_rsp_io_cb_t cb, void *arg);
-extern int32_t ocs_scsi_send_nodata_io(ocs_node_t *node, ocs_io_t *io, uint64_t lun, void *cdb, uint32_t cdb_len, ocs_scsi_rsp_io_cb_t cb, void *arg);
+extern int32_t ocs_scsi_send_nodata_io(ocs_node_t *node, ocs_io_t *io, uint64_t lun, void *cdb, uint32_t cdb_len,
+ ocs_scsi_rsp_io_cb_t cb, void *arg, uint32_t flags);
extern void ocs_scsi_del_target_complete(ocs_node_t *node);
typedef enum {
diff --git a/sys/dev/ocs_fc/ocs_unsol.c b/sys/dev/ocs_fc/ocs_unsol.c
index cf2526f0721a..12b600132c00 100644
--- a/sys/dev/ocs_fc/ocs_unsol.c
+++ b/sys/dev/ocs_fc/ocs_unsol.c
@@ -854,6 +854,7 @@ ocs_get_flags_fcp_cmd(fcp_cmnd_iu_t *cmnd)
flags |= OCS_SCSI_CMD_UNTAGGED;
break;
}
+ flags |= (uint32_t)cmnd->command_priority << OCS_SCSI_PRIORITY_SHIFT;
if (cmnd->wrdata)
flags |= OCS_SCSI_CMD_DIR_IN;
if (cmnd->rddata)