72 #define INVALID_APP_TAG 0xffffffff
73 #define RAMD_APP_TAG 0x0
75 #define IOFMT "[%04x][i:%0*x t:%0*x h:%04x][c:%02x]"
76 #define IOFMT_ITT_SIZE(ocs) ((ocs->ocs_xport == OCS_XPORT_FC) ? 4 : 8)
77 #define IOFMT_ARGS(io) io->instance_index, IOFMT_ITT_SIZE(io->ocs), io->init_task_tag, IOFMT_ITT_SIZE(io->ocs), io->tgt_task_tag, io->hw_tag, io->tgt_io.cdb[0]
79 #define io_sm_trace() \
81 if (OCS_LOG_ENABLE_SCSI_TGT_TRACE(io->node->ocs)) \
82 ocs_log_info(io->ocs, "[%s]" IOFMT " (IO) %-20s %-20s\n", \
83 (io->node ? io->node->display_name : ""), \
84 IOFMT_ARGS(io), __func__, ocs_sm_event_name(evt)); \
87 #define tmfio_sm_trace() \
89 if (OCS_LOG_ENABLE_SCSI_TGT_TRACE(tmfio->ocs)) \
90 ocs_log_info(tmfio->ocs, "[%s]" IOFMT " (TMF) %-20s %-20s\n", \
91 (tmfio->node ? tmfio->node->display_name : ""), \
92 IOFMT_ARGS(tmfio), __func__, ocs_sm_event_name(evt)); \
95 #define io_printf(io, fmt, ...) \
97 ocs_log_debug(io->ocs, "[%s]" IOFMT " %-20s " fmt, \
98 (io->node ? io->node->display_name : ""), \
99 IOFMT_ARGS(io), __func__, ##__VA_ARGS__); \
102 #define OCS_RAMD_MIN_SIZE (1024*1024)
104 #define ENABLE_CMD_TRACE 0
105 #define ENABLE_API_TRACE 0
106 #define ENABLE_BUFFER_DUMP 0
108 #define trace(io, enable_flag, fmt, ...) \
112 ocs_log_debug(NULL, "[%s]" IOFMT " %s: " fmt, io->node->display_name, \
113 IOFMT_ARGS(io), __func__, ##__VA_ARGS__); \
115 ocs_log_debug(NULL, "%s: " fmt, __func__, ##__VA_ARGS__); \
120 #define cmd_trace(io, fmt, ...) trace(io, ENABLE_CMD_TRACE, fmt, ##__VA_ARGS__)
122 #define api_trace(...) \
124 if (ENABLE_API_TRACE) \
125 ocs_log_debug(NULL, "%s:\n", __func__); \
129 #define container_of(p, stype, field) ((stype *)(((uint8_t *)(p)) - offsetof(stype, field)))
132 #if defined(OCS_INCLUDE_ISCSI)
133 #define ACTIVE_IO_COUNT(ocs) ocs_atomic_read(&ocs->io_active_count)
135 #define ACTIVE_IO_COUNT(ocs) ocs_atomic_read(&ocs->xport->io_active_count)
156 "__ocs_ramd_io_init",
157 "__ocs_ramd_io_init_err_injection",
158 "__ocs_ramd_io_wait_first_burst",
159 "__ocs_ramd_io_wait_dataphase_compl",
160 "__ocs_ramd_io_wait_and_validate_dataphase",
161 "__ocs_ramd_io_wait_and_complete_writesame_dataphase",
162 "__ocs_ramd_io_wait_resp_compl",
163 "__ocs_ramd_io_aborting",
164 "__ocs_ramd_io_aborting_wait_io_cmpl",
165 "__ocs_ramd_io_aborting_wait_abort_cmpl",
166 "__ocs_ramd_tmf_wait_resp_cmpl",
167 "__ocs_ramd_abts_wait_io_abort_resp",
168 "__ocs_ramd_wait_abts_acc_cmpl",
169 "__ocs_ramd_io_wait_first_burst_send_resp"
228 uint32_t app_tag, uint32_t ref_tag);
230 uint32_t app_tag, uint32_t ref_tag);
232 uint8_t wrprotect, uint8_t pbdata, uint8_t lbdata,
233 uint32_t app_tag, uint32_t ref_tag);
235 uint8_t cor_dis, uint8_t wr_uncor, uint8_t pblock);
237 uint8_t pblock, uint8_t corrct);
240 static int32_t
ocs_mgmt_read_block(ocs_t *ocs,
char *,
void *, uint32_t,
void *, uint32_t);
252 #define DATA_DIR_NONE 0x00
253 #define DATA_DIR_READ 0x01
254 #define DATA_DIR_WRITE 0x02
255 #define DATA_DIR_RDWR 0x03
312 int ocs_mgmt_ramd_exec(
char *parent,
char *action,
void *arg_in, uint32_t arg_in_length,
313 void *arg_out, uint32_t arg_out_length,
void *
object);
334 ocs_io_t *io, ocs_io_t *tmfio)
358 uint32_t ramd_threading = 0;
362 ocs_lock_init(NULL, &
ramd_lock,
"RAM disc alloc lock");
365 ocs_memset(scsi_cmd_lookup, 0,
sizeof(scsi_cmd_lookup));
366 for (i = 0, pcmd = scsi_cmd_table; i < ARRAY_SIZE(scsi_cmd_table); i++, pcmd++) {
367 scsi_cmd_lookup[pcmd->
scsi_cmd] = pcmd;
371 ramd_threading = ocs_strtoul(buf, 0, 0);
372 ocs_log_debug(NULL,
"ramd_threading: %d\n", ramd_threading);
376 thread_cmds = ocs_strtoul(buf, 0, 0);
377 ocs_log_debug(NULL,
"thread_cmds: %d\n", thread_cmds);
380 if (thread_cmds && !ramd_threading) {
381 ocs_log_test(NULL,
"Can't thread_cmds without enabling ramd_threading\n");
435 ocs_lock_init(io->ocs, &io->tgt_io.sm_lock,
"iosmlock:%p", io);
452 ocs_lock_free(&io->tgt_io.sm_lock);
473 ocs_t *ocs = io->ocs;
476 if (ocs->tgt_ocs.use_global_ramd) {
477 if (lun < ocs->tgt_ocs.rdisc_count) {
478 rval = ocs->tgt_ocs.rdisc[lun];
481 ocs_node_t *node = io->node;
484 ocs_sport_t *sport = node->sport;
487 if (lun < sport->tgt_sport.rdisc_count) {
488 rval = sport->tgt_sport.rdisc[lun];
523 if (ocs->tgt_ocs.use_global_ramd) {
525 if (lun < ocs->tgt_ocs.rdisc_count) {
526 rval = ocs->tgt_ocs.rdisc[lun];
531 if (domain != NULL) {
534 if (lun < sport->tgt_sport.rdisc_count) {
535 rval = sport->tgt_sport.rdisc[lun];
556 uint32_t num_luns = 1;
557 uint32_t ramdisc_blocksize = 512;
558 uint64_t ramdisc_size = 50*1024*1024;
559 uint64_t ramdisc_blockcount = 0;
560 uint32_t max_sge_size;
565 uint8_t dif_separate = 0;
566 uint8_t external_dif = 0;
567 char t10_vendor_id[8] = { 0 };
568 uint32_t dif_capable;
575 ramdisc_size = ocs_strtoul(prop_buf, &p, 0);
578 ramdisc_size *= 1024;
581 ramdisc_size *= 1024;
584 ramdisc_size *= 1024;
588 ocs_log_warn(ocs,
"Ramdisc size %s (%" PRIu64
") too small. Min size %u.\n",
593 if (
ocs_get_property(
"ramdisc_blocksize", prop_buf,
sizeof(prop_buf)) == 0) {
594 ramdisc_blocksize = ocs_strtoul(prop_buf, 0, 0);
597 num_luns = ocs_strtoul(prop_buf, 0, 0);
600 p_type = ocs_strtoul(prop_buf, 0, 0);
606 ocs_log_warn(ocs,
"WARNING: RAMD: Cannot initialize with DIF, port is not DIF capable\n");
617 external_dif = ocs_strlen(prop_buf) > 0;
619 if (ocs_strlen(prop_buf) >
sizeof(t10_vendor_id)) {
620 ocs_log_err(ocs,
"External dif vendor ID size exceeded the MAX size. Max size is : %lu\n",
621 sizeof(t10_vendor_id));
624 ocs_strncpy(t10_vendor_id, prop_buf,
sizeof(t10_vendor_id));
631 ocs_log_err(ocs,
"Device does not support DIF, ignoring user's external dif request.\n");
636 dif_separate = ocs_strtoul(prop_buf, 0, 0);
639 ramdisc_blockcount = ramdisc_size / ramdisc_blocksize;
640 ocs_log_debug(ocs,
"Ramdisc: num_luns:%d blocksize:%d blockcount:%" PRIu64
" (%" PRIu64
" mb)\n",
641 num_luns, ramdisc_blocksize, ramdisc_blockcount, (ramdisc_blocksize*ramdisc_blockcount) / (1024*1024));
643 *rdisc = ocs_malloc(ocs,
sizeof(
ocs_ramdisc_t*) * num_luns, OCS_M_NOWAIT | OCS_M_ZERO);
645 *rdisc_count = num_luns;
647 max_sge_size = ocs->tgt_ocs.max_sge;
648 if (max_sge_size > OCS_MAX_DMA_ALLOC)
649 max_sge_size = OCS_MAX_DMA_ALLOC;
651 for (i = 0; i < num_luns; i ++) {
658 ocs_thread_yield(NULL);
662 if ((*rdisc)[i] == NULL) {
663 ocs_log_err(ocs,
"Error: ocs_malloc rdisc[%d] failed\n", i);
674 max_sge_size/ramdisc_blocksize, ramdisc_size / ramdisc_blocksize);
676 ocs_log_err(ocs,
"Error: ocs_new_ramdisc failed allocating LUN %d\n", i);
688 (*rdisc)[i]->lun = i;
696 ocs_log_debug(ocs,
"Ramdisc: Enabling DIF separate\n");
697 (*rdisc)[i]->force_dif_separate = TRUE;
701 ocs_log_debug(ocs,
"Ramdisc: Enabling proprietary end-to-end protection\n");
702 (*rdisc)[i]->external_dif = TRUE;
703 ocs_strncpy((*rdisc)[i]->t10_vendor_id, t10_vendor_id,
sizeof((*rdisc)[i]->t10_vendor_id));
706 ocs_format_ramdisc(ocs, (*rdisc)[i], ramdisc_blocksize, p_type, prot_en, dif_separate);
723 if (*rdisc == NULL) {
727 ocs_log_debug(ocs,
"freeing ramd, count=%d\n", *rdisc_count);
728 for (i = 0; i < *rdisc_count; i ++) {
729 if ((*rdisc)[i] != NULL) {
734 ocs_free(ocs, *rdisc,
sizeof(
ocs_ramdisc_t*) * (*rdisc_count));
768 ocs_log_debug(ocs,
"total_ios=%d\n", total_ios);
771 ocs_atomic_init(&ocs->tgt_ocs.io_high_watermark, ocs->tgt_ocs.watermark_max);
772 ocs_atomic_init(&ocs->tgt_ocs.watermark_hit, 0);
773 ocs_atomic_init(&ocs->tgt_ocs.initiator_count, 0);
776 ocs->tgt_ocs.use_global_ramd = TRUE;
778 ocs->tgt_ocs.use_global_ramd = ocs_strtoul(prop_buf, NULL, 0);
781 #if defined(OCS_INCLUDE_FC)
785 if (ocs->tgt_ocs.use_global_ramd) {
792 ocs_log_debug(ocs,
"initialized subsequent RAM disk\n");
802 ocs_log_debug(ocs,
"initialized first RAM disk count=%d\n", ocs->tgt_ocs.rdisc_count);
803 ocs_ramd = ocs->tgt_ocs.rdisc;
813 ocs_log_debug(ocs,
"Ramdisc: task set full processing is %s\n",
814 ocs->tgt_ocs.enable_task_set_full ?
"enabled" :
"disabled");
842 if (ocs->tgt_ocs.use_global_ramd && ocs->tgt_ocs.rdisc) {
847 ocs_log_debug(ocs,
"decremented ramd ref count %d\n",
855 }
else if (!ocs->tgt_ocs.use_global_ramd) {
926 ocs_t *ocs = sport->ocs;
929 ocs_log_debug(ocs,
"targ: New SPORT: %s\n", sport->display_name);
932 if (!ocs->tgt_ocs.use_global_ramd) {
938 &sport->tgt_sport.rdisc_count);
943 ocs_log_debug(ocs,
"initialized sport RAM disk count=%d\n",
944 sport->tgt_sport.rdisc_count);
948 sport->tgt_sport.rdisc_count);
950 ocs_log_test(ocs,
"ocs_port_rdisc_save failed\n");
976 ocs_t *ocs = sport->ocs;
980 ocs_log_debug(sport->ocs,
"Del SPORT: %s\n", sport->display_name);
1032 int32_t initiator_count;
1042 initiator_count = ocs_atomic_add_return(&ocs->tgt_ocs.initiator_count, 1) + 1;
1043 watermark = OCS_MAX(ocs->tgt_ocs.watermark_min,
1045 ocs_atomic_set(&ocs->tgt_ocs.io_high_watermark, watermark);
1047 if (ocs->tgt_ocs.use_global_ramd) {
1048 num_luns = ocs->tgt_ocs.rdisc_count;
1049 }
else if (node->sport != NULL) {
1050 num_luns = node->sport->tgt_sport.rdisc_count;
1052 if (num_luns == 0) {
1053 ocs_log_warn(ocs,
"0 luns found");
1059 OCS_M_NOWAIT | OCS_M_ZERO);
1060 if (node->tgt_node.ua_queues == NULL) {
1061 node->tgt_node.num_ua_queues = 0;
1063 node->tgt_node.num_ua_queues = num_luns;
1064 for (i=0; i<num_luns; i++) {
1065 ocs_lock_init(node->ocs, &node->tgt_node.ua_queues[i].ua_queue_lock,
"ua queue lock");
1066 node->tgt_node.ua_queues[i].num_entries = 0;
1095 uint32_t num_luns = 0;
1096 int32_t initiator_count;
1113 initiator_count = ocs_atomic_sub_return(&ocs->tgt_ocs.initiator_count, 1) - 1;
1114 watermark = OCS_MAX(ocs->tgt_ocs.watermark_min,
1116 ocs_atomic_set(&ocs->tgt_ocs.io_high_watermark, watermark);
1119 if (ocs->tgt_ocs.use_global_ramd) {
1120 num_luns = ocs->tgt_ocs.rdisc_count;
1121 }
else if (node->sport != NULL) {
1122 num_luns = node->sport->tgt_sport.rdisc_count;
1125 if (node->tgt_node.ua_queues != NULL) {
1128 for (i=0; i<num_luns; i++) {
1129 ocs_lock_free(&node->tgt_node.ua_queues[i].ua_queue_lock);
1132 node->tgt_node.ua_queues = NULL;
1134 node->tgt_node.num_ua_queues = 0;
1153 ocs_dma_free(io->ocs, &io->tgt_io.payload);
1158 io->tgt_io.thr = NULL;
1168 uint8_t response_code:7,
1171 uint8_t sense_key:4,
1176 uint8_t information[4];
1178 uint8_t command_specific_information[4];
1182 uint8_t sense_key_specific_hi:7,
1184 uint8_t sense_key_specific_lo[2];
1231 ocs_dma_t first_burst_buffers[], uint32_t first_burst_bytes)
1244 io->tgt_io.first_burst_bytes = first_burst_bytes;
1245 io->tgt_io.first_burst_buffers = first_burst_buffers;
1270 uint32_t max_addrlen,
void **dif_vaddr)
1274 if (max_addrlen >= 1) {
1276 addrlen[0].
length = io->tgt_io.ramdisc->data_block_size;
1303 uint8_t has_first_burst,
1304 ocs_dma_t first_burst_buffers[], uint32_t first_burst_bytes)
1308 ocs_t *ocs = io->ocs;
1310 int32_t active_io_count;
1318 for (i = 0; i < cdb_len; i ++)
1319 ocs_log_debug(NULL,
"%02X ", cdb[i]);
1320 ocs_log_debug(NULL,
"\n");
1325 io->tgt_io.flags = flags;
1326 io->tgt_io.first_burst_buffers = first_burst_buffers;
1327 io->tgt_io.first_burst_bytes = first_burst_bytes;
1328 io->tgt_io.tmfio = NULL;
1331 io->tgt_io.lun = lun;
1332 io->tgt_io.sm.app = io;
1335 io->tgt_io.io_block_count = 0;
1336 io->tgt_io.acc_block_count = 0;
1337 io->tgt_io.cur_lba = 0;
1338 io->tgt_io.cur_block_count = 0;
1340 io->tgt_io.sgl_phys = 0;
1345 io->tgt_io.lun_is_valid = (io->tgt_io.ramdisc != NULL);
1349 io->timeout = ocs->target_io_timer_sec;
1352 io->trecv_wqe_timer = ocs->tgt_wqe_timer;
1355 ocs_lock(&io->tgt_io.sm_lock);
1358 if (ocs->tgt_ocs.enable_task_set_full &&
1359 (active_io_count >= ocs_atomic_read(&ocs->tgt_ocs.io_high_watermark))) {
1360 ocs_atomic_add_return(&ocs->tgt_ocs.watermark_hit, 1);
1362 if (has_first_burst) {
1363 io->tgt_io.send_task_set_full = TRUE;
1372 ocs_unlock(&io->tgt_io.sm_lock);
1379 uint32_t svc_action = cdb[1] & 0x1F;
1381 for (i = 0; i < ARRAY_SIZE(scsi_cmd_table_svc_in_action16); i ++) {
1382 if (scsi_cmd_table_svc_in_action16[i].scsi_cmd == svc_action) {
1383 pcmd = &scsi_cmd_table_svc_in_action16[i];
1388 uint32_t svc_action = cdb[1] & 0x1F;
1390 for (i = 0; i < ARRAY_SIZE(scsi_cmd_table_svc_out_action16); i ++) {
1391 if (scsi_cmd_table_svc_out_action16[i].scsi_cmd == svc_action) {
1392 pcmd = &scsi_cmd_table_svc_out_action16[i];
1397 uint16_t svc_action = (cdb[8] << 8) |
1399 for (i = 0; i < ARRAY_SIZE(scsi_cmd_table_variable_len_cdb); i ++) {
1400 if (scsi_cmd_table_variable_len_cdb[i].scsi_cmd == svc_action) {
1401 pcmd = &scsi_cmd_table_variable_len_cdb[i];
1407 pcmd = scsi_cmd_lookup[cdb[0]];
1411 io->tgt_io.pcmd = pcmd;
1412 io->tgt_io.cdb_len = cdb_len;
1413 ocs_memcpy(io->tgt_io.cdb, cdb, MIN(cdb_len, ARRAY_SIZE(io->tgt_io.cdb)));
1416 io->tgt_io.has_first_burst = has_first_burst;
1425 ocs_unlock(&io->tgt_io.sm_lock);
1446 ocs_io_t *io = ctx->app;
1447 ocs_t *ocs = io->ocs;
1453 switch (ocs->err_injection) {
1455 if (ocs->cmd_err_inject != 0 && ocs->cmd_err_inject == pcmd->
scsi_cmd) {
1456 io_printf(io,
"Err-injection test: drop command\n");
1461 if (ocs->cmd_err_inject != 0 && ocs->cmd_err_inject == pcmd->
scsi_cmd) {
1462 io_printf(io,
"Err-injection test: free dropped command\n");
1468 if (ocs->cmd_err_inject != 0 && ocs->cmd_err_inject == pcmd->
scsi_cmd) {
1469 io_printf(io,
"Err-injection test: delay command\n");
1470 ocs_msleep(ocs->delay_value_msec);
1495 io->tgt_io.tmfio = (ocs_io_t *)arg;
1497 io->tgt_io.tmfio = NULL;
1533 ocs_sm_ctx_t *ctx = &io->tgt_io.sm;
1534 uint8_t *cdb = io->tgt_io.cdb;
1590 ocs_io_t *io = ctx->app;
1591 ocs_t *ocs = io->ocs;
1599 ocs_node_t *node = io->node;
1602 uint32_t lun = io->tgt_io.lun;
1603 uint8_t direction = 0;
1609 if (io->tgt_io.has_first_burst &&
1610 (io->tgt_io.first_burst_bytes == 0 ||
1611 io->tgt_io.first_burst_buffers == NULL)) {
1616 pcmd = io->tgt_io.pcmd;
1645 if (pcmd->
check_lun && !io->tgt_io.lun_is_valid) {
1646 io_printf(io,
"lun %d out of range\n", io->tgt_io.lun);
1657 switch (io->tgt_io.cdb[0]) {
1727 ocs_io_t *io = ctx->app;
1728 ocs_t *ocs = io->ocs;
1739 if (io->tgt_io.has_first_burst &&
1740 (io->tgt_io.first_burst_bytes == 0 ||
1741 io->tgt_io.first_burst_buffers == NULL)) {
1745 io_printf(io,
"Err-injection test: First burst data dropped\n");
1755 io_printf(io,
"first burst/auto-xfr-rdy error encountered\n");
1761 io_printf(io,
"first burst/auto-xfr-rdy aborted encountered\n");
1777 io->tgt_io.tmfio = (ocs_io_t *)arg;
1779 io->tgt_io.tmfio = NULL;
1816 ocs_lock(&io->tgt_io.sm_lock);
1818 ocs_unlock(&io->tgt_io.sm_lock);
1827 uint8_t check_cond = TRUE;
1829 switch (scsi_status) {
1839 io_printf(io,
"status=%d, freeing io\n", scsi_status);
1896 ocs_io_t *io = ctx->app;
1897 ocs_t *ocs = io->ocs;
1905 io_printf(io,
"Err-injection test: drop response lun x%x\n", io->tgt_io.lun);
1951 int32_t (*validate)(ocs_io_t *io);
1952 ocs_io_t *io = ctx->app;
1953 ocs_t *ocs = io->ocs;
1963 io_printf(io,
"Err-injection test: drop response lun x%x\n", io->tgt_io.lun);
1970 result = validate(io);
2019 ocs_io_t *io = ctx->app;
2020 ocs_t *ocs = io->ocs;
2029 io_printf(io,
"Err-injection test: drop response lun x%x\n", io->tgt_io.lun);
2095 ocs_assert(io->tgt_io.send_task_set_full || io->tgt_io.send_check_cond, NULL);
2099 if (io->tgt_io.send_task_set_full) {
2101 }
else if (io->tgt_io.send_check_cond) {
2103 io->tgt_io.send_asc,
2104 io->tgt_io.send_ascq);
2115 io_printf(io,
"first burst/auto-xfr-rdy error encountered\n");
2121 io_printf(io,
"first burst/auto-xfr-rdy aborted encountered\n");
2137 io->tgt_io.tmfio = (ocs_io_t *)arg;
2139 io->tgt_io.tmfio = NULL;
2261 io_printf(io,
"abort failed, status=%d\n", scsi_status);
2263 ocs_lock(&io->tgt_io.sm_lock);
2265 ocs_unlock(&io->tgt_io.sm_lock);
2336 ocs_io_t *tmfio = io->tgt_io.tmfio;
2341 io->tgt_io.tmfio = NULL;
2460 ocs_io_t *io = ctx->app;
2480 io->tgt_io.tmfio = (ocs_io_t *)arg;
2482 io->tgt_io.tmfio = NULL;
2557 ocs_memset(&rsp, 0,
sizeof(rsp));
2558 ocs_memset(&sense, 0,
sizeof(sense));
2564 #if defined(OCS_INCLUDE_FC)
2565 rsp.
residual = io->exp_xfer_len - io->transferred;
2605 ocs_t *ocs = io->ocs;
2607 ocs_memset(&rsp, 0,
sizeof(rsp));
2614 ocs_lock(&io->node->active_ios_lock);
2618 ioloop->tgt_io.lun == io->tgt_io.lun) {
2624 ocs_unlock(&io->node->active_ios_lock);
2631 ocs_log_info(ocs,
"OCS RAMD TASK SET FULL. Tasks >= %d\n", ocs_atomic_read(&ocs->tgt_ocs.io_high_watermark));
2635 ocs_log_info(ocs,
"OCS RAMD SCSI BUSY\n");
2696 sport = node->sport;
2698 tmfio->tgt_io.lun = lun;
2705 if(tmfio->tgt_io.ramdisc == NULL) {
2706 io_printf(tmfio,
"Invalid lun specified, cmd=%d, lun=%d\n", cmd, lun);
2710 tmfio->tgt_io.sm.app = tmfio;
2720 io_printf(tmfio,
"unsupported TMF=%d\n", cmd);
2735 tmfio->tgt_io.sm.app = tmfio;
2750 ocs_log_debug(ocs,
"[%s] abort_task_set\n", node->display_name);
2758 ocs_log_debug(ocs,
"[%s] clear_task_set\n", node->display_name);
2772 ocs_log_debug(ocs,
"[%s] logical unit reset, lun x%x\n", node->display_name, tmfio->tgt_io.lun);
2795 if (ocs->tgt_ocs.use_global_ramd) {
2796 lun_count = ocs->tgt_ocs.rdisc_count;
2798 lun_count = sport->tgt_sport.rdisc_count;
2802 ocs_log_debug(ocs,
"[%s] target reset: lun count=%d\n",
2803 node->display_name, lun_count);
2813 for (lun = 0; lun < lun_count; lun++) {
2826 tmfio->tgt_io.sm.app = tmfio;
2853 ocs_lock(&io->tgt_io.sm_lock);
2855 ocs_unlock(&io->tgt_io.sm_lock);
2882 ocs_lock(&io->tgt_io.sm_lock);
2884 #if ENABLE_BUFFER_DUMP==1
2885 #if defined(OCS_INCLUDE_DEBUG)
2887 if (io->tgt_io.is_read == FALSE) {
2888 ocs_t *ocs = io->ocs;
2890 uint32_t max_sgl = (ocs->tgt_ocs.max_sgl < ARRAY_SIZE(sgl) ? ocs->tgt_ocs.max_sgl : ARRAY_SIZE(sgl));
2891 uint32_t blk_count = io->tgt_io.cur_block_count;
2894 uint32_t sgl_flags = 0;
2896 if (io->tgt_io.sgl_phys) {
2900 lba = io->tgt_io.io_lba + io->tgt_io.acc_block_count;
2901 sgl_count =
ocs_ramdisc_sgl(ocs, io->tgt_io.ramdisc, sgl, max_sgl, ocs->tgt_ocs.max_sge,
2902 lba, &blk_count, sgl_flags, TRUE);
2907 switch (scsi_status) {
2911 io->tgt_io.acc_block_count += io->tgt_io.cur_block_count;
2913 if (io->tgt_io.acc_block_count < io->tgt_io.io_block_count) {
2914 io->tgt_io.dif_info.ref_tag += io->tgt_io.cur_block_count;
2921 const char *fn = strrchr(__FILE__,
'/'); \
2922 ocs_log_err(io->ocs,
"%s(%d) assertion (rc == 0) failed\n", (fn ? fn + 1 : __FILE__), __LINE__);
2923 ocs_unlock(&io->tgt_io.sm_lock);
2927 #if ENABLE_DIF_VERIFICATION == 1
2928 if (!io->tgt_io.is_read) {
2929 if (ocs_ramdisc_dif_verify(io->ocs, io->tgt_io.ramdisc, io->tgt_io.io_lba,
2930 io->tgt_io.io_block_count) != 0) {
2931 ocs_log_test(io->ocs,
"Write DIF IO at LBA 0x%"
2932 PRIx64
" for %d blocks with bad data in RAM\n",
2933 io->tgt_io.io_lba, io->tgt_io.io_block_count);
2945 io_printf(io,
"dataphase error %d\n", scsi_status);
2950 ocs_unlock(&io->tgt_io.sm_lock);
2970 uint32_t block_count;
2977 lba = ((cdb[1] & 0x1f) << 16) |
2982 block_count = cdb[4];
2987 if (block_count == 0){
2998 if (io->tgt_io.ramdisc->prot_en == 0) {
3024 uint32_t block_count;
3030 lba = ((uint32_t)(cdb[2] << 24)) |
3031 ((uint32_t)(cdb[3] << 16)) |
3032 ((uint32_t)(cdb[4] << 8)) |
3033 ((uint32_t)(cdb[5] << 0));
3041 wrprotect = ((cdb[1] & 0xe0) >> 5);
3043 if ((io->tgt_io.ramdisc->prot_en == 1) && (io->tgt_io.ramdisc->p_type == 2) && (wrprotect != 0)) {
3068 uint32_t block_count;
3074 lba = ((uint32_t)(cdb[2] << 24)) |
3075 ((uint32_t)(cdb[3] << 16)) |
3076 ((uint32_t)(cdb[4] << 8)) |
3077 ((uint32_t)(cdb[5] << 0));
3081 ((uint32_t)(cdb[6] << 24)) |
3082 ((uint32_t)(cdb[7] << 16)) |
3083 ((uint32_t)(cdb[8] << 8)) |
3084 ((uint32_t)(cdb[9] << 0));
3087 wrprotect = ((cdb[1] & 0xe0) >> 5);
3089 if ((io->tgt_io.ramdisc->prot_en == 1) && (io->tgt_io.ramdisc->p_type == 2) && (wrprotect != 0)) {
3114 uint32_t block_count;
3120 lba = ((uint64_t)cdb[2] << 56) |
3121 ((uint64_t)cdb[3] << 48) |
3122 ((uint64_t)cdb[4] << 40) |
3123 ((uint64_t)cdb[5] << 32) |
3124 ((uint64_t)cdb[6] << 24) |
3125 ((uint64_t)cdb[7] << 16) |
3126 ((uint64_t)cdb[8] << 8) |
3127 ((uint64_t)cdb[9] << 0);
3137 wrprotect = ((cdb[1] & 0xe0) >> 5);
3139 if ((io->tgt_io.ramdisc->prot_en == 1) && (io->tgt_io.ramdisc->p_type == 2) && (wrprotect != 0)) {
3164 uint32_t block_count;
3176 lba = ((uint64_t)cdb[12] << 56) |
3177 ((uint64_t)cdb[13] << 48) |
3178 ((uint64_t)cdb[14] << 40) |
3179 ((uint64_t)cdb[15] << 32) |
3180 ((uint64_t)cdb[16] << 24) |
3181 ((uint64_t)cdb[17] << 16) |
3182 ((uint64_t)cdb[18] << 8) |
3183 ((uint64_t)cdb[19] << 0);
3193 wrprotect = ((cdb[10] & 0xe0) >> 5);
3196 ref_tag = (cdb[20] << 24) |
3202 app_tag = (cdb[24] << 8) |
3205 if (io->tgt_io.ramdisc->prot_en == 0) {
3206 if (wrprotect != 0) {
3219 if ((io->tgt_io.ramdisc->prot_en == 1) && (io->tgt_io.ramdisc->p_type != 2)) {
3248 uint8_t cor_dis, wr_uncor, pblock;
3253 cor_dis = (cdb[1] >> 7) & 1;
3254 wr_uncor = (cdb[1] >> 6) & 1;
3255 pblock = (cdb[1] >> 5) & 1;
3258 lba = ((uint32_t)(cdb[2] << 24)) |
3259 ((uint32_t)(cdb[3] << 16)) |
3260 ((uint32_t)(cdb[4] << 8)) |
3261 ((uint32_t)(cdb[5] << 0));
3263 xfer_len = (cdb[7] << 8) |
3269 if ((xfer_len == 0) && (!wr_uncor)) {
3295 uint8_t cor_dis, wr_uncor, pblock;
3301 cor_dis = (cdb[1] >> 7) & 1;
3302 wr_uncor = (cdb[1] >> 6) & 1;
3303 pblock = (cdb[1] >> 5) & 1;
3306 lba = ((uint64_t)cdb[2] << 56) |
3307 ((uint64_t)cdb[3] << 48) |
3308 ((uint64_t)cdb[4] << 40) |
3309 ((uint64_t)cdb[5] << 32) |
3310 ((uint64_t)cdb[6] << 24) |
3311 ((uint64_t)cdb[7] << 16) |
3312 ((uint64_t)cdb[8] << 8) |
3313 ((uint64_t)cdb[9] << 0);
3315 xfer_len = (cdb[12] << 8) |
3321 if ((xfer_len == 0) && (!wr_uncor)) {
3346 uint16_t num_blocks;
3354 wrprotect = (cdb[1] & 0xe0) >> 5;
3355 pbdata = (cdb[1] & 0x04) >> 2;
3356 lbdata = (cdb[1] & 0x02) >> 1;
3359 lba = ((uint32_t)(cdb[2] << 24)) |
3360 ((uint32_t)(cdb[3] << 16)) |
3361 ((uint32_t)(cdb[4] << 8)) |
3362 ((uint32_t)(cdb[5] << 0));
3364 num_blocks = (cdb[7] << 8) |
3367 if ((io->tgt_io.ramdisc->prot_en == 1) && (io->tgt_io.ramdisc->p_type == 2) && (wrprotect != 0)) {
3393 uint16_t num_blocks;
3401 wrprotect = (cdb[1] & 0xe0) >> 5;
3402 pbdata = (cdb[1] & 0x04) >> 2;
3403 lbdata = (cdb[1] & 0x02) >> 1;
3406 lba = ((uint64_t)cdb[2] << 56) |
3407 ((uint64_t)cdb[3] << 48) |
3408 ((uint64_t)cdb[4] << 40) |
3409 ((uint64_t)cdb[5] << 32) |
3410 ((uint64_t)cdb[6] << 24) |
3411 ((uint64_t)cdb[7] << 16) |
3412 ((uint64_t)cdb[8] << 8) |
3413 ((uint64_t)cdb[9] << 0);
3415 num_blocks = ((uint64_t)cdb[10] << 24) |
3416 ((uint64_t)cdb[11] << 16) |
3417 ((uint64_t)cdb[12] << 8) |
3418 ((uint64_t)cdb[13] << 0);
3420 if ((io->tgt_io.ramdisc->prot_en == 1) && (io->tgt_io.ramdisc->p_type == 2) && (wrprotect != 0)) {
3446 uint16_t num_blocks;
3450 uint32_t expected_ref_tag;
3451 uint16_t expected_app_tag;
3457 wrprotect = (cdb[10] & 0xe0) >> 5;
3458 pbdata = (cdb[10] & 0x04) >> 2;
3459 lbdata = (cdb[10] & 0x02) >> 1;
3462 lba = ((uint64_t)cdb[12] << 56) |
3463 ((uint64_t)cdb[13] << 48) |
3464 ((uint64_t)cdb[14] << 40) |
3465 ((uint64_t)cdb[15] << 32) |
3466 ((uint64_t)cdb[16] << 24) |
3467 ((uint64_t)cdb[17] << 16) |
3468 ((uint64_t)cdb[18] << 8) |
3469 ((uint64_t)cdb[19] << 0);
3471 expected_ref_tag = ((uint64_t)cdb[20] << 24) |
3472 ((uint64_t)cdb[21] << 16) |
3473 ((uint64_t)cdb[22] << 8) |
3474 ((uint64_t)cdb[23] << 0);
3476 expected_app_tag = ((uint64_t)cdb[24] << 8) |
3477 ((uint64_t)cdb[25] << 0);
3479 num_blocks = ((uint64_t)cdb[28] << 24) |
3480 ((uint64_t)cdb[29] << 16) |
3481 ((uint64_t)cdb[30] << 8) |
3482 ((uint64_t)cdb[31] << 0);
3484 if (io->tgt_io.ramdisc->prot_en == 0) {
3485 if (wrprotect != 0) {
3498 if ((io->tgt_io.ramdisc->prot_en == 1) && (io->tgt_io.ramdisc->p_type != 2)) {
3507 expected_app_tag, expected_ref_tag);
3522 uint32_t offset = 0;
3523 uint32_t buf_index = 0;
3524 uint32_t buffer_size;
3526 while (bytes_left > 0) {
3527 buffer_size = (bytes_left > io->tgt_io.first_burst_buffers[buf_index].size ?
3528 io->tgt_io.first_burst_buffers[buf_index].size : bytes_left);
3530 ocs_memcpy((uint8_t *)io->tgt_io.payload.virt + offset,
3531 io->tgt_io.first_burst_buffers[buf_index].virt,
3534 bytes_left -= buffer_size;
3535 offset += buffer_size;
3553 uint32_t buf_index = 0;
3554 uint64_t lba = io->tgt_io.io_lba;
3555 uint32_t bytes_left;
3558 uint32_t src_remaining;
3560 uint32_t dst_remaining;
3567 bytes_left = (io->tgt_io.first_burst_bytes - (io->tgt_io.first_burst_bytes % blocksize));
3569 src = io->tgt_io.first_burst_buffers[buf_index].virt;
3570 src_remaining = io->tgt_io.first_burst_buffers[buf_index++].size;
3572 #if defined(OCS_INCLUDE_FC)
3573 if (io->ocs->esoc) {
3574 uint64_t lba_offset;
3576 lba_offset = (lba % 32) * blocksize;
3582 dst_remaining = blocksize;
3584 while (bytes_left > 0) {
3586 n = MIN(bytes_left, MIN(dst_remaining, src_remaining));
3588 ocs_memcpy(dst, src, n);
3595 if (src_remaining == 0) {
3596 src = io->tgt_io.first_burst_buffers[buf_index].virt;
3597 src_remaining = io->tgt_io.first_burst_buffers[buf_index++].size;
3599 if (dst_remaining == 0) {
3601 dst_remaining = blocksize;
3605 io->tgt_io.acc_block_count += io->tgt_io.first_burst_bytes / ramdisc->
phys_block_size;
3627 switch(ramdisc->
p_type) {
3667 uint32_t data_blk_size)
3671 uint32_t bytes_left;
3672 uint32_t buf_index = 0;
3673 uint32_t blk_count = 0;
3674 uint64_t lba = io->tgt_io.io_lba;
3678 uint16_t recv_apptag;
3679 uint32_t recv_reftag;
3682 uint32_t src_remaining;
3684 uint32_t dst_remaining;
3697 bytes_left = (io->tgt_io.first_burst_bytes -
3698 (io->tgt_io.first_burst_bytes % blocksize));
3709 src = io->tgt_io.first_burst_buffers[buf_index].virt;
3710 src_remaining = io->tgt_io.first_burst_buffers[buf_index++].size;
3712 #if defined(OCS_INCLUDE_FC)
3713 if (io->ocs->esoc) {
3714 uint64_t lba_offset;
3716 lba_offset = (lba % 32) * blocksize;
3722 while (bytes_left > 0) {
3725 dst_remaining = data_blk_size;
3729 while (dst_remaining > 0) {
3730 n = MIN(bytes_left, MIN(dst_remaining, src_remaining));
3731 ocs_memcpy(dst, src, n);
3738 if (src_remaining == 0) {
3739 src = io->tgt_io.first_burst_buffers[buf_index].virt;
3740 src_remaining = io->tgt_io.first_burst_buffers[buf_index++].size;
3750 dst = (uint8_t*) &difdata;
3751 dst_remaining =
sizeof(difdata);
3752 while (dst_remaining > 0) {
3753 n = MIN(bytes_left, MIN(dst_remaining, src_remaining));
3754 ocs_memcpy(dst, src, n);
3760 if (src_remaining == 0) {
3761 src = io->tgt_io.first_burst_buffers[buf_index].virt;
3762 src_remaining = io->tgt_io.first_burst_buffers[buf_index++].size;
3767 recv_crc = ocs_be16toh(difdata.
crc);
3770 io_printf(io,
"%s: miscompare (CRC) received 0x%x but "
3779 recv_apptag = ocs_be16toh(difdata.
app_tag);
3781 dif_info->
app_tag != recv_apptag) {
3782 io_printf(io,
"%s: miscompare (app_tag) received 0x%x but "
3791 recv_reftag = ocs_be32toh(difdata.
ref_tag);
3793 dif_info->
ref_tag + blk_count != recv_reftag) {
3794 io_printf(io,
"%s: miscompare (ref_tag) received 0x%x but "
3798 dif_info->
ref_tag + blk_count);
3806 uint32_t blkCount = dif_info->
ref_tag + blk_count;
3808 difdata.
crc = ocs_htobe16(crc);
3810 difdata.
ref_tag = ocs_htobe32(blkCount);
3819 ocs_memcpy(dif, &difdata,
sizeof(*dif));
3825 io->tgt_io.acc_block_count = blk_count;
3834 if (io->tgt_io.ramdisc->prot_en) {
3838 ocs_log_err(io->ocs,
"Unsupported write DIF block size: %d\n",
3839 io->tgt_io.ramdisc->data_block_size);
3859 dif_info->
dif_separate = io->tgt_io.ramdisc->dif_separate;
3874 switch (wrprotect) {
3877 if (io->tgt_io.ramdisc->prot_en) {
3889 if (io->tgt_io.ramdisc->prot_en) {
3902 if (io->tgt_io.ramdisc->prot_en) {
3914 if (io->tgt_io.ramdisc->prot_en) {
3926 if (io->tgt_io.ramdisc->prot_en) {
3938 if (io->tgt_io.ramdisc->prot_en) {
3976 uint32_t app_tag, uint32_t ref_tag)
3985 if (block_count == 0) {
3987 }
else if (io->exp_xfer_len == 0) {
3992 dif_info = &(io->tgt_io.dif_info);
3997 if ((io->tgt_io.ramdisc->prot_en == 0) && (wrprotect != 0)) {
4003 io->tgt_io.is_read = FALSE;
4004 io->tgt_io.io_lba = lba;
4005 io->tgt_io.io_block_count = block_count;
4006 io->tgt_io.acc_block_count = 0;
4007 io->tgt_io.cur_lba = 0;
4008 io->tgt_io.cur_block_count = 0;
4010 cmd_trace(io,
"lba x%" PRIx64
" count x%x\n", lba, block_count);
4018 dif_info->
lba = lba;
4021 if (io->tgt_io.first_burst_bytes) {
4033 if (io->tgt_io.acc_block_count == io->tgt_io.io_block_count) {
4066 uint8_t cor_dis, uint8_t wr_uncor, uint8_t pblock)
4075 if (wr_uncor == 1 || cor_dis == 1) {
4081 io->tgt_io.is_read = FALSE;
4082 io->tgt_io.io_lba = lba;
4083 io->tgt_io.io_block_count = xfer_len / io->tgt_io.ramdisc->data_block_size;
4085 cmd_trace(io,
"lba x%" PRIx64
"\n", lba);
4087 dif_info = &(io->tgt_io.dif_info);
4092 if (io->tgt_io.first_burst_bytes) {
4098 if (io->tgt_io.acc_block_count == io->tgt_io.io_block_count) {
4103 io->tgt_io.sgl_phys = 1;
4136 uint8_t wrprotect, uint8_t pbdata, uint8_t lbdata,
4137 uint32_t app_tag, uint32_t ref_tag)
4147 if ((io->tgt_io.ramdisc->prot_en == 0) && (wrprotect != 0)) {
4153 io->tgt_io.wrprotect = wrprotect;
4154 io->tgt_io.pbdata = pbdata;
4155 io->tgt_io.lbdata = lbdata;
4156 io->tgt_io.num_blocks = block_count;
4159 if ((pbdata == 1) && (lbdata == 1)) {
4164 if ((lba + block_count) > io->tgt_io.ramdisc->block_count) {
4175 dif_info = &(io->tgt_io.dif_info);
4181 io->tgt_io.is_read = FALSE;
4182 io->tgt_io.io_lba = lba;
4183 io->tgt_io.io_block_count = block_count;
4185 cmd_trace(io,
"lba x%" PRIx64
" count x%x\n", lba, block_count);
4194 if (io->tgt_io.first_burst_bytes) {
4206 if (io->tgt_io.acc_block_count == io->tgt_io.io_block_count) {
4214 io->tgt_io.supress_auto_response = 1;
4247 uint64_t start_lba = io->tgt_io.io_lba;
4248 uint32_t block_count = io->tgt_io.num_blocks;
4260 if (block_count == 0) {
4261 block_count = io->tgt_io.ramdisc->block_count - start_lba;
4267 if ((io->tgt_io.lbdata == 0) && (io->tgt_io.pbdata == 0)) {
4268 if (io->tgt_io.ramdisc->prot_en == 0) {
4270 for (i=1; i<block_count; i++) {
4272 ocs_memcpy(dest, src, io->tgt_io.ramdisc->phys_block_size);
4276 ref_tag = ocs_be32toh(src_dif->
ref_tag);
4280 for (i=1; i<block_count; i++) {
4282 ocs_memcpy(dest, src, io->tgt_io.ramdisc->phys_block_size);
4286 dst_dif->
crc = src_dif->
crc;
4288 dst_dif->
ref_tag = ocs_htobe32(ref_tag + i);
4292 }
else if ((io->tgt_io.lbdata == 0) && (io->tgt_io.pbdata == 1)) {
4298 for (i=0; i<block_count; i++) {
4300 ocs_memcpy(dest, src, io->tgt_io.ramdisc->phys_block_size);
4301 phys_addr = ocs_htobe64(start_lba + i);
4302 ocs_memcpy(dest, &phys_addr, 8);
4305 }
else if ((io->tgt_io.lbdata == 1) && (io->tgt_io.pbdata == 0)) {
4309 for (i=0; i<block_count; i++) {
4311 ocs_memcpy(dest, src, io->tgt_io.ramdisc->phys_block_size);
4312 ref_tag = ocs_htobe32(start_lba + i);
4313 ocs_memcpy(dest, &ref_tag, 4);
4342 uint32_t block_count;
4347 lba = ((cdb[1] & 0x1f) << 16) |
4350 block_count = cdb[4];
4355 if (block_count == 0){
4386 uint32_t block_count;
4391 lba = ((uint32_t)(cdb[2] << 24)) |
4392 ((uint32_t)(cdb[3] << 16)) |
4393 ((uint32_t)(cdb[4] << 8)) |
4394 ((uint32_t)(cdb[5] << 0));
4398 rdprotect = ((cdb[1] & 0xe0) >> 5);
4400 if ((io->tgt_io.ramdisc->prot_en == 1) && (io->tgt_io.ramdisc->p_type == 2) && (rdprotect != 0)) {
4425 uint32_t block_count;
4430 lba = (cdb[2] << 24) |
4434 block_count = ((uint32_t)(cdb[6] << 24)) |
4435 ((uint32_t)(cdb[7] << 16)) |
4436 ((uint32_t)(cdb[8] << 8)) |
4437 ((uint32_t)(cdb[9] << 0));
4438 rdprotect = ((cdb[1] & 0xe0) >> 5);
4440 if ((io->tgt_io.ramdisc->prot_en == 1) && (io->tgt_io.ramdisc->p_type == 2) && (rdprotect != 0)) {
4465 uint32_t block_count;
4470 lba = ((uint64_t)cdb[2] << 56) |
4471 ((uint64_t)cdb[3] << 48) |
4472 ((uint64_t)cdb[4] << 40) |
4473 ((uint64_t)cdb[5] << 32) |
4474 ((uint64_t)cdb[6] << 24) |
4475 ((uint64_t)cdb[7] << 16) |
4476 ((uint64_t)cdb[8] << 8) |
4477 ((uint64_t)cdb[9] << 0);
4478 block_count = (cdb[10] << 24) |
4482 rdprotect = ((cdb[1] & 0xe0) >> 5);
4484 if ((io->tgt_io.ramdisc->prot_en == 1) && (io->tgt_io.ramdisc->p_type == 2) && (rdprotect != 0)) {
4509 uint32_t block_count;
4517 lba = ((uint64_t)cdb[12] << 56) |
4518 ((uint64_t)cdb[13] << 48) |
4519 ((uint64_t)cdb[14] << 40) |
4520 ((uint64_t)cdb[15] << 32) |
4521 ((uint64_t)cdb[16] << 24) |
4522 ((uint64_t)cdb[17] << 16) |
4523 ((uint64_t)cdb[18] << 8) |
4524 ((uint64_t)cdb[19] << 0);
4525 block_count = (cdb[28] << 24) |
4529 rdprotect = ((cdb[10] & 0xe0) >> 5);
4530 ref_tag = (cdb[20] << 24) |
4534 app_tag = (cdb[24] << 8) |
4537 if (io->tgt_io.ramdisc->prot_en == 0) {
4538 if (rdprotect != 0) {
4550 if ((io->tgt_io.ramdisc->prot_en == 1) && (io->tgt_io.ramdisc->p_type != 2)) {
4578 uint8_t pblock, corrct;
4582 pblock = (cdb[1] >> 2) & 1;
4583 corrct = (cdb[1] >> 1) & 1;
4585 lba = ((uint32_t)(cdb[2] << 24)) |
4586 ((uint32_t)(cdb[3] << 16)) |
4587 ((uint32_t)(cdb[4] << 8)) |
4588 ((uint32_t)(cdb[5] << 0));
4597 if (xfer_len == 0) {
4622 uint8_t pblock, corrct;
4627 lba = ((uint64_t)cdb[2] << 56) |
4628 ((uint64_t)cdb[3] << 48) |
4629 ((uint64_t)cdb[4] << 40) |
4630 ((uint64_t)cdb[5] << 32) |
4631 ((uint64_t)cdb[6] << 24) |
4632 ((uint64_t)cdb[7] << 16) |
4633 ((uint64_t)cdb[8] << 8) |
4634 ((uint64_t)cdb[9] << 0);
4643 if (xfer_len == 0) {
4647 pblock = (cdb[14] >> 1) & 1;
4648 corrct = cdb[14] & 1;
4664 ocs_t *ocs = io->ocs;
4671 uint32_t sgl_flags = 0;
4675 max_sgl = MIN(ocs->tgt_ocs.max_sgl, io->sgl_allocated);
4679 blocksize = io->tgt_io.ramdisc->phys_block_size;
4684 if (io->tgt_io.sgl_phys) {
4688 lba = io->tgt_io.io_lba + io->tgt_io.acc_block_count;
4697 io->tgt_io.cur_block_count = io->tgt_io.io_block_count - io->tgt_io.acc_block_count;
4698 if (!io->tgt_io.is_read &&
4699 (io->tgt_io.cur_block_count * blocksize) > io->node->max_wr_xfer_size) {
4700 io->tgt_io.cur_block_count = io->node->max_wr_xfer_size / blocksize;
4705 ocs->tgt_ocs.max_sge,
4707 if (sgl_status < 0) {
4708 ocs_log_err(io->ocs,
"Failed building SGLs\n");
4711 io->sgl_count = sgl_status;
4713 if (dif_info != NULL) {
4722 (io->tgt_io.io_block_count == (io->tgt_io.acc_block_count + io->tgt_io.cur_block_count))) {
4726 if (io->tgt_io.supress_auto_response) {
4730 xfer_len = (io->tgt_io.cur_block_count * (uint64_t)blocksize);
4732 if (io->tgt_io.is_read) {
4733 #if ENABLE_DIF_VERIFICATION == 1
4734 if (ocs_ramdisc_dif_verify(ocs, io->tgt_io.ramdisc, lba, io->tgt_io.cur_block_count) != 0) {
4735 ocs_log_test(io->ocs,
"Read DIF IO at LBA 0x%" PRIx64
4736 " for %d blocks with bad data in RAM\n",
4737 lba, io->tgt_io.cur_block_count);
4769 uint32_t app_tag, uint32_t ref_tag)
4778 if (block_count == 0) {
4780 }
else if (io->exp_xfer_len == 0) {
4785 dif_info = &(io->tgt_io.dif_info);
4790 if ((io->tgt_io.ramdisc->prot_en == 0) && (rdprotect != 0)) {
4795 io->tgt_io.io_lba = lba;
4796 io->tgt_io.io_block_count = block_count;
4797 io->tgt_io.acc_block_count = 0;
4798 io->tgt_io.cur_lba = 0;
4799 io->tgt_io.cur_block_count = 0;
4801 io->tgt_io.is_read = TRUE;
4803 cmd_trace(io,
"lba x%" PRIx64
" count x%x io_len x%x\n", lba, block_count,
4804 io->tgt_io.io_block_count * io->tgt_io.ramdisc->phys_block_size);
4811 dif_info->
dif_separate = io->tgt_io.ramdisc->dif_separate;
4817 dif_info->
lba = lba;
4822 ocs_log_test(io->ocs,
"Unsupported DIF read block size: %d\n",
4823 io->tgt_io.ramdisc->data_block_size);
4827 switch (rdprotect) {
4830 if (io->tgt_io.ramdisc->prot_en) {
4845 if (io->tgt_io.ramdisc->prot_en) {
4857 if (io->tgt_io.ramdisc->prot_en) {
4869 if (io->tgt_io.ramdisc->prot_en) {
4881 if (io->tgt_io.ramdisc->prot_en) {
4931 io->tgt_io.is_read = TRUE;
4932 io->tgt_io.io_lba = lba;
4933 io->tgt_io.io_block_count = xfer_len / io->tgt_io.ramdisc->phys_block_size;
4935 cmd_trace(io,
"lba x%" PRIx64
" io_len x%x\n", lba, io->tgt_io.io_block_count *
4936 io->tgt_io.ramdisc->phys_block_size);
4938 dif_info = &(io->tgt_io.dif_info);
4942 io->tgt_io.sgl_phys = 1;
4976 uint8_t protection_field_usage;
4979 uint8_t prot_en = 0;
4980 uint8_t dif_separate;
4986 fmtpinfo = io->tgt_io.fmtpinfo;
4988 payload = io->tgt_io.payload.virt;
4990 protection_field_usage = payload[0] & 0x07;
4992 dif_separate = (payload[1] & 1) != 0;
5005 if (protection_field_usage != 0) {
5042 int formatted_block_size;
5054 if (io->tgt_io.ramdisc->pending_block_size == 0) {
5055 if (io->tgt_io.ramdisc->prot_en) {
5056 formatted_block_size = io->tgt_io.ramdisc->phys_block_size - 8;
5058 formatted_block_size = io->tgt_io.ramdisc->phys_block_size;
5061 formatted_block_size = io->tgt_io.ramdisc->pending_block_size;
5064 switch(formatted_block_size) {
5073 ocs_log_test(io->ocs,
"Failing format with protection enabled and block size of %d\n", formatted_block_size);
5081 if (
ocs_format_ramdisc(io->ocs, io->tgt_io.ramdisc, io->tgt_io.ramdisc->pending_block_size, p_type,
5082 prot_en, dif_separate)) {
5123 ocs_lock(&io->tgt_io.sm_lock);
5133 ocs_log_test(io->ocs,
"dataphase completed with errors %d\n", scsi_status);
5134 ocs_unlock(&io->tgt_io.sm_lock);
5135 return -scsi_status;
5138 ocs_unlock(&io->tgt_io.sm_lock);
5163 uint8_t parameter_list_header_length;
5169 fmtpinfo = (cdb[1] & 0xc0) >> 6;
5170 longlist = (cdb[1] & 0x20) >> 5;
5171 fmtdata = (cdb[1] & 0x10) >> 4;
5175 if ((fmtpinfo != 0) && (fmtdata == 0)) {
5184 if (fmtpinfo && !io->tgt_io.ramdisc->prot_capable) {
5189 io->tgt_io.fmtpinfo = fmtpinfo;
5194 parameter_list_header_length = 8;
5196 parameter_list_header_length = 4;
5199 rc = ocs_dma_alloc(io->ocs, &io->tgt_io.payload, parameter_list_header_length, 16);
5201 ocs_log_err(io->ocs,
"ocs_scsi_dma_alloc failed\n");
5211 if (io->tgt_io.first_burst_bytes >= parameter_list_header_length) {
5223 sgl.
addr = io->tgt_io.payload.phys;
5224 sgl.
len = parameter_list_header_length;
5232 ocs_log_test(io->ocs,
"Failed to start data phase, rc is %d\n", rc);
5241 rc =
ocs_format_ramdisc(io->ocs, io->tgt_io.ramdisc, io->tgt_io.ramdisc->pending_block_size,
5287 uint32_t block_size;
5290 lba = (cdb[2] << 24) |
5294 pmi = (cdb[8] & 1) != 0;
5296 cmd_trace(io,
"lba x%x cpmi x%x\n", lba, pmi);
5298 rc = ocs_dma_alloc(io->ocs, &io->tgt_io.payload, 256, 16);
5300 ocs_log_err(io->ocs,
"ocs_dma_alloc failed\n");
5305 param = io->tgt_io.payload.virt;
5306 memset(param, 0,
sizeof(*param));
5309 param->
returned_lba = ocs_htobe32(io->tgt_io.ramdisc->block_count - 1);
5314 block_size = io->tgt_io.ramdisc->phys_block_size;
5315 if (io->tgt_io.ramdisc->prot_en) {
5320 xfer_len =
sizeof (*param);
5321 sgl[0].
addr = io->tgt_io.payload.phys;
5322 sgl[0].
len = xfer_len;
5324 io->tgt_io.is_read = TRUE;
5341 uint8_t prot_en : 1,
5344 uint8_t lba_per_phys_blk:4,
5346 uint8_t lowest_aligned_lba_msb:6,
5350 uint8_t reserved[16];
5372 uint32_t allocation_len;
5374 uint32_t block_size;
5378 lba = (((uint64_t)cdb[2]) << 56) |
5379 (((uint64_t)cdb[3]) << 48) |
5380 (((uint64_t)cdb[4]) << 40) |
5381 (((uint64_t)cdb[5]) << 32) |
5382 (((uint64_t)cdb[6]) << 24) |
5383 (((uint64_t)cdb[7]) << 16) |
5384 (((uint64_t)cdb[8]) << 8) |
5385 (((uint64_t)cdb[9]) << 0);
5395 if (allocation_len == 0) {
5399 pmi = (cdb[15] & 1) != 0;
5401 cmd_trace(io,
"lba %" PRId64
" len %d pmi %d\n", lba, allocation_len, pmi);
5402 rc = ocs_dma_alloc(io->ocs, &io->tgt_io.payload, allocation_len, 16);
5404 ocs_log_err(NULL,
"ocs_dma_alloc failed\n");
5409 param = io->tgt_io.payload.virt;
5410 memset(param, 0,
sizeof(*param));
5413 param->
returned_lba = ocs_htobe64(io->tgt_io.ramdisc->block_count - 1);
5418 block_size = io->tgt_io.ramdisc->phys_block_size;
5419 if (io->tgt_io.ramdisc->prot_en) {
5424 if (io->tgt_io.ramdisc->prot_en == 0) {
5430 param->
p_type = io->tgt_io.ramdisc->p_type - 1;
5436 xfer_len =
sizeof (*param);
5437 sgl[0].
addr = io->tgt_io.payload.phys;
5438 sgl[0].
len = xfer_len;
5440 io->tgt_io.is_read = TRUE;
5451 #define INQ_VPD_SUPPORTED_PAGE_00 0x00
5452 #define INQ_VPD_UNIT_SERIAL_NO_PAGE_80 0x80
5453 #define INQ_VPD_DEVICE_ID_PAGE_83 0x83
5454 #define INQ_VPD_EXT_INQ_DATA_PAGE_86 0x86
5455 #define INQ_VPD_BLOCKS_LIMIT_PAGE_B0 0xB0
5456 #define INQ_VPD_BLOCK_DEV_CHARS_PAGE_B1 0xB1
5476 uint8_t peripheral_device_type:5,
5477 peripheral_qualifier:3;
5481 uint8_t response_data_format:4,
5485 uint8_t additional_len;
5504 uint8_t t10_vendor_id[8];
5505 uint8_t product_id[16];
5506 uint8_t product_revision_level[4];
5507 uint8_t vendor_specific[20];
5513 uint8_t version_descriptor_1[2];
5514 uint8_t version_descriptor_2[2];
5515 uint8_t version_descriptor_3[2];
5516 uint8_t version_descriptor_4[2];
5517 uint8_t version_descriptor_5[2];
5518 uint8_t version_descriptor_6[2];
5519 uint8_t version_descriptor_7[2];
5520 uint8_t version_descriptor_8[2];
5522 uint8_t vendor_specific_parameters[0];
5545 uint8_t peripheral_device_type:5,
5546 peripheral_qualifier:3;
5550 uint8_t page_codes[0];
5557 uint8_t peripheral_device_type:5,
5558 peripheral_qualifier:3;
5562 uint8_t product_serial_number[24];
5569 uint8_t peripheral_device_type:5,
5570 peripheral_qualifier:3;
5580 protocol_identifier:4;
5581 uint8_t designator_type:4,
5594 uint8_t company_id[3];
5595 uint8_t vendor_specific_extension_identifier[5];
5603 uint8_t peripheral_device_type:5,
5604 peripheral_qualifier:3;
5632 uint8_t multi_io_nexus_microcode_download:4,
5641 uint8_t peripheral_device_type:5,
5642 peripheral_qualifier:3;
5647 uint8_t maximum_compare_and_write_length;
5655 uint32_t unmap_granularity_alignment:31,
5666 uint8_t peripheral_device_type:5,
5667 peripheral_qualifier:3;
5672 uint8_t nominal_form_factor:4,
5698 uint32_t allocation_len;
5699 uint32_t xfer_len = 0;
5700 ocs_t *ocs = io->ocs;
5705 allocation_len = (cdb[3] << 8) | (cdb[4]);
5710 if (allocation_len == 0) {
5714 rc = ocs_dma_alloc(io->ocs, &io->tgt_io.payload, 256, 16);
5716 ocs_log_err(NULL,
"ocs__dma_alloc failed\n");
5737 if (!io->tgt_io.lun_is_valid) {
5741 inq = io->tgt_io.payload.virt;
5742 memset(inq, 0,
sizeof(*inq));
5757 inq = io->tgt_io.payload.virt;
5758 memset(inq, 0,
sizeof(*inq));
5765 inq->
protect = io->tgt_io.ramdisc->prot_capable;
5768 ocs_memcpy(inq->
product_id,
"ocs-ramd ", 16);
5774 if (io->tgt_io.ramdisc->external_dif) {
5783 ocs_strncpy(inq->
t10_vendor_id, io->tgt_io.ramdisc->t10_vendor_id,
5784 MIN(
sizeof(inq->
t10_vendor_id), ocs_strlen(io->tgt_io.ramdisc->t10_vendor_id)));
5789 inqextdif->
protect = io->tgt_io.ramdisc->prot_capable;
5805 inq = io->tgt_io.payload.virt;
5806 memset(inq, 0,
sizeof(*inq));
5812 xfer_len =
sizeof(*inq) + (p - inq->
page_codes);
5820 uint64_t serial_id, serial_len;
5821 uint8_t serial_str[16];
5823 inq = io->tgt_io.payload.virt;
5824 memset(inq, 0,
sizeof(*inq));
5841 serial_id = io->tgt_io.lun;
5844 if (!ocs->tgt_ocs.use_global_ramd) {
5845 if (io->node && io->node->sport) {
5846 serial_id |= (io->node->sport->instance_index << 24);
5851 serial_id |= ((uint64_t)ocs->instance_index << 32);
5854 ocs_snprintf(serial_str,
sizeof(serial_str),
"%" PRIX64, serial_id);
5855 serial_len = ocs_strlen(serial_str) + 1;
5866 xfer_len =
sizeof(*inq);
5875 uint32_t directory_id;
5877 ocs_memset(inq, 0,
sizeof(*inq));
5878 ocs_memset(pd, 0,
sizeof(*pd));
5879 ocs_memset(designator, 0,
sizeof(*designator));
5902 directory_id = io->tgt_io.lun;
5903 if (!ocs->tgt_ocs.use_global_ramd) {
5904 ocs_node_t *node = io->node;
5906 ocs_sport_t *sport = node->sport;
5907 if (sport != NULL) {
5908 directory_id |= (sport->instance_index << 24);
5919 if (first_ocs != NULL) {
5935 inq->
page_length = ocs_htobe16(
sizeof(*pd) +
sizeof(*designator));
5937 xfer_len =
sizeof(*inq) +
sizeof(*pd) +
sizeof(*designator);
5944 ocs_memset(inq, 0,
sizeof(*inq));
5948 if (io->tgt_io.ramdisc->external_dif) {
5955 xfer_len =
sizeof(*inq);
5963 ocs_memset(inq, 0,
sizeof(*inq));
5982 xfer_len =
sizeof(*inq);
5990 ocs_memset(inq, 0,
sizeof(*inq));
5997 xfer_len =
sizeof(*inq);
6008 if (xfer_len > allocation_len) {
6009 xfer_len = allocation_len;
6012 sgl[0].
addr = io->tgt_io.payload.phys;
6013 sgl[0].
len = xfer_len;
6016 io->tgt_io.is_read = TRUE;
6043 uint8_t allocation_len;
6044 static char sense_data[] = {
6045 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
6046 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6049 int sense_data_len = 18;
6053 rc = ocs_dma_alloc(io->ocs, &io->tgt_io.payload, 256, 16);
6055 ocs_log_err(NULL,
"ocs_scsi_dma_alloc failed\n");
6060 allocation_len = cdb[4];
6065 if (allocation_len == 0) {
6069 if (allocation_len < sense_data_len) {
6070 sense_data_len = allocation_len;
6073 ocs_memcpy(io->tgt_io.payload.virt, sense_data, sense_data_len);
6075 sgl[0].
addr = io->tgt_io.payload.phys;
6076 sgl[0].
len = sense_data_len;
6078 io->tgt_io.is_read = TRUE;
6131 uint32_t stub_res6_rel6 = 0;
6137 stub_res6_rel6 = ocs_strtoul(prop_buf, 0, 0);
6140 if (stub_res6_rel6 == TRUE) {
6168 uint32_t allocation_len;
6171 uint32_t lun_count = 0;
6172 uint32_t xfer_len = 0;
6176 if (io->ocs->tgt_ocs.use_global_ramd) {
6177 lun_count = io->ocs->tgt_ocs.rdisc_count;
6178 }
else if (io->node != NULL && io->node->sport != NULL) {
6179 lun_count = io->node->sport->tgt_sport.rdisc_count;
6184 allocation_len = (cdb[6] << 24) |
6192 if (allocation_len == 0) {
6196 cmd_trace(io,
"len x%x\n", allocation_len);
6198 rc = ocs_dma_alloc(io->ocs, &io->tgt_io.payload, allocation_len, 16);
6200 ocs_log_err(NULL,
"ocs_dma_alloc failed\n");
6205 param = io->tgt_io.payload.virt;
6207 *param++ = ocs_htobe32(lun_count*8);
6215 if ((allocation_len - 8) / 8 < lun_count) {
6216 lun_count = (allocation_len - 8) / 8;
6220 if (lun_count <= 256) {
6221 for (i = 0; i < lun_count; i ++) {
6222 uint8_t *p = (uint8_t*) param;
6223 ocs_memset(p, 0, 8);
6238 for (i = 0; i < lun_count; i ++) {
6239 uint8_t *p = (uint8_t*) param;
6240 ocs_memset(p, 0, 8);
6242 p[0] |= (i & 0x3F00) >> 8;
6248 xfer_len = (param - ((uint32_t*)io->tgt_io.payload.virt))*
sizeof(*param);
6250 sgl[0].
addr = io->tgt_io.payload.phys;
6251 sgl[0].
len = xfer_len;
6253 io->tgt_io.is_read = TRUE;
6288 uint16_t block_descriptor_length;
6290 uint32_t block_size = 0;
6295 payload = io->tgt_io.payload.virt;
6297 lun = io->tgt_io.lun;
6302 block_descriptor_length = payload[3];
6307 block_descriptor_length = (payload[6] << 8) | payload[7];
6308 longlba = payload[4] & 0x01;
6329 if (block_descriptor_length != 0) {
6332 block_size = (payload[12] << 24) | (payload[13] << 16)
6333 | (payload[14] << 8) | payload[15];
6336 block_size = (payload[5] << 16) | (payload[6] << 8) | payload[7];
6344 payload += block_descriptor_length;
6378 ocs_lock(&io->tgt_io.sm_lock);
6388 ocs_log_test(io->ocs,
"dataphase completed with errors %d\n", scsi_status);
6389 ocs_unlock(&io->tgt_io.sm_lock);
6390 return -scsi_status;
6392 ocs_unlock(&io->tgt_io.sm_lock);
6413 uint16_t parameter_list_length;
6417 io->tgt_io.mode_select_opcode = cdb[0];
6420 parameter_list_length = cdb[4];
6422 parameter_list_length = (cdb[7] << 8) | cdb[8];
6428 if (parameter_list_length == 0) {
6435 rc = ocs_dma_alloc(io->ocs, &io->tgt_io.payload, parameter_list_length, 16);
6437 ocs_log_err(io->ocs,
"ocs_scsi_dma_alloc failed\n");
6443 sgl.
addr = io->tgt_io.payload.phys;
6444 sgl.
len = parameter_list_length;
6451 if (io->tgt_io.first_burst_bytes >= parameter_list_length) {
6467 ocs_log_test(io->ocs,
"Failed to start data phase, rc is %d\n", rc);
6490 ocs_list_t tmf_abort_list;
6495 ocs_lock(&node->active_ios_lock);
6497 ocs_log_debug(node->ocs,
"[%s] aborting IO's\n", node->display_name);
6502 if (!io->tmf_abort && ocs_ref_get_unless_zero(&io->ref)) {
6504 io->tmf_abort = TRUE;
6509 ocs_unlock(&node->active_ios_lock);
6519 io->tmf_abort = FALSE;
6520 ocs_ref_put(&io->ref);
6543 ocs_list_t tmf_abort_list;
6548 ocs_lock(&node->active_ios_lock);
6551 ocs_log_debug(node->ocs,
"[%s] aborting IO's for lun x%x\n", node->display_name, lun);
6558 if ( (io->tgt_io.lun == lun) && !io->tmf_abort && ocs_ref_get_unless_zero(&io->ref)) {
6560 io->tmf_abort = TRUE;
6565 ocs_unlock(&node->active_ios_lock);
6572 io->tmf_abort = FALSE;
6573 ocs_ref_put(&io->ref);
6600 if (ocs->tgt_ocs.use_global_ramd) {
6601 num_luns = ocs->tgt_ocs.rdisc_count;
6603 for (i = 0; i < num_luns; i ++) {
6629 ocs_ddump_value(textbuf,
"has_first_burst",
"%d", io->tgt_io.has_first_burst);
6630 ocs_ddump_value(textbuf,
"first_burst_bytes",
"%d", io->tgt_io.first_burst_bytes);
6632 ocs_ddump_value(textbuf,
"lun_is_valid",
"%d", io->tgt_io.lun_is_valid);
6634 ocs_ddump_value(textbuf,
"io_block_count",
"%d", io->tgt_io.io_block_count);
6635 ocs_ddump_value(textbuf,
"acc_block_count",
"%d", io->tgt_io.acc_block_count);
6637 ocs_ddump_value(textbuf,
"cur_block_count",
"%d", io->tgt_io.cur_block_count);
6758 static void post_one_ua(ocs_node_t *node, uint32_t lun, uint8_t asc, uint8_t ascq) {
6762 ocs_t *ocs = node->ocs;
6765 if (lun >= node->tgt_node.num_ua_queues) {
6770 ua_queue = &node->tgt_node.ua_queues[lun];
6781 if (ua_entry->
asc == asc) {
6782 ocs_log_debug(ocs,
"Removing old entry for asc 0x%02x for node %d lun %d\n",
6783 asc, node->instance_index, lun);
6790 ua_entry = ocs_malloc(ocs,
sizeof(*ua_entry), OCS_M_NOWAIT | OCS_M_ZERO);
6791 if (ua_entry != NULL) {
6792 ua_entry->
asc = asc;
6793 ua_entry->
ascq = ascq;
6795 ocs_log_debug(ocs,
"Posted UA %02x/%02x to node %d lun %d\n", asc, ascq, node->instance_index, lun);
6797 ocs_log_err(ocs,
"UA entry allocation failed for node %d, UA is dropped\n",
6798 node->instance_index);
6828 ocs_domain_t *domain;
6833 if (ocs->tgt_ocs.use_global_ramd) {
6841 if (node != except_node) {
6858 for (i=0;i<sport->tgt_sport.rdisc_count;i++) {
6859 if (sport->tgt_sport.rdisc[i] == ramdisc) {
6862 if (node != except_node) {
6905 if (lun >= node->tgt_node.num_ua_queues) {
6910 ua_queue = &node->tgt_node.ua_queues[lun];
6921 *asc = ua_entry->
asc;
6922 *ascq = ua_entry->
ascq;
6952 if (lun >= node->tgt_node.num_ua_queues) {
6957 ua_queue = &node->tgt_node.ua_queues[lun];
6961 if ((ua_entry->
asc == asc) && (ua_entry->
ascq == ascq)) {
6963 ocs_log_debug(ocs,
"Removed UA %02x/%02x from node %d lun %d\n",
6964 asc, ascq, node->instance_index, lun);
6996 snprintf(qualifier,
sizeof(qualifier),
"%s/tgt", parent);
6999 if (ocs_strncmp(name, qualifier, strlen(qualifier)) == 0) {
7000 char *unqualified_name = name + strlen(qualifier) +1;
7003 if (ocs_strcmp(unqualified_name,
"ramdisc_size") == 0) {
7007 }
else if (ocs_strcmp(unqualified_name,
"ramdisc_blocksize") == 0) {
7011 }
else if (ocs_strcmp(unqualified_name,
"num_luns") == 0) {
7015 }
else if (ocs_strcmp(unqualified_name,
"dif_separate") == 0) {
7019 }
else if (ocs_strcmp(unqualified_name,
"p_type") == 0) {
7055 void *arg_out, uint32_t arg_out_length,
void *
object)
7064 ocs_snprintf(qualifier,
sizeof(qualifier),
"%s/tgt", parent);
7067 if (ocs_strncmp(action_name, qualifier, strlen(qualifier)) == 0) {
7068 char *unqualified_name = action_name + strlen(qualifier) +1;
7071 if (ocs_strcmp(unqualified_name,
"read_block") == 0) {
7073 arg_out, arg_out_length);
7086 char input_buffer[80];
7091 if ((arg_in == NULL) ||
7092 (arg_in_length == 0) ||
7093 (arg_out == NULL) ||
7094 (arg_out_length == 0)) {
7098 if (arg_in_length >
sizeof(input_buffer)) {
7099 arg_in_length =
sizeof(input_buffer);
7102 if (ocs_copy_from_user(input_buffer, arg_in, arg_in_length)) {
7103 ocs_log_test(ocs,
"Failed to copy addr from user\n");
7107 if (ocs_sscanf(input_buffer,
"%d:%d:%d", &tgt, &lun, &lba) != 3) {
7112 if (ramdisc == NULL) {
7118 length = arg_out_length;
7120 if (ocs_copy_to_user(arg_out, block, length)) {
7121 ocs_log_test(ocs,
"Failed to copy buffer to user\n");
7168 ocs_free(ocs, prd,
sizeof(*prd));
7194 if (prd->
tgt_id == tgt_id) {
7195 *rdisc = prd->
rdisc;
7224 port_rdisc = ocs_malloc(ocs,
sizeof(*port_rdisc), OCS_M_ZERO|OCS_M_NOWAIT);
7225 if (port_rdisc == NULL) {
7226 ocs_log_err(NULL,
"ocs_malloc failed\n");
7229 port_rdisc->
tgt_id = tgt_id;
7230 port_rdisc->
rdisc = rdisc;
7236 #if defined(OCS_INCLUDE_FC)
7278 if (ocs->holdoff_link_online == 0) {
7279 ocs_log_debug(ocs,
"Restore port ONLINE\n");
7282 ocs_log_err(ocs,
"Failed to bring port online\n");
int32_t ocs_scsi_tgt_port_online(ocs_t *ocs)
#define OCS_WATERMARK_HIGH_PCT
static int32_t ocs_ramd_data_phase_start(ocs_io_t *io)
Common code to start a SCSI data phase once the IO has been set up.
ocs_sport_t * ocs_sport_get_instance(ocs_domain_t *domain, uint32_t index)
Return a SLI port object, given an instance index.
uint32_t optimal_unmap_granularity
ocs_mgmt_functions_t ramd_mgmt_functions
int32_t ocs_hal_flush(ocs_hal_t *hal)
#define OCS_SCSI_FIRST_BURST_ERR
uint32_t disable_app_ffff
static ocs_ramd_hndlr_rtn_e ocs_ramd_complete_write_same(ocs_io_t *io)
Command completion for the SCSI WRITE SAME command.
A structure used to map a handler function to a SCSI sommand.
int32_t ocs_new_ramdisc(ocs_t *ocs, ocs_ramdisc_t *ramdisc, uint32_t block_size, uint32_t blocks_per_segment, uint64_t block_count)
Create a new ramdisc instance (LUN).
#define INQ_VPD_BLOCKS_LIMIT_PAGE_B0
static int32_t ocs_io_busy(ocs_io_t *io)
Test if IO object is busy.
A structure used to create the inquiry page 83 data.
target private ocs structure
Defines the standard sense response bits per the SCSI SPC specification.
uint8_t peripheral_device_type
#define SCSI_ASC_CAPACITY_DATA_HAS_CHANGED
int32_t ocs_scsi_tgt_io_exit(ocs_io_t *io)
Un-initialize SCSI IO.
int32_t ocs_scsi_recv_tmf(ocs_io_t *tmfio, uint32_t lun, ocs_scsi_tmf_cmd_e cmd, ocs_io_t *abortio, uint32_t flags)
Receive a TMF command IO.
int32_t ocs_scsi_tgt_del_device(ocs_t *ocs)
Tears down the target members of the ocs structure.
ocs_list_t ocs_list_link_t
uint8_t uint8_t additional_len
int32_t ocs_scsi_tgt_new_device(ocs_t *ocs)
Initializes any target fields on the ocs structure.
uint8_t nominal_form_factor
int32_t ocs_scsi_tgt_driver_init(void)
Driver-wide initialization for the target-server.
static void * __ocs_ramd_io_wait_and_complete_writesame_dataphase(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
State: Wait for the data phase to complete following a WRITE SAME command.
int32_t ocs_port_rdisc_init(ocs_t *ocs)
Initialize per port ramdisc structure.
A structure used to create the inquiry page B0 data.
void ocs_mgmt_ramd_list(ocs_textbuf_t *textbuf, void *object)
uint8_t * ocs_ramdisc_lba_address(ocs_ramdisc_t *ramdisc, uint64_t lba)
Return the address of a ramdisc logical block.
A structure used to create the inquiry page 80 data.
int32_t ocs_scsi_tgt_io_init(ocs_io_t *io)
Initialize SCSI IO.
void ocs_ramd_tgt_bounce(void(*fctn)(void *arg), void *arg, uint32_t s_id, uint32_t d_id, uint32_t ox_id)
uint16_t optimal_transfer_length_granularity
uint32_t ocs_scsi_tgt_io_state(ocs_io_t *io)
Set SCST IO state.
static void ocs_scsi_ramd_free(ocs_t *ocs, ocs_ramdisc_t ***rdisc, uint32_t *rdisc_count)
Free the memory associate with a ramdisc.
static int32_t ocs_list_empty(ocs_list_t *list)
Test if a list is empty.
T10 DIF information passed to the transport.
ocs_domain_t * ocs_domain_get_instance(ocs_t *ocs, uint32_t index)
Return a pointer to the domain, given the instance index.
#define SCSI_ASC_POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED
static int32_t ocs_ramd_abort_node_tasks(ocs_node_t *nodes, ocs_io_t *io)
Abort all tasks associated with a node.
#define SNSCODE_ABORTED_CMD
static int32_t ocs_ramd_abort_tgt_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags, void *arg)
Command abort callback.
static ocs_ramd_hndlr_rtn_e ocs_ramd_read12(ocs_io_t *io, uint8_t cdb[])
Process the SCSI READ (12) command.
static void * __ocs_ramd_io_wait_first_burst_send_resp(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
State: Wait on first burst then send response.
#define ACTIVE_IO_COUNT(ocs)
static void * __ocs_ramd_io_init(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
State: Initial IO state.
#define SNSCODEQUAL_INV_CMDIU
int32_t _scsi_io_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags, void *arg)
Response phase callback.
void ocs_scsi_tgt_count_sessions(ocs_t *ocs, uint64_t wwpn)
int32_t ocs_scsi_tgt_driver_exit(void)
Driver-wide clean-up for the target-server.
A structure used to create the inquiry page 00 data.
int32_t ocs_ramdisc_sgl(ocs_t *ocs, ocs_ramdisc_t *ramdisc, ocs_ramdisc_sgl_t *sgl, uint32_t max_sgl, uint32_t max_sge_size, uint32_t lba, uint32_t *block_count, uint32_t req_flags, uint8_t dump_buffer)
Build an SGL list for blocks in a ramdisc.
#define SCSI_VAR_CMD_SVC_ACT_WRITE_SAME32
static void * __ocs_ramd_io_wait_first_burst(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
State: Waiting for first burst data.
static void * ocs_list_get_head(ocs_list_t *list)
Return the first item in the list.
static ocs_lock_t ramd_lock
uint16_t medium_rotation_rate
static ocs_ramd_hndlr_rtn_e ocs_ramd_write32(ocs_io_t *io, uint8_t cdb[])
Process the SCSI WRITE (32) command.
static ocs_ramd_hndlr_rtn_e ocs_ramd_report_luns(ocs_io_t *io, uint8_t cdb[])
Process the SCSI REPORT LUNS command.
int32_t ocs_scsi_tgt_new_sport(ocs_sport_t *sport)
Accept a new SLI Port notification.
uint32_t sense_data_length
#define SNS_UNIT_ATTENTION
static int32_t ocs_ramd_first_burst_no_dif(ocs_io_t *io, ocs_ramdisc_t *ramdisc)
Process the first burst data without any DIF information.
static void * __ocs_ramd_io_aborting_wait_io_cmpl(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
State: Aborting IO.
ocs_ramdisc_ua_t is a collection of UNIT ATTENTION conditions
#define INQ_VPD_BLOCK_DEV_CHARS_PAGE_B1
void ocs_ramd_clear_ua(ocs_t *ocs, ocs_node_t *node, uint32_t lun, uint8_t asc, uint8_t ascq)
Clear a Unit Attention condition.
uint32_t maximum_transfer_length
static void ocs_ramd_set_dif_prot_type_fields(ocs_t *ocs, ocs_ramdisc_t *ramdisc, ocs_scsi_dif_info_t *dif_info)
Set the Disable App and reference fields based on the protection type.
A structure used to create READ CAPACITY (16) parameter data.
#define SCSI_MODE_SELECT10
uint8_t vendor_specific_extension_identifier[5]
static ocs_ramd_hndlr_rtn_e ocs_ramd_call_cmd_handler(ocs_io_t *io)
Function to call the command handler for a CDB.
static ocs_ramd_hndlr_rtn_e ocs_ramd_write_long10(ocs_io_t *io, uint8_t cdb[])
Process the SCSI WRITE LONG (10) command.
void ocs_scsi_tgt_del_domain(ocs_domain_t *domain)
Accept a domain lost notification.
static int32_t ocs_scsi_ramd_create(ocs_t *ocs, ocs_ramdisc_t ***rdisc, uint32_t *rdisc_count)
Create a RAMD (target) based on the property parameter values.
static void ocs_device_lock(ocs_t *ocs)
int32_t _ocs_scsi_recv_cmd(ocs_io_t *io, uint32_t lun, uint8_t *cdb, uint32_t cdb_len, uint32_t flags)
Receive an FCP SCSI command.
#define OCS_SCSI_DIF_OPER_PASS_THRU
static void ocs_ramd_io_free(ocs_io_t *io)
Perform ramd IO free.
static uint32_t thread_cmds
uint8_t response_data_format
static ocs_ramd_hndlr_rtn_e ocs_ramd_write_long16(ocs_io_t *io, uint8_t cdb[])
Process the SCSI WRITE LONG (16) command.
#define OCS_SCSI_LOW_LATENCY
uint32_t maximum_write_same_length_hi
generic scatter-gather list structure
void ocs_set_ramdisc_blocksize(ocs_t *ocs, ocs_ramdisc_t *ramdisc, uint32_t block_size)
Set the ramdisc block size.
static void * __ocs_ramd_io_wait_resp_compl(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
State: Wait for the response to complete.
static int32_t ocs_ramd_abort_node_tasks_lun(ocs_node_t *node, uint32_t lun, ocs_io_t *io)
Abort tasks associated with a given node and LUN.
int32_t _scsi_dataphase_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags, void *arg)
Command data phase callback.
static ocs_ramd_hndlr_rtn_e ocs_ramd_inquiry(ocs_io_t *io, uint8_t cdb[])
Process the SCSI INQUIRY command.
uint8_t uint8_t uint8_t t10_vendor_id[8]
void ocs_mgmt_start_unnumbered_section(ocs_textbuf_t *textbuf, const char *name)
Generate the beginning of an unnumbered section in a management XML document.
#define OCS_WATERMARK_LOW_PCT
static int32_t ocs_ramd_first_burst_with_dif(ocs_io_t *io, ocs_ramdisc_t *ramdisc, uint32_t data_blk_size)
Process the first burst data by adding/verifying/stripping DIF information.
int32_t ocs_scsi_del_initiator(ocs_node_t *node, ocs_scsi_del_initiator_reason_e reason)
Delete a SCSI initiator node.
ramdisc instance structure
A structure that contains the status and extended status fields.
#define SCSI_WRITE_SAME16
int const char const char void ocs_mgmt_emit_boolean(ocs_textbuf_t *textbuf, int access, const char *name, const int value)
Generate a property with a boolean value in a management XML document.
A structure used to create the device ID data for inquiry page 83.
int32_t ocs_ramd_get_ua(ocs_t *ocs, ocs_node_t *node, uint32_t lun, uint8_t *asc, uint8_t *ascq)
Get a pending Unit Attention, if any.
#define OCS_SCSI_CMD_DIR_OUT
static void * __ocs_ramd_io_aborting_wait_abort_cmpl(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
State: Aborting IO.
static void ocs_domain_unlock(ocs_domain_t *domain)
static ocs_ramd_hndlr_rtn_e ocs_ramd_test_unit_ready(ocs_io_t *io, uint8_t cdb[])
Process the SCSI TEST UNIT READY command.
int32_t ocs_del_ramdisc(ocs_t *ocs, ocs_ramdisc_t *ramdisc)
Delete a ramdisc instance.
#define OCS_SCSI_NO_AUTO_RESPONSE
The Designator used by inquiry page 83. This is an EUI-64 based 12-byte identifier.
ocs_scsi_del_initiator_reason_e
static ocs_ramd_hndlr_rtn_e ocs_ramd_read10(ocs_io_t *io, uint8_t cdb[])
Process the SCSI READ (10) command.
static void * ocs_list_remove(ocs_list_t *list, void *item)
Remove an item from the list.
#define SCSI_VARIABLE_LEN_CDB
static void * __ocs_ramd_io_aborting(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
State: Aborting IO.
static ocs_ramd_hndlr_rtn_e ocs_ramd_read_capacity16(ocs_io_t *io, uint8_t cdb[])
Process the SCSI READ CAPACITY (16) command.
uint8_t protection_information_length
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)
static ocs_ramd_hndlr_rtn_e ocs_ramd_write_same10(ocs_io_t *io, uint8_t cdb[])
Process the SCSI WRITE SAME (10) command.
void ocs_scsi_tgt_del_sport(ocs_sport_t *sport)
Accept a SLI Port gone notification.
#define SGL_REQ_FLAGS_PHYS
const char * ocs_sm_event_name(ocs_sm_event_t evt)
static scsi_cmd_table_t * scsi_cmd_lookup[256]
int32_t ocs_scsi_recv_cmd_common(ocs_io_t *io, uint32_t lun, uint8_t *cdb, uint32_t cdb_len, uint32_t flags, uint8_t has_first_burst, ocs_dma_t first_burst_buffers[], uint32_t first_burst_bytes)
Common code used by ocs_scsi_recv_cmd() and ocs_scsi_recv_cmd_first_burst().
uint8_t vendor_specific_parameters[0]
int32_t ocs_xport_control(ocs_xport_t *xport, ocs_xport_ctrl_e cmd,...)
Perform transport attach function.
uint32_t maximum_write_same_length_lo
#define ocs_list_init(head, type, link)
ocs_ramd_hndlr_rtn_e ocs_ramd_mode_sense10(ocs_io_t *io, uint8_t cdb[])
Process SCSI Mode Sense 10 command.
#define SCSI_VAR_CMD_SVC_ACT_WRITE32
void ocs_ramd_stop_threads(void)
static ocs_ramd_hndlr_rtn_e ocs_ramd_format_unit(ocs_io_t *io, uint8_t cdb[])
Process the SCSI FORMAT UNIT command.
#define scsi_pack_result(key, code, qualifier)
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)
ocs_ramd_hndlr_rtn_e(* handler)(ocs_io_t *io, uint8_t cdb[])
int32_t ocs_port_rdisc_save(ocs_t *ocs, uint32_t tgt_id, ocs_ramdisc_t **rdisc, uint32_t rdisc_count)
Save a per port ramdisc.
#define OCS_SCSI_IO_CMPL_RSP_SENT
#define SCSI_SERVICE_ACTION_OUT16
uint8_t product_serial_number[24]
void ocs_ramd_thread_ddump(ocs_textbuf_t *textbuf)
int32_t ocs_scsi_get_block_vaddr(ocs_io_t *io, uint64_t blocknumber, ocs_scsi_vaddr_len_t addrlen[], uint32_t max_addrlen, void **dif_vaddr)
Return address of data and DIF data given a block in the target.
#define SCSI_SERVICE_ACTION_IN16
static void * __ocs_ramd_io_common(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
State: Common IO event handler.
#define INQ_VPD_UNIT_SERIAL_NO_PAGE_80
static ocs_ramd_hndlr_rtn_e ocs_ramd_read_capacity10(ocs_io_t *io, uint8_t cdb[])
Process the SCSI READ CAPACITY (10) command.
#define SCSI_WRITE_AND_VERIFY16
void ocs_scsi_update_first_burst_transferred(ocs_io_t *io, uint32_t transferred)
Update transferred count.
uint8_t data_format_version
#define INQ_VPD_SUPPORTED_PAGE_00
A structure used to create the standard inquiry data.
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.
void ocs_ramd_post_ua(ocs_t *ocs, ocs_ramdisc_t *ramdisc, uint8_t asc, uint8_t ascq, ocs_node_t *except_node)
Post a Unit Attention condition to a ramdisc.
uint8_t lowest_aligned_lba_lsb
ocs_ramd_hndlr_rtn_e ocs_ramd_mode_sense6(ocs_io_t *io, uint8_t cdb[])
Process SCSI Mode Sense 6 command.
#define ocs_list_foreach_safe(list, item, nxt)
Iterate a linked list safely.
void ocs_mgmt_end_unnumbered_section(ocs_textbuf_t *textbuf, const char *name)
Generate the end of a section in a management XML document.
uint32_t maximum_prefetch_xdread_xdwrite_transfer_length
static void * __ocs_ramd_tmf_wait_resp_cmpl(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
State: Wait for the TMF response to complete.
static void ocs_device_unlock(ocs_t *ocs)
generic ramdisc scatter-gather list
#define SCSI_WRITE_SAME10
#define io_printf(io, fmt,...)
#define OCS_SCSI_LAST_DATAPHASE
ocs_ramdisc_t * ocs_ramd_lookup_by_tgt(ocs_t *ocs, uint32_t tgt, uint32_t lun)
Given an TGT number and a LUN number, return the corresponding ramdisc.
static ocs_ramd_hndlr_rtn_e ocs_ramd_read6(ocs_io_t *io, uint8_t cdb[])
Process the SCSI READ (6) command.
int32_t ocs_ramd_start_threads(uint32_t threading_mode, uint32_t arg_thread_cmds)
#define SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED
static scsi_cmd_table_t scsi_cmd_table_variable_len_cdb[]
#define INQ_VPD_DEVICE_ID_PAGE_83
static ocs_ramd_hndlr_rtn_e ocs_ramd_read_common(ocs_io_t *io, uint64_t lba, uint32_t block_count, uint8_t rdprotect, uint32_t app_tag, uint32_t ref_tag)
Common code used for all SCSI READ commands.
#define OCS_SCSI_FIRST_BURST_ABORTED
#define SCSI_VAR_CMD_SVC_ACT_WRITE_VERIFY32
static ocs_ramd_hndlr_rtn_e ocs_ramd_read_long10(ocs_io_t *io, uint8_t cdb[])
Process the SCSI READ LONG (10) command.
#define INQ_VPD_EXT_INQ_DATA_PAGE_86
int32_t ocs_scsi_tgt_new_domain(ocs_domain_t *domain)
Accept a new domain notification.
#define SCSI_REQUEST_SENSE
static ocs_ramd_hndlr_rtn_e ocs_ramd_read16(ocs_io_t *io, uint8_t cdb[])
Process the SCSI READ (16) command.
#define OCS_SCSI_WQ_CLASS(x)
#define SCSI_MODE_SENSE10
int32_t ocs_scsi_new_initiator(ocs_node_t *node)
Receive notification of a new SCSI initiator node.
static int32_t scsi_format_unit_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags, void *arg)
Command data phase callback for the FORMAT UNIT command.
dif_t * ocs_ramdisc_dif_address(ocs_ramdisc_t *ramdisc, uint64_t lba)
Return the address of the DIF block if protection is enabled.
static void ocs_ignore_abort_evt(ocs_sm_event_t evt, const char *func, ocs_io_t *io, ocs_io_t *tmfio)
Ignore abort event.
static void * __ocs_ramd_io_wait_dataphase_compl(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
State: Wait for the data phase to complete.
#define OCS_LOG_ENABLE_Q_FULL_BUSY_MSG(ocs)
uint32_t disable_app_ref_ffff
uint8_t peripheral_qualifier
#define SNSCODE_INV_CMDIU
#define SCSI_TEST_UNIT_READY
static ocs_ramd_hndlr_rtn_e ocs_ramd_mode_select(ocs_io_t *io, uint8_t cdb[])
Process the SCSI MODE SELECT command.
void ocs_sm_transition(ocs_sm_ctx_t *ctx, ocs_sm_function_t state, void *data)
Transition to a new state.
static ocs_ramd_hndlr_rtn_e ocs_ramd_read_long_common(ocs_io_t *io, uint64_t lba, uint16_t xfer_len, uint8_t pblock, uint8_t corrct)
Common code used for all SCSI READ commands.
#define SCSI_WRITE_LONG10
ocs_ramdisc_t * ocs_ramd_lookup(ocs_io_t *io, uint32_t lun)
Given an IO and a LUN number, return the ramdisc to which the IO is directed.
void ocs_mgmt_ramd_get_all(ocs_textbuf_t *textbuf, void *object)
ocs_t * ocs_get_instance(uint32_t index)
return pointer to ocs structure given instance index
#define SCSI_WRITE_AND_VERIFY10
static void ocs_sport_lock(ocs_sport_t *sport)
#define SCSI_ASC_REPORTED_LUNS_DATA_HAS_CHANGED
#define OCS_RAMD_MIN_SIZE
int32_t scsi_io_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags, void *arg)
ocs_mgmt_get_list_handler get_list_handler
#define OCS_CTRLMASK_TGT_ALWAYS_VERIFY_DIF
static ocs_ramd_hndlr_rtn_e ocs_ramd_write_long_common(ocs_io_t *io, uint64_t lba, uint16_t xfer_len, uint8_t cor_dis, uint8_t wr_uncor, uint8_t pblock)
Common code for all SCSI WRITE LONG commands.
#define SCSI_STATUS_TASK_SET_FULL
static ocs_ramd_hndlr_rtn_e ocs_ramd_write_same32(ocs_io_t *io, uint8_t cdb[])
Process the SCSI WRITE SAME (32) command.
#define SCSI_SVC_ACTION16_WRITE_LONG
void ocs_scsi_tgt_cancel_io(ocs_t *ocs)
#define SCSI_MODE_SELECT6
#define SCSI_SVC_ACTION16_READ_LONG
int ocs_sm_post_event(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *data)
Post an event to a context.
static ocs_ramdisc_t ** ocs_ramd
static void ocs_list_add_tail(ocs_list_t *list, void *item)
Add an item to the tail of the list.
static ocs_ramd_hndlr_rtn_e ocs_ramd_write_same16(ocs_io_t *io, uint8_t cdb[])
Process the SCSI WRITE SAME (16) command.
static void * __ocs_ramd_io_wait_and_validate_dataphase(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
State: Wait for the data phase to complete, then validate the received data.
uint8_t designator_length
ocs_ramd_hndlr_rtn_e ocs_ramd_check_cond(ocs_io_t *io, uint8_t sense_key, uint8_t asc, uint8_t ascq)
Send a SCSI check condition.
A structure used to create the READ CAPACITY (10) parameter data.
#define SCSI_WRITE_AND_VERIFY12
void ocs_scsi_tgt_ddump(ocs_textbuf_t *textbuf, ocs_scsi_ddump_type_e type, void *obj)
uint32_t unmap_granularity_alignment
static ocs_ramd_hndlr_rtn_e ocs_ramd_read_long16(ocs_io_t *io, uint8_t cdb[])
Process the SCSI READ LONG (16) command.
static void post_one_ua(ocs_node_t *node, uint32_t lun, uint8_t asc, uint8_t ascq)
Post a Unit Attention condition to a node/LUN (I_T nexus).
#define SCSI_VAR_CMD_SVC_ACT_READ32
#define cmd_trace(io, fmt,...)
#define OCS_SCSI_CMD_DIR_IN
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 ocs_ramd_hndlr_rtn_e ocs_ramd_write16(ocs_io_t *io, uint8_t cdb[])
Process the SCSI WRITE (16) command.
uint32_t maximum_unmap_block_descriptor_count
static void ocs_domain_lock(ocs_domain_t *domain)
static int32_t ocs_ramd_io_error(ocs_io_t *io, ocs_scsi_io_status_e scsi_status)
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.
static ocs_ramd_hndlr_rtn_e ocs_ramd_reserve_release(ocs_io_t *io, uint8_t cdb[])
Process the SCSI RESERVE or RELEASE command.
#define OCS_SCSI_DIF_OPER_INSERT
static int32_t ocs_ramd_tgt_abort_rsp_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags, void *arg)
Abort response callback.
#define SCSI_SVC_ACTION16_READ_CAPACITY
static int32_t ocs_ramd_first_burst_local(ocs_io_t *io, uint32_t bytes_left)
Process first burst data into the IO DMA memory.
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.
void ocs_port_rdisc_free(ocs_t *ocs)
Free per port ramdisc structure.
#define OCS_IO_WATERMARK_PER_INITIATOR
ocs_atomic_t watermark_hit
void ocs_scsi_tgt_sess_del_wait(ocs_sport_t *sport)
int32_t ocs_scsi_validate_initiator(ocs_node_t *node)
Validate a new initiator.
uint8_t supportedVPDPageList[]
static void ocs_ramd_abort_cleanup(ocs_io_t *io)
State: Cleanup aborted IO.
int32_t ocs_get_property(const char *prop_name, char *buffer, uint32_t buffer_len)
get driver wide property value
Vendor specific inquiry data for External DIF.
int32_t ocs_format_ramdisc(ocs_t *ocs, ocs_ramdisc_t *ramdisc, uint32_t block_size, uint8_t p_type, uint8_t prot_en, uint8_t dif_separate)
Reformat an existing ramdisc, possibly the changing block size and/or protection. ...
int ocs_mgmt_ramd_get(ocs_textbuf_t *textbuf, char *parent, char *name, void *object)
static void * __ocs_ramd_io_init_err_injection(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
State: Initial IO state with error injection enabled.
uint8_t uint8_t maximum_compare_and_write_length
ocs_ramdisc_ua_t represents a single UNIT ATTENTION condition
#define ocs_assert(cond,...)
uint32_t maximum_unmap_lba_count
static ocs_ramd_hndlr_rtn_e ocs_ramd_write_common(ocs_io_t *io, uint64_t lba, uint32_t block_count, uint8_t wrprotect, uint32_t app_tag, uint32_t ref_tag)
Common code for all SCSI WRITE commands.
int32_t ocs_port_rdisc_find(ocs_t *ocs, uint32_t tgt_id, ocs_ramdisc_t ***rdisc, uint32_t *rdisc_count)
Find a per port ramdisc instance.
A structure used to create the inquiry page B1 data.
static scsi_cmd_table_t scsi_cmd_table_svc_in_action16[]
ocs_atomic_t io_high_watermark
ocs_atomic_t initiator_count
static int32_t scsi_mode_select_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags, void *arg)
Command data phase callback for the MODE SELECT command.
static const char * ocs_ramd_state_names[]
#define container_of(p, stype, field)
int ocs_mgmt_ramd_exec(char *parent, char *action, void *arg_in, uint32_t arg_in_length, void *arg_out, uint32_t arg_out_length, void *object)
uint16_t ocs_scsi_dif_calc_crc(const uint8_t *buffer, uint32_t size, uint16_t crc)
Calculate the T10 PI CRC guard value for a block.
#define OCS_SCSI_CALL_COMPLETE
void ocs_mgmt_emit_string(ocs_textbuf_t *textbuf, int access, const char *name, const char *value)
Generate a property with a string value in a management XML document.
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)
Send TMF response data.
#define ocs_list_foreach(list, item)
Iterate a linked list.
static void * __ocs_ramd_wait_abts_acc_cmpl(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
State: ABTS: Wait for the BA_ACC to complete.
int32_t ocs_hal_io_cancel(ocs_hal_t *hal)
int32_t ocs_scsi_recv_cmd_first_burst(ocs_io_t *io, uint32_t lun, uint8_t *cdb, uint32_t cdb_len, uint32_t flags, ocs_dma_t first_burst_buffers[], uint32_t first_burst_bytes)
Receive an FCP SCSI command with the first burst data.
uint32_t optimal_transfer_length
static int32_t ocs_mgmt_read_block(ocs_t *ocs, char *, void *, uint32_t, void *, uint32_t)
static void * __ocs_ramd_abts_wait_io_abort_resp(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
State: ABTS: Wait for the IO to be aborted, and send response.
static ocs_ramd_hndlr_rtn_e ocs_ramd_write_same_common(ocs_io_t *io, uint64_t lba, uint32_t block_count, uint8_t wrprotect, uint8_t pbdata, uint8_t lbdata, uint32_t app_tag, uint32_t ref_tag)
Common code for all SCSI WRITE SAME commands.
int32_t ocs_scsi_dif_set_blocksize(ocs_scsi_dif_info_t *dif_info, uint32_t blocksize)
Set SCSI API DIF blocksize.
static uint32_t ocs_ramd_count
#define ENABLE_BUFFER_DUMP
static ocs_ramd_hndlr_rtn_e ocs_ramd_read32(ocs_io_t *io, uint8_t cdb[])
Process the SCSI READ (32) command.
ocs_ramd_hndlr_rtn_e ocs_ramd_task_set_full_or_busy(ocs_io_t *io)
Send a SCSI task set full or busy status.
void ocs_ddump_ramdisc(ocs_textbuf_t *textbuf, ocs_ramdisc_t *ramdisc)
int32_t scsi_dataphase_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags, void *arg)
static uint32_t scsi_validate_mode_select(ocs_io_t *io)
Validate a MODE SELECT parameter list.
static scsi_cmd_table_t scsi_cmd_table_svc_out_action16[]
void * ocs_scsi_get_property_ptr(ocs_t *ocs, ocs_scsi_property_e prop)
Return a property pointer.
void ocs_sm_disable(ocs_sm_ctx_t *ctx)
Disable further state machine processing.
ocs_ramd_hndlr_rtn_e ocs_ramd_good_status(ocs_io_t *io)
Send a good SCSI status.
static ocs_ramd_hndlr_rtn_e ocs_ramd_request_sense(ocs_io_t *io, uint8_t cdb[])
Process the SCSI REQUEST SENSE command.
static uint32_t scsi_validate_format_unit(ocs_io_t *io)
Validate a FORMAT UNIT parameter list.
static ocs_ramd_hndlr_rtn_e ocs_ramd_write6(ocs_io_t *io, uint8_t cdb[])
Process the SCSI WRITE (6) command.
ocs_scsi_dif_oper_e dif_oper
static void ocs_sport_unlock(ocs_sport_t *sport)
static scsi_cmd_table_t scsi_cmd_table[]
static ocs_ramd_hndlr_rtn_e ocs_ramd_write12(ocs_io_t *io, uint8_t cdb[])
Process the SCSI WRITE (12) command.
uint8_t additional_sense_length
static ocs_ramd_hndlr_rtn_e ocs_ramd_write10(ocs_io_t *io, uint8_t cdb[])
Process the SCSI WRITE (10) command.
void ocs_mgmt_emit_property_name(ocs_textbuf_t *textbuf, int access, const char *name)
Generate a property, with no value, in a management XML document.
uint32_t ocs_scsi_get_property(ocs_t *ocs, ocs_scsi_property_e prop)
Return SCSI API integer valued property.
uint8_t product_revision_level[4]
void ocs_ddump_value(ocs_textbuf_t *textbuf, const char *name, const char *fmt,...)
Generate driver dump data for a given value.
static ocs_ramd_hndlr_rtn_e ocs_ramd_init_write_dif(ocs_io_t *io, ocs_scsi_dif_info_t *dif_info, uint8_t wrprotect, uint32_t app_tag, uint32_t ref_tag)
void ocs_scsi_io_complete(ocs_io_t *io)
Notify the base driver that the IO is complete.
#define OCS_SCSI_DIF_OPER_STRIP
#define SCSI_READ_CAPACITY10
A structure used to create the inquiry page 86 data.