65 ocs_t *ocs = iscsi->
os;
72 !cxn->nop_sent_for_tm &&
80 ocs_log_test(ocs,
"sending nop-in failed\n");
82 cxn->nop_sent_for_tm = TRUE;
83 ocs_atomic_add_return(&cxn->nop_abort_counter, 1);
103 io->on_abort_list = 1;
104 io->nop_abort_counter = ocs_atomic_read(&cxn->nop_abort_counter);
123 ocs_io_t *io, *io_next;
124 uint32_t abort_counter;
126 abort_counter = ocs_atomic_read(&cxn->nop_abort_counter);
134 if (io->nop_abort_counter < abort_counter) {
135 if (io->scsi_io_cb) {
142 io->scsi_io_cb = NULL;
144 io_trace(io,
"IO completed with status 0x%x (flags 0x%x)\n",
147 cb(io, cb_status, flags, io->scsi_io_cb_arg);
173 ocs_io_t *io = ul_arg;
192 io->scsi_mem_offset += (io->scsi_mem_xfer_size);
193 io->scsi_wire_offset += (io->scsi_wire_xfer_size);
201 if (io->scsi_io_cb) {
222 uint32_t pdu_size = (iscsi->
hal->
sli.
is_skyhawk ? cxn->max_xmit_dsl : 8192);
224 if ((io->scsi_wire_xfer_size % pdu_size) > 0) {
227 io->data_sn += (io->scsi_wire_xfer_size / pdu_size);
239 io->scsi_io_cb = NULL;
250 io_trace(io,
"IO completed with status 0x%x (flags 0x%x)\n",
252 cb(io, cb_status, flags, io->scsi_io_cb_arg);
273 uint32_t *dword = NULL;
277 #if defined(OCS_INCLUDE_DEBUG)
278 ocs_t *ocs = io->ocs;
285 while (sgl_info != NULL &&
286 sgl_count < io->hio->
n_sge) {
288 dword = (uint32_t*)data;
290 io_trace(io,
"SGL %d 0x%08x 0x%08x 0x%08x 0x%08x",
291 sgl_count, dword[0], dword[1], dword[2], dword[3]);
297 if (sgl_info != NULL) {
298 io_trace(io,
"Move to SGL ICD 0x%x", sgl_info->
icd);
323 if (io->hal_cb != NULL) {
356 if (ocs_atomic_add_return(&ocs->io_pending_recursing, 1)) {
358 ocs_atomic_sub_return(&ocs->io_pending_recursing, 1);
382 ocs_atomic_sub_return(&ocs->io_pending_count, 1);
384 if ((io->cmd_tgt == 0) && (io->cmd_ini == 0)) {
385 ocs_log_err(ocs,
"assertion failed: niether io->cmd_tgt nor io->cmd_ini set\n");
388 ocs_atomic_sub_return(&ocs->io_pending_recursing, 1);
397 if (io->hio == NULL) {
410 ocs_log_test(ocs,
"call to ocs_hal_async_call() failed\n");
430 ocs_atomic_sub_return(&ocs->io_pending_recursing, 1);
453 ocs_atomic_add_return(&ocs->io_total_pending, 1);
454 ocs_atomic_add_return(&ocs->io_pending_count, 1);
478 ocs_t *ocs = io->ocs;
479 ocs_cxn_t *cxn = io->
node;
503 if (io->hio != NULL) {
557 ocs_t *ocs = io->ocs;
563 io->hw_tag = hio->
tag;
566 ocs_memcpy(io->hio->bhs.virt, io->bhs, 48);
569 io->iparam.unassisted.bhs = &io->hio->bhs;
582 &io->iparam, io->node, io->hal_cb, io);
600 ocs_t *ocs = node->ocs;
606 if (io->node == node) {
608 ocs_atomic_sub_return(&ocs->io_pending_count, 1);
638 ocs_t *ocs = io->ocs;
639 uint32_t blocksize = 0;
646 ocs_log_err(ocs,
"ocs_hal_io_init_sges failed: %d\n", rc);
674 ocs_log_err(hal->
os,
"Invalid hal_dif blocksize %d\n", hal_dif_temp.
blk_size);
677 for (i = 0; i < sgl_count; i++) {
678 if ((sgl[i].len % blocksize) != 0) {
679 ocs_log_err(hal->
os,
"sgl[%d] len of %ld is not multiple of blocksize\n",
686 for (i = 0; i < sgl_count; i++) {
701 blockcount = sgl[i].
len / blocksize;
712 ocs_log_err(ocs,
"ocs_hal_io_add_sge failed: count=%d rc=%d\n",
718 for (i = 0; i < sgl_count; i++) {
725 ocs_log_err(ocs,
"ocs_hal_io_add_sge failed: count=%d rc=%d\n",
774 ocs_session_t *session;
777 int wire_blocksize = 0;
788 io->sgl_count = sgl_count;
791 if (sgl && (sgl != io->sgl)) {
792 ocs_assert(sgl_count <= io->sgl_allocated, -1);
793 ocs_memcpy(io->sgl, sgl, sgl_count*
sizeof(*io->sgl));
802 session = cxn->session;
804 io_trace(io,
"send wire_len %d\n", wire_len);
816 io->scsi_io_cb_arg = arg;
817 io->scsi_wire_xfer_size = wire_len;
822 if (dif_info == NULL) {
823 io->scsi_mem_xfer_size = wire_len;
853 num_blocks = wire_len / wire_blocksize;
860 io->scsi_mem_xfer_size = num_blocks * blocksize;
865 io->scsi_mem_xfer_size = num_blocks * (blocksize + 8);
879 if ((io->exp_xfer_len - io->scsi_wire_offset) < wire_len) {
880 wire_len = io->exp_xfer_len - io->scsi_wire_offset;
890 hdr->
itt = ocs_htobe32(io->init_task_tag);
891 hdr->
ttt = 0xFFFFFFFF;
892 hdr->
expCmdSN = ocs_htobe32(session->exp_cmd_sn);
893 hdr->
maxCmdSN = ocs_htobe32(session->max_cmd_sn);
896 ocs_memset(&io->iparam, 0,
sizeof(io->iparam));
897 io->iparam.tgt_read.data_sn = io->data_sn;
898 io->iparam.tgt_read.dif_info = (dif_info ? &io->hal_dif : NULL);
904 io->iparam.tgt_read.piggy_back_status = 1;
905 if (wire_len + io->scsi_wire_offset < io->exp_xfer_len) {
906 io->iparam.tgt_read.underrun = 1;
907 hdr->
residualCount = ocs_htobe32(io->exp_xfer_len - (wire_len + io->scsi_wire_offset));
908 io_trace(io,
"set underflow for %d bytes, exp_xfer_len=%d, scsi_wire_offset= %d, wire_=%d\n",
909 io->exp_xfer_len - (wire_len + io->scsi_wire_offset),
911 io->scsi_wire_offset,
913 }
else if (wire_len + io->scsi_wire_offset > io->exp_xfer_len) {
914 io->iparam.tgt_read.overrun = 1;
915 hdr->
residualCount = ocs_htobe32((wire_len + io->scsi_wire_offset) - io->exp_xfer_len);
916 io_trace(io,
"set overflow for %d bytes, exp_xfer_len=%d, scsi_wire_offset=%d, wire_len=%d\n",
917 (wire_len + io->scsi_wire_offset) - io->exp_xfer_len,
919 io->scsi_wire_offset,
927 io->hal_io_size = wire_len;
969 ocs_session_t *session;
982 io->sgl_count = sgl_count;
985 if (sgl && (sgl != io->sgl)) {
986 ocs_assert(sgl_count <= io->sgl_allocated, -1);
987 ocs_memcpy(io->sgl, sgl, sgl_count*
sizeof(*io->sgl));
996 session = cxn->session;
1003 io_trace(io,
"recv wire_len %d\n", wire_len);
1014 io->scsi_io_cb = cb;
1015 io->scsi_io_cb_arg = arg;
1016 io->scsi_mem_xfer_size = io->scsi_wire_xfer_size = wire_len;
1024 if ((io->exp_xfer_len - io->scsi_wire_offset) < wire_len) {
1025 wire_len = io->exp_xfer_len - io->scsi_wire_offset;
1039 hdr->
itt = ocs_htobe32(io->init_task_tag);
1040 hdr->
ExpCmdSN = ocs_htobe32(session->exp_cmd_sn);
1041 hdr->
MaxCmdSN = ocs_htobe32(session->max_cmd_sn);
1042 hdr->
R2TSN = ocs_htobe32(io->r2tsn++);
1046 ocs_memset(&io->iparam, 0,
sizeof(io->iparam));
1048 io->iparam.tgt_write.lun = (((ocs_be32toh(lun->
lun_32[0])) >> 16) & 0x3fff);
1049 io->iparam.tgt_write.exp_data_sn = 0;
1050 io->iparam.tgt_write.itt = io->init_task_tag;
1051 io->iparam.tgt_write.r2t_offset = io->scsi_wire_offset;
1052 io->iparam.tgt_write.dif_info = (dif_info ? &io->hal_dif : NULL);
1054 io->hal_io_size = wire_len;
1086 ocs_session_t *session;
1092 uint8_t scsi_status = 0;
1093 uint32_t sense_data_length = 0;
1094 uint8_t *sense_data = NULL;
1103 iscsi = &ocs->iscsi;
1104 session = cxn->session;
1120 io->scsi_io_cb = cb;
1121 io->scsi_io_cb_arg = arg;
1134 hdr->
status = scsi_status;
1135 hdr->
itt = ocs_htobe32(io->init_task_tag);
1136 hdr->
ExpCmdSN = ocs_htobe32(session->exp_cmd_sn);
1137 hdr->
MaxCmdSN = ocs_htobe32(session->max_cmd_sn);
1140 hdr->
ExpDataSN = ocs_htobe32(io->data_sn);
1142 hdr->
ExpDataSN = ocs_htobe32(io->r2tsn);
1146 if (io->scsi_wire_offset < io->exp_xfer_len) {
1148 hdr->
ResidualCnt = ocs_htobe32(io->exp_xfer_len - io->scsi_wire_offset);
1149 io_trace(io,
"set underflow for %d bytes, exp_xfer_len=%d, len=%d\n",
1150 io->exp_xfer_len - io->scsi_wire_offset, io->exp_xfer_len, io->scsi_wire_offset);
1151 }
else if (io->scsi_wire_offset > io->exp_xfer_len) {
1153 hdr->
ResidualCnt = ocs_htobe32(io->scsi_wire_offset - io->exp_xfer_len);
1154 io_trace(io,
"set overflow for %d bytes, exp_xfer_len=%d, len=%d\n",
1155 io->scsi_wire_offset - io->exp_xfer_len, io->exp_xfer_len, io->scsi_wire_offset);
1159 ocs_memset(&io->iparam, 0,
sizeof(io->iparam));
1160 io->iparam.tgt_rsp.payload1 = NULL;
1161 io->iparam.tgt_rsp.payload2 = NULL;
1164 dsl = sense_data_length + 2;
1169 if (io->sensebuf.virt == NULL) {
1170 ocs_log_err(ocs,
"NULL response buffer\n");
1173 io->iparam.tgt_rsp.payload1 = &io->sensebuf;
1175 rsp_bytes = (uint8_t*)io->sensebuf.virt;
1176 rsp_bytes[0] = (sense_data_length >> 8) & 0xff;
1177 rsp_bytes[1] = sense_data_length & 0xff;
1178 ocs_memcpy(&rsp_bytes[2], sense_data, dsl - 2);
1182 io->hal_io_size = dsl;
1203 ocs_t *ocs = io->ocs;
1206 io->scsi_io_cb = cb;
1207 io->scsi_io_cb_arg = arg;
1217 ocs_atomic_sub_return(&ocs->io_pending_count, 1);
1226 }
else if (io->hio == NULL) {
1236 ocs_log_debug(ocs,
"abort ICD %d\n", io->hio->icd);
1271 uint8_t *addl_rsp_info,
1323 ocs_cxn_t *cxn = io->node;
1324 ocs_session_t *session = cxn->session;
1326 #if defined(OCS_INCLUDE_DEBUG)
1327 ocs_t *ocs = io->ocs;
1337 io->scsi_io_cb = cb;
1338 io->scsi_io_cb_arg = arg;
1350 hdr->
itt = ocs_htobe32(io->init_task_tag);
1351 hdr->
ExpCmdSN = ocs_htobe32(session->exp_cmd_sn);
1352 hdr->
MaxCmdSN = ocs_htobe32(session->max_cmd_sn);
1356 ocs_memset(&io->iparam, 0,
sizeof(io->iparam));
1357 io->iparam.unassisted.set_dm = TRUE;
1358 io->iparam.unassisted.is_login = FALSE;
1359 io->iparam.unassisted.incr_statsn = TRUE;
1360 io->iparam.unassisted.bhs = NULL;
1361 io->iparam.unassisted.payload1 = NULL;
1362 io->iparam.unassisted.payload2 = NULL;
1366 io->hal_io_size = 0;
1386 ocs_io_t *io = ul_arg;
1388 ocs_session_t *session = cxn->session;
1397 iscsi = &ocs->iscsi;
1405 if (ini_fields != NULL &&
1409 session->exp_cmd_sn = ini_fields->
exp_cmdsn;
1410 session->cmd_window = ini_fields->
cmd_window;
1421 cxn->idle_count = 0;
1424 if (io->scsi_io_cb) {
1450 io->scsi_io_cb = NULL;
1452 io_trace(io,
"IO completed with status 0x%x (flags 0x%x)\n",
1455 cb(io, cb_status, &rsp, flags, io->scsi_io_cb_arg);
1485 ocs_io_t *io = ul_arg;
1491 iscsi = &ocs->iscsi;
1523 uint64_t iscsi_lun = 0;
1524 uint8_t *iscsi_lun_byte = (uint8_t*)&iscsi_lun;
1529 iscsi_lun_byte[1] = lun & 0xff;
1536 iscsi_lun_byte[1] = lun & 0xff;
1538 ocs_log_test(ocs,
"unsupported LU %08X\n", lun);
1539 iscsi_lun = 0xFFFFFFFFFFFFFFFF;
1563 uint32_t lun,
void *cdb, uint32_t cdb_len,
1570 ocs_session_t *session = node->session;
1571 ocs_t *ocs = iscsi->
os;
1579 ocs_log_test(ocs,
"cxn not ready, state is %d\n", node->cxn_state);
1588 ocs_log_test(ocs,
"CDB len %d is not supported\n", cdb_len);
1596 if (!
GT_NOTWRAPPED(session->exp_cmd_sn + session->cmd_window,
1598 ocs_log_test(ocs,
"iSCSI cmd window closed, exp_cmd_sn 0x%x, window 0x%x, cmd_sn 0x%x\n",
1599 session->exp_cmd_sn, session->cmd_window, session->cmd_sn);
1603 io->sgl_count = sgl_count;
1606 if (sgl != io->sgl) {
1607 ocs_assert(sgl_count <= io->sgl_allocated, -1);
1608 ocs_memcpy(io->sgl, sgl,
sizeof(*io->sgl) * sgl_count);
1618 io->ocs = iscsi->
os;
1620 io->init_task_tag = 0;
1621 io->exp_xfer_len = wire_len;
1622 io->io_type = io_type;
1623 io->scsi_io_cb = cb;
1624 io->scsi_io_cb_arg = arg;
1625 io->scsi_mem_xfer_size = io->scsi_wire_xfer_size = wire_len;
1627 io->cmd_sn = session->cmd_sn++;
1641 hdr->
CmdSN = ocs_htobe32(io->cmd_sn);
1642 ocs_memcpy(hdr->
cdb, cdb, (cdb_len < 16 ? cdb_len : 16));
1644 ocs_memset(&io->iparam, 0,
sizeof(io->iparam));
1645 io->iparam.ini_io.lun = (((ocs_be32toh(iscsi_lun->
lun_32[0])) >> 16) & 0x3fff);
1646 io->iparam.ini_io.cmdsn = io->cmd_sn;
1647 io->iparam.ini_io.dif_info = (dif_info ? &io->hal_dif : NULL);
1649 io_trace(io,
"start INI Io, CmdSn=%d, instance=0x%x, size=0x%x, DIF=%s, oper=%s\n",
1650 io->cmd_sn, io->instance_index, wire_len,
1651 (io->iparam.ini_io.dif_info == NULL ?
"Non-DIF" :
"DIF"),
1652 (io->is_read ?
"READ" :
"WRITE"));
1654 io->hal_io_size = wire_len;
1659 node->idle_count = 0;
1700 lun, cdb, cdb_len, dif_info, sgl, sgl_count,
1729 lun, cdb, cdb_len, NULL, NULL, 0,0,
1767 lun, cdb, cdb_len, dif_info, sgl, sgl_count,
1773 ocs_scsi_sgl_t *sgl, uint32_t sgl_count, uint32_t wire_len, uint32_t first_burst,
1776 ocs_log_test(node->ocs,
"First burst not implemented\n");
1799 ocs_session_t *session = node->session;
1800 ocs_t *ocs = iscsi->
os;
1815 io->init_task_tag = 0;
1816 io->exp_xfer_len = 0;
1820 io->scsi_io_cb = cb;
1821 io->scsi_io_cb_arg = arg;
1822 io->scsi_mem_xfer_size = 0;
1823 io->scsi_wire_xfer_size = 0;
1825 io->cmd_sn = session->cmd_sn;
1853 hdr->
ref_task_tag = (ref_io->hio == NULL ? ref_io->init_task_tag : ref_io->hio->itt);
1857 ocs_log_test(ocs,
"unsupported TMF %d\n", tmf);
1862 hdr->
cmd_sn = ocs_htobe32(io->cmd_sn);
1864 ocs_memset(&io->iparam, 0,
sizeof(io->iparam));
1865 io->iparam.ini_tmf.lun = (((ocs_be32toh(iscsi_lun->
lun_32[0])) >> 16) & 0x3fff);
1866 io->iparam.ini_tmf.cmdsn = io->cmd_sn;
1868 io_trace(io,
"start INI TMF (CmdSn %d)\n", io->cmd_sn);
1874 io->hal_io_size = 0;
1879 node->idle_count = 0;
1912 uint32_t sgl_count, uint32_t len,
1936 if (scsi_dif_info == NULL) {
1959 ocs_log_test(ocs,
"unhandled SCSI DIF operation %d\n",
1984 ocs_log_test(ocs,
"unhandled SCSI DIF block size %d\n",
2028 ocs_log_test(io->ocs,
"Got completion for non-busy io with tag 0x%x\n", io->tag);
2050 uint32_t sgl_chain_capable;
2054 uint32_t dif_capable;
2059 return (max_sge < ocs->max_sge_size ? max_sge : ocs->max_sge_size);
2065 if (ocs->enable_sgl_chaining &&
2068 &sgl_chain_capable))) {
2070 if (sgl_chain_capable) {
2102 ocs_log_test(ocs,
"invalid property request %d\n", prop);
2138 ocs_strlen(rc) == 0) {
2140 rc = ocs->sport[0].mac_str;
2164 ocs_log_test(ocs,
"invalid property request %d\n", prop);
2197 iscsi = node->iscsi;
2201 ocs_atomic_add_return(&ocs->io_alloc_failed_count, 1);
2210 io->scsi_mem_xfer_size = 0;
2211 io->scsi_wire_xfer_size = 0;
2212 io->scsi_mem_offset = 0;
2213 io->scsi_wire_offset = 0;
2215 io->init_task_tag = 0;
2216 io->exp_xfer_len = 0;
2221 io->on_abort_list = 0;
2225 ocs_ref_init(&io->ref, NULL, NULL);
2231 io->cmd_tgt = FALSE;
2234 io->cmd_ini = FALSE;
2244 ocs_atomic_add_return(&ocs->io_active_count, 1);
2245 ocs_atomic_add_return(&ocs->io_total_alloc, 1);
2247 io_trace(io,
"allocating io 0x%p %s\n", io, io->display_name);
2267 ocs_t *ocs = io->ocs;
2268 ocs_node_t *node = io->node;
2271 io_trace(io,
"freeing io 0x%p %s\n", io, io->display_name);
2277 if (io->on_abort_list) {
2284 ocs_atomic_sub_return(&ocs->io_active_count, 1);
2285 ocs_atomic_sub_return(&ocs->io_total_free, 1);
2315 io->scsi_mem_offset = transferred;
2316 io->scsi_wire_offset = transferred;
2332 uint32_t d_id, uint32_t ox_id))
2338 ocs_log_test(ocs,
"ocs_hal_callback(OCS_HAL_CB_BOUNCE) failed: %d\n", rc);
2352 ocs_log_test(hal->
os,
"received rc %d aborting IOs\n", rc);
2354 uint32_t inters = 10;
2358 ocs_delay_usec(10000);
2386 #if !defined(OCS_EXPORT)
2387 #define OCS_EXPORT(...)
Defines the iSCSI response PDU header.
Defines the iSCSI command PDU header.
#define ISCSI_RESP_DATAIN
uint32_t disable_app_ffff
SGL information structure.
uint32_t ocs_hal_cxn_get_free_wq_cnt(ocs_hal_t *hal, ocs_cxn_t *cxn)
Returns the number of free entries on the work queue for this connection.
static int32_t ocs_io_busy(ocs_io_t *io)
Test if IO object is busy.
static int32_t ocs_list_on_list(ocs_list_link_t *link)
Test if object is on a list.
#define OCS_ISCSI_LOGIN_MAX_BURST_LEN
uint32_t ExpectedDataTransferLength
uint8_t data_segment_length[3]
void ocs_scsi_pending_cleanup(ocs_node_t *node)
Clean up any IOs on the pending list when a connection goes down.
int32_t ocs_scsi_recv_wr_data(ocs_io_t *io, uint32_t flags, ocs_scsi_dif_info_t *dif_info, ocs_scsi_sgl_t *sgl, uint32_t sgl_count, uint64_t wire_len, ocs_scsi_io_cb_t cb, void *arg)
Prepare to receive write data.
static void ocs_target_nop_check(ocs_cxn_t *cxn)
This function sends a target nop.
#define ISCSI_LUN_ADDRESS_METHOD_MASK
static int32_t ocs_scsi_check_pending_async_cb(ocs_hal_t *hal, int32_t status, void *arg)
Check pending error asynchronous callback function/.
static int32_t ocs_list_empty(ocs_list_t *list)
Test if a list is empty.
#define ISCSI_LUN_ADDRESS_METHOD_SHIFT
T10 DIF information passed to the transport.
T10 DIF information passed to the transport.
static int32_t ocs_scsi_send_tmf_internal(ocs_node_t *node, ocs_io_t *io, ocs_io_t *ref_io, uint32_t lun, ocs_scsi_tmf_cmd_e tmf, ocs_scsi_rsp_io_cb_t cb, void *arg)
Sends a task management command on an initiator (internal).
static void ocs_log_sgl(ocs_io_t *io)
This function logs the SGLs for an IO.
#define ISCSI_LUN_ADDR_FLAT_MAX
static void * ocs_list_get_head(ocs_list_t *list)
Return the first item in the list.
uint32_t sense_data_length
static int32_t ocs_scsi_check_pending(ocs_t *ocs)
Check for pending IOs to dispatch.
ocs_hal_rtn_e ocs_hal_io_add_seed_sge(ocs_hal_t *hal, ocs_hal_io_t *io, ocs_hal_dif_info_t *dif_info)
Add a T10 PI seed scatter gather list entry.
ocs_hal_rtn_e
defines common HAL return statuses.
ocs_hal_rtn_e ocs_hal_io_init_sges(ocs_hal_t *hal, ocs_hal_io_t *io, ocs_hal_io_type_e type, uint32_t offset)
Initialize the Scatter Gather List entries of an IO.
Defines the iSCSI task management PDU header.
ocs_hal_abort_type_e
HAL abort types.
#define GT_NOTWRAPPED(a, b)
uint32_t desiredDataTransferLength
static void ocs_device_lock(ocs_t *ocs)
bool ocs_scsi_check_cxn_wq_full(ocs_t *ocs, ocs_cxn_t *cxn)
Check Connection WQ's full status.
#define OCS_SCSI_DIF_OPER_PASS_THRU
ocs_hal_rtn_e ocs_hal_io_add_sge(ocs_hal_t *hal, ocs_hal_io_t *io, uintptr_t addr, uint32_t length)
Add a Scatter Gather list Entry to an IO.
static int32_t ocs_initiator_io_cb(struct ocs_hal_io_s *hio, ocs_cxn_t *cxn, int32_t status, ocs_ini_cmpl_fields_t *ini_fields, void *ul_arg)
This function is the callback for a initiator IO.
generic scatter-gather list structure
int32_t ocs_scsi_io_dispatch(ocs_io_t *io, void *cb)
Attempt to dispatch an IO.
ocs_hal_rtn_e ocs_hal_callback(ocs_hal_t *hal, ocs_hal_callback_e which, void *func, void *arg)
register a callback for the given event.
static uint8_t * ocs_find_vpd(uint8_t *vpddata, uint32_t vpddata_length, const char *key)
find a VPD entry
int32_t(* ocs_scsi_rsp_io_cb_t)(ocs_io_t *io, ocs_scsi_io_status_e status, ocs_scsi_cmd_resp_t *rsp, uint32_t flags, void *arg)
void ocs_scsi_io_free(ocs_io_t *io)
Free a SCSI IO context.
int32_t ocs_scsi_send_rd_io(ocs_node_t *node, ocs_io_t *io, uint32_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)
Initiate initiator read IO.
static void * ocs_list_remove(ocs_list_t *list, void *item)
Remove an item from the list.
#define ISCSI_TASK_MGMT_FUNCTION_REJECTED
#define ISCSI_TASK_MGMT_TASK_DOES_NOT_EXIST
int32_t ocs_scsi_send_rd_data(ocs_io_t *io, uint32_t flags, ocs_scsi_dif_info_t *dif_info, ocs_scsi_sgl_t *sgl, uint32_t sgl_count, uint64_t wire_len, ocs_scsi_io_cb_t cb, void *arg)
Send read data.
ocs_hal_io_t * ocs_hal_io_alloc(ocs_hal_t *hal)
Allocate a HAL IO object.
ocs_hal_io_type_e
enum identifying IO types.
#define ISCSI_TASK_MGMT_LUN_DOES_NOT_EXIST
#define ISCSI_RESPONSE_CMD_COMPLETED
static int32_t ocs_target_io_cb(struct ocs_hal_io_s *hio, ocs_cxn_t *cxn, int32_t status, ocs_ini_cmpl_fields_t *ini_fields, void *ul_arg)
This function is the callback for a target IO.
uint32_t ocs_io_pool_allocated(ocs_io_pool_t *io_pool)
#define ISCSI_CLEAR_TASK_SET
#define OCS_SCSI_IO_CMPL_RSP_SENT
ocs_hal_rtn_e ocs_hal_io_abort(ocs_hal_t *hal, ocs_hal_io_t *io, ocs_hal_abort_scope_e abort_scope, ocs_hal_abort_type_e abort_type)
Abort a currently running IO.
void ocs_scsi_update_first_burst_transferred(ocs_io_t *io, uint32_t transferred)
Update transferred count.
ocs_scsi_dif_blk_size_e blk_size
void ocs_scsi_register_bounce(ocs_t *ocs, void(*fctn)(void(*fctn)(void *arg), void *arg, uint32_t s_id, uint32_t d_id, uint32_t ox_id))
Register bounce callback for multi-threading.
#define ocs_list_foreach_safe(list, item, nxt)
Iterate a linked list safely.
int ocs_scsi_abort_io(ocs_hal_t *hal, ocs_hal_io_t *hio, ocs_hal_abort_type_e abort_type)
ocs_hal_rtn_e ocs_hal_io_send(ocs_hal_t *hal, ocs_hal_io_type_e type, ocs_hal_io_t *io, uint32_t len, ocs_hal_io_param_t *iparam, ocs_cxn_t *cxn, io_cb_t cb, void *arg)
Send a read, write, or response IO.
static void ocs_device_unlock(ocs_t *ocs)
void ocs_target_io_aborted_nop_cmpl(ocs_cxn_t *cxn)
This function is called whenever a target NOP completes.
Defines the iSCSI task management response PDU header.
#define OCS_SCSI_LAST_DATAPHASE
static void ocs_target_io_aborted(ocs_io_t *io, ocs_cxn_t *cxn)
This function is called when an IO is aborted.
ocs_hal_rtn_e ocs_hal_io_add_dif_sge(ocs_hal_t *hal, ocs_hal_io_t *io, uintptr_t addr)
Add a T10 DIF scatter gather list entry to an IO.
ocs_hal_rtn_e ocs_hal_get(ocs_hal_t *hal, ocs_hal_property_e prop, uint32_t *value)
#define CONN_STATE_LOGOUT_REQUESTED
uint32_t disable_app_ffff
Defines the iSCSI data-in PDU header.
#define OCS_SCSI_SNS_BUF_VALID(sense)
#define io_trace(io, fmt,...)
uint32_t disable_app_ref_ffff
static void ocs_scsi_io_add_to_pending(ocs_t *ocs, ocs_io_t *io, uint8_t lock_held)
Place an IO on the pending list to retry later when resources are available.
#define OCS_DEBUG_ENABLE_IO_TRACE
int32_t ocs_iscsi_send_nop_in(ocs_cxn_t *cxn, uint64_t lun, uint32_t itt, uint32_t ttt, char *data_ptr, uint32_t data_len)
Send NOP-In from a target.
int32_t(* ocs_scsi_io_cb_t)(ocs_io_t *io, ocs_scsi_io_status_e status, uint32_t flags, void *arg)
int32_t ocs_scsi_send_wr_io_first_burst(ocs_node_t *node, ocs_io_t *io, uint32_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)
Defines a union to decode the SCSI LUN field in various ways.
#define ISCSI_TASK_MGMT_FUNCTION_COMPLETE
static int32_t ocs_initiator_io_tm_cb(struct ocs_hal_io_s *hio, ocs_cxn_t *cxn, int32_t status, ocs_ini_cmpl_fields_t *ini_fields, void *ul_arg)
This function is the callback for a initiator TM IO.
int32_t ocs_scsi_send_nodata_io(ocs_node_t *node, ocs_io_t *io, uint32_t lun, void *cdb, uint32_t cdb_len, ocs_scsi_rsp_io_cb_t cb, void *arg)
Initiate initiator SCSI command with no data.
int ocs_sm_post_event(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *data)
Post an event to a context.
ocs_list_t login_retry_busy
static void ocs_list_add_tail(ocs_list_t *list, void *item)
Add an item to the tail of the list.
void ocs_hal_io_free(ocs_hal_t *hal, ocs_hal_io_t *io)
Free a previously allocated HAL IO object.
ocs_scsi_property_e
property names for ocs_scsi_get_property() functions
Defines the iSCSI R2T PDU header.
uint32_t auto_incr_ref_tag
ocs_hal_dif_oper_e dif_oper
static void ocs_node_lock(ocs_node_t *node)
void ocs_iscsi_login_retry(ocs_cxn_t *cxn)
Attempt to start a request on the retry queue.
int32_t ocs_scsi_send_tmf(ocs_node_t *node, ocs_io_t *io, ocs_io_t *io_to_abort, uint32_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)
initiate initiator task management operation
defines a structure to contain the fields specific to an initiator IO completion. ...
int32_t ocs_scsi_dif_wire_blocksize(ocs_scsi_dif_info_t *dif_info, int wiretomem)
Return wire block size given SCSI DIF API.
static void * ocs_list_next(ocs_list_t *list, void *item)
Get the next item on the list.
#define SLI4_SGE_MAX_RESERVED
int32_t ocs_scsi_tgt_abort_io(ocs_io_t *io, bool send_abts, ocs_scsi_io_cb_t cb, void *arg)
Abort a target IO.
#define ISCSI_LUN_ADDR_SIMPLE_MAX
static void ocs_node_unlock(ocs_node_t *node)
#define OCS_SCSI_DIF_OPER_INSERT
static int32_t ocs_scsi_build_sgls(ocs_hal_t *hal, ocs_io_t *io, ocs_hal_dif_info_t *hal_dif, ocs_scsi_sgl_t *sgl, uint32_t sgl_count, ocs_hal_io_type_e type)
Build the SGLs for the IO.
int32_t ocs_scsi_send_resp(ocs_io_t *io, uint32_t flags, ocs_scsi_cmd_resp_t *rsp, ocs_scsi_io_cb_t cb, void *arg)
Send response data.
int ocs_debug_is_enabled(uint32_t mask)
return true if debug bits are enabled
#define OCS_DEFAULT_SGL_COUNT
int32_t ocs_hal_async_call(ocs_hal_t *hal, ocs_hal_async_cb_t callback, void *arg)
Make an async callback using NOP mailbox command.
#define ocs_assert(cond,...)
static uint64_t ocs_scsi_convert_lun(ocs_t *ocs, uint32_t lun)
Sends an initiator command to the chip.
int32_t io_cb_t(struct ocs_hal_io_s *io, ocs_cxn_t *cxn, int32_t status, ocs_ini_cmpl_fields_t *ini_fields, void *ul_arg)
IO Completion function prototype.
Scatter-Gather Entry (SGE)
static int32_t ocs_scsi_io_dispatch_hal_io(ocs_io_t *io, ocs_hal_io_t *hio, uint8_t lock_held)
Dispatch IO.
#define CONN_STATE_FULL_FEATURE
static void ocs_io_free(ocs_t *ocs, ocs_io_t *io)
#define ISCSI_LUN_ADDR_METHOD_FLAT
int32_t ocs_scsi_send_wr_io(ocs_node_t *node, ocs_io_t *io, uint32_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)
Initiate initiator write IO.
void * ocs_hal_get_ptr(ocs_hal_t *hal, ocs_hal_property_e prop)
static int32_t ocs_scsi_convert_dif_info(ocs_t *ocs, ocs_scsi_dif_info_t *scsi_dif_info, ocs_hal_dif_info_t *hal_dif_info)
Convert SCSI API T10 DIF information into the FC HAL format.
ocs_io_t * ocs_scsi_io_alloc(ocs_node_t *node, ocs_scsi_io_role_e role)
allocate a SCSI IO context.
ocs_hal_dif_blk_size_e blk_size
int32_t ocs_scsi_send_tmf_resp(ocs_io_t *io, ocs_scsi_tmf_resp_e rspcode, uint8_t addl_rsp_info[3], ocs_scsi_io_cb_t cb, void *arg)
void * ocs_scsi_get_property_ptr(ocs_t *ocs, ocs_scsi_property_e prop)
return a property pointer.
uint32_t disable_app_ref_ffff
ocs_scsi_dif_oper_e dif_oper
static ocs_io_t * ocs_io_alloc(ocs_t *ocs)
int32_t ocs_iscsi_send_tmf_resp(ocs_io_t *io, uint8_t response, ocs_scsi_io_cb_t cb, void *arg)
send TMF response data
uint32_t ocs_scsi_get_property(ocs_t *ocs, ocs_scsi_property_e prop)
Return SCSI API integer valued property.
void ocs_scsi_io_complete(ocs_io_t *io)
Notify base that IO is complete.
#define OCS_SCSI_DIF_OPER_STRIP
#define CONN_STATE_CLEANUP
static int32_t ocs_scsi_send_ini_io(ocs_node_t *node, ocs_io_t *io, ocs_hal_io_type_e io_type, uint32_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)
Sends an initiator command to the chip.