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)