Lines Matching +full:negative +full:- +full:phase

1 /*-
49 #define SCSI_ITT_SIZE(ocs) ((ocs->ocs_xport == OCS_XPORT_FC) ? 4 : 8)
51 … SCSI_IOFMT_ARGS(io) io->instance_index, SCSI_ITT_SIZE(io->ocs), io->init_task_tag, SCSI_ITT_SIZE(…
53 #define enable_tsend_auto_resp(ocs) ((ocs->ctrlmask & OCS_CTRLMASK_XPORT_DISABLE_AUTORSP_TSEND) ==…
54 #define enable_treceive_auto_resp(ocs) ((ocs->ctrlmask & OCS_CTRLMASK_XPORT_DISABLE_AUTORSP_TRECEIV…
56 #define scsi_io_printf(io, fmt, ...) ocs_log_info(io->ocs, "[%s]" SCSI_IOFMT fmt, \
57 io->node->display_name, SCSI_IOFMT_ARGS(io), ##__VA_ARGS__)
61 if (OCS_LOG_ENABLE_SCSI_TRACE(io->ocs)) \
91 * @brief Returns a big-endian 32-bit value given a pointer.
93 * @param p Pointer to the 32-bit big-endian location.
95 * @return Returns the byte-swapped 32-bit value.
121 ocs_lock(&node->active_ios_lock); in ocs_scsi_io_alloc_enable()
122 node->io_alloc_enabled = TRUE; in ocs_scsi_io_alloc_enable()
123 ocs_unlock(&node->active_ios_lock); in ocs_scsi_io_alloc_enable()
143 ocs_lock(&node->active_ios_lock); in ocs_scsi_io_alloc_disable()
144 node->io_alloc_enabled = FALSE; in ocs_scsi_io_alloc_disable()
145 ocs_unlock(&node->active_ios_lock); in ocs_scsi_io_alloc_disable()
154 * is called by an initiator-client when issuing SCSI commands to remote
158 * "ini_io" that is declared and used by an initiator-client for private information.
175 ocs_assert(node->ocs, NULL); in ocs_scsi_io_alloc()
177 ocs = node->ocs; in ocs_scsi_io_alloc()
178 ocs_assert(ocs->xport, NULL); in ocs_scsi_io_alloc()
179 xport = ocs->xport; in ocs_scsi_io_alloc()
181 ocs_lock(&node->active_ios_lock); in ocs_scsi_io_alloc()
183 if (!node->io_alloc_enabled) { in ocs_scsi_io_alloc()
184 ocs_unlock(&node->active_ios_lock); in ocs_scsi_io_alloc()
190 ocs_atomic_add_return(&xport->io_alloc_failed_count, 1); in ocs_scsi_io_alloc()
191 ocs_unlock(&node->active_ios_lock); in ocs_scsi_io_alloc()
196 ocs_ref_init(&io->ref, _ocs_scsi_io_free, io); in ocs_scsi_io_alloc()
198 if (io->hio != NULL) { in ocs_scsi_io_alloc()
199 ocs_log_err(node->ocs, "assertion failed: io->hio is not NULL\n"); in ocs_scsi_io_alloc()
201 ocs_unlock(&node->active_ios_lock); in ocs_scsi_io_alloc()
206 io->ocs = ocs; in ocs_scsi_io_alloc()
207 io->node = node; in ocs_scsi_io_alloc()
210 io->io_type = OCS_IO_TYPE_IO; in ocs_scsi_io_alloc()
211 io->display_name = "scsi_io"; in ocs_scsi_io_alloc()
215 io->cmd_ini = TRUE; in ocs_scsi_io_alloc()
216 io->cmd_tgt = FALSE; in ocs_scsi_io_alloc()
219 io->cmd_ini = FALSE; in ocs_scsi_io_alloc()
220 io->cmd_tgt = TRUE; in ocs_scsi_io_alloc()
225 ocs_list_add_tail(&node->active_ios, io); in ocs_scsi_io_alloc()
227 ocs_unlock(&node->active_ios_lock); in ocs_scsi_io_alloc()
249 ocs_t *ocs = io->ocs; in _ocs_scsi_io_free()
250 ocs_node_t *node = io->node; in _ocs_scsi_io_free()
255 scsi_io_trace(io, "freeing io 0x%p %s\n", io, io->display_name); in _ocs_scsi_io_free()
259 ocs_lock(&node->active_ios_lock); in _ocs_scsi_io_free()
260 ocs_list_remove(&node->active_ios, io); in _ocs_scsi_io_free()
261 send_empty_event = (!node->io_alloc_enabled) && ocs_list_empty(&node->active_ios); in _ocs_scsi_io_free()
262 ocs_unlock(&node->active_ios_lock); in _ocs_scsi_io_free()
268 io->node = NULL; in _ocs_scsi_io_free()
287 scsi_io_trace(io, "freeing io 0x%p %s\n", io, io->display_name); in ocs_scsi_io_free()
288 ocs_assert(ocs_ref_read_count(&io->ref) > 0); in ocs_scsi_io_free()
289 ocs_ref_put(&io->ref); /* ocs_ref_get(): ocs_scsi_io_alloc() */ in ocs_scsi_io_free()
310 * @param app Application-specific data (generally a pointer to the IO context).
325 ocs_hw_dif_info_t *dif_info = &io->hw_dif; in ocs_target_io_cb()
332 ocs = io->ocs; in ocs_target_io_cb()
337 io->transferred += length; in ocs_target_io_cb()
340 if (io->scsi_tgt_cb) { in ocs_target_io_cb()
341 ocs_scsi_io_cb_t cb = io->scsi_tgt_cb; in ocs_target_io_cb()
345 io->scsi_tgt_cb = NULL; in ocs_target_io_cb()
347 /* if status was good, and auto-good-response was set, then callback in ocs_target_io_cb()
348 * target-server with IO_CMPL_RSP_SENT, otherwise send IO_CMPL in ocs_target_io_cb()
350 if ((status == 0) && (io->auto_resp)) in ocs_target_io_cb()
377 scsi_status = ocs_scsi_dif_check_unknown(io, 0, io->wire_len, is_crc); in ocs_target_io_cb()
385 …* . Operation is a pass thru (CRC or CKSUM on IN, and CRC or CHKSUM on OUT) (all pass-thru case… in ocs_target_io_cb()
388 …(dif_info->dif == SLI4_DIF_PASS_THROUGH) && (dif_info->dif_oper != OCS_HW_SGE_DIF_OP_IN_RAW_OUT_RA… in ocs_target_io_cb()
391 /* If we can't do additional checking, then fall-back to guard error */ in ocs_target_io_cb()
431 cb(io, scsi_status, flags, io->scsi_tgt_cb_arg); in ocs_target_io_cb()
451 switch(dif_info->dif_oper) { in ocs_scsi_dif_guard_is_crc()
463 switch(dif_info->dif_oper) { in ocs_scsi_dif_guard_is_crc()
503 ocs_t *ocs = io->ocs; in ocs_scsi_dif_check_unknown()
504 ocs_hw_dif_info_t *dif_info = &io->hw_dif; in ocs_scsi_dif_check_unknown()
510 ocs_scsi_vaddr_len_t addrlen[4]; /* address-length pairs returned from target */ in ocs_scsi_dif_check_unknown()
511 int32_t addrlen_count; /* count of address-length pairs */ in ocs_scsi_dif_check_unknown()
513 ocs_scsi_dif_info_t scsi_dif_info = io->scsi_dif_info; in ocs_scsi_dif_check_unknown()
515 blocksize = ocs_hw_dif_mem_blocksize(&io->hw_dif, TRUE); in ocs_scsi_dif_check_unknown()
518 check_count = last_check_block - first_check_block; in ocs_scsi_dif_check_unknown()
568 uint16_t crc = dif_info->dif_seed; in ocs_scsi_dif_check_guard()
572 if ((dif == NULL) || !dif_info->check_guard) { in ocs_scsi_dif_check_guard()
580 return (crc == ocs_be16toh(dif->crc)); in ocs_scsi_dif_check_guard()
584 return (checksum == dif->crc); in ocs_scsi_dif_check_guard()
604 if ((dif == NULL) || !dif_info->check_app_tag) { in ocs_scsi_dif_check_app_tag()
609 exp_app_tag, ocs_be16toh(dif->app_tag)); in ocs_scsi_dif_check_app_tag()
611 return (exp_app_tag == ocs_be16toh(dif->app_tag)); in ocs_scsi_dif_check_app_tag()
630 if ((dif == NULL) || !dif_info->check_ref_tag) { in ocs_scsi_dif_check_ref_tag()
634 if (exp_ref_tag != ocs_be32toh(dif->ref_tag)) { in ocs_scsi_dif_check_ref_tag()
636 exp_ref_tag, ocs_be32toh(dif->ref_tag)); in ocs_scsi_dif_check_ref_tag()
662 if (hw_dif->dif_oper != OCS_HW_DIF_OPER_DISABLED) { in ocs_scsi_count_sgls()
664 if (!hw_dif->dif_separate) { in ocs_scsi_count_sgls()
670 if (hw_dif->dif_separate) { in ocs_scsi_count_sgls()
687 ocs_t *ocs = hw->os; in ocs_scsi_build_sgls()
691 ocs_assert(hio, -1); in ocs_scsi_build_sgls()
697 return -1; in ocs_scsi_build_sgls()
701 if (hw_dif->dif_oper != OCS_HW_DIF_OPER_DISABLED) { in ocs_scsi_build_sgls()
703 if (!hw_dif->dif_separate) { in ocs_scsi_build_sgls()
714 if (hw_dif->dif_separate) { in ocs_scsi_build_sgls()
715 switch(hw_dif->blk_size) { in ocs_scsi_build_sgls()
723 ocs_log_test(hw->os, "Inavlid hw_dif blocksize %d\n", hw_dif->blk_size); in ocs_scsi_build_sgls()
724 return -1; in ocs_scsi_build_sgls()
728 ocs_log_test(hw->os, "sgl[%d] len of %ld is not multiple of blocksize\n", in ocs_scsi_build_sgls()
730 return -1; in ocs_scsi_build_sgls()
736 ocs_assert(sgl[i].addr, -1); in ocs_scsi_build_sgls()
737 ocs_assert(sgl[i].len, -1); in ocs_scsi_build_sgls()
740 if (hw_dif->dif_separate) { in ocs_scsi_build_sgls()
751 if (hw_dif->dif_oper == OCS_HW_DIF_OPER_INSERT) { in ocs_scsi_build_sgls()
752 hw_dif->ref_tag_repl += blockcount; in ocs_scsi_build_sgls()
754 hw_dif->ref_tag_cmp += blockcount; in ocs_scsi_build_sgls()
768 ocs_assert(sgl[i].addr, -1); in ocs_scsi_build_sgls()
769 ocs_assert(sgl[i].len, -1); in ocs_scsi_build_sgls()
791 * @return Returns 0 on success, or a negative error code value on failure.
801 hw_dif_info->dif_oper = OCS_HW_DIF_OPER_DISABLED; in ocs_scsi_convert_dif_info()
802 hw_dif_info->blk_size = OCS_HW_DIF_BK_SIZE_NA; in ocs_scsi_convert_dif_info()
807 switch(scsi_dif_info->dif_oper) { in ocs_scsi_convert_dif_info()
809 hw_dif_info->dif_oper = OCS_HW_SGE_DIF_OP_IN_NODIF_OUT_CRC; in ocs_scsi_convert_dif_info()
810 hw_dif_info->dif = SLI4_DIF_INSERT; in ocs_scsi_convert_dif_info()
813 hw_dif_info->dif_oper = OCS_HW_SGE_DIF_OP_IN_CRC_OUT_NODIF; in ocs_scsi_convert_dif_info()
814 hw_dif_info->dif = SLI4_DIF_STRIP; in ocs_scsi_convert_dif_info()
817 hw_dif_info->dif_oper = OCS_HW_SGE_DIF_OP_IN_NODIF_OUT_CHKSUM; in ocs_scsi_convert_dif_info()
818 hw_dif_info->dif = SLI4_DIF_INSERT; in ocs_scsi_convert_dif_info()
821 hw_dif_info->dif_oper = OCS_HW_SGE_DIF_OP_IN_CHKSUM_OUT_NODIF; in ocs_scsi_convert_dif_info()
822 hw_dif_info->dif = SLI4_DIF_STRIP; in ocs_scsi_convert_dif_info()
825 hw_dif_info->dif_oper = OCS_HW_SGE_DIF_OP_IN_CRC_OUT_CRC; in ocs_scsi_convert_dif_info()
826 hw_dif_info->dif = SLI4_DIF_PASS_THROUGH; in ocs_scsi_convert_dif_info()
829 hw_dif_info->dif_oper = OCS_HW_SGE_DIF_OP_IN_CHKSUM_OUT_CHKSUM; in ocs_scsi_convert_dif_info()
830 hw_dif_info->dif = SLI4_DIF_PASS_THROUGH; in ocs_scsi_convert_dif_info()
833 hw_dif_info->dif_oper = OCS_HW_SGE_DIF_OP_IN_CRC_OUT_CHKSUM; in ocs_scsi_convert_dif_info()
834 hw_dif_info->dif = SLI4_DIF_PASS_THROUGH; in ocs_scsi_convert_dif_info()
837 hw_dif_info->dif_oper = OCS_HW_SGE_DIF_OP_IN_CHKSUM_OUT_CRC; in ocs_scsi_convert_dif_info()
838 hw_dif_info->dif = SLI4_DIF_PASS_THROUGH; in ocs_scsi_convert_dif_info()
841 hw_dif_info->dif_oper = OCS_HW_SGE_DIF_OP_IN_RAW_OUT_RAW; in ocs_scsi_convert_dif_info()
842 hw_dif_info->dif = SLI4_DIF_PASS_THROUGH; in ocs_scsi_convert_dif_info()
846 scsi_dif_info->dif_oper); in ocs_scsi_convert_dif_info()
847 return -1; in ocs_scsi_convert_dif_info()
850 switch(scsi_dif_info->blk_size) { in ocs_scsi_convert_dif_info()
852 hw_dif_info->blk_size = OCS_HW_DIF_BK_SIZE_512; in ocs_scsi_convert_dif_info()
855 hw_dif_info->blk_size = OCS_HW_DIF_BK_SIZE_1024; in ocs_scsi_convert_dif_info()
858 hw_dif_info->blk_size = OCS_HW_DIF_BK_SIZE_2048; in ocs_scsi_convert_dif_info()
861 hw_dif_info->blk_size = OCS_HW_DIF_BK_SIZE_4096; in ocs_scsi_convert_dif_info()
864 hw_dif_info->blk_size = OCS_HW_DIF_BK_SIZE_520; in ocs_scsi_convert_dif_info()
867 hw_dif_info->blk_size = OCS_HW_DIF_BK_SIZE_4104; in ocs_scsi_convert_dif_info()
871 scsi_dif_info->blk_size); in ocs_scsi_convert_dif_info()
872 return -1; in ocs_scsi_convert_dif_info()
877 if (hw_dif_info->dif == SLI4_DIF_INSERT ) { in ocs_scsi_convert_dif_info()
878 hw_dif_info->ref_tag_repl = scsi_dif_info->ref_tag; in ocs_scsi_convert_dif_info()
879 hw_dif_info->app_tag_repl = scsi_dif_info->app_tag; in ocs_scsi_convert_dif_info()
881 hw_dif_info->ref_tag_cmp = scsi_dif_info->ref_tag; in ocs_scsi_convert_dif_info()
882 hw_dif_info->app_tag_cmp = scsi_dif_info->app_tag; in ocs_scsi_convert_dif_info()
885 hw_dif_info->check_ref_tag = scsi_dif_info->check_ref_tag; in ocs_scsi_convert_dif_info()
886 hw_dif_info->check_app_tag = scsi_dif_info->check_app_tag; in ocs_scsi_convert_dif_info()
887 hw_dif_info->check_guard = scsi_dif_info->check_guard; in ocs_scsi_convert_dif_info()
888 hw_dif_info->auto_incr_ref_tag = 1; in ocs_scsi_convert_dif_info()
889 hw_dif_info->dif_separate = scsi_dif_info->dif_separate; in ocs_scsi_convert_dif_info()
890 hw_dif_info->disable_app_ffff = scsi_dif_info->disable_app_ffff; in ocs_scsi_convert_dif_info()
891 hw_dif_info->disable_app_ref_ffff = scsi_dif_info->disable_app_ref_ffff; in ocs_scsi_convert_dif_info()
893 ocs_hw_get(&ocs->hw, OCS_HW_DIF_SEED, &dif_seed); in ocs_scsi_convert_dif_info()
894 hw_dif_info->dif_seed = dif_seed; in ocs_scsi_convert_dif_info()
907 ocs_hw_io_t *hio = io->hio; in ocs_log_sgl()
914 ocs_addr32_hi(hio->def_sgl.phys), in ocs_log_sgl()
915 ocs_addr32_lo(hio->def_sgl.phys)); in ocs_log_sgl()
916 n_sge = (hio->sgl == &hio->def_sgl ? hio->n_sge : hio->def_sgl_count); in ocs_log_sgl()
917 for (i = 0, data = hio->def_sgl.virt; i < n_sge; i++, data++) { in ocs_log_sgl()
928 if (hio->ovfl_sgl != NULL && in ocs_log_sgl()
929 hio->sgl == hio->ovfl_sgl) { in ocs_log_sgl()
931 ocs_addr32_hi(hio->ovfl_sgl->phys), in ocs_log_sgl()
932 ocs_addr32_lo(hio->ovfl_sgl->phys)); in ocs_log_sgl()
933 for (i = 0, data = hio->ovfl_sgl->virt; i < hio->n_sge; i++, data++) { in ocs_log_sgl()
966 if (io->hw_cb != NULL) { in ocs_scsi_check_pending_async_cb()
967 ocs_hw_done_t cb = io->hw_cb; in ocs_scsi_check_pending_async_cb()
969 io->hw_cb = NULL; in ocs_scsi_check_pending_async_cb()
970 cb(io->hio, NULL, 0, SLI4_FC_WCQE_STATUS_DISPATCH_ERROR, 0, io); in ocs_scsi_check_pending_async_cb()
991 ocs_xport_t *xport = ocs->xport; in ocs_scsi_check_pending()
999 if (ocs_atomic_add_return(&xport->io_pending_recursing, 1)) { in ocs_scsi_check_pending()
1001 ocs_atomic_sub_return(&xport->io_pending_recursing, 1); in ocs_scsi_check_pending()
1006 ocs_lock(&xport->io_pending_lock); in ocs_scsi_check_pending()
1009 io = ocs_list_remove_head(&xport->io_pending_list); in ocs_scsi_check_pending()
1011 if (io->io_type == OCS_IO_TYPE_ABORT) { in ocs_scsi_check_pending()
1014 hio = ocs_hw_io_alloc(&ocs->hw); in ocs_scsi_check_pending()
1020 ocs_list_add_head(&xport->io_pending_list, io); in ocs_scsi_check_pending()
1023 hio->eq = io->hw_priv; in ocs_scsi_check_pending()
1028 ocs_unlock(&xport->io_pending_lock); in ocs_scsi_check_pending()
1037 ocs_atomic_sub_return(&xport->io_pending_count, 1); in ocs_scsi_check_pending()
1049 if (ocs_hw_async_call(&ocs->hw, ocs_scsi_check_pending_async_cb, io)) { in ocs_scsi_check_pending()
1065 ocs_lock(&xport->io_pending_lock); in ocs_scsi_check_pending()
1066 ocs_list_foreach(&xport->io_pending_list, io) { in ocs_scsi_check_pending()
1067 if (io->io_type == OCS_IO_TYPE_ABORT) { in ocs_scsi_check_pending()
1068 if (io->io_to_abort->hio != NULL) { in ocs_scsi_check_pending()
1077 ocs_list_remove(&xport->io_pending_list, io); in ocs_scsi_check_pending()
1078 ocs_atomic_sub_return(&xport->io_pending_count, 1); in ocs_scsi_check_pending()
1082 ocs_unlock(&xport->io_pending_lock); in ocs_scsi_check_pending()
1087 if (ocs_hw_async_call(&ocs->hw, ocs_scsi_check_pending_async_cb, io)) { in ocs_scsi_check_pending()
1094 ocs_atomic_sub_return(&xport->io_pending_recursing, 1); in ocs_scsi_check_pending()
1099 * @brief Attempt to dispatch a non-abort IO
1103 * - if the pending list is not empty, add IO to pending list
1105 * - if pending list is empty, try to allocate a HW IO. If none
1108 * - if HW IO is available, attach this IO to the HW IO and
1114 * @return Returns 0 on success, a negative error code value on failure.
1121 ocs_t *ocs = io->ocs; in ocs_scsi_io_dispatch()
1122 ocs_xport_t *xport = ocs->xport; in ocs_scsi_io_dispatch()
1124 ocs_assert(io->cmd_tgt || io->cmd_ini, -1); in ocs_scsi_io_dispatch()
1125 ocs_assert((io->io_type != OCS_IO_TYPE_ABORT), -1); in ocs_scsi_io_dispatch()
1126 io->hw_cb = cb; in ocs_scsi_io_dispatch()
1129 * if this IO already has a HW IO, then this is either not the first phase of in ocs_scsi_io_dispatch()
1132 if (io->hio != NULL) { in ocs_scsi_io_dispatch()
1133 return ocs_scsi_io_dispatch_hw_io(io, io->hio); in ocs_scsi_io_dispatch()
1141 ocs_lock(&xport->io_pending_lock); in ocs_scsi_io_dispatch()
1142 if (!ocs_list_empty(&xport->io_pending_list)) { in ocs_scsi_io_dispatch()
1147 if (io->low_latency) { in ocs_scsi_io_dispatch()
1148 ocs_list_add_head(&xport->io_pending_list, io); in ocs_scsi_io_dispatch()
1150 ocs_list_add_tail(&xport->io_pending_list, io); in ocs_scsi_io_dispatch()
1152 ocs_unlock(&xport->io_pending_lock); in ocs_scsi_io_dispatch()
1153 ocs_atomic_add_return(&xport->io_pending_count, 1); in ocs_scsi_io_dispatch()
1154 ocs_atomic_add_return(&xport->io_total_pending, 1); in ocs_scsi_io_dispatch()
1160 ocs_unlock(&xport->io_pending_lock); in ocs_scsi_io_dispatch()
1166 hio = ocs_hw_io_alloc(&io->ocs->hw); in ocs_scsi_io_dispatch()
1169 ocs_lock(&xport->io_pending_lock); in ocs_scsi_io_dispatch()
1170 ocs_list_add_tail(&xport->io_pending_list, io); in ocs_scsi_io_dispatch()
1171 ocs_unlock(&xport->io_pending_lock); in ocs_scsi_io_dispatch()
1173 ocs_atomic_add_return(&xport->io_total_pending, 1); in ocs_scsi_io_dispatch()
1174 ocs_atomic_add_return(&xport->io_pending_count, 1); in ocs_scsi_io_dispatch()
1187 * - if the pending list is not empty, add IO to pending list
1189 * - if pending list is empty, send abort to the HW.
1194 * @return Returns 0 on success, a negative error code value on failure.
1200 ocs_t *ocs = io->ocs; in ocs_scsi_io_dispatch_abort()
1201 ocs_xport_t *xport = ocs->xport; in ocs_scsi_io_dispatch_abort()
1203 ocs_assert((io->io_type == OCS_IO_TYPE_ABORT), -1); in ocs_scsi_io_dispatch_abort()
1204 io->hw_cb = cb; in ocs_scsi_io_dispatch_abort()
1211 ocs_lock(&xport->io_pending_lock); in ocs_scsi_io_dispatch_abort()
1212 if (!ocs_list_empty(&xport->io_pending_list)) { in ocs_scsi_io_dispatch_abort()
1213 ocs_list_add_tail(&xport->io_pending_list, io); in ocs_scsi_io_dispatch_abort()
1214 ocs_unlock(&xport->io_pending_lock); in ocs_scsi_io_dispatch_abort()
1215 ocs_atomic_add_return(&xport->io_pending_count, 1); in ocs_scsi_io_dispatch_abort()
1216 ocs_atomic_add_return(&xport->io_total_pending, 1); in ocs_scsi_io_dispatch_abort()
1222 ocs_unlock(&xport->io_pending_lock); in ocs_scsi_io_dispatch_abort()
1239 * @return Returns 0 on success, a negative error code value on failure.
1246 ocs_t *ocs = io->ocs; in ocs_scsi_io_dispatch_hw_io()
1249 io->hio = hio; in ocs_scsi_io_dispatch_hw_io()
1250 if (io->cmd_tgt) { in ocs_scsi_io_dispatch_hw_io()
1251 io->tgt_task_tag = hio->indicator; in ocs_scsi_io_dispatch_hw_io()
1252 } else if (io->cmd_ini) { in ocs_scsi_io_dispatch_hw_io()
1253 io->init_task_tag = hio->indicator; in ocs_scsi_io_dispatch_hw_io()
1255 io->hw_tag = hio->reqtag; in ocs_scsi_io_dispatch_hw_io()
1257 hio->eq = io->hw_priv; in ocs_scsi_io_dispatch_hw_io()
1260 switch(io->wq_steering) { in ocs_scsi_io_dispatch_hw_io()
1262 hio->wq_steering = OCS_HW_WQ_STEERING_CLASS; in ocs_scsi_io_dispatch_hw_io()
1265 hio->wq_steering = OCS_HW_WQ_STEERING_REQUEST; in ocs_scsi_io_dispatch_hw_io()
1268 hio->wq_steering = OCS_HW_WQ_STEERING_CPU; in ocs_scsi_io_dispatch_hw_io()
1272 switch (io->io_type) { in ocs_scsi_io_dispatch_hw_io()
1278 ocs_hw_get(&ocs->hw, OCS_HW_N_SGL, &max_sgl); in ocs_scsi_io_dispatch_hw_io()
1279 ocs_hw_get(&ocs->hw, OCS_HW_SGL_CHAINING_HOST_ALLOCATED, &host_allocated); in ocs_scsi_io_dispatch_hw_io()
1285 total_count = ocs_scsi_count_sgls(&io->hw_dif, io->sgl, io->sgl_count); in ocs_scsi_io_dispatch_hw_io()
1293 uint32_t count = total_count - max_sgl + 1; in ocs_scsi_io_dispatch_hw_io()
1294 rc = ocs_dma_alloc(ocs, &io->ovfl_sgl, count*sizeof(sli4_sge_t), 64); in ocs_scsi_io_dispatch_hw_io()
1299 rc = ocs_hw_io_register_sgl(&ocs->hw, io->hio, &io->ovfl_sgl, count); in ocs_scsi_io_dispatch_hw_io()
1306 io->node->chained_io_count++; in ocs_scsi_io_dispatch_hw_io()
1309 rc = ocs_scsi_build_sgls(&ocs->hw, io->hio, &io->hw_dif, io->sgl, io->sgl_count, io->hio_type); in ocs_scsi_io_dispatch_hw_io()
1319 if (io->app_id) { in ocs_scsi_io_dispatch_hw_io()
1320 io->iparam.fcp_tgt.app_id = io->app_id; in ocs_scsi_io_dispatch_hw_io()
1323 …rc = ocs_hw_io_send(&io->ocs->hw, io->hio_type, io->hio, io->wire_len, &io->iparam, &io->node->rno… in ocs_scsi_io_dispatch_hw_io()
1324 io->hw_cb, io); in ocs_scsi_io_dispatch_hw_io()
1329 rc = ocs_hw_srrs_send(&ocs->hw, io->hio_type, io->hio, in ocs_scsi_io_dispatch_hw_io()
1330 &io->els_req, io->wire_len, in ocs_scsi_io_dispatch_hw_io()
1331 &io->els_rsp, &io->node->rnode, &io->iparam, in ocs_scsi_io_dispatch_hw_io()
1332 io->hw_cb, io); in ocs_scsi_io_dispatch_hw_io()
1336 rc = ocs_hw_srrs_send(&ocs->hw, io->hio_type, io->hio, in ocs_scsi_io_dispatch_hw_io()
1337 &io->els_rsp, io->wire_len, in ocs_scsi_io_dispatch_hw_io()
1338 NULL, &io->node->rnode, &io->iparam, in ocs_scsi_io_dispatch_hw_io()
1339 io->hw_cb, io); in ocs_scsi_io_dispatch_hw_io()
1345 rc = ocs_hw_srrs_send(&ocs->hw, io->hio_type, io->hio, in ocs_scsi_io_dispatch_hw_io()
1346 NULL, 0, NULL, &io->node->rnode, &io->iparam, io->hw_cb, io); in ocs_scsi_io_dispatch_hw_io()
1350 scsi_io_printf(io, "Unknown IO type=%d\n", io->io_type); in ocs_scsi_io_dispatch_hw_io()
1351 rc = -1; in ocs_scsi_io_dispatch_hw_io()
1365 * @return Returns 0 on success, or a negative error code value on failure.
1373 switch (io->io_type) { in ocs_scsi_io_dispatch_no_hw_io()
1376 ocs_assert(io->io_to_abort, -1); in ocs_scsi_io_dispatch_no_hw_io()
1377 hio_to_abort = io->io_to_abort->hio; in ocs_scsi_io_dispatch_no_hw_io()
1383 * the backend, but the data phase has not yet started, so we don't in ocs_scsi_io_dispatch_no_hw_io()
1391 SCSI_IOFMT_ARGS(io->io_to_abort)); in ocs_scsi_io_dispatch_no_hw_io()
1392 ((ocs_hw_done_t)io->hw_cb)(io->hio, NULL, 0, SLI4_FC_WCQE_STATUS_SUCCESS, 0, io); in ocs_scsi_io_dispatch_no_hw_io()
1396 scsi_io_printf(io, "aborting " SCSI_IOFMT "\n", SCSI_IOFMT_ARGS(io->io_to_abort)); in ocs_scsi_io_dispatch_no_hw_io()
1397 rc = ocs_hw_io_abort(&io->ocs->hw, hio_to_abort, io->send_abts, in ocs_scsi_io_dispatch_no_hw_io()
1398 io->hw_cb, io); in ocs_scsi_io_dispatch_no_hw_io()
1403 status = -1; in ocs_scsi_io_dispatch_no_hw_io()
1405 SCSI_IOFMT_ARGS(io->io_to_abort), rc); in ocs_scsi_io_dispatch_no_hw_io()
1407 ((ocs_hw_done_t)io->hw_cb)(io->hio, NULL, 0, status, 0, io); in ocs_scsi_io_dispatch_no_hw_io()
1415 scsi_io_printf(io, "Unknown IO type=%d\n", io->io_type); in ocs_scsi_io_dispatch_no_hw_io()
1416 rc = -1; in ocs_scsi_io_dispatch_no_hw_io()
1427 * This call is made by a target-server to initiate a SCSI read or write data phase, transferring
1429 * scatter-gather list @c sgl of length @c sgl_count. The @c wire_len argument
1430 * specifies the payload length (independent of the scatter-gather list cumulative length).
1436 * IO has completed (OCS_SCSI_IO_COMPL) and another data phase or response may be sent;
1443 * @param sgl Pointer to the payload scatter-gather list.
1444 * @param sgl_count Count of the scatter-gather list elements.
1447 * @param enable_ar Enable auto-response if true.
1449 * @param arg Application-supplied callback data.
1451 * @return Returns 0 on success, or a negative error code value on failure.
1466 if ((dif_info != NULL) && (dif_info->dif_oper == OCS_SCSI_DIF_OPER_DISABLED)) { in ocs_scsi_xfer_data()
1470 ocs_assert(io, -1); in ocs_scsi_xfer_data()
1473 ocs_hw_get(&io->ocs->hw, OCS_HW_DISABLE_AR_TGT_DIF, &disable_ar_tgt_dif); in ocs_scsi_xfer_data()
1479 io->sgl_count = sgl_count; in ocs_scsi_xfer_data()
1482 if (sgl && (sgl != io->sgl)) { in ocs_scsi_xfer_data()
1483 ocs_assert(sgl_count <= io->sgl_allocated, -1); in ocs_scsi_xfer_data()
1484 ocs_memcpy(io->sgl, sgl, sgl_count*sizeof(*io->sgl)); in ocs_scsi_xfer_data()
1487 ocs = io->ocs; in ocs_scsi_xfer_data()
1488 ocs_assert(ocs, -1); in ocs_scsi_xfer_data()
1489 ocs_assert(io->node, -1); in ocs_scsi_xfer_data()
1493 ocs_assert(sgl, -1); in ocs_scsi_xfer_data()
1494 ocs_assert(sgl_count > 0, -1); in ocs_scsi_xfer_data()
1495 ocs_assert(io->exp_xfer_len > io->transferred, -1); in ocs_scsi_xfer_data()
1497 io->hio_type = type; in ocs_scsi_xfer_data()
1499 io->scsi_tgt_cb = cb; in ocs_scsi_xfer_data()
1500 io->scsi_tgt_cb_arg = arg; in ocs_scsi_xfer_data()
1502 rc = ocs_scsi_convert_dif_info(ocs, dif_info, &io->hw_dif); in ocs_scsi_xfer_data()
1509 io->scsi_dif_info = *dif_info; in ocs_scsi_xfer_data()
1512 io->wire_len = MIN(xwire_len, io->exp_xfer_len - io->transferred); in ocs_scsi_xfer_data()
1513 residual = (xwire_len - io->wire_len); in ocs_scsi_xfer_data()
1515 ocs_memset(&io->iparam, 0, sizeof(io->iparam)); in ocs_scsi_xfer_data()
1516 io->iparam.fcp_tgt.ox_id = io->init_task_tag; in ocs_scsi_xfer_data()
1517 io->iparam.fcp_tgt.offset = io->transferred; in ocs_scsi_xfer_data()
1518 io->iparam.fcp_tgt.dif_oper = io->hw_dif.dif; in ocs_scsi_xfer_data()
1519 io->iparam.fcp_tgt.blk_size = io->hw_dif.blk_size; in ocs_scsi_xfer_data()
1520 io->iparam.fcp_tgt.cs_ctl = io->cs_ctl; in ocs_scsi_xfer_data()
1521 io->iparam.fcp_tgt.timeout = io->timeout; in ocs_scsi_xfer_data()
1523 /* if this is the last data phase and there is no residual, enable in ocs_scsi_xfer_data()
1524 * auto-good-response in ocs_scsi_xfer_data()
1527 …(residual == 0) && ((io->transferred + io->wire_len) == io->exp_xfer_len) && (!(flags & OCS_SCSI_N… in ocs_scsi_xfer_data()
1528 io->iparam.fcp_tgt.flags |= SLI4_IO_AUTO_GOOD_RESPONSE; in ocs_scsi_xfer_data()
1529 io->auto_resp = TRUE; in ocs_scsi_xfer_data()
1531 io->auto_resp = FALSE; in ocs_scsi_xfer_data()
1535 io->xfer_req = io->wire_len; in ocs_scsi_xfer_data()
1540 io->transferred += residual; in ocs_scsi_xfer_data()
1545 ocs_scsi_sgl_t *sgl_ptr = &io->sgl[sgl_count-1]; in ocs_scsi_xfer_data()
1548 size_t len = sgl_ptr->len; in ocs_scsi_xfer_data()
1550 sgl_ptr->len = len - residual; in ocs_scsi_xfer_data()
1553 sgl_ptr->len = 0; in ocs_scsi_xfer_data()
1554 residual -= len; in ocs_scsi_xfer_data()
1555 io->sgl_count--; in ocs_scsi_xfer_data()
1557 sgl_ptr--; in ocs_scsi_xfer_data()
1562 io->low_latency = (flags & OCS_SCSI_LOW_LATENCY) != 0; in ocs_scsi_xfer_data()
1563 io->wq_steering = (flags & OCS_SCSI_WQ_STEERING_MASK) >> OCS_SCSI_WQ_STEERING_SHIFT; in ocs_scsi_xfer_data()
1564 io->wq_class = (flags & OCS_SCSI_WQ_CLASS_MASK) >> OCS_SCSI_WQ_CLASS_SHIFT; in ocs_scsi_xfer_data()
1576 enable_tsend_auto_resp(io->ocs), cb, arg); in ocs_scsi_send_rd_data()
1586 enable_treceive_auto_resp(io->ocs), cb, arg); in ocs_scsi_recv_wr_data()
1602 if (io->ovfl_sgl.size) { in ocs_scsi_io_free_ovfl()
1603 ocs_dma_free(io->ocs, &io->ovfl_sgl); in ocs_scsi_io_free_ovfl()
1612 * This function is used by a target-server to send the SCSI response data to a remote
1613 * initiator node. The target-server populates the @c ocs_scsi_cmd_resp_t
1617 * Upon completion, the callback function @c cb is invoked. The target-server will generally
1624 * @param arg Application-specified completion callback argument.
1626 * @return Returns 0 on success, or a negative error code value on failure.
1639 ocs_assert(io, -1); in ocs_scsi_send_resp()
1641 ocs = io->ocs; in ocs_scsi_send_resp()
1642 ocs_assert(ocs, -1); in ocs_scsi_send_resp()
1644 ocs_assert(io->node, -1); in ocs_scsi_send_resp()
1646 ocs_scsi_convert_dif_info(ocs, NULL, &io->hw_dif); in ocs_scsi_send_resp()
1649 scsi_status = rsp->scsi_status; in ocs_scsi_send_resp()
1650 scsi_status_qualifier = rsp->scsi_status_qualifier; in ocs_scsi_send_resp()
1651 sense_data = rsp->sense_data; in ocs_scsi_send_resp()
1652 sense_data_length = rsp->sense_data_length; in ocs_scsi_send_resp()
1653 residual = rsp->residual; in ocs_scsi_send_resp()
1655 residual = io->exp_xfer_len - io->transferred; in ocs_scsi_send_resp()
1658 io->wire_len = 0; in ocs_scsi_send_resp()
1659 io->hio_type = OCS_HW_IO_TARGET_RSP; in ocs_scsi_send_resp()
1661 io->scsi_tgt_cb = cb; in ocs_scsi_send_resp()
1662 io->scsi_tgt_cb_arg = arg; in ocs_scsi_send_resp()
1664 ocs_memset(&io->iparam, 0, sizeof(io->iparam)); in ocs_scsi_send_resp()
1665 io->iparam.fcp_tgt.ox_id = io->init_task_tag; in ocs_scsi_send_resp()
1666 io->iparam.fcp_tgt.offset = 0; in ocs_scsi_send_resp()
1667 io->iparam.fcp_tgt.cs_ctl = io->cs_ctl; in ocs_scsi_send_resp()
1668 io->iparam.fcp_tgt.timeout = io->timeout; in ocs_scsi_send_resp()
1671 io->low_latency = (flags & OCS_SCSI_LOW_LATENCY) != 0; in ocs_scsi_send_resp()
1672 io->wq_steering = (flags & OCS_SCSI_WQ_STEERING_MASK) >> OCS_SCSI_WQ_STEERING_SHIFT; in ocs_scsi_send_resp()
1673 io->wq_class = (flags & OCS_SCSI_WQ_CLASS_MASK) >> OCS_SCSI_WQ_CLASS_SHIFT; in ocs_scsi_send_resp()
1676 fcp_rsp_iu_t *fcprsp = io->rspbuf.virt; in ocs_scsi_send_resp()
1680 return -1; in ocs_scsi_send_resp()
1687 io->wire_len += (sizeof(*fcprsp) - sizeof(fcprsp->data)); in ocs_scsi_send_resp()
1689 fcprsp->scsi_status = scsi_status; in ocs_scsi_send_resp()
1690 *((uint16_t*)fcprsp->status_qualifier) = ocs_htobe16(scsi_status_qualifier); in ocs_scsi_send_resp()
1699 fcprsp->flags |= FCP_RESID_UNDER; in ocs_scsi_send_resp()
1700 *((uint32_t *)fcprsp->fcp_resid) = ocs_htobe32(residual); in ocs_scsi_send_resp()
1702 fcprsp->flags |= FCP_RESID_OVER; in ocs_scsi_send_resp()
1703 *((uint32_t *)fcprsp->fcp_resid) = ocs_htobe32(-residual); in ocs_scsi_send_resp()
1708 ocs_assert(sense_data_length <= sizeof(fcprsp->data), -1); in ocs_scsi_send_resp()
1709 fcprsp->flags |= FCP_SNS_LEN_VALID; in ocs_scsi_send_resp()
1710 ocs_memcpy(fcprsp->data, sense_data, sense_data_length); in ocs_scsi_send_resp()
1711 *((uint32_t*)fcprsp->fcp_sns_len) = ocs_htobe32(sense_data_length); in ocs_scsi_send_resp()
1712 io->wire_len += sense_data_length; in ocs_scsi_send_resp()
1715 io->sgl[0].addr = io->rspbuf.phys; in ocs_scsi_send_resp()
1716 io->sgl[0].dif_addr = 0; in ocs_scsi_send_resp()
1717 io->sgl[0].len = io->wire_len; in ocs_scsi_send_resp()
1718 io->sgl_count = 1; in ocs_scsi_send_resp()
1722 io->iparam.fcp_tgt.flags |= SLI4_IO_AUTO_GOOD_RESPONSE; in ocs_scsi_send_resp()
1733 * This function is used by a target-server to send SCSI TMF response data to a remote
1735 * Upon completion, the callback function @c cb is invoked. The target-server will generally
1742 * @param arg Application-specified completion callback argument.
1744 * @return Returns 0 on success, or a negative error code value on failure.
1750 int32_t rc = -1; in ocs_scsi_send_tmf_resp()
1756 ocs_assert(io, -1); in ocs_scsi_send_tmf_resp()
1757 ocs_assert(io->ocs, -1); in ocs_scsi_send_tmf_resp()
1758 ocs_assert(io->node, -1); in ocs_scsi_send_tmf_resp()
1760 ocs = io->ocs; in ocs_scsi_send_tmf_resp()
1762 io->wire_len = 0; in ocs_scsi_send_tmf_resp()
1763 ocs_scsi_convert_dif_info(ocs, NULL, &io->hw_dif); in ocs_scsi_send_tmf_resp()
1787 io->hio_type = OCS_HW_IO_TARGET_RSP; in ocs_scsi_send_tmf_resp()
1789 io->scsi_tgt_cb = cb; in ocs_scsi_send_tmf_resp()
1790 io->scsi_tgt_cb_arg = arg; in ocs_scsi_send_tmf_resp()
1792 if (io->tmf_cmd == OCS_SCSI_TMF_ABORT_TASK) { in ocs_scsi_send_tmf_resp()
1798 fcprsp = io->rspbuf.virt; in ocs_scsi_send_tmf_resp()
1801 fcprsp->flags |= FCP_RSP_LEN_VALID; in ocs_scsi_send_tmf_resp()
1803 rspinfo = (fcp_rsp_info_t*) fcprsp->data; in ocs_scsi_send_tmf_resp()
1805 ocs_memcpy(rspinfo->addl_rsp_info, addl_rsp_info, sizeof(rspinfo->addl_rsp_info)); in ocs_scsi_send_tmf_resp()
1807 rspinfo->rsp_code = fcp_rspcode; in ocs_scsi_send_tmf_resp()
1809 io->wire_len = sizeof(*fcprsp) - sizeof(fcprsp->data) + sizeof(*rspinfo); in ocs_scsi_send_tmf_resp()
1811 *((uint32_t*)fcprsp->fcp_rsp_len) = ocs_htobe32(sizeof(*rspinfo)); in ocs_scsi_send_tmf_resp()
1813 io->sgl[0].addr = io->rspbuf.phys; in ocs_scsi_send_tmf_resp()
1814 io->sgl[0].dif_addr = 0; in ocs_scsi_send_tmf_resp()
1815 io->sgl[0].len = io->wire_len; in ocs_scsi_send_tmf_resp()
1816 io->sgl_count = 1; in ocs_scsi_send_tmf_resp()
1818 ocs_memset(&io->iparam, 0, sizeof(io->iparam)); in ocs_scsi_send_tmf_resp()
1819 io->iparam.fcp_tgt.ox_id = io->init_task_tag; in ocs_scsi_send_tmf_resp()
1820 io->iparam.fcp_tgt.offset = 0; in ocs_scsi_send_tmf_resp()
1821 io->iparam.fcp_tgt.cs_ctl = io->cs_ctl; in ocs_scsi_send_tmf_resp()
1822 io->iparam.fcp_tgt.timeout = io->timeout; in ocs_scsi_send_tmf_resp()
1840 * @param app Application-specified callback data.
1842 * @return Returns 0 on success, or a negative error code value on failure.
1852 ocs_assert(io, -1); in ocs_target_abort_cb()
1853 ocs_assert(io->ocs, -1); in ocs_target_abort_cb()
1855 ocs = io->ocs; in ocs_target_abort_cb()
1857 if (io->abort_cb) { in ocs_target_abort_cb()
1858 ocs_scsi_io_cb_t abort_cb = io->abort_cb; in ocs_target_abort_cb()
1859 void *abort_cb_arg = io->abort_cb_arg; in ocs_target_abort_cb()
1861 io->abort_cb = NULL; in ocs_target_abort_cb()
1862 io->abort_cb_arg = NULL; in ocs_target_abort_cb()
1890 abort_cb(io->io_to_abort, scsi_status, 0, abort_cb_arg); in ocs_target_abort_cb()
1893 ocs_assert(io != io->io_to_abort, -1); in ocs_target_abort_cb()
1896 ocs_ref_put(&io->io_to_abort->ref); /* ocs_ref_get(): ocs_scsi_tgt_abort_io() */ in ocs_target_abort_cb()
1909 * This routine is called from a SCSI target-server. It initiates an abort of a
1910 * previously-issued target data phase or response request.
1916 * @return Returns 0 on success, or a non-zero value on failure.
1926 ocs_assert(io, -1); in ocs_scsi_tgt_abort_io()
1927 ocs_assert(io->node, -1); in ocs_scsi_tgt_abort_io()
1928 ocs_assert(io->ocs, -1); in ocs_scsi_tgt_abort_io()
1930 ocs = io->ocs; in ocs_scsi_tgt_abort_io()
1931 xport = ocs->xport; in ocs_scsi_tgt_abort_io()
1934 if ((ocs_ref_get_unless_zero(&io->ref) == 0)) { in ocs_scsi_tgt_abort_io()
1937 return -1; in ocs_scsi_tgt_abort_io()
1947 ocs_atomic_add_return(&xport->io_alloc_failed_count, 1); in ocs_scsi_tgt_abort_io()
1948 ocs_ref_put(&io->ref); /* ocs_ref_get(): same function */ in ocs_scsi_tgt_abort_io()
1949 return -1; in ocs_scsi_tgt_abort_io()
1953 ocs_assert(abort_io->hio == NULL, -1); in ocs_scsi_tgt_abort_io()
1956 abort_io->cmd_tgt = TRUE; in ocs_scsi_tgt_abort_io()
1957 abort_io->node = io->node; in ocs_scsi_tgt_abort_io()
1959 /* set type and abort-specific fields */ in ocs_scsi_tgt_abort_io()
1960 abort_io->io_type = OCS_IO_TYPE_ABORT; in ocs_scsi_tgt_abort_io()
1961 abort_io->display_name = "tgt_abort"; in ocs_scsi_tgt_abort_io()
1962 abort_io->io_to_abort = io; in ocs_scsi_tgt_abort_io()
1963 abort_io->send_abts = FALSE; in ocs_scsi_tgt_abort_io()
1964 abort_io->abort_cb = cb; in ocs_scsi_tgt_abort_io()
1965 abort_io->abort_cb_arg = arg; in ocs_scsi_tgt_abort_io()
1970 ocs_ref_put(&io->ref); /* ocs_ref_get(): same function */ in ocs_scsi_tgt_abort_io()
1986 * @param app Application-specified callback data.
1988 * @return Returns 0 on success, or a negative error code value on failure.
1998 ocs_assert(io, -1); in ocs_target_bls_resp_cb()
1999 ocs_assert(io->ocs, -1); in ocs_target_bls_resp_cb()
2001 ocs = io->ocs; in ocs_target_bls_resp_cb()
2011 if (io->bls_cb) { in ocs_target_bls_resp_cb()
2012 ocs_scsi_io_cb_t bls_cb = io->bls_cb; in ocs_target_bls_resp_cb()
2013 void *bls_cb_arg = io->bls_cb_arg; in ocs_target_bls_resp_cb()
2015 io->bls_cb = NULL; in ocs_target_bls_resp_cb()
2016 io->bls_cb_arg = NULL; in ocs_target_bls_resp_cb()
2034 * @param arg Application-specified completion callback argument.
2036 * @return Returns 0 on success, or a negative error code value on failure.
2045 ocs_assert(io, -1); in ocs_target_send_bls_resp()
2048 ocs_memset(&io->iparam, 0, sizeof(io->iparam)); in ocs_target_send_bls_resp()
2049 io->iparam.bls.ox_id = io->init_task_tag; in ocs_target_send_bls_resp()
2050 io->iparam.bls.rx_id = io->abort_rx_id; in ocs_target_send_bls_resp()
2052 acc = (void *)io->iparam.bls.payload; in ocs_target_send_bls_resp()
2054 ocs_memset(io->iparam.bls.payload, 0, sizeof(io->iparam.bls.payload)); in ocs_target_send_bls_resp()
2055 acc->ox_id = io->iparam.bls.ox_id; in ocs_target_send_bls_resp()
2056 acc->rx_id = io->iparam.bls.rx_id; in ocs_target_send_bls_resp()
2057 acc->high_seq_cnt = UINT16_MAX; in ocs_target_send_bls_resp()
2061 /* set type and BLS-specific fields */ in ocs_target_send_bls_resp()
2062 io->io_type = OCS_IO_TYPE_BLS_RESP; in ocs_target_send_bls_resp()
2063 io->display_name = "bls_rsp"; in ocs_target_send_bls_resp()
2064 io->hio_type = OCS_HW_BLS_ACC; in ocs_target_send_bls_resp()
2065 io->bls_cb = cb; in ocs_target_send_bls_resp()
2066 io->bls_cb_arg = arg; in ocs_target_send_bls_resp()
2078 * This function is called by a target-server to notify the base driver that an IO
2081 * @n @b Note: This function is not called by initiator-clients.
2093 ocs_log_test(io->ocs, "Got completion for non-busy io with tag 0x%x\n", io->tag); in ocs_scsi_io_complete()
2097 scsi_io_trace(io, "freeing io 0x%p %s\n", io, io->display_name); in ocs_scsi_io_complete()
2098 ocs_assert(ocs_ref_read_count(&io->ref) > 0); in ocs_scsi_io_complete()
2099 ocs_ref_put(&io->ref); /* ocs_ref_get(): ocs_scsi_io_alloc() */ in ocs_scsi_io_complete()
2113 * @param app Application-specified callback data.
2127 ocs_assert(io->scsi_ini_cb); in ocs_initiator_io_cb()
2131 ocs = io->ocs; in ocs_initiator_io_cb()
2137 if (io->scsi_ini_cb) { in ocs_initiator_io_cb()
2138 fcp_rsp_iu_t *fcprsp = io->rspbuf.virt; in ocs_initiator_io_cb()
2140 ocs_scsi_rsp_io_cb_t cb = io->scsi_ini_cb; in ocs_initiator_io_cb()
2142 uint8_t *pd = fcprsp->data; in ocs_initiator_io_cb()
2145 io->scsi_ini_cb = NULL; in ocs_initiator_io_cb()
2156 rsp.scsi_status = fcprsp->scsi_status; in ocs_initiator_io_cb()
2157 rsp.scsi_status_qualifier = ocs_be16toh(*((uint16_t*)fcprsp->status_qualifier)); in ocs_initiator_io_cb()
2159 if (fcprsp->flags & FCP_RSP_LEN_VALID) { in ocs_initiator_io_cb()
2161 rsp.response_data_length = ocs_fc_getbe32(fcprsp->fcp_rsp_len); in ocs_initiator_io_cb()
2164 if (fcprsp->flags & FCP_SNS_LEN_VALID) { in ocs_initiator_io_cb()
2165 uint32_t sns_len = ocs_fc_getbe32(fcprsp->fcp_sns_len); in ocs_initiator_io_cb()
2171 if (fcprsp->flags & FCP_RESID_OVER) { in ocs_initiator_io_cb()
2172 rsp.residual = -ocs_fc_getbe32(fcprsp->fcp_resid); in ocs_initiator_io_cb()
2174 } else if (fcprsp->flags & FCP_RESID_UNDER) { in ocs_initiator_io_cb()
2175 rsp.residual = ocs_fc_getbe32(fcprsp->fcp_resid); in ocs_initiator_io_cb()
2185 if (length != io->wire_len) { in ocs_initiator_io_cb()
2187 uint8_t *rsp_bytes = io->rspbuf.virt; in ocs_initiator_io_cb()
2199 ocs_log_test(io->ocs, "[%s]" SCSI_IOFMT "local reject=0x%02x\n", in ocs_initiator_io_cb()
2200 io->node->display_name, SCSI_IOFMT_ARGS(io), in ocs_initiator_io_cb()
2232 cb(io, scsi_status, &rsp, flags, io->scsi_ini_cb_arg); in ocs_initiator_io_cb()
2242 * This call is made by an initiator-client to send a SCSI read command. The payload
2243 * for the command is given by a scatter-gather list @c sgl for @c sgl_count
2255 * @param sgl Pointer to the scatter-gather list.
2256 * @param sgl_count Count of the scatter-gather list elements.
2259 * @param arg Application-specified completion callback argument.
2261 * @return Returns 0 on success, or a negative error code value on failure.
2282 * This call is made by an initiator-client to send a SCSI write command. The payload
2283 * for the command is given by a scatter-gather list @c sgl for @c sgl_count
2295 * @param sgl Pointer to the scatter-gather list.
2296 * @param sgl_count Count of the scatter-gather list elements.
2299 * @param arg Application-specified completion callback argument.
2301 * @return Returns 0 on success, or a negative error code value on failure.
2321 * This call is made by an initiator-client to send a SCSI write command. The payload
2322 * for the command is given by a scatter-gather list @c sgl for @c sgl_count
2334 * @param sgl Pointer to the scatter-gather list.
2335 * @param sgl_count Count of the scatter-gather list elements.
2339 * @param arg Application-specified completion callback argument.
2341 * @return Returns 0 on success, or a negative error code value on failure.
2362 * This call is made by an initiator-client to send a SCSI command with no data.
2373 * @param arg Application-specified completion callback argument.
2375 * @return Returns 0 on success, or a negative error code value on failure.
2405 * @param sgl Pointer to the scatter-gather list.
2406 * @param sgl_count Count of the scatter-gather list elements.
2409 * @param arg Application-specified completion callback argument.
2411 * @return Returns 0 on success, or a negative error code value on failure.
2418 ocs_assert(io, -1); in ocs_scsi_send_tmf()
2421 ocs_assert(io_to_abort, -1); in ocs_scsi_send_tmf()
2424 if ((ocs_ref_get_unless_zero(&io_to_abort->ref) == 0)) { in ocs_scsi_send_tmf()
2427 return -1; in ocs_scsi_send_tmf()
2431 /* abort-specific fields */ in ocs_scsi_send_tmf()
2432 io->io_type = OCS_IO_TYPE_ABORT; in ocs_scsi_send_tmf()
2433 io->display_name = "abort_task"; in ocs_scsi_send_tmf()
2434 io->io_to_abort = io_to_abort; in ocs_scsi_send_tmf()
2435 io->send_abts = TRUE; in ocs_scsi_send_tmf()
2436 io->scsi_ini_cb = cb; in ocs_scsi_send_tmf()
2437 io->scsi_ini_cb_arg = arg; in ocs_scsi_send_tmf()
2443 ocs_ref_put(&io->ref); /* ocs_ref_get(): same function */ in ocs_scsi_send_tmf()
2446 io->display_name = "tmf"; in ocs_scsi_send_tmf()
2469 * @param sgl Pointer to the scatter-gather list.
2474 * @param arg Application-specified completion callback argument.
2476 * @return Returns 0 on success, or a negative error code value on failure.
2494 ocs_assert(io->node, -1); in ocs_scsi_send_io()
2495 ocs_assert(io->node == node, -1); in ocs_scsi_send_io()
2496 ocs_assert(io, -1); in ocs_scsi_send_io()
2497 ocs = io->ocs; in ocs_scsi_send_io()
2498 ocs_assert(cb, -1); in ocs_scsi_send_io()
2500 io->sgl_count = sgl_count; in ocs_scsi_send_io()
2503 if (sgl != io->sgl) { in ocs_scsi_send_io()
2504 ocs_assert(sgl_count <= io->sgl_allocated, -1); in ocs_scsi_send_io()
2505 ocs_memcpy(io->sgl, sgl, sizeof(*io->sgl) * sgl_count); in ocs_scsi_send_io()
2509 io->tgt_task_tag = 0xffff; in ocs_scsi_send_io()
2511 io->wire_len = wire_len; in ocs_scsi_send_io()
2512 io->hio_type = type; in ocs_scsi_send_io()
2523 ocs_textbuf_printf(&txtbuf, "%02X%s", cdb[i], (i == (cdb_len-1)) ? "" : " "); in ocs_scsi_send_io()
2525 scsi_io_printf(io, "%s len %d, %s\n", (io->hio_type == OCS_HW_IO_INITIATOR_READ) ? "read" : in ocs_scsi_send_io()
2526 (io->hio_type == OCS_HW_IO_INITIATOR_WRITE) ? "write" : "", io->wire_len, in ocs_scsi_send_io()
2530 ocs_assert(io->cmdbuf.virt, -1); in ocs_scsi_send_io()
2532 cmnd = io->cmdbuf.virt; in ocs_scsi_send_io()
2534 ocs_assert(sizeof(*cmnd) <= io->cmdbuf.size, -1); in ocs_scsi_send_io()
2539 cmnd_bytes = sizeof(fcp_cmnd_iu_t) - sizeof(cmnd->fcp_cdb_and_dl) + sizeof(uint32_t); in ocs_scsi_send_io()
2541 fcp_dl = (uint32_t*)(&(cmnd->fcp_cdb_and_dl)); in ocs_scsi_send_io()
2545 ocs_memcpy(cmnd->fcp_cdb, cdb, cdb_len); in ocs_scsi_send_io()
2549 ocs_memcpy(cmnd->fcp_cdb, cdb, 16); in ocs_scsi_send_io()
2550 addl_cdb_bytes = cdb_len - 16; in ocs_scsi_send_io()
2551 ocs_memcpy(cmnd->fcp_cdb_and_dl, &(cdb[16]), addl_cdb_bytes); in ocs_scsi_send_io()
2553 cmnd->additional_fcp_cdb_length = (addl_cdb_bytes + 3) / 4; in ocs_scsi_send_io()
2554 fcp_dl += cmnd->additional_fcp_cdb_length; in ocs_scsi_send_io()
2561 be64enc(cmnd->fcp_lun, CAM_EXTLUN_BYTE_SWIZZLE(lun)); in ocs_scsi_send_io()
2563 if (node->fcp2device) { in ocs_scsi_send_io()
2564 if(ocs_get_crn(node, &cmnd->command_reference_number, in ocs_scsi_send_io()
2566 return -1; in ocs_scsi_send_io()
2570 cmnd->task_attribute = FCP_TASK_ATTR_HEAD_OF_QUEUE; in ocs_scsi_send_io()
2572 cmnd->task_attribute = FCP_TASK_ATTR_ORDERED; in ocs_scsi_send_io()
2574 cmnd->task_attribute = FCP_TASK_ATTR_UNTAGGED; in ocs_scsi_send_io()
2576 cmnd->task_attribute = FCP_TASK_ATTR_ACA; in ocs_scsi_send_io()
2578 cmnd->task_attribute = FCP_TASK_ATTR_SIMPLE; in ocs_scsi_send_io()
2579 cmnd->command_priority = (flags & OCS_SCSI_PRIORITY_MASK) >> in ocs_scsi_send_io()
2607 cmnd->task_management_flags = tmf_flags; in ocs_scsi_send_io()
2609 *fcp_dl = ocs_htobe32(io->wire_len); in ocs_scsi_send_io()
2611 switch (io->hio_type) { in ocs_scsi_send_io()
2613 cmnd->rddata = 1; in ocs_scsi_send_io()
2616 cmnd->wrdata = 1; in ocs_scsi_send_io()
2622 ocs_log_test(ocs, "bad IO type %d\n", io->hio_type); in ocs_scsi_send_io()
2623 return -1; in ocs_scsi_send_io()
2626 rc = ocs_scsi_convert_dif_info(ocs, dif_info, &io->hw_dif); in ocs_scsi_send_io()
2631 io->scsi_ini_cb = cb; in ocs_scsi_send_io()
2632 io->scsi_ini_cb_arg = arg; in ocs_scsi_send_io()
2635 io->iparam.fcp_ini.cmnd = &io->cmdbuf; in ocs_scsi_send_io()
2636 io->iparam.fcp_ini.cmnd_size = cmnd_bytes; in ocs_scsi_send_io()
2637 io->iparam.fcp_ini.rsp = &io->rspbuf; in ocs_scsi_send_io()
2638 io->iparam.fcp_ini.flags = 0; in ocs_scsi_send_io()
2639 io->iparam.fcp_ini.dif_oper = io->hw_dif.dif; in ocs_scsi_send_io()
2640 io->iparam.fcp_ini.blk_size = io->hw_dif.blk_size; in ocs_scsi_send_io()
2641 io->iparam.fcp_ini.timeout = io->timeout; in ocs_scsi_send_io()
2642 io->iparam.fcp_ini.first_burst = first_burst; in ocs_scsi_send_io()
2659 * @param arg Application-specific callback, usually IO context.
2661 * @return Returns 0 on success, or a negative error code value on failure.
2672 ocs_assert(io, -1); in ocs_scsi_abort_io_cb()
2673 ocs_assert(ocs_io_busy(io), -1); in ocs_scsi_abort_io_cb()
2674 ocs_assert(io->ocs, -1); in ocs_scsi_abort_io_cb()
2675 ocs_assert(io->io_to_abort, -1); in ocs_scsi_abort_io_cb()
2676 ocs = io->ocs; in ocs_scsi_abort_io_cb()
2681 ocs_ref_put(&io->io_to_abort->ref); /* ocs_ref_get(): ocs_scsi_send_tmf() */ in ocs_scsi_abort_io_cb()
2706 if (io->scsi_ini_cb) { in ocs_scsi_abort_io_cb()
2707 (*io->scsi_ini_cb)(io, scsi_status, NULL, 0, io->scsi_ini_cb_arg); in ocs_scsi_abort_io_cb()
2721 * This function is called by a target-server or initiator-client to
2732 ocs_xport_t *xport = ocs->xport; in ocs_scsi_get_property()
2737 if (0 == ocs_hw_get(&ocs->hw, OCS_HW_MAX_SGE, &val)) { in ocs_scsi_get_property()
2742 if (ocs->ctrlmask & OCS_CTRLMASK_TEST_CHAINED_SGLS) { in ocs_scsi_get_property()
2744 * If chain SGL test-mode is enabled, the number of HW SGEs in ocs_scsi_get_property()
2749 if (0 == ocs_hw_get(&ocs->hw, OCS_HW_N_SGL, &val)) { in ocs_scsi_get_property()
2754 return ocs_io_pool_allocated(xport->io_pool); in ocs_scsi_get_property()
2756 if (0 == ocs_hw_get(&ocs->hw, OCS_HW_DIF_CAPABLE, &val)) { in ocs_scsi_get_property()
2763 if (ocs_hw_get(&ocs->hw, OCS_HW_DIF_MULTI_SEPARATE, &val) == 0) { in ocs_scsi_get_property()
2769 if (ocs_hw_get(&ocs->hw, OCS_HW_SEND_FRAME_CAPABLE, &val) == 0) { in ocs_scsi_get_property()
2786 * This function is called by a target-server or initiator-client to
2800 rc = ocs_hw_get_ptr(&ocs->hw, OCS_HW_WWN_NODE); in ocs_scsi_get_property_ptr()
2803 rc = ocs_hw_get_ptr(&ocs->hw, OCS_HW_WWN_PORT); in ocs_scsi_get_property_ptr()
2806 rc = ocs_hw_get_ptr(&ocs->hw, OCS_HW_PORTNUM); in ocs_scsi_get_property_ptr()
2809 rc = ocs_hw_get_ptr(&ocs->hw, OCS_HW_BIOS_VERSION_STRING); in ocs_scsi_get_property_ptr()
2816 if (ocs_hw_get(&ocs->hw, OCS_HW_VPD_LEN, &vpd_len)) { in ocs_scsi_get_property_ptr()
2818 rc = "\012sn-unknown"; in ocs_scsi_get_property_ptr()
2822 pvpd = ocs_hw_get_ptr(&ocs->hw, OCS_HW_VPD); in ocs_scsi_get_property_ptr()
2832 if ((ocs == NULL) || (ocs->domain == NULL) || (ocs->domain->sport == NULL)) { in ocs_scsi_get_property_ptr()
2835 rc = &ocs->domain->sport->wwnn_str[8]; in ocs_scsi_get_property_ptr()
2845 if (ocs_hw_get(&ocs->hw, OCS_HW_VPD_LEN, &vpd_len)) { in ocs_scsi_get_property_ptr()
2847 rc = "\012pn-unknown"; in ocs_scsi_get_property_ptr()
2850 pvpd = ocs_hw_get_ptr(&ocs->hw, OCS_HW_VPD); in ocs_scsi_get_property_ptr()
2854 rc = "\012pn-unknown"; in ocs_scsi_get_property_ptr()
2857 rc = "\012pn-unknown"; in ocs_scsi_get_property_ptr()
2876 * Sent by the target-server to notify the base driver that the work started from
2896 * Sent by the initiator-client to notify the base driver that the work started from
2915 * Updates io->transferred, as required when using first burst, when the amount
2927 io->transferred = transferred; in ocs_scsi_update_first_burst_transferred()
2931 * @brief Register bounce callback for multi-threading.
2947 rc = ocs_hw_callback(&ocs->hw, OCS_HW_CB_BOUNCE, fctn, NULL); in ocs_scsi_register_bounce()