diff options
author | Jiri Kosina <jkosina@suse.cz> | 2013-01-29 04:48:30 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2013-01-29 04:48:30 -0500 |
commit | 617677295b53a40d0e54aac4cbbc216ffbc755dd (patch) | |
tree | 51b9e87213243ed5efff252c8e8d8fec4eebc588 /drivers/target | |
parent | 5c8d1b68e01a144813e38795fe6dbe7ebb506131 (diff) | |
parent | 6abb7c25775b7fb2225ad0508236d63ca710e65f (diff) |
Merge branch 'master' into for-next
Conflicts:
drivers/devfreq/exynos4_bus.c
Sync with Linus' tree to be able to apply patches that are
against newer code (mvneta).
Diffstat (limited to 'drivers/target')
42 files changed, 2733 insertions, 3712 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index d6ce2182e672..339f97f7085b 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -735,7 +735,7 @@ static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn) | |||
735 | list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) { | 735 | list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) { |
736 | spin_lock(&cmd->istate_lock); | 736 | spin_lock(&cmd->istate_lock); |
737 | if ((cmd->i_state == ISTATE_SENT_STATUS) && | 737 | if ((cmd->i_state == ISTATE_SENT_STATUS) && |
738 | (cmd->stat_sn < exp_statsn)) { | 738 | iscsi_sna_lt(cmd->stat_sn, exp_statsn)) { |
739 | cmd->i_state = ISTATE_REMOVE; | 739 | cmd->i_state = ISTATE_REMOVE; |
740 | spin_unlock(&cmd->istate_lock); | 740 | spin_unlock(&cmd->istate_lock); |
741 | iscsit_add_cmd_to_immediate_queue(cmd, conn, | 741 | iscsit_add_cmd_to_immediate_queue(cmd, conn, |
@@ -767,9 +767,8 @@ static int iscsit_handle_scsi_cmd( | |||
767 | struct iscsi_conn *conn, | 767 | struct iscsi_conn *conn, |
768 | unsigned char *buf) | 768 | unsigned char *buf) |
769 | { | 769 | { |
770 | int data_direction, cmdsn_ret = 0, immed_ret, ret, transport_ret; | 770 | int data_direction, payload_length, cmdsn_ret = 0, immed_ret; |
771 | int dump_immediate_data = 0, send_check_condition = 0, payload_length; | 771 | struct iscsi_cmd *cmd = NULL; |
772 | struct iscsi_cmd *cmd = NULL; | ||
773 | struct iscsi_scsi_req *hdr; | 772 | struct iscsi_scsi_req *hdr; |
774 | int iscsi_task_attr; | 773 | int iscsi_task_attr; |
775 | int sam_task_attr; | 774 | int sam_task_attr; |
@@ -956,38 +955,26 @@ done: | |||
956 | " ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt, | 955 | " ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt, |
957 | hdr->cmdsn, hdr->data_length, payload_length, conn->cid); | 956 | hdr->cmdsn, hdr->data_length, payload_length, conn->cid); |
958 | 957 | ||
959 | /* | 958 | cmd->sense_reason = transport_lookup_cmd_lun(&cmd->se_cmd, |
960 | * The CDB is going to an se_device_t. | 959 | scsilun_to_int(&hdr->lun)); |
961 | */ | 960 | if (cmd->sense_reason) |
962 | ret = transport_lookup_cmd_lun(&cmd->se_cmd, | 961 | goto attach_cmd; |
963 | scsilun_to_int(&hdr->lun)); | 962 | |
964 | if (ret < 0) { | 963 | cmd->sense_reason = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb); |
965 | if (cmd->se_cmd.scsi_sense_reason == TCM_NON_EXISTENT_LUN) { | 964 | if (cmd->sense_reason) { |
966 | pr_debug("Responding to non-acl'ed," | 965 | if (cmd->sense_reason == TCM_OUT_OF_RESOURCES) { |
967 | " non-existent or non-exported iSCSI LUN:" | 966 | return iscsit_add_reject_from_cmd( |
968 | " 0x%016Lx\n", get_unaligned_le64(&hdr->lun)); | 967 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, |
968 | 1, 1, buf, cmd); | ||
969 | } | 969 | } |
970 | send_check_condition = 1; | 970 | |
971 | goto attach_cmd; | 971 | goto attach_cmd; |
972 | } | 972 | } |
973 | 973 | ||
974 | transport_ret = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb); | 974 | if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0) { |
975 | if (transport_ret == -ENOMEM) { | ||
976 | return iscsit_add_reject_from_cmd( | 975 | return iscsit_add_reject_from_cmd( |
977 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 976 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, |
978 | 1, 1, buf, cmd); | 977 | 1, 1, buf, cmd); |
979 | } else if (transport_ret < 0) { | ||
980 | /* | ||
981 | * Unsupported SAM Opcode. CHECK_CONDITION will be sent | ||
982 | * in iscsit_execute_cmd() during the CmdSN OOO Execution | ||
983 | * Mechinism. | ||
984 | */ | ||
985 | send_check_condition = 1; | ||
986 | } else { | ||
987 | if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0) | ||
988 | return iscsit_add_reject_from_cmd( | ||
989 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | ||
990 | 1, 1, buf, cmd); | ||
991 | } | 978 | } |
992 | 979 | ||
993 | attach_cmd: | 980 | attach_cmd: |
@@ -1000,11 +987,12 @@ attach_cmd: | |||
1000 | */ | 987 | */ |
1001 | core_alua_check_nonop_delay(&cmd->se_cmd); | 988 | core_alua_check_nonop_delay(&cmd->se_cmd); |
1002 | 989 | ||
1003 | ret = iscsit_allocate_iovecs(cmd); | 990 | if (iscsit_allocate_iovecs(cmd) < 0) { |
1004 | if (ret < 0) | ||
1005 | return iscsit_add_reject_from_cmd( | 991 | return iscsit_add_reject_from_cmd( |
1006 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 992 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, |
1007 | 1, 0, buf, cmd); | 993 | 1, 0, buf, cmd); |
994 | } | ||
995 | |||
1008 | /* | 996 | /* |
1009 | * Check the CmdSN against ExpCmdSN/MaxCmdSN here if | 997 | * Check the CmdSN against ExpCmdSN/MaxCmdSN here if |
1010 | * the Immediate Bit is not set, and no Immediate | 998 | * the Immediate Bit is not set, and no Immediate |
@@ -1031,10 +1019,7 @@ attach_cmd: | |||
1031 | * If no Immediate Data is attached, it's OK to return now. | 1019 | * If no Immediate Data is attached, it's OK to return now. |
1032 | */ | 1020 | */ |
1033 | if (!cmd->immediate_data) { | 1021 | if (!cmd->immediate_data) { |
1034 | if (send_check_condition) | 1022 | if (!cmd->sense_reason && cmd->unsolicited_data) { |
1035 | return 0; | ||
1036 | |||
1037 | if (cmd->unsolicited_data) { | ||
1038 | iscsit_set_dataout_sequence_values(cmd); | 1023 | iscsit_set_dataout_sequence_values(cmd); |
1039 | 1024 | ||
1040 | spin_lock_bh(&cmd->dataout_timeout_lock); | 1025 | spin_lock_bh(&cmd->dataout_timeout_lock); |
@@ -1050,19 +1035,17 @@ attach_cmd: | |||
1050 | * thread. They are processed in CmdSN order by | 1035 | * thread. They are processed in CmdSN order by |
1051 | * iscsit_check_received_cmdsn() below. | 1036 | * iscsit_check_received_cmdsn() below. |
1052 | */ | 1037 | */ |
1053 | if (send_check_condition) { | 1038 | if (cmd->sense_reason) { |
1054 | immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; | 1039 | immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; |
1055 | dump_immediate_data = 1; | ||
1056 | goto after_immediate_data; | 1040 | goto after_immediate_data; |
1057 | } | 1041 | } |
1058 | /* | 1042 | /* |
1059 | * Call directly into transport_generic_new_cmd() to perform | 1043 | * Call directly into transport_generic_new_cmd() to perform |
1060 | * the backend memory allocation. | 1044 | * the backend memory allocation. |
1061 | */ | 1045 | */ |
1062 | ret = transport_generic_new_cmd(&cmd->se_cmd); | 1046 | cmd->sense_reason = transport_generic_new_cmd(&cmd->se_cmd); |
1063 | if (ret < 0) { | 1047 | if (cmd->sense_reason) { |
1064 | immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; | 1048 | immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; |
1065 | dump_immediate_data = 1; | ||
1066 | goto after_immediate_data; | 1049 | goto after_immediate_data; |
1067 | } | 1050 | } |
1068 | 1051 | ||
@@ -1079,7 +1062,7 @@ after_immediate_data: | |||
1079 | * Special case for Unsupported SAM WRITE Opcodes | 1062 | * Special case for Unsupported SAM WRITE Opcodes |
1080 | * and ImmediateData=Yes. | 1063 | * and ImmediateData=Yes. |
1081 | */ | 1064 | */ |
1082 | if (dump_immediate_data) { | 1065 | if (cmd->sense_reason) { |
1083 | if (iscsit_dump_data_payload(conn, payload_length, 1) < 0) | 1066 | if (iscsit_dump_data_payload(conn, payload_length, 1) < 0) |
1084 | return -1; | 1067 | return -1; |
1085 | } else if (cmd->unsolicited_data) { | 1068 | } else if (cmd->unsolicited_data) { |
@@ -1272,8 +1255,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) | |||
1272 | spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); | 1255 | spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); |
1273 | 1256 | ||
1274 | spin_lock_irqsave(&se_cmd->t_state_lock, flags); | 1257 | spin_lock_irqsave(&se_cmd->t_state_lock, flags); |
1275 | if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) || | 1258 | if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE)) |
1276 | (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION)) | ||
1277 | dump_unsolicited_data = 1; | 1259 | dump_unsolicited_data = 1; |
1278 | spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); | 1260 | spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); |
1279 | 1261 | ||
@@ -1742,7 +1724,6 @@ static int iscsit_handle_task_mgt_cmd( | |||
1742 | ret = transport_lookup_tmr_lun(&cmd->se_cmd, | 1724 | ret = transport_lookup_tmr_lun(&cmd->se_cmd, |
1743 | scsilun_to_int(&hdr->lun)); | 1725 | scsilun_to_int(&hdr->lun)); |
1744 | if (ret < 0) { | 1726 | if (ret < 0) { |
1745 | cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1746 | se_tmr->response = ISCSI_TMF_RSP_NO_LUN; | 1727 | se_tmr->response = ISCSI_TMF_RSP_NO_LUN; |
1747 | goto attach; | 1728 | goto attach; |
1748 | } | 1729 | } |
@@ -1751,10 +1732,8 @@ static int iscsit_handle_task_mgt_cmd( | |||
1751 | switch (function) { | 1732 | switch (function) { |
1752 | case ISCSI_TM_FUNC_ABORT_TASK: | 1733 | case ISCSI_TM_FUNC_ABORT_TASK: |
1753 | se_tmr->response = iscsit_tmr_abort_task(cmd, buf); | 1734 | se_tmr->response = iscsit_tmr_abort_task(cmd, buf); |
1754 | if (se_tmr->response != ISCSI_TMF_RSP_COMPLETE) { | 1735 | if (se_tmr->response) |
1755 | cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1756 | goto attach; | 1736 | goto attach; |
1757 | } | ||
1758 | break; | 1737 | break; |
1759 | case ISCSI_TM_FUNC_ABORT_TASK_SET: | 1738 | case ISCSI_TM_FUNC_ABORT_TASK_SET: |
1760 | case ISCSI_TM_FUNC_CLEAR_ACA: | 1739 | case ISCSI_TM_FUNC_CLEAR_ACA: |
@@ -1763,14 +1742,12 @@ static int iscsit_handle_task_mgt_cmd( | |||
1763 | break; | 1742 | break; |
1764 | case ISCSI_TM_FUNC_TARGET_WARM_RESET: | 1743 | case ISCSI_TM_FUNC_TARGET_WARM_RESET: |
1765 | if (iscsit_tmr_task_warm_reset(conn, tmr_req, buf) < 0) { | 1744 | if (iscsit_tmr_task_warm_reset(conn, tmr_req, buf) < 0) { |
1766 | cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1767 | se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED; | 1745 | se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED; |
1768 | goto attach; | 1746 | goto attach; |
1769 | } | 1747 | } |
1770 | break; | 1748 | break; |
1771 | case ISCSI_TM_FUNC_TARGET_COLD_RESET: | 1749 | case ISCSI_TM_FUNC_TARGET_COLD_RESET: |
1772 | if (iscsit_tmr_task_cold_reset(conn, tmr_req, buf) < 0) { | 1750 | if (iscsit_tmr_task_cold_reset(conn, tmr_req, buf) < 0) { |
1773 | cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1774 | se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED; | 1751 | se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED; |
1775 | goto attach; | 1752 | goto attach; |
1776 | } | 1753 | } |
@@ -1781,7 +1758,7 @@ static int iscsit_handle_task_mgt_cmd( | |||
1781 | * Perform sanity checks on the ExpDataSN only if the | 1758 | * Perform sanity checks on the ExpDataSN only if the |
1782 | * TASK_REASSIGN was successful. | 1759 | * TASK_REASSIGN was successful. |
1783 | */ | 1760 | */ |
1784 | if (se_tmr->response != ISCSI_TMF_RSP_COMPLETE) | 1761 | if (se_tmr->response) |
1785 | break; | 1762 | break; |
1786 | 1763 | ||
1787 | if (iscsit_check_task_reassign_expdatasn(tmr_req, conn) < 0) | 1764 | if (iscsit_check_task_reassign_expdatasn(tmr_req, conn) < 0) |
@@ -1792,7 +1769,6 @@ static int iscsit_handle_task_mgt_cmd( | |||
1792 | default: | 1769 | default: |
1793 | pr_err("Unknown TMR function: 0x%02x, protocol" | 1770 | pr_err("Unknown TMR function: 0x%02x, protocol" |
1794 | " error.\n", function); | 1771 | " error.\n", function); |
1795 | cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1796 | se_tmr->response = ISCSI_TMF_RSP_NOT_SUPPORTED; | 1772 | se_tmr->response = ISCSI_TMF_RSP_NOT_SUPPORTED; |
1797 | goto attach; | 1773 | goto attach; |
1798 | } | 1774 | } |
@@ -2360,7 +2336,7 @@ static void iscsit_build_conn_drop_async_message(struct iscsi_conn *conn) | |||
2360 | if (!conn_p) | 2336 | if (!conn_p) |
2361 | return; | 2337 | return; |
2362 | 2338 | ||
2363 | cmd = iscsit_allocate_cmd(conn_p, GFP_KERNEL); | 2339 | cmd = iscsit_allocate_cmd(conn_p, GFP_ATOMIC); |
2364 | if (!cmd) { | 2340 | if (!cmd) { |
2365 | iscsit_dec_conn_usage_count(conn_p); | 2341 | iscsit_dec_conn_usage_count(conn_p); |
2366 | return; | 2342 | return; |
@@ -3719,7 +3695,9 @@ restart: | |||
3719 | */ | 3695 | */ |
3720 | iscsit_thread_check_cpumask(conn, current, 1); | 3696 | iscsit_thread_check_cpumask(conn, current, 1); |
3721 | 3697 | ||
3722 | schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT); | 3698 | wait_event_interruptible(conn->queues_wq, |
3699 | !iscsit_conn_all_queues_empty(conn) || | ||
3700 | ts->status == ISCSI_THREAD_SET_RESET); | ||
3723 | 3701 | ||
3724 | if ((ts->status == ISCSI_THREAD_SET_RESET) || | 3702 | if ((ts->status == ISCSI_THREAD_SET_RESET) || |
3725 | signal_pending(current)) | 3703 | signal_pending(current)) |
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index 0f03b7919d7c..78d75c8567d0 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c | |||
@@ -754,9 +754,33 @@ static ssize_t lio_target_nacl_store_cmdsn_depth( | |||
754 | 754 | ||
755 | TF_NACL_BASE_ATTR(lio_target, cmdsn_depth, S_IRUGO | S_IWUSR); | 755 | TF_NACL_BASE_ATTR(lio_target, cmdsn_depth, S_IRUGO | S_IWUSR); |
756 | 756 | ||
757 | static ssize_t lio_target_nacl_show_tag( | ||
758 | struct se_node_acl *se_nacl, | ||
759 | char *page) | ||
760 | { | ||
761 | return snprintf(page, PAGE_SIZE, "%s", se_nacl->acl_tag); | ||
762 | } | ||
763 | |||
764 | static ssize_t lio_target_nacl_store_tag( | ||
765 | struct se_node_acl *se_nacl, | ||
766 | const char *page, | ||
767 | size_t count) | ||
768 | { | ||
769 | int ret; | ||
770 | |||
771 | ret = core_tpg_set_initiator_node_tag(se_nacl->se_tpg, se_nacl, page); | ||
772 | |||
773 | if (ret < 0) | ||
774 | return ret; | ||
775 | return count; | ||
776 | } | ||
777 | |||
778 | TF_NACL_BASE_ATTR(lio_target, tag, S_IRUGO | S_IWUSR); | ||
779 | |||
757 | static struct configfs_attribute *lio_target_initiator_attrs[] = { | 780 | static struct configfs_attribute *lio_target_initiator_attrs[] = { |
758 | &lio_target_nacl_info.attr, | 781 | &lio_target_nacl_info.attr, |
759 | &lio_target_nacl_cmdsn_depth.attr, | 782 | &lio_target_nacl_cmdsn_depth.attr, |
783 | &lio_target_nacl_tag.attr, | ||
760 | NULL, | 784 | NULL, |
761 | }; | 785 | }; |
762 | 786 | ||
@@ -803,7 +827,7 @@ static struct se_node_acl *lio_target_make_nodeacl( | |||
803 | acl = container_of(se_nacl, struct iscsi_node_acl, se_node_acl); | 827 | acl = container_of(se_nacl, struct iscsi_node_acl, se_node_acl); |
804 | stats_cg = &se_nacl->acl_fabric_stat_group; | 828 | stats_cg = &se_nacl->acl_fabric_stat_group; |
805 | 829 | ||
806 | stats_cg->default_groups = kzalloc(sizeof(struct config_group) * 2, | 830 | stats_cg->default_groups = kmalloc(sizeof(struct config_group *) * 2, |
807 | GFP_KERNEL); | 831 | GFP_KERNEL); |
808 | if (!stats_cg->default_groups) { | 832 | if (!stats_cg->default_groups) { |
809 | pr_err("Unable to allocate memory for" | 833 | pr_err("Unable to allocate memory for" |
@@ -1268,7 +1292,7 @@ static struct se_wwn *lio_target_call_coreaddtiqn( | |||
1268 | */ | 1292 | */ |
1269 | stats_cg = &tiqn->tiqn_wwn.fabric_stat_group; | 1293 | stats_cg = &tiqn->tiqn_wwn.fabric_stat_group; |
1270 | 1294 | ||
1271 | stats_cg->default_groups = kzalloc(sizeof(struct config_group) * 6, | 1295 | stats_cg->default_groups = kmalloc(sizeof(struct config_group *) * 6, |
1272 | GFP_KERNEL); | 1296 | GFP_KERNEL); |
1273 | if (!stats_cg->default_groups) { | 1297 | if (!stats_cg->default_groups) { |
1274 | pr_err("Unable to allocate memory for" | 1298 | pr_err("Unable to allocate memory for" |
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index 2ba9f9b9435c..7a333d28d9a2 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h | |||
@@ -474,7 +474,7 @@ struct iscsi_cmd { | |||
474 | struct scatterlist *first_data_sg; | 474 | struct scatterlist *first_data_sg; |
475 | u32 first_data_sg_off; | 475 | u32 first_data_sg_off; |
476 | u32 kmapped_nents; | 476 | u32 kmapped_nents; |
477 | 477 | sense_reason_t sense_reason; | |
478 | } ____cacheline_aligned; | 478 | } ____cacheline_aligned; |
479 | 479 | ||
480 | struct iscsi_tmr_req { | 480 | struct iscsi_tmr_req { |
@@ -486,6 +486,7 @@ struct iscsi_tmr_req { | |||
486 | }; | 486 | }; |
487 | 487 | ||
488 | struct iscsi_conn { | 488 | struct iscsi_conn { |
489 | wait_queue_head_t queues_wq; | ||
489 | /* Authentication Successful for this connection */ | 490 | /* Authentication Successful for this connection */ |
490 | u8 auth_complete; | 491 | u8 auth_complete; |
491 | /* State connection is currently in */ | 492 | /* State connection is currently in */ |
diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c index 21f29d91a8cb..0b52a2371305 100644 --- a/drivers/target/iscsi/iscsi_target_erl1.c +++ b/drivers/target/iscsi/iscsi_target_erl1.c | |||
@@ -929,11 +929,10 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo) | |||
929 | case ISCSI_OP_SCSI_CMD: | 929 | case ISCSI_OP_SCSI_CMD: |
930 | /* | 930 | /* |
931 | * Go ahead and send the CHECK_CONDITION status for | 931 | * Go ahead and send the CHECK_CONDITION status for |
932 | * any SCSI CDB exceptions that may have occurred, also | 932 | * any SCSI CDB exceptions that may have occurred. |
933 | * handle the SCF_SCSI_RESERVATION_CONFLICT case here as well. | ||
934 | */ | 933 | */ |
935 | if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) { | 934 | if (cmd->sense_reason) { |
936 | if (se_cmd->scsi_sense_reason == TCM_RESERVATION_CONFLICT) { | 935 | if (cmd->sense_reason == TCM_RESERVATION_CONFLICT) { |
937 | cmd->i_state = ISTATE_SEND_STATUS; | 936 | cmd->i_state = ISTATE_SEND_STATUS; |
938 | spin_unlock_bh(&cmd->istate_lock); | 937 | spin_unlock_bh(&cmd->istate_lock); |
939 | iscsit_add_cmd_to_response_queue(cmd, cmd->conn, | 938 | iscsit_add_cmd_to_response_queue(cmd, cmd->conn, |
@@ -956,7 +955,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo) | |||
956 | * exception | 955 | * exception |
957 | */ | 956 | */ |
958 | return transport_send_check_condition_and_sense(se_cmd, | 957 | return transport_send_check_condition_and_sense(se_cmd, |
959 | se_cmd->scsi_sense_reason, 0); | 958 | cmd->sense_reason, 0); |
960 | } | 959 | } |
961 | /* | 960 | /* |
962 | * Special case for delayed CmdSN with Immediate | 961 | * Special case for delayed CmdSN with Immediate |
@@ -1013,7 +1012,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo) | |||
1013 | iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state); | 1012 | iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state); |
1014 | break; | 1013 | break; |
1015 | case ISCSI_OP_SCSI_TMFUNC: | 1014 | case ISCSI_OP_SCSI_TMFUNC: |
1016 | if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) { | 1015 | if (cmd->se_cmd.se_tmr_req->response) { |
1017 | spin_unlock_bh(&cmd->istate_lock); | 1016 | spin_unlock_bh(&cmd->istate_lock); |
1018 | iscsit_add_cmd_to_response_queue(cmd, cmd->conn, | 1017 | iscsit_add_cmd_to_response_queue(cmd, cmd->conn, |
1019 | cmd->i_state); | 1018 | cmd->i_state); |
diff --git a/drivers/target/iscsi/iscsi_target_erl2.c b/drivers/target/iscsi/iscsi_target_erl2.c index 17d8c20094fd..ba6091bf93fc 100644 --- a/drivers/target/iscsi/iscsi_target_erl2.c +++ b/drivers/target/iscsi/iscsi_target_erl2.c | |||
@@ -372,7 +372,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) | |||
372 | * made generic here. | 372 | * made generic here. |
373 | */ | 373 | */ |
374 | if (!(cmd->cmd_flags & ICF_OOO_CMDSN) && !cmd->immediate_cmd && | 374 | if (!(cmd->cmd_flags & ICF_OOO_CMDSN) && !cmd->immediate_cmd && |
375 | (cmd->cmd_sn >= conn->sess->exp_cmd_sn)) { | 375 | iscsi_sna_gte(cmd->cmd_sn, conn->sess->exp_cmd_sn)) { |
376 | list_del(&cmd->i_conn_node); | 376 | list_del(&cmd->i_conn_node); |
377 | spin_unlock_bh(&conn->cmd_lock); | 377 | spin_unlock_bh(&conn->cmd_lock); |
378 | iscsit_free_cmd(cmd); | 378 | iscsit_free_cmd(cmd); |
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index cdc8a10939c3..fdb632f0ab85 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c | |||
@@ -41,6 +41,7 @@ | |||
41 | 41 | ||
42 | static int iscsi_login_init_conn(struct iscsi_conn *conn) | 42 | static int iscsi_login_init_conn(struct iscsi_conn *conn) |
43 | { | 43 | { |
44 | init_waitqueue_head(&conn->queues_wq); | ||
44 | INIT_LIST_HEAD(&conn->conn_list); | 45 | INIT_LIST_HEAD(&conn->conn_list); |
45 | INIT_LIST_HEAD(&conn->conn_cmd_list); | 46 | INIT_LIST_HEAD(&conn->conn_cmd_list); |
46 | INIT_LIST_HEAD(&conn->immed_queue_list); | 47 | INIT_LIST_HEAD(&conn->immed_queue_list); |
@@ -126,13 +127,13 @@ int iscsi_check_for_session_reinstatement(struct iscsi_conn *conn) | |||
126 | 127 | ||
127 | initiatorname_param = iscsi_find_param_from_key( | 128 | initiatorname_param = iscsi_find_param_from_key( |
128 | INITIATORNAME, conn->param_list); | 129 | INITIATORNAME, conn->param_list); |
129 | if (!initiatorname_param) | ||
130 | return -1; | ||
131 | |||
132 | sessiontype_param = iscsi_find_param_from_key( | 130 | sessiontype_param = iscsi_find_param_from_key( |
133 | SESSIONTYPE, conn->param_list); | 131 | SESSIONTYPE, conn->param_list); |
134 | if (!sessiontype_param) | 132 | if (!initiatorname_param || !sessiontype_param) { |
133 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, | ||
134 | ISCSI_LOGIN_STATUS_MISSING_FIELDS); | ||
135 | return -1; | 135 | return -1; |
136 | } | ||
136 | 137 | ||
137 | sessiontype = (strncmp(sessiontype_param->value, NORMAL, 6)) ? 1 : 0; | 138 | sessiontype = (strncmp(sessiontype_param->value, NORMAL, 6)) ? 1 : 0; |
138 | 139 | ||
@@ -253,9 +254,9 @@ static int iscsi_login_zero_tsih_s1( | |||
253 | kfree(sess); | 254 | kfree(sess); |
254 | return -ENOMEM; | 255 | return -ENOMEM; |
255 | } | 256 | } |
256 | spin_lock(&sess_idr_lock); | 257 | spin_lock_bh(&sess_idr_lock); |
257 | ret = idr_get_new(&sess_idr, NULL, &sess->session_index); | 258 | ret = idr_get_new(&sess_idr, NULL, &sess->session_index); |
258 | spin_unlock(&sess_idr_lock); | 259 | spin_unlock_bh(&sess_idr_lock); |
259 | 260 | ||
260 | if (ret < 0) { | 261 | if (ret < 0) { |
261 | pr_err("idr_get_new() for sess_idr failed\n"); | 262 | pr_err("idr_get_new() for sess_idr failed\n"); |
@@ -1117,10 +1118,8 @@ new_sess_out: | |||
1117 | idr_remove(&sess_idr, conn->sess->session_index); | 1118 | idr_remove(&sess_idr, conn->sess->session_index); |
1118 | spin_unlock_bh(&sess_idr_lock); | 1119 | spin_unlock_bh(&sess_idr_lock); |
1119 | } | 1120 | } |
1120 | if (conn->sess->sess_ops) | 1121 | kfree(conn->sess->sess_ops); |
1121 | kfree(conn->sess->sess_ops); | 1122 | kfree(conn->sess); |
1122 | if (conn->sess) | ||
1123 | kfree(conn->sess); | ||
1124 | old_sess_out: | 1123 | old_sess_out: |
1125 | iscsi_stop_login_thread_timer(np); | 1124 | iscsi_stop_login_thread_timer(np); |
1126 | /* | 1125 | /* |
diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c index e9053a04f24c..9d902aefe01a 100644 --- a/drivers/target/iscsi/iscsi_target_nego.c +++ b/drivers/target/iscsi/iscsi_target_nego.c | |||
@@ -620,8 +620,11 @@ static int iscsi_target_handle_csg_one(struct iscsi_conn *conn, struct iscsi_log | |||
620 | login->req_buf, | 620 | login->req_buf, |
621 | payload_length, | 621 | payload_length, |
622 | conn); | 622 | conn); |
623 | if (ret < 0) | 623 | if (ret < 0) { |
624 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, | ||
625 | ISCSI_LOGIN_STATUS_INIT_ERR); | ||
624 | return -1; | 626 | return -1; |
627 | } | ||
625 | 628 | ||
626 | if (login->first_request) | 629 | if (login->first_request) |
627 | if (iscsi_target_check_first_request(conn, login) < 0) | 630 | if (iscsi_target_check_first_request(conn, login) < 0) |
@@ -636,8 +639,11 @@ static int iscsi_target_handle_csg_one(struct iscsi_conn *conn, struct iscsi_log | |||
636 | login->rsp_buf, | 639 | login->rsp_buf, |
637 | &login->rsp_length, | 640 | &login->rsp_length, |
638 | conn->param_list); | 641 | conn->param_list); |
639 | if (ret < 0) | 642 | if (ret < 0) { |
643 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, | ||
644 | ISCSI_LOGIN_STATUS_INIT_ERR); | ||
640 | return -1; | 645 | return -1; |
646 | } | ||
641 | 647 | ||
642 | if (!login->auth_complete && | 648 | if (!login->auth_complete && |
643 | ISCSI_TPG_ATTRIB(ISCSI_TPG_C(conn))->authentication) { | 649 | ISCSI_TPG_ATTRIB(ISCSI_TPG_C(conn))->authentication) { |
diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c index 1bf7432bfcbc..d89164287d00 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.c +++ b/drivers/target/iscsi/iscsi_target_parameters.c | |||
@@ -154,22 +154,18 @@ static struct iscsi_param *iscsi_set_default_param(struct iscsi_param_list *para | |||
154 | } | 154 | } |
155 | INIT_LIST_HEAD(¶m->p_list); | 155 | INIT_LIST_HEAD(¶m->p_list); |
156 | 156 | ||
157 | param->name = kzalloc(strlen(name) + 1, GFP_KERNEL); | 157 | param->name = kstrdup(name, GFP_KERNEL); |
158 | if (!param->name) { | 158 | if (!param->name) { |
159 | pr_err("Unable to allocate memory for parameter name.\n"); | 159 | pr_err("Unable to allocate memory for parameter name.\n"); |
160 | goto out; | 160 | goto out; |
161 | } | 161 | } |
162 | 162 | ||
163 | param->value = kzalloc(strlen(value) + 1, GFP_KERNEL); | 163 | param->value = kstrdup(value, GFP_KERNEL); |
164 | if (!param->value) { | 164 | if (!param->value) { |
165 | pr_err("Unable to allocate memory for parameter value.\n"); | 165 | pr_err("Unable to allocate memory for parameter value.\n"); |
166 | goto out; | 166 | goto out; |
167 | } | 167 | } |
168 | 168 | ||
169 | memcpy(param->name, name, strlen(name)); | ||
170 | param->name[strlen(name)] = '\0'; | ||
171 | memcpy(param->value, value, strlen(value)); | ||
172 | param->value[strlen(value)] = '\0'; | ||
173 | param->phase = phase; | 169 | param->phase = phase; |
174 | param->scope = scope; | 170 | param->scope = scope; |
175 | param->sender = sender; | 171 | param->sender = sender; |
@@ -635,11 +631,8 @@ void iscsi_release_param_list(struct iscsi_param_list *param_list) | |||
635 | list_del(¶m->p_list); | 631 | list_del(¶m->p_list); |
636 | 632 | ||
637 | kfree(param->name); | 633 | kfree(param->name); |
638 | param->name = NULL; | ||
639 | kfree(param->value); | 634 | kfree(param->value); |
640 | param->value = NULL; | ||
641 | kfree(param); | 635 | kfree(param); |
642 | param = NULL; | ||
643 | } | 636 | } |
644 | 637 | ||
645 | iscsi_release_extra_responses(param_list); | 638 | iscsi_release_extra_responses(param_list); |
@@ -687,15 +680,12 @@ int iscsi_update_param_value(struct iscsi_param *param, char *value) | |||
687 | { | 680 | { |
688 | kfree(param->value); | 681 | kfree(param->value); |
689 | 682 | ||
690 | param->value = kzalloc(strlen(value) + 1, GFP_KERNEL); | 683 | param->value = kstrdup(value, GFP_KERNEL); |
691 | if (!param->value) { | 684 | if (!param->value) { |
692 | pr_err("Unable to allocate memory for value.\n"); | 685 | pr_err("Unable to allocate memory for value.\n"); |
693 | return -ENOMEM; | 686 | return -ENOMEM; |
694 | } | 687 | } |
695 | 688 | ||
696 | memcpy(param->value, value, strlen(value)); | ||
697 | param->value[strlen(value)] = '\0'; | ||
698 | |||
699 | pr_debug("iSCSI Parameter updated to %s=%s\n", | 689 | pr_debug("iSCSI Parameter updated to %s=%s\n", |
700 | param->name, param->value); | 690 | param->name, param->value); |
701 | return 0; | 691 | return 0; |
diff --git a/drivers/target/iscsi/iscsi_target_tmr.c b/drivers/target/iscsi/iscsi_target_tmr.c index 4a99820d063b..9d4417aae921 100644 --- a/drivers/target/iscsi/iscsi_target_tmr.c +++ b/drivers/target/iscsi/iscsi_target_tmr.c | |||
@@ -50,8 +50,8 @@ u8 iscsit_tmr_abort_task( | |||
50 | if (!ref_cmd) { | 50 | if (!ref_cmd) { |
51 | pr_err("Unable to locate RefTaskTag: 0x%08x on CID:" | 51 | pr_err("Unable to locate RefTaskTag: 0x%08x on CID:" |
52 | " %hu.\n", hdr->rtt, conn->cid); | 52 | " %hu.\n", hdr->rtt, conn->cid); |
53 | return (be32_to_cpu(hdr->refcmdsn) >= conn->sess->exp_cmd_sn && | 53 | return (iscsi_sna_gte(be32_to_cpu(hdr->refcmdsn), conn->sess->exp_cmd_sn) && |
54 | be32_to_cpu(hdr->refcmdsn) <= conn->sess->max_cmd_sn) ? | 54 | iscsi_sna_lte(be32_to_cpu(hdr->refcmdsn), conn->sess->max_cmd_sn)) ? |
55 | ISCSI_TMF_RSP_COMPLETE : ISCSI_TMF_RSP_NO_TASK; | 55 | ISCSI_TMF_RSP_COMPLETE : ISCSI_TMF_RSP_NO_TASK; |
56 | } | 56 | } |
57 | if (ref_cmd->cmd_sn != be32_to_cpu(hdr->refcmdsn)) { | 57 | if (ref_cmd->cmd_sn != be32_to_cpu(hdr->refcmdsn)) { |
diff --git a/drivers/target/iscsi/iscsi_target_tq.c b/drivers/target/iscsi/iscsi_target_tq.c index 9d881a000e42..81289520f96b 100644 --- a/drivers/target/iscsi/iscsi_target_tq.c +++ b/drivers/target/iscsi/iscsi_target_tq.c | |||
@@ -66,8 +66,7 @@ static struct iscsi_thread_set *iscsi_get_ts_from_inactive_list(void) | |||
66 | return NULL; | 66 | return NULL; |
67 | } | 67 | } |
68 | 68 | ||
69 | list_for_each_entry(ts, &inactive_ts_list, ts_list) | 69 | ts = list_first_entry(&inactive_ts_list, struct iscsi_thread_set, ts_list); |
70 | break; | ||
71 | 70 | ||
72 | list_del(&ts->ts_list); | 71 | list_del(&ts->ts_list); |
73 | iscsit_global->inactive_ts--; | 72 | iscsit_global->inactive_ts--; |
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index c8dab6c7b5dc..7ce350578c82 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c | |||
@@ -488,7 +488,7 @@ void iscsit_add_cmd_to_immediate_queue( | |||
488 | atomic_set(&conn->check_immediate_queue, 1); | 488 | atomic_set(&conn->check_immediate_queue, 1); |
489 | spin_unlock_bh(&conn->immed_queue_lock); | 489 | spin_unlock_bh(&conn->immed_queue_lock); |
490 | 490 | ||
491 | wake_up_process(conn->thread_set->tx_thread); | 491 | wake_up(&conn->queues_wq); |
492 | } | 492 | } |
493 | 493 | ||
494 | struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *conn) | 494 | struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *conn) |
@@ -500,8 +500,8 @@ struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *c | |||
500 | spin_unlock_bh(&conn->immed_queue_lock); | 500 | spin_unlock_bh(&conn->immed_queue_lock); |
501 | return NULL; | 501 | return NULL; |
502 | } | 502 | } |
503 | list_for_each_entry(qr, &conn->immed_queue_list, qr_list) | 503 | qr = list_first_entry(&conn->immed_queue_list, |
504 | break; | 504 | struct iscsi_queue_req, qr_list); |
505 | 505 | ||
506 | list_del(&qr->qr_list); | 506 | list_del(&qr->qr_list); |
507 | if (qr->cmd) | 507 | if (qr->cmd) |
@@ -562,7 +562,7 @@ void iscsit_add_cmd_to_response_queue( | |||
562 | atomic_inc(&cmd->response_queue_count); | 562 | atomic_inc(&cmd->response_queue_count); |
563 | spin_unlock_bh(&conn->response_queue_lock); | 563 | spin_unlock_bh(&conn->response_queue_lock); |
564 | 564 | ||
565 | wake_up_process(conn->thread_set->tx_thread); | 565 | wake_up(&conn->queues_wq); |
566 | } | 566 | } |
567 | 567 | ||
568 | struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *conn) | 568 | struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *conn) |
@@ -575,8 +575,8 @@ struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *co | |||
575 | return NULL; | 575 | return NULL; |
576 | } | 576 | } |
577 | 577 | ||
578 | list_for_each_entry(qr, &conn->response_queue_list, qr_list) | 578 | qr = list_first_entry(&conn->response_queue_list, |
579 | break; | 579 | struct iscsi_queue_req, qr_list); |
580 | 580 | ||
581 | list_del(&qr->qr_list); | 581 | list_del(&qr->qr_list); |
582 | if (qr->cmd) | 582 | if (qr->cmd) |
@@ -616,6 +616,24 @@ static void iscsit_remove_cmd_from_response_queue( | |||
616 | } | 616 | } |
617 | } | 617 | } |
618 | 618 | ||
619 | bool iscsit_conn_all_queues_empty(struct iscsi_conn *conn) | ||
620 | { | ||
621 | bool empty; | ||
622 | |||
623 | spin_lock_bh(&conn->immed_queue_lock); | ||
624 | empty = list_empty(&conn->immed_queue_list); | ||
625 | spin_unlock_bh(&conn->immed_queue_lock); | ||
626 | |||
627 | if (!empty) | ||
628 | return empty; | ||
629 | |||
630 | spin_lock_bh(&conn->response_queue_lock); | ||
631 | empty = list_empty(&conn->response_queue_list); | ||
632 | spin_unlock_bh(&conn->response_queue_lock); | ||
633 | |||
634 | return empty; | ||
635 | } | ||
636 | |||
619 | void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn) | 637 | void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn) |
620 | { | 638 | { |
621 | struct iscsi_queue_req *qr, *qr_tmp; | 639 | struct iscsi_queue_req *qr, *qr_tmp; |
diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h index 44054bd35437..894d0f837924 100644 --- a/drivers/target/iscsi/iscsi_target_util.h +++ b/drivers/target/iscsi/iscsi_target_util.h | |||
@@ -25,6 +25,7 @@ extern struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_ | |||
25 | extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8); | 25 | extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8); |
26 | extern struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *); | 26 | extern struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *); |
27 | extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_conn *); | 27 | extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_conn *); |
28 | extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *); | ||
28 | extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *); | 29 | extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *); |
29 | extern void iscsit_release_cmd(struct iscsi_cmd *); | 30 | extern void iscsit_release_cmd(struct iscsi_cmd *); |
30 | extern void iscsit_free_cmd(struct iscsi_cmd *); | 31 | extern void iscsit_free_cmd(struct iscsi_cmd *); |
diff --git a/drivers/target/loopback/tcm_loop.h b/drivers/target/loopback/tcm_loop.h index 7b54893db665..dd7a84ee78e1 100644 --- a/drivers/target/loopback/tcm_loop.h +++ b/drivers/target/loopback/tcm_loop.h | |||
@@ -53,7 +53,6 @@ struct tcm_loop_hba { | |||
53 | struct se_hba_s *se_hba; | 53 | struct se_hba_s *se_hba; |
54 | struct se_lun *tl_hba_lun; | 54 | struct se_lun *tl_hba_lun; |
55 | struct se_port *tl_hba_lun_sep; | 55 | struct se_port *tl_hba_lun_sep; |
56 | struct se_device_s *se_dev_hba_ptr; | ||
57 | struct tcm_loop_nexus *tl_nexus; | 56 | struct tcm_loop_nexus *tl_nexus; |
58 | struct device dev; | 57 | struct device dev; |
59 | struct Scsi_Host *sh; | 58 | struct Scsi_Host *sh; |
diff --git a/drivers/target/sbp/Kconfig b/drivers/target/sbp/Kconfig index 132da544eafc..1614bc710d4e 100644 --- a/drivers/target/sbp/Kconfig +++ b/drivers/target/sbp/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config SBP_TARGET | 1 | config SBP_TARGET |
2 | tristate "FireWire SBP-2 fabric module" | 2 | tristate "FireWire SBP-2 fabric module" |
3 | depends on FIREWIRE && EXPERIMENTAL | 3 | depends on FIREWIRE |
4 | help | 4 | help |
5 | Say Y or M here to enable SCSI target functionality over FireWire. | 5 | Say Y or M here to enable SCSI target functionality over FireWire. |
6 | This enables you to expose SCSI devices to other nodes on the FireWire | 6 | This enables you to expose SCSI devices to other nodes on the FireWire |
diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index be793883413d..6917a9e938e7 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c | |||
@@ -704,16 +704,17 @@ static void session_maintenance_work(struct work_struct *work) | |||
704 | static int tgt_agent_rw_agent_state(struct fw_card *card, int tcode, void *data, | 704 | static int tgt_agent_rw_agent_state(struct fw_card *card, int tcode, void *data, |
705 | struct sbp_target_agent *agent) | 705 | struct sbp_target_agent *agent) |
706 | { | 706 | { |
707 | __be32 state; | 707 | int state; |
708 | 708 | ||
709 | switch (tcode) { | 709 | switch (tcode) { |
710 | case TCODE_READ_QUADLET_REQUEST: | 710 | case TCODE_READ_QUADLET_REQUEST: |
711 | pr_debug("tgt_agent AGENT_STATE READ\n"); | 711 | pr_debug("tgt_agent AGENT_STATE READ\n"); |
712 | 712 | ||
713 | spin_lock_bh(&agent->lock); | 713 | spin_lock_bh(&agent->lock); |
714 | state = cpu_to_be32(agent->state); | 714 | state = agent->state; |
715 | spin_unlock_bh(&agent->lock); | 715 | spin_unlock_bh(&agent->lock); |
716 | memcpy(data, &state, sizeof(state)); | 716 | |
717 | *(__be32 *)data = cpu_to_be32(state); | ||
717 | 718 | ||
718 | return RCODE_COMPLETE; | 719 | return RCODE_COMPLETE; |
719 | 720 | ||
@@ -2207,20 +2208,23 @@ static struct se_portal_group *sbp_make_tpg( | |||
2207 | tport->mgt_agt = sbp_management_agent_register(tport); | 2208 | tport->mgt_agt = sbp_management_agent_register(tport); |
2208 | if (IS_ERR(tport->mgt_agt)) { | 2209 | if (IS_ERR(tport->mgt_agt)) { |
2209 | ret = PTR_ERR(tport->mgt_agt); | 2210 | ret = PTR_ERR(tport->mgt_agt); |
2210 | kfree(tpg); | 2211 | goto out_free_tpg; |
2211 | return ERR_PTR(ret); | ||
2212 | } | 2212 | } |
2213 | 2213 | ||
2214 | ret = core_tpg_register(&sbp_fabric_configfs->tf_ops, wwn, | 2214 | ret = core_tpg_register(&sbp_fabric_configfs->tf_ops, wwn, |
2215 | &tpg->se_tpg, (void *)tpg, | 2215 | &tpg->se_tpg, (void *)tpg, |
2216 | TRANSPORT_TPG_TYPE_NORMAL); | 2216 | TRANSPORT_TPG_TYPE_NORMAL); |
2217 | if (ret < 0) { | 2217 | if (ret < 0) |
2218 | sbp_management_agent_unregister(tport->mgt_agt); | 2218 | goto out_unreg_mgt_agt; |
2219 | kfree(tpg); | ||
2220 | return ERR_PTR(ret); | ||
2221 | } | ||
2222 | 2219 | ||
2223 | return &tpg->se_tpg; | 2220 | return &tpg->se_tpg; |
2221 | |||
2222 | out_unreg_mgt_agt: | ||
2223 | sbp_management_agent_unregister(tport->mgt_agt); | ||
2224 | out_free_tpg: | ||
2225 | tport->tpg = NULL; | ||
2226 | kfree(tpg); | ||
2227 | return ERR_PTR(ret); | ||
2224 | } | 2228 | } |
2225 | 2229 | ||
2226 | static void sbp_drop_tpg(struct se_portal_group *se_tpg) | 2230 | static void sbp_drop_tpg(struct se_portal_group *se_tpg) |
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 9a5f9a7aecd2..7d4ec02e29a9 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c | |||
@@ -3,8 +3,7 @@ | |||
3 | * | 3 | * |
4 | * This file contains SPC-3 compliant asymmetric logical unit assigntment (ALUA) | 4 | * This file contains SPC-3 compliant asymmetric logical unit assigntment (ALUA) |
5 | * | 5 | * |
6 | * Copyright (c) 2009-2010 Rising Tide Systems | 6 | * (c) Copyright 2009-2012 RisingTide Systems LLC. |
7 | * Copyright (c) 2009-2010 Linux-iSCSI.org | ||
8 | * | 7 | * |
9 | * Nicholas A. Bellinger <nab@kernel.org> | 8 | * Nicholas A. Bellinger <nab@kernel.org> |
10 | * | 9 | * |
@@ -41,7 +40,7 @@ | |||
41 | #include "target_core_alua.h" | 40 | #include "target_core_alua.h" |
42 | #include "target_core_ua.h" | 41 | #include "target_core_ua.h" |
43 | 42 | ||
44 | static int core_alua_check_transition(int state, int *primary); | 43 | static sense_reason_t core_alua_check_transition(int state, int *primary); |
45 | static int core_alua_set_tg_pt_secondary_state( | 44 | static int core_alua_set_tg_pt_secondary_state( |
46 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, | 45 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, |
47 | struct se_port *port, int explict, int offline); | 46 | struct se_port *port, int explict, int offline); |
@@ -59,15 +58,17 @@ struct t10_alua_lu_gp *default_lu_gp; | |||
59 | * | 58 | * |
60 | * See spc4r17 section 6.27 | 59 | * See spc4r17 section 6.27 |
61 | */ | 60 | */ |
62 | int target_emulate_report_target_port_groups(struct se_cmd *cmd) | 61 | sense_reason_t |
62 | target_emulate_report_target_port_groups(struct se_cmd *cmd) | ||
63 | { | 63 | { |
64 | struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev; | 64 | struct se_device *dev = cmd->se_dev; |
65 | struct se_port *port; | 65 | struct se_port *port; |
66 | struct t10_alua_tg_pt_gp *tg_pt_gp; | 66 | struct t10_alua_tg_pt_gp *tg_pt_gp; |
67 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; | 67 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; |
68 | unsigned char *buf; | 68 | unsigned char *buf; |
69 | u32 rd_len = 0, off; | 69 | u32 rd_len = 0, off; |
70 | int ext_hdr = (cmd->t_task_cdb[1] & 0x20); | 70 | int ext_hdr = (cmd->t_task_cdb[1] & 0x20); |
71 | |||
71 | /* | 72 | /* |
72 | * Skip over RESERVED area to first Target port group descriptor | 73 | * Skip over RESERVED area to first Target port group descriptor |
73 | * depending on the PARAMETER DATA FORMAT type.. | 74 | * depending on the PARAMETER DATA FORMAT type.. |
@@ -81,13 +82,14 @@ int target_emulate_report_target_port_groups(struct se_cmd *cmd) | |||
81 | pr_warn("REPORT TARGET PORT GROUPS allocation length %u too" | 82 | pr_warn("REPORT TARGET PORT GROUPS allocation length %u too" |
82 | " small for %s header\n", cmd->data_length, | 83 | " small for %s header\n", cmd->data_length, |
83 | (ext_hdr) ? "extended" : "normal"); | 84 | (ext_hdr) ? "extended" : "normal"); |
84 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 85 | return TCM_INVALID_CDB_FIELD; |
85 | return -EINVAL; | ||
86 | } | 86 | } |
87 | buf = transport_kmap_data_sg(cmd); | 87 | buf = transport_kmap_data_sg(cmd); |
88 | if (!buf) | ||
89 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
88 | 90 | ||
89 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 91 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
90 | list_for_each_entry(tg_pt_gp, &su_dev->t10_alua.tg_pt_gps_list, | 92 | list_for_each_entry(tg_pt_gp, &dev->t10_alua.tg_pt_gps_list, |
91 | tg_pt_gp_list) { | 93 | tg_pt_gp_list) { |
92 | /* | 94 | /* |
93 | * Check if the Target port group and Target port descriptor list | 95 | * Check if the Target port group and Target port descriptor list |
@@ -160,7 +162,7 @@ int target_emulate_report_target_port_groups(struct se_cmd *cmd) | |||
160 | } | 162 | } |
161 | spin_unlock(&tg_pt_gp->tg_pt_gp_lock); | 163 | spin_unlock(&tg_pt_gp->tg_pt_gp_lock); |
162 | } | 164 | } |
163 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 165 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
164 | /* | 166 | /* |
165 | * Set the RETURN DATA LENGTH set in the header of the DataIN Payload | 167 | * Set the RETURN DATA LENGTH set in the header of the DataIN Payload |
166 | */ | 168 | */ |
@@ -200,32 +202,33 @@ int target_emulate_report_target_port_groups(struct se_cmd *cmd) | |||
200 | * | 202 | * |
201 | * See spc4r17 section 6.35 | 203 | * See spc4r17 section 6.35 |
202 | */ | 204 | */ |
203 | int target_emulate_set_target_port_groups(struct se_cmd *cmd) | 205 | sense_reason_t |
206 | target_emulate_set_target_port_groups(struct se_cmd *cmd) | ||
204 | { | 207 | { |
205 | struct se_device *dev = cmd->se_dev; | 208 | struct se_device *dev = cmd->se_dev; |
206 | struct se_subsystem_dev *su_dev = dev->se_sub_dev; | ||
207 | struct se_port *port, *l_port = cmd->se_lun->lun_sep; | 209 | struct se_port *port, *l_port = cmd->se_lun->lun_sep; |
208 | struct se_node_acl *nacl = cmd->se_sess->se_node_acl; | 210 | struct se_node_acl *nacl = cmd->se_sess->se_node_acl; |
209 | struct t10_alua_tg_pt_gp *tg_pt_gp = NULL, *l_tg_pt_gp; | 211 | struct t10_alua_tg_pt_gp *tg_pt_gp = NULL, *l_tg_pt_gp; |
210 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, *l_tg_pt_gp_mem; | 212 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, *l_tg_pt_gp_mem; |
211 | unsigned char *buf; | 213 | unsigned char *buf; |
212 | unsigned char *ptr; | 214 | unsigned char *ptr; |
215 | sense_reason_t rc = TCM_NO_SENSE; | ||
213 | u32 len = 4; /* Skip over RESERVED area in header */ | 216 | u32 len = 4; /* Skip over RESERVED area in header */ |
214 | int alua_access_state, primary = 0, rc; | 217 | int alua_access_state, primary = 0; |
215 | u16 tg_pt_id, rtpi; | 218 | u16 tg_pt_id, rtpi; |
216 | 219 | ||
217 | if (!l_port) { | 220 | if (!l_port) |
218 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 221 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
219 | return -EINVAL; | 222 | |
220 | } | ||
221 | if (cmd->data_length < 4) { | 223 | if (cmd->data_length < 4) { |
222 | pr_warn("SET TARGET PORT GROUPS parameter list length %u too" | 224 | pr_warn("SET TARGET PORT GROUPS parameter list length %u too" |
223 | " small\n", cmd->data_length); | 225 | " small\n", cmd->data_length); |
224 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 226 | return TCM_INVALID_PARAMETER_LIST; |
225 | return -EINVAL; | ||
226 | } | 227 | } |
227 | 228 | ||
228 | buf = transport_kmap_data_sg(cmd); | 229 | buf = transport_kmap_data_sg(cmd); |
230 | if (!buf) | ||
231 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
229 | 232 | ||
230 | /* | 233 | /* |
231 | * Determine if explict ALUA via SET_TARGET_PORT_GROUPS is allowed | 234 | * Determine if explict ALUA via SET_TARGET_PORT_GROUPS is allowed |
@@ -234,8 +237,7 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
234 | l_tg_pt_gp_mem = l_port->sep_alua_tg_pt_gp_mem; | 237 | l_tg_pt_gp_mem = l_port->sep_alua_tg_pt_gp_mem; |
235 | if (!l_tg_pt_gp_mem) { | 238 | if (!l_tg_pt_gp_mem) { |
236 | pr_err("Unable to access l_port->sep_alua_tg_pt_gp_mem\n"); | 239 | pr_err("Unable to access l_port->sep_alua_tg_pt_gp_mem\n"); |
237 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | 240 | rc = TCM_UNSUPPORTED_SCSI_OPCODE; |
238 | rc = -EINVAL; | ||
239 | goto out; | 241 | goto out; |
240 | } | 242 | } |
241 | spin_lock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); | 243 | spin_lock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); |
@@ -243,24 +245,22 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
243 | if (!l_tg_pt_gp) { | 245 | if (!l_tg_pt_gp) { |
244 | spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); | 246 | spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); |
245 | pr_err("Unable to access *l_tg_pt_gp_mem->tg_pt_gp\n"); | 247 | pr_err("Unable to access *l_tg_pt_gp_mem->tg_pt_gp\n"); |
246 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | 248 | rc = TCM_UNSUPPORTED_SCSI_OPCODE; |
247 | rc = -EINVAL; | ||
248 | goto out; | 249 | goto out; |
249 | } | 250 | } |
250 | rc = (l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA); | ||
251 | spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); | 251 | spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); |
252 | 252 | ||
253 | if (!rc) { | 253 | if (!(l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA)) { |
254 | pr_debug("Unable to process SET_TARGET_PORT_GROUPS" | 254 | pr_debug("Unable to process SET_TARGET_PORT_GROUPS" |
255 | " while TPGS_EXPLICT_ALUA is disabled\n"); | 255 | " while TPGS_EXPLICT_ALUA is disabled\n"); |
256 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | 256 | rc = TCM_UNSUPPORTED_SCSI_OPCODE; |
257 | rc = -EINVAL; | ||
258 | goto out; | 257 | goto out; |
259 | } | 258 | } |
260 | 259 | ||
261 | ptr = &buf[4]; /* Skip over RESERVED area in header */ | 260 | ptr = &buf[4]; /* Skip over RESERVED area in header */ |
262 | 261 | ||
263 | while (len < cmd->data_length) { | 262 | while (len < cmd->data_length) { |
263 | bool found = false; | ||
264 | alua_access_state = (ptr[0] & 0x0f); | 264 | alua_access_state = (ptr[0] & 0x0f); |
265 | /* | 265 | /* |
266 | * Check the received ALUA access state, and determine if | 266 | * Check the received ALUA access state, and determine if |
@@ -268,7 +268,7 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
268 | * access state. | 268 | * access state. |
269 | */ | 269 | */ |
270 | rc = core_alua_check_transition(alua_access_state, &primary); | 270 | rc = core_alua_check_transition(alua_access_state, &primary); |
271 | if (rc != 0) { | 271 | if (rc) { |
272 | /* | 272 | /* |
273 | * If the SET TARGET PORT GROUPS attempts to establish | 273 | * If the SET TARGET PORT GROUPS attempts to establish |
274 | * an invalid combination of target port asymmetric | 274 | * an invalid combination of target port asymmetric |
@@ -279,11 +279,9 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
279 | * REQUEST, and the additional sense code set to INVALID | 279 | * REQUEST, and the additional sense code set to INVALID |
280 | * FIELD IN PARAMETER LIST. | 280 | * FIELD IN PARAMETER LIST. |
281 | */ | 281 | */ |
282 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
283 | rc = -EINVAL; | ||
284 | goto out; | 282 | goto out; |
285 | } | 283 | } |
286 | rc = -1; | 284 | |
287 | /* | 285 | /* |
288 | * If the ASYMMETRIC ACCESS STATE field (see table 267) | 286 | * If the ASYMMETRIC ACCESS STATE field (see table 267) |
289 | * specifies a primary target port asymmetric access state, | 287 | * specifies a primary target port asymmetric access state, |
@@ -303,9 +301,9 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
303 | * Locate the matching target port group ID from | 301 | * Locate the matching target port group ID from |
304 | * the global tg_pt_gp list | 302 | * the global tg_pt_gp list |
305 | */ | 303 | */ |
306 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 304 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
307 | list_for_each_entry(tg_pt_gp, | 305 | list_for_each_entry(tg_pt_gp, |
308 | &su_dev->t10_alua.tg_pt_gps_list, | 306 | &dev->t10_alua.tg_pt_gps_list, |
309 | tg_pt_gp_list) { | 307 | tg_pt_gp_list) { |
310 | if (!tg_pt_gp->tg_pt_gp_valid_id) | 308 | if (!tg_pt_gp->tg_pt_gp_valid_id) |
311 | continue; | 309 | continue; |
@@ -315,27 +313,20 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
315 | 313 | ||
316 | atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt); | 314 | atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt); |
317 | smp_mb__after_atomic_inc(); | 315 | smp_mb__after_atomic_inc(); |
318 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | ||
319 | 316 | ||
320 | rc = core_alua_do_port_transition(tg_pt_gp, | 317 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
318 | |||
319 | if (!core_alua_do_port_transition(tg_pt_gp, | ||
321 | dev, l_port, nacl, | 320 | dev, l_port, nacl, |
322 | alua_access_state, 1); | 321 | alua_access_state, 1)) |
322 | found = true; | ||
323 | 323 | ||
324 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 324 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
325 | atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt); | 325 | atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt); |
326 | smp_mb__after_atomic_dec(); | 326 | smp_mb__after_atomic_dec(); |
327 | break; | 327 | break; |
328 | } | 328 | } |
329 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 329 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
330 | /* | ||
331 | * If not matching target port group ID can be located | ||
332 | * throw an exception with ASCQ: INVALID_PARAMETER_LIST | ||
333 | */ | ||
334 | if (rc != 0) { | ||
335 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
336 | rc = -EINVAL; | ||
337 | goto out; | ||
338 | } | ||
339 | } else { | 330 | } else { |
340 | /* | 331 | /* |
341 | * Extact the RELATIVE TARGET PORT IDENTIFIER to identify | 332 | * Extact the RELATIVE TARGET PORT IDENTIFIER to identify |
@@ -354,25 +345,22 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
354 | continue; | 345 | continue; |
355 | 346 | ||
356 | tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; | 347 | tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; |
348 | |||
357 | spin_unlock(&dev->se_port_lock); | 349 | spin_unlock(&dev->se_port_lock); |
358 | 350 | ||
359 | rc = core_alua_set_tg_pt_secondary_state( | 351 | if (!core_alua_set_tg_pt_secondary_state( |
360 | tg_pt_gp_mem, port, 1, 1); | 352 | tg_pt_gp_mem, port, 1, 1)) |
353 | found = true; | ||
361 | 354 | ||
362 | spin_lock(&dev->se_port_lock); | 355 | spin_lock(&dev->se_port_lock); |
363 | break; | 356 | break; |
364 | } | 357 | } |
365 | spin_unlock(&dev->se_port_lock); | 358 | spin_unlock(&dev->se_port_lock); |
366 | /* | 359 | } |
367 | * If not matching relative target port identifier can | 360 | |
368 | * be located, throw an exception with ASCQ: | 361 | if (!found) { |
369 | * INVALID_PARAMETER_LIST | 362 | rc = TCM_INVALID_PARAMETER_LIST; |
370 | */ | 363 | goto out; |
371 | if (rc != 0) { | ||
372 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
373 | rc = -EINVAL; | ||
374 | goto out; | ||
375 | } | ||
376 | } | 364 | } |
377 | 365 | ||
378 | ptr += 4; | 366 | ptr += 4; |
@@ -523,40 +511,27 @@ static inline int core_alua_state_transition( | |||
523 | } | 511 | } |
524 | 512 | ||
525 | /* | 513 | /* |
526 | * Used for alua_type SPC_ALUA_PASSTHROUGH and SPC2_ALUA_DISABLED | ||
527 | * in transport_cmd_sequencer(). This function is assigned to | ||
528 | * struct t10_alua *->state_check() in core_setup_alua() | ||
529 | */ | ||
530 | static int core_alua_state_check_nop( | ||
531 | struct se_cmd *cmd, | ||
532 | unsigned char *cdb, | ||
533 | u8 *alua_ascq) | ||
534 | { | ||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | /* | ||
539 | * Used for alua_type SPC3_ALUA_EMULATED in transport_cmd_sequencer(). | ||
540 | * This function is assigned to struct t10_alua *->state_check() in | ||
541 | * core_setup_alua() | ||
542 | * | ||
543 | * Also, this function can return three different return codes to | ||
544 | * signal transport_generic_cmd_sequencer() | ||
545 | * | ||
546 | * return 1: Is used to signal LUN not accecsable, and check condition/not ready | 514 | * return 1: Is used to signal LUN not accecsable, and check condition/not ready |
547 | * return 0: Used to signal success | 515 | * return 0: Used to signal success |
548 | * reutrn -1: Used to signal failure, and invalid cdb field | 516 | * reutrn -1: Used to signal failure, and invalid cdb field |
549 | */ | 517 | */ |
550 | static int core_alua_state_check( | 518 | sense_reason_t |
551 | struct se_cmd *cmd, | 519 | target_alua_state_check(struct se_cmd *cmd) |
552 | unsigned char *cdb, | ||
553 | u8 *alua_ascq) | ||
554 | { | 520 | { |
521 | struct se_device *dev = cmd->se_dev; | ||
522 | unsigned char *cdb = cmd->t_task_cdb; | ||
555 | struct se_lun *lun = cmd->se_lun; | 523 | struct se_lun *lun = cmd->se_lun; |
556 | struct se_port *port = lun->lun_sep; | 524 | struct se_port *port = lun->lun_sep; |
557 | struct t10_alua_tg_pt_gp *tg_pt_gp; | 525 | struct t10_alua_tg_pt_gp *tg_pt_gp; |
558 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; | 526 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; |
559 | int out_alua_state, nonop_delay_msecs; | 527 | int out_alua_state, nonop_delay_msecs; |
528 | u8 alua_ascq; | ||
529 | int ret; | ||
530 | |||
531 | if (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE) | ||
532 | return 0; | ||
533 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) | ||
534 | return 0; | ||
560 | 535 | ||
561 | if (!port) | 536 | if (!port) |
562 | return 0; | 537 | return 0; |
@@ -565,11 +540,11 @@ static int core_alua_state_check( | |||
565 | * access state: OFFLINE | 540 | * access state: OFFLINE |
566 | */ | 541 | */ |
567 | if (atomic_read(&port->sep_tg_pt_secondary_offline)) { | 542 | if (atomic_read(&port->sep_tg_pt_secondary_offline)) { |
568 | *alua_ascq = ASCQ_04H_ALUA_OFFLINE; | ||
569 | pr_debug("ALUA: Got secondary offline status for local" | 543 | pr_debug("ALUA: Got secondary offline status for local" |
570 | " target port\n"); | 544 | " target port\n"); |
571 | *alua_ascq = ASCQ_04H_ALUA_OFFLINE; | 545 | alua_ascq = ASCQ_04H_ALUA_OFFLINE; |
572 | return 1; | 546 | ret = 1; |
547 | goto out; | ||
573 | } | 548 | } |
574 | /* | 549 | /* |
575 | * Second, obtain the struct t10_alua_tg_pt_gp_member pointer to the | 550 | * Second, obtain the struct t10_alua_tg_pt_gp_member pointer to the |
@@ -594,14 +569,18 @@ static int core_alua_state_check( | |||
594 | 569 | ||
595 | switch (out_alua_state) { | 570 | switch (out_alua_state) { |
596 | case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED: | 571 | case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED: |
597 | return core_alua_state_nonoptimized(cmd, cdb, | 572 | ret = core_alua_state_nonoptimized(cmd, cdb, |
598 | nonop_delay_msecs, alua_ascq); | 573 | nonop_delay_msecs, &alua_ascq); |
574 | break; | ||
599 | case ALUA_ACCESS_STATE_STANDBY: | 575 | case ALUA_ACCESS_STATE_STANDBY: |
600 | return core_alua_state_standby(cmd, cdb, alua_ascq); | 576 | ret = core_alua_state_standby(cmd, cdb, &alua_ascq); |
577 | break; | ||
601 | case ALUA_ACCESS_STATE_UNAVAILABLE: | 578 | case ALUA_ACCESS_STATE_UNAVAILABLE: |
602 | return core_alua_state_unavailable(cmd, cdb, alua_ascq); | 579 | ret = core_alua_state_unavailable(cmd, cdb, &alua_ascq); |
580 | break; | ||
603 | case ALUA_ACCESS_STATE_TRANSITION: | 581 | case ALUA_ACCESS_STATE_TRANSITION: |
604 | return core_alua_state_transition(cmd, cdb, alua_ascq); | 582 | ret = core_alua_state_transition(cmd, cdb, &alua_ascq); |
583 | break; | ||
605 | /* | 584 | /* |
606 | * OFFLINE is a secondary ALUA target port group access state, that is | 585 | * OFFLINE is a secondary ALUA target port group access state, that is |
607 | * handled above with struct se_port->sep_tg_pt_secondary_offline=1 | 586 | * handled above with struct se_port->sep_tg_pt_secondary_offline=1 |
@@ -610,7 +589,24 @@ static int core_alua_state_check( | |||
610 | default: | 589 | default: |
611 | pr_err("Unknown ALUA access state: 0x%02x\n", | 590 | pr_err("Unknown ALUA access state: 0x%02x\n", |
612 | out_alua_state); | 591 | out_alua_state); |
613 | return -EINVAL; | 592 | return TCM_INVALID_CDB_FIELD; |
593 | } | ||
594 | |||
595 | out: | ||
596 | if (ret > 0) { | ||
597 | /* | ||
598 | * Set SCSI additional sense code (ASC) to 'LUN Not Accessible'; | ||
599 | * The ALUA additional sense code qualifier (ASCQ) is determined | ||
600 | * by the ALUA primary or secondary access state.. | ||
601 | */ | ||
602 | pr_debug("[%s]: ALUA TG Port not available, " | ||
603 | "SenseKey: NOT_READY, ASC/ASCQ: " | ||
604 | "0x04/0x%02x\n", | ||
605 | cmd->se_tfo->get_fabric_name(), alua_ascq); | ||
606 | |||
607 | cmd->scsi_asc = 0x04; | ||
608 | cmd->scsi_ascq = alua_ascq; | ||
609 | return TCM_CHECK_CONDITION_NOT_READY; | ||
614 | } | 610 | } |
615 | 611 | ||
616 | return 0; | 612 | return 0; |
@@ -619,7 +615,8 @@ static int core_alua_state_check( | |||
619 | /* | 615 | /* |
620 | * Check implict and explict ALUA state change request. | 616 | * Check implict and explict ALUA state change request. |
621 | */ | 617 | */ |
622 | static int core_alua_check_transition(int state, int *primary) | 618 | static sense_reason_t |
619 | core_alua_check_transition(int state, int *primary) | ||
623 | { | 620 | { |
624 | switch (state) { | 621 | switch (state) { |
625 | case ALUA_ACCESS_STATE_ACTIVE_OPTMIZED: | 622 | case ALUA_ACCESS_STATE_ACTIVE_OPTMIZED: |
@@ -641,7 +638,7 @@ static int core_alua_check_transition(int state, int *primary) | |||
641 | break; | 638 | break; |
642 | default: | 639 | default: |
643 | pr_err("Unknown ALUA access state: 0x%02x\n", state); | 640 | pr_err("Unknown ALUA access state: 0x%02x\n", state); |
644 | return -EINVAL; | 641 | return TCM_INVALID_PARAMETER_LIST; |
645 | } | 642 | } |
646 | 643 | ||
647 | return 0; | 644 | return 0; |
@@ -758,8 +755,7 @@ static int core_alua_update_tpg_primary_metadata( | |||
758 | int primary_state, | 755 | int primary_state, |
759 | unsigned char *md_buf) | 756 | unsigned char *md_buf) |
760 | { | 757 | { |
761 | struct se_subsystem_dev *su_dev = tg_pt_gp->tg_pt_gp_su_dev; | 758 | struct t10_wwn *wwn = &tg_pt_gp->tg_pt_gp_dev->t10_wwn; |
762 | struct t10_wwn *wwn = &su_dev->t10_wwn; | ||
763 | char path[ALUA_METADATA_PATH_LEN]; | 759 | char path[ALUA_METADATA_PATH_LEN]; |
764 | int len; | 760 | int len; |
765 | 761 | ||
@@ -899,7 +895,6 @@ int core_alua_do_port_transition( | |||
899 | { | 895 | { |
900 | struct se_device *dev; | 896 | struct se_device *dev; |
901 | struct se_port *port; | 897 | struct se_port *port; |
902 | struct se_subsystem_dev *su_dev; | ||
903 | struct se_node_acl *nacl; | 898 | struct se_node_acl *nacl; |
904 | struct t10_alua_lu_gp *lu_gp; | 899 | struct t10_alua_lu_gp *lu_gp; |
905 | struct t10_alua_lu_gp_member *lu_gp_mem, *local_lu_gp_mem; | 900 | struct t10_alua_lu_gp_member *lu_gp_mem, *local_lu_gp_mem; |
@@ -949,14 +944,13 @@ int core_alua_do_port_transition( | |||
949 | lu_gp_mem_list) { | 944 | lu_gp_mem_list) { |
950 | 945 | ||
951 | dev = lu_gp_mem->lu_gp_mem_dev; | 946 | dev = lu_gp_mem->lu_gp_mem_dev; |
952 | su_dev = dev->se_sub_dev; | ||
953 | atomic_inc(&lu_gp_mem->lu_gp_mem_ref_cnt); | 947 | atomic_inc(&lu_gp_mem->lu_gp_mem_ref_cnt); |
954 | smp_mb__after_atomic_inc(); | 948 | smp_mb__after_atomic_inc(); |
955 | spin_unlock(&lu_gp->lu_gp_lock); | 949 | spin_unlock(&lu_gp->lu_gp_lock); |
956 | 950 | ||
957 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 951 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
958 | list_for_each_entry(tg_pt_gp, | 952 | list_for_each_entry(tg_pt_gp, |
959 | &su_dev->t10_alua.tg_pt_gps_list, | 953 | &dev->t10_alua.tg_pt_gps_list, |
960 | tg_pt_gp_list) { | 954 | tg_pt_gp_list) { |
961 | 955 | ||
962 | if (!tg_pt_gp->tg_pt_gp_valid_id) | 956 | if (!tg_pt_gp->tg_pt_gp_valid_id) |
@@ -981,7 +975,7 @@ int core_alua_do_port_transition( | |||
981 | } | 975 | } |
982 | atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt); | 976 | atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt); |
983 | smp_mb__after_atomic_inc(); | 977 | smp_mb__after_atomic_inc(); |
984 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 978 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
985 | /* | 979 | /* |
986 | * core_alua_do_transition_tg_pt() will always return | 980 | * core_alua_do_transition_tg_pt() will always return |
987 | * success. | 981 | * success. |
@@ -989,11 +983,11 @@ int core_alua_do_port_transition( | |||
989 | core_alua_do_transition_tg_pt(tg_pt_gp, port, | 983 | core_alua_do_transition_tg_pt(tg_pt_gp, port, |
990 | nacl, md_buf, new_state, explict); | 984 | nacl, md_buf, new_state, explict); |
991 | 985 | ||
992 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 986 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
993 | atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt); | 987 | atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt); |
994 | smp_mb__after_atomic_dec(); | 988 | smp_mb__after_atomic_dec(); |
995 | } | 989 | } |
996 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 990 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
997 | 991 | ||
998 | spin_lock(&lu_gp->lu_gp_lock); | 992 | spin_lock(&lu_gp->lu_gp_lock); |
999 | atomic_dec(&lu_gp_mem->lu_gp_mem_ref_cnt); | 993 | atomic_dec(&lu_gp_mem->lu_gp_mem_ref_cnt); |
@@ -1268,14 +1262,9 @@ void core_alua_free_lu_gp(struct t10_alua_lu_gp *lu_gp) | |||
1268 | 1262 | ||
1269 | void core_alua_free_lu_gp_mem(struct se_device *dev) | 1263 | void core_alua_free_lu_gp_mem(struct se_device *dev) |
1270 | { | 1264 | { |
1271 | struct se_subsystem_dev *su_dev = dev->se_sub_dev; | ||
1272 | struct t10_alua *alua = &su_dev->t10_alua; | ||
1273 | struct t10_alua_lu_gp *lu_gp; | 1265 | struct t10_alua_lu_gp *lu_gp; |
1274 | struct t10_alua_lu_gp_member *lu_gp_mem; | 1266 | struct t10_alua_lu_gp_member *lu_gp_mem; |
1275 | 1267 | ||
1276 | if (alua->alua_type != SPC3_ALUA_EMULATED) | ||
1277 | return; | ||
1278 | |||
1279 | lu_gp_mem = dev->dev_alua_lu_gp_mem; | 1268 | lu_gp_mem = dev->dev_alua_lu_gp_mem; |
1280 | if (!lu_gp_mem) | 1269 | if (!lu_gp_mem) |
1281 | return; | 1270 | return; |
@@ -1358,10 +1347,8 @@ void __core_alua_drop_lu_gp_mem( | |||
1358 | spin_unlock(&lu_gp->lu_gp_lock); | 1347 | spin_unlock(&lu_gp->lu_gp_lock); |
1359 | } | 1348 | } |
1360 | 1349 | ||
1361 | struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp( | 1350 | struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(struct se_device *dev, |
1362 | struct se_subsystem_dev *su_dev, | 1351 | const char *name, int def_group) |
1363 | const char *name, | ||
1364 | int def_group) | ||
1365 | { | 1352 | { |
1366 | struct t10_alua_tg_pt_gp *tg_pt_gp; | 1353 | struct t10_alua_tg_pt_gp *tg_pt_gp; |
1367 | 1354 | ||
@@ -1375,7 +1362,7 @@ struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp( | |||
1375 | mutex_init(&tg_pt_gp->tg_pt_gp_md_mutex); | 1362 | mutex_init(&tg_pt_gp->tg_pt_gp_md_mutex); |
1376 | spin_lock_init(&tg_pt_gp->tg_pt_gp_lock); | 1363 | spin_lock_init(&tg_pt_gp->tg_pt_gp_lock); |
1377 | atomic_set(&tg_pt_gp->tg_pt_gp_ref_cnt, 0); | 1364 | atomic_set(&tg_pt_gp->tg_pt_gp_ref_cnt, 0); |
1378 | tg_pt_gp->tg_pt_gp_su_dev = su_dev; | 1365 | tg_pt_gp->tg_pt_gp_dev = dev; |
1379 | tg_pt_gp->tg_pt_gp_md_buf_len = ALUA_MD_BUF_LEN; | 1366 | tg_pt_gp->tg_pt_gp_md_buf_len = ALUA_MD_BUF_LEN; |
1380 | atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state, | 1367 | atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state, |
1381 | ALUA_ACCESS_STATE_ACTIVE_OPTMIZED); | 1368 | ALUA_ACCESS_STATE_ACTIVE_OPTMIZED); |
@@ -1392,14 +1379,14 @@ struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp( | |||
1392 | tg_pt_gp->tg_pt_gp_implict_trans_secs = ALUA_DEFAULT_IMPLICT_TRANS_SECS; | 1379 | tg_pt_gp->tg_pt_gp_implict_trans_secs = ALUA_DEFAULT_IMPLICT_TRANS_SECS; |
1393 | 1380 | ||
1394 | if (def_group) { | 1381 | if (def_group) { |
1395 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 1382 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
1396 | tg_pt_gp->tg_pt_gp_id = | 1383 | tg_pt_gp->tg_pt_gp_id = |
1397 | su_dev->t10_alua.alua_tg_pt_gps_counter++; | 1384 | dev->t10_alua.alua_tg_pt_gps_counter++; |
1398 | tg_pt_gp->tg_pt_gp_valid_id = 1; | 1385 | tg_pt_gp->tg_pt_gp_valid_id = 1; |
1399 | su_dev->t10_alua.alua_tg_pt_gps_count++; | 1386 | dev->t10_alua.alua_tg_pt_gps_count++; |
1400 | list_add_tail(&tg_pt_gp->tg_pt_gp_list, | 1387 | list_add_tail(&tg_pt_gp->tg_pt_gp_list, |
1401 | &su_dev->t10_alua.tg_pt_gps_list); | 1388 | &dev->t10_alua.tg_pt_gps_list); |
1402 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 1389 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
1403 | } | 1390 | } |
1404 | 1391 | ||
1405 | return tg_pt_gp; | 1392 | return tg_pt_gp; |
@@ -1409,9 +1396,10 @@ int core_alua_set_tg_pt_gp_id( | |||
1409 | struct t10_alua_tg_pt_gp *tg_pt_gp, | 1396 | struct t10_alua_tg_pt_gp *tg_pt_gp, |
1410 | u16 tg_pt_gp_id) | 1397 | u16 tg_pt_gp_id) |
1411 | { | 1398 | { |
1412 | struct se_subsystem_dev *su_dev = tg_pt_gp->tg_pt_gp_su_dev; | 1399 | struct se_device *dev = tg_pt_gp->tg_pt_gp_dev; |
1413 | struct t10_alua_tg_pt_gp *tg_pt_gp_tmp; | 1400 | struct t10_alua_tg_pt_gp *tg_pt_gp_tmp; |
1414 | u16 tg_pt_gp_id_tmp; | 1401 | u16 tg_pt_gp_id_tmp; |
1402 | |||
1415 | /* | 1403 | /* |
1416 | * The tg_pt_gp->tg_pt_gp_id may only be set once.. | 1404 | * The tg_pt_gp->tg_pt_gp_id may only be set once.. |
1417 | */ | 1405 | */ |
@@ -1421,19 +1409,19 @@ int core_alua_set_tg_pt_gp_id( | |||
1421 | return -EINVAL; | 1409 | return -EINVAL; |
1422 | } | 1410 | } |
1423 | 1411 | ||
1424 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 1412 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
1425 | if (su_dev->t10_alua.alua_tg_pt_gps_count == 0x0000ffff) { | 1413 | if (dev->t10_alua.alua_tg_pt_gps_count == 0x0000ffff) { |
1426 | pr_err("Maximum ALUA alua_tg_pt_gps_count:" | 1414 | pr_err("Maximum ALUA alua_tg_pt_gps_count:" |
1427 | " 0x0000ffff reached\n"); | 1415 | " 0x0000ffff reached\n"); |
1428 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 1416 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
1429 | kmem_cache_free(t10_alua_tg_pt_gp_cache, tg_pt_gp); | 1417 | kmem_cache_free(t10_alua_tg_pt_gp_cache, tg_pt_gp); |
1430 | return -ENOSPC; | 1418 | return -ENOSPC; |
1431 | } | 1419 | } |
1432 | again: | 1420 | again: |
1433 | tg_pt_gp_id_tmp = (tg_pt_gp_id != 0) ? tg_pt_gp_id : | 1421 | tg_pt_gp_id_tmp = (tg_pt_gp_id != 0) ? tg_pt_gp_id : |
1434 | su_dev->t10_alua.alua_tg_pt_gps_counter++; | 1422 | dev->t10_alua.alua_tg_pt_gps_counter++; |
1435 | 1423 | ||
1436 | list_for_each_entry(tg_pt_gp_tmp, &su_dev->t10_alua.tg_pt_gps_list, | 1424 | list_for_each_entry(tg_pt_gp_tmp, &dev->t10_alua.tg_pt_gps_list, |
1437 | tg_pt_gp_list) { | 1425 | tg_pt_gp_list) { |
1438 | if (tg_pt_gp_tmp->tg_pt_gp_id == tg_pt_gp_id_tmp) { | 1426 | if (tg_pt_gp_tmp->tg_pt_gp_id == tg_pt_gp_id_tmp) { |
1439 | if (!tg_pt_gp_id) | 1427 | if (!tg_pt_gp_id) |
@@ -1441,7 +1429,7 @@ again: | |||
1441 | 1429 | ||
1442 | pr_err("ALUA Target Port Group ID: %hu already" | 1430 | pr_err("ALUA Target Port Group ID: %hu already" |
1443 | " exists, ignoring request\n", tg_pt_gp_id); | 1431 | " exists, ignoring request\n", tg_pt_gp_id); |
1444 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 1432 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
1445 | return -EINVAL; | 1433 | return -EINVAL; |
1446 | } | 1434 | } |
1447 | } | 1435 | } |
@@ -1449,9 +1437,9 @@ again: | |||
1449 | tg_pt_gp->tg_pt_gp_id = tg_pt_gp_id_tmp; | 1437 | tg_pt_gp->tg_pt_gp_id = tg_pt_gp_id_tmp; |
1450 | tg_pt_gp->tg_pt_gp_valid_id = 1; | 1438 | tg_pt_gp->tg_pt_gp_valid_id = 1; |
1451 | list_add_tail(&tg_pt_gp->tg_pt_gp_list, | 1439 | list_add_tail(&tg_pt_gp->tg_pt_gp_list, |
1452 | &su_dev->t10_alua.tg_pt_gps_list); | 1440 | &dev->t10_alua.tg_pt_gps_list); |
1453 | su_dev->t10_alua.alua_tg_pt_gps_count++; | 1441 | dev->t10_alua.alua_tg_pt_gps_count++; |
1454 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 1442 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
1455 | 1443 | ||
1456 | return 0; | 1444 | return 0; |
1457 | } | 1445 | } |
@@ -1480,8 +1468,9 @@ struct t10_alua_tg_pt_gp_member *core_alua_allocate_tg_pt_gp_mem( | |||
1480 | void core_alua_free_tg_pt_gp( | 1468 | void core_alua_free_tg_pt_gp( |
1481 | struct t10_alua_tg_pt_gp *tg_pt_gp) | 1469 | struct t10_alua_tg_pt_gp *tg_pt_gp) |
1482 | { | 1470 | { |
1483 | struct se_subsystem_dev *su_dev = tg_pt_gp->tg_pt_gp_su_dev; | 1471 | struct se_device *dev = tg_pt_gp->tg_pt_gp_dev; |
1484 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, *tg_pt_gp_mem_tmp; | 1472 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, *tg_pt_gp_mem_tmp; |
1473 | |||
1485 | /* | 1474 | /* |
1486 | * Once we have reached this point, config_item_put() has already | 1475 | * Once we have reached this point, config_item_put() has already |
1487 | * been called from target_core_alua_drop_tg_pt_gp(). | 1476 | * been called from target_core_alua_drop_tg_pt_gp(). |
@@ -1490,10 +1479,11 @@ void core_alua_free_tg_pt_gp( | |||
1490 | * no assications *OR* explict ALUA via SET_TARGET_PORT_GROUPS | 1479 | * no assications *OR* explict ALUA via SET_TARGET_PORT_GROUPS |
1491 | * can be made while we are releasing struct t10_alua_tg_pt_gp. | 1480 | * can be made while we are releasing struct t10_alua_tg_pt_gp. |
1492 | */ | 1481 | */ |
1493 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 1482 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
1494 | list_del(&tg_pt_gp->tg_pt_gp_list); | 1483 | list_del(&tg_pt_gp->tg_pt_gp_list); |
1495 | su_dev->t10_alua.alua_tg_pt_gps_counter--; | 1484 | dev->t10_alua.alua_tg_pt_gps_counter--; |
1496 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 1485 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
1486 | |||
1497 | /* | 1487 | /* |
1498 | * Allow a struct t10_alua_tg_pt_gp_member * referenced by | 1488 | * Allow a struct t10_alua_tg_pt_gp_member * referenced by |
1499 | * core_alua_get_tg_pt_gp_by_name() in | 1489 | * core_alua_get_tg_pt_gp_by_name() in |
@@ -1502,6 +1492,7 @@ void core_alua_free_tg_pt_gp( | |||
1502 | */ | 1492 | */ |
1503 | while (atomic_read(&tg_pt_gp->tg_pt_gp_ref_cnt)) | 1493 | while (atomic_read(&tg_pt_gp->tg_pt_gp_ref_cnt)) |
1504 | cpu_relax(); | 1494 | cpu_relax(); |
1495 | |||
1505 | /* | 1496 | /* |
1506 | * Release reference to struct t10_alua_tg_pt_gp from all associated | 1497 | * Release reference to struct t10_alua_tg_pt_gp from all associated |
1507 | * struct se_port. | 1498 | * struct se_port. |
@@ -1525,9 +1516,9 @@ void core_alua_free_tg_pt_gp( | |||
1525 | * default_tg_pt_gp. | 1516 | * default_tg_pt_gp. |
1526 | */ | 1517 | */ |
1527 | spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); | 1518 | spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); |
1528 | if (tg_pt_gp != su_dev->t10_alua.default_tg_pt_gp) { | 1519 | if (tg_pt_gp != dev->t10_alua.default_tg_pt_gp) { |
1529 | __core_alua_attach_tg_pt_gp_mem(tg_pt_gp_mem, | 1520 | __core_alua_attach_tg_pt_gp_mem(tg_pt_gp_mem, |
1530 | su_dev->t10_alua.default_tg_pt_gp); | 1521 | dev->t10_alua.default_tg_pt_gp); |
1531 | } else | 1522 | } else |
1532 | tg_pt_gp_mem->tg_pt_gp = NULL; | 1523 | tg_pt_gp_mem->tg_pt_gp = NULL; |
1533 | spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); | 1524 | spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); |
@@ -1541,14 +1532,9 @@ void core_alua_free_tg_pt_gp( | |||
1541 | 1532 | ||
1542 | void core_alua_free_tg_pt_gp_mem(struct se_port *port) | 1533 | void core_alua_free_tg_pt_gp_mem(struct se_port *port) |
1543 | { | 1534 | { |
1544 | struct se_subsystem_dev *su_dev = port->sep_lun->lun_se_dev->se_sub_dev; | ||
1545 | struct t10_alua *alua = &su_dev->t10_alua; | ||
1546 | struct t10_alua_tg_pt_gp *tg_pt_gp; | 1535 | struct t10_alua_tg_pt_gp *tg_pt_gp; |
1547 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; | 1536 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; |
1548 | 1537 | ||
1549 | if (alua->alua_type != SPC3_ALUA_EMULATED) | ||
1550 | return; | ||
1551 | |||
1552 | tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; | 1538 | tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; |
1553 | if (!tg_pt_gp_mem) | 1539 | if (!tg_pt_gp_mem) |
1554 | return; | 1540 | return; |
@@ -1574,25 +1560,24 @@ void core_alua_free_tg_pt_gp_mem(struct se_port *port) | |||
1574 | } | 1560 | } |
1575 | 1561 | ||
1576 | static struct t10_alua_tg_pt_gp *core_alua_get_tg_pt_gp_by_name( | 1562 | static struct t10_alua_tg_pt_gp *core_alua_get_tg_pt_gp_by_name( |
1577 | struct se_subsystem_dev *su_dev, | 1563 | struct se_device *dev, const char *name) |
1578 | const char *name) | ||
1579 | { | 1564 | { |
1580 | struct t10_alua_tg_pt_gp *tg_pt_gp; | 1565 | struct t10_alua_tg_pt_gp *tg_pt_gp; |
1581 | struct config_item *ci; | 1566 | struct config_item *ci; |
1582 | 1567 | ||
1583 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 1568 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
1584 | list_for_each_entry(tg_pt_gp, &su_dev->t10_alua.tg_pt_gps_list, | 1569 | list_for_each_entry(tg_pt_gp, &dev->t10_alua.tg_pt_gps_list, |
1585 | tg_pt_gp_list) { | 1570 | tg_pt_gp_list) { |
1586 | if (!tg_pt_gp->tg_pt_gp_valid_id) | 1571 | if (!tg_pt_gp->tg_pt_gp_valid_id) |
1587 | continue; | 1572 | continue; |
1588 | ci = &tg_pt_gp->tg_pt_gp_group.cg_item; | 1573 | ci = &tg_pt_gp->tg_pt_gp_group.cg_item; |
1589 | if (!strcmp(config_item_name(ci), name)) { | 1574 | if (!strcmp(config_item_name(ci), name)) { |
1590 | atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt); | 1575 | atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt); |
1591 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 1576 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
1592 | return tg_pt_gp; | 1577 | return tg_pt_gp; |
1593 | } | 1578 | } |
1594 | } | 1579 | } |
1595 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 1580 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
1596 | 1581 | ||
1597 | return NULL; | 1582 | return NULL; |
1598 | } | 1583 | } |
@@ -1600,11 +1585,11 @@ static struct t10_alua_tg_pt_gp *core_alua_get_tg_pt_gp_by_name( | |||
1600 | static void core_alua_put_tg_pt_gp_from_name( | 1585 | static void core_alua_put_tg_pt_gp_from_name( |
1601 | struct t10_alua_tg_pt_gp *tg_pt_gp) | 1586 | struct t10_alua_tg_pt_gp *tg_pt_gp) |
1602 | { | 1587 | { |
1603 | struct se_subsystem_dev *su_dev = tg_pt_gp->tg_pt_gp_su_dev; | 1588 | struct se_device *dev = tg_pt_gp->tg_pt_gp_dev; |
1604 | 1589 | ||
1605 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 1590 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
1606 | atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt); | 1591 | atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt); |
1607 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 1592 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
1608 | } | 1593 | } |
1609 | 1594 | ||
1610 | /* | 1595 | /* |
@@ -1640,16 +1625,11 @@ static void __core_alua_drop_tg_pt_gp_mem( | |||
1640 | 1625 | ||
1641 | ssize_t core_alua_show_tg_pt_gp_info(struct se_port *port, char *page) | 1626 | ssize_t core_alua_show_tg_pt_gp_info(struct se_port *port, char *page) |
1642 | { | 1627 | { |
1643 | struct se_subsystem_dev *su_dev = port->sep_lun->lun_se_dev->se_sub_dev; | ||
1644 | struct config_item *tg_pt_ci; | 1628 | struct config_item *tg_pt_ci; |
1645 | struct t10_alua *alua = &su_dev->t10_alua; | ||
1646 | struct t10_alua_tg_pt_gp *tg_pt_gp; | 1629 | struct t10_alua_tg_pt_gp *tg_pt_gp; |
1647 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; | 1630 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; |
1648 | ssize_t len = 0; | 1631 | ssize_t len = 0; |
1649 | 1632 | ||
1650 | if (alua->alua_type != SPC3_ALUA_EMULATED) | ||
1651 | return len; | ||
1652 | |||
1653 | tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; | 1633 | tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; |
1654 | if (!tg_pt_gp_mem) | 1634 | if (!tg_pt_gp_mem) |
1655 | return len; | 1635 | return len; |
@@ -1683,7 +1663,7 @@ ssize_t core_alua_store_tg_pt_gp_info( | |||
1683 | { | 1663 | { |
1684 | struct se_portal_group *tpg; | 1664 | struct se_portal_group *tpg; |
1685 | struct se_lun *lun; | 1665 | struct se_lun *lun; |
1686 | struct se_subsystem_dev *su_dev = port->sep_lun->lun_se_dev->se_sub_dev; | 1666 | struct se_device *dev = port->sep_lun->lun_se_dev; |
1687 | struct t10_alua_tg_pt_gp *tg_pt_gp = NULL, *tg_pt_gp_new = NULL; | 1667 | struct t10_alua_tg_pt_gp *tg_pt_gp = NULL, *tg_pt_gp_new = NULL; |
1688 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; | 1668 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; |
1689 | unsigned char buf[TG_PT_GROUP_NAME_BUF]; | 1669 | unsigned char buf[TG_PT_GROUP_NAME_BUF]; |
@@ -1692,13 +1672,9 @@ ssize_t core_alua_store_tg_pt_gp_info( | |||
1692 | tpg = port->sep_tpg; | 1672 | tpg = port->sep_tpg; |
1693 | lun = port->sep_lun; | 1673 | lun = port->sep_lun; |
1694 | 1674 | ||
1695 | if (su_dev->t10_alua.alua_type != SPC3_ALUA_EMULATED) { | 1675 | tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; |
1696 | pr_warn("SPC3_ALUA_EMULATED not enabled for" | 1676 | if (!tg_pt_gp_mem) |
1697 | " %s/tpgt_%hu/%s\n", tpg->se_tpg_tfo->tpg_get_wwn(tpg), | 1677 | return 0; |
1698 | tpg->se_tpg_tfo->tpg_get_tag(tpg), | ||
1699 | config_item_name(&lun->lun_group.cg_item)); | ||
1700 | return -EINVAL; | ||
1701 | } | ||
1702 | 1678 | ||
1703 | if (count > TG_PT_GROUP_NAME_BUF) { | 1679 | if (count > TG_PT_GROUP_NAME_BUF) { |
1704 | pr_err("ALUA Target Port Group alias too large!\n"); | 1680 | pr_err("ALUA Target Port Group alias too large!\n"); |
@@ -1716,18 +1692,11 @@ ssize_t core_alua_store_tg_pt_gp_info( | |||
1716 | * struct t10_alua_tg_pt_gp. This reference is released with | 1692 | * struct t10_alua_tg_pt_gp. This reference is released with |
1717 | * core_alua_put_tg_pt_gp_from_name() below. | 1693 | * core_alua_put_tg_pt_gp_from_name() below. |
1718 | */ | 1694 | */ |
1719 | tg_pt_gp_new = core_alua_get_tg_pt_gp_by_name(su_dev, | 1695 | tg_pt_gp_new = core_alua_get_tg_pt_gp_by_name(dev, |
1720 | strstrip(buf)); | 1696 | strstrip(buf)); |
1721 | if (!tg_pt_gp_new) | 1697 | if (!tg_pt_gp_new) |
1722 | return -ENODEV; | 1698 | return -ENODEV; |
1723 | } | 1699 | } |
1724 | tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; | ||
1725 | if (!tg_pt_gp_mem) { | ||
1726 | if (tg_pt_gp_new) | ||
1727 | core_alua_put_tg_pt_gp_from_name(tg_pt_gp_new); | ||
1728 | pr_err("NULL struct se_port->sep_alua_tg_pt_gp_mem pointer\n"); | ||
1729 | return -EINVAL; | ||
1730 | } | ||
1731 | 1700 | ||
1732 | spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); | 1701 | spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); |
1733 | tg_pt_gp = tg_pt_gp_mem->tg_pt_gp; | 1702 | tg_pt_gp = tg_pt_gp_mem->tg_pt_gp; |
@@ -1750,7 +1719,7 @@ ssize_t core_alua_store_tg_pt_gp_info( | |||
1750 | 1719 | ||
1751 | __core_alua_drop_tg_pt_gp_mem(tg_pt_gp_mem, tg_pt_gp); | 1720 | __core_alua_drop_tg_pt_gp_mem(tg_pt_gp_mem, tg_pt_gp); |
1752 | __core_alua_attach_tg_pt_gp_mem(tg_pt_gp_mem, | 1721 | __core_alua_attach_tg_pt_gp_mem(tg_pt_gp_mem, |
1753 | su_dev->t10_alua.default_tg_pt_gp); | 1722 | dev->t10_alua.default_tg_pt_gp); |
1754 | spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); | 1723 | spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); |
1755 | 1724 | ||
1756 | return count; | 1725 | return count; |
@@ -2054,32 +2023,12 @@ ssize_t core_alua_store_secondary_write_metadata( | |||
2054 | return count; | 2023 | return count; |
2055 | } | 2024 | } |
2056 | 2025 | ||
2057 | int core_setup_alua(struct se_device *dev, int force_pt) | 2026 | int core_setup_alua(struct se_device *dev) |
2058 | { | 2027 | { |
2059 | struct se_subsystem_dev *su_dev = dev->se_sub_dev; | 2028 | if (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV && |
2060 | struct t10_alua *alua = &su_dev->t10_alua; | 2029 | !(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) { |
2061 | struct t10_alua_lu_gp_member *lu_gp_mem; | 2030 | struct t10_alua_lu_gp_member *lu_gp_mem; |
2062 | /* | 2031 | |
2063 | * If this device is from Target_Core_Mod/pSCSI, use the ALUA logic | ||
2064 | * of the Underlying SCSI hardware. In Linux/SCSI terms, this can | ||
2065 | * cause a problem because libata and some SATA RAID HBAs appear | ||
2066 | * under Linux/SCSI, but emulate SCSI logic themselves. | ||
2067 | */ | ||
2068 | if (((dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) && | ||
2069 | !(dev->se_sub_dev->se_dev_attrib.emulate_alua)) || force_pt) { | ||
2070 | alua->alua_type = SPC_ALUA_PASSTHROUGH; | ||
2071 | alua->alua_state_check = &core_alua_state_check_nop; | ||
2072 | pr_debug("%s: Using SPC_ALUA_PASSTHROUGH, no ALUA" | ||
2073 | " emulation\n", dev->transport->name); | ||
2074 | return 0; | ||
2075 | } | ||
2076 | /* | ||
2077 | * If SPC-3 or above is reported by real or emulated struct se_device, | ||
2078 | * use emulated ALUA. | ||
2079 | */ | ||
2080 | if (dev->transport->get_device_rev(dev) >= SCSI_3) { | ||
2081 | pr_debug("%s: Enabling ALUA Emulation for SPC-3" | ||
2082 | " device\n", dev->transport->name); | ||
2083 | /* | 2032 | /* |
2084 | * Associate this struct se_device with the default ALUA | 2033 | * Associate this struct se_device with the default ALUA |
2085 | * LUN Group. | 2034 | * LUN Group. |
@@ -2088,8 +2037,6 @@ int core_setup_alua(struct se_device *dev, int force_pt) | |||
2088 | if (IS_ERR(lu_gp_mem)) | 2037 | if (IS_ERR(lu_gp_mem)) |
2089 | return PTR_ERR(lu_gp_mem); | 2038 | return PTR_ERR(lu_gp_mem); |
2090 | 2039 | ||
2091 | alua->alua_type = SPC3_ALUA_EMULATED; | ||
2092 | alua->alua_state_check = &core_alua_state_check; | ||
2093 | spin_lock(&lu_gp_mem->lu_gp_mem_lock); | 2040 | spin_lock(&lu_gp_mem->lu_gp_mem_lock); |
2094 | __core_alua_attach_lu_gp_mem(lu_gp_mem, | 2041 | __core_alua_attach_lu_gp_mem(lu_gp_mem, |
2095 | default_lu_gp); | 2042 | default_lu_gp); |
@@ -2098,11 +2045,6 @@ int core_setup_alua(struct se_device *dev, int force_pt) | |||
2098 | pr_debug("%s: Adding to default ALUA LU Group:" | 2045 | pr_debug("%s: Adding to default ALUA LU Group:" |
2099 | " core/alua/lu_gps/default_lu_gp\n", | 2046 | " core/alua/lu_gps/default_lu_gp\n", |
2100 | dev->transport->name); | 2047 | dev->transport->name); |
2101 | } else { | ||
2102 | alua->alua_type = SPC2_ALUA_DISABLED; | ||
2103 | alua->alua_state_check = &core_alua_state_check_nop; | ||
2104 | pr_debug("%s: Disabling ALUA Emulation for SPC-2" | ||
2105 | " device\n", dev->transport->name); | ||
2106 | } | 2048 | } |
2107 | 2049 | ||
2108 | return 0; | 2050 | return 0; |
diff --git a/drivers/target/target_core_alua.h b/drivers/target/target_core_alua.h index f920c170d47b..e539c3e7f4ad 100644 --- a/drivers/target/target_core_alua.h +++ b/drivers/target/target_core_alua.h | |||
@@ -72,8 +72,8 @@ extern struct kmem_cache *t10_alua_lu_gp_mem_cache; | |||
72 | extern struct kmem_cache *t10_alua_tg_pt_gp_cache; | 72 | extern struct kmem_cache *t10_alua_tg_pt_gp_cache; |
73 | extern struct kmem_cache *t10_alua_tg_pt_gp_mem_cache; | 73 | extern struct kmem_cache *t10_alua_tg_pt_gp_mem_cache; |
74 | 74 | ||
75 | extern int target_emulate_report_target_port_groups(struct se_cmd *); | 75 | extern sense_reason_t target_emulate_report_target_port_groups(struct se_cmd *); |
76 | extern int target_emulate_set_target_port_groups(struct se_cmd *); | 76 | extern sense_reason_t target_emulate_set_target_port_groups(struct se_cmd *); |
77 | extern int core_alua_check_nonop_delay(struct se_cmd *); | 77 | extern int core_alua_check_nonop_delay(struct se_cmd *); |
78 | extern int core_alua_do_port_transition(struct t10_alua_tg_pt_gp *, | 78 | extern int core_alua_do_port_transition(struct t10_alua_tg_pt_gp *, |
79 | struct se_device *, struct se_port *, | 79 | struct se_device *, struct se_port *, |
@@ -91,7 +91,7 @@ extern void __core_alua_drop_lu_gp_mem(struct t10_alua_lu_gp_member *, | |||
91 | struct t10_alua_lu_gp *); | 91 | struct t10_alua_lu_gp *); |
92 | extern void core_alua_drop_lu_gp_dev(struct se_device *); | 92 | extern void core_alua_drop_lu_gp_dev(struct se_device *); |
93 | extern struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp( | 93 | extern struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp( |
94 | struct se_subsystem_dev *, const char *, int); | 94 | struct se_device *, const char *, int); |
95 | extern int core_alua_set_tg_pt_gp_id(struct t10_alua_tg_pt_gp *, u16); | 95 | extern int core_alua_set_tg_pt_gp_id(struct t10_alua_tg_pt_gp *, u16); |
96 | extern struct t10_alua_tg_pt_gp_member *core_alua_allocate_tg_pt_gp_mem( | 96 | extern struct t10_alua_tg_pt_gp_member *core_alua_allocate_tg_pt_gp_mem( |
97 | struct se_port *); | 97 | struct se_port *); |
@@ -131,6 +131,7 @@ extern ssize_t core_alua_show_secondary_write_metadata(struct se_lun *, | |||
131 | char *); | 131 | char *); |
132 | extern ssize_t core_alua_store_secondary_write_metadata(struct se_lun *, | 132 | extern ssize_t core_alua_store_secondary_write_metadata(struct se_lun *, |
133 | const char *, size_t); | 133 | const char *, size_t); |
134 | extern int core_setup_alua(struct se_device *, int); | 134 | extern int core_setup_alua(struct se_device *); |
135 | extern sense_reason_t target_alua_state_check(struct se_cmd *cmd); | ||
135 | 136 | ||
136 | #endif /* TARGET_CORE_ALUA_H */ | 137 | #endif /* TARGET_CORE_ALUA_H */ |
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 015f5be27bf6..4efb61b8d001 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c | |||
@@ -3,8 +3,7 @@ | |||
3 | * | 3 | * |
4 | * This file contains ConfigFS logic for the Generic Target Engine project. | 4 | * This file contains ConfigFS logic for the Generic Target Engine project. |
5 | * | 5 | * |
6 | * Copyright (c) 2008-2011 Rising Tide Systems | 6 | * (c) Copyright 2008-2012 RisingTide Systems LLC. |
7 | * Copyright (c) 2008-2011 Linux-iSCSI.org | ||
8 | * | 7 | * |
9 | * Nicholas A. Bellinger <nab@kernel.org> | 8 | * Nicholas A. Bellinger <nab@kernel.org> |
10 | * | 9 | * |
@@ -565,21 +564,8 @@ static ssize_t target_core_dev_show_attr_##_name( \ | |||
565 | struct se_dev_attrib *da, \ | 564 | struct se_dev_attrib *da, \ |
566 | char *page) \ | 565 | char *page) \ |
567 | { \ | 566 | { \ |
568 | struct se_device *dev; \ | 567 | return snprintf(page, PAGE_SIZE, "%u\n", \ |
569 | struct se_subsystem_dev *se_dev = da->da_sub_dev; \ | 568 | (u32)da->da_dev->dev_attrib._name); \ |
570 | ssize_t rb; \ | ||
571 | \ | ||
572 | spin_lock(&se_dev->se_dev_lock); \ | ||
573 | dev = se_dev->se_dev_ptr; \ | ||
574 | if (!dev) { \ | ||
575 | spin_unlock(&se_dev->se_dev_lock); \ | ||
576 | return -ENODEV; \ | ||
577 | } \ | ||
578 | rb = snprintf(page, PAGE_SIZE, "%u\n", \ | ||
579 | (u32)dev->se_sub_dev->se_dev_attrib._name); \ | ||
580 | spin_unlock(&se_dev->se_dev_lock); \ | ||
581 | \ | ||
582 | return rb; \ | ||
583 | } | 569 | } |
584 | 570 | ||
585 | #define DEF_DEV_ATTRIB_STORE(_name) \ | 571 | #define DEF_DEV_ATTRIB_STORE(_name) \ |
@@ -588,26 +574,16 @@ static ssize_t target_core_dev_store_attr_##_name( \ | |||
588 | const char *page, \ | 574 | const char *page, \ |
589 | size_t count) \ | 575 | size_t count) \ |
590 | { \ | 576 | { \ |
591 | struct se_device *dev; \ | ||
592 | struct se_subsystem_dev *se_dev = da->da_sub_dev; \ | ||
593 | unsigned long val; \ | 577 | unsigned long val; \ |
594 | int ret; \ | 578 | int ret; \ |
595 | \ | 579 | \ |
596 | spin_lock(&se_dev->se_dev_lock); \ | ||
597 | dev = se_dev->se_dev_ptr; \ | ||
598 | if (!dev) { \ | ||
599 | spin_unlock(&se_dev->se_dev_lock); \ | ||
600 | return -ENODEV; \ | ||
601 | } \ | ||
602 | ret = strict_strtoul(page, 0, &val); \ | 580 | ret = strict_strtoul(page, 0, &val); \ |
603 | if (ret < 0) { \ | 581 | if (ret < 0) { \ |
604 | spin_unlock(&se_dev->se_dev_lock); \ | ||
605 | pr_err("strict_strtoul() failed with" \ | 582 | pr_err("strict_strtoul() failed with" \ |
606 | " ret: %d\n", ret); \ | 583 | " ret: %d\n", ret); \ |
607 | return -EINVAL; \ | 584 | return -EINVAL; \ |
608 | } \ | 585 | } \ |
609 | ret = se_dev_set_##_name(dev, (u32)val); \ | 586 | ret = se_dev_set_##_name(da->da_dev, (u32)val); \ |
610 | spin_unlock(&se_dev->se_dev_lock); \ | ||
611 | \ | 587 | \ |
612 | return (!ret) ? count : -EINVAL; \ | 588 | return (!ret) ? count : -EINVAL; \ |
613 | } | 589 | } |
@@ -699,6 +675,9 @@ SE_DEV_ATTR(unmap_granularity, S_IRUGO | S_IWUSR); | |||
699 | DEF_DEV_ATTRIB(unmap_granularity_alignment); | 675 | DEF_DEV_ATTRIB(unmap_granularity_alignment); |
700 | SE_DEV_ATTR(unmap_granularity_alignment, S_IRUGO | S_IWUSR); | 676 | SE_DEV_ATTR(unmap_granularity_alignment, S_IRUGO | S_IWUSR); |
701 | 677 | ||
678 | DEF_DEV_ATTRIB(max_write_same_len); | ||
679 | SE_DEV_ATTR(max_write_same_len, S_IRUGO | S_IWUSR); | ||
680 | |||
702 | CONFIGFS_EATTR_OPS(target_core_dev_attrib, se_dev_attrib, da_group); | 681 | CONFIGFS_EATTR_OPS(target_core_dev_attrib, se_dev_attrib, da_group); |
703 | 682 | ||
704 | static struct configfs_attribute *target_core_dev_attrib_attrs[] = { | 683 | static struct configfs_attribute *target_core_dev_attrib_attrs[] = { |
@@ -724,6 +703,7 @@ static struct configfs_attribute *target_core_dev_attrib_attrs[] = { | |||
724 | &target_core_dev_attrib_max_unmap_block_desc_count.attr, | 703 | &target_core_dev_attrib_max_unmap_block_desc_count.attr, |
725 | &target_core_dev_attrib_unmap_granularity.attr, | 704 | &target_core_dev_attrib_unmap_granularity.attr, |
726 | &target_core_dev_attrib_unmap_granularity_alignment.attr, | 705 | &target_core_dev_attrib_unmap_granularity_alignment.attr, |
706 | &target_core_dev_attrib_max_write_same_len.attr, | ||
727 | NULL, | 707 | NULL, |
728 | }; | 708 | }; |
729 | 709 | ||
@@ -764,13 +744,6 @@ static ssize_t target_core_dev_wwn_show_attr_vpd_unit_serial( | |||
764 | struct t10_wwn *t10_wwn, | 744 | struct t10_wwn *t10_wwn, |
765 | char *page) | 745 | char *page) |
766 | { | 746 | { |
767 | struct se_subsystem_dev *se_dev = t10_wwn->t10_sub_dev; | ||
768 | struct se_device *dev; | ||
769 | |||
770 | dev = se_dev->se_dev_ptr; | ||
771 | if (!dev) | ||
772 | return -ENODEV; | ||
773 | |||
774 | return sprintf(page, "T10 VPD Unit Serial Number: %s\n", | 747 | return sprintf(page, "T10 VPD Unit Serial Number: %s\n", |
775 | &t10_wwn->unit_serial[0]); | 748 | &t10_wwn->unit_serial[0]); |
776 | } | 749 | } |
@@ -780,8 +753,7 @@ static ssize_t target_core_dev_wwn_store_attr_vpd_unit_serial( | |||
780 | const char *page, | 753 | const char *page, |
781 | size_t count) | 754 | size_t count) |
782 | { | 755 | { |
783 | struct se_subsystem_dev *su_dev = t10_wwn->t10_sub_dev; | 756 | struct se_device *dev = t10_wwn->t10_dev; |
784 | struct se_device *dev; | ||
785 | unsigned char buf[INQUIRY_VPD_SERIAL_LEN]; | 757 | unsigned char buf[INQUIRY_VPD_SERIAL_LEN]; |
786 | 758 | ||
787 | /* | 759 | /* |
@@ -794,7 +766,7 @@ static ssize_t target_core_dev_wwn_store_attr_vpd_unit_serial( | |||
794 | * it is doing 'the right thing' wrt a world wide unique | 766 | * it is doing 'the right thing' wrt a world wide unique |
795 | * VPD Unit Serial Number that OS dependent multipath can depend on. | 767 | * VPD Unit Serial Number that OS dependent multipath can depend on. |
796 | */ | 768 | */ |
797 | if (su_dev->su_dev_flags & SDF_FIRMWARE_VPD_UNIT_SERIAL) { | 769 | if (dev->dev_flags & DF_FIRMWARE_VPD_UNIT_SERIAL) { |
798 | pr_err("Underlying SCSI device firmware provided VPD" | 770 | pr_err("Underlying SCSI device firmware provided VPD" |
799 | " Unit Serial, ignoring request\n"); | 771 | " Unit Serial, ignoring request\n"); |
800 | return -EOPNOTSUPP; | 772 | return -EOPNOTSUPP; |
@@ -811,15 +783,13 @@ static ssize_t target_core_dev_wwn_store_attr_vpd_unit_serial( | |||
811 | * (underneath the initiator side OS dependent multipath code) | 783 | * (underneath the initiator side OS dependent multipath code) |
812 | * could cause negative effects. | 784 | * could cause negative effects. |
813 | */ | 785 | */ |
814 | dev = su_dev->se_dev_ptr; | 786 | if (dev->export_count) { |
815 | if (dev) { | 787 | pr_err("Unable to set VPD Unit Serial while" |
816 | if (atomic_read(&dev->dev_export_obj.obj_access_count)) { | 788 | " active %d $FABRIC_MOD exports exist\n", |
817 | pr_err("Unable to set VPD Unit Serial while" | 789 | dev->export_count); |
818 | " active %d $FABRIC_MOD exports exist\n", | 790 | return -EINVAL; |
819 | atomic_read(&dev->dev_export_obj.obj_access_count)); | ||
820 | return -EINVAL; | ||
821 | } | ||
822 | } | 791 | } |
792 | |||
823 | /* | 793 | /* |
824 | * This currently assumes ASCII encoding for emulated VPD Unit Serial. | 794 | * This currently assumes ASCII encoding for emulated VPD Unit Serial. |
825 | * | 795 | * |
@@ -828,12 +798,12 @@ static ssize_t target_core_dev_wwn_store_attr_vpd_unit_serial( | |||
828 | */ | 798 | */ |
829 | memset(buf, 0, INQUIRY_VPD_SERIAL_LEN); | 799 | memset(buf, 0, INQUIRY_VPD_SERIAL_LEN); |
830 | snprintf(buf, INQUIRY_VPD_SERIAL_LEN, "%s", page); | 800 | snprintf(buf, INQUIRY_VPD_SERIAL_LEN, "%s", page); |
831 | snprintf(su_dev->t10_wwn.unit_serial, INQUIRY_VPD_SERIAL_LEN, | 801 | snprintf(dev->t10_wwn.unit_serial, INQUIRY_VPD_SERIAL_LEN, |
832 | "%s", strstrip(buf)); | 802 | "%s", strstrip(buf)); |
833 | su_dev->su_dev_flags |= SDF_EMULATED_VPD_UNIT_SERIAL; | 803 | dev->dev_flags |= DF_EMULATED_VPD_UNIT_SERIAL; |
834 | 804 | ||
835 | pr_debug("Target_Core_ConfigFS: Set emulated VPD Unit Serial:" | 805 | pr_debug("Target_Core_ConfigFS: Set emulated VPD Unit Serial:" |
836 | " %s\n", su_dev->t10_wwn.unit_serial); | 806 | " %s\n", dev->t10_wwn.unit_serial); |
837 | 807 | ||
838 | return count; | 808 | return count; |
839 | } | 809 | } |
@@ -847,16 +817,10 @@ static ssize_t target_core_dev_wwn_show_attr_vpd_protocol_identifier( | |||
847 | struct t10_wwn *t10_wwn, | 817 | struct t10_wwn *t10_wwn, |
848 | char *page) | 818 | char *page) |
849 | { | 819 | { |
850 | struct se_subsystem_dev *se_dev = t10_wwn->t10_sub_dev; | ||
851 | struct se_device *dev; | ||
852 | struct t10_vpd *vpd; | 820 | struct t10_vpd *vpd; |
853 | unsigned char buf[VPD_TMP_BUF_SIZE]; | 821 | unsigned char buf[VPD_TMP_BUF_SIZE]; |
854 | ssize_t len = 0; | 822 | ssize_t len = 0; |
855 | 823 | ||
856 | dev = se_dev->se_dev_ptr; | ||
857 | if (!dev) | ||
858 | return -ENODEV; | ||
859 | |||
860 | memset(buf, 0, VPD_TMP_BUF_SIZE); | 824 | memset(buf, 0, VPD_TMP_BUF_SIZE); |
861 | 825 | ||
862 | spin_lock(&t10_wwn->t10_vpd_lock); | 826 | spin_lock(&t10_wwn->t10_vpd_lock); |
@@ -894,16 +858,10 @@ static ssize_t target_core_dev_wwn_show_attr_##_name( \ | |||
894 | struct t10_wwn *t10_wwn, \ | 858 | struct t10_wwn *t10_wwn, \ |
895 | char *page) \ | 859 | char *page) \ |
896 | { \ | 860 | { \ |
897 | struct se_subsystem_dev *se_dev = t10_wwn->t10_sub_dev; \ | ||
898 | struct se_device *dev; \ | ||
899 | struct t10_vpd *vpd; \ | 861 | struct t10_vpd *vpd; \ |
900 | unsigned char buf[VPD_TMP_BUF_SIZE]; \ | 862 | unsigned char buf[VPD_TMP_BUF_SIZE]; \ |
901 | ssize_t len = 0; \ | 863 | ssize_t len = 0; \ |
902 | \ | 864 | \ |
903 | dev = se_dev->se_dev_ptr; \ | ||
904 | if (!dev) \ | ||
905 | return -ENODEV; \ | ||
906 | \ | ||
907 | spin_lock(&t10_wwn->t10_vpd_lock); \ | 865 | spin_lock(&t10_wwn->t10_vpd_lock); \ |
908 | list_for_each_entry(vpd, &t10_wwn->t10_vpd_list, vpd_list) { \ | 866 | list_for_each_entry(vpd, &t10_wwn->t10_vpd_list, vpd_list) { \ |
909 | if (vpd->association != _assoc) \ | 867 | if (vpd->association != _assoc) \ |
@@ -1003,7 +961,7 @@ static struct config_item_type target_core_dev_wwn_cit = { | |||
1003 | 961 | ||
1004 | /* Start functions for struct config_item_type target_core_dev_pr_cit */ | 962 | /* Start functions for struct config_item_type target_core_dev_pr_cit */ |
1005 | 963 | ||
1006 | CONFIGFS_EATTR_STRUCT(target_core_dev_pr, se_subsystem_dev); | 964 | CONFIGFS_EATTR_STRUCT(target_core_dev_pr, se_device); |
1007 | #define SE_DEV_PR_ATTR(_name, _mode) \ | 965 | #define SE_DEV_PR_ATTR(_name, _mode) \ |
1008 | static struct target_core_dev_pr_attribute target_core_dev_pr_##_name = \ | 966 | static struct target_core_dev_pr_attribute target_core_dev_pr_##_name = \ |
1009 | __CONFIGFS_EATTR(_name, _mode, \ | 967 | __CONFIGFS_EATTR(_name, _mode, \ |
@@ -1015,13 +973,8 @@ static struct target_core_dev_pr_attribute target_core_dev_pr_##_name = \ | |||
1015 | __CONFIGFS_EATTR_RO(_name, \ | 973 | __CONFIGFS_EATTR_RO(_name, \ |
1016 | target_core_dev_pr_show_attr_##_name); | 974 | target_core_dev_pr_show_attr_##_name); |
1017 | 975 | ||
1018 | /* | 976 | static ssize_t target_core_dev_pr_show_spc3_res(struct se_device *dev, |
1019 | * res_holder | 977 | char *page) |
1020 | */ | ||
1021 | static ssize_t target_core_dev_pr_show_spc3_res( | ||
1022 | struct se_device *dev, | ||
1023 | char *page, | ||
1024 | ssize_t *len) | ||
1025 | { | 978 | { |
1026 | struct se_node_acl *se_nacl; | 979 | struct se_node_acl *se_nacl; |
1027 | struct t10_pr_registration *pr_reg; | 980 | struct t10_pr_registration *pr_reg; |
@@ -1030,134 +983,82 @@ static ssize_t target_core_dev_pr_show_spc3_res( | |||
1030 | 983 | ||
1031 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); | 984 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); |
1032 | 985 | ||
1033 | spin_lock(&dev->dev_reservation_lock); | ||
1034 | pr_reg = dev->dev_pr_res_holder; | 986 | pr_reg = dev->dev_pr_res_holder; |
1035 | if (!pr_reg) { | 987 | if (!pr_reg) |
1036 | *len += sprintf(page + *len, "No SPC-3 Reservation holder\n"); | 988 | return sprintf(page, "No SPC-3 Reservation holder\n"); |
1037 | spin_unlock(&dev->dev_reservation_lock); | 989 | |
1038 | return *len; | ||
1039 | } | ||
1040 | se_nacl = pr_reg->pr_reg_nacl; | 990 | se_nacl = pr_reg->pr_reg_nacl; |
1041 | prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0], | 991 | prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0], |
1042 | PR_REG_ISID_ID_LEN); | 992 | PR_REG_ISID_ID_LEN); |
1043 | 993 | ||
1044 | *len += sprintf(page + *len, "SPC-3 Reservation: %s Initiator: %s%s\n", | 994 | return sprintf(page, "SPC-3 Reservation: %s Initiator: %s%s\n", |
1045 | se_nacl->se_tpg->se_tpg_tfo->get_fabric_name(), | 995 | se_nacl->se_tpg->se_tpg_tfo->get_fabric_name(), |
1046 | se_nacl->initiatorname, (prf_isid) ? &i_buf[0] : ""); | 996 | se_nacl->initiatorname, (prf_isid) ? &i_buf[0] : ""); |
1047 | spin_unlock(&dev->dev_reservation_lock); | ||
1048 | |||
1049 | return *len; | ||
1050 | } | 997 | } |
1051 | 998 | ||
1052 | static ssize_t target_core_dev_pr_show_spc2_res( | 999 | static ssize_t target_core_dev_pr_show_spc2_res(struct se_device *dev, |
1053 | struct se_device *dev, | 1000 | char *page) |
1054 | char *page, | ||
1055 | ssize_t *len) | ||
1056 | { | 1001 | { |
1057 | struct se_node_acl *se_nacl; | 1002 | struct se_node_acl *se_nacl; |
1003 | ssize_t len; | ||
1058 | 1004 | ||
1059 | spin_lock(&dev->dev_reservation_lock); | ||
1060 | se_nacl = dev->dev_reserved_node_acl; | 1005 | se_nacl = dev->dev_reserved_node_acl; |
1061 | if (!se_nacl) { | 1006 | if (se_nacl) { |
1062 | *len += sprintf(page + *len, "No SPC-2 Reservation holder\n"); | 1007 | len = sprintf(page, |
1063 | spin_unlock(&dev->dev_reservation_lock); | 1008 | "SPC-2 Reservation: %s Initiator: %s\n", |
1064 | return *len; | 1009 | se_nacl->se_tpg->se_tpg_tfo->get_fabric_name(), |
1010 | se_nacl->initiatorname); | ||
1011 | } else { | ||
1012 | len = sprintf(page, "No SPC-2 Reservation holder\n"); | ||
1065 | } | 1013 | } |
1066 | *len += sprintf(page + *len, "SPC-2 Reservation: %s Initiator: %s\n", | 1014 | return len; |
1067 | se_nacl->se_tpg->se_tpg_tfo->get_fabric_name(), | ||
1068 | se_nacl->initiatorname); | ||
1069 | spin_unlock(&dev->dev_reservation_lock); | ||
1070 | |||
1071 | return *len; | ||
1072 | } | 1015 | } |
1073 | 1016 | ||
1074 | static ssize_t target_core_dev_pr_show_attr_res_holder( | 1017 | static ssize_t target_core_dev_pr_show_attr_res_holder(struct se_device *dev, |
1075 | struct se_subsystem_dev *su_dev, | 1018 | char *page) |
1076 | char *page) | ||
1077 | { | 1019 | { |
1078 | ssize_t len = 0; | 1020 | int ret; |
1079 | 1021 | ||
1080 | if (!su_dev->se_dev_ptr) | 1022 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) |
1081 | return -ENODEV; | 1023 | return sprintf(page, "Passthrough\n"); |
1082 | |||
1083 | switch (su_dev->t10_pr.res_type) { | ||
1084 | case SPC3_PERSISTENT_RESERVATIONS: | ||
1085 | target_core_dev_pr_show_spc3_res(su_dev->se_dev_ptr, | ||
1086 | page, &len); | ||
1087 | break; | ||
1088 | case SPC2_RESERVATIONS: | ||
1089 | target_core_dev_pr_show_spc2_res(su_dev->se_dev_ptr, | ||
1090 | page, &len); | ||
1091 | break; | ||
1092 | case SPC_PASSTHROUGH: | ||
1093 | len += sprintf(page+len, "Passthrough\n"); | ||
1094 | break; | ||
1095 | default: | ||
1096 | len += sprintf(page+len, "Unknown\n"); | ||
1097 | break; | ||
1098 | } | ||
1099 | 1024 | ||
1100 | return len; | 1025 | spin_lock(&dev->dev_reservation_lock); |
1026 | if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) | ||
1027 | ret = target_core_dev_pr_show_spc2_res(dev, page); | ||
1028 | else | ||
1029 | ret = target_core_dev_pr_show_spc3_res(dev, page); | ||
1030 | spin_unlock(&dev->dev_reservation_lock); | ||
1031 | return ret; | ||
1101 | } | 1032 | } |
1102 | 1033 | ||
1103 | SE_DEV_PR_ATTR_RO(res_holder); | 1034 | SE_DEV_PR_ATTR_RO(res_holder); |
1104 | 1035 | ||
1105 | /* | ||
1106 | * res_pr_all_tgt_pts | ||
1107 | */ | ||
1108 | static ssize_t target_core_dev_pr_show_attr_res_pr_all_tgt_pts( | 1036 | static ssize_t target_core_dev_pr_show_attr_res_pr_all_tgt_pts( |
1109 | struct se_subsystem_dev *su_dev, | 1037 | struct se_device *dev, char *page) |
1110 | char *page) | ||
1111 | { | 1038 | { |
1112 | struct se_device *dev; | ||
1113 | struct t10_pr_registration *pr_reg; | ||
1114 | ssize_t len = 0; | 1039 | ssize_t len = 0; |
1115 | 1040 | ||
1116 | dev = su_dev->se_dev_ptr; | ||
1117 | if (!dev) | ||
1118 | return -ENODEV; | ||
1119 | |||
1120 | if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS) | ||
1121 | return len; | ||
1122 | |||
1123 | spin_lock(&dev->dev_reservation_lock); | 1041 | spin_lock(&dev->dev_reservation_lock); |
1124 | pr_reg = dev->dev_pr_res_holder; | 1042 | if (!dev->dev_pr_res_holder) { |
1125 | if (!pr_reg) { | ||
1126 | len = sprintf(page, "No SPC-3 Reservation holder\n"); | 1043 | len = sprintf(page, "No SPC-3 Reservation holder\n"); |
1127 | spin_unlock(&dev->dev_reservation_lock); | 1044 | } else if (dev->dev_pr_res_holder->pr_reg_all_tg_pt) { |
1128 | return len; | ||
1129 | } | ||
1130 | /* | ||
1131 | * See All Target Ports (ALL_TG_PT) bit in spcr17, section 6.14.3 | ||
1132 | * Basic PERSISTENT RESERVER OUT parameter list, page 290 | ||
1133 | */ | ||
1134 | if (pr_reg->pr_reg_all_tg_pt) | ||
1135 | len = sprintf(page, "SPC-3 Reservation: All Target" | 1045 | len = sprintf(page, "SPC-3 Reservation: All Target" |
1136 | " Ports registration\n"); | 1046 | " Ports registration\n"); |
1137 | else | 1047 | } else { |
1138 | len = sprintf(page, "SPC-3 Reservation: Single" | 1048 | len = sprintf(page, "SPC-3 Reservation: Single" |
1139 | " Target Port registration\n"); | 1049 | " Target Port registration\n"); |
1140 | spin_unlock(&dev->dev_reservation_lock); | 1050 | } |
1141 | 1051 | ||
1052 | spin_unlock(&dev->dev_reservation_lock); | ||
1142 | return len; | 1053 | return len; |
1143 | } | 1054 | } |
1144 | 1055 | ||
1145 | SE_DEV_PR_ATTR_RO(res_pr_all_tgt_pts); | 1056 | SE_DEV_PR_ATTR_RO(res_pr_all_tgt_pts); |
1146 | 1057 | ||
1147 | /* | ||
1148 | * res_pr_generation | ||
1149 | */ | ||
1150 | static ssize_t target_core_dev_pr_show_attr_res_pr_generation( | 1058 | static ssize_t target_core_dev_pr_show_attr_res_pr_generation( |
1151 | struct se_subsystem_dev *su_dev, | 1059 | struct se_device *dev, char *page) |
1152 | char *page) | ||
1153 | { | 1060 | { |
1154 | if (!su_dev->se_dev_ptr) | 1061 | return sprintf(page, "0x%08x\n", dev->t10_pr.pr_generation); |
1155 | return -ENODEV; | ||
1156 | |||
1157 | if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS) | ||
1158 | return 0; | ||
1159 | |||
1160 | return sprintf(page, "0x%08x\n", su_dev->t10_pr.pr_generation); | ||
1161 | } | 1062 | } |
1162 | 1063 | ||
1163 | SE_DEV_PR_ATTR_RO(res_pr_generation); | 1064 | SE_DEV_PR_ATTR_RO(res_pr_generation); |
@@ -1166,10 +1067,8 @@ SE_DEV_PR_ATTR_RO(res_pr_generation); | |||
1166 | * res_pr_holder_tg_port | 1067 | * res_pr_holder_tg_port |
1167 | */ | 1068 | */ |
1168 | static ssize_t target_core_dev_pr_show_attr_res_pr_holder_tg_port( | 1069 | static ssize_t target_core_dev_pr_show_attr_res_pr_holder_tg_port( |
1169 | struct se_subsystem_dev *su_dev, | 1070 | struct se_device *dev, char *page) |
1170 | char *page) | ||
1171 | { | 1071 | { |
1172 | struct se_device *dev; | ||
1173 | struct se_node_acl *se_nacl; | 1072 | struct se_node_acl *se_nacl; |
1174 | struct se_lun *lun; | 1073 | struct se_lun *lun; |
1175 | struct se_portal_group *se_tpg; | 1074 | struct se_portal_group *se_tpg; |
@@ -1177,20 +1076,13 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_holder_tg_port( | |||
1177 | struct target_core_fabric_ops *tfo; | 1076 | struct target_core_fabric_ops *tfo; |
1178 | ssize_t len = 0; | 1077 | ssize_t len = 0; |
1179 | 1078 | ||
1180 | dev = su_dev->se_dev_ptr; | ||
1181 | if (!dev) | ||
1182 | return -ENODEV; | ||
1183 | |||
1184 | if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS) | ||
1185 | return len; | ||
1186 | |||
1187 | spin_lock(&dev->dev_reservation_lock); | 1079 | spin_lock(&dev->dev_reservation_lock); |
1188 | pr_reg = dev->dev_pr_res_holder; | 1080 | pr_reg = dev->dev_pr_res_holder; |
1189 | if (!pr_reg) { | 1081 | if (!pr_reg) { |
1190 | len = sprintf(page, "No SPC-3 Reservation holder\n"); | 1082 | len = sprintf(page, "No SPC-3 Reservation holder\n"); |
1191 | spin_unlock(&dev->dev_reservation_lock); | 1083 | goto out_unlock; |
1192 | return len; | ||
1193 | } | 1084 | } |
1085 | |||
1194 | se_nacl = pr_reg->pr_reg_nacl; | 1086 | se_nacl = pr_reg->pr_reg_nacl; |
1195 | se_tpg = se_nacl->se_tpg; | 1087 | se_tpg = se_nacl->se_tpg; |
1196 | lun = pr_reg->pr_reg_tg_pt_lun; | 1088 | lun = pr_reg->pr_reg_tg_pt_lun; |
@@ -1204,19 +1096,16 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_holder_tg_port( | |||
1204 | " %s Logical Unit: %u\n", lun->lun_sep->sep_rtpi, | 1096 | " %s Logical Unit: %u\n", lun->lun_sep->sep_rtpi, |
1205 | tfo->get_fabric_name(), tfo->tpg_get_tag(se_tpg), | 1097 | tfo->get_fabric_name(), tfo->tpg_get_tag(se_tpg), |
1206 | tfo->get_fabric_name(), lun->unpacked_lun); | 1098 | tfo->get_fabric_name(), lun->unpacked_lun); |
1207 | spin_unlock(&dev->dev_reservation_lock); | ||
1208 | 1099 | ||
1100 | out_unlock: | ||
1101 | spin_unlock(&dev->dev_reservation_lock); | ||
1209 | return len; | 1102 | return len; |
1210 | } | 1103 | } |
1211 | 1104 | ||
1212 | SE_DEV_PR_ATTR_RO(res_pr_holder_tg_port); | 1105 | SE_DEV_PR_ATTR_RO(res_pr_holder_tg_port); |
1213 | 1106 | ||
1214 | /* | ||
1215 | * res_pr_registered_i_pts | ||
1216 | */ | ||
1217 | static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts( | 1107 | static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts( |
1218 | struct se_subsystem_dev *su_dev, | 1108 | struct se_device *dev, char *page) |
1219 | char *page) | ||
1220 | { | 1109 | { |
1221 | struct target_core_fabric_ops *tfo; | 1110 | struct target_core_fabric_ops *tfo; |
1222 | struct t10_pr_registration *pr_reg; | 1111 | struct t10_pr_registration *pr_reg; |
@@ -1225,16 +1114,10 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts( | |||
1225 | ssize_t len = 0; | 1114 | ssize_t len = 0; |
1226 | int reg_count = 0, prf_isid; | 1115 | int reg_count = 0, prf_isid; |
1227 | 1116 | ||
1228 | if (!su_dev->se_dev_ptr) | ||
1229 | return -ENODEV; | ||
1230 | |||
1231 | if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS) | ||
1232 | return len; | ||
1233 | |||
1234 | len += sprintf(page+len, "SPC-3 PR Registrations:\n"); | 1117 | len += sprintf(page+len, "SPC-3 PR Registrations:\n"); |
1235 | 1118 | ||
1236 | spin_lock(&su_dev->t10_pr.registration_lock); | 1119 | spin_lock(&dev->t10_pr.registration_lock); |
1237 | list_for_each_entry(pr_reg, &su_dev->t10_pr.registration_list, | 1120 | list_for_each_entry(pr_reg, &dev->t10_pr.registration_list, |
1238 | pr_reg_list) { | 1121 | pr_reg_list) { |
1239 | 1122 | ||
1240 | memset(buf, 0, 384); | 1123 | memset(buf, 0, 384); |
@@ -1254,7 +1137,7 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts( | |||
1254 | len += sprintf(page+len, "%s", buf); | 1137 | len += sprintf(page+len, "%s", buf); |
1255 | reg_count++; | 1138 | reg_count++; |
1256 | } | 1139 | } |
1257 | spin_unlock(&su_dev->t10_pr.registration_lock); | 1140 | spin_unlock(&dev->t10_pr.registration_lock); |
1258 | 1141 | ||
1259 | if (!reg_count) | 1142 | if (!reg_count) |
1260 | len += sprintf(page+len, "None\n"); | 1143 | len += sprintf(page+len, "None\n"); |
@@ -1264,88 +1147,48 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts( | |||
1264 | 1147 | ||
1265 | SE_DEV_PR_ATTR_RO(res_pr_registered_i_pts); | 1148 | SE_DEV_PR_ATTR_RO(res_pr_registered_i_pts); |
1266 | 1149 | ||
1267 | /* | ||
1268 | * res_pr_type | ||
1269 | */ | ||
1270 | static ssize_t target_core_dev_pr_show_attr_res_pr_type( | 1150 | static ssize_t target_core_dev_pr_show_attr_res_pr_type( |
1271 | struct se_subsystem_dev *su_dev, | 1151 | struct se_device *dev, char *page) |
1272 | char *page) | ||
1273 | { | 1152 | { |
1274 | struct se_device *dev; | ||
1275 | struct t10_pr_registration *pr_reg; | 1153 | struct t10_pr_registration *pr_reg; |
1276 | ssize_t len = 0; | 1154 | ssize_t len = 0; |
1277 | 1155 | ||
1278 | dev = su_dev->se_dev_ptr; | ||
1279 | if (!dev) | ||
1280 | return -ENODEV; | ||
1281 | |||
1282 | if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS) | ||
1283 | return len; | ||
1284 | |||
1285 | spin_lock(&dev->dev_reservation_lock); | 1156 | spin_lock(&dev->dev_reservation_lock); |
1286 | pr_reg = dev->dev_pr_res_holder; | 1157 | pr_reg = dev->dev_pr_res_holder; |
1287 | if (!pr_reg) { | 1158 | if (pr_reg) { |
1159 | len = sprintf(page, "SPC-3 Reservation Type: %s\n", | ||
1160 | core_scsi3_pr_dump_type(pr_reg->pr_res_type)); | ||
1161 | } else { | ||
1288 | len = sprintf(page, "No SPC-3 Reservation holder\n"); | 1162 | len = sprintf(page, "No SPC-3 Reservation holder\n"); |
1289 | spin_unlock(&dev->dev_reservation_lock); | ||
1290 | return len; | ||
1291 | } | 1163 | } |
1292 | len = sprintf(page, "SPC-3 Reservation Type: %s\n", | ||
1293 | core_scsi3_pr_dump_type(pr_reg->pr_res_type)); | ||
1294 | spin_unlock(&dev->dev_reservation_lock); | ||
1295 | 1164 | ||
1165 | spin_unlock(&dev->dev_reservation_lock); | ||
1296 | return len; | 1166 | return len; |
1297 | } | 1167 | } |
1298 | 1168 | ||
1299 | SE_DEV_PR_ATTR_RO(res_pr_type); | 1169 | SE_DEV_PR_ATTR_RO(res_pr_type); |
1300 | 1170 | ||
1301 | /* | ||
1302 | * res_type | ||
1303 | */ | ||
1304 | static ssize_t target_core_dev_pr_show_attr_res_type( | 1171 | static ssize_t target_core_dev_pr_show_attr_res_type( |
1305 | struct se_subsystem_dev *su_dev, | 1172 | struct se_device *dev, char *page) |
1306 | char *page) | ||
1307 | { | 1173 | { |
1308 | ssize_t len = 0; | 1174 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) |
1309 | 1175 | return sprintf(page, "SPC_PASSTHROUGH\n"); | |
1310 | if (!su_dev->se_dev_ptr) | 1176 | else if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) |
1311 | return -ENODEV; | 1177 | return sprintf(page, "SPC2_RESERVATIONS\n"); |
1312 | 1178 | else | |
1313 | switch (su_dev->t10_pr.res_type) { | 1179 | return sprintf(page, "SPC3_PERSISTENT_RESERVATIONS\n"); |
1314 | case SPC3_PERSISTENT_RESERVATIONS: | ||
1315 | len = sprintf(page, "SPC3_PERSISTENT_RESERVATIONS\n"); | ||
1316 | break; | ||
1317 | case SPC2_RESERVATIONS: | ||
1318 | len = sprintf(page, "SPC2_RESERVATIONS\n"); | ||
1319 | break; | ||
1320 | case SPC_PASSTHROUGH: | ||
1321 | len = sprintf(page, "SPC_PASSTHROUGH\n"); | ||
1322 | break; | ||
1323 | default: | ||
1324 | len = sprintf(page, "UNKNOWN\n"); | ||
1325 | break; | ||
1326 | } | ||
1327 | |||
1328 | return len; | ||
1329 | } | 1180 | } |
1330 | 1181 | ||
1331 | SE_DEV_PR_ATTR_RO(res_type); | 1182 | SE_DEV_PR_ATTR_RO(res_type); |
1332 | 1183 | ||
1333 | /* | ||
1334 | * res_aptpl_active | ||
1335 | */ | ||
1336 | |||
1337 | static ssize_t target_core_dev_pr_show_attr_res_aptpl_active( | 1184 | static ssize_t target_core_dev_pr_show_attr_res_aptpl_active( |
1338 | struct se_subsystem_dev *su_dev, | 1185 | struct se_device *dev, char *page) |
1339 | char *page) | ||
1340 | { | 1186 | { |
1341 | if (!su_dev->se_dev_ptr) | 1187 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) |
1342 | return -ENODEV; | ||
1343 | |||
1344 | if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS) | ||
1345 | return 0; | 1188 | return 0; |
1346 | 1189 | ||
1347 | return sprintf(page, "APTPL Bit Status: %s\n", | 1190 | return sprintf(page, "APTPL Bit Status: %s\n", |
1348 | (su_dev->t10_pr.pr_aptpl_active) ? "Activated" : "Disabled"); | 1191 | (dev->t10_pr.pr_aptpl_active) ? "Activated" : "Disabled"); |
1349 | } | 1192 | } |
1350 | 1193 | ||
1351 | SE_DEV_PR_ATTR_RO(res_aptpl_active); | 1194 | SE_DEV_PR_ATTR_RO(res_aptpl_active); |
@@ -1354,13 +1197,9 @@ SE_DEV_PR_ATTR_RO(res_aptpl_active); | |||
1354 | * res_aptpl_metadata | 1197 | * res_aptpl_metadata |
1355 | */ | 1198 | */ |
1356 | static ssize_t target_core_dev_pr_show_attr_res_aptpl_metadata( | 1199 | static ssize_t target_core_dev_pr_show_attr_res_aptpl_metadata( |
1357 | struct se_subsystem_dev *su_dev, | 1200 | struct se_device *dev, char *page) |
1358 | char *page) | ||
1359 | { | 1201 | { |
1360 | if (!su_dev->se_dev_ptr) | 1202 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) |
1361 | return -ENODEV; | ||
1362 | |||
1363 | if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS) | ||
1364 | return 0; | 1203 | return 0; |
1365 | 1204 | ||
1366 | return sprintf(page, "Ready to process PR APTPL metadata..\n"); | 1205 | return sprintf(page, "Ready to process PR APTPL metadata..\n"); |
@@ -1392,11 +1231,10 @@ static match_table_t tokens = { | |||
1392 | }; | 1231 | }; |
1393 | 1232 | ||
1394 | static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata( | 1233 | static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata( |
1395 | struct se_subsystem_dev *su_dev, | 1234 | struct se_device *dev, |
1396 | const char *page, | 1235 | const char *page, |
1397 | size_t count) | 1236 | size_t count) |
1398 | { | 1237 | { |
1399 | struct se_device *dev; | ||
1400 | unsigned char *i_fabric = NULL, *i_port = NULL, *isid = NULL; | 1238 | unsigned char *i_fabric = NULL, *i_port = NULL, *isid = NULL; |
1401 | unsigned char *t_fabric = NULL, *t_port = NULL; | 1239 | unsigned char *t_fabric = NULL, *t_port = NULL; |
1402 | char *orig, *ptr, *arg_p, *opts; | 1240 | char *orig, *ptr, *arg_p, *opts; |
@@ -1408,14 +1246,12 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata( | |||
1408 | u16 port_rpti = 0, tpgt = 0; | 1246 | u16 port_rpti = 0, tpgt = 0; |
1409 | u8 type = 0, scope; | 1247 | u8 type = 0, scope; |
1410 | 1248 | ||
1411 | dev = su_dev->se_dev_ptr; | 1249 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) |
1412 | if (!dev) | 1250 | return 0; |
1413 | return -ENODEV; | 1251 | if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) |
1414 | |||
1415 | if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS) | ||
1416 | return 0; | 1252 | return 0; |
1417 | 1253 | ||
1418 | if (atomic_read(&dev->dev_export_obj.obj_access_count)) { | 1254 | if (dev->export_count) { |
1419 | pr_debug("Unable to process APTPL metadata while" | 1255 | pr_debug("Unable to process APTPL metadata while" |
1420 | " active fabric exports exist\n"); | 1256 | " active fabric exports exist\n"); |
1421 | return -EINVAL; | 1257 | return -EINVAL; |
@@ -1558,7 +1394,7 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata( | |||
1558 | goto out; | 1394 | goto out; |
1559 | } | 1395 | } |
1560 | 1396 | ||
1561 | ret = core_scsi3_alloc_aptpl_registration(&su_dev->t10_pr, sa_res_key, | 1397 | ret = core_scsi3_alloc_aptpl_registration(&dev->t10_pr, sa_res_key, |
1562 | i_port, isid, mapped_lun, t_port, tpgt, target_lun, | 1398 | i_port, isid, mapped_lun, t_port, tpgt, target_lun, |
1563 | res_holder, all_tg_pt, type); | 1399 | res_holder, all_tg_pt, type); |
1564 | out: | 1400 | out: |
@@ -1573,7 +1409,7 @@ out: | |||
1573 | 1409 | ||
1574 | SE_DEV_PR_ATTR(res_aptpl_metadata, S_IRUGO | S_IWUSR); | 1410 | SE_DEV_PR_ATTR(res_aptpl_metadata, S_IRUGO | S_IWUSR); |
1575 | 1411 | ||
1576 | CONFIGFS_EATTR_OPS(target_core_dev_pr, se_subsystem_dev, se_dev_pr_group); | 1412 | CONFIGFS_EATTR_OPS(target_core_dev_pr, se_device, dev_pr_group); |
1577 | 1413 | ||
1578 | static struct configfs_attribute *target_core_dev_pr_attrs[] = { | 1414 | static struct configfs_attribute *target_core_dev_pr_attrs[] = { |
1579 | &target_core_dev_pr_res_holder.attr, | 1415 | &target_core_dev_pr_res_holder.attr, |
@@ -1605,18 +1441,14 @@ static struct config_item_type target_core_dev_pr_cit = { | |||
1605 | 1441 | ||
1606 | static ssize_t target_core_show_dev_info(void *p, char *page) | 1442 | static ssize_t target_core_show_dev_info(void *p, char *page) |
1607 | { | 1443 | { |
1608 | struct se_subsystem_dev *se_dev = p; | 1444 | struct se_device *dev = p; |
1609 | struct se_hba *hba = se_dev->se_dev_hba; | 1445 | struct se_subsystem_api *t = dev->transport; |
1610 | struct se_subsystem_api *t = hba->transport; | ||
1611 | int bl = 0; | 1446 | int bl = 0; |
1612 | ssize_t read_bytes = 0; | 1447 | ssize_t read_bytes = 0; |
1613 | 1448 | ||
1614 | if (!se_dev->se_dev_ptr) | 1449 | transport_dump_dev_state(dev, page, &bl); |
1615 | return -ENODEV; | ||
1616 | |||
1617 | transport_dump_dev_state(se_dev->se_dev_ptr, page, &bl); | ||
1618 | read_bytes += bl; | 1450 | read_bytes += bl; |
1619 | read_bytes += t->show_configfs_dev_params(hba, se_dev, page+read_bytes); | 1451 | read_bytes += t->show_configfs_dev_params(dev, page+read_bytes); |
1620 | return read_bytes; | 1452 | return read_bytes; |
1621 | } | 1453 | } |
1622 | 1454 | ||
@@ -1633,17 +1465,10 @@ static ssize_t target_core_store_dev_control( | |||
1633 | const char *page, | 1465 | const char *page, |
1634 | size_t count) | 1466 | size_t count) |
1635 | { | 1467 | { |
1636 | struct se_subsystem_dev *se_dev = p; | 1468 | struct se_device *dev = p; |
1637 | struct se_hba *hba = se_dev->se_dev_hba; | 1469 | struct se_subsystem_api *t = dev->transport; |
1638 | struct se_subsystem_api *t = hba->transport; | ||
1639 | 1470 | ||
1640 | if (!se_dev->se_dev_su_ptr) { | 1471 | return t->set_configfs_dev_params(dev, page, count); |
1641 | pr_err("Unable to locate struct se_subsystem_dev>se" | ||
1642 | "_dev_su_ptr\n"); | ||
1643 | return -EINVAL; | ||
1644 | } | ||
1645 | |||
1646 | return t->set_configfs_dev_params(hba, se_dev, page, count); | ||
1647 | } | 1472 | } |
1648 | 1473 | ||
1649 | static struct target_core_configfs_attribute target_core_attr_dev_control = { | 1474 | static struct target_core_configfs_attribute target_core_attr_dev_control = { |
@@ -1656,12 +1481,12 @@ static struct target_core_configfs_attribute target_core_attr_dev_control = { | |||
1656 | 1481 | ||
1657 | static ssize_t target_core_show_dev_alias(void *p, char *page) | 1482 | static ssize_t target_core_show_dev_alias(void *p, char *page) |
1658 | { | 1483 | { |
1659 | struct se_subsystem_dev *se_dev = p; | 1484 | struct se_device *dev = p; |
1660 | 1485 | ||
1661 | if (!(se_dev->su_dev_flags & SDF_USING_ALIAS)) | 1486 | if (!(dev->dev_flags & DF_USING_ALIAS)) |
1662 | return 0; | 1487 | return 0; |
1663 | 1488 | ||
1664 | return snprintf(page, PAGE_SIZE, "%s\n", se_dev->se_dev_alias); | 1489 | return snprintf(page, PAGE_SIZE, "%s\n", dev->dev_alias); |
1665 | } | 1490 | } |
1666 | 1491 | ||
1667 | static ssize_t target_core_store_dev_alias( | 1492 | static ssize_t target_core_store_dev_alias( |
@@ -1669,8 +1494,8 @@ static ssize_t target_core_store_dev_alias( | |||
1669 | const char *page, | 1494 | const char *page, |
1670 | size_t count) | 1495 | size_t count) |
1671 | { | 1496 | { |
1672 | struct se_subsystem_dev *se_dev = p; | 1497 | struct se_device *dev = p; |
1673 | struct se_hba *hba = se_dev->se_dev_hba; | 1498 | struct se_hba *hba = dev->se_hba; |
1674 | ssize_t read_bytes; | 1499 | ssize_t read_bytes; |
1675 | 1500 | ||
1676 | if (count > (SE_DEV_ALIAS_LEN-1)) { | 1501 | if (count > (SE_DEV_ALIAS_LEN-1)) { |
@@ -1680,19 +1505,18 @@ static ssize_t target_core_store_dev_alias( | |||
1680 | return -EINVAL; | 1505 | return -EINVAL; |
1681 | } | 1506 | } |
1682 | 1507 | ||
1683 | read_bytes = snprintf(&se_dev->se_dev_alias[0], SE_DEV_ALIAS_LEN, | 1508 | read_bytes = snprintf(&dev->dev_alias[0], SE_DEV_ALIAS_LEN, "%s", page); |
1684 | "%s", page); | ||
1685 | if (!read_bytes) | 1509 | if (!read_bytes) |
1686 | return -EINVAL; | 1510 | return -EINVAL; |
1687 | if (se_dev->se_dev_alias[read_bytes - 1] == '\n') | 1511 | if (dev->dev_alias[read_bytes - 1] == '\n') |
1688 | se_dev->se_dev_alias[read_bytes - 1] = '\0'; | 1512 | dev->dev_alias[read_bytes - 1] = '\0'; |
1689 | 1513 | ||
1690 | se_dev->su_dev_flags |= SDF_USING_ALIAS; | 1514 | dev->dev_flags |= DF_USING_ALIAS; |
1691 | 1515 | ||
1692 | pr_debug("Target_Core_ConfigFS: %s/%s set alias: %s\n", | 1516 | pr_debug("Target_Core_ConfigFS: %s/%s set alias: %s\n", |
1693 | config_item_name(&hba->hba_group.cg_item), | 1517 | config_item_name(&hba->hba_group.cg_item), |
1694 | config_item_name(&se_dev->se_dev_group.cg_item), | 1518 | config_item_name(&dev->dev_group.cg_item), |
1695 | se_dev->se_dev_alias); | 1519 | dev->dev_alias); |
1696 | 1520 | ||
1697 | return read_bytes; | 1521 | return read_bytes; |
1698 | } | 1522 | } |
@@ -1707,12 +1531,12 @@ static struct target_core_configfs_attribute target_core_attr_dev_alias = { | |||
1707 | 1531 | ||
1708 | static ssize_t target_core_show_dev_udev_path(void *p, char *page) | 1532 | static ssize_t target_core_show_dev_udev_path(void *p, char *page) |
1709 | { | 1533 | { |
1710 | struct se_subsystem_dev *se_dev = p; | 1534 | struct se_device *dev = p; |
1711 | 1535 | ||
1712 | if (!(se_dev->su_dev_flags & SDF_USING_UDEV_PATH)) | 1536 | if (!(dev->dev_flags & DF_USING_UDEV_PATH)) |
1713 | return 0; | 1537 | return 0; |
1714 | 1538 | ||
1715 | return snprintf(page, PAGE_SIZE, "%s\n", se_dev->se_dev_udev_path); | 1539 | return snprintf(page, PAGE_SIZE, "%s\n", dev->udev_path); |
1716 | } | 1540 | } |
1717 | 1541 | ||
1718 | static ssize_t target_core_store_dev_udev_path( | 1542 | static ssize_t target_core_store_dev_udev_path( |
@@ -1720,8 +1544,8 @@ static ssize_t target_core_store_dev_udev_path( | |||
1720 | const char *page, | 1544 | const char *page, |
1721 | size_t count) | 1545 | size_t count) |
1722 | { | 1546 | { |
1723 | struct se_subsystem_dev *se_dev = p; | 1547 | struct se_device *dev = p; |
1724 | struct se_hba *hba = se_dev->se_dev_hba; | 1548 | struct se_hba *hba = dev->se_hba; |
1725 | ssize_t read_bytes; | 1549 | ssize_t read_bytes; |
1726 | 1550 | ||
1727 | if (count > (SE_UDEV_PATH_LEN-1)) { | 1551 | if (count > (SE_UDEV_PATH_LEN-1)) { |
@@ -1731,19 +1555,19 @@ static ssize_t target_core_store_dev_udev_path( | |||
1731 | return -EINVAL; | 1555 | return -EINVAL; |
1732 | } | 1556 | } |
1733 | 1557 | ||
1734 | read_bytes = snprintf(&se_dev->se_dev_udev_path[0], SE_UDEV_PATH_LEN, | 1558 | read_bytes = snprintf(&dev->udev_path[0], SE_UDEV_PATH_LEN, |
1735 | "%s", page); | 1559 | "%s", page); |
1736 | if (!read_bytes) | 1560 | if (!read_bytes) |
1737 | return -EINVAL; | 1561 | return -EINVAL; |
1738 | if (se_dev->se_dev_udev_path[read_bytes - 1] == '\n') | 1562 | if (dev->udev_path[read_bytes - 1] == '\n') |
1739 | se_dev->se_dev_udev_path[read_bytes - 1] = '\0'; | 1563 | dev->udev_path[read_bytes - 1] = '\0'; |
1740 | 1564 | ||
1741 | se_dev->su_dev_flags |= SDF_USING_UDEV_PATH; | 1565 | dev->dev_flags |= DF_USING_UDEV_PATH; |
1742 | 1566 | ||
1743 | pr_debug("Target_Core_ConfigFS: %s/%s set udev_path: %s\n", | 1567 | pr_debug("Target_Core_ConfigFS: %s/%s set udev_path: %s\n", |
1744 | config_item_name(&hba->hba_group.cg_item), | 1568 | config_item_name(&hba->hba_group.cg_item), |
1745 | config_item_name(&se_dev->se_dev_group.cg_item), | 1569 | config_item_name(&dev->dev_group.cg_item), |
1746 | se_dev->se_dev_udev_path); | 1570 | dev->udev_path); |
1747 | 1571 | ||
1748 | return read_bytes; | 1572 | return read_bytes; |
1749 | } | 1573 | } |
@@ -1761,11 +1585,9 @@ static ssize_t target_core_store_dev_enable( | |||
1761 | const char *page, | 1585 | const char *page, |
1762 | size_t count) | 1586 | size_t count) |
1763 | { | 1587 | { |
1764 | struct se_subsystem_dev *se_dev = p; | 1588 | struct se_device *dev = p; |
1765 | struct se_device *dev; | ||
1766 | struct se_hba *hba = se_dev->se_dev_hba; | ||
1767 | struct se_subsystem_api *t = hba->transport; | ||
1768 | char *ptr; | 1589 | char *ptr; |
1590 | int ret; | ||
1769 | 1591 | ||
1770 | ptr = strstr(page, "1"); | 1592 | ptr = strstr(page, "1"); |
1771 | if (!ptr) { | 1593 | if (!ptr) { |
@@ -1773,25 +1595,10 @@ static ssize_t target_core_store_dev_enable( | |||
1773 | " is \"1\"\n"); | 1595 | " is \"1\"\n"); |
1774 | return -EINVAL; | 1596 | return -EINVAL; |
1775 | } | 1597 | } |
1776 | if (se_dev->se_dev_ptr) { | ||
1777 | pr_err("se_dev->se_dev_ptr already set for storage" | ||
1778 | " object\n"); | ||
1779 | return -EEXIST; | ||
1780 | } | ||
1781 | |||
1782 | if (t->check_configfs_dev_params(hba, se_dev) < 0) | ||
1783 | return -EINVAL; | ||
1784 | |||
1785 | dev = t->create_virtdevice(hba, se_dev, se_dev->se_dev_su_ptr); | ||
1786 | if (IS_ERR(dev)) | ||
1787 | return PTR_ERR(dev); | ||
1788 | else if (!dev) | ||
1789 | return -EINVAL; | ||
1790 | |||
1791 | se_dev->se_dev_ptr = dev; | ||
1792 | pr_debug("Target_Core_ConfigFS: Registered se_dev->se_dev_ptr:" | ||
1793 | " %p\n", se_dev->se_dev_ptr); | ||
1794 | 1598 | ||
1599 | ret = target_configure_device(dev); | ||
1600 | if (ret) | ||
1601 | return ret; | ||
1795 | return count; | 1602 | return count; |
1796 | } | 1603 | } |
1797 | 1604 | ||
@@ -1805,26 +1612,15 @@ static struct target_core_configfs_attribute target_core_attr_dev_enable = { | |||
1805 | 1612 | ||
1806 | static ssize_t target_core_show_alua_lu_gp(void *p, char *page) | 1613 | static ssize_t target_core_show_alua_lu_gp(void *p, char *page) |
1807 | { | 1614 | { |
1808 | struct se_device *dev; | 1615 | struct se_device *dev = p; |
1809 | struct se_subsystem_dev *su_dev = p; | ||
1810 | struct config_item *lu_ci; | 1616 | struct config_item *lu_ci; |
1811 | struct t10_alua_lu_gp *lu_gp; | 1617 | struct t10_alua_lu_gp *lu_gp; |
1812 | struct t10_alua_lu_gp_member *lu_gp_mem; | 1618 | struct t10_alua_lu_gp_member *lu_gp_mem; |
1813 | ssize_t len = 0; | 1619 | ssize_t len = 0; |
1814 | 1620 | ||
1815 | dev = su_dev->se_dev_ptr; | ||
1816 | if (!dev) | ||
1817 | return -ENODEV; | ||
1818 | |||
1819 | if (su_dev->t10_alua.alua_type != SPC3_ALUA_EMULATED) | ||
1820 | return len; | ||
1821 | |||
1822 | lu_gp_mem = dev->dev_alua_lu_gp_mem; | 1621 | lu_gp_mem = dev->dev_alua_lu_gp_mem; |
1823 | if (!lu_gp_mem) { | 1622 | if (!lu_gp_mem) |
1824 | pr_err("NULL struct se_device->dev_alua_lu_gp_mem" | 1623 | return 0; |
1825 | " pointer\n"); | ||
1826 | return -EINVAL; | ||
1827 | } | ||
1828 | 1624 | ||
1829 | spin_lock(&lu_gp_mem->lu_gp_mem_lock); | 1625 | spin_lock(&lu_gp_mem->lu_gp_mem_lock); |
1830 | lu_gp = lu_gp_mem->lu_gp; | 1626 | lu_gp = lu_gp_mem->lu_gp; |
@@ -1843,24 +1639,17 @@ static ssize_t target_core_store_alua_lu_gp( | |||
1843 | const char *page, | 1639 | const char *page, |
1844 | size_t count) | 1640 | size_t count) |
1845 | { | 1641 | { |
1846 | struct se_device *dev; | 1642 | struct se_device *dev = p; |
1847 | struct se_subsystem_dev *su_dev = p; | 1643 | struct se_hba *hba = dev->se_hba; |
1848 | struct se_hba *hba = su_dev->se_dev_hba; | ||
1849 | struct t10_alua_lu_gp *lu_gp = NULL, *lu_gp_new = NULL; | 1644 | struct t10_alua_lu_gp *lu_gp = NULL, *lu_gp_new = NULL; |
1850 | struct t10_alua_lu_gp_member *lu_gp_mem; | 1645 | struct t10_alua_lu_gp_member *lu_gp_mem; |
1851 | unsigned char buf[LU_GROUP_NAME_BUF]; | 1646 | unsigned char buf[LU_GROUP_NAME_BUF]; |
1852 | int move = 0; | 1647 | int move = 0; |
1853 | 1648 | ||
1854 | dev = su_dev->se_dev_ptr; | 1649 | lu_gp_mem = dev->dev_alua_lu_gp_mem; |
1855 | if (!dev) | 1650 | if (!lu_gp_mem) |
1856 | return -ENODEV; | 1651 | return 0; |
1857 | 1652 | ||
1858 | if (su_dev->t10_alua.alua_type != SPC3_ALUA_EMULATED) { | ||
1859 | pr_warn("SPC3_ALUA_EMULATED not enabled for %s/%s\n", | ||
1860 | config_item_name(&hba->hba_group.cg_item), | ||
1861 | config_item_name(&su_dev->se_dev_group.cg_item)); | ||
1862 | return -EINVAL; | ||
1863 | } | ||
1864 | if (count > LU_GROUP_NAME_BUF) { | 1653 | if (count > LU_GROUP_NAME_BUF) { |
1865 | pr_err("ALUA LU Group Alias too large!\n"); | 1654 | pr_err("ALUA LU Group Alias too large!\n"); |
1866 | return -EINVAL; | 1655 | return -EINVAL; |
@@ -1881,14 +1670,6 @@ static ssize_t target_core_store_alua_lu_gp( | |||
1881 | if (!lu_gp_new) | 1670 | if (!lu_gp_new) |
1882 | return -ENODEV; | 1671 | return -ENODEV; |
1883 | } | 1672 | } |
1884 | lu_gp_mem = dev->dev_alua_lu_gp_mem; | ||
1885 | if (!lu_gp_mem) { | ||
1886 | if (lu_gp_new) | ||
1887 | core_alua_put_lu_gp_from_name(lu_gp_new); | ||
1888 | pr_err("NULL struct se_device->dev_alua_lu_gp_mem" | ||
1889 | " pointer\n"); | ||
1890 | return -EINVAL; | ||
1891 | } | ||
1892 | 1673 | ||
1893 | spin_lock(&lu_gp_mem->lu_gp_mem_lock); | 1674 | spin_lock(&lu_gp_mem->lu_gp_mem_lock); |
1894 | lu_gp = lu_gp_mem->lu_gp; | 1675 | lu_gp = lu_gp_mem->lu_gp; |
@@ -1902,7 +1683,7 @@ static ssize_t target_core_store_alua_lu_gp( | |||
1902 | " from ALUA LU Group: core/alua/lu_gps/%s, ID:" | 1683 | " from ALUA LU Group: core/alua/lu_gps/%s, ID:" |
1903 | " %hu\n", | 1684 | " %hu\n", |
1904 | config_item_name(&hba->hba_group.cg_item), | 1685 | config_item_name(&hba->hba_group.cg_item), |
1905 | config_item_name(&su_dev->se_dev_group.cg_item), | 1686 | config_item_name(&dev->dev_group.cg_item), |
1906 | config_item_name(&lu_gp->lu_gp_group.cg_item), | 1687 | config_item_name(&lu_gp->lu_gp_group.cg_item), |
1907 | lu_gp->lu_gp_id); | 1688 | lu_gp->lu_gp_id); |
1908 | 1689 | ||
@@ -1927,7 +1708,7 @@ static ssize_t target_core_store_alua_lu_gp( | |||
1927 | " core/alua/lu_gps/%s, ID: %hu\n", | 1708 | " core/alua/lu_gps/%s, ID: %hu\n", |
1928 | (move) ? "Moving" : "Adding", | 1709 | (move) ? "Moving" : "Adding", |
1929 | config_item_name(&hba->hba_group.cg_item), | 1710 | config_item_name(&hba->hba_group.cg_item), |
1930 | config_item_name(&su_dev->se_dev_group.cg_item), | 1711 | config_item_name(&dev->dev_group.cg_item), |
1931 | config_item_name(&lu_gp_new->lu_gp_group.cg_item), | 1712 | config_item_name(&lu_gp_new->lu_gp_group.cg_item), |
1932 | lu_gp_new->lu_gp_id); | 1713 | lu_gp_new->lu_gp_id); |
1933 | 1714 | ||
@@ -1955,69 +1736,44 @@ static struct configfs_attribute *lio_core_dev_attrs[] = { | |||
1955 | 1736 | ||
1956 | static void target_core_dev_release(struct config_item *item) | 1737 | static void target_core_dev_release(struct config_item *item) |
1957 | { | 1738 | { |
1958 | struct se_subsystem_dev *se_dev = container_of(to_config_group(item), | 1739 | struct config_group *dev_cg = to_config_group(item); |
1959 | struct se_subsystem_dev, se_dev_group); | 1740 | struct se_device *dev = |
1960 | struct se_hba *hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item); | 1741 | container_of(dev_cg, struct se_device, dev_group); |
1961 | struct se_subsystem_api *t = hba->transport; | ||
1962 | struct config_group *dev_cg = &se_dev->se_dev_group; | ||
1963 | 1742 | ||
1964 | kfree(dev_cg->default_groups); | 1743 | kfree(dev_cg->default_groups); |
1965 | /* | 1744 | target_free_device(dev); |
1966 | * This pointer will set when the storage is enabled with: | ||
1967 | *`echo 1 > $CONFIGFS/core/$HBA/$DEV/dev_enable` | ||
1968 | */ | ||
1969 | if (se_dev->se_dev_ptr) { | ||
1970 | pr_debug("Target_Core_ConfigFS: Calling se_free_" | ||
1971 | "virtual_device() for se_dev_ptr: %p\n", | ||
1972 | se_dev->se_dev_ptr); | ||
1973 | |||
1974 | se_free_virtual_device(se_dev->se_dev_ptr, hba); | ||
1975 | } else { | ||
1976 | /* | ||
1977 | * Release struct se_subsystem_dev->se_dev_su_ptr.. | ||
1978 | */ | ||
1979 | pr_debug("Target_Core_ConfigFS: Calling t->free_" | ||
1980 | "device() for se_dev_su_ptr: %p\n", | ||
1981 | se_dev->se_dev_su_ptr); | ||
1982 | |||
1983 | t->free_device(se_dev->se_dev_su_ptr); | ||
1984 | } | ||
1985 | |||
1986 | pr_debug("Target_Core_ConfigFS: Deallocating se_subsystem" | ||
1987 | "_dev_t: %p\n", se_dev); | ||
1988 | kfree(se_dev); | ||
1989 | } | 1745 | } |
1990 | 1746 | ||
1991 | static ssize_t target_core_dev_show(struct config_item *item, | 1747 | static ssize_t target_core_dev_show(struct config_item *item, |
1992 | struct configfs_attribute *attr, | 1748 | struct configfs_attribute *attr, |
1993 | char *page) | 1749 | char *page) |
1994 | { | 1750 | { |
1995 | struct se_subsystem_dev *se_dev = container_of( | 1751 | struct config_group *dev_cg = to_config_group(item); |
1996 | to_config_group(item), struct se_subsystem_dev, | 1752 | struct se_device *dev = |
1997 | se_dev_group); | 1753 | container_of(dev_cg, struct se_device, dev_group); |
1998 | struct target_core_configfs_attribute *tc_attr = container_of( | 1754 | struct target_core_configfs_attribute *tc_attr = container_of( |
1999 | attr, struct target_core_configfs_attribute, attr); | 1755 | attr, struct target_core_configfs_attribute, attr); |
2000 | 1756 | ||
2001 | if (!tc_attr->show) | 1757 | if (!tc_attr->show) |
2002 | return -EINVAL; | 1758 | return -EINVAL; |
2003 | 1759 | ||
2004 | return tc_attr->show(se_dev, page); | 1760 | return tc_attr->show(dev, page); |
2005 | } | 1761 | } |
2006 | 1762 | ||
2007 | static ssize_t target_core_dev_store(struct config_item *item, | 1763 | static ssize_t target_core_dev_store(struct config_item *item, |
2008 | struct configfs_attribute *attr, | 1764 | struct configfs_attribute *attr, |
2009 | const char *page, size_t count) | 1765 | const char *page, size_t count) |
2010 | { | 1766 | { |
2011 | struct se_subsystem_dev *se_dev = container_of( | 1767 | struct config_group *dev_cg = to_config_group(item); |
2012 | to_config_group(item), struct se_subsystem_dev, | 1768 | struct se_device *dev = |
2013 | se_dev_group); | 1769 | container_of(dev_cg, struct se_device, dev_group); |
2014 | struct target_core_configfs_attribute *tc_attr = container_of( | 1770 | struct target_core_configfs_attribute *tc_attr = container_of( |
2015 | attr, struct target_core_configfs_attribute, attr); | 1771 | attr, struct target_core_configfs_attribute, attr); |
2016 | 1772 | ||
2017 | if (!tc_attr->store) | 1773 | if (!tc_attr->store) |
2018 | return -EINVAL; | 1774 | return -EINVAL; |
2019 | 1775 | ||
2020 | return tc_attr->store(se_dev, page, count); | 1776 | return tc_attr->store(dev, page, count); |
2021 | } | 1777 | } |
2022 | 1778 | ||
2023 | static struct configfs_item_operations target_core_dev_item_ops = { | 1779 | static struct configfs_item_operations target_core_dev_item_ops = { |
@@ -2107,7 +1863,6 @@ static ssize_t target_core_alua_lu_gp_show_attr_members( | |||
2107 | { | 1863 | { |
2108 | struct se_device *dev; | 1864 | struct se_device *dev; |
2109 | struct se_hba *hba; | 1865 | struct se_hba *hba; |
2110 | struct se_subsystem_dev *su_dev; | ||
2111 | struct t10_alua_lu_gp_member *lu_gp_mem; | 1866 | struct t10_alua_lu_gp_member *lu_gp_mem; |
2112 | ssize_t len = 0, cur_len; | 1867 | ssize_t len = 0, cur_len; |
2113 | unsigned char buf[LU_GROUP_NAME_BUF]; | 1868 | unsigned char buf[LU_GROUP_NAME_BUF]; |
@@ -2117,12 +1872,11 @@ static ssize_t target_core_alua_lu_gp_show_attr_members( | |||
2117 | spin_lock(&lu_gp->lu_gp_lock); | 1872 | spin_lock(&lu_gp->lu_gp_lock); |
2118 | list_for_each_entry(lu_gp_mem, &lu_gp->lu_gp_mem_list, lu_gp_mem_list) { | 1873 | list_for_each_entry(lu_gp_mem, &lu_gp->lu_gp_mem_list, lu_gp_mem_list) { |
2119 | dev = lu_gp_mem->lu_gp_mem_dev; | 1874 | dev = lu_gp_mem->lu_gp_mem_dev; |
2120 | su_dev = dev->se_sub_dev; | 1875 | hba = dev->se_hba; |
2121 | hba = su_dev->se_dev_hba; | ||
2122 | 1876 | ||
2123 | cur_len = snprintf(buf, LU_GROUP_NAME_BUF, "%s/%s\n", | 1877 | cur_len = snprintf(buf, LU_GROUP_NAME_BUF, "%s/%s\n", |
2124 | config_item_name(&hba->hba_group.cg_item), | 1878 | config_item_name(&hba->hba_group.cg_item), |
2125 | config_item_name(&su_dev->se_dev_group.cg_item)); | 1879 | config_item_name(&dev->dev_group.cg_item)); |
2126 | cur_len++; /* Extra byte for NULL terminator */ | 1880 | cur_len++; /* Extra byte for NULL terminator */ |
2127 | 1881 | ||
2128 | if ((cur_len + len) > PAGE_SIZE) { | 1882 | if ((cur_len + len) > PAGE_SIZE) { |
@@ -2260,7 +2014,7 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_state( | |||
2260 | const char *page, | 2014 | const char *page, |
2261 | size_t count) | 2015 | size_t count) |
2262 | { | 2016 | { |
2263 | struct se_subsystem_dev *su_dev = tg_pt_gp->tg_pt_gp_su_dev; | 2017 | struct se_device *dev = tg_pt_gp->tg_pt_gp_dev; |
2264 | unsigned long tmp; | 2018 | unsigned long tmp; |
2265 | int new_state, ret; | 2019 | int new_state, ret; |
2266 | 2020 | ||
@@ -2284,7 +2038,7 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_state( | |||
2284 | return -EINVAL; | 2038 | return -EINVAL; |
2285 | } | 2039 | } |
2286 | 2040 | ||
2287 | ret = core_alua_do_port_transition(tg_pt_gp, su_dev->se_dev_ptr, | 2041 | ret = core_alua_do_port_transition(tg_pt_gp, dev, |
2288 | NULL, NULL, new_state, 0); | 2042 | NULL, NULL, new_state, 0); |
2289 | return (!ret) ? count : -EINVAL; | 2043 | return (!ret) ? count : -EINVAL; |
2290 | } | 2044 | } |
@@ -2620,11 +2374,10 @@ static struct config_group *target_core_alua_create_tg_pt_gp( | |||
2620 | struct t10_alua *alua = container_of(group, struct t10_alua, | 2374 | struct t10_alua *alua = container_of(group, struct t10_alua, |
2621 | alua_tg_pt_gps_group); | 2375 | alua_tg_pt_gps_group); |
2622 | struct t10_alua_tg_pt_gp *tg_pt_gp; | 2376 | struct t10_alua_tg_pt_gp *tg_pt_gp; |
2623 | struct se_subsystem_dev *su_dev = alua->t10_sub_dev; | ||
2624 | struct config_group *alua_tg_pt_gp_cg = NULL; | 2377 | struct config_group *alua_tg_pt_gp_cg = NULL; |
2625 | struct config_item *alua_tg_pt_gp_ci = NULL; | 2378 | struct config_item *alua_tg_pt_gp_ci = NULL; |
2626 | 2379 | ||
2627 | tg_pt_gp = core_alua_allocate_tg_pt_gp(su_dev, name, 0); | 2380 | tg_pt_gp = core_alua_allocate_tg_pt_gp(alua->t10_dev, name, 0); |
2628 | if (!tg_pt_gp) | 2381 | if (!tg_pt_gp) |
2629 | return NULL; | 2382 | return NULL; |
2630 | 2383 | ||
@@ -2721,10 +2474,10 @@ static struct config_group *target_core_make_subdev( | |||
2721 | const char *name) | 2474 | const char *name) |
2722 | { | 2475 | { |
2723 | struct t10_alua_tg_pt_gp *tg_pt_gp; | 2476 | struct t10_alua_tg_pt_gp *tg_pt_gp; |
2724 | struct se_subsystem_dev *se_dev; | ||
2725 | struct se_subsystem_api *t; | 2477 | struct se_subsystem_api *t; |
2726 | struct config_item *hba_ci = &group->cg_item; | 2478 | struct config_item *hba_ci = &group->cg_item; |
2727 | struct se_hba *hba = item_to_hba(hba_ci); | 2479 | struct se_hba *hba = item_to_hba(hba_ci); |
2480 | struct se_device *dev; | ||
2728 | struct config_group *dev_cg = NULL, *tg_pt_gp_cg = NULL; | 2481 | struct config_group *dev_cg = NULL, *tg_pt_gp_cg = NULL; |
2729 | struct config_group *dev_stat_grp = NULL; | 2482 | struct config_group *dev_stat_grp = NULL; |
2730 | int errno = -ENOMEM, ret; | 2483 | int errno = -ENOMEM, ret; |
@@ -2737,120 +2490,80 @@ static struct config_group *target_core_make_subdev( | |||
2737 | */ | 2490 | */ |
2738 | t = hba->transport; | 2491 | t = hba->transport; |
2739 | 2492 | ||
2740 | se_dev = kzalloc(sizeof(struct se_subsystem_dev), GFP_KERNEL); | 2493 | dev = target_alloc_device(hba, name); |
2741 | if (!se_dev) { | 2494 | if (!dev) |
2742 | pr_err("Unable to allocate memory for" | 2495 | goto out_unlock; |
2743 | " struct se_subsystem_dev\n"); | 2496 | |
2744 | goto unlock; | 2497 | dev_cg = &dev->dev_group; |
2745 | } | 2498 | |
2746 | INIT_LIST_HEAD(&se_dev->t10_wwn.t10_vpd_list); | 2499 | dev_cg->default_groups = kmalloc(sizeof(struct config_group *) * 6, |
2747 | spin_lock_init(&se_dev->t10_wwn.t10_vpd_lock); | ||
2748 | INIT_LIST_HEAD(&se_dev->t10_pr.registration_list); | ||
2749 | INIT_LIST_HEAD(&se_dev->t10_pr.aptpl_reg_list); | ||
2750 | spin_lock_init(&se_dev->t10_pr.registration_lock); | ||
2751 | spin_lock_init(&se_dev->t10_pr.aptpl_reg_lock); | ||
2752 | INIT_LIST_HEAD(&se_dev->t10_alua.tg_pt_gps_list); | ||
2753 | spin_lock_init(&se_dev->t10_alua.tg_pt_gps_lock); | ||
2754 | spin_lock_init(&se_dev->se_dev_lock); | ||
2755 | se_dev->t10_pr.pr_aptpl_buf_len = PR_APTPL_BUF_LEN; | ||
2756 | se_dev->t10_wwn.t10_sub_dev = se_dev; | ||
2757 | se_dev->t10_alua.t10_sub_dev = se_dev; | ||
2758 | se_dev->se_dev_attrib.da_sub_dev = se_dev; | ||
2759 | |||
2760 | se_dev->se_dev_hba = hba; | ||
2761 | dev_cg = &se_dev->se_dev_group; | ||
2762 | |||
2763 | dev_cg->default_groups = kzalloc(sizeof(struct config_group) * 7, | ||
2764 | GFP_KERNEL); | 2500 | GFP_KERNEL); |
2765 | if (!dev_cg->default_groups) | 2501 | if (!dev_cg->default_groups) |
2766 | goto out; | 2502 | goto out_free_device; |
2767 | /* | ||
2768 | * Set se_dev_su_ptr from struct se_subsystem_api returned void ptr | ||
2769 | * for ->allocate_virtdevice() | ||
2770 | * | ||
2771 | * se_dev->se_dev_ptr will be set after ->create_virtdev() | ||
2772 | * has been called successfully in the next level up in the | ||
2773 | * configfs tree for device object's struct config_group. | ||
2774 | */ | ||
2775 | se_dev->se_dev_su_ptr = t->allocate_virtdevice(hba, name); | ||
2776 | if (!se_dev->se_dev_su_ptr) { | ||
2777 | pr_err("Unable to locate subsystem dependent pointer" | ||
2778 | " from allocate_virtdevice()\n"); | ||
2779 | goto out; | ||
2780 | } | ||
2781 | 2503 | ||
2782 | config_group_init_type_name(&se_dev->se_dev_group, name, | 2504 | config_group_init_type_name(dev_cg, name, &target_core_dev_cit); |
2783 | &target_core_dev_cit); | 2505 | config_group_init_type_name(&dev->dev_attrib.da_group, "attrib", |
2784 | config_group_init_type_name(&se_dev->se_dev_attrib.da_group, "attrib", | ||
2785 | &target_core_dev_attrib_cit); | 2506 | &target_core_dev_attrib_cit); |
2786 | config_group_init_type_name(&se_dev->se_dev_pr_group, "pr", | 2507 | config_group_init_type_name(&dev->dev_pr_group, "pr", |
2787 | &target_core_dev_pr_cit); | 2508 | &target_core_dev_pr_cit); |
2788 | config_group_init_type_name(&se_dev->t10_wwn.t10_wwn_group, "wwn", | 2509 | config_group_init_type_name(&dev->t10_wwn.t10_wwn_group, "wwn", |
2789 | &target_core_dev_wwn_cit); | 2510 | &target_core_dev_wwn_cit); |
2790 | config_group_init_type_name(&se_dev->t10_alua.alua_tg_pt_gps_group, | 2511 | config_group_init_type_name(&dev->t10_alua.alua_tg_pt_gps_group, |
2791 | "alua", &target_core_alua_tg_pt_gps_cit); | 2512 | "alua", &target_core_alua_tg_pt_gps_cit); |
2792 | config_group_init_type_name(&se_dev->dev_stat_grps.stat_group, | 2513 | config_group_init_type_name(&dev->dev_stat_grps.stat_group, |
2793 | "statistics", &target_core_stat_cit); | 2514 | "statistics", &target_core_stat_cit); |
2794 | 2515 | ||
2795 | dev_cg->default_groups[0] = &se_dev->se_dev_attrib.da_group; | 2516 | dev_cg->default_groups[0] = &dev->dev_attrib.da_group; |
2796 | dev_cg->default_groups[1] = &se_dev->se_dev_pr_group; | 2517 | dev_cg->default_groups[1] = &dev->dev_pr_group; |
2797 | dev_cg->default_groups[2] = &se_dev->t10_wwn.t10_wwn_group; | 2518 | dev_cg->default_groups[2] = &dev->t10_wwn.t10_wwn_group; |
2798 | dev_cg->default_groups[3] = &se_dev->t10_alua.alua_tg_pt_gps_group; | 2519 | dev_cg->default_groups[3] = &dev->t10_alua.alua_tg_pt_gps_group; |
2799 | dev_cg->default_groups[4] = &se_dev->dev_stat_grps.stat_group; | 2520 | dev_cg->default_groups[4] = &dev->dev_stat_grps.stat_group; |
2800 | dev_cg->default_groups[5] = NULL; | 2521 | dev_cg->default_groups[5] = NULL; |
2801 | /* | 2522 | /* |
2802 | * Add core/$HBA/$DEV/alua/default_tg_pt_gp | 2523 | * Add core/$HBA/$DEV/alua/default_tg_pt_gp |
2803 | */ | 2524 | */ |
2804 | tg_pt_gp = core_alua_allocate_tg_pt_gp(se_dev, "default_tg_pt_gp", 1); | 2525 | tg_pt_gp = core_alua_allocate_tg_pt_gp(dev, "default_tg_pt_gp", 1); |
2805 | if (!tg_pt_gp) | 2526 | if (!tg_pt_gp) |
2806 | goto out; | 2527 | goto out_free_dev_cg_default_groups; |
2528 | dev->t10_alua.default_tg_pt_gp = tg_pt_gp; | ||
2807 | 2529 | ||
2808 | tg_pt_gp_cg = &se_dev->t10_alua.alua_tg_pt_gps_group; | 2530 | tg_pt_gp_cg = &dev->t10_alua.alua_tg_pt_gps_group; |
2809 | tg_pt_gp_cg->default_groups = kzalloc(sizeof(struct config_group) * 2, | 2531 | tg_pt_gp_cg->default_groups = kmalloc(sizeof(struct config_group *) * 2, |
2810 | GFP_KERNEL); | 2532 | GFP_KERNEL); |
2811 | if (!tg_pt_gp_cg->default_groups) { | 2533 | if (!tg_pt_gp_cg->default_groups) { |
2812 | pr_err("Unable to allocate tg_pt_gp_cg->" | 2534 | pr_err("Unable to allocate tg_pt_gp_cg->" |
2813 | "default_groups\n"); | 2535 | "default_groups\n"); |
2814 | goto out; | 2536 | goto out_free_tg_pt_gp; |
2815 | } | 2537 | } |
2816 | 2538 | ||
2817 | config_group_init_type_name(&tg_pt_gp->tg_pt_gp_group, | 2539 | config_group_init_type_name(&tg_pt_gp->tg_pt_gp_group, |
2818 | "default_tg_pt_gp", &target_core_alua_tg_pt_gp_cit); | 2540 | "default_tg_pt_gp", &target_core_alua_tg_pt_gp_cit); |
2819 | tg_pt_gp_cg->default_groups[0] = &tg_pt_gp->tg_pt_gp_group; | 2541 | tg_pt_gp_cg->default_groups[0] = &tg_pt_gp->tg_pt_gp_group; |
2820 | tg_pt_gp_cg->default_groups[1] = NULL; | 2542 | tg_pt_gp_cg->default_groups[1] = NULL; |
2821 | se_dev->t10_alua.default_tg_pt_gp = tg_pt_gp; | ||
2822 | /* | 2543 | /* |
2823 | * Add core/$HBA/$DEV/statistics/ default groups | 2544 | * Add core/$HBA/$DEV/statistics/ default groups |
2824 | */ | 2545 | */ |
2825 | dev_stat_grp = &se_dev->dev_stat_grps.stat_group; | 2546 | dev_stat_grp = &dev->dev_stat_grps.stat_group; |
2826 | dev_stat_grp->default_groups = kzalloc(sizeof(struct config_group) * 4, | 2547 | dev_stat_grp->default_groups = kmalloc(sizeof(struct config_group *) * 4, |
2827 | GFP_KERNEL); | 2548 | GFP_KERNEL); |
2828 | if (!dev_stat_grp->default_groups) { | 2549 | if (!dev_stat_grp->default_groups) { |
2829 | pr_err("Unable to allocate dev_stat_grp->default_groups\n"); | 2550 | pr_err("Unable to allocate dev_stat_grp->default_groups\n"); |
2830 | goto out; | 2551 | goto out_free_tg_pt_gp_cg_default_groups; |
2831 | } | 2552 | } |
2832 | target_stat_setup_dev_default_groups(se_dev); | 2553 | target_stat_setup_dev_default_groups(dev); |
2833 | |||
2834 | pr_debug("Target_Core_ConfigFS: Allocated struct se_subsystem_dev:" | ||
2835 | " %p se_dev_su_ptr: %p\n", se_dev, se_dev->se_dev_su_ptr); | ||
2836 | 2554 | ||
2837 | mutex_unlock(&hba->hba_access_mutex); | 2555 | mutex_unlock(&hba->hba_access_mutex); |
2838 | return &se_dev->se_dev_group; | 2556 | return dev_cg; |
2839 | out: | 2557 | |
2840 | if (se_dev->t10_alua.default_tg_pt_gp) { | 2558 | out_free_tg_pt_gp_cg_default_groups: |
2841 | core_alua_free_tg_pt_gp(se_dev->t10_alua.default_tg_pt_gp); | 2559 | kfree(tg_pt_gp_cg->default_groups); |
2842 | se_dev->t10_alua.default_tg_pt_gp = NULL; | 2560 | out_free_tg_pt_gp: |
2843 | } | 2561 | core_alua_free_tg_pt_gp(tg_pt_gp); |
2844 | if (dev_stat_grp) | 2562 | out_free_dev_cg_default_groups: |
2845 | kfree(dev_stat_grp->default_groups); | 2563 | kfree(dev_cg->default_groups); |
2846 | if (tg_pt_gp_cg) | 2564 | out_free_device: |
2847 | kfree(tg_pt_gp_cg->default_groups); | 2565 | target_free_device(dev); |
2848 | if (dev_cg) | 2566 | out_unlock: |
2849 | kfree(dev_cg->default_groups); | ||
2850 | if (se_dev->se_dev_su_ptr) | ||
2851 | t->free_device(se_dev->se_dev_su_ptr); | ||
2852 | kfree(se_dev); | ||
2853 | unlock: | ||
2854 | mutex_unlock(&hba->hba_access_mutex); | 2567 | mutex_unlock(&hba->hba_access_mutex); |
2855 | return ERR_PTR(errno); | 2568 | return ERR_PTR(errno); |
2856 | } | 2569 | } |
@@ -2859,18 +2572,19 @@ static void target_core_drop_subdev( | |||
2859 | struct config_group *group, | 2572 | struct config_group *group, |
2860 | struct config_item *item) | 2573 | struct config_item *item) |
2861 | { | 2574 | { |
2862 | struct se_subsystem_dev *se_dev = container_of(to_config_group(item), | 2575 | struct config_group *dev_cg = to_config_group(item); |
2863 | struct se_subsystem_dev, se_dev_group); | 2576 | struct se_device *dev = |
2577 | container_of(dev_cg, struct se_device, dev_group); | ||
2864 | struct se_hba *hba; | 2578 | struct se_hba *hba; |
2865 | struct config_item *df_item; | 2579 | struct config_item *df_item; |
2866 | struct config_group *dev_cg, *tg_pt_gp_cg, *dev_stat_grp; | 2580 | struct config_group *tg_pt_gp_cg, *dev_stat_grp; |
2867 | int i; | 2581 | int i; |
2868 | 2582 | ||
2869 | hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item); | 2583 | hba = item_to_hba(&dev->se_hba->hba_group.cg_item); |
2870 | 2584 | ||
2871 | mutex_lock(&hba->hba_access_mutex); | 2585 | mutex_lock(&hba->hba_access_mutex); |
2872 | 2586 | ||
2873 | dev_stat_grp = &se_dev->dev_stat_grps.stat_group; | 2587 | dev_stat_grp = &dev->dev_stat_grps.stat_group; |
2874 | for (i = 0; dev_stat_grp->default_groups[i]; i++) { | 2588 | for (i = 0; dev_stat_grp->default_groups[i]; i++) { |
2875 | df_item = &dev_stat_grp->default_groups[i]->cg_item; | 2589 | df_item = &dev_stat_grp->default_groups[i]->cg_item; |
2876 | dev_stat_grp->default_groups[i] = NULL; | 2590 | dev_stat_grp->default_groups[i] = NULL; |
@@ -2878,7 +2592,7 @@ static void target_core_drop_subdev( | |||
2878 | } | 2592 | } |
2879 | kfree(dev_stat_grp->default_groups); | 2593 | kfree(dev_stat_grp->default_groups); |
2880 | 2594 | ||
2881 | tg_pt_gp_cg = &se_dev->t10_alua.alua_tg_pt_gps_group; | 2595 | tg_pt_gp_cg = &dev->t10_alua.alua_tg_pt_gps_group; |
2882 | for (i = 0; tg_pt_gp_cg->default_groups[i]; i++) { | 2596 | for (i = 0; tg_pt_gp_cg->default_groups[i]; i++) { |
2883 | df_item = &tg_pt_gp_cg->default_groups[i]->cg_item; | 2597 | df_item = &tg_pt_gp_cg->default_groups[i]->cg_item; |
2884 | tg_pt_gp_cg->default_groups[i] = NULL; | 2598 | tg_pt_gp_cg->default_groups[i] = NULL; |
@@ -2889,17 +2603,15 @@ static void target_core_drop_subdev( | |||
2889 | * core_alua_free_tg_pt_gp() is called from ->default_tg_pt_gp | 2603 | * core_alua_free_tg_pt_gp() is called from ->default_tg_pt_gp |
2890 | * directly from target_core_alua_tg_pt_gp_release(). | 2604 | * directly from target_core_alua_tg_pt_gp_release(). |
2891 | */ | 2605 | */ |
2892 | se_dev->t10_alua.default_tg_pt_gp = NULL; | 2606 | dev->t10_alua.default_tg_pt_gp = NULL; |
2893 | 2607 | ||
2894 | dev_cg = &se_dev->se_dev_group; | ||
2895 | for (i = 0; dev_cg->default_groups[i]; i++) { | 2608 | for (i = 0; dev_cg->default_groups[i]; i++) { |
2896 | df_item = &dev_cg->default_groups[i]->cg_item; | 2609 | df_item = &dev_cg->default_groups[i]->cg_item; |
2897 | dev_cg->default_groups[i] = NULL; | 2610 | dev_cg->default_groups[i] = NULL; |
2898 | config_item_put(df_item); | 2611 | config_item_put(df_item); |
2899 | } | 2612 | } |
2900 | /* | 2613 | /* |
2901 | * The releasing of se_dev and associated se_dev->se_dev_ptr is done | 2614 | * se_dev is released from target_core_dev_item_ops->release() |
2902 | * from target_core_dev_item_ops->release() ->target_core_dev_release(). | ||
2903 | */ | 2615 | */ |
2904 | config_item_put(item); | 2616 | config_item_put(item); |
2905 | mutex_unlock(&hba->hba_access_mutex); | 2617 | mutex_unlock(&hba->hba_access_mutex); |
@@ -2962,13 +2674,10 @@ static ssize_t target_core_hba_store_attr_hba_mode(struct se_hba *hba, | |||
2962 | return -EINVAL; | 2674 | return -EINVAL; |
2963 | } | 2675 | } |
2964 | 2676 | ||
2965 | spin_lock(&hba->device_lock); | 2677 | if (hba->dev_count) { |
2966 | if (!list_empty(&hba->hba_dev_list)) { | ||
2967 | pr_err("Unable to set hba_mode with active devices\n"); | 2678 | pr_err("Unable to set hba_mode with active devices\n"); |
2968 | spin_unlock(&hba->device_lock); | ||
2969 | return -EINVAL; | 2679 | return -EINVAL; |
2970 | } | 2680 | } |
2971 | spin_unlock(&hba->device_lock); | ||
2972 | 2681 | ||
2973 | ret = transport->pmode_enable_hba(hba, mode_flag); | 2682 | ret = transport->pmode_enable_hba(hba, mode_flag); |
2974 | if (ret < 0) | 2683 | if (ret < 0) |
@@ -3120,7 +2829,7 @@ static int __init target_core_init_configfs(void) | |||
3120 | * and ALUA Logical Unit Group and Target Port Group infrastructure. | 2829 | * and ALUA Logical Unit Group and Target Port Group infrastructure. |
3121 | */ | 2830 | */ |
3122 | target_cg = &subsys->su_group; | 2831 | target_cg = &subsys->su_group; |
3123 | target_cg->default_groups = kzalloc(sizeof(struct config_group) * 2, | 2832 | target_cg->default_groups = kmalloc(sizeof(struct config_group) * 2, |
3124 | GFP_KERNEL); | 2833 | GFP_KERNEL); |
3125 | if (!target_cg->default_groups) { | 2834 | if (!target_cg->default_groups) { |
3126 | pr_err("Unable to allocate target_cg->default_groups\n"); | 2835 | pr_err("Unable to allocate target_cg->default_groups\n"); |
@@ -3136,7 +2845,7 @@ static int __init target_core_init_configfs(void) | |||
3136 | * Create ALUA infrastructure under /sys/kernel/config/target/core/alua/ | 2845 | * Create ALUA infrastructure under /sys/kernel/config/target/core/alua/ |
3137 | */ | 2846 | */ |
3138 | hba_cg = &target_core_hbagroup; | 2847 | hba_cg = &target_core_hbagroup; |
3139 | hba_cg->default_groups = kzalloc(sizeof(struct config_group) * 2, | 2848 | hba_cg->default_groups = kmalloc(sizeof(struct config_group *) * 2, |
3140 | GFP_KERNEL); | 2849 | GFP_KERNEL); |
3141 | if (!hba_cg->default_groups) { | 2850 | if (!hba_cg->default_groups) { |
3142 | pr_err("Unable to allocate hba_cg->default_groups\n"); | 2851 | pr_err("Unable to allocate hba_cg->default_groups\n"); |
@@ -3152,7 +2861,7 @@ static int __init target_core_init_configfs(void) | |||
3152 | * groups under /sys/kernel/config/target/core/alua/ | 2861 | * groups under /sys/kernel/config/target/core/alua/ |
3153 | */ | 2862 | */ |
3154 | alua_cg = &alua_group; | 2863 | alua_cg = &alua_group; |
3155 | alua_cg->default_groups = kzalloc(sizeof(struct config_group) * 2, | 2864 | alua_cg->default_groups = kmalloc(sizeof(struct config_group *) * 2, |
3156 | GFP_KERNEL); | 2865 | GFP_KERNEL); |
3157 | if (!alua_cg->default_groups) { | 2866 | if (!alua_cg->default_groups) { |
3158 | pr_err("Unable to allocate alua_cg->default_groups\n"); | 2867 | pr_err("Unable to allocate alua_cg->default_groups\n"); |
@@ -3174,7 +2883,7 @@ static int __init target_core_init_configfs(void) | |||
3174 | } | 2883 | } |
3175 | 2884 | ||
3176 | lu_gp_cg = &alua_lu_gps_group; | 2885 | lu_gp_cg = &alua_lu_gps_group; |
3177 | lu_gp_cg->default_groups = kzalloc(sizeof(struct config_group) * 2, | 2886 | lu_gp_cg->default_groups = kmalloc(sizeof(struct config_group *) * 2, |
3178 | GFP_KERNEL); | 2887 | GFP_KERNEL); |
3179 | if (!lu_gp_cg->default_groups) { | 2888 | if (!lu_gp_cg->default_groups) { |
3180 | pr_err("Unable to allocate lu_gp_cg->default_groups\n"); | 2889 | pr_err("Unable to allocate lu_gp_cg->default_groups\n"); |
@@ -3206,7 +2915,8 @@ static int __init target_core_init_configfs(void) | |||
3206 | if (ret < 0) | 2915 | if (ret < 0) |
3207 | goto out; | 2916 | goto out; |
3208 | 2917 | ||
3209 | if (core_dev_setup_virtual_lun0() < 0) | 2918 | ret = core_dev_setup_virtual_lun0(); |
2919 | if (ret < 0) | ||
3210 | goto out; | 2920 | goto out; |
3211 | 2921 | ||
3212 | return 0; | 2922 | return 0; |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 8d774da16320..e2695101bb99 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -4,10 +4,7 @@ | |||
4 | * This file contains the TCM Virtual Device and Disk Transport | 4 | * This file contains the TCM Virtual Device and Disk Transport |
5 | * agnostic related functions. | 5 | * agnostic related functions. |
6 | * | 6 | * |
7 | * Copyright (c) 2003, 2004, 2005 PyX Technologies, Inc. | 7 | * (c) Copyright 2003-2012 RisingTide Systems LLC. |
8 | * Copyright (c) 2005-2006 SBE, Inc. All Rights Reserved. | ||
9 | * Copyright (c) 2007-2010 Rising Tide Systems | ||
10 | * Copyright (c) 2008-2010 Linux-iSCSI.org | ||
11 | * | 8 | * |
12 | * Nicholas A. Bellinger <nab@kernel.org> | 9 | * Nicholas A. Bellinger <nab@kernel.org> |
13 | * | 10 | * |
@@ -50,26 +47,20 @@ | |||
50 | #include "target_core_pr.h" | 47 | #include "target_core_pr.h" |
51 | #include "target_core_ua.h" | 48 | #include "target_core_ua.h" |
52 | 49 | ||
53 | static void se_dev_start(struct se_device *dev); | ||
54 | static void se_dev_stop(struct se_device *dev); | ||
55 | |||
56 | static struct se_hba *lun0_hba; | 50 | static struct se_hba *lun0_hba; |
57 | static struct se_subsystem_dev *lun0_su_dev; | ||
58 | /* not static, needed by tpg.c */ | 51 | /* not static, needed by tpg.c */ |
59 | struct se_device *g_lun0_dev; | 52 | struct se_device *g_lun0_dev; |
60 | 53 | ||
61 | int transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) | 54 | sense_reason_t |
55 | transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) | ||
62 | { | 56 | { |
63 | struct se_lun *se_lun = NULL; | 57 | struct se_lun *se_lun = NULL; |
64 | struct se_session *se_sess = se_cmd->se_sess; | 58 | struct se_session *se_sess = se_cmd->se_sess; |
65 | struct se_device *dev; | 59 | struct se_device *dev; |
66 | unsigned long flags; | 60 | unsigned long flags; |
67 | 61 | ||
68 | if (unpacked_lun >= TRANSPORT_MAX_LUNS_PER_TPG) { | 62 | if (unpacked_lun >= TRANSPORT_MAX_LUNS_PER_TPG) |
69 | se_cmd->scsi_sense_reason = TCM_NON_EXISTENT_LUN; | 63 | return TCM_NON_EXISTENT_LUN; |
70 | se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
71 | return -ENODEV; | ||
72 | } | ||
73 | 64 | ||
74 | spin_lock_irqsave(&se_sess->se_node_acl->device_list_lock, flags); | 65 | spin_lock_irqsave(&se_sess->se_node_acl->device_list_lock, flags); |
75 | se_cmd->se_deve = se_sess->se_node_acl->device_list[unpacked_lun]; | 66 | se_cmd->se_deve = se_sess->se_node_acl->device_list[unpacked_lun]; |
@@ -81,14 +72,12 @@ int transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) | |||
81 | 72 | ||
82 | if ((se_cmd->data_direction == DMA_TO_DEVICE) && | 73 | if ((se_cmd->data_direction == DMA_TO_DEVICE) && |
83 | (deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)) { | 74 | (deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)) { |
84 | se_cmd->scsi_sense_reason = TCM_WRITE_PROTECTED; | ||
85 | se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
86 | pr_err("TARGET_CORE[%s]: Detected WRITE_PROTECTED LUN" | 75 | pr_err("TARGET_CORE[%s]: Detected WRITE_PROTECTED LUN" |
87 | " Access for 0x%08x\n", | 76 | " Access for 0x%08x\n", |
88 | se_cmd->se_tfo->get_fabric_name(), | 77 | se_cmd->se_tfo->get_fabric_name(), |
89 | unpacked_lun); | 78 | unpacked_lun); |
90 | spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); | 79 | spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); |
91 | return -EACCES; | 80 | return TCM_WRITE_PROTECTED; |
92 | } | 81 | } |
93 | 82 | ||
94 | if (se_cmd->data_direction == DMA_TO_DEVICE) | 83 | if (se_cmd->data_direction == DMA_TO_DEVICE) |
@@ -113,38 +102,24 @@ int transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) | |||
113 | * MappedLUN=0 exists for this Initiator Port. | 102 | * MappedLUN=0 exists for this Initiator Port. |
114 | */ | 103 | */ |
115 | if (unpacked_lun != 0) { | 104 | if (unpacked_lun != 0) { |
116 | se_cmd->scsi_sense_reason = TCM_NON_EXISTENT_LUN; | ||
117 | se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
118 | pr_err("TARGET_CORE[%s]: Detected NON_EXISTENT_LUN" | 105 | pr_err("TARGET_CORE[%s]: Detected NON_EXISTENT_LUN" |
119 | " Access for 0x%08x\n", | 106 | " Access for 0x%08x\n", |
120 | se_cmd->se_tfo->get_fabric_name(), | 107 | se_cmd->se_tfo->get_fabric_name(), |
121 | unpacked_lun); | 108 | unpacked_lun); |
122 | return -ENODEV; | 109 | return TCM_NON_EXISTENT_LUN; |
123 | } | 110 | } |
124 | /* | 111 | /* |
125 | * Force WRITE PROTECT for virtual LUN 0 | 112 | * Force WRITE PROTECT for virtual LUN 0 |
126 | */ | 113 | */ |
127 | if ((se_cmd->data_direction != DMA_FROM_DEVICE) && | 114 | if ((se_cmd->data_direction != DMA_FROM_DEVICE) && |
128 | (se_cmd->data_direction != DMA_NONE)) { | 115 | (se_cmd->data_direction != DMA_NONE)) |
129 | se_cmd->scsi_sense_reason = TCM_WRITE_PROTECTED; | 116 | return TCM_WRITE_PROTECTED; |
130 | se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
131 | return -EACCES; | ||
132 | } | ||
133 | 117 | ||
134 | se_lun = &se_sess->se_tpg->tpg_virt_lun0; | 118 | se_lun = &se_sess->se_tpg->tpg_virt_lun0; |
135 | se_cmd->se_lun = &se_sess->se_tpg->tpg_virt_lun0; | 119 | se_cmd->se_lun = &se_sess->se_tpg->tpg_virt_lun0; |
136 | se_cmd->orig_fe_lun = 0; | 120 | se_cmd->orig_fe_lun = 0; |
137 | se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; | 121 | se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; |
138 | } | 122 | } |
139 | /* | ||
140 | * Determine if the struct se_lun is online. | ||
141 | * FIXME: Check for LUN_RESET + UNIT Attention | ||
142 | */ | ||
143 | if (se_dev_check_online(se_lun->lun_se_dev) != 0) { | ||
144 | se_cmd->scsi_sense_reason = TCM_NON_EXISTENT_LUN; | ||
145 | se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
146 | return -ENODEV; | ||
147 | } | ||
148 | 123 | ||
149 | /* Directly associate cmd with se_dev */ | 124 | /* Directly associate cmd with se_dev */ |
150 | se_cmd->se_dev = se_lun->lun_se_dev; | 125 | se_cmd->se_dev = se_lun->lun_se_dev; |
@@ -175,11 +150,8 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 unpacked_lun) | |||
175 | struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; | 150 | struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; |
176 | unsigned long flags; | 151 | unsigned long flags; |
177 | 152 | ||
178 | if (unpacked_lun >= TRANSPORT_MAX_LUNS_PER_TPG) { | 153 | if (unpacked_lun >= TRANSPORT_MAX_LUNS_PER_TPG) |
179 | se_cmd->scsi_sense_reason = TCM_NON_EXISTENT_LUN; | ||
180 | se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
181 | return -ENODEV; | 154 | return -ENODEV; |
182 | } | ||
183 | 155 | ||
184 | spin_lock_irqsave(&se_sess->se_node_acl->device_list_lock, flags); | 156 | spin_lock_irqsave(&se_sess->se_node_acl->device_list_lock, flags); |
185 | se_cmd->se_deve = se_sess->se_node_acl->device_list[unpacked_lun]; | 157 | se_cmd->se_deve = se_sess->se_node_acl->device_list[unpacked_lun]; |
@@ -199,15 +171,6 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 unpacked_lun) | |||
199 | " Access for 0x%08x\n", | 171 | " Access for 0x%08x\n", |
200 | se_cmd->se_tfo->get_fabric_name(), | 172 | se_cmd->se_tfo->get_fabric_name(), |
201 | unpacked_lun); | 173 | unpacked_lun); |
202 | se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
203 | return -ENODEV; | ||
204 | } | ||
205 | /* | ||
206 | * Determine if the struct se_lun is online. | ||
207 | * FIXME: Check for LUN_RESET + UNIT Attention | ||
208 | */ | ||
209 | if (se_dev_check_online(se_lun->lun_se_dev) != 0) { | ||
210 | se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
211 | return -ENODEV; | 174 | return -ENODEV; |
212 | } | 175 | } |
213 | 176 | ||
@@ -565,7 +528,6 @@ static void core_export_port( | |||
565 | struct se_port *port, | 528 | struct se_port *port, |
566 | struct se_lun *lun) | 529 | struct se_lun *lun) |
567 | { | 530 | { |
568 | struct se_subsystem_dev *su_dev = dev->se_sub_dev; | ||
569 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem = NULL; | 531 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem = NULL; |
570 | 532 | ||
571 | spin_lock(&dev->se_port_lock); | 533 | spin_lock(&dev->se_port_lock); |
@@ -578,7 +540,8 @@ static void core_export_port( | |||
578 | list_add_tail(&port->sep_list, &dev->dev_sep_list); | 540 | list_add_tail(&port->sep_list, &dev->dev_sep_list); |
579 | spin_unlock(&dev->se_port_lock); | 541 | spin_unlock(&dev->se_port_lock); |
580 | 542 | ||
581 | if (su_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) { | 543 | if (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV && |
544 | !(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) { | ||
582 | tg_pt_gp_mem = core_alua_allocate_tg_pt_gp_mem(port); | 545 | tg_pt_gp_mem = core_alua_allocate_tg_pt_gp_mem(port); |
583 | if (IS_ERR(tg_pt_gp_mem) || !tg_pt_gp_mem) { | 546 | if (IS_ERR(tg_pt_gp_mem) || !tg_pt_gp_mem) { |
584 | pr_err("Unable to allocate t10_alua_tg_pt" | 547 | pr_err("Unable to allocate t10_alua_tg_pt" |
@@ -587,7 +550,7 @@ static void core_export_port( | |||
587 | } | 550 | } |
588 | spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); | 551 | spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); |
589 | __core_alua_attach_tg_pt_gp_mem(tg_pt_gp_mem, | 552 | __core_alua_attach_tg_pt_gp_mem(tg_pt_gp_mem, |
590 | su_dev->t10_alua.default_tg_pt_gp); | 553 | dev->t10_alua.default_tg_pt_gp); |
591 | spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); | 554 | spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); |
592 | pr_debug("%s/%s: Adding to default ALUA Target Port" | 555 | pr_debug("%s/%s: Adding to default ALUA Target Port" |
593 | " Group: alua/default_tg_pt_gp\n", | 556 | " Group: alua/default_tg_pt_gp\n", |
@@ -625,6 +588,7 @@ int core_dev_export( | |||
625 | struct se_portal_group *tpg, | 588 | struct se_portal_group *tpg, |
626 | struct se_lun *lun) | 589 | struct se_lun *lun) |
627 | { | 590 | { |
591 | struct se_hba *hba = dev->se_hba; | ||
628 | struct se_port *port; | 592 | struct se_port *port; |
629 | 593 | ||
630 | port = core_alloc_port(dev); | 594 | port = core_alloc_port(dev); |
@@ -632,9 +596,11 @@ int core_dev_export( | |||
632 | return PTR_ERR(port); | 596 | return PTR_ERR(port); |
633 | 597 | ||
634 | lun->lun_se_dev = dev; | 598 | lun->lun_se_dev = dev; |
635 | se_dev_start(dev); | ||
636 | 599 | ||
637 | atomic_inc(&dev->dev_export_obj.obj_access_count); | 600 | spin_lock(&hba->device_lock); |
601 | dev->export_count++; | ||
602 | spin_unlock(&hba->device_lock); | ||
603 | |||
638 | core_export_port(dev, tpg, port, lun); | 604 | core_export_port(dev, tpg, port, lun); |
639 | return 0; | 605 | return 0; |
640 | } | 606 | } |
@@ -644,6 +610,7 @@ void core_dev_unexport( | |||
644 | struct se_portal_group *tpg, | 610 | struct se_portal_group *tpg, |
645 | struct se_lun *lun) | 611 | struct se_lun *lun) |
646 | { | 612 | { |
613 | struct se_hba *hba = dev->se_hba; | ||
647 | struct se_port *port = lun->lun_sep; | 614 | struct se_port *port = lun->lun_sep; |
648 | 615 | ||
649 | spin_lock(&lun->lun_sep_lock); | 616 | spin_lock(&lun->lun_sep_lock); |
@@ -654,284 +621,54 @@ void core_dev_unexport( | |||
654 | spin_unlock(&lun->lun_sep_lock); | 621 | spin_unlock(&lun->lun_sep_lock); |
655 | 622 | ||
656 | spin_lock(&dev->se_port_lock); | 623 | spin_lock(&dev->se_port_lock); |
657 | atomic_dec(&dev->dev_export_obj.obj_access_count); | ||
658 | core_release_port(dev, port); | 624 | core_release_port(dev, port); |
659 | spin_unlock(&dev->se_port_lock); | 625 | spin_unlock(&dev->se_port_lock); |
660 | 626 | ||
661 | se_dev_stop(dev); | ||
662 | lun->lun_se_dev = NULL; | ||
663 | } | ||
664 | |||
665 | int target_report_luns(struct se_cmd *se_cmd) | ||
666 | { | ||
667 | struct se_dev_entry *deve; | ||
668 | struct se_session *se_sess = se_cmd->se_sess; | ||
669 | unsigned char *buf; | ||
670 | u32 lun_count = 0, offset = 8, i; | ||
671 | |||
672 | if (se_cmd->data_length < 16) { | ||
673 | pr_warn("REPORT LUNS allocation length %u too small\n", | ||
674 | se_cmd->data_length); | ||
675 | se_cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
676 | return -EINVAL; | ||
677 | } | ||
678 | |||
679 | buf = transport_kmap_data_sg(se_cmd); | ||
680 | if (!buf) | ||
681 | return -ENOMEM; | ||
682 | |||
683 | /* | ||
684 | * If no struct se_session pointer is present, this struct se_cmd is | ||
685 | * coming via a target_core_mod PASSTHROUGH op, and not through | ||
686 | * a $FABRIC_MOD. In that case, report LUN=0 only. | ||
687 | */ | ||
688 | if (!se_sess) { | ||
689 | int_to_scsilun(0, (struct scsi_lun *)&buf[offset]); | ||
690 | lun_count = 1; | ||
691 | goto done; | ||
692 | } | ||
693 | |||
694 | spin_lock_irq(&se_sess->se_node_acl->device_list_lock); | ||
695 | for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { | ||
696 | deve = se_sess->se_node_acl->device_list[i]; | ||
697 | if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS)) | ||
698 | continue; | ||
699 | /* | ||
700 | * We determine the correct LUN LIST LENGTH even once we | ||
701 | * have reached the initial allocation length. | ||
702 | * See SPC2-R20 7.19. | ||
703 | */ | ||
704 | lun_count++; | ||
705 | if ((offset + 8) > se_cmd->data_length) | ||
706 | continue; | ||
707 | |||
708 | int_to_scsilun(deve->mapped_lun, (struct scsi_lun *)&buf[offset]); | ||
709 | offset += 8; | ||
710 | } | ||
711 | spin_unlock_irq(&se_sess->se_node_acl->device_list_lock); | ||
712 | |||
713 | /* | ||
714 | * See SPC3 r07, page 159. | ||
715 | */ | ||
716 | done: | ||
717 | lun_count *= 8; | ||
718 | buf[0] = ((lun_count >> 24) & 0xff); | ||
719 | buf[1] = ((lun_count >> 16) & 0xff); | ||
720 | buf[2] = ((lun_count >> 8) & 0xff); | ||
721 | buf[3] = (lun_count & 0xff); | ||
722 | transport_kunmap_data_sg(se_cmd); | ||
723 | |||
724 | target_complete_cmd(se_cmd, GOOD); | ||
725 | return 0; | ||
726 | } | ||
727 | |||
728 | /* se_release_device_for_hba(): | ||
729 | * | ||
730 | * | ||
731 | */ | ||
732 | void se_release_device_for_hba(struct se_device *dev) | ||
733 | { | ||
734 | struct se_hba *hba = dev->se_hba; | ||
735 | |||
736 | if ((dev->dev_status & TRANSPORT_DEVICE_ACTIVATED) || | ||
737 | (dev->dev_status & TRANSPORT_DEVICE_DEACTIVATED) || | ||
738 | (dev->dev_status & TRANSPORT_DEVICE_SHUTDOWN) || | ||
739 | (dev->dev_status & TRANSPORT_DEVICE_OFFLINE_ACTIVATED) || | ||
740 | (dev->dev_status & TRANSPORT_DEVICE_OFFLINE_DEACTIVATED)) | ||
741 | se_dev_stop(dev); | ||
742 | |||
743 | if (dev->dev_ptr) { | ||
744 | destroy_workqueue(dev->tmr_wq); | ||
745 | if (dev->transport->free_device) | ||
746 | dev->transport->free_device(dev->dev_ptr); | ||
747 | } | ||
748 | |||
749 | spin_lock(&hba->device_lock); | 627 | spin_lock(&hba->device_lock); |
750 | list_del(&dev->dev_list); | 628 | dev->export_count--; |
751 | hba->dev_count--; | ||
752 | spin_unlock(&hba->device_lock); | 629 | spin_unlock(&hba->device_lock); |
753 | 630 | ||
754 | core_scsi3_free_all_registrations(dev); | 631 | lun->lun_se_dev = NULL; |
755 | se_release_vpd_for_dev(dev); | ||
756 | |||
757 | kfree(dev); | ||
758 | } | 632 | } |
759 | 633 | ||
760 | void se_release_vpd_for_dev(struct se_device *dev) | 634 | static void se_release_vpd_for_dev(struct se_device *dev) |
761 | { | 635 | { |
762 | struct t10_vpd *vpd, *vpd_tmp; | 636 | struct t10_vpd *vpd, *vpd_tmp; |
763 | 637 | ||
764 | spin_lock(&dev->se_sub_dev->t10_wwn.t10_vpd_lock); | 638 | spin_lock(&dev->t10_wwn.t10_vpd_lock); |
765 | list_for_each_entry_safe(vpd, vpd_tmp, | 639 | list_for_each_entry_safe(vpd, vpd_tmp, |
766 | &dev->se_sub_dev->t10_wwn.t10_vpd_list, vpd_list) { | 640 | &dev->t10_wwn.t10_vpd_list, vpd_list) { |
767 | list_del(&vpd->vpd_list); | 641 | list_del(&vpd->vpd_list); |
768 | kfree(vpd); | 642 | kfree(vpd); |
769 | } | 643 | } |
770 | spin_unlock(&dev->se_sub_dev->t10_wwn.t10_vpd_lock); | 644 | spin_unlock(&dev->t10_wwn.t10_vpd_lock); |
771 | } | ||
772 | |||
773 | /* se_free_virtual_device(): | ||
774 | * | ||
775 | * Used for IBLOCK, RAMDISK, and FILEIO Transport Drivers. | ||
776 | */ | ||
777 | int se_free_virtual_device(struct se_device *dev, struct se_hba *hba) | ||
778 | { | ||
779 | if (!list_empty(&dev->dev_sep_list)) | ||
780 | dump_stack(); | ||
781 | |||
782 | core_alua_free_lu_gp_mem(dev); | ||
783 | se_release_device_for_hba(dev); | ||
784 | |||
785 | return 0; | ||
786 | } | ||
787 | |||
788 | static void se_dev_start(struct se_device *dev) | ||
789 | { | ||
790 | struct se_hba *hba = dev->se_hba; | ||
791 | |||
792 | spin_lock(&hba->device_lock); | ||
793 | atomic_inc(&dev->dev_obj.obj_access_count); | ||
794 | if (atomic_read(&dev->dev_obj.obj_access_count) == 1) { | ||
795 | if (dev->dev_status & TRANSPORT_DEVICE_DEACTIVATED) { | ||
796 | dev->dev_status &= ~TRANSPORT_DEVICE_DEACTIVATED; | ||
797 | dev->dev_status |= TRANSPORT_DEVICE_ACTIVATED; | ||
798 | } else if (dev->dev_status & | ||
799 | TRANSPORT_DEVICE_OFFLINE_DEACTIVATED) { | ||
800 | dev->dev_status &= | ||
801 | ~TRANSPORT_DEVICE_OFFLINE_DEACTIVATED; | ||
802 | dev->dev_status |= TRANSPORT_DEVICE_OFFLINE_ACTIVATED; | ||
803 | } | ||
804 | } | ||
805 | spin_unlock(&hba->device_lock); | ||
806 | } | ||
807 | |||
808 | static void se_dev_stop(struct se_device *dev) | ||
809 | { | ||
810 | struct se_hba *hba = dev->se_hba; | ||
811 | |||
812 | spin_lock(&hba->device_lock); | ||
813 | atomic_dec(&dev->dev_obj.obj_access_count); | ||
814 | if (atomic_read(&dev->dev_obj.obj_access_count) == 0) { | ||
815 | if (dev->dev_status & TRANSPORT_DEVICE_ACTIVATED) { | ||
816 | dev->dev_status &= ~TRANSPORT_DEVICE_ACTIVATED; | ||
817 | dev->dev_status |= TRANSPORT_DEVICE_DEACTIVATED; | ||
818 | } else if (dev->dev_status & | ||
819 | TRANSPORT_DEVICE_OFFLINE_ACTIVATED) { | ||
820 | dev->dev_status &= ~TRANSPORT_DEVICE_OFFLINE_ACTIVATED; | ||
821 | dev->dev_status |= TRANSPORT_DEVICE_OFFLINE_DEACTIVATED; | ||
822 | } | ||
823 | } | ||
824 | spin_unlock(&hba->device_lock); | ||
825 | } | ||
826 | |||
827 | int se_dev_check_online(struct se_device *dev) | ||
828 | { | ||
829 | unsigned long flags; | ||
830 | int ret; | ||
831 | |||
832 | spin_lock_irqsave(&dev->dev_status_lock, flags); | ||
833 | ret = ((dev->dev_status & TRANSPORT_DEVICE_ACTIVATED) || | ||
834 | (dev->dev_status & TRANSPORT_DEVICE_DEACTIVATED)) ? 0 : 1; | ||
835 | spin_unlock_irqrestore(&dev->dev_status_lock, flags); | ||
836 | |||
837 | return ret; | ||
838 | } | ||
839 | |||
840 | int se_dev_check_shutdown(struct se_device *dev) | ||
841 | { | ||
842 | int ret; | ||
843 | |||
844 | spin_lock_irq(&dev->dev_status_lock); | ||
845 | ret = (dev->dev_status & TRANSPORT_DEVICE_SHUTDOWN); | ||
846 | spin_unlock_irq(&dev->dev_status_lock); | ||
847 | |||
848 | return ret; | ||
849 | } | 645 | } |
850 | 646 | ||
851 | static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size) | 647 | static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size) |
852 | { | 648 | { |
853 | u32 tmp, aligned_max_sectors; | 649 | u32 aligned_max_sectors; |
650 | u32 alignment; | ||
854 | /* | 651 | /* |
855 | * Limit max_sectors to a PAGE_SIZE aligned value for modern | 652 | * Limit max_sectors to a PAGE_SIZE aligned value for modern |
856 | * transport_allocate_data_tasks() operation. | 653 | * transport_allocate_data_tasks() operation. |
857 | */ | 654 | */ |
858 | tmp = rounddown((max_sectors * block_size), PAGE_SIZE); | 655 | alignment = max(1ul, PAGE_SIZE / block_size); |
859 | aligned_max_sectors = (tmp / block_size); | 656 | aligned_max_sectors = rounddown(max_sectors, alignment); |
860 | if (max_sectors != aligned_max_sectors) { | ||
861 | printk(KERN_INFO "Rounding down aligned max_sectors from %u" | ||
862 | " to %u\n", max_sectors, aligned_max_sectors); | ||
863 | return aligned_max_sectors; | ||
864 | } | ||
865 | |||
866 | return max_sectors; | ||
867 | } | ||
868 | 657 | ||
869 | void se_dev_set_default_attribs( | 658 | if (max_sectors != aligned_max_sectors) |
870 | struct se_device *dev, | 659 | pr_info("Rounding down aligned max_sectors from %u to %u\n", |
871 | struct se_dev_limits *dev_limits) | 660 | max_sectors, aligned_max_sectors); |
872 | { | ||
873 | struct queue_limits *limits = &dev_limits->limits; | ||
874 | |||
875 | dev->se_sub_dev->se_dev_attrib.emulate_dpo = DA_EMULATE_DPO; | ||
876 | dev->se_sub_dev->se_dev_attrib.emulate_fua_write = DA_EMULATE_FUA_WRITE; | ||
877 | dev->se_sub_dev->se_dev_attrib.emulate_fua_read = DA_EMULATE_FUA_READ; | ||
878 | dev->se_sub_dev->se_dev_attrib.emulate_write_cache = DA_EMULATE_WRITE_CACHE; | ||
879 | dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl = DA_EMULATE_UA_INTLLCK_CTRL; | ||
880 | dev->se_sub_dev->se_dev_attrib.emulate_tas = DA_EMULATE_TAS; | ||
881 | dev->se_sub_dev->se_dev_attrib.emulate_tpu = DA_EMULATE_TPU; | ||
882 | dev->se_sub_dev->se_dev_attrib.emulate_tpws = DA_EMULATE_TPWS; | ||
883 | dev->se_sub_dev->se_dev_attrib.emulate_reservations = DA_EMULATE_RESERVATIONS; | ||
884 | dev->se_sub_dev->se_dev_attrib.emulate_alua = DA_EMULATE_ALUA; | ||
885 | dev->se_sub_dev->se_dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS; | ||
886 | dev->se_sub_dev->se_dev_attrib.is_nonrot = DA_IS_NONROT; | ||
887 | dev->se_sub_dev->se_dev_attrib.emulate_rest_reord = DA_EMULATE_REST_REORD; | ||
888 | /* | ||
889 | * The TPU=1 and TPWS=1 settings will be set in TCM/IBLOCK | ||
890 | * iblock_create_virtdevice() from struct queue_limits values | ||
891 | * if blk_queue_discard()==1 | ||
892 | */ | ||
893 | dev->se_sub_dev->se_dev_attrib.max_unmap_lba_count = DA_MAX_UNMAP_LBA_COUNT; | ||
894 | dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count = | ||
895 | DA_MAX_UNMAP_BLOCK_DESC_COUNT; | ||
896 | dev->se_sub_dev->se_dev_attrib.unmap_granularity = DA_UNMAP_GRANULARITY_DEFAULT; | ||
897 | dev->se_sub_dev->se_dev_attrib.unmap_granularity_alignment = | ||
898 | DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT; | ||
899 | /* | ||
900 | * block_size is based on subsystem plugin dependent requirements. | ||
901 | */ | ||
902 | dev->se_sub_dev->se_dev_attrib.hw_block_size = limits->logical_block_size; | ||
903 | dev->se_sub_dev->se_dev_attrib.block_size = limits->logical_block_size; | ||
904 | /* | ||
905 | * Align max_hw_sectors down to PAGE_SIZE I/O transfers | ||
906 | */ | ||
907 | limits->max_hw_sectors = se_dev_align_max_sectors(limits->max_hw_sectors, | ||
908 | limits->logical_block_size); | ||
909 | dev->se_sub_dev->se_dev_attrib.hw_max_sectors = limits->max_hw_sectors; | ||
910 | 661 | ||
911 | /* | 662 | return aligned_max_sectors; |
912 | * Set fabric_max_sectors, which is reported in block limits | ||
913 | * VPD page (B0h). | ||
914 | */ | ||
915 | dev->se_sub_dev->se_dev_attrib.fabric_max_sectors = DA_FABRIC_MAX_SECTORS; | ||
916 | /* | ||
917 | * Set optimal_sectors from fabric_max_sectors, which can be | ||
918 | * lowered via configfs. | ||
919 | */ | ||
920 | dev->se_sub_dev->se_dev_attrib.optimal_sectors = DA_FABRIC_MAX_SECTORS; | ||
921 | /* | ||
922 | * queue_depth is based on subsystem plugin dependent requirements. | ||
923 | */ | ||
924 | dev->se_sub_dev->se_dev_attrib.hw_queue_depth = dev_limits->hw_queue_depth; | ||
925 | dev->se_sub_dev->se_dev_attrib.queue_depth = dev_limits->queue_depth; | ||
926 | } | 663 | } |
927 | 664 | ||
928 | int se_dev_set_max_unmap_lba_count( | 665 | int se_dev_set_max_unmap_lba_count( |
929 | struct se_device *dev, | 666 | struct se_device *dev, |
930 | u32 max_unmap_lba_count) | 667 | u32 max_unmap_lba_count) |
931 | { | 668 | { |
932 | dev->se_sub_dev->se_dev_attrib.max_unmap_lba_count = max_unmap_lba_count; | 669 | dev->dev_attrib.max_unmap_lba_count = max_unmap_lba_count; |
933 | pr_debug("dev[%p]: Set max_unmap_lba_count: %u\n", | 670 | pr_debug("dev[%p]: Set max_unmap_lba_count: %u\n", |
934 | dev, dev->se_sub_dev->se_dev_attrib.max_unmap_lba_count); | 671 | dev, dev->dev_attrib.max_unmap_lba_count); |
935 | return 0; | 672 | return 0; |
936 | } | 673 | } |
937 | 674 | ||
@@ -939,10 +676,10 @@ int se_dev_set_max_unmap_block_desc_count( | |||
939 | struct se_device *dev, | 676 | struct se_device *dev, |
940 | u32 max_unmap_block_desc_count) | 677 | u32 max_unmap_block_desc_count) |
941 | { | 678 | { |
942 | dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count = | 679 | dev->dev_attrib.max_unmap_block_desc_count = |
943 | max_unmap_block_desc_count; | 680 | max_unmap_block_desc_count; |
944 | pr_debug("dev[%p]: Set max_unmap_block_desc_count: %u\n", | 681 | pr_debug("dev[%p]: Set max_unmap_block_desc_count: %u\n", |
945 | dev, dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count); | 682 | dev, dev->dev_attrib.max_unmap_block_desc_count); |
946 | return 0; | 683 | return 0; |
947 | } | 684 | } |
948 | 685 | ||
@@ -950,9 +687,9 @@ int se_dev_set_unmap_granularity( | |||
950 | struct se_device *dev, | 687 | struct se_device *dev, |
951 | u32 unmap_granularity) | 688 | u32 unmap_granularity) |
952 | { | 689 | { |
953 | dev->se_sub_dev->se_dev_attrib.unmap_granularity = unmap_granularity; | 690 | dev->dev_attrib.unmap_granularity = unmap_granularity; |
954 | pr_debug("dev[%p]: Set unmap_granularity: %u\n", | 691 | pr_debug("dev[%p]: Set unmap_granularity: %u\n", |
955 | dev, dev->se_sub_dev->se_dev_attrib.unmap_granularity); | 692 | dev, dev->dev_attrib.unmap_granularity); |
956 | return 0; | 693 | return 0; |
957 | } | 694 | } |
958 | 695 | ||
@@ -960,9 +697,19 @@ int se_dev_set_unmap_granularity_alignment( | |||
960 | struct se_device *dev, | 697 | struct se_device *dev, |
961 | u32 unmap_granularity_alignment) | 698 | u32 unmap_granularity_alignment) |
962 | { | 699 | { |
963 | dev->se_sub_dev->se_dev_attrib.unmap_granularity_alignment = unmap_granularity_alignment; | 700 | dev->dev_attrib.unmap_granularity_alignment = unmap_granularity_alignment; |
964 | pr_debug("dev[%p]: Set unmap_granularity_alignment: %u\n", | 701 | pr_debug("dev[%p]: Set unmap_granularity_alignment: %u\n", |
965 | dev, dev->se_sub_dev->se_dev_attrib.unmap_granularity_alignment); | 702 | dev, dev->dev_attrib.unmap_granularity_alignment); |
703 | return 0; | ||
704 | } | ||
705 | |||
706 | int se_dev_set_max_write_same_len( | ||
707 | struct se_device *dev, | ||
708 | u32 max_write_same_len) | ||
709 | { | ||
710 | dev->dev_attrib.max_write_same_len = max_write_same_len; | ||
711 | pr_debug("dev[%p]: Set max_write_same_len: %u\n", | ||
712 | dev, dev->dev_attrib.max_write_same_len); | ||
966 | return 0; | 713 | return 0; |
967 | } | 714 | } |
968 | 715 | ||
@@ -993,9 +740,9 @@ int se_dev_set_emulate_fua_write(struct se_device *dev, int flag) | |||
993 | pr_err("emulate_fua_write not supported for pSCSI\n"); | 740 | pr_err("emulate_fua_write not supported for pSCSI\n"); |
994 | return -EINVAL; | 741 | return -EINVAL; |
995 | } | 742 | } |
996 | dev->se_sub_dev->se_dev_attrib.emulate_fua_write = flag; | 743 | dev->dev_attrib.emulate_fua_write = flag; |
997 | pr_debug("dev[%p]: SE Device Forced Unit Access WRITEs: %d\n", | 744 | pr_debug("dev[%p]: SE Device Forced Unit Access WRITEs: %d\n", |
998 | dev, dev->se_sub_dev->se_dev_attrib.emulate_fua_write); | 745 | dev, dev->dev_attrib.emulate_fua_write); |
999 | return 0; | 746 | return 0; |
1000 | } | 747 | } |
1001 | 748 | ||
@@ -1025,9 +772,9 @@ int se_dev_set_emulate_write_cache(struct se_device *dev, int flag) | |||
1025 | pr_err("emulate_write_cache not supported for pSCSI\n"); | 772 | pr_err("emulate_write_cache not supported for pSCSI\n"); |
1026 | return -EINVAL; | 773 | return -EINVAL; |
1027 | } | 774 | } |
1028 | dev->se_sub_dev->se_dev_attrib.emulate_write_cache = flag; | 775 | dev->dev_attrib.emulate_write_cache = flag; |
1029 | pr_debug("dev[%p]: SE Device WRITE_CACHE_EMULATION flag: %d\n", | 776 | pr_debug("dev[%p]: SE Device WRITE_CACHE_EMULATION flag: %d\n", |
1030 | dev, dev->se_sub_dev->se_dev_attrib.emulate_write_cache); | 777 | dev, dev->dev_attrib.emulate_write_cache); |
1031 | return 0; | 778 | return 0; |
1032 | } | 779 | } |
1033 | 780 | ||
@@ -1038,16 +785,15 @@ int se_dev_set_emulate_ua_intlck_ctrl(struct se_device *dev, int flag) | |||
1038 | return -EINVAL; | 785 | return -EINVAL; |
1039 | } | 786 | } |
1040 | 787 | ||
1041 | if (atomic_read(&dev->dev_export_obj.obj_access_count)) { | 788 | if (dev->export_count) { |
1042 | pr_err("dev[%p]: Unable to change SE Device" | 789 | pr_err("dev[%p]: Unable to change SE Device" |
1043 | " UA_INTRLCK_CTRL while dev_export_obj: %d count" | 790 | " UA_INTRLCK_CTRL while export_count is %d\n", |
1044 | " exists\n", dev, | 791 | dev, dev->export_count); |
1045 | atomic_read(&dev->dev_export_obj.obj_access_count)); | ||
1046 | return -EINVAL; | 792 | return -EINVAL; |
1047 | } | 793 | } |
1048 | dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl = flag; | 794 | dev->dev_attrib.emulate_ua_intlck_ctrl = flag; |
1049 | pr_debug("dev[%p]: SE Device UA_INTRLCK_CTRL flag: %d\n", | 795 | pr_debug("dev[%p]: SE Device UA_INTRLCK_CTRL flag: %d\n", |
1050 | dev, dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl); | 796 | dev, dev->dev_attrib.emulate_ua_intlck_ctrl); |
1051 | 797 | ||
1052 | return 0; | 798 | return 0; |
1053 | } | 799 | } |
@@ -1059,15 +805,15 @@ int se_dev_set_emulate_tas(struct se_device *dev, int flag) | |||
1059 | return -EINVAL; | 805 | return -EINVAL; |
1060 | } | 806 | } |
1061 | 807 | ||
1062 | if (atomic_read(&dev->dev_export_obj.obj_access_count)) { | 808 | if (dev->export_count) { |
1063 | pr_err("dev[%p]: Unable to change SE Device TAS while" | 809 | pr_err("dev[%p]: Unable to change SE Device TAS while" |
1064 | " dev_export_obj: %d count exists\n", dev, | 810 | " export_count is %d\n", |
1065 | atomic_read(&dev->dev_export_obj.obj_access_count)); | 811 | dev, dev->export_count); |
1066 | return -EINVAL; | 812 | return -EINVAL; |
1067 | } | 813 | } |
1068 | dev->se_sub_dev->se_dev_attrib.emulate_tas = flag; | 814 | dev->dev_attrib.emulate_tas = flag; |
1069 | pr_debug("dev[%p]: SE Device TASK_ABORTED status bit: %s\n", | 815 | pr_debug("dev[%p]: SE Device TASK_ABORTED status bit: %s\n", |
1070 | dev, (dev->se_sub_dev->se_dev_attrib.emulate_tas) ? "Enabled" : "Disabled"); | 816 | dev, (dev->dev_attrib.emulate_tas) ? "Enabled" : "Disabled"); |
1071 | 817 | ||
1072 | return 0; | 818 | return 0; |
1073 | } | 819 | } |
@@ -1082,12 +828,12 @@ int se_dev_set_emulate_tpu(struct se_device *dev, int flag) | |||
1082 | * We expect this value to be non-zero when generic Block Layer | 828 | * We expect this value to be non-zero when generic Block Layer |
1083 | * Discard supported is detected iblock_create_virtdevice(). | 829 | * Discard supported is detected iblock_create_virtdevice(). |
1084 | */ | 830 | */ |
1085 | if (flag && !dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { | 831 | if (flag && !dev->dev_attrib.max_unmap_block_desc_count) { |
1086 | pr_err("Generic Block Discard not supported\n"); | 832 | pr_err("Generic Block Discard not supported\n"); |
1087 | return -ENOSYS; | 833 | return -ENOSYS; |
1088 | } | 834 | } |
1089 | 835 | ||
1090 | dev->se_sub_dev->se_dev_attrib.emulate_tpu = flag; | 836 | dev->dev_attrib.emulate_tpu = flag; |
1091 | pr_debug("dev[%p]: SE Device Thin Provisioning UNMAP bit: %d\n", | 837 | pr_debug("dev[%p]: SE Device Thin Provisioning UNMAP bit: %d\n", |
1092 | dev, flag); | 838 | dev, flag); |
1093 | return 0; | 839 | return 0; |
@@ -1103,12 +849,12 @@ int se_dev_set_emulate_tpws(struct se_device *dev, int flag) | |||
1103 | * We expect this value to be non-zero when generic Block Layer | 849 | * We expect this value to be non-zero when generic Block Layer |
1104 | * Discard supported is detected iblock_create_virtdevice(). | 850 | * Discard supported is detected iblock_create_virtdevice(). |
1105 | */ | 851 | */ |
1106 | if (flag && !dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { | 852 | if (flag && !dev->dev_attrib.max_unmap_block_desc_count) { |
1107 | pr_err("Generic Block Discard not supported\n"); | 853 | pr_err("Generic Block Discard not supported\n"); |
1108 | return -ENOSYS; | 854 | return -ENOSYS; |
1109 | } | 855 | } |
1110 | 856 | ||
1111 | dev->se_sub_dev->se_dev_attrib.emulate_tpws = flag; | 857 | dev->dev_attrib.emulate_tpws = flag; |
1112 | pr_debug("dev[%p]: SE Device Thin Provisioning WRITE_SAME: %d\n", | 858 | pr_debug("dev[%p]: SE Device Thin Provisioning WRITE_SAME: %d\n", |
1113 | dev, flag); | 859 | dev, flag); |
1114 | return 0; | 860 | return 0; |
@@ -1120,9 +866,9 @@ int se_dev_set_enforce_pr_isids(struct se_device *dev, int flag) | |||
1120 | pr_err("Illegal value %d\n", flag); | 866 | pr_err("Illegal value %d\n", flag); |
1121 | return -EINVAL; | 867 | return -EINVAL; |
1122 | } | 868 | } |
1123 | dev->se_sub_dev->se_dev_attrib.enforce_pr_isids = flag; | 869 | dev->dev_attrib.enforce_pr_isids = flag; |
1124 | pr_debug("dev[%p]: SE Device enforce_pr_isids bit: %s\n", dev, | 870 | pr_debug("dev[%p]: SE Device enforce_pr_isids bit: %s\n", dev, |
1125 | (dev->se_sub_dev->se_dev_attrib.enforce_pr_isids) ? "Enabled" : "Disabled"); | 871 | (dev->dev_attrib.enforce_pr_isids) ? "Enabled" : "Disabled"); |
1126 | return 0; | 872 | return 0; |
1127 | } | 873 | } |
1128 | 874 | ||
@@ -1132,7 +878,7 @@ int se_dev_set_is_nonrot(struct se_device *dev, int flag) | |||
1132 | printk(KERN_ERR "Illegal value %d\n", flag); | 878 | printk(KERN_ERR "Illegal value %d\n", flag); |
1133 | return -EINVAL; | 879 | return -EINVAL; |
1134 | } | 880 | } |
1135 | dev->se_sub_dev->se_dev_attrib.is_nonrot = flag; | 881 | dev->dev_attrib.is_nonrot = flag; |
1136 | pr_debug("dev[%p]: SE Device is_nonrot bit: %d\n", | 882 | pr_debug("dev[%p]: SE Device is_nonrot bit: %d\n", |
1137 | dev, flag); | 883 | dev, flag); |
1138 | return 0; | 884 | return 0; |
@@ -1145,7 +891,7 @@ int se_dev_set_emulate_rest_reord(struct se_device *dev, int flag) | |||
1145 | " reordering not implemented\n", dev); | 891 | " reordering not implemented\n", dev); |
1146 | return -ENOSYS; | 892 | return -ENOSYS; |
1147 | } | 893 | } |
1148 | dev->se_sub_dev->se_dev_attrib.emulate_rest_reord = flag; | 894 | dev->dev_attrib.emulate_rest_reord = flag; |
1149 | pr_debug("dev[%p]: SE Device emulate_rest_reord: %d\n", dev, flag); | 895 | pr_debug("dev[%p]: SE Device emulate_rest_reord: %d\n", dev, flag); |
1150 | return 0; | 896 | return 0; |
1151 | } | 897 | } |
@@ -1155,10 +901,10 @@ int se_dev_set_emulate_rest_reord(struct se_device *dev, int flag) | |||
1155 | */ | 901 | */ |
1156 | int se_dev_set_queue_depth(struct se_device *dev, u32 queue_depth) | 902 | int se_dev_set_queue_depth(struct se_device *dev, u32 queue_depth) |
1157 | { | 903 | { |
1158 | if (atomic_read(&dev->dev_export_obj.obj_access_count)) { | 904 | if (dev->export_count) { |
1159 | pr_err("dev[%p]: Unable to change SE Device TCQ while" | 905 | pr_err("dev[%p]: Unable to change SE Device TCQ while" |
1160 | " dev_export_obj: %d count exists\n", dev, | 906 | " export_count is %d\n", |
1161 | atomic_read(&dev->dev_export_obj.obj_access_count)); | 907 | dev, dev->export_count); |
1162 | return -EINVAL; | 908 | return -EINVAL; |
1163 | } | 909 | } |
1164 | if (!queue_depth) { | 910 | if (!queue_depth) { |
@@ -1168,26 +914,26 @@ int se_dev_set_queue_depth(struct se_device *dev, u32 queue_depth) | |||
1168 | } | 914 | } |
1169 | 915 | ||
1170 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { | 916 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { |
1171 | if (queue_depth > dev->se_sub_dev->se_dev_attrib.hw_queue_depth) { | 917 | if (queue_depth > dev->dev_attrib.hw_queue_depth) { |
1172 | pr_err("dev[%p]: Passed queue_depth: %u" | 918 | pr_err("dev[%p]: Passed queue_depth: %u" |
1173 | " exceeds TCM/SE_Device TCQ: %u\n", | 919 | " exceeds TCM/SE_Device TCQ: %u\n", |
1174 | dev, queue_depth, | 920 | dev, queue_depth, |
1175 | dev->se_sub_dev->se_dev_attrib.hw_queue_depth); | 921 | dev->dev_attrib.hw_queue_depth); |
1176 | return -EINVAL; | 922 | return -EINVAL; |
1177 | } | 923 | } |
1178 | } else { | 924 | } else { |
1179 | if (queue_depth > dev->se_sub_dev->se_dev_attrib.queue_depth) { | 925 | if (queue_depth > dev->dev_attrib.queue_depth) { |
1180 | if (queue_depth > dev->se_sub_dev->se_dev_attrib.hw_queue_depth) { | 926 | if (queue_depth > dev->dev_attrib.hw_queue_depth) { |
1181 | pr_err("dev[%p]: Passed queue_depth:" | 927 | pr_err("dev[%p]: Passed queue_depth:" |
1182 | " %u exceeds TCM/SE_Device MAX" | 928 | " %u exceeds TCM/SE_Device MAX" |
1183 | " TCQ: %u\n", dev, queue_depth, | 929 | " TCQ: %u\n", dev, queue_depth, |
1184 | dev->se_sub_dev->se_dev_attrib.hw_queue_depth); | 930 | dev->dev_attrib.hw_queue_depth); |
1185 | return -EINVAL; | 931 | return -EINVAL; |
1186 | } | 932 | } |
1187 | } | 933 | } |
1188 | } | 934 | } |
1189 | 935 | ||
1190 | dev->se_sub_dev->se_dev_attrib.queue_depth = dev->queue_depth = queue_depth; | 936 | dev->dev_attrib.queue_depth = dev->queue_depth = queue_depth; |
1191 | pr_debug("dev[%p]: SE Device TCQ Depth changed to: %u\n", | 937 | pr_debug("dev[%p]: SE Device TCQ Depth changed to: %u\n", |
1192 | dev, queue_depth); | 938 | dev, queue_depth); |
1193 | return 0; | 939 | return 0; |
@@ -1195,10 +941,10 @@ int se_dev_set_queue_depth(struct se_device *dev, u32 queue_depth) | |||
1195 | 941 | ||
1196 | int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors) | 942 | int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors) |
1197 | { | 943 | { |
1198 | if (atomic_read(&dev->dev_export_obj.obj_access_count)) { | 944 | if (dev->export_count) { |
1199 | pr_err("dev[%p]: Unable to change SE Device" | 945 | pr_err("dev[%p]: Unable to change SE Device" |
1200 | " fabric_max_sectors while dev_export_obj: %d count exists\n", | 946 | " fabric_max_sectors while export_count is %d\n", |
1201 | dev, atomic_read(&dev->dev_export_obj.obj_access_count)); | 947 | dev, dev->export_count); |
1202 | return -EINVAL; | 948 | return -EINVAL; |
1203 | } | 949 | } |
1204 | if (!fabric_max_sectors) { | 950 | if (!fabric_max_sectors) { |
@@ -1213,11 +959,11 @@ int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors) | |||
1213 | return -EINVAL; | 959 | return -EINVAL; |
1214 | } | 960 | } |
1215 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { | 961 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { |
1216 | if (fabric_max_sectors > dev->se_sub_dev->se_dev_attrib.hw_max_sectors) { | 962 | if (fabric_max_sectors > dev->dev_attrib.hw_max_sectors) { |
1217 | pr_err("dev[%p]: Passed fabric_max_sectors: %u" | 963 | pr_err("dev[%p]: Passed fabric_max_sectors: %u" |
1218 | " greater than TCM/SE_Device max_sectors:" | 964 | " greater than TCM/SE_Device max_sectors:" |
1219 | " %u\n", dev, fabric_max_sectors, | 965 | " %u\n", dev, fabric_max_sectors, |
1220 | dev->se_sub_dev->se_dev_attrib.hw_max_sectors); | 966 | dev->dev_attrib.hw_max_sectors); |
1221 | return -EINVAL; | 967 | return -EINVAL; |
1222 | } | 968 | } |
1223 | } else { | 969 | } else { |
@@ -1233,9 +979,9 @@ int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors) | |||
1233 | * Align max_sectors down to PAGE_SIZE to follow transport_allocate_data_tasks() | 979 | * Align max_sectors down to PAGE_SIZE to follow transport_allocate_data_tasks() |
1234 | */ | 980 | */ |
1235 | fabric_max_sectors = se_dev_align_max_sectors(fabric_max_sectors, | 981 | fabric_max_sectors = se_dev_align_max_sectors(fabric_max_sectors, |
1236 | dev->se_sub_dev->se_dev_attrib.block_size); | 982 | dev->dev_attrib.block_size); |
1237 | 983 | ||
1238 | dev->se_sub_dev->se_dev_attrib.fabric_max_sectors = fabric_max_sectors; | 984 | dev->dev_attrib.fabric_max_sectors = fabric_max_sectors; |
1239 | pr_debug("dev[%p]: SE Device max_sectors changed to %u\n", | 985 | pr_debug("dev[%p]: SE Device max_sectors changed to %u\n", |
1240 | dev, fabric_max_sectors); | 986 | dev, fabric_max_sectors); |
1241 | return 0; | 987 | return 0; |
@@ -1243,10 +989,10 @@ int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors) | |||
1243 | 989 | ||
1244 | int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors) | 990 | int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors) |
1245 | { | 991 | { |
1246 | if (atomic_read(&dev->dev_export_obj.obj_access_count)) { | 992 | if (dev->export_count) { |
1247 | pr_err("dev[%p]: Unable to change SE Device" | 993 | pr_err("dev[%p]: Unable to change SE Device" |
1248 | " optimal_sectors while dev_export_obj: %d count exists\n", | 994 | " optimal_sectors while export_count is %d\n", |
1249 | dev, atomic_read(&dev->dev_export_obj.obj_access_count)); | 995 | dev, dev->export_count); |
1250 | return -EINVAL; | 996 | return -EINVAL; |
1251 | } | 997 | } |
1252 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { | 998 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { |
@@ -1254,14 +1000,14 @@ int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors) | |||
1254 | " changed for TCM/pSCSI\n", dev); | 1000 | " changed for TCM/pSCSI\n", dev); |
1255 | return -EINVAL; | 1001 | return -EINVAL; |
1256 | } | 1002 | } |
1257 | if (optimal_sectors > dev->se_sub_dev->se_dev_attrib.fabric_max_sectors) { | 1003 | if (optimal_sectors > dev->dev_attrib.fabric_max_sectors) { |
1258 | pr_err("dev[%p]: Passed optimal_sectors %u cannot be" | 1004 | pr_err("dev[%p]: Passed optimal_sectors %u cannot be" |
1259 | " greater than fabric_max_sectors: %u\n", dev, | 1005 | " greater than fabric_max_sectors: %u\n", dev, |
1260 | optimal_sectors, dev->se_sub_dev->se_dev_attrib.fabric_max_sectors); | 1006 | optimal_sectors, dev->dev_attrib.fabric_max_sectors); |
1261 | return -EINVAL; | 1007 | return -EINVAL; |
1262 | } | 1008 | } |
1263 | 1009 | ||
1264 | dev->se_sub_dev->se_dev_attrib.optimal_sectors = optimal_sectors; | 1010 | dev->dev_attrib.optimal_sectors = optimal_sectors; |
1265 | pr_debug("dev[%p]: SE Device optimal_sectors changed to %u\n", | 1011 | pr_debug("dev[%p]: SE Device optimal_sectors changed to %u\n", |
1266 | dev, optimal_sectors); | 1012 | dev, optimal_sectors); |
1267 | return 0; | 1013 | return 0; |
@@ -1269,10 +1015,10 @@ int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors) | |||
1269 | 1015 | ||
1270 | int se_dev_set_block_size(struct se_device *dev, u32 block_size) | 1016 | int se_dev_set_block_size(struct se_device *dev, u32 block_size) |
1271 | { | 1017 | { |
1272 | if (atomic_read(&dev->dev_export_obj.obj_access_count)) { | 1018 | if (dev->export_count) { |
1273 | pr_err("dev[%p]: Unable to change SE Device block_size" | 1019 | pr_err("dev[%p]: Unable to change SE Device block_size" |
1274 | " while dev_export_obj: %d count exists\n", dev, | 1020 | " while export_count is %d\n", |
1275 | atomic_read(&dev->dev_export_obj.obj_access_count)); | 1021 | dev, dev->export_count); |
1276 | return -EINVAL; | 1022 | return -EINVAL; |
1277 | } | 1023 | } |
1278 | 1024 | ||
@@ -1293,7 +1039,7 @@ int se_dev_set_block_size(struct se_device *dev, u32 block_size) | |||
1293 | return -EINVAL; | 1039 | return -EINVAL; |
1294 | } | 1040 | } |
1295 | 1041 | ||
1296 | dev->se_sub_dev->se_dev_attrib.block_size = block_size; | 1042 | dev->dev_attrib.block_size = block_size; |
1297 | pr_debug("dev[%p]: SE Device block_size changed to %u\n", | 1043 | pr_debug("dev[%p]: SE Device block_size changed to %u\n", |
1298 | dev, block_size); | 1044 | dev, block_size); |
1299 | return 0; | 1045 | return 0; |
@@ -1307,12 +1053,6 @@ struct se_lun *core_dev_add_lun( | |||
1307 | struct se_lun *lun_p; | 1053 | struct se_lun *lun_p; |
1308 | int rc; | 1054 | int rc; |
1309 | 1055 | ||
1310 | if (atomic_read(&dev->dev_access_obj.obj_access_count) != 0) { | ||
1311 | pr_err("Unable to export struct se_device while dev_access_obj: %d\n", | ||
1312 | atomic_read(&dev->dev_access_obj.obj_access_count)); | ||
1313 | return ERR_PTR(-EACCES); | ||
1314 | } | ||
1315 | |||
1316 | lun_p = core_tpg_pre_addlun(tpg, lun); | 1056 | lun_p = core_tpg_pre_addlun(tpg, lun); |
1317 | if (IS_ERR(lun_p)) | 1057 | if (IS_ERR(lun_p)) |
1318 | return lun_p; | 1058 | return lun_p; |
@@ -1568,12 +1308,211 @@ void core_dev_free_initiator_node_lun_acl( | |||
1568 | kfree(lacl); | 1308 | kfree(lacl); |
1569 | } | 1309 | } |
1570 | 1310 | ||
1311 | static void scsi_dump_inquiry(struct se_device *dev) | ||
1312 | { | ||
1313 | struct t10_wwn *wwn = &dev->t10_wwn; | ||
1314 | char buf[17]; | ||
1315 | int i, device_type; | ||
1316 | /* | ||
1317 | * Print Linux/SCSI style INQUIRY formatting to the kernel ring buffer | ||
1318 | */ | ||
1319 | for (i = 0; i < 8; i++) | ||
1320 | if (wwn->vendor[i] >= 0x20) | ||
1321 | buf[i] = wwn->vendor[i]; | ||
1322 | else | ||
1323 | buf[i] = ' '; | ||
1324 | buf[i] = '\0'; | ||
1325 | pr_debug(" Vendor: %s\n", buf); | ||
1326 | |||
1327 | for (i = 0; i < 16; i++) | ||
1328 | if (wwn->model[i] >= 0x20) | ||
1329 | buf[i] = wwn->model[i]; | ||
1330 | else | ||
1331 | buf[i] = ' '; | ||
1332 | buf[i] = '\0'; | ||
1333 | pr_debug(" Model: %s\n", buf); | ||
1334 | |||
1335 | for (i = 0; i < 4; i++) | ||
1336 | if (wwn->revision[i] >= 0x20) | ||
1337 | buf[i] = wwn->revision[i]; | ||
1338 | else | ||
1339 | buf[i] = ' '; | ||
1340 | buf[i] = '\0'; | ||
1341 | pr_debug(" Revision: %s\n", buf); | ||
1342 | |||
1343 | device_type = dev->transport->get_device_type(dev); | ||
1344 | pr_debug(" Type: %s ", scsi_device_type(device_type)); | ||
1345 | } | ||
1346 | |||
1347 | struct se_device *target_alloc_device(struct se_hba *hba, const char *name) | ||
1348 | { | ||
1349 | struct se_device *dev; | ||
1350 | |||
1351 | dev = hba->transport->alloc_device(hba, name); | ||
1352 | if (!dev) | ||
1353 | return NULL; | ||
1354 | |||
1355 | dev->dev_link_magic = SE_DEV_LINK_MAGIC; | ||
1356 | dev->se_hba = hba; | ||
1357 | dev->transport = hba->transport; | ||
1358 | |||
1359 | INIT_LIST_HEAD(&dev->dev_list); | ||
1360 | INIT_LIST_HEAD(&dev->dev_sep_list); | ||
1361 | INIT_LIST_HEAD(&dev->dev_tmr_list); | ||
1362 | INIT_LIST_HEAD(&dev->delayed_cmd_list); | ||
1363 | INIT_LIST_HEAD(&dev->state_list); | ||
1364 | INIT_LIST_HEAD(&dev->qf_cmd_list); | ||
1365 | spin_lock_init(&dev->stats_lock); | ||
1366 | spin_lock_init(&dev->execute_task_lock); | ||
1367 | spin_lock_init(&dev->delayed_cmd_lock); | ||
1368 | spin_lock_init(&dev->dev_reservation_lock); | ||
1369 | spin_lock_init(&dev->se_port_lock); | ||
1370 | spin_lock_init(&dev->se_tmr_lock); | ||
1371 | spin_lock_init(&dev->qf_cmd_lock); | ||
1372 | atomic_set(&dev->dev_ordered_id, 0); | ||
1373 | INIT_LIST_HEAD(&dev->t10_wwn.t10_vpd_list); | ||
1374 | spin_lock_init(&dev->t10_wwn.t10_vpd_lock); | ||
1375 | INIT_LIST_HEAD(&dev->t10_pr.registration_list); | ||
1376 | INIT_LIST_HEAD(&dev->t10_pr.aptpl_reg_list); | ||
1377 | spin_lock_init(&dev->t10_pr.registration_lock); | ||
1378 | spin_lock_init(&dev->t10_pr.aptpl_reg_lock); | ||
1379 | INIT_LIST_HEAD(&dev->t10_alua.tg_pt_gps_list); | ||
1380 | spin_lock_init(&dev->t10_alua.tg_pt_gps_lock); | ||
1381 | |||
1382 | dev->t10_pr.pr_aptpl_buf_len = PR_APTPL_BUF_LEN; | ||
1383 | dev->t10_wwn.t10_dev = dev; | ||
1384 | dev->t10_alua.t10_dev = dev; | ||
1385 | |||
1386 | dev->dev_attrib.da_dev = dev; | ||
1387 | dev->dev_attrib.emulate_dpo = DA_EMULATE_DPO; | ||
1388 | dev->dev_attrib.emulate_fua_write = DA_EMULATE_FUA_WRITE; | ||
1389 | dev->dev_attrib.emulate_fua_read = DA_EMULATE_FUA_READ; | ||
1390 | dev->dev_attrib.emulate_write_cache = DA_EMULATE_WRITE_CACHE; | ||
1391 | dev->dev_attrib.emulate_ua_intlck_ctrl = DA_EMULATE_UA_INTLLCK_CTRL; | ||
1392 | dev->dev_attrib.emulate_tas = DA_EMULATE_TAS; | ||
1393 | dev->dev_attrib.emulate_tpu = DA_EMULATE_TPU; | ||
1394 | dev->dev_attrib.emulate_tpws = DA_EMULATE_TPWS; | ||
1395 | dev->dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS; | ||
1396 | dev->dev_attrib.is_nonrot = DA_IS_NONROT; | ||
1397 | dev->dev_attrib.emulate_rest_reord = DA_EMULATE_REST_REORD; | ||
1398 | dev->dev_attrib.max_unmap_lba_count = DA_MAX_UNMAP_LBA_COUNT; | ||
1399 | dev->dev_attrib.max_unmap_block_desc_count = | ||
1400 | DA_MAX_UNMAP_BLOCK_DESC_COUNT; | ||
1401 | dev->dev_attrib.unmap_granularity = DA_UNMAP_GRANULARITY_DEFAULT; | ||
1402 | dev->dev_attrib.unmap_granularity_alignment = | ||
1403 | DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT; | ||
1404 | dev->dev_attrib.max_write_same_len = DA_MAX_WRITE_SAME_LEN; | ||
1405 | dev->dev_attrib.fabric_max_sectors = DA_FABRIC_MAX_SECTORS; | ||
1406 | dev->dev_attrib.optimal_sectors = DA_FABRIC_MAX_SECTORS; | ||
1407 | |||
1408 | return dev; | ||
1409 | } | ||
1410 | |||
1411 | int target_configure_device(struct se_device *dev) | ||
1412 | { | ||
1413 | struct se_hba *hba = dev->se_hba; | ||
1414 | int ret; | ||
1415 | |||
1416 | if (dev->dev_flags & DF_CONFIGURED) { | ||
1417 | pr_err("se_dev->se_dev_ptr already set for storage" | ||
1418 | " object\n"); | ||
1419 | return -EEXIST; | ||
1420 | } | ||
1421 | |||
1422 | ret = dev->transport->configure_device(dev); | ||
1423 | if (ret) | ||
1424 | goto out; | ||
1425 | dev->dev_flags |= DF_CONFIGURED; | ||
1426 | |||
1427 | /* | ||
1428 | * XXX: there is not much point to have two different values here.. | ||
1429 | */ | ||
1430 | dev->dev_attrib.block_size = dev->dev_attrib.hw_block_size; | ||
1431 | dev->dev_attrib.queue_depth = dev->dev_attrib.hw_queue_depth; | ||
1432 | |||
1433 | /* | ||
1434 | * Align max_hw_sectors down to PAGE_SIZE I/O transfers | ||
1435 | */ | ||
1436 | dev->dev_attrib.hw_max_sectors = | ||
1437 | se_dev_align_max_sectors(dev->dev_attrib.hw_max_sectors, | ||
1438 | dev->dev_attrib.hw_block_size); | ||
1439 | |||
1440 | dev->dev_index = scsi_get_new_index(SCSI_DEVICE_INDEX); | ||
1441 | dev->creation_time = get_jiffies_64(); | ||
1442 | |||
1443 | ret = core_setup_alua(dev); | ||
1444 | if (ret) | ||
1445 | goto out; | ||
1446 | |||
1447 | /* | ||
1448 | * Startup the struct se_device processing thread | ||
1449 | */ | ||
1450 | dev->tmr_wq = alloc_workqueue("tmr-%s", WQ_MEM_RECLAIM | WQ_UNBOUND, 1, | ||
1451 | dev->transport->name); | ||
1452 | if (!dev->tmr_wq) { | ||
1453 | pr_err("Unable to create tmr workqueue for %s\n", | ||
1454 | dev->transport->name); | ||
1455 | ret = -ENOMEM; | ||
1456 | goto out_free_alua; | ||
1457 | } | ||
1458 | |||
1459 | /* | ||
1460 | * Setup work_queue for QUEUE_FULL | ||
1461 | */ | ||
1462 | INIT_WORK(&dev->qf_work_queue, target_qf_do_work); | ||
1463 | |||
1464 | /* | ||
1465 | * Preload the initial INQUIRY const values if we are doing | ||
1466 | * anything virtual (IBLOCK, FILEIO, RAMDISK), but not for TCM/pSCSI | ||
1467 | * passthrough because this is being provided by the backend LLD. | ||
1468 | */ | ||
1469 | if (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) { | ||
1470 | strncpy(&dev->t10_wwn.vendor[0], "LIO-ORG", 8); | ||
1471 | strncpy(&dev->t10_wwn.model[0], | ||
1472 | dev->transport->inquiry_prod, 16); | ||
1473 | strncpy(&dev->t10_wwn.revision[0], | ||
1474 | dev->transport->inquiry_rev, 4); | ||
1475 | } | ||
1476 | |||
1477 | scsi_dump_inquiry(dev); | ||
1478 | |||
1479 | spin_lock(&hba->device_lock); | ||
1480 | hba->dev_count++; | ||
1481 | spin_unlock(&hba->device_lock); | ||
1482 | return 0; | ||
1483 | |||
1484 | out_free_alua: | ||
1485 | core_alua_free_lu_gp_mem(dev); | ||
1486 | out: | ||
1487 | se_release_vpd_for_dev(dev); | ||
1488 | return ret; | ||
1489 | } | ||
1490 | |||
1491 | void target_free_device(struct se_device *dev) | ||
1492 | { | ||
1493 | struct se_hba *hba = dev->se_hba; | ||
1494 | |||
1495 | WARN_ON(!list_empty(&dev->dev_sep_list)); | ||
1496 | |||
1497 | if (dev->dev_flags & DF_CONFIGURED) { | ||
1498 | destroy_workqueue(dev->tmr_wq); | ||
1499 | |||
1500 | spin_lock(&hba->device_lock); | ||
1501 | hba->dev_count--; | ||
1502 | spin_unlock(&hba->device_lock); | ||
1503 | } | ||
1504 | |||
1505 | core_alua_free_lu_gp_mem(dev); | ||
1506 | core_scsi3_free_all_registrations(dev); | ||
1507 | se_release_vpd_for_dev(dev); | ||
1508 | |||
1509 | dev->transport->free_device(dev); | ||
1510 | } | ||
1511 | |||
1571 | int core_dev_setup_virtual_lun0(void) | 1512 | int core_dev_setup_virtual_lun0(void) |
1572 | { | 1513 | { |
1573 | struct se_hba *hba; | 1514 | struct se_hba *hba; |
1574 | struct se_device *dev; | 1515 | struct se_device *dev; |
1575 | struct se_subsystem_dev *se_dev = NULL; | ||
1576 | struct se_subsystem_api *t; | ||
1577 | char buf[16]; | 1516 | char buf[16]; |
1578 | int ret; | 1517 | int ret; |
1579 | 1518 | ||
@@ -1581,60 +1520,28 @@ int core_dev_setup_virtual_lun0(void) | |||
1581 | if (IS_ERR(hba)) | 1520 | if (IS_ERR(hba)) |
1582 | return PTR_ERR(hba); | 1521 | return PTR_ERR(hba); |
1583 | 1522 | ||
1584 | lun0_hba = hba; | 1523 | dev = target_alloc_device(hba, "virt_lun0"); |
1585 | t = hba->transport; | 1524 | if (!dev) { |
1586 | |||
1587 | se_dev = kzalloc(sizeof(struct se_subsystem_dev), GFP_KERNEL); | ||
1588 | if (!se_dev) { | ||
1589 | pr_err("Unable to allocate memory for" | ||
1590 | " struct se_subsystem_dev\n"); | ||
1591 | ret = -ENOMEM; | 1525 | ret = -ENOMEM; |
1592 | goto out; | 1526 | goto out_free_hba; |
1593 | } | 1527 | } |
1594 | INIT_LIST_HEAD(&se_dev->t10_wwn.t10_vpd_list); | ||
1595 | spin_lock_init(&se_dev->t10_wwn.t10_vpd_lock); | ||
1596 | INIT_LIST_HEAD(&se_dev->t10_pr.registration_list); | ||
1597 | INIT_LIST_HEAD(&se_dev->t10_pr.aptpl_reg_list); | ||
1598 | spin_lock_init(&se_dev->t10_pr.registration_lock); | ||
1599 | spin_lock_init(&se_dev->t10_pr.aptpl_reg_lock); | ||
1600 | INIT_LIST_HEAD(&se_dev->t10_alua.tg_pt_gps_list); | ||
1601 | spin_lock_init(&se_dev->t10_alua.tg_pt_gps_lock); | ||
1602 | spin_lock_init(&se_dev->se_dev_lock); | ||
1603 | se_dev->t10_pr.pr_aptpl_buf_len = PR_APTPL_BUF_LEN; | ||
1604 | se_dev->t10_wwn.t10_sub_dev = se_dev; | ||
1605 | se_dev->t10_alua.t10_sub_dev = se_dev; | ||
1606 | se_dev->se_dev_attrib.da_sub_dev = se_dev; | ||
1607 | se_dev->se_dev_hba = hba; | ||
1608 | |||
1609 | se_dev->se_dev_su_ptr = t->allocate_virtdevice(hba, "virt_lun0"); | ||
1610 | if (!se_dev->se_dev_su_ptr) { | ||
1611 | pr_err("Unable to locate subsystem dependent pointer" | ||
1612 | " from allocate_virtdevice()\n"); | ||
1613 | ret = -ENOMEM; | ||
1614 | goto out; | ||
1615 | } | ||
1616 | lun0_su_dev = se_dev; | ||
1617 | 1528 | ||
1618 | memset(buf, 0, 16); | 1529 | memset(buf, 0, 16); |
1619 | sprintf(buf, "rd_pages=8"); | 1530 | sprintf(buf, "rd_pages=8"); |
1620 | t->set_configfs_dev_params(hba, se_dev, buf, sizeof(buf)); | 1531 | hba->transport->set_configfs_dev_params(dev, buf, sizeof(buf)); |
1621 | 1532 | ||
1622 | dev = t->create_virtdevice(hba, se_dev, se_dev->se_dev_su_ptr); | 1533 | ret = target_configure_device(dev); |
1623 | if (IS_ERR(dev)) { | 1534 | if (ret) |
1624 | ret = PTR_ERR(dev); | 1535 | goto out_free_se_dev; |
1625 | goto out; | ||
1626 | } | ||
1627 | se_dev->se_dev_ptr = dev; | ||
1628 | g_lun0_dev = dev; | ||
1629 | 1536 | ||
1537 | lun0_hba = hba; | ||
1538 | g_lun0_dev = dev; | ||
1630 | return 0; | 1539 | return 0; |
1631 | out: | 1540 | |
1632 | lun0_su_dev = NULL; | 1541 | out_free_se_dev: |
1633 | kfree(se_dev); | 1542 | target_free_device(dev); |
1634 | if (lun0_hba) { | 1543 | out_free_hba: |
1635 | core_delete_hba(lun0_hba); | 1544 | core_delete_hba(hba); |
1636 | lun0_hba = NULL; | ||
1637 | } | ||
1638 | return ret; | 1545 | return ret; |
1639 | } | 1546 | } |
1640 | 1547 | ||
@@ -1642,14 +1549,11 @@ out: | |||
1642 | void core_dev_release_virtual_lun0(void) | 1549 | void core_dev_release_virtual_lun0(void) |
1643 | { | 1550 | { |
1644 | struct se_hba *hba = lun0_hba; | 1551 | struct se_hba *hba = lun0_hba; |
1645 | struct se_subsystem_dev *su_dev = lun0_su_dev; | ||
1646 | 1552 | ||
1647 | if (!hba) | 1553 | if (!hba) |
1648 | return; | 1554 | return; |
1649 | 1555 | ||
1650 | if (g_lun0_dev) | 1556 | if (g_lun0_dev) |
1651 | se_free_virtual_device(g_lun0_dev, hba); | 1557 | target_free_device(g_lun0_dev); |
1652 | |||
1653 | kfree(su_dev); | ||
1654 | core_delete_hba(hba); | 1558 | core_delete_hba(hba); |
1655 | } | 1559 | } |
diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index bca737bb813d..810263dfa4a1 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c | |||
@@ -4,10 +4,9 @@ | |||
4 | * This file contains generic fabric module configfs infrastructure for | 4 | * This file contains generic fabric module configfs infrastructure for |
5 | * TCM v4.x code | 5 | * TCM v4.x code |
6 | * | 6 | * |
7 | * Copyright (c) 2010,2011 Rising Tide Systems | 7 | * (c) Copyright 2010-2012 RisingTide Systems LLC. |
8 | * Copyright (c) 2010,2011 Linux-iSCSI.org | ||
9 | * | 8 | * |
10 | * Copyright (c) Nicholas A. Bellinger <nab@linux-iscsi.org> | 9 | * Nicholas A. Bellinger <nab@linux-iscsi.org> |
11 | * | 10 | * |
12 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
@@ -71,6 +70,12 @@ static int target_fabric_mappedlun_link( | |||
71 | struct se_portal_group *se_tpg; | 70 | struct se_portal_group *se_tpg; |
72 | struct config_item *nacl_ci, *tpg_ci, *tpg_ci_s, *wwn_ci, *wwn_ci_s; | 71 | struct config_item *nacl_ci, *tpg_ci, *tpg_ci_s, *wwn_ci, *wwn_ci_s; |
73 | int ret = 0, lun_access; | 72 | int ret = 0, lun_access; |
73 | |||
74 | if (lun->lun_link_magic != SE_LUN_LINK_MAGIC) { | ||
75 | pr_err("Bad lun->lun_link_magic, not a valid lun_ci pointer:" | ||
76 | " %p to struct lun: %p\n", lun_ci, lun); | ||
77 | return -EFAULT; | ||
78 | } | ||
74 | /* | 79 | /* |
75 | * Ensure that the source port exists | 80 | * Ensure that the source port exists |
76 | */ | 81 | */ |
@@ -358,7 +363,7 @@ static struct config_group *target_fabric_make_mappedlun( | |||
358 | } | 363 | } |
359 | 364 | ||
360 | lacl_cg = &lacl->se_lun_group; | 365 | lacl_cg = &lacl->se_lun_group; |
361 | lacl_cg->default_groups = kzalloc(sizeof(struct config_group) * 2, | 366 | lacl_cg->default_groups = kmalloc(sizeof(struct config_group *) * 2, |
362 | GFP_KERNEL); | 367 | GFP_KERNEL); |
363 | if (!lacl_cg->default_groups) { | 368 | if (!lacl_cg->default_groups) { |
364 | pr_err("Unable to allocate lacl_cg->default_groups\n"); | 369 | pr_err("Unable to allocate lacl_cg->default_groups\n"); |
@@ -374,7 +379,7 @@ static struct config_group *target_fabric_make_mappedlun( | |||
374 | lacl_cg->default_groups[1] = NULL; | 379 | lacl_cg->default_groups[1] = NULL; |
375 | 380 | ||
376 | ml_stat_grp = &lacl->ml_stat_grps.stat_group; | 381 | ml_stat_grp = &lacl->ml_stat_grps.stat_group; |
377 | ml_stat_grp->default_groups = kzalloc(sizeof(struct config_group) * 3, | 382 | ml_stat_grp->default_groups = kmalloc(sizeof(struct config_group *) * 3, |
378 | GFP_KERNEL); | 383 | GFP_KERNEL); |
379 | if (!ml_stat_grp->default_groups) { | 384 | if (!ml_stat_grp->default_groups) { |
380 | pr_err("Unable to allocate ml_stat_grp->default_groups\n"); | 385 | pr_err("Unable to allocate ml_stat_grp->default_groups\n"); |
@@ -734,17 +739,21 @@ static int target_fabric_port_link( | |||
734 | struct config_item *se_dev_ci) | 739 | struct config_item *se_dev_ci) |
735 | { | 740 | { |
736 | struct config_item *tpg_ci; | 741 | struct config_item *tpg_ci; |
737 | struct se_device *dev; | ||
738 | struct se_lun *lun = container_of(to_config_group(lun_ci), | 742 | struct se_lun *lun = container_of(to_config_group(lun_ci), |
739 | struct se_lun, lun_group); | 743 | struct se_lun, lun_group); |
740 | struct se_lun *lun_p; | 744 | struct se_lun *lun_p; |
741 | struct se_portal_group *se_tpg; | 745 | struct se_portal_group *se_tpg; |
742 | struct se_subsystem_dev *se_dev = container_of( | 746 | struct se_device *dev = |
743 | to_config_group(se_dev_ci), struct se_subsystem_dev, | 747 | container_of(to_config_group(se_dev_ci), struct se_device, dev_group); |
744 | se_dev_group); | ||
745 | struct target_fabric_configfs *tf; | 748 | struct target_fabric_configfs *tf; |
746 | int ret; | 749 | int ret; |
747 | 750 | ||
751 | if (dev->dev_link_magic != SE_DEV_LINK_MAGIC) { | ||
752 | pr_err("Bad dev->dev_link_magic, not a valid se_dev_ci pointer:" | ||
753 | " %p to struct se_device: %p\n", se_dev_ci, dev); | ||
754 | return -EFAULT; | ||
755 | } | ||
756 | |||
748 | tpg_ci = &lun_ci->ci_parent->ci_group->cg_item; | 757 | tpg_ci = &lun_ci->ci_parent->ci_group->cg_item; |
749 | se_tpg = container_of(to_config_group(tpg_ci), | 758 | se_tpg = container_of(to_config_group(tpg_ci), |
750 | struct se_portal_group, tpg_group); | 759 | struct se_portal_group, tpg_group); |
@@ -755,14 +764,6 @@ static int target_fabric_port_link( | |||
755 | return -EEXIST; | 764 | return -EEXIST; |
756 | } | 765 | } |
757 | 766 | ||
758 | dev = se_dev->se_dev_ptr; | ||
759 | if (!dev) { | ||
760 | pr_err("Unable to locate struct se_device pointer from" | ||
761 | " %s\n", config_item_name(se_dev_ci)); | ||
762 | ret = -ENODEV; | ||
763 | goto out; | ||
764 | } | ||
765 | |||
766 | lun_p = core_dev_add_lun(se_tpg, dev, lun->unpacked_lun); | 767 | lun_p = core_dev_add_lun(se_tpg, dev, lun->unpacked_lun); |
767 | if (IS_ERR(lun_p)) { | 768 | if (IS_ERR(lun_p)) { |
768 | pr_err("core_dev_add_lun() failed\n"); | 769 | pr_err("core_dev_add_lun() failed\n"); |
@@ -869,7 +870,7 @@ static struct config_group *target_fabric_make_lun( | |||
869 | return ERR_PTR(-EINVAL); | 870 | return ERR_PTR(-EINVAL); |
870 | 871 | ||
871 | lun_cg = &lun->lun_group; | 872 | lun_cg = &lun->lun_group; |
872 | lun_cg->default_groups = kzalloc(sizeof(struct config_group) * 2, | 873 | lun_cg->default_groups = kmalloc(sizeof(struct config_group *) * 2, |
873 | GFP_KERNEL); | 874 | GFP_KERNEL); |
874 | if (!lun_cg->default_groups) { | 875 | if (!lun_cg->default_groups) { |
875 | pr_err("Unable to allocate lun_cg->default_groups\n"); | 876 | pr_err("Unable to allocate lun_cg->default_groups\n"); |
diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c index e460d6233a0a..687b0b0a4aa6 100644 --- a/drivers/target/target_core_fabric_lib.c +++ b/drivers/target/target_core_fabric_lib.c | |||
@@ -4,8 +4,7 @@ | |||
4 | * This file contains generic high level protocol identifier and PR | 4 | * This file contains generic high level protocol identifier and PR |
5 | * handlers for TCM fabric modules | 5 | * handlers for TCM fabric modules |
6 | * | 6 | * |
7 | * Copyright (c) 2010 Rising Tide Systems, Inc. | 7 | * (c) Copyright 2010-2012 RisingTide Systems LLC. |
8 | * Copyright (c) 2010 Linux-iSCSI.org | ||
9 | * | 8 | * |
10 | * Nicholas A. Bellinger <nab@linux-iscsi.org> | 9 | * Nicholas A. Bellinger <nab@linux-iscsi.org> |
11 | * | 10 | * |
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 0360383dfb94..b9c88497e8f0 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c | |||
@@ -3,10 +3,7 @@ | |||
3 | * | 3 | * |
4 | * This file contains the Storage Engine <-> FILEIO transport specific functions | 4 | * This file contains the Storage Engine <-> FILEIO transport specific functions |
5 | * | 5 | * |
6 | * Copyright (c) 2005 PyX Technologies, Inc. | 6 | * (c) Copyright 2005-2012 RisingTide Systems LLC. |
7 | * Copyright (c) 2005-2006 SBE, Inc. All Rights Reserved. | ||
8 | * Copyright (c) 2007-2010 Rising Tide Systems | ||
9 | * Copyright (c) 2008-2010 Linux-iSCSI.org | ||
10 | * | 7 | * |
11 | * Nicholas A. Bellinger <nab@kernel.org> | 8 | * Nicholas A. Bellinger <nab@kernel.org> |
12 | * | 9 | * |
@@ -41,7 +38,10 @@ | |||
41 | 38 | ||
42 | #include "target_core_file.h" | 39 | #include "target_core_file.h" |
43 | 40 | ||
44 | static struct se_subsystem_api fileio_template; | 41 | static inline struct fd_dev *FD_DEV(struct se_device *dev) |
42 | { | ||
43 | return container_of(dev, struct fd_dev, dev); | ||
44 | } | ||
45 | 45 | ||
46 | /* fd_attach_hba(): (Part of se_subsystem_api_t template) | 46 | /* fd_attach_hba(): (Part of se_subsystem_api_t template) |
47 | * | 47 | * |
@@ -82,7 +82,7 @@ static void fd_detach_hba(struct se_hba *hba) | |||
82 | hba->hba_ptr = NULL; | 82 | hba->hba_ptr = NULL; |
83 | } | 83 | } |
84 | 84 | ||
85 | static void *fd_allocate_virtdevice(struct se_hba *hba, const char *name) | 85 | static struct se_device *fd_alloc_device(struct se_hba *hba, const char *name) |
86 | { | 86 | { |
87 | struct fd_dev *fd_dev; | 87 | struct fd_dev *fd_dev; |
88 | struct fd_host *fd_host = hba->hba_ptr; | 88 | struct fd_host *fd_host = hba->hba_ptr; |
@@ -97,34 +97,28 @@ static void *fd_allocate_virtdevice(struct se_hba *hba, const char *name) | |||
97 | 97 | ||
98 | pr_debug("FILEIO: Allocated fd_dev for %p\n", name); | 98 | pr_debug("FILEIO: Allocated fd_dev for %p\n", name); |
99 | 99 | ||
100 | return fd_dev; | 100 | return &fd_dev->dev; |
101 | } | 101 | } |
102 | 102 | ||
103 | /* fd_create_virtdevice(): (Part of se_subsystem_api_t template) | 103 | static int fd_configure_device(struct se_device *dev) |
104 | * | ||
105 | * | ||
106 | */ | ||
107 | static struct se_device *fd_create_virtdevice( | ||
108 | struct se_hba *hba, | ||
109 | struct se_subsystem_dev *se_dev, | ||
110 | void *p) | ||
111 | { | 104 | { |
112 | struct se_device *dev; | 105 | struct fd_dev *fd_dev = FD_DEV(dev); |
113 | struct se_dev_limits dev_limits; | 106 | struct fd_host *fd_host = dev->se_hba->hba_ptr; |
114 | struct queue_limits *limits; | ||
115 | struct fd_dev *fd_dev = p; | ||
116 | struct fd_host *fd_host = hba->hba_ptr; | ||
117 | struct file *file; | 107 | struct file *file; |
118 | struct inode *inode = NULL; | 108 | struct inode *inode = NULL; |
119 | int dev_flags = 0, flags, ret = -EINVAL; | 109 | int flags, ret = -EINVAL; |
120 | 110 | ||
121 | memset(&dev_limits, 0, sizeof(struct se_dev_limits)); | 111 | if (!(fd_dev->fbd_flags & FBDF_HAS_PATH)) { |
112 | pr_err("Missing fd_dev_name=\n"); | ||
113 | return -EINVAL; | ||
114 | } | ||
122 | 115 | ||
123 | /* | 116 | /* |
124 | * Use O_DSYNC by default instead of O_SYNC to forgo syncing | 117 | * Use O_DSYNC by default instead of O_SYNC to forgo syncing |
125 | * of pure timestamp updates. | 118 | * of pure timestamp updates. |
126 | */ | 119 | */ |
127 | flags = O_RDWR | O_CREAT | O_LARGEFILE | O_DSYNC; | 120 | flags = O_RDWR | O_CREAT | O_LARGEFILE | O_DSYNC; |
121 | |||
128 | /* | 122 | /* |
129 | * Optionally allow fd_buffered_io=1 to be enabled for people | 123 | * Optionally allow fd_buffered_io=1 to be enabled for people |
130 | * who want use the fs buffer cache as an WriteCache mechanism. | 124 | * who want use the fs buffer cache as an WriteCache mechanism. |
@@ -154,22 +148,17 @@ static struct se_device *fd_create_virtdevice( | |||
154 | */ | 148 | */ |
155 | inode = file->f_mapping->host; | 149 | inode = file->f_mapping->host; |
156 | if (S_ISBLK(inode->i_mode)) { | 150 | if (S_ISBLK(inode->i_mode)) { |
157 | struct request_queue *q; | 151 | struct request_queue *q = bdev_get_queue(inode->i_bdev); |
158 | unsigned long long dev_size; | 152 | unsigned long long dev_size; |
159 | /* | 153 | |
160 | * Setup the local scope queue_limits from struct request_queue->limits | 154 | dev->dev_attrib.hw_block_size = |
161 | * to pass into transport_add_device_to_core_hba() as struct se_dev_limits. | 155 | bdev_logical_block_size(inode->i_bdev); |
162 | */ | 156 | dev->dev_attrib.hw_max_sectors = queue_max_hw_sectors(q); |
163 | q = bdev_get_queue(inode->i_bdev); | 157 | |
164 | limits = &dev_limits.limits; | ||
165 | limits->logical_block_size = bdev_logical_block_size(inode->i_bdev); | ||
166 | limits->max_hw_sectors = queue_max_hw_sectors(q); | ||
167 | limits->max_sectors = queue_max_sectors(q); | ||
168 | /* | 158 | /* |
169 | * Determine the number of bytes from i_size_read() minus | 159 | * Determine the number of bytes from i_size_read() minus |
170 | * one (1) logical sector from underlying struct block_device | 160 | * one (1) logical sector from underlying struct block_device |
171 | */ | 161 | */ |
172 | fd_dev->fd_block_size = bdev_logical_block_size(inode->i_bdev); | ||
173 | dev_size = (i_size_read(file->f_mapping->host) - | 162 | dev_size = (i_size_read(file->f_mapping->host) - |
174 | fd_dev->fd_block_size); | 163 | fd_dev->fd_block_size); |
175 | 164 | ||
@@ -185,26 +174,18 @@ static struct se_device *fd_create_virtdevice( | |||
185 | goto fail; | 174 | goto fail; |
186 | } | 175 | } |
187 | 176 | ||
188 | limits = &dev_limits.limits; | 177 | dev->dev_attrib.hw_block_size = FD_BLOCKSIZE; |
189 | limits->logical_block_size = FD_BLOCKSIZE; | 178 | dev->dev_attrib.hw_max_sectors = FD_MAX_SECTORS; |
190 | limits->max_hw_sectors = FD_MAX_SECTORS; | ||
191 | limits->max_sectors = FD_MAX_SECTORS; | ||
192 | fd_dev->fd_block_size = FD_BLOCKSIZE; | ||
193 | } | 179 | } |
194 | 180 | ||
195 | dev_limits.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH; | 181 | fd_dev->fd_block_size = dev->dev_attrib.hw_block_size; |
196 | dev_limits.queue_depth = FD_DEVICE_QUEUE_DEPTH; | ||
197 | 182 | ||
198 | dev = transport_add_device_to_core_hba(hba, &fileio_template, | 183 | dev->dev_attrib.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH; |
199 | se_dev, dev_flags, fd_dev, | ||
200 | &dev_limits, "FILEIO", FD_VERSION); | ||
201 | if (!dev) | ||
202 | goto fail; | ||
203 | 184 | ||
204 | if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) { | 185 | if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) { |
205 | pr_debug("FILEIO: Forcing setting of emulate_write_cache=1" | 186 | pr_debug("FILEIO: Forcing setting of emulate_write_cache=1" |
206 | " with FDBD_HAS_BUFFERED_IO_WCE\n"); | 187 | " with FDBD_HAS_BUFFERED_IO_WCE\n"); |
207 | dev->se_sub_dev->se_dev_attrib.emulate_write_cache = 1; | 188 | dev->dev_attrib.emulate_write_cache = 1; |
208 | } | 189 | } |
209 | 190 | ||
210 | fd_dev->fd_dev_id = fd_host->fd_host_dev_id_count++; | 191 | fd_dev->fd_dev_id = fd_host->fd_host_dev_id_count++; |
@@ -214,22 +195,18 @@ static struct se_device *fd_create_virtdevice( | |||
214 | " %llu total bytes\n", fd_host->fd_host_id, fd_dev->fd_dev_id, | 195 | " %llu total bytes\n", fd_host->fd_host_id, fd_dev->fd_dev_id, |
215 | fd_dev->fd_dev_name, fd_dev->fd_dev_size); | 196 | fd_dev->fd_dev_name, fd_dev->fd_dev_size); |
216 | 197 | ||
217 | return dev; | 198 | return 0; |
218 | fail: | 199 | fail: |
219 | if (fd_dev->fd_file) { | 200 | if (fd_dev->fd_file) { |
220 | filp_close(fd_dev->fd_file, NULL); | 201 | filp_close(fd_dev->fd_file, NULL); |
221 | fd_dev->fd_file = NULL; | 202 | fd_dev->fd_file = NULL; |
222 | } | 203 | } |
223 | return ERR_PTR(ret); | 204 | return ret; |
224 | } | 205 | } |
225 | 206 | ||
226 | /* fd_free_device(): (Part of se_subsystem_api_t template) | 207 | static void fd_free_device(struct se_device *dev) |
227 | * | ||
228 | * | ||
229 | */ | ||
230 | static void fd_free_device(void *p) | ||
231 | { | 208 | { |
232 | struct fd_dev *fd_dev = p; | 209 | struct fd_dev *fd_dev = FD_DEV(dev); |
233 | 210 | ||
234 | if (fd_dev->fd_file) { | 211 | if (fd_dev->fd_file) { |
235 | filp_close(fd_dev->fd_file, NULL); | 212 | filp_close(fd_dev->fd_file, NULL); |
@@ -239,17 +216,16 @@ static void fd_free_device(void *p) | |||
239 | kfree(fd_dev); | 216 | kfree(fd_dev); |
240 | } | 217 | } |
241 | 218 | ||
242 | static int fd_do_readv(struct se_cmd *cmd, struct scatterlist *sgl, | 219 | static int fd_do_rw(struct se_cmd *cmd, struct scatterlist *sgl, |
243 | u32 sgl_nents) | 220 | u32 sgl_nents, int is_write) |
244 | { | 221 | { |
245 | struct se_device *se_dev = cmd->se_dev; | 222 | struct se_device *se_dev = cmd->se_dev; |
246 | struct fd_dev *dev = se_dev->dev_ptr; | 223 | struct fd_dev *dev = FD_DEV(se_dev); |
247 | struct file *fd = dev->fd_file; | 224 | struct file *fd = dev->fd_file; |
248 | struct scatterlist *sg; | 225 | struct scatterlist *sg; |
249 | struct iovec *iov; | 226 | struct iovec *iov; |
250 | mm_segment_t old_fs; | 227 | mm_segment_t old_fs; |
251 | loff_t pos = (cmd->t_task_lba * | 228 | loff_t pos = (cmd->t_task_lba * se_dev->dev_attrib.block_size); |
252 | se_dev->se_sub_dev->se_dev_attrib.block_size); | ||
253 | int ret = 0, i; | 229 | int ret = 0, i; |
254 | 230 | ||
255 | iov = kzalloc(sizeof(struct iovec) * sgl_nents, GFP_KERNEL); | 231 | iov = kzalloc(sizeof(struct iovec) * sgl_nents, GFP_KERNEL); |
@@ -260,81 +236,58 @@ static int fd_do_readv(struct se_cmd *cmd, struct scatterlist *sgl, | |||
260 | 236 | ||
261 | for_each_sg(sgl, sg, sgl_nents, i) { | 237 | for_each_sg(sgl, sg, sgl_nents, i) { |
262 | iov[i].iov_len = sg->length; | 238 | iov[i].iov_len = sg->length; |
263 | iov[i].iov_base = sg_virt(sg); | 239 | iov[i].iov_base = kmap(sg_page(sg)) + sg->offset; |
264 | } | 240 | } |
265 | 241 | ||
266 | old_fs = get_fs(); | 242 | old_fs = get_fs(); |
267 | set_fs(get_ds()); | 243 | set_fs(get_ds()); |
268 | ret = vfs_readv(fd, &iov[0], sgl_nents, &pos); | 244 | |
245 | if (is_write) | ||
246 | ret = vfs_writev(fd, &iov[0], sgl_nents, &pos); | ||
247 | else | ||
248 | ret = vfs_readv(fd, &iov[0], sgl_nents, &pos); | ||
249 | |||
269 | set_fs(old_fs); | 250 | set_fs(old_fs); |
270 | 251 | ||
252 | for_each_sg(sgl, sg, sgl_nents, i) | ||
253 | kunmap(sg_page(sg)); | ||
254 | |||
271 | kfree(iov); | 255 | kfree(iov); |
272 | /* | 256 | |
273 | * Return zeros and GOOD status even if the READ did not return | 257 | if (is_write) { |
274 | * the expected virt_size for struct file w/o a backing struct | ||
275 | * block_device. | ||
276 | */ | ||
277 | if (S_ISBLK(fd->f_dentry->d_inode->i_mode)) { | ||
278 | if (ret < 0 || ret != cmd->data_length) { | 258 | if (ret < 0 || ret != cmd->data_length) { |
279 | pr_err("vfs_readv() returned %d," | 259 | pr_err("%s() write returned %d\n", __func__, ret); |
280 | " expecting %d for S_ISBLK\n", ret, | ||
281 | (int)cmd->data_length); | ||
282 | return (ret < 0 ? ret : -EINVAL); | 260 | return (ret < 0 ? ret : -EINVAL); |
283 | } | 261 | } |
284 | } else { | 262 | } else { |
285 | if (ret < 0) { | 263 | /* |
286 | pr_err("vfs_readv() returned %d for non" | 264 | * Return zeros and GOOD status even if the READ did not return |
287 | " S_ISBLK\n", ret); | 265 | * the expected virt_size for struct file w/o a backing struct |
288 | return ret; | 266 | * block_device. |
267 | */ | ||
268 | if (S_ISBLK(fd->f_dentry->d_inode->i_mode)) { | ||
269 | if (ret < 0 || ret != cmd->data_length) { | ||
270 | pr_err("%s() returned %d, expecting %u for " | ||
271 | "S_ISBLK\n", __func__, ret, | ||
272 | cmd->data_length); | ||
273 | return (ret < 0 ? ret : -EINVAL); | ||
274 | } | ||
275 | } else { | ||
276 | if (ret < 0) { | ||
277 | pr_err("%s() returned %d for non S_ISBLK\n", | ||
278 | __func__, ret); | ||
279 | return ret; | ||
280 | } | ||
289 | } | 281 | } |
290 | } | 282 | } |
291 | |||
292 | return 1; | ||
293 | } | ||
294 | |||
295 | static int fd_do_writev(struct se_cmd *cmd, struct scatterlist *sgl, | ||
296 | u32 sgl_nents) | ||
297 | { | ||
298 | struct se_device *se_dev = cmd->se_dev; | ||
299 | struct fd_dev *dev = se_dev->dev_ptr; | ||
300 | struct file *fd = dev->fd_file; | ||
301 | struct scatterlist *sg; | ||
302 | struct iovec *iov; | ||
303 | mm_segment_t old_fs; | ||
304 | loff_t pos = (cmd->t_task_lba * | ||
305 | se_dev->se_sub_dev->se_dev_attrib.block_size); | ||
306 | int ret, i = 0; | ||
307 | |||
308 | iov = kzalloc(sizeof(struct iovec) * sgl_nents, GFP_KERNEL); | ||
309 | if (!iov) { | ||
310 | pr_err("Unable to allocate fd_do_writev iov[]\n"); | ||
311 | return -ENOMEM; | ||
312 | } | ||
313 | |||
314 | for_each_sg(sgl, sg, sgl_nents, i) { | ||
315 | iov[i].iov_len = sg->length; | ||
316 | iov[i].iov_base = sg_virt(sg); | ||
317 | } | ||
318 | |||
319 | old_fs = get_fs(); | ||
320 | set_fs(get_ds()); | ||
321 | ret = vfs_writev(fd, &iov[0], sgl_nents, &pos); | ||
322 | set_fs(old_fs); | ||
323 | |||
324 | kfree(iov); | ||
325 | |||
326 | if (ret < 0 || ret != cmd->data_length) { | ||
327 | pr_err("vfs_writev() returned %d\n", ret); | ||
328 | return (ret < 0 ? ret : -EINVAL); | ||
329 | } | ||
330 | |||
331 | return 1; | 283 | return 1; |
332 | } | 284 | } |
333 | 285 | ||
334 | static int fd_execute_sync_cache(struct se_cmd *cmd) | 286 | static sense_reason_t |
287 | fd_execute_sync_cache(struct se_cmd *cmd) | ||
335 | { | 288 | { |
336 | struct se_device *dev = cmd->se_dev; | 289 | struct se_device *dev = cmd->se_dev; |
337 | struct fd_dev *fd_dev = dev->dev_ptr; | 290 | struct fd_dev *fd_dev = FD_DEV(dev); |
338 | int immed = (cmd->t_task_cdb[1] & 0x2); | 291 | int immed = (cmd->t_task_cdb[1] & 0x2); |
339 | loff_t start, end; | 292 | loff_t start, end; |
340 | int ret; | 293 | int ret; |
@@ -353,7 +306,7 @@ static int fd_execute_sync_cache(struct se_cmd *cmd) | |||
353 | start = 0; | 306 | start = 0; |
354 | end = LLONG_MAX; | 307 | end = LLONG_MAX; |
355 | } else { | 308 | } else { |
356 | start = cmd->t_task_lba * dev->se_sub_dev->se_dev_attrib.block_size; | 309 | start = cmd->t_task_lba * dev->dev_attrib.block_size; |
357 | if (cmd->data_length) | 310 | if (cmd->data_length) |
358 | end = start + cmd->data_length; | 311 | end = start + cmd->data_length; |
359 | else | 312 | else |
@@ -367,17 +320,16 @@ static int fd_execute_sync_cache(struct se_cmd *cmd) | |||
367 | if (immed) | 320 | if (immed) |
368 | return 0; | 321 | return 0; |
369 | 322 | ||
370 | if (ret) { | 323 | if (ret) |
371 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
372 | target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION); | 324 | target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION); |
373 | } else { | 325 | else |
374 | target_complete_cmd(cmd, SAM_STAT_GOOD); | 326 | target_complete_cmd(cmd, SAM_STAT_GOOD); |
375 | } | ||
376 | 327 | ||
377 | return 0; | 328 | return 0; |
378 | } | 329 | } |
379 | 330 | ||
380 | static int fd_execute_rw(struct se_cmd *cmd) | 331 | static sense_reason_t |
332 | fd_execute_rw(struct se_cmd *cmd) | ||
381 | { | 333 | { |
382 | struct scatterlist *sgl = cmd->t_data_sg; | 334 | struct scatterlist *sgl = cmd->t_data_sg; |
383 | u32 sgl_nents = cmd->t_data_nents; | 335 | u32 sgl_nents = cmd->t_data_nents; |
@@ -390,30 +342,29 @@ static int fd_execute_rw(struct se_cmd *cmd) | |||
390 | * physical memory addresses to struct iovec virtual memory. | 342 | * physical memory addresses to struct iovec virtual memory. |
391 | */ | 343 | */ |
392 | if (data_direction == DMA_FROM_DEVICE) { | 344 | if (data_direction == DMA_FROM_DEVICE) { |
393 | ret = fd_do_readv(cmd, sgl, sgl_nents); | 345 | ret = fd_do_rw(cmd, sgl, sgl_nents, 0); |
394 | } else { | 346 | } else { |
395 | ret = fd_do_writev(cmd, sgl, sgl_nents); | 347 | ret = fd_do_rw(cmd, sgl, sgl_nents, 1); |
396 | /* | 348 | /* |
397 | * Perform implict vfs_fsync_range() for fd_do_writev() ops | 349 | * Perform implict vfs_fsync_range() for fd_do_writev() ops |
398 | * for SCSI WRITEs with Forced Unit Access (FUA) set. | 350 | * for SCSI WRITEs with Forced Unit Access (FUA) set. |
399 | * Allow this to happen independent of WCE=0 setting. | 351 | * Allow this to happen independent of WCE=0 setting. |
400 | */ | 352 | */ |
401 | if (ret > 0 && | 353 | if (ret > 0 && |
402 | dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 && | 354 | dev->dev_attrib.emulate_fua_write > 0 && |
403 | (cmd->se_cmd_flags & SCF_FUA)) { | 355 | (cmd->se_cmd_flags & SCF_FUA)) { |
404 | struct fd_dev *fd_dev = dev->dev_ptr; | 356 | struct fd_dev *fd_dev = FD_DEV(dev); |
405 | loff_t start = cmd->t_task_lba * | 357 | loff_t start = cmd->t_task_lba * |
406 | dev->se_sub_dev->se_dev_attrib.block_size; | 358 | dev->dev_attrib.block_size; |
407 | loff_t end = start + cmd->data_length; | 359 | loff_t end = start + cmd->data_length; |
408 | 360 | ||
409 | vfs_fsync_range(fd_dev->fd_file, start, end, 1); | 361 | vfs_fsync_range(fd_dev->fd_file, start, end, 1); |
410 | } | 362 | } |
411 | } | 363 | } |
412 | 364 | ||
413 | if (ret < 0) { | 365 | if (ret < 0) |
414 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 366 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
415 | return ret; | 367 | |
416 | } | ||
417 | if (ret) | 368 | if (ret) |
418 | target_complete_cmd(cmd, SAM_STAT_GOOD); | 369 | target_complete_cmd(cmd, SAM_STAT_GOOD); |
419 | return 0; | 370 | return 0; |
@@ -430,12 +381,10 @@ static match_table_t tokens = { | |||
430 | {Opt_err, NULL} | 381 | {Opt_err, NULL} |
431 | }; | 382 | }; |
432 | 383 | ||
433 | static ssize_t fd_set_configfs_dev_params( | 384 | static ssize_t fd_set_configfs_dev_params(struct se_device *dev, |
434 | struct se_hba *hba, | 385 | const char *page, ssize_t count) |
435 | struct se_subsystem_dev *se_dev, | ||
436 | const char *page, ssize_t count) | ||
437 | { | 386 | { |
438 | struct fd_dev *fd_dev = se_dev->se_dev_su_ptr; | 387 | struct fd_dev *fd_dev = FD_DEV(dev); |
439 | char *orig, *ptr, *arg_p, *opts; | 388 | char *orig, *ptr, *arg_p, *opts; |
440 | substring_t args[MAX_OPT_ARGS]; | 389 | substring_t args[MAX_OPT_ARGS]; |
441 | int ret = 0, arg, token; | 390 | int ret = 0, arg, token; |
@@ -502,24 +451,9 @@ out: | |||
502 | return (!ret) ? count : ret; | 451 | return (!ret) ? count : ret; |
503 | } | 452 | } |
504 | 453 | ||
505 | static ssize_t fd_check_configfs_dev_params(struct se_hba *hba, struct se_subsystem_dev *se_dev) | 454 | static ssize_t fd_show_configfs_dev_params(struct se_device *dev, char *b) |
506 | { | 455 | { |
507 | struct fd_dev *fd_dev = se_dev->se_dev_su_ptr; | 456 | struct fd_dev *fd_dev = FD_DEV(dev); |
508 | |||
509 | if (!(fd_dev->fbd_flags & FBDF_HAS_PATH)) { | ||
510 | pr_err("Missing fd_dev_name=\n"); | ||
511 | return -EINVAL; | ||
512 | } | ||
513 | |||
514 | return 0; | ||
515 | } | ||
516 | |||
517 | static ssize_t fd_show_configfs_dev_params( | ||
518 | struct se_hba *hba, | ||
519 | struct se_subsystem_dev *se_dev, | ||
520 | char *b) | ||
521 | { | ||
522 | struct fd_dev *fd_dev = se_dev->se_dev_su_ptr; | ||
523 | ssize_t bl = 0; | 457 | ssize_t bl = 0; |
524 | 458 | ||
525 | bl = sprintf(b + bl, "TCM FILEIO ID: %u", fd_dev->fd_dev_id); | 459 | bl = sprintf(b + bl, "TCM FILEIO ID: %u", fd_dev->fd_dev_id); |
@@ -530,27 +464,9 @@ static ssize_t fd_show_configfs_dev_params( | |||
530 | return bl; | 464 | return bl; |
531 | } | 465 | } |
532 | 466 | ||
533 | /* fd_get_device_rev(): (Part of se_subsystem_api_t template) | ||
534 | * | ||
535 | * | ||
536 | */ | ||
537 | static u32 fd_get_device_rev(struct se_device *dev) | ||
538 | { | ||
539 | return SCSI_SPC_2; /* Returns SPC-3 in Initiator Data */ | ||
540 | } | ||
541 | |||
542 | /* fd_get_device_type(): (Part of se_subsystem_api_t template) | ||
543 | * | ||
544 | * | ||
545 | */ | ||
546 | static u32 fd_get_device_type(struct se_device *dev) | ||
547 | { | ||
548 | return TYPE_DISK; | ||
549 | } | ||
550 | |||
551 | static sector_t fd_get_blocks(struct se_device *dev) | 467 | static sector_t fd_get_blocks(struct se_device *dev) |
552 | { | 468 | { |
553 | struct fd_dev *fd_dev = dev->dev_ptr; | 469 | struct fd_dev *fd_dev = FD_DEV(dev); |
554 | struct file *f = fd_dev->fd_file; | 470 | struct file *f = fd_dev->fd_file; |
555 | struct inode *i = f->f_mapping->host; | 471 | struct inode *i = f->f_mapping->host; |
556 | unsigned long long dev_size; | 472 | unsigned long long dev_size; |
@@ -564,34 +480,35 @@ static sector_t fd_get_blocks(struct se_device *dev) | |||
564 | else | 480 | else |
565 | dev_size = fd_dev->fd_dev_size; | 481 | dev_size = fd_dev->fd_dev_size; |
566 | 482 | ||
567 | return div_u64(dev_size, dev->se_sub_dev->se_dev_attrib.block_size); | 483 | return div_u64(dev_size, dev->dev_attrib.block_size); |
568 | } | 484 | } |
569 | 485 | ||
570 | static struct spc_ops fd_spc_ops = { | 486 | static struct sbc_ops fd_sbc_ops = { |
571 | .execute_rw = fd_execute_rw, | 487 | .execute_rw = fd_execute_rw, |
572 | .execute_sync_cache = fd_execute_sync_cache, | 488 | .execute_sync_cache = fd_execute_sync_cache, |
573 | }; | 489 | }; |
574 | 490 | ||
575 | static int fd_parse_cdb(struct se_cmd *cmd) | 491 | static sense_reason_t |
492 | fd_parse_cdb(struct se_cmd *cmd) | ||
576 | { | 493 | { |
577 | return sbc_parse_cdb(cmd, &fd_spc_ops); | 494 | return sbc_parse_cdb(cmd, &fd_sbc_ops); |
578 | } | 495 | } |
579 | 496 | ||
580 | static struct se_subsystem_api fileio_template = { | 497 | static struct se_subsystem_api fileio_template = { |
581 | .name = "fileio", | 498 | .name = "fileio", |
499 | .inquiry_prod = "FILEIO", | ||
500 | .inquiry_rev = FD_VERSION, | ||
582 | .owner = THIS_MODULE, | 501 | .owner = THIS_MODULE, |
583 | .transport_type = TRANSPORT_PLUGIN_VHBA_PDEV, | 502 | .transport_type = TRANSPORT_PLUGIN_VHBA_PDEV, |
584 | .attach_hba = fd_attach_hba, | 503 | .attach_hba = fd_attach_hba, |
585 | .detach_hba = fd_detach_hba, | 504 | .detach_hba = fd_detach_hba, |
586 | .allocate_virtdevice = fd_allocate_virtdevice, | 505 | .alloc_device = fd_alloc_device, |
587 | .create_virtdevice = fd_create_virtdevice, | 506 | .configure_device = fd_configure_device, |
588 | .free_device = fd_free_device, | 507 | .free_device = fd_free_device, |
589 | .parse_cdb = fd_parse_cdb, | 508 | .parse_cdb = fd_parse_cdb, |
590 | .check_configfs_dev_params = fd_check_configfs_dev_params, | ||
591 | .set_configfs_dev_params = fd_set_configfs_dev_params, | 509 | .set_configfs_dev_params = fd_set_configfs_dev_params, |
592 | .show_configfs_dev_params = fd_show_configfs_dev_params, | 510 | .show_configfs_dev_params = fd_show_configfs_dev_params, |
593 | .get_device_rev = fd_get_device_rev, | 511 | .get_device_type = sbc_get_device_type, |
594 | .get_device_type = fd_get_device_type, | ||
595 | .get_blocks = fd_get_blocks, | 512 | .get_blocks = fd_get_blocks, |
596 | }; | 513 | }; |
597 | 514 | ||
diff --git a/drivers/target/target_core_file.h b/drivers/target/target_core_file.h index 876ae53ef5b8..bc02b018ae46 100644 --- a/drivers/target/target_core_file.h +++ b/drivers/target/target_core_file.h | |||
@@ -17,6 +17,8 @@ | |||
17 | #define FDBD_HAS_BUFFERED_IO_WCE 0x04 | 17 | #define FDBD_HAS_BUFFERED_IO_WCE 0x04 |
18 | 18 | ||
19 | struct fd_dev { | 19 | struct fd_dev { |
20 | struct se_device dev; | ||
21 | |||
20 | u32 fbd_flags; | 22 | u32 fbd_flags; |
21 | unsigned char fd_dev_name[FD_MAX_DEV_NAME]; | 23 | unsigned char fd_dev_name[FD_MAX_DEV_NAME]; |
22 | /* Unique Ramdisk Device ID in Ramdisk HBA */ | 24 | /* Unique Ramdisk Device ID in Ramdisk HBA */ |
diff --git a/drivers/target/target_core_hba.c b/drivers/target/target_core_hba.c index 3dd1bd4b6f71..d2616cd48f1e 100644 --- a/drivers/target/target_core_hba.c +++ b/drivers/target/target_core_hba.c | |||
@@ -3,10 +3,7 @@ | |||
3 | * | 3 | * |
4 | * This file contains the TCM HBA Transport related functions. | 4 | * This file contains the TCM HBA Transport related functions. |
5 | * | 5 | * |
6 | * Copyright (c) 2003, 2004, 2005 PyX Technologies, Inc. | 6 | * (c) Copyright 2003-2012 RisingTide Systems LLC. |
7 | * Copyright (c) 2005, 2006, 2007 SBE, Inc. | ||
8 | * Copyright (c) 2007-2010 Rising Tide Systems | ||
9 | * Copyright (c) 2008-2010 Linux-iSCSI.org | ||
10 | * | 7 | * |
11 | * Nicholas A. Bellinger <nab@kernel.org> | 8 | * Nicholas A. Bellinger <nab@kernel.org> |
12 | * | 9 | * |
@@ -113,7 +110,6 @@ core_alloc_hba(const char *plugin_name, u32 plugin_dep_id, u32 hba_flags) | |||
113 | return ERR_PTR(-ENOMEM); | 110 | return ERR_PTR(-ENOMEM); |
114 | } | 111 | } |
115 | 112 | ||
116 | INIT_LIST_HEAD(&hba->hba_dev_list); | ||
117 | spin_lock_init(&hba->device_lock); | 113 | spin_lock_init(&hba->device_lock); |
118 | mutex_init(&hba->hba_access_mutex); | 114 | mutex_init(&hba->hba_access_mutex); |
119 | 115 | ||
@@ -152,8 +148,7 @@ out_free_hba: | |||
152 | int | 148 | int |
153 | core_delete_hba(struct se_hba *hba) | 149 | core_delete_hba(struct se_hba *hba) |
154 | { | 150 | { |
155 | if (!list_empty(&hba->hba_dev_list)) | 151 | WARN_ON(hba->dev_count); |
156 | dump_stack(); | ||
157 | 152 | ||
158 | hba->transport->detach_hba(hba); | 153 | hba->transport->detach_hba(hba); |
159 | 154 | ||
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 57d7674c5013..b526d23dcd4f 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c | |||
@@ -4,10 +4,7 @@ | |||
4 | * This file contains the Storage Engine <-> Linux BlockIO transport | 4 | * This file contains the Storage Engine <-> Linux BlockIO transport |
5 | * specific functions. | 5 | * specific functions. |
6 | * | 6 | * |
7 | * Copyright (c) 2003, 2004, 2005 PyX Technologies, Inc. | 7 | * (c) Copyright 2003-2012 RisingTide Systems LLC. |
8 | * Copyright (c) 2005, 2006, 2007 SBE, Inc. | ||
9 | * Copyright (c) 2007-2010 Rising Tide Systems | ||
10 | * Copyright (c) 2008-2010 Linux-iSCSI.org | ||
11 | * | 8 | * |
12 | * Nicholas A. Bellinger <nab@kernel.org> | 9 | * Nicholas A. Bellinger <nab@kernel.org> |
13 | * | 10 | * |
@@ -50,9 +47,13 @@ | |||
50 | #define IBLOCK_MAX_BIO_PER_TASK 32 /* max # of bios to submit at a time */ | 47 | #define IBLOCK_MAX_BIO_PER_TASK 32 /* max # of bios to submit at a time */ |
51 | #define IBLOCK_BIO_POOL_SIZE 128 | 48 | #define IBLOCK_BIO_POOL_SIZE 128 |
52 | 49 | ||
53 | static struct se_subsystem_api iblock_template; | 50 | static inline struct iblock_dev *IBLOCK_DEV(struct se_device *dev) |
51 | { | ||
52 | return container_of(dev, struct iblock_dev, dev); | ||
53 | } | ||
54 | |||
54 | 55 | ||
55 | static void iblock_bio_done(struct bio *, int); | 56 | static struct se_subsystem_api iblock_template; |
56 | 57 | ||
57 | /* iblock_attach_hba(): (Part of se_subsystem_api_t template) | 58 | /* iblock_attach_hba(): (Part of se_subsystem_api_t template) |
58 | * | 59 | * |
@@ -70,7 +71,7 @@ static void iblock_detach_hba(struct se_hba *hba) | |||
70 | { | 71 | { |
71 | } | 72 | } |
72 | 73 | ||
73 | static void *iblock_allocate_virtdevice(struct se_hba *hba, const char *name) | 74 | static struct se_device *iblock_alloc_device(struct se_hba *hba, const char *name) |
74 | { | 75 | { |
75 | struct iblock_dev *ib_dev = NULL; | 76 | struct iblock_dev *ib_dev = NULL; |
76 | 77 | ||
@@ -82,40 +83,28 @@ static void *iblock_allocate_virtdevice(struct se_hba *hba, const char *name) | |||
82 | 83 | ||
83 | pr_debug( "IBLOCK: Allocated ib_dev for %s\n", name); | 84 | pr_debug( "IBLOCK: Allocated ib_dev for %s\n", name); |
84 | 85 | ||
85 | return ib_dev; | 86 | return &ib_dev->dev; |
86 | } | 87 | } |
87 | 88 | ||
88 | static struct se_device *iblock_create_virtdevice( | 89 | static int iblock_configure_device(struct se_device *dev) |
89 | struct se_hba *hba, | ||
90 | struct se_subsystem_dev *se_dev, | ||
91 | void *p) | ||
92 | { | 90 | { |
93 | struct iblock_dev *ib_dev = p; | 91 | struct iblock_dev *ib_dev = IBLOCK_DEV(dev); |
94 | struct se_device *dev; | ||
95 | struct se_dev_limits dev_limits; | ||
96 | struct block_device *bd = NULL; | ||
97 | struct request_queue *q; | 92 | struct request_queue *q; |
98 | struct queue_limits *limits; | 93 | struct block_device *bd = NULL; |
99 | u32 dev_flags = 0; | ||
100 | fmode_t mode; | 94 | fmode_t mode; |
101 | int ret = -EINVAL; | 95 | int ret = -ENOMEM; |
102 | 96 | ||
103 | if (!ib_dev) { | 97 | if (!(ib_dev->ibd_flags & IBDF_HAS_UDEV_PATH)) { |
104 | pr_err("Unable to locate struct iblock_dev parameter\n"); | 98 | pr_err("Missing udev_path= parameters for IBLOCK\n"); |
105 | return ERR_PTR(ret); | 99 | return -EINVAL; |
106 | } | 100 | } |
107 | memset(&dev_limits, 0, sizeof(struct se_dev_limits)); | ||
108 | 101 | ||
109 | ib_dev->ibd_bio_set = bioset_create(IBLOCK_BIO_POOL_SIZE, 0); | 102 | ib_dev->ibd_bio_set = bioset_create(IBLOCK_BIO_POOL_SIZE, 0); |
110 | if (!ib_dev->ibd_bio_set) { | 103 | if (!ib_dev->ibd_bio_set) { |
111 | pr_err("IBLOCK: Unable to create bioset()\n"); | 104 | pr_err("IBLOCK: Unable to create bioset\n"); |
112 | return ERR_PTR(-ENOMEM); | 105 | goto out; |
113 | } | 106 | } |
114 | pr_debug("IBLOCK: Created bio_set()\n"); | 107 | |
115 | /* | ||
116 | * iblock_check_configfs_dev_params() ensures that ib_dev->ibd_udev_path | ||
117 | * must already have been set in order for echo 1 > $HBA/$DEV/enable to run. | ||
118 | */ | ||
119 | pr_debug( "IBLOCK: Claiming struct block_device: %s\n", | 108 | pr_debug( "IBLOCK: Claiming struct block_device: %s\n", |
120 | ib_dev->ibd_udev_path); | 109 | ib_dev->ibd_udev_path); |
121 | 110 | ||
@@ -126,27 +115,15 @@ static struct se_device *iblock_create_virtdevice( | |||
126 | bd = blkdev_get_by_path(ib_dev->ibd_udev_path, mode, ib_dev); | 115 | bd = blkdev_get_by_path(ib_dev->ibd_udev_path, mode, ib_dev); |
127 | if (IS_ERR(bd)) { | 116 | if (IS_ERR(bd)) { |
128 | ret = PTR_ERR(bd); | 117 | ret = PTR_ERR(bd); |
129 | goto failed; | 118 | goto out_free_bioset; |
130 | } | 119 | } |
131 | /* | ||
132 | * Setup the local scope queue_limits from struct request_queue->limits | ||
133 | * to pass into transport_add_device_to_core_hba() as struct se_dev_limits. | ||
134 | */ | ||
135 | q = bdev_get_queue(bd); | ||
136 | limits = &dev_limits.limits; | ||
137 | limits->logical_block_size = bdev_logical_block_size(bd); | ||
138 | limits->max_hw_sectors = UINT_MAX; | ||
139 | limits->max_sectors = UINT_MAX; | ||
140 | dev_limits.hw_queue_depth = q->nr_requests; | ||
141 | dev_limits.queue_depth = q->nr_requests; | ||
142 | |||
143 | ib_dev->ibd_bd = bd; | 120 | ib_dev->ibd_bd = bd; |
144 | 121 | ||
145 | dev = transport_add_device_to_core_hba(hba, | 122 | q = bdev_get_queue(bd); |
146 | &iblock_template, se_dev, dev_flags, ib_dev, | 123 | |
147 | &dev_limits, "IBLOCK", IBLOCK_VERSION); | 124 | dev->dev_attrib.hw_block_size = bdev_logical_block_size(bd); |
148 | if (!dev) | 125 | dev->dev_attrib.hw_max_sectors = UINT_MAX; |
149 | goto failed; | 126 | dev->dev_attrib.hw_queue_depth = q->nr_requests; |
150 | 127 | ||
151 | /* | 128 | /* |
152 | * Check if the underlying struct block_device request_queue supports | 129 | * Check if the underlying struct block_device request_queue supports |
@@ -154,38 +131,41 @@ static struct se_device *iblock_create_virtdevice( | |||
154 | * in ATA and we need to set TPE=1 | 131 | * in ATA and we need to set TPE=1 |
155 | */ | 132 | */ |
156 | if (blk_queue_discard(q)) { | 133 | if (blk_queue_discard(q)) { |
157 | dev->se_sub_dev->se_dev_attrib.max_unmap_lba_count = | 134 | dev->dev_attrib.max_unmap_lba_count = |
158 | q->limits.max_discard_sectors; | 135 | q->limits.max_discard_sectors; |
136 | |||
159 | /* | 137 | /* |
160 | * Currently hardcoded to 1 in Linux/SCSI code.. | 138 | * Currently hardcoded to 1 in Linux/SCSI code.. |
161 | */ | 139 | */ |
162 | dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count = 1; | 140 | dev->dev_attrib.max_unmap_block_desc_count = 1; |
163 | dev->se_sub_dev->se_dev_attrib.unmap_granularity = | 141 | dev->dev_attrib.unmap_granularity = |
164 | q->limits.discard_granularity >> 9; | 142 | q->limits.discard_granularity >> 9; |
165 | dev->se_sub_dev->se_dev_attrib.unmap_granularity_alignment = | 143 | dev->dev_attrib.unmap_granularity_alignment = |
166 | q->limits.discard_alignment; | 144 | q->limits.discard_alignment; |
167 | 145 | ||
168 | pr_debug("IBLOCK: BLOCK Discard support available," | 146 | pr_debug("IBLOCK: BLOCK Discard support available," |
169 | " disabled by default\n"); | 147 | " disabled by default\n"); |
170 | } | 148 | } |
149 | /* | ||
150 | * Enable write same emulation for IBLOCK and use 0xFFFF as | ||
151 | * the smaller WRITE_SAME(10) only has a two-byte block count. | ||
152 | */ | ||
153 | dev->dev_attrib.max_write_same_len = 0xFFFF; | ||
171 | 154 | ||
172 | if (blk_queue_nonrot(q)) | 155 | if (blk_queue_nonrot(q)) |
173 | dev->se_sub_dev->se_dev_attrib.is_nonrot = 1; | 156 | dev->dev_attrib.is_nonrot = 1; |
174 | 157 | return 0; | |
175 | return dev; | ||
176 | 158 | ||
177 | failed: | 159 | out_free_bioset: |
178 | if (ib_dev->ibd_bio_set) { | 160 | bioset_free(ib_dev->ibd_bio_set); |
179 | bioset_free(ib_dev->ibd_bio_set); | 161 | ib_dev->ibd_bio_set = NULL; |
180 | ib_dev->ibd_bio_set = NULL; | 162 | out: |
181 | } | 163 | return ret; |
182 | ib_dev->ibd_bd = NULL; | ||
183 | return ERR_PTR(ret); | ||
184 | } | 164 | } |
185 | 165 | ||
186 | static void iblock_free_device(void *p) | 166 | static void iblock_free_device(struct se_device *dev) |
187 | { | 167 | { |
188 | struct iblock_dev *ib_dev = p; | 168 | struct iblock_dev *ib_dev = IBLOCK_DEV(dev); |
189 | 169 | ||
190 | if (ib_dev->ibd_bd != NULL) | 170 | if (ib_dev->ibd_bd != NULL) |
191 | blkdev_put(ib_dev->ibd_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL); | 171 | blkdev_put(ib_dev->ibd_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL); |
@@ -203,12 +183,12 @@ static unsigned long long iblock_emulate_read_cap_with_block_size( | |||
203 | bdev_logical_block_size(bd)) - 1); | 183 | bdev_logical_block_size(bd)) - 1); |
204 | u32 block_size = bdev_logical_block_size(bd); | 184 | u32 block_size = bdev_logical_block_size(bd); |
205 | 185 | ||
206 | if (block_size == dev->se_sub_dev->se_dev_attrib.block_size) | 186 | if (block_size == dev->dev_attrib.block_size) |
207 | return blocks_long; | 187 | return blocks_long; |
208 | 188 | ||
209 | switch (block_size) { | 189 | switch (block_size) { |
210 | case 4096: | 190 | case 4096: |
211 | switch (dev->se_sub_dev->se_dev_attrib.block_size) { | 191 | switch (dev->dev_attrib.block_size) { |
212 | case 2048: | 192 | case 2048: |
213 | blocks_long <<= 1; | 193 | blocks_long <<= 1; |
214 | break; | 194 | break; |
@@ -222,7 +202,7 @@ static unsigned long long iblock_emulate_read_cap_with_block_size( | |||
222 | } | 202 | } |
223 | break; | 203 | break; |
224 | case 2048: | 204 | case 2048: |
225 | switch (dev->se_sub_dev->se_dev_attrib.block_size) { | 205 | switch (dev->dev_attrib.block_size) { |
226 | case 4096: | 206 | case 4096: |
227 | blocks_long >>= 1; | 207 | blocks_long >>= 1; |
228 | break; | 208 | break; |
@@ -237,7 +217,7 @@ static unsigned long long iblock_emulate_read_cap_with_block_size( | |||
237 | } | 217 | } |
238 | break; | 218 | break; |
239 | case 1024: | 219 | case 1024: |
240 | switch (dev->se_sub_dev->se_dev_attrib.block_size) { | 220 | switch (dev->dev_attrib.block_size) { |
241 | case 4096: | 221 | case 4096: |
242 | blocks_long >>= 2; | 222 | blocks_long >>= 2; |
243 | break; | 223 | break; |
@@ -252,7 +232,7 @@ static unsigned long long iblock_emulate_read_cap_with_block_size( | |||
252 | } | 232 | } |
253 | break; | 233 | break; |
254 | case 512: | 234 | case 512: |
255 | switch (dev->se_sub_dev->se_dev_attrib.block_size) { | 235 | switch (dev->dev_attrib.block_size) { |
256 | case 4096: | 236 | case 4096: |
257 | blocks_long >>= 3; | 237 | blocks_long >>= 3; |
258 | break; | 238 | break; |
@@ -273,6 +253,87 @@ static unsigned long long iblock_emulate_read_cap_with_block_size( | |||
273 | return blocks_long; | 253 | return blocks_long; |
274 | } | 254 | } |
275 | 255 | ||
256 | static void iblock_complete_cmd(struct se_cmd *cmd) | ||
257 | { | ||
258 | struct iblock_req *ibr = cmd->priv; | ||
259 | u8 status; | ||
260 | |||
261 | if (!atomic_dec_and_test(&ibr->pending)) | ||
262 | return; | ||
263 | |||
264 | if (atomic_read(&ibr->ib_bio_err_cnt)) | ||
265 | status = SAM_STAT_CHECK_CONDITION; | ||
266 | else | ||
267 | status = SAM_STAT_GOOD; | ||
268 | |||
269 | target_complete_cmd(cmd, status); | ||
270 | kfree(ibr); | ||
271 | } | ||
272 | |||
273 | static void iblock_bio_done(struct bio *bio, int err) | ||
274 | { | ||
275 | struct se_cmd *cmd = bio->bi_private; | ||
276 | struct iblock_req *ibr = cmd->priv; | ||
277 | |||
278 | /* | ||
279 | * Set -EIO if !BIO_UPTODATE and the passed is still err=0 | ||
280 | */ | ||
281 | if (!test_bit(BIO_UPTODATE, &bio->bi_flags) && !err) | ||
282 | err = -EIO; | ||
283 | |||
284 | if (err != 0) { | ||
285 | pr_err("test_bit(BIO_UPTODATE) failed for bio: %p," | ||
286 | " err: %d\n", bio, err); | ||
287 | /* | ||
288 | * Bump the ib_bio_err_cnt and release bio. | ||
289 | */ | ||
290 | atomic_inc(&ibr->ib_bio_err_cnt); | ||
291 | smp_mb__after_atomic_inc(); | ||
292 | } | ||
293 | |||
294 | bio_put(bio); | ||
295 | |||
296 | iblock_complete_cmd(cmd); | ||
297 | } | ||
298 | |||
299 | static struct bio * | ||
300 | iblock_get_bio(struct se_cmd *cmd, sector_t lba, u32 sg_num) | ||
301 | { | ||
302 | struct iblock_dev *ib_dev = IBLOCK_DEV(cmd->se_dev); | ||
303 | struct bio *bio; | ||
304 | |||
305 | /* | ||
306 | * Only allocate as many vector entries as the bio code allows us to, | ||
307 | * we'll loop later on until we have handled the whole request. | ||
308 | */ | ||
309 | if (sg_num > BIO_MAX_PAGES) | ||
310 | sg_num = BIO_MAX_PAGES; | ||
311 | |||
312 | bio = bio_alloc_bioset(GFP_NOIO, sg_num, ib_dev->ibd_bio_set); | ||
313 | if (!bio) { | ||
314 | pr_err("Unable to allocate memory for bio\n"); | ||
315 | return NULL; | ||
316 | } | ||
317 | |||
318 | bio->bi_bdev = ib_dev->ibd_bd; | ||
319 | bio->bi_private = cmd; | ||
320 | bio->bi_end_io = &iblock_bio_done; | ||
321 | bio->bi_sector = lba; | ||
322 | |||
323 | return bio; | ||
324 | } | ||
325 | |||
326 | static void iblock_submit_bios(struct bio_list *list, int rw) | ||
327 | { | ||
328 | struct blk_plug plug; | ||
329 | struct bio *bio; | ||
330 | |||
331 | blk_start_plug(&plug); | ||
332 | while ((bio = bio_list_pop(list))) | ||
333 | submit_bio(rw, bio); | ||
334 | blk_finish_plug(&plug); | ||
335 | } | ||
336 | |||
276 | static void iblock_end_io_flush(struct bio *bio, int err) | 337 | static void iblock_end_io_flush(struct bio *bio, int err) |
277 | { | 338 | { |
278 | struct se_cmd *cmd = bio->bi_private; | 339 | struct se_cmd *cmd = bio->bi_private; |
@@ -281,13 +342,10 @@ static void iblock_end_io_flush(struct bio *bio, int err) | |||
281 | pr_err("IBLOCK: cache flush failed: %d\n", err); | 342 | pr_err("IBLOCK: cache flush failed: %d\n", err); |
282 | 343 | ||
283 | if (cmd) { | 344 | if (cmd) { |
284 | if (err) { | 345 | if (err) |
285 | cmd->scsi_sense_reason = | ||
286 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
287 | target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION); | 346 | target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION); |
288 | } else { | 347 | else |
289 | target_complete_cmd(cmd, SAM_STAT_GOOD); | 348 | target_complete_cmd(cmd, SAM_STAT_GOOD); |
290 | } | ||
291 | } | 349 | } |
292 | 350 | ||
293 | bio_put(bio); | 351 | bio_put(bio); |
@@ -297,9 +355,10 @@ static void iblock_end_io_flush(struct bio *bio, int err) | |||
297 | * Implement SYCHRONIZE CACHE. Note that we can't handle lba ranges and must | 355 | * Implement SYCHRONIZE CACHE. Note that we can't handle lba ranges and must |
298 | * always flush the whole cache. | 356 | * always flush the whole cache. |
299 | */ | 357 | */ |
300 | static int iblock_execute_sync_cache(struct se_cmd *cmd) | 358 | static sense_reason_t |
359 | iblock_execute_sync_cache(struct se_cmd *cmd) | ||
301 | { | 360 | { |
302 | struct iblock_dev *ib_dev = cmd->se_dev->dev_ptr; | 361 | struct iblock_dev *ib_dev = IBLOCK_DEV(cmd->se_dev); |
303 | int immed = (cmd->t_task_cdb[1] & 0x2); | 362 | int immed = (cmd->t_task_cdb[1] & 0x2); |
304 | struct bio *bio; | 363 | struct bio *bio; |
305 | 364 | ||
@@ -319,25 +378,27 @@ static int iblock_execute_sync_cache(struct se_cmd *cmd) | |||
319 | return 0; | 378 | return 0; |
320 | } | 379 | } |
321 | 380 | ||
322 | static int iblock_execute_unmap(struct se_cmd *cmd) | 381 | static sense_reason_t |
382 | iblock_execute_unmap(struct se_cmd *cmd) | ||
323 | { | 383 | { |
324 | struct se_device *dev = cmd->se_dev; | 384 | struct se_device *dev = cmd->se_dev; |
325 | struct iblock_dev *ibd = dev->dev_ptr; | 385 | struct iblock_dev *ib_dev = IBLOCK_DEV(dev); |
326 | unsigned char *buf, *ptr = NULL; | 386 | unsigned char *buf, *ptr = NULL; |
327 | sector_t lba; | 387 | sector_t lba; |
328 | int size; | 388 | int size; |
329 | u32 range; | 389 | u32 range; |
330 | int ret = 0; | 390 | sense_reason_t ret = 0; |
331 | int dl, bd_dl; | 391 | int dl, bd_dl, err; |
332 | 392 | ||
333 | if (cmd->data_length < 8) { | 393 | if (cmd->data_length < 8) { |
334 | pr_warn("UNMAP parameter list length %u too small\n", | 394 | pr_warn("UNMAP parameter list length %u too small\n", |
335 | cmd->data_length); | 395 | cmd->data_length); |
336 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 396 | return TCM_INVALID_PARAMETER_LIST; |
337 | return -EINVAL; | ||
338 | } | 397 | } |
339 | 398 | ||
340 | buf = transport_kmap_data_sg(cmd); | 399 | buf = transport_kmap_data_sg(cmd); |
400 | if (!buf) | ||
401 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
341 | 402 | ||
342 | dl = get_unaligned_be16(&buf[0]); | 403 | dl = get_unaligned_be16(&buf[0]); |
343 | bd_dl = get_unaligned_be16(&buf[2]); | 404 | bd_dl = get_unaligned_be16(&buf[2]); |
@@ -349,9 +410,8 @@ static int iblock_execute_unmap(struct se_cmd *cmd) | |||
349 | else | 410 | else |
350 | size = bd_dl; | 411 | size = bd_dl; |
351 | 412 | ||
352 | if (size / 16 > dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { | 413 | if (size / 16 > dev->dev_attrib.max_unmap_block_desc_count) { |
353 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 414 | ret = TCM_INVALID_PARAMETER_LIST; |
354 | ret = -EINVAL; | ||
355 | goto err; | 415 | goto err; |
356 | } | 416 | } |
357 | 417 | ||
@@ -366,23 +426,22 @@ static int iblock_execute_unmap(struct se_cmd *cmd) | |||
366 | pr_debug("UNMAP: Using lba: %llu and range: %u\n", | 426 | pr_debug("UNMAP: Using lba: %llu and range: %u\n", |
367 | (unsigned long long)lba, range); | 427 | (unsigned long long)lba, range); |
368 | 428 | ||
369 | if (range > dev->se_sub_dev->se_dev_attrib.max_unmap_lba_count) { | 429 | if (range > dev->dev_attrib.max_unmap_lba_count) { |
370 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 430 | ret = TCM_INVALID_PARAMETER_LIST; |
371 | ret = -EINVAL; | ||
372 | goto err; | 431 | goto err; |
373 | } | 432 | } |
374 | 433 | ||
375 | if (lba + range > dev->transport->get_blocks(dev) + 1) { | 434 | if (lba + range > dev->transport->get_blocks(dev) + 1) { |
376 | cmd->scsi_sense_reason = TCM_ADDRESS_OUT_OF_RANGE; | 435 | ret = TCM_ADDRESS_OUT_OF_RANGE; |
377 | ret = -EINVAL; | ||
378 | goto err; | 436 | goto err; |
379 | } | 437 | } |
380 | 438 | ||
381 | ret = blkdev_issue_discard(ibd->ibd_bd, lba, range, | 439 | err = blkdev_issue_discard(ib_dev->ibd_bd, lba, range, |
382 | GFP_KERNEL, 0); | 440 | GFP_KERNEL, 0); |
383 | if (ret < 0) { | 441 | if (err < 0) { |
384 | pr_err("blkdev_issue_discard() failed: %d\n", | 442 | pr_err("blkdev_issue_discard() failed: %d\n", |
385 | ret); | 443 | err); |
444 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
386 | goto err; | 445 | goto err; |
387 | } | 446 | } |
388 | 447 | ||
@@ -397,23 +456,86 @@ err: | |||
397 | return ret; | 456 | return ret; |
398 | } | 457 | } |
399 | 458 | ||
400 | static int iblock_execute_write_same(struct se_cmd *cmd) | 459 | static sense_reason_t |
460 | iblock_execute_write_same_unmap(struct se_cmd *cmd) | ||
401 | { | 461 | { |
402 | struct iblock_dev *ibd = cmd->se_dev->dev_ptr; | 462 | struct iblock_dev *ib_dev = IBLOCK_DEV(cmd->se_dev); |
403 | int ret; | 463 | int rc; |
404 | 464 | ||
405 | ret = blkdev_issue_discard(ibd->ibd_bd, cmd->t_task_lba, | 465 | rc = blkdev_issue_discard(ib_dev->ibd_bd, cmd->t_task_lba, |
406 | spc_get_write_same_sectors(cmd), GFP_KERNEL, | 466 | spc_get_write_same_sectors(cmd), GFP_KERNEL, 0); |
407 | 0); | 467 | if (rc < 0) { |
408 | if (ret < 0) { | 468 | pr_warn("blkdev_issue_discard() failed: %d\n", rc); |
409 | pr_debug("blkdev_issue_discard() failed for WRITE_SAME\n"); | 469 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
410 | return ret; | ||
411 | } | 470 | } |
412 | 471 | ||
413 | target_complete_cmd(cmd, GOOD); | 472 | target_complete_cmd(cmd, GOOD); |
414 | return 0; | 473 | return 0; |
415 | } | 474 | } |
416 | 475 | ||
476 | static sense_reason_t | ||
477 | iblock_execute_write_same(struct se_cmd *cmd) | ||
478 | { | ||
479 | struct iblock_req *ibr; | ||
480 | struct scatterlist *sg; | ||
481 | struct bio *bio; | ||
482 | struct bio_list list; | ||
483 | sector_t block_lba = cmd->t_task_lba; | ||
484 | sector_t sectors = spc_get_write_same_sectors(cmd); | ||
485 | |||
486 | sg = &cmd->t_data_sg[0]; | ||
487 | |||
488 | if (cmd->t_data_nents > 1 || | ||
489 | sg->length != cmd->se_dev->dev_attrib.block_size) { | ||
490 | pr_err("WRITE_SAME: Illegal SGL t_data_nents: %u length: %u" | ||
491 | " block_size: %u\n", cmd->t_data_nents, sg->length, | ||
492 | cmd->se_dev->dev_attrib.block_size); | ||
493 | return TCM_INVALID_CDB_FIELD; | ||
494 | } | ||
495 | |||
496 | ibr = kzalloc(sizeof(struct iblock_req), GFP_KERNEL); | ||
497 | if (!ibr) | ||
498 | goto fail; | ||
499 | cmd->priv = ibr; | ||
500 | |||
501 | bio = iblock_get_bio(cmd, block_lba, 1); | ||
502 | if (!bio) | ||
503 | goto fail_free_ibr; | ||
504 | |||
505 | bio_list_init(&list); | ||
506 | bio_list_add(&list, bio); | ||
507 | |||
508 | atomic_set(&ibr->pending, 1); | ||
509 | |||
510 | while (sectors) { | ||
511 | while (bio_add_page(bio, sg_page(sg), sg->length, sg->offset) | ||
512 | != sg->length) { | ||
513 | |||
514 | bio = iblock_get_bio(cmd, block_lba, 1); | ||
515 | if (!bio) | ||
516 | goto fail_put_bios; | ||
517 | |||
518 | atomic_inc(&ibr->pending); | ||
519 | bio_list_add(&list, bio); | ||
520 | } | ||
521 | |||
522 | /* Always in 512 byte units for Linux/Block */ | ||
523 | block_lba += sg->length >> IBLOCK_LBA_SHIFT; | ||
524 | sectors -= 1; | ||
525 | } | ||
526 | |||
527 | iblock_submit_bios(&list, WRITE); | ||
528 | return 0; | ||
529 | |||
530 | fail_put_bios: | ||
531 | while ((bio = bio_list_pop(&list))) | ||
532 | bio_put(bio); | ||
533 | fail_free_ibr: | ||
534 | kfree(ibr); | ||
535 | fail: | ||
536 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
537 | } | ||
538 | |||
417 | enum { | 539 | enum { |
418 | Opt_udev_path, Opt_readonly, Opt_force, Opt_err | 540 | Opt_udev_path, Opt_readonly, Opt_force, Opt_err |
419 | }; | 541 | }; |
@@ -425,11 +547,10 @@ static match_table_t tokens = { | |||
425 | {Opt_err, NULL} | 547 | {Opt_err, NULL} |
426 | }; | 548 | }; |
427 | 549 | ||
428 | static ssize_t iblock_set_configfs_dev_params(struct se_hba *hba, | 550 | static ssize_t iblock_set_configfs_dev_params(struct se_device *dev, |
429 | struct se_subsystem_dev *se_dev, | 551 | const char *page, ssize_t count) |
430 | const char *page, ssize_t count) | ||
431 | { | 552 | { |
432 | struct iblock_dev *ib_dev = se_dev->se_dev_su_ptr; | 553 | struct iblock_dev *ib_dev = IBLOCK_DEV(dev); |
433 | char *orig, *ptr, *arg_p, *opts; | 554 | char *orig, *ptr, *arg_p, *opts; |
434 | substring_t args[MAX_OPT_ARGS]; | 555 | substring_t args[MAX_OPT_ARGS]; |
435 | int ret = 0, token; | 556 | int ret = 0, token; |
@@ -491,43 +612,26 @@ out: | |||
491 | return (!ret) ? count : ret; | 612 | return (!ret) ? count : ret; |
492 | } | 613 | } |
493 | 614 | ||
494 | static ssize_t iblock_check_configfs_dev_params( | 615 | static ssize_t iblock_show_configfs_dev_params(struct se_device *dev, char *b) |
495 | struct se_hba *hba, | ||
496 | struct se_subsystem_dev *se_dev) | ||
497 | { | 616 | { |
498 | struct iblock_dev *ibd = se_dev->se_dev_su_ptr; | 617 | struct iblock_dev *ib_dev = IBLOCK_DEV(dev); |
499 | 618 | struct block_device *bd = ib_dev->ibd_bd; | |
500 | if (!(ibd->ibd_flags & IBDF_HAS_UDEV_PATH)) { | ||
501 | pr_err("Missing udev_path= parameters for IBLOCK\n"); | ||
502 | return -EINVAL; | ||
503 | } | ||
504 | |||
505 | return 0; | ||
506 | } | ||
507 | |||
508 | static ssize_t iblock_show_configfs_dev_params( | ||
509 | struct se_hba *hba, | ||
510 | struct se_subsystem_dev *se_dev, | ||
511 | char *b) | ||
512 | { | ||
513 | struct iblock_dev *ibd = se_dev->se_dev_su_ptr; | ||
514 | struct block_device *bd = ibd->ibd_bd; | ||
515 | char buf[BDEVNAME_SIZE]; | 619 | char buf[BDEVNAME_SIZE]; |
516 | ssize_t bl = 0; | 620 | ssize_t bl = 0; |
517 | 621 | ||
518 | if (bd) | 622 | if (bd) |
519 | bl += sprintf(b + bl, "iBlock device: %s", | 623 | bl += sprintf(b + bl, "iBlock device: %s", |
520 | bdevname(bd, buf)); | 624 | bdevname(bd, buf)); |
521 | if (ibd->ibd_flags & IBDF_HAS_UDEV_PATH) | 625 | if (ib_dev->ibd_flags & IBDF_HAS_UDEV_PATH) |
522 | bl += sprintf(b + bl, " UDEV PATH: %s", | 626 | bl += sprintf(b + bl, " UDEV PATH: %s", |
523 | ibd->ibd_udev_path); | 627 | ib_dev->ibd_udev_path); |
524 | bl += sprintf(b + bl, " readonly: %d\n", ibd->ibd_readonly); | 628 | bl += sprintf(b + bl, " readonly: %d\n", ib_dev->ibd_readonly); |
525 | 629 | ||
526 | bl += sprintf(b + bl, " "); | 630 | bl += sprintf(b + bl, " "); |
527 | if (bd) { | 631 | if (bd) { |
528 | bl += sprintf(b + bl, "Major: %d Minor: %d %s\n", | 632 | bl += sprintf(b + bl, "Major: %d Minor: %d %s\n", |
529 | MAJOR(bd->bd_dev), MINOR(bd->bd_dev), (!bd->bd_contains) ? | 633 | MAJOR(bd->bd_dev), MINOR(bd->bd_dev), (!bd->bd_contains) ? |
530 | "" : (bd->bd_holder == ibd) ? | 634 | "" : (bd->bd_holder == ib_dev) ? |
531 | "CLAIMED: IBLOCK" : "CLAIMED: OS"); | 635 | "CLAIMED: IBLOCK" : "CLAIMED: OS"); |
532 | } else { | 636 | } else { |
533 | bl += sprintf(b + bl, "Major: 0 Minor: 0\n"); | 637 | bl += sprintf(b + bl, "Major: 0 Minor: 0\n"); |
@@ -536,61 +640,8 @@ static ssize_t iblock_show_configfs_dev_params( | |||
536 | return bl; | 640 | return bl; |
537 | } | 641 | } |
538 | 642 | ||
539 | static void iblock_complete_cmd(struct se_cmd *cmd) | 643 | static sense_reason_t |
540 | { | 644 | iblock_execute_rw(struct se_cmd *cmd) |
541 | struct iblock_req *ibr = cmd->priv; | ||
542 | u8 status; | ||
543 | |||
544 | if (!atomic_dec_and_test(&ibr->pending)) | ||
545 | return; | ||
546 | |||
547 | if (atomic_read(&ibr->ib_bio_err_cnt)) | ||
548 | status = SAM_STAT_CHECK_CONDITION; | ||
549 | else | ||
550 | status = SAM_STAT_GOOD; | ||
551 | |||
552 | target_complete_cmd(cmd, status); | ||
553 | kfree(ibr); | ||
554 | } | ||
555 | |||
556 | static struct bio * | ||
557 | iblock_get_bio(struct se_cmd *cmd, sector_t lba, u32 sg_num) | ||
558 | { | ||
559 | struct iblock_dev *ib_dev = cmd->se_dev->dev_ptr; | ||
560 | struct bio *bio; | ||
561 | |||
562 | /* | ||
563 | * Only allocate as many vector entries as the bio code allows us to, | ||
564 | * we'll loop later on until we have handled the whole request. | ||
565 | */ | ||
566 | if (sg_num > BIO_MAX_PAGES) | ||
567 | sg_num = BIO_MAX_PAGES; | ||
568 | |||
569 | bio = bio_alloc_bioset(GFP_NOIO, sg_num, ib_dev->ibd_bio_set); | ||
570 | if (!bio) { | ||
571 | pr_err("Unable to allocate memory for bio\n"); | ||
572 | return NULL; | ||
573 | } | ||
574 | |||
575 | bio->bi_bdev = ib_dev->ibd_bd; | ||
576 | bio->bi_private = cmd; | ||
577 | bio->bi_end_io = &iblock_bio_done; | ||
578 | bio->bi_sector = lba; | ||
579 | return bio; | ||
580 | } | ||
581 | |||
582 | static void iblock_submit_bios(struct bio_list *list, int rw) | ||
583 | { | ||
584 | struct blk_plug plug; | ||
585 | struct bio *bio; | ||
586 | |||
587 | blk_start_plug(&plug); | ||
588 | while ((bio = bio_list_pop(list))) | ||
589 | submit_bio(rw, bio); | ||
590 | blk_finish_plug(&plug); | ||
591 | } | ||
592 | |||
593 | static int iblock_execute_rw(struct se_cmd *cmd) | ||
594 | { | 645 | { |
595 | struct scatterlist *sgl = cmd->t_data_sg; | 646 | struct scatterlist *sgl = cmd->t_data_sg; |
596 | u32 sgl_nents = cmd->t_data_nents; | 647 | u32 sgl_nents = cmd->t_data_nents; |
@@ -611,8 +662,8 @@ static int iblock_execute_rw(struct se_cmd *cmd) | |||
611 | * Force data to disk if we pretend to not have a volatile | 662 | * Force data to disk if we pretend to not have a volatile |
612 | * write cache, or the initiator set the Force Unit Access bit. | 663 | * write cache, or the initiator set the Force Unit Access bit. |
613 | */ | 664 | */ |
614 | if (dev->se_sub_dev->se_dev_attrib.emulate_write_cache == 0 || | 665 | if (dev->dev_attrib.emulate_write_cache == 0 || |
615 | (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 && | 666 | (dev->dev_attrib.emulate_fua_write > 0 && |
616 | (cmd->se_cmd_flags & SCF_FUA))) | 667 | (cmd->se_cmd_flags & SCF_FUA))) |
617 | rw = WRITE_FUA; | 668 | rw = WRITE_FUA; |
618 | else | 669 | else |
@@ -625,19 +676,18 @@ static int iblock_execute_rw(struct se_cmd *cmd) | |||
625 | * Convert the blocksize advertised to the initiator to the 512 byte | 676 | * Convert the blocksize advertised to the initiator to the 512 byte |
626 | * units unconditionally used by the Linux block layer. | 677 | * units unconditionally used by the Linux block layer. |
627 | */ | 678 | */ |
628 | if (dev->se_sub_dev->se_dev_attrib.block_size == 4096) | 679 | if (dev->dev_attrib.block_size == 4096) |
629 | block_lba = (cmd->t_task_lba << 3); | 680 | block_lba = (cmd->t_task_lba << 3); |
630 | else if (dev->se_sub_dev->se_dev_attrib.block_size == 2048) | 681 | else if (dev->dev_attrib.block_size == 2048) |
631 | block_lba = (cmd->t_task_lba << 2); | 682 | block_lba = (cmd->t_task_lba << 2); |
632 | else if (dev->se_sub_dev->se_dev_attrib.block_size == 1024) | 683 | else if (dev->dev_attrib.block_size == 1024) |
633 | block_lba = (cmd->t_task_lba << 1); | 684 | block_lba = (cmd->t_task_lba << 1); |
634 | else if (dev->se_sub_dev->se_dev_attrib.block_size == 512) | 685 | else if (dev->dev_attrib.block_size == 512) |
635 | block_lba = cmd->t_task_lba; | 686 | block_lba = cmd->t_task_lba; |
636 | else { | 687 | else { |
637 | pr_err("Unsupported SCSI -> BLOCK LBA conversion:" | 688 | pr_err("Unsupported SCSI -> BLOCK LBA conversion:" |
638 | " %u\n", dev->se_sub_dev->se_dev_attrib.block_size); | 689 | " %u\n", dev->dev_attrib.block_size); |
639 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 690 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
640 | return -ENOSYS; | ||
641 | } | 691 | } |
642 | 692 | ||
643 | ibr = kzalloc(sizeof(struct iblock_req), GFP_KERNEL); | 693 | ibr = kzalloc(sizeof(struct iblock_req), GFP_KERNEL); |
@@ -697,83 +747,48 @@ fail_put_bios: | |||
697 | bio_put(bio); | 747 | bio_put(bio); |
698 | fail_free_ibr: | 748 | fail_free_ibr: |
699 | kfree(ibr); | 749 | kfree(ibr); |
700 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
701 | fail: | 750 | fail: |
702 | return -ENOMEM; | 751 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
703 | } | ||
704 | |||
705 | static u32 iblock_get_device_rev(struct se_device *dev) | ||
706 | { | ||
707 | return SCSI_SPC_2; /* Returns SPC-3 in Initiator Data */ | ||
708 | } | ||
709 | |||
710 | static u32 iblock_get_device_type(struct se_device *dev) | ||
711 | { | ||
712 | return TYPE_DISK; | ||
713 | } | 752 | } |
714 | 753 | ||
715 | static sector_t iblock_get_blocks(struct se_device *dev) | 754 | static sector_t iblock_get_blocks(struct se_device *dev) |
716 | { | 755 | { |
717 | struct iblock_dev *ibd = dev->dev_ptr; | 756 | struct iblock_dev *ib_dev = IBLOCK_DEV(dev); |
718 | struct block_device *bd = ibd->ibd_bd; | 757 | struct block_device *bd = ib_dev->ibd_bd; |
719 | struct request_queue *q = bdev_get_queue(bd); | 758 | struct request_queue *q = bdev_get_queue(bd); |
720 | 759 | ||
721 | return iblock_emulate_read_cap_with_block_size(dev, bd, q); | 760 | return iblock_emulate_read_cap_with_block_size(dev, bd, q); |
722 | } | 761 | } |
723 | 762 | ||
724 | static void iblock_bio_done(struct bio *bio, int err) | 763 | static struct sbc_ops iblock_sbc_ops = { |
725 | { | ||
726 | struct se_cmd *cmd = bio->bi_private; | ||
727 | struct iblock_req *ibr = cmd->priv; | ||
728 | |||
729 | /* | ||
730 | * Set -EIO if !BIO_UPTODATE and the passed is still err=0 | ||
731 | */ | ||
732 | if (!test_bit(BIO_UPTODATE, &bio->bi_flags) && !err) | ||
733 | err = -EIO; | ||
734 | |||
735 | if (err != 0) { | ||
736 | pr_err("test_bit(BIO_UPTODATE) failed for bio: %p," | ||
737 | " err: %d\n", bio, err); | ||
738 | /* | ||
739 | * Bump the ib_bio_err_cnt and release bio. | ||
740 | */ | ||
741 | atomic_inc(&ibr->ib_bio_err_cnt); | ||
742 | smp_mb__after_atomic_inc(); | ||
743 | } | ||
744 | |||
745 | bio_put(bio); | ||
746 | |||
747 | iblock_complete_cmd(cmd); | ||
748 | } | ||
749 | |||
750 | static struct spc_ops iblock_spc_ops = { | ||
751 | .execute_rw = iblock_execute_rw, | 764 | .execute_rw = iblock_execute_rw, |
752 | .execute_sync_cache = iblock_execute_sync_cache, | 765 | .execute_sync_cache = iblock_execute_sync_cache, |
753 | .execute_write_same = iblock_execute_write_same, | 766 | .execute_write_same = iblock_execute_write_same, |
767 | .execute_write_same_unmap = iblock_execute_write_same_unmap, | ||
754 | .execute_unmap = iblock_execute_unmap, | 768 | .execute_unmap = iblock_execute_unmap, |
755 | }; | 769 | }; |
756 | 770 | ||
757 | static int iblock_parse_cdb(struct se_cmd *cmd) | 771 | static sense_reason_t |
772 | iblock_parse_cdb(struct se_cmd *cmd) | ||
758 | { | 773 | { |
759 | return sbc_parse_cdb(cmd, &iblock_spc_ops); | 774 | return sbc_parse_cdb(cmd, &iblock_sbc_ops); |
760 | } | 775 | } |
761 | 776 | ||
762 | static struct se_subsystem_api iblock_template = { | 777 | static struct se_subsystem_api iblock_template = { |
763 | .name = "iblock", | 778 | .name = "iblock", |
779 | .inquiry_prod = "IBLOCK", | ||
780 | .inquiry_rev = IBLOCK_VERSION, | ||
764 | .owner = THIS_MODULE, | 781 | .owner = THIS_MODULE, |
765 | .transport_type = TRANSPORT_PLUGIN_VHBA_PDEV, | 782 | .transport_type = TRANSPORT_PLUGIN_VHBA_PDEV, |
766 | .attach_hba = iblock_attach_hba, | 783 | .attach_hba = iblock_attach_hba, |
767 | .detach_hba = iblock_detach_hba, | 784 | .detach_hba = iblock_detach_hba, |
768 | .allocate_virtdevice = iblock_allocate_virtdevice, | 785 | .alloc_device = iblock_alloc_device, |
769 | .create_virtdevice = iblock_create_virtdevice, | 786 | .configure_device = iblock_configure_device, |
770 | .free_device = iblock_free_device, | 787 | .free_device = iblock_free_device, |
771 | .parse_cdb = iblock_parse_cdb, | 788 | .parse_cdb = iblock_parse_cdb, |
772 | .check_configfs_dev_params = iblock_check_configfs_dev_params, | ||
773 | .set_configfs_dev_params = iblock_set_configfs_dev_params, | 789 | .set_configfs_dev_params = iblock_set_configfs_dev_params, |
774 | .show_configfs_dev_params = iblock_show_configfs_dev_params, | 790 | .show_configfs_dev_params = iblock_show_configfs_dev_params, |
775 | .get_device_rev = iblock_get_device_rev, | 791 | .get_device_type = sbc_get_device_type, |
776 | .get_device_type = iblock_get_device_type, | ||
777 | .get_blocks = iblock_get_blocks, | 792 | .get_blocks = iblock_get_blocks, |
778 | }; | 793 | }; |
779 | 794 | ||
diff --git a/drivers/target/target_core_iblock.h b/drivers/target/target_core_iblock.h index 533627ae79ec..01c2afd81500 100644 --- a/drivers/target/target_core_iblock.h +++ b/drivers/target/target_core_iblock.h | |||
@@ -14,6 +14,7 @@ struct iblock_req { | |||
14 | #define IBDF_HAS_UDEV_PATH 0x01 | 14 | #define IBDF_HAS_UDEV_PATH 0x01 |
15 | 15 | ||
16 | struct iblock_dev { | 16 | struct iblock_dev { |
17 | struct se_device dev; | ||
17 | unsigned char ibd_udev_path[SE_UDEV_PATH_LEN]; | 18 | unsigned char ibd_udev_path[SE_UDEV_PATH_LEN]; |
18 | u32 ibd_flags; | 19 | u32 ibd_flags; |
19 | struct bio_set *ibd_bio_set; | 20 | struct bio_set *ibd_bio_set; |
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index 0fd428225d11..93e9c1f580b0 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h | |||
@@ -19,18 +19,12 @@ int core_dev_export(struct se_device *, struct se_portal_group *, | |||
19 | struct se_lun *); | 19 | struct se_lun *); |
20 | void core_dev_unexport(struct se_device *, struct se_portal_group *, | 20 | void core_dev_unexport(struct se_device *, struct se_portal_group *, |
21 | struct se_lun *); | 21 | struct se_lun *); |
22 | int target_report_luns(struct se_cmd *); | ||
23 | void se_release_device_for_hba(struct se_device *); | ||
24 | void se_release_vpd_for_dev(struct se_device *); | ||
25 | int se_free_virtual_device(struct se_device *, struct se_hba *); | ||
26 | int se_dev_check_online(struct se_device *); | ||
27 | int se_dev_check_shutdown(struct se_device *); | ||
28 | void se_dev_set_default_attribs(struct se_device *, struct se_dev_limits *); | ||
29 | int se_dev_set_task_timeout(struct se_device *, u32); | 22 | int se_dev_set_task_timeout(struct se_device *, u32); |
30 | int se_dev_set_max_unmap_lba_count(struct se_device *, u32); | 23 | int se_dev_set_max_unmap_lba_count(struct se_device *, u32); |
31 | int se_dev_set_max_unmap_block_desc_count(struct se_device *, u32); | 24 | int se_dev_set_max_unmap_block_desc_count(struct se_device *, u32); |
32 | int se_dev_set_unmap_granularity(struct se_device *, u32); | 25 | int se_dev_set_unmap_granularity(struct se_device *, u32); |
33 | int se_dev_set_unmap_granularity_alignment(struct se_device *, u32); | 26 | int se_dev_set_unmap_granularity_alignment(struct se_device *, u32); |
27 | int se_dev_set_max_write_same_len(struct se_device *, u32); | ||
34 | int se_dev_set_emulate_dpo(struct se_device *, int); | 28 | int se_dev_set_emulate_dpo(struct se_device *, int); |
35 | int se_dev_set_emulate_fua_write(struct se_device *, int); | 29 | int se_dev_set_emulate_fua_write(struct se_device *, int); |
36 | int se_dev_set_emulate_fua_read(struct se_device *, int); | 30 | int se_dev_set_emulate_fua_read(struct se_device *, int); |
@@ -60,6 +54,9 @@ void core_dev_free_initiator_node_lun_acl(struct se_portal_group *, | |||
60 | struct se_lun_acl *lacl); | 54 | struct se_lun_acl *lacl); |
61 | int core_dev_setup_virtual_lun0(void); | 55 | int core_dev_setup_virtual_lun0(void); |
62 | void core_dev_release_virtual_lun0(void); | 56 | void core_dev_release_virtual_lun0(void); |
57 | struct se_device *target_alloc_device(struct se_hba *hba, const char *name); | ||
58 | int target_configure_device(struct se_device *dev); | ||
59 | void target_free_device(struct se_device *); | ||
63 | 60 | ||
64 | /* target_core_hba.c */ | 61 | /* target_core_hba.c */ |
65 | struct se_hba *core_alloc_hba(const char *, u32, u32); | 62 | struct se_hba *core_alloc_hba(const char *, u32, u32); |
@@ -105,10 +102,11 @@ int transport_dump_vpd_ident(struct t10_vpd *, unsigned char *, int); | |||
105 | bool target_stop_cmd(struct se_cmd *cmd, unsigned long *flags); | 102 | bool target_stop_cmd(struct se_cmd *cmd, unsigned long *flags); |
106 | int transport_clear_lun_from_sessions(struct se_lun *); | 103 | int transport_clear_lun_from_sessions(struct se_lun *); |
107 | void transport_send_task_abort(struct se_cmd *); | 104 | void transport_send_task_abort(struct se_cmd *); |
108 | int target_cmd_size_check(struct se_cmd *cmd, unsigned int size); | 105 | sense_reason_t target_cmd_size_check(struct se_cmd *cmd, unsigned int size); |
106 | void target_qf_do_work(struct work_struct *work); | ||
109 | 107 | ||
110 | /* target_core_stat.c */ | 108 | /* target_core_stat.c */ |
111 | void target_stat_setup_dev_default_groups(struct se_subsystem_dev *); | 109 | void target_stat_setup_dev_default_groups(struct se_device *); |
112 | void target_stat_setup_port_default_groups(struct se_lun *); | 110 | void target_stat_setup_port_default_groups(struct se_lun *); |
113 | void target_stat_setup_mappedlun_default_groups(struct se_lun_acl *); | 111 | void target_stat_setup_mappedlun_default_groups(struct se_lun_acl *); |
114 | 112 | ||
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 8c323a98c4a0..8e0290b38e43 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -4,8 +4,7 @@ | |||
4 | * This file contains SPC-3 compliant persistent reservations and | 4 | * This file contains SPC-3 compliant persistent reservations and |
5 | * legacy SPC-2 reservations with compatible reservation handling (CRH=1) | 5 | * legacy SPC-2 reservations with compatible reservation handling (CRH=1) |
6 | * | 6 | * |
7 | * Copyright (c) 2009, 2010 Rising Tide Systems | 7 | * (c) Copyright 2009-2012 RisingTide Systems LLC. |
8 | * Copyright (c) 2009, 2010 Linux-iSCSI.org | ||
9 | * | 8 | * |
10 | * Nicholas A. Bellinger <nab@kernel.org> | 9 | * Nicholas A. Bellinger <nab@kernel.org> |
11 | * | 10 | * |
@@ -68,49 +67,33 @@ int core_pr_dump_initiator_port( | |||
68 | static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *, | 67 | static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *, |
69 | struct t10_pr_registration *, int); | 68 | struct t10_pr_registration *, int); |
70 | 69 | ||
71 | static int core_scsi2_reservation_seq_non_holder( | 70 | static sense_reason_t |
72 | struct se_cmd *cmd, | 71 | target_scsi2_reservation_check(struct se_cmd *cmd) |
73 | unsigned char *cdb, | ||
74 | u32 pr_reg_type) | ||
75 | { | 72 | { |
76 | switch (cdb[0]) { | 73 | struct se_device *dev = cmd->se_dev; |
74 | struct se_session *sess = cmd->se_sess; | ||
75 | |||
76 | switch (cmd->t_task_cdb[0]) { | ||
77 | case INQUIRY: | 77 | case INQUIRY: |
78 | case RELEASE: | 78 | case RELEASE: |
79 | case RELEASE_10: | 79 | case RELEASE_10: |
80 | return 0; | 80 | return 0; |
81 | default: | 81 | default: |
82 | return 1; | 82 | break; |
83 | } | 83 | } |
84 | 84 | ||
85 | return 1; | 85 | if (!dev->dev_reserved_node_acl || !sess) |
86 | } | ||
87 | |||
88 | static int core_scsi2_reservation_check(struct se_cmd *cmd, u32 *pr_reg_type) | ||
89 | { | ||
90 | struct se_device *dev = cmd->se_dev; | ||
91 | struct se_session *sess = cmd->se_sess; | ||
92 | int ret; | ||
93 | |||
94 | if (!sess) | ||
95 | return 0; | 86 | return 0; |
96 | 87 | ||
97 | spin_lock(&dev->dev_reservation_lock); | 88 | if (dev->dev_reserved_node_acl != sess->se_node_acl) |
98 | if (!dev->dev_reserved_node_acl || !sess) { | 89 | return TCM_RESERVATION_CONFLICT; |
99 | spin_unlock(&dev->dev_reservation_lock); | 90 | |
100 | return 0; | 91 | if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID) { |
101 | } | 92 | if (dev->dev_res_bin_isid != sess->sess_bin_isid) |
102 | if (dev->dev_reserved_node_acl != sess->se_node_acl) { | 93 | return TCM_RESERVATION_CONFLICT; |
103 | spin_unlock(&dev->dev_reservation_lock); | ||
104 | return -EINVAL; | ||
105 | } | ||
106 | if (!(dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID)) { | ||
107 | spin_unlock(&dev->dev_reservation_lock); | ||
108 | return 0; | ||
109 | } | 94 | } |
110 | ret = (dev->dev_res_bin_isid == sess->sess_bin_isid) ? 0 : -EINVAL; | ||
111 | spin_unlock(&dev->dev_reservation_lock); | ||
112 | 95 | ||
113 | return ret; | 96 | return 0; |
114 | } | 97 | } |
115 | 98 | ||
116 | static struct t10_pr_registration *core_scsi3_locate_pr_reg(struct se_device *, | 99 | static struct t10_pr_registration *core_scsi3_locate_pr_reg(struct se_device *, |
@@ -120,15 +103,11 @@ static void core_scsi3_put_pr_reg(struct t10_pr_registration *); | |||
120 | static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd) | 103 | static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd) |
121 | { | 104 | { |
122 | struct se_session *se_sess = cmd->se_sess; | 105 | struct se_session *se_sess = cmd->se_sess; |
123 | struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev; | 106 | struct se_device *dev = cmd->se_dev; |
124 | struct t10_pr_registration *pr_reg; | 107 | struct t10_pr_registration *pr_reg; |
125 | struct t10_reservation *pr_tmpl = &su_dev->t10_pr; | 108 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
126 | int crh = (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS); | ||
127 | int conflict = 0; | 109 | int conflict = 0; |
128 | 110 | ||
129 | if (!crh) | ||
130 | return -EINVAL; | ||
131 | |||
132 | pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl, | 111 | pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl, |
133 | se_sess); | 112 | se_sess); |
134 | if (pr_reg) { | 113 | if (pr_reg) { |
@@ -186,32 +165,28 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd) | |||
186 | pr_err("Received legacy SPC-2 RESERVE/RELEASE" | 165 | pr_err("Received legacy SPC-2 RESERVE/RELEASE" |
187 | " while active SPC-3 registrations exist," | 166 | " while active SPC-3 registrations exist," |
188 | " returning RESERVATION_CONFLICT\n"); | 167 | " returning RESERVATION_CONFLICT\n"); |
189 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | ||
190 | return -EBUSY; | 168 | return -EBUSY; |
191 | } | 169 | } |
192 | 170 | ||
193 | return 0; | 171 | return 0; |
194 | } | 172 | } |
195 | 173 | ||
196 | int target_scsi2_reservation_release(struct se_cmd *cmd) | 174 | sense_reason_t |
175 | target_scsi2_reservation_release(struct se_cmd *cmd) | ||
197 | { | 176 | { |
198 | struct se_device *dev = cmd->se_dev; | 177 | struct se_device *dev = cmd->se_dev; |
199 | struct se_session *sess = cmd->se_sess; | 178 | struct se_session *sess = cmd->se_sess; |
200 | struct se_portal_group *tpg; | 179 | struct se_portal_group *tpg; |
201 | int ret = 0, rc; | 180 | int rc; |
202 | 181 | ||
203 | if (!sess || !sess->se_tpg) | 182 | if (!sess || !sess->se_tpg) |
204 | goto out; | 183 | goto out; |
205 | rc = target_check_scsi2_reservation_conflict(cmd); | 184 | rc = target_check_scsi2_reservation_conflict(cmd); |
206 | if (rc == 1) | 185 | if (rc == 1) |
207 | goto out; | 186 | goto out; |
208 | else if (rc < 0) { | 187 | if (rc < 0) |
209 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 188 | return TCM_RESERVATION_CONFLICT; |
210 | ret = -EINVAL; | ||
211 | goto out; | ||
212 | } | ||
213 | 189 | ||
214 | ret = 0; | ||
215 | spin_lock(&dev->dev_reservation_lock); | 190 | spin_lock(&dev->dev_reservation_lock); |
216 | if (!dev->dev_reserved_node_acl || !sess) | 191 | if (!dev->dev_reserved_node_acl || !sess) |
217 | goto out_unlock; | 192 | goto out_unlock; |
@@ -223,10 +198,10 @@ int target_scsi2_reservation_release(struct se_cmd *cmd) | |||
223 | goto out_unlock; | 198 | goto out_unlock; |
224 | 199 | ||
225 | dev->dev_reserved_node_acl = NULL; | 200 | dev->dev_reserved_node_acl = NULL; |
226 | dev->dev_flags &= ~DF_SPC2_RESERVATIONS; | 201 | dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS; |
227 | if (dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID) { | 202 | if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID) { |
228 | dev->dev_res_bin_isid = 0; | 203 | dev->dev_res_bin_isid = 0; |
229 | dev->dev_flags &= ~DF_SPC2_RESERVATIONS_WITH_ISID; | 204 | dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS_WITH_ISID; |
230 | } | 205 | } |
231 | tpg = sess->se_tpg; | 206 | tpg = sess->se_tpg; |
232 | pr_debug("SCSI-2 Released reservation for %s LUN: %u ->" | 207 | pr_debug("SCSI-2 Released reservation for %s LUN: %u ->" |
@@ -237,25 +212,24 @@ int target_scsi2_reservation_release(struct se_cmd *cmd) | |||
237 | out_unlock: | 212 | out_unlock: |
238 | spin_unlock(&dev->dev_reservation_lock); | 213 | spin_unlock(&dev->dev_reservation_lock); |
239 | out: | 214 | out: |
240 | if (!ret) | 215 | target_complete_cmd(cmd, GOOD); |
241 | target_complete_cmd(cmd, GOOD); | 216 | return 0; |
242 | return ret; | ||
243 | } | 217 | } |
244 | 218 | ||
245 | int target_scsi2_reservation_reserve(struct se_cmd *cmd) | 219 | sense_reason_t |
220 | target_scsi2_reservation_reserve(struct se_cmd *cmd) | ||
246 | { | 221 | { |
247 | struct se_device *dev = cmd->se_dev; | 222 | struct se_device *dev = cmd->se_dev; |
248 | struct se_session *sess = cmd->se_sess; | 223 | struct se_session *sess = cmd->se_sess; |
249 | struct se_portal_group *tpg; | 224 | struct se_portal_group *tpg; |
250 | int ret = 0, rc; | 225 | sense_reason_t ret = 0; |
226 | int rc; | ||
251 | 227 | ||
252 | if ((cmd->t_task_cdb[1] & 0x01) && | 228 | if ((cmd->t_task_cdb[1] & 0x01) && |
253 | (cmd->t_task_cdb[1] & 0x02)) { | 229 | (cmd->t_task_cdb[1] & 0x02)) { |
254 | pr_err("LongIO and Obselete Bits set, returning" | 230 | pr_err("LongIO and Obselete Bits set, returning" |
255 | " ILLEGAL_REQUEST\n"); | 231 | " ILLEGAL_REQUEST\n"); |
256 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | 232 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
257 | ret = -EINVAL; | ||
258 | goto out; | ||
259 | } | 233 | } |
260 | /* | 234 | /* |
261 | * This is currently the case for target_core_mod passthrough struct se_cmd | 235 | * This is currently the case for target_core_mod passthrough struct se_cmd |
@@ -266,13 +240,10 @@ int target_scsi2_reservation_reserve(struct se_cmd *cmd) | |||
266 | rc = target_check_scsi2_reservation_conflict(cmd); | 240 | rc = target_check_scsi2_reservation_conflict(cmd); |
267 | if (rc == 1) | 241 | if (rc == 1) |
268 | goto out; | 242 | goto out; |
269 | else if (rc < 0) { | ||
270 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | ||
271 | ret = -EINVAL; | ||
272 | goto out; | ||
273 | } | ||
274 | 243 | ||
275 | ret = 0; | 244 | if (rc < 0) |
245 | return TCM_RESERVATION_CONFLICT; | ||
246 | |||
276 | tpg = sess->se_tpg; | 247 | tpg = sess->se_tpg; |
277 | spin_lock(&dev->dev_reservation_lock); | 248 | spin_lock(&dev->dev_reservation_lock); |
278 | if (dev->dev_reserved_node_acl && | 249 | if (dev->dev_reserved_node_acl && |
@@ -286,16 +257,15 @@ int target_scsi2_reservation_reserve(struct se_cmd *cmd) | |||
286 | " from %s \n", cmd->se_lun->unpacked_lun, | 257 | " from %s \n", cmd->se_lun->unpacked_lun, |
287 | cmd->se_deve->mapped_lun, | 258 | cmd->se_deve->mapped_lun, |
288 | sess->se_node_acl->initiatorname); | 259 | sess->se_node_acl->initiatorname); |
289 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 260 | ret = TCM_RESERVATION_CONFLICT; |
290 | ret = -EINVAL; | ||
291 | goto out_unlock; | 261 | goto out_unlock; |
292 | } | 262 | } |
293 | 263 | ||
294 | dev->dev_reserved_node_acl = sess->se_node_acl; | 264 | dev->dev_reserved_node_acl = sess->se_node_acl; |
295 | dev->dev_flags |= DF_SPC2_RESERVATIONS; | 265 | dev->dev_reservation_flags |= DRF_SPC2_RESERVATIONS; |
296 | if (sess->sess_bin_isid != 0) { | 266 | if (sess->sess_bin_isid != 0) { |
297 | dev->dev_res_bin_isid = sess->sess_bin_isid; | 267 | dev->dev_res_bin_isid = sess->sess_bin_isid; |
298 | dev->dev_flags |= DF_SPC2_RESERVATIONS_WITH_ISID; | 268 | dev->dev_reservation_flags |= DRF_SPC2_RESERVATIONS_WITH_ISID; |
299 | } | 269 | } |
300 | pr_debug("SCSI-2 Reserved %s LUN: %u -> MAPPED LUN: %u" | 270 | pr_debug("SCSI-2 Reserved %s LUN: %u -> MAPPED LUN: %u" |
301 | " for %s\n", tpg->se_tpg_tfo->get_fabric_name(), | 271 | " for %s\n", tpg->se_tpg_tfo->get_fabric_name(), |
@@ -319,9 +289,9 @@ out: | |||
319 | */ | 289 | */ |
320 | static int core_scsi3_pr_seq_non_holder( | 290 | static int core_scsi3_pr_seq_non_holder( |
321 | struct se_cmd *cmd, | 291 | struct se_cmd *cmd, |
322 | unsigned char *cdb, | ||
323 | u32 pr_reg_type) | 292 | u32 pr_reg_type) |
324 | { | 293 | { |
294 | unsigned char *cdb = cmd->t_task_cdb; | ||
325 | struct se_dev_entry *se_deve; | 295 | struct se_dev_entry *se_deve; |
326 | struct se_session *se_sess = cmd->se_sess; | 296 | struct se_session *se_sess = cmd->se_sess; |
327 | int other_cdb = 0, ignore_reg; | 297 | int other_cdb = 0, ignore_reg; |
@@ -330,17 +300,11 @@ static int core_scsi3_pr_seq_non_holder( | |||
330 | int we = 0; /* Write Exclusive */ | 300 | int we = 0; /* Write Exclusive */ |
331 | int legacy = 0; /* Act like a legacy device and return | 301 | int legacy = 0; /* Act like a legacy device and return |
332 | * RESERVATION CONFLICT on some CDBs */ | 302 | * RESERVATION CONFLICT on some CDBs */ |
333 | /* | ||
334 | * A legacy SPC-2 reservation is being held. | ||
335 | */ | ||
336 | if (cmd->se_dev->dev_flags & DF_SPC2_RESERVATIONS) | ||
337 | return core_scsi2_reservation_seq_non_holder(cmd, | ||
338 | cdb, pr_reg_type); | ||
339 | 303 | ||
340 | se_deve = se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; | 304 | se_deve = se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; |
341 | /* | 305 | /* |
342 | * Determine if the registration should be ignored due to | 306 | * Determine if the registration should be ignored due to |
343 | * non-matching ISIDs in core_scsi3_pr_reservation_check(). | 307 | * non-matching ISIDs in target_scsi3_pr_reservation_check(). |
344 | */ | 308 | */ |
345 | ignore_reg = (pr_reg_type & 0x80000000); | 309 | ignore_reg = (pr_reg_type & 0x80000000); |
346 | if (ignore_reg) | 310 | if (ignore_reg) |
@@ -563,10 +527,41 @@ static int core_scsi3_pr_seq_non_holder( | |||
563 | return 1; /* Conflict by default */ | 527 | return 1; /* Conflict by default */ |
564 | } | 528 | } |
565 | 529 | ||
530 | static sense_reason_t | ||
531 | target_scsi3_pr_reservation_check(struct se_cmd *cmd) | ||
532 | { | ||
533 | struct se_device *dev = cmd->se_dev; | ||
534 | struct se_session *sess = cmd->se_sess; | ||
535 | u32 pr_reg_type; | ||
536 | |||
537 | if (!dev->dev_pr_res_holder) | ||
538 | return 0; | ||
539 | |||
540 | pr_reg_type = dev->dev_pr_res_holder->pr_res_type; | ||
541 | cmd->pr_res_key = dev->dev_pr_res_holder->pr_res_key; | ||
542 | if (dev->dev_pr_res_holder->pr_reg_nacl != sess->se_node_acl) | ||
543 | goto check_nonholder; | ||
544 | |||
545 | if (dev->dev_pr_res_holder->isid_present_at_reg) { | ||
546 | if (dev->dev_pr_res_holder->pr_reg_bin_isid != | ||
547 | sess->sess_bin_isid) { | ||
548 | pr_reg_type |= 0x80000000; | ||
549 | goto check_nonholder; | ||
550 | } | ||
551 | } | ||
552 | |||
553 | return 0; | ||
554 | |||
555 | check_nonholder: | ||
556 | if (core_scsi3_pr_seq_non_holder(cmd, pr_reg_type)) | ||
557 | return TCM_RESERVATION_CONFLICT; | ||
558 | return 0; | ||
559 | } | ||
560 | |||
566 | static u32 core_scsi3_pr_generation(struct se_device *dev) | 561 | static u32 core_scsi3_pr_generation(struct se_device *dev) |
567 | { | 562 | { |
568 | struct se_subsystem_dev *su_dev = dev->se_sub_dev; | ||
569 | u32 prg; | 563 | u32 prg; |
564 | |||
570 | /* | 565 | /* |
571 | * PRGeneration field shall contain the value of a 32-bit wrapping | 566 | * PRGeneration field shall contain the value of a 32-bit wrapping |
572 | * counter mainted by the device server. | 567 | * counter mainted by the device server. |
@@ -577,56 +572,12 @@ static u32 core_scsi3_pr_generation(struct se_device *dev) | |||
577 | * See spc4r17 section 6.3.12 READ_KEYS service action | 572 | * See spc4r17 section 6.3.12 READ_KEYS service action |
578 | */ | 573 | */ |
579 | spin_lock(&dev->dev_reservation_lock); | 574 | spin_lock(&dev->dev_reservation_lock); |
580 | prg = su_dev->t10_pr.pr_generation++; | 575 | prg = dev->t10_pr.pr_generation++; |
581 | spin_unlock(&dev->dev_reservation_lock); | 576 | spin_unlock(&dev->dev_reservation_lock); |
582 | 577 | ||
583 | return prg; | 578 | return prg; |
584 | } | 579 | } |
585 | 580 | ||
586 | static int core_scsi3_pr_reservation_check( | ||
587 | struct se_cmd *cmd, | ||
588 | u32 *pr_reg_type) | ||
589 | { | ||
590 | struct se_device *dev = cmd->se_dev; | ||
591 | struct se_session *sess = cmd->se_sess; | ||
592 | int ret; | ||
593 | |||
594 | if (!sess) | ||
595 | return 0; | ||
596 | /* | ||
597 | * A legacy SPC-2 reservation is being held. | ||
598 | */ | ||
599 | if (dev->dev_flags & DF_SPC2_RESERVATIONS) | ||
600 | return core_scsi2_reservation_check(cmd, pr_reg_type); | ||
601 | |||
602 | spin_lock(&dev->dev_reservation_lock); | ||
603 | if (!dev->dev_pr_res_holder) { | ||
604 | spin_unlock(&dev->dev_reservation_lock); | ||
605 | return 0; | ||
606 | } | ||
607 | *pr_reg_type = dev->dev_pr_res_holder->pr_res_type; | ||
608 | cmd->pr_res_key = dev->dev_pr_res_holder->pr_res_key; | ||
609 | if (dev->dev_pr_res_holder->pr_reg_nacl != sess->se_node_acl) { | ||
610 | spin_unlock(&dev->dev_reservation_lock); | ||
611 | return -EINVAL; | ||
612 | } | ||
613 | if (!dev->dev_pr_res_holder->isid_present_at_reg) { | ||
614 | spin_unlock(&dev->dev_reservation_lock); | ||
615 | return 0; | ||
616 | } | ||
617 | ret = (dev->dev_pr_res_holder->pr_reg_bin_isid == | ||
618 | sess->sess_bin_isid) ? 0 : -EINVAL; | ||
619 | /* | ||
620 | * Use bit in *pr_reg_type to notify ISID mismatch in | ||
621 | * core_scsi3_pr_seq_non_holder(). | ||
622 | */ | ||
623 | if (ret != 0) | ||
624 | *pr_reg_type |= 0x80000000; | ||
625 | spin_unlock(&dev->dev_reservation_lock); | ||
626 | |||
627 | return ret; | ||
628 | } | ||
629 | |||
630 | static struct t10_pr_registration *__core_scsi3_do_alloc_registration( | 581 | static struct t10_pr_registration *__core_scsi3_do_alloc_registration( |
631 | struct se_device *dev, | 582 | struct se_device *dev, |
632 | struct se_node_acl *nacl, | 583 | struct se_node_acl *nacl, |
@@ -636,7 +587,6 @@ static struct t10_pr_registration *__core_scsi3_do_alloc_registration( | |||
636 | int all_tg_pt, | 587 | int all_tg_pt, |
637 | int aptpl) | 588 | int aptpl) |
638 | { | 589 | { |
639 | struct se_subsystem_dev *su_dev = dev->se_sub_dev; | ||
640 | struct t10_pr_registration *pr_reg; | 590 | struct t10_pr_registration *pr_reg; |
641 | 591 | ||
642 | pr_reg = kmem_cache_zalloc(t10_pr_reg_cache, GFP_ATOMIC); | 592 | pr_reg = kmem_cache_zalloc(t10_pr_reg_cache, GFP_ATOMIC); |
@@ -645,7 +595,7 @@ static struct t10_pr_registration *__core_scsi3_do_alloc_registration( | |||
645 | return NULL; | 595 | return NULL; |
646 | } | 596 | } |
647 | 597 | ||
648 | pr_reg->pr_aptpl_buf = kzalloc(su_dev->t10_pr.pr_aptpl_buf_len, | 598 | pr_reg->pr_aptpl_buf = kzalloc(dev->t10_pr.pr_aptpl_buf_len, |
649 | GFP_ATOMIC); | 599 | GFP_ATOMIC); |
650 | if (!pr_reg->pr_aptpl_buf) { | 600 | if (!pr_reg->pr_aptpl_buf) { |
651 | pr_err("Unable to allocate pr_reg->pr_aptpl_buf\n"); | 601 | pr_err("Unable to allocate pr_reg->pr_aptpl_buf\n"); |
@@ -929,7 +879,7 @@ static int __core_scsi3_check_aptpl_registration( | |||
929 | struct se_dev_entry *deve) | 879 | struct se_dev_entry *deve) |
930 | { | 880 | { |
931 | struct t10_pr_registration *pr_reg, *pr_reg_tmp; | 881 | struct t10_pr_registration *pr_reg, *pr_reg_tmp; |
932 | struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr; | 882 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
933 | unsigned char i_port[PR_APTPL_MAX_IPORT_LEN]; | 883 | unsigned char i_port[PR_APTPL_MAX_IPORT_LEN]; |
934 | unsigned char t_port[PR_APTPL_MAX_TPORT_LEN]; | 884 | unsigned char t_port[PR_APTPL_MAX_TPORT_LEN]; |
935 | u16 tpgt; | 885 | u16 tpgt; |
@@ -996,11 +946,10 @@ int core_scsi3_check_aptpl_registration( | |||
996 | struct se_lun *lun, | 946 | struct se_lun *lun, |
997 | struct se_lun_acl *lun_acl) | 947 | struct se_lun_acl *lun_acl) |
998 | { | 948 | { |
999 | struct se_subsystem_dev *su_dev = dev->se_sub_dev; | ||
1000 | struct se_node_acl *nacl = lun_acl->se_lun_nacl; | 949 | struct se_node_acl *nacl = lun_acl->se_lun_nacl; |
1001 | struct se_dev_entry *deve = nacl->device_list[lun_acl->mapped_lun]; | 950 | struct se_dev_entry *deve = nacl->device_list[lun_acl->mapped_lun]; |
1002 | 951 | ||
1003 | if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS) | 952 | if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) |
1004 | return 0; | 953 | return 0; |
1005 | 954 | ||
1006 | return __core_scsi3_check_aptpl_registration(dev, tpg, lun, | 955 | return __core_scsi3_check_aptpl_registration(dev, tpg, lun, |
@@ -1051,10 +1000,9 @@ static void __core_scsi3_add_registration( | |||
1051 | int register_type, | 1000 | int register_type, |
1052 | int register_move) | 1001 | int register_move) |
1053 | { | 1002 | { |
1054 | struct se_subsystem_dev *su_dev = dev->se_sub_dev; | ||
1055 | struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo; | 1003 | struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo; |
1056 | struct t10_pr_registration *pr_reg_tmp, *pr_reg_tmp_safe; | 1004 | struct t10_pr_registration *pr_reg_tmp, *pr_reg_tmp_safe; |
1057 | struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr; | 1005 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
1058 | 1006 | ||
1059 | /* | 1007 | /* |
1060 | * Increment PRgeneration counter for struct se_device upon a successful | 1008 | * Increment PRgeneration counter for struct se_device upon a successful |
@@ -1066,7 +1014,7 @@ static void __core_scsi3_add_registration( | |||
1066 | * for the REGISTER. | 1014 | * for the REGISTER. |
1067 | */ | 1015 | */ |
1068 | pr_reg->pr_res_generation = (register_move) ? | 1016 | pr_reg->pr_res_generation = (register_move) ? |
1069 | su_dev->t10_pr.pr_generation++ : | 1017 | dev->t10_pr.pr_generation++ : |
1070 | core_scsi3_pr_generation(dev); | 1018 | core_scsi3_pr_generation(dev); |
1071 | 1019 | ||
1072 | spin_lock(&pr_tmpl->registration_lock); | 1020 | spin_lock(&pr_tmpl->registration_lock); |
@@ -1135,7 +1083,7 @@ static struct t10_pr_registration *__core_scsi3_locate_pr_reg( | |||
1135 | struct se_node_acl *nacl, | 1083 | struct se_node_acl *nacl, |
1136 | unsigned char *isid) | 1084 | unsigned char *isid) |
1137 | { | 1085 | { |
1138 | struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr; | 1086 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
1139 | struct t10_pr_registration *pr_reg, *pr_reg_tmp; | 1087 | struct t10_pr_registration *pr_reg, *pr_reg_tmp; |
1140 | struct se_portal_group *tpg; | 1088 | struct se_portal_group *tpg; |
1141 | 1089 | ||
@@ -1160,7 +1108,7 @@ static struct t10_pr_registration *__core_scsi3_locate_pr_reg( | |||
1160 | * for fabric modules (iSCSI) requiring them. | 1108 | * for fabric modules (iSCSI) requiring them. |
1161 | */ | 1109 | */ |
1162 | if (tpg->se_tpg_tfo->sess_get_initiator_sid != NULL) { | 1110 | if (tpg->se_tpg_tfo->sess_get_initiator_sid != NULL) { |
1163 | if (dev->se_sub_dev->se_dev_attrib.enforce_pr_isids) | 1111 | if (dev->dev_attrib.enforce_pr_isids) |
1164 | continue; | 1112 | continue; |
1165 | } | 1113 | } |
1166 | atomic_inc(&pr_reg->pr_res_holders); | 1114 | atomic_inc(&pr_reg->pr_res_holders); |
@@ -1274,7 +1222,7 @@ static void __core_scsi3_free_registration( | |||
1274 | { | 1222 | { |
1275 | struct target_core_fabric_ops *tfo = | 1223 | struct target_core_fabric_ops *tfo = |
1276 | pr_reg->pr_reg_nacl->se_tpg->se_tpg_tfo; | 1224 | pr_reg->pr_reg_nacl->se_tpg->se_tpg_tfo; |
1277 | struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr; | 1225 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
1278 | char i_buf[PR_REG_ISID_ID_LEN]; | 1226 | char i_buf[PR_REG_ISID_ID_LEN]; |
1279 | int prf_isid; | 1227 | int prf_isid; |
1280 | 1228 | ||
@@ -1335,7 +1283,7 @@ void core_scsi3_free_pr_reg_from_nacl( | |||
1335 | struct se_device *dev, | 1283 | struct se_device *dev, |
1336 | struct se_node_acl *nacl) | 1284 | struct se_node_acl *nacl) |
1337 | { | 1285 | { |
1338 | struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr; | 1286 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
1339 | struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_res_holder; | 1287 | struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_res_holder; |
1340 | /* | 1288 | /* |
1341 | * If the passed se_node_acl matches the reservation holder, | 1289 | * If the passed se_node_acl matches the reservation holder, |
@@ -1365,7 +1313,7 @@ void core_scsi3_free_pr_reg_from_nacl( | |||
1365 | void core_scsi3_free_all_registrations( | 1313 | void core_scsi3_free_all_registrations( |
1366 | struct se_device *dev) | 1314 | struct se_device *dev) |
1367 | { | 1315 | { |
1368 | struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr; | 1316 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
1369 | struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_res_holder; | 1317 | struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_res_holder; |
1370 | 1318 | ||
1371 | spin_lock(&dev->dev_reservation_lock); | 1319 | spin_lock(&dev->dev_reservation_lock); |
@@ -1479,7 +1427,8 @@ static void core_scsi3_lunacl_undepend_item(struct se_dev_entry *se_deve) | |||
1479 | smp_mb__after_atomic_dec(); | 1427 | smp_mb__after_atomic_dec(); |
1480 | } | 1428 | } |
1481 | 1429 | ||
1482 | static int core_scsi3_decode_spec_i_port( | 1430 | static sense_reason_t |
1431 | core_scsi3_decode_spec_i_port( | ||
1483 | struct se_cmd *cmd, | 1432 | struct se_cmd *cmd, |
1484 | struct se_portal_group *tpg, | 1433 | struct se_portal_group *tpg, |
1485 | unsigned char *l_isid, | 1434 | unsigned char *l_isid, |
@@ -1501,8 +1450,9 @@ static int core_scsi3_decode_spec_i_port( | |||
1501 | unsigned char *buf; | 1450 | unsigned char *buf; |
1502 | unsigned char *ptr, *i_str = NULL, proto_ident, tmp_proto_ident; | 1451 | unsigned char *ptr, *i_str = NULL, proto_ident, tmp_proto_ident; |
1503 | char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN]; | 1452 | char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN]; |
1453 | sense_reason_t ret; | ||
1504 | u32 tpdl, tid_len = 0; | 1454 | u32 tpdl, tid_len = 0; |
1505 | int ret, dest_local_nexus, prf_isid; | 1455 | int dest_local_nexus, prf_isid; |
1506 | u32 dest_rtpi = 0; | 1456 | u32 dest_rtpi = 0; |
1507 | 1457 | ||
1508 | memset(dest_iport, 0, 64); | 1458 | memset(dest_iport, 0, 64); |
@@ -1517,8 +1467,7 @@ static int core_scsi3_decode_spec_i_port( | |||
1517 | tidh_new = kzalloc(sizeof(struct pr_transport_id_holder), GFP_KERNEL); | 1467 | tidh_new = kzalloc(sizeof(struct pr_transport_id_holder), GFP_KERNEL); |
1518 | if (!tidh_new) { | 1468 | if (!tidh_new) { |
1519 | pr_err("Unable to allocate tidh_new\n"); | 1469 | pr_err("Unable to allocate tidh_new\n"); |
1520 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1470 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1521 | return -EINVAL; | ||
1522 | } | 1471 | } |
1523 | INIT_LIST_HEAD(&tidh_new->dest_list); | 1472 | INIT_LIST_HEAD(&tidh_new->dest_list); |
1524 | tidh_new->dest_tpg = tpg; | 1473 | tidh_new->dest_tpg = tpg; |
@@ -1530,8 +1479,7 @@ static int core_scsi3_decode_spec_i_port( | |||
1530 | sa_res_key, all_tg_pt, aptpl); | 1479 | sa_res_key, all_tg_pt, aptpl); |
1531 | if (!local_pr_reg) { | 1480 | if (!local_pr_reg) { |
1532 | kfree(tidh_new); | 1481 | kfree(tidh_new); |
1533 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1482 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1534 | return -ENOMEM; | ||
1535 | } | 1483 | } |
1536 | tidh_new->dest_pr_reg = local_pr_reg; | 1484 | tidh_new->dest_pr_reg = local_pr_reg; |
1537 | /* | 1485 | /* |
@@ -1545,12 +1493,16 @@ static int core_scsi3_decode_spec_i_port( | |||
1545 | if (cmd->data_length < 28) { | 1493 | if (cmd->data_length < 28) { |
1546 | pr_warn("SPC-PR: Received PR OUT parameter list" | 1494 | pr_warn("SPC-PR: Received PR OUT parameter list" |
1547 | " length too small: %u\n", cmd->data_length); | 1495 | " length too small: %u\n", cmd->data_length); |
1548 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 1496 | ret = TCM_INVALID_PARAMETER_LIST; |
1549 | ret = -EINVAL; | ||
1550 | goto out; | 1497 | goto out; |
1551 | } | 1498 | } |
1552 | 1499 | ||
1553 | buf = transport_kmap_data_sg(cmd); | 1500 | buf = transport_kmap_data_sg(cmd); |
1501 | if (!buf) { | ||
1502 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1503 | goto out; | ||
1504 | } | ||
1505 | |||
1554 | /* | 1506 | /* |
1555 | * For a PERSISTENT RESERVE OUT specify initiator ports payload, | 1507 | * For a PERSISTENT RESERVE OUT specify initiator ports payload, |
1556 | * first extract TransportID Parameter Data Length, and make sure | 1508 | * first extract TransportID Parameter Data Length, and make sure |
@@ -1565,9 +1517,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1565 | pr_err("SPC-3 PR: Illegal tpdl: %u + 28 byte header" | 1517 | pr_err("SPC-3 PR: Illegal tpdl: %u + 28 byte header" |
1566 | " does not equal CDB data_length: %u\n", tpdl, | 1518 | " does not equal CDB data_length: %u\n", tpdl, |
1567 | cmd->data_length); | 1519 | cmd->data_length); |
1568 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 1520 | ret = TCM_INVALID_PARAMETER_LIST; |
1569 | ret = -EINVAL; | 1521 | goto out_unmap; |
1570 | goto out; | ||
1571 | } | 1522 | } |
1572 | /* | 1523 | /* |
1573 | * Start processing the received transport IDs using the | 1524 | * Start processing the received transport IDs using the |
@@ -1610,16 +1561,13 @@ static int core_scsi3_decode_spec_i_port( | |||
1610 | smp_mb__after_atomic_inc(); | 1561 | smp_mb__after_atomic_inc(); |
1611 | spin_unlock(&dev->se_port_lock); | 1562 | spin_unlock(&dev->se_port_lock); |
1612 | 1563 | ||
1613 | ret = core_scsi3_tpg_depend_item(tmp_tpg); | 1564 | if (core_scsi3_tpg_depend_item(tmp_tpg)) { |
1614 | if (ret != 0) { | ||
1615 | pr_err(" core_scsi3_tpg_depend_item()" | 1565 | pr_err(" core_scsi3_tpg_depend_item()" |
1616 | " for tmp_tpg\n"); | 1566 | " for tmp_tpg\n"); |
1617 | atomic_dec(&tmp_tpg->tpg_pr_ref_count); | 1567 | atomic_dec(&tmp_tpg->tpg_pr_ref_count); |
1618 | smp_mb__after_atomic_dec(); | 1568 | smp_mb__after_atomic_dec(); |
1619 | cmd->scsi_sense_reason = | 1569 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1620 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1570 | goto out_unmap; |
1621 | ret = -EINVAL; | ||
1622 | goto out; | ||
1623 | } | 1571 | } |
1624 | /* | 1572 | /* |
1625 | * Locate the destination initiator ACL to be registered | 1573 | * Locate the destination initiator ACL to be registered |
@@ -1641,17 +1589,14 @@ static int core_scsi3_decode_spec_i_port( | |||
1641 | continue; | 1589 | continue; |
1642 | } | 1590 | } |
1643 | 1591 | ||
1644 | ret = core_scsi3_nodeacl_depend_item(dest_node_acl); | 1592 | if (core_scsi3_nodeacl_depend_item(dest_node_acl)) { |
1645 | if (ret != 0) { | ||
1646 | pr_err("configfs_depend_item() failed" | 1593 | pr_err("configfs_depend_item() failed" |
1647 | " for dest_node_acl->acl_group\n"); | 1594 | " for dest_node_acl->acl_group\n"); |
1648 | atomic_dec(&dest_node_acl->acl_pr_ref_count); | 1595 | atomic_dec(&dest_node_acl->acl_pr_ref_count); |
1649 | smp_mb__after_atomic_dec(); | 1596 | smp_mb__after_atomic_dec(); |
1650 | core_scsi3_tpg_undepend_item(tmp_tpg); | 1597 | core_scsi3_tpg_undepend_item(tmp_tpg); |
1651 | cmd->scsi_sense_reason = | 1598 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1652 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1599 | goto out_unmap; |
1653 | ret = -EINVAL; | ||
1654 | goto out; | ||
1655 | } | 1600 | } |
1656 | 1601 | ||
1657 | dest_tpg = tmp_tpg; | 1602 | dest_tpg = tmp_tpg; |
@@ -1668,9 +1613,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1668 | if (!dest_tpg) { | 1613 | if (!dest_tpg) { |
1669 | pr_err("SPC-3 PR SPEC_I_PT: Unable to locate" | 1614 | pr_err("SPC-3 PR SPEC_I_PT: Unable to locate" |
1670 | " dest_tpg\n"); | 1615 | " dest_tpg\n"); |
1671 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 1616 | ret = TCM_INVALID_PARAMETER_LIST; |
1672 | ret = -EINVAL; | 1617 | goto out_unmap; |
1673 | goto out; | ||
1674 | } | 1618 | } |
1675 | 1619 | ||
1676 | pr_debug("SPC-3 PR SPEC_I_PT: Got %s data_length: %u tpdl: %u" | 1620 | pr_debug("SPC-3 PR SPEC_I_PT: Got %s data_length: %u tpdl: %u" |
@@ -1683,9 +1627,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1683 | " %u for Transport ID: %s\n", tid_len, ptr); | 1627 | " %u for Transport ID: %s\n", tid_len, ptr); |
1684 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1628 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
1685 | core_scsi3_tpg_undepend_item(dest_tpg); | 1629 | core_scsi3_tpg_undepend_item(dest_tpg); |
1686 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 1630 | ret = TCM_INVALID_PARAMETER_LIST; |
1687 | ret = -EINVAL; | 1631 | goto out_unmap; |
1688 | goto out; | ||
1689 | } | 1632 | } |
1690 | /* | 1633 | /* |
1691 | * Locate the desintation struct se_dev_entry pointer for matching | 1634 | * Locate the desintation struct se_dev_entry pointer for matching |
@@ -1702,23 +1645,19 @@ static int core_scsi3_decode_spec_i_port( | |||
1702 | 1645 | ||
1703 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1646 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
1704 | core_scsi3_tpg_undepend_item(dest_tpg); | 1647 | core_scsi3_tpg_undepend_item(dest_tpg); |
1705 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 1648 | ret = TCM_INVALID_PARAMETER_LIST; |
1706 | ret = -EINVAL; | 1649 | goto out_unmap; |
1707 | goto out; | ||
1708 | } | 1650 | } |
1709 | 1651 | ||
1710 | ret = core_scsi3_lunacl_depend_item(dest_se_deve); | 1652 | if (core_scsi3_lunacl_depend_item(dest_se_deve)) { |
1711 | if (ret < 0) { | ||
1712 | pr_err("core_scsi3_lunacl_depend_item()" | 1653 | pr_err("core_scsi3_lunacl_depend_item()" |
1713 | " failed\n"); | 1654 | " failed\n"); |
1714 | atomic_dec(&dest_se_deve->pr_ref_count); | 1655 | atomic_dec(&dest_se_deve->pr_ref_count); |
1715 | smp_mb__after_atomic_dec(); | 1656 | smp_mb__after_atomic_dec(); |
1716 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1657 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
1717 | core_scsi3_tpg_undepend_item(dest_tpg); | 1658 | core_scsi3_tpg_undepend_item(dest_tpg); |
1718 | cmd->scsi_sense_reason = | 1659 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1719 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1660 | goto out_unmap; |
1720 | ret = -EINVAL; | ||
1721 | goto out; | ||
1722 | } | 1661 | } |
1723 | 1662 | ||
1724 | pr_debug("SPC-3 PR SPEC_I_PT: Located %s Node: %s" | 1663 | pr_debug("SPC-3 PR SPEC_I_PT: Located %s Node: %s" |
@@ -1754,10 +1693,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1754 | core_scsi3_lunacl_undepend_item(dest_se_deve); | 1693 | core_scsi3_lunacl_undepend_item(dest_se_deve); |
1755 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1694 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
1756 | core_scsi3_tpg_undepend_item(dest_tpg); | 1695 | core_scsi3_tpg_undepend_item(dest_tpg); |
1757 | cmd->scsi_sense_reason = | 1696 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1758 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1697 | goto out_unmap; |
1759 | ret = -ENOMEM; | ||
1760 | goto out; | ||
1761 | } | 1698 | } |
1762 | INIT_LIST_HEAD(&tidh_new->dest_list); | 1699 | INIT_LIST_HEAD(&tidh_new->dest_list); |
1763 | tidh_new->dest_tpg = dest_tpg; | 1700 | tidh_new->dest_tpg = dest_tpg; |
@@ -1788,9 +1725,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1788 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1725 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
1789 | core_scsi3_tpg_undepend_item(dest_tpg); | 1726 | core_scsi3_tpg_undepend_item(dest_tpg); |
1790 | kfree(tidh_new); | 1727 | kfree(tidh_new); |
1791 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 1728 | ret = TCM_INVALID_PARAMETER_LIST; |
1792 | ret = -EINVAL; | 1729 | goto out_unmap; |
1793 | goto out; | ||
1794 | } | 1730 | } |
1795 | tidh_new->dest_pr_reg = dest_pr_reg; | 1731 | tidh_new->dest_pr_reg = dest_pr_reg; |
1796 | list_add_tail(&tidh_new->dest_list, &tid_dest_list); | 1732 | list_add_tail(&tidh_new->dest_list, &tid_dest_list); |
@@ -1848,8 +1784,9 @@ static int core_scsi3_decode_spec_i_port( | |||
1848 | } | 1784 | } |
1849 | 1785 | ||
1850 | return 0; | 1786 | return 0; |
1851 | out: | 1787 | out_unmap: |
1852 | transport_kunmap_data_sg(cmd); | 1788 | transport_kunmap_data_sg(cmd); |
1789 | out: | ||
1853 | /* | 1790 | /* |
1854 | * For the failure case, release everything from tid_dest_list | 1791 | * For the failure case, release everything from tid_dest_list |
1855 | * including *dest_pr_reg and the configfs dependances.. | 1792 | * including *dest_pr_reg and the configfs dependances.. |
@@ -1899,7 +1836,6 @@ static int __core_scsi3_update_aptpl_buf( | |||
1899 | { | 1836 | { |
1900 | struct se_lun *lun; | 1837 | struct se_lun *lun; |
1901 | struct se_portal_group *tpg; | 1838 | struct se_portal_group *tpg; |
1902 | struct se_subsystem_dev *su_dev = dev->se_sub_dev; | ||
1903 | struct t10_pr_registration *pr_reg; | 1839 | struct t10_pr_registration *pr_reg; |
1904 | unsigned char tmp[512], isid_buf[32]; | 1840 | unsigned char tmp[512], isid_buf[32]; |
1905 | ssize_t len = 0; | 1841 | ssize_t len = 0; |
@@ -1917,8 +1853,8 @@ static int __core_scsi3_update_aptpl_buf( | |||
1917 | /* | 1853 | /* |
1918 | * Walk the registration list.. | 1854 | * Walk the registration list.. |
1919 | */ | 1855 | */ |
1920 | spin_lock(&su_dev->t10_pr.registration_lock); | 1856 | spin_lock(&dev->t10_pr.registration_lock); |
1921 | list_for_each_entry(pr_reg, &su_dev->t10_pr.registration_list, | 1857 | list_for_each_entry(pr_reg, &dev->t10_pr.registration_list, |
1922 | pr_reg_list) { | 1858 | pr_reg_list) { |
1923 | 1859 | ||
1924 | tmp[0] = '\0'; | 1860 | tmp[0] = '\0'; |
@@ -1963,7 +1899,7 @@ static int __core_scsi3_update_aptpl_buf( | |||
1963 | if ((len + strlen(tmp) >= pr_aptpl_buf_len)) { | 1899 | if ((len + strlen(tmp) >= pr_aptpl_buf_len)) { |
1964 | pr_err("Unable to update renaming" | 1900 | pr_err("Unable to update renaming" |
1965 | " APTPL metadata\n"); | 1901 | " APTPL metadata\n"); |
1966 | spin_unlock(&su_dev->t10_pr.registration_lock); | 1902 | spin_unlock(&dev->t10_pr.registration_lock); |
1967 | return -EMSGSIZE; | 1903 | return -EMSGSIZE; |
1968 | } | 1904 | } |
1969 | len += sprintf(buf+len, "%s", tmp); | 1905 | len += sprintf(buf+len, "%s", tmp); |
@@ -1981,13 +1917,13 @@ static int __core_scsi3_update_aptpl_buf( | |||
1981 | if ((len + strlen(tmp) >= pr_aptpl_buf_len)) { | 1917 | if ((len + strlen(tmp) >= pr_aptpl_buf_len)) { |
1982 | pr_err("Unable to update renaming" | 1918 | pr_err("Unable to update renaming" |
1983 | " APTPL metadata\n"); | 1919 | " APTPL metadata\n"); |
1984 | spin_unlock(&su_dev->t10_pr.registration_lock); | 1920 | spin_unlock(&dev->t10_pr.registration_lock); |
1985 | return -EMSGSIZE; | 1921 | return -EMSGSIZE; |
1986 | } | 1922 | } |
1987 | len += sprintf(buf+len, "%s", tmp); | 1923 | len += sprintf(buf+len, "%s", tmp); |
1988 | reg_count++; | 1924 | reg_count++; |
1989 | } | 1925 | } |
1990 | spin_unlock(&su_dev->t10_pr.registration_lock); | 1926 | spin_unlock(&dev->t10_pr.registration_lock); |
1991 | 1927 | ||
1992 | if (!reg_count) | 1928 | if (!reg_count) |
1993 | len += sprintf(buf+len, "No Registrations or Reservations"); | 1929 | len += sprintf(buf+len, "No Registrations or Reservations"); |
@@ -2019,7 +1955,7 @@ static int __core_scsi3_write_aptpl_to_file( | |||
2019 | unsigned char *buf, | 1955 | unsigned char *buf, |
2020 | u32 pr_aptpl_buf_len) | 1956 | u32 pr_aptpl_buf_len) |
2021 | { | 1957 | { |
2022 | struct t10_wwn *wwn = &dev->se_sub_dev->t10_wwn; | 1958 | struct t10_wwn *wwn = &dev->t10_wwn; |
2023 | struct file *file; | 1959 | struct file *file; |
2024 | struct iovec iov[1]; | 1960 | struct iovec iov[1]; |
2025 | mm_segment_t old_fs; | 1961 | mm_segment_t old_fs; |
@@ -2065,14 +2001,15 @@ static int __core_scsi3_write_aptpl_to_file( | |||
2065 | return 0; | 2001 | return 0; |
2066 | } | 2002 | } |
2067 | 2003 | ||
2068 | static int core_scsi3_update_and_write_aptpl( | 2004 | static int |
2069 | struct se_device *dev, | 2005 | core_scsi3_update_and_write_aptpl(struct se_device *dev, unsigned char *in_buf, |
2070 | unsigned char *in_buf, | 2006 | u32 in_pr_aptpl_buf_len) |
2071 | u32 in_pr_aptpl_buf_len) | ||
2072 | { | 2007 | { |
2073 | unsigned char null_buf[64], *buf; | 2008 | unsigned char null_buf[64], *buf; |
2074 | u32 pr_aptpl_buf_len; | 2009 | u32 pr_aptpl_buf_len; |
2075 | int ret, clear_aptpl_metadata = 0; | 2010 | int clear_aptpl_metadata = 0; |
2011 | int ret; | ||
2012 | |||
2076 | /* | 2013 | /* |
2077 | * Can be called with a NULL pointer from PROUT service action CLEAR | 2014 | * Can be called with a NULL pointer from PROUT service action CLEAR |
2078 | */ | 2015 | */ |
@@ -2094,25 +2031,17 @@ static int core_scsi3_update_and_write_aptpl( | |||
2094 | clear_aptpl_metadata); | 2031 | clear_aptpl_metadata); |
2095 | if (ret != 0) | 2032 | if (ret != 0) |
2096 | return ret; | 2033 | return ret; |
2034 | |||
2097 | /* | 2035 | /* |
2098 | * __core_scsi3_write_aptpl_to_file() will call strlen() | 2036 | * __core_scsi3_write_aptpl_to_file() will call strlen() |
2099 | * on the passed buf to determine pr_aptpl_buf_len. | 2037 | * on the passed buf to determine pr_aptpl_buf_len. |
2100 | */ | 2038 | */ |
2101 | ret = __core_scsi3_write_aptpl_to_file(dev, buf, 0); | 2039 | return __core_scsi3_write_aptpl_to_file(dev, buf, 0); |
2102 | if (ret != 0) | ||
2103 | return ret; | ||
2104 | |||
2105 | return ret; | ||
2106 | } | 2040 | } |
2107 | 2041 | ||
2108 | static int core_scsi3_emulate_pro_register( | 2042 | static sense_reason_t |
2109 | struct se_cmd *cmd, | 2043 | core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, |
2110 | u64 res_key, | 2044 | int aptpl, int all_tg_pt, int spec_i_pt, int ignore_key) |
2111 | u64 sa_res_key, | ||
2112 | int aptpl, | ||
2113 | int all_tg_pt, | ||
2114 | int spec_i_pt, | ||
2115 | int ignore_key) | ||
2116 | { | 2045 | { |
2117 | struct se_session *se_sess = cmd->se_sess; | 2046 | struct se_session *se_sess = cmd->se_sess; |
2118 | struct se_device *dev = cmd->se_dev; | 2047 | struct se_device *dev = cmd->se_dev; |
@@ -2120,16 +2049,16 @@ static int core_scsi3_emulate_pro_register( | |||
2120 | struct se_lun *se_lun = cmd->se_lun; | 2049 | struct se_lun *se_lun = cmd->se_lun; |
2121 | struct se_portal_group *se_tpg; | 2050 | struct se_portal_group *se_tpg; |
2122 | struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_reg_tmp, *pr_reg_e; | 2051 | struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_reg_tmp, *pr_reg_e; |
2123 | struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr; | 2052 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
2124 | /* Used for APTPL metadata w/ UNREGISTER */ | 2053 | /* Used for APTPL metadata w/ UNREGISTER */ |
2125 | unsigned char *pr_aptpl_buf = NULL; | 2054 | unsigned char *pr_aptpl_buf = NULL; |
2126 | unsigned char isid_buf[PR_REG_ISID_LEN], *isid_ptr = NULL; | 2055 | unsigned char isid_buf[PR_REG_ISID_LEN], *isid_ptr = NULL; |
2127 | int pr_holder = 0, ret = 0, type; | 2056 | sense_reason_t ret = TCM_NO_SENSE; |
2057 | int pr_holder = 0, type; | ||
2128 | 2058 | ||
2129 | if (!se_sess || !se_lun) { | 2059 | if (!se_sess || !se_lun) { |
2130 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); | 2060 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); |
2131 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 2061 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2132 | return -EINVAL; | ||
2133 | } | 2062 | } |
2134 | se_tpg = se_sess->se_tpg; | 2063 | se_tpg = se_sess->se_tpg; |
2135 | se_deve = se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; | 2064 | se_deve = se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; |
@@ -2148,8 +2077,7 @@ static int core_scsi3_emulate_pro_register( | |||
2148 | if (res_key) { | 2077 | if (res_key) { |
2149 | pr_warn("SPC-3 PR: Reservation Key non-zero" | 2078 | pr_warn("SPC-3 PR: Reservation Key non-zero" |
2150 | " for SA REGISTER, returning CONFLICT\n"); | 2079 | " for SA REGISTER, returning CONFLICT\n"); |
2151 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2080 | return TCM_RESERVATION_CONFLICT; |
2152 | return -EINVAL; | ||
2153 | } | 2081 | } |
2154 | /* | 2082 | /* |
2155 | * Do nothing but return GOOD status. | 2083 | * Do nothing but return GOOD status. |
@@ -2163,15 +2091,13 @@ static int core_scsi3_emulate_pro_register( | |||
2163 | * Port Endpoint that the PRO was received from on the | 2091 | * Port Endpoint that the PRO was received from on the |
2164 | * Logical Unit of the SCSI device server. | 2092 | * Logical Unit of the SCSI device server. |
2165 | */ | 2093 | */ |
2166 | ret = core_scsi3_alloc_registration(cmd->se_dev, | 2094 | if (core_scsi3_alloc_registration(cmd->se_dev, |
2167 | se_sess->se_node_acl, se_deve, isid_ptr, | 2095 | se_sess->se_node_acl, se_deve, isid_ptr, |
2168 | sa_res_key, all_tg_pt, aptpl, | 2096 | sa_res_key, all_tg_pt, aptpl, |
2169 | ignore_key, 0); | 2097 | ignore_key, 0)) { |
2170 | if (ret != 0) { | ||
2171 | pr_err("Unable to allocate" | 2098 | pr_err("Unable to allocate" |
2172 | " struct t10_pr_registration\n"); | 2099 | " struct t10_pr_registration\n"); |
2173 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 2100 | return TCM_INVALID_PARAMETER_LIST; |
2174 | return -EINVAL; | ||
2175 | } | 2101 | } |
2176 | } else { | 2102 | } else { |
2177 | /* | 2103 | /* |
@@ -2205,201 +2131,192 @@ static int core_scsi3_emulate_pro_register( | |||
2205 | pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, | 2131 | pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, |
2206 | se_sess->se_node_acl, se_sess); | 2132 | se_sess->se_node_acl, se_sess); |
2207 | 2133 | ||
2208 | ret = core_scsi3_update_and_write_aptpl(cmd->se_dev, | 2134 | if (core_scsi3_update_and_write_aptpl(cmd->se_dev, |
2209 | &pr_reg->pr_aptpl_buf[0], | 2135 | &pr_reg->pr_aptpl_buf[0], |
2210 | pr_tmpl->pr_aptpl_buf_len); | 2136 | pr_tmpl->pr_aptpl_buf_len)) { |
2211 | if (!ret) { | ||
2212 | pr_tmpl->pr_aptpl_active = 1; | 2137 | pr_tmpl->pr_aptpl_active = 1; |
2213 | pr_debug("SPC-3 PR: Set APTPL Bit Activated for REGISTER\n"); | 2138 | pr_debug("SPC-3 PR: Set APTPL Bit Activated for REGISTER\n"); |
2214 | } | 2139 | } |
2215 | 2140 | ||
2216 | core_scsi3_put_pr_reg(pr_reg); | 2141 | goto out_put_pr_reg; |
2217 | return ret; | 2142 | } |
2218 | } else { | 2143 | |
2219 | /* | 2144 | /* |
2220 | * Locate the existing *pr_reg via struct se_node_acl pointers | 2145 | * Locate the existing *pr_reg via struct se_node_acl pointers |
2221 | */ | 2146 | */ |
2222 | pr_reg = pr_reg_e; | 2147 | pr_reg = pr_reg_e; |
2223 | type = pr_reg->pr_res_type; | 2148 | type = pr_reg->pr_res_type; |
2224 | 2149 | ||
2225 | if (!ignore_key) { | 2150 | if (!ignore_key) { |
2226 | if (res_key != pr_reg->pr_res_key) { | 2151 | if (res_key != pr_reg->pr_res_key) { |
2227 | pr_err("SPC-3 PR REGISTER: Received" | 2152 | pr_err("SPC-3 PR REGISTER: Received" |
2228 | " res_key: 0x%016Lx does not match" | 2153 | " res_key: 0x%016Lx does not match" |
2229 | " existing SA REGISTER res_key:" | 2154 | " existing SA REGISTER res_key:" |
2230 | " 0x%016Lx\n", res_key, | 2155 | " 0x%016Lx\n", res_key, |
2231 | pr_reg->pr_res_key); | 2156 | pr_reg->pr_res_key); |
2232 | core_scsi3_put_pr_reg(pr_reg); | 2157 | ret = TCM_RESERVATION_CONFLICT; |
2233 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2158 | goto out_put_pr_reg; |
2234 | return -EINVAL; | ||
2235 | } | ||
2236 | } | 2159 | } |
2237 | if (spec_i_pt) { | 2160 | } |
2238 | pr_err("SPC-3 PR UNREGISTER: SPEC_I_PT" | 2161 | |
2239 | " set while sa_res_key=0\n"); | 2162 | if (spec_i_pt) { |
2240 | core_scsi3_put_pr_reg(pr_reg); | 2163 | pr_err("SPC-3 PR UNREGISTER: SPEC_I_PT" |
2241 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 2164 | " set while sa_res_key=0\n"); |
2242 | return -EINVAL; | 2165 | ret = TCM_INVALID_PARAMETER_LIST; |
2166 | goto out_put_pr_reg; | ||
2167 | } | ||
2168 | |||
2169 | /* | ||
2170 | * An existing ALL_TG_PT=1 registration being released | ||
2171 | * must also set ALL_TG_PT=1 in the incoming PROUT. | ||
2172 | */ | ||
2173 | if (pr_reg->pr_reg_all_tg_pt && !(all_tg_pt)) { | ||
2174 | pr_err("SPC-3 PR UNREGISTER: ALL_TG_PT=1" | ||
2175 | " registration exists, but ALL_TG_PT=1 bit not" | ||
2176 | " present in received PROUT\n"); | ||
2177 | ret = TCM_INVALID_CDB_FIELD; | ||
2178 | goto out_put_pr_reg; | ||
2179 | } | ||
2180 | |||
2181 | /* | ||
2182 | * Allocate APTPL metadata buffer used for UNREGISTER ops | ||
2183 | */ | ||
2184 | if (aptpl) { | ||
2185 | pr_aptpl_buf = kzalloc(pr_tmpl->pr_aptpl_buf_len, | ||
2186 | GFP_KERNEL); | ||
2187 | if (!pr_aptpl_buf) { | ||
2188 | pr_err("Unable to allocate" | ||
2189 | " pr_aptpl_buf\n"); | ||
2190 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
2191 | goto out_put_pr_reg; | ||
2243 | } | 2192 | } |
2244 | /* | 2193 | } |
2245 | * An existing ALL_TG_PT=1 registration being released | 2194 | |
2246 | * must also set ALL_TG_PT=1 in the incoming PROUT. | 2195 | /* |
2247 | */ | 2196 | * sa_res_key=0 Unregister Reservation Key for registered I_T |
2248 | if (pr_reg->pr_reg_all_tg_pt && !(all_tg_pt)) { | 2197 | * Nexus sa_res_key=1 Change Reservation Key for registered I_T |
2249 | pr_err("SPC-3 PR UNREGISTER: ALL_TG_PT=1" | 2198 | * Nexus. |
2250 | " registration exists, but ALL_TG_PT=1 bit not" | 2199 | */ |
2251 | " present in received PROUT\n"); | 2200 | if (!sa_res_key) { |
2252 | core_scsi3_put_pr_reg(pr_reg); | 2201 | pr_holder = core_scsi3_check_implict_release( |
2253 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 2202 | cmd->se_dev, pr_reg); |
2254 | return -EINVAL; | 2203 | if (pr_holder < 0) { |
2204 | kfree(pr_aptpl_buf); | ||
2205 | ret = TCM_RESERVATION_CONFLICT; | ||
2206 | goto out_put_pr_reg; | ||
2255 | } | 2207 | } |
2208 | |||
2209 | spin_lock(&pr_tmpl->registration_lock); | ||
2256 | /* | 2210 | /* |
2257 | * Allocate APTPL metadata buffer used for UNREGISTER ops | 2211 | * Release all ALL_TG_PT=1 for the matching SCSI Initiator Port |
2212 | * and matching pr_res_key. | ||
2258 | */ | 2213 | */ |
2259 | if (aptpl) { | 2214 | if (pr_reg->pr_reg_all_tg_pt) { |
2260 | pr_aptpl_buf = kzalloc(pr_tmpl->pr_aptpl_buf_len, | 2215 | list_for_each_entry_safe(pr_reg_p, pr_reg_tmp, |
2261 | GFP_KERNEL); | 2216 | &pr_tmpl->registration_list, |
2262 | if (!pr_aptpl_buf) { | 2217 | pr_reg_list) { |
2263 | pr_err("Unable to allocate" | 2218 | |
2264 | " pr_aptpl_buf\n"); | 2219 | if (!pr_reg_p->pr_reg_all_tg_pt) |
2265 | core_scsi3_put_pr_reg(pr_reg); | 2220 | continue; |
2266 | cmd->scsi_sense_reason = | 2221 | if (pr_reg_p->pr_res_key != res_key) |
2267 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 2222 | continue; |
2268 | return -EINVAL; | 2223 | if (pr_reg == pr_reg_p) |
2224 | continue; | ||
2225 | if (strcmp(pr_reg->pr_reg_nacl->initiatorname, | ||
2226 | pr_reg_p->pr_reg_nacl->initiatorname)) | ||
2227 | continue; | ||
2228 | |||
2229 | __core_scsi3_free_registration(dev, | ||
2230 | pr_reg_p, NULL, 0); | ||
2269 | } | 2231 | } |
2270 | } | 2232 | } |
2233 | |||
2271 | /* | 2234 | /* |
2272 | * sa_res_key=0 Unregister Reservation Key for registered I_T | 2235 | * Release the calling I_T Nexus registration now.. |
2273 | * Nexus sa_res_key=1 Change Reservation Key for registered I_T | ||
2274 | * Nexus. | ||
2275 | */ | 2236 | */ |
2276 | if (!sa_res_key) { | 2237 | __core_scsi3_free_registration(cmd->se_dev, pr_reg, NULL, 1); |
2277 | pr_holder = core_scsi3_check_implict_release( | ||
2278 | cmd->se_dev, pr_reg); | ||
2279 | if (pr_holder < 0) { | ||
2280 | kfree(pr_aptpl_buf); | ||
2281 | core_scsi3_put_pr_reg(pr_reg); | ||
2282 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | ||
2283 | return -EINVAL; | ||
2284 | } | ||
2285 | |||
2286 | spin_lock(&pr_tmpl->registration_lock); | ||
2287 | /* | ||
2288 | * Release all ALL_TG_PT=1 for the matching SCSI Initiator Port | ||
2289 | * and matching pr_res_key. | ||
2290 | */ | ||
2291 | if (pr_reg->pr_reg_all_tg_pt) { | ||
2292 | list_for_each_entry_safe(pr_reg_p, pr_reg_tmp, | ||
2293 | &pr_tmpl->registration_list, | ||
2294 | pr_reg_list) { | ||
2295 | |||
2296 | if (!pr_reg_p->pr_reg_all_tg_pt) | ||
2297 | continue; | ||
2298 | 2238 | ||
2299 | if (pr_reg_p->pr_res_key != res_key) | 2239 | /* |
2300 | continue; | 2240 | * From spc4r17, section 5.7.11.3 Unregistering |
2301 | 2241 | * | |
2302 | if (pr_reg == pr_reg_p) | 2242 | * If the persistent reservation is a registrants only |
2303 | continue; | 2243 | * type, the device server shall establish a unit |
2304 | 2244 | * attention condition for the initiator port associated | |
2305 | if (strcmp(pr_reg->pr_reg_nacl->initiatorname, | 2245 | * with every registered I_T nexus except for the I_T |
2306 | pr_reg_p->pr_reg_nacl->initiatorname)) | 2246 | * nexus on which the PERSISTENT RESERVE OUT command was |
2307 | continue; | 2247 | * received, with the additional sense code set to |
2308 | 2248 | * RESERVATIONS RELEASED. | |
2309 | __core_scsi3_free_registration(dev, | 2249 | */ |
2310 | pr_reg_p, NULL, 0); | 2250 | if (pr_holder && |
2311 | } | 2251 | (type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY || |
2312 | } | 2252 | type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY)) { |
2313 | /* | 2253 | list_for_each_entry(pr_reg_p, |
2314 | * Release the calling I_T Nexus registration now.. | 2254 | &pr_tmpl->registration_list, |
2315 | */ | 2255 | pr_reg_list) { |
2316 | __core_scsi3_free_registration(cmd->se_dev, pr_reg, | 2256 | |
2317 | NULL, 1); | 2257 | core_scsi3_ua_allocate( |
2318 | /* | 2258 | pr_reg_p->pr_reg_nacl, |
2319 | * From spc4r17, section 5.7.11.3 Unregistering | 2259 | pr_reg_p->pr_res_mapped_lun, |
2320 | * | 2260 | 0x2A, |
2321 | * If the persistent reservation is a registrants only | 2261 | ASCQ_2AH_RESERVATIONS_RELEASED); |
2322 | * type, the device server shall establish a unit | ||
2323 | * attention condition for the initiator port associated | ||
2324 | * with every registered I_T nexus except for the I_T | ||
2325 | * nexus on which the PERSISTENT RESERVE OUT command was | ||
2326 | * received, with the additional sense code set to | ||
2327 | * RESERVATIONS RELEASED. | ||
2328 | */ | ||
2329 | if (pr_holder && | ||
2330 | ((type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY) || | ||
2331 | (type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY))) { | ||
2332 | list_for_each_entry(pr_reg_p, | ||
2333 | &pr_tmpl->registration_list, | ||
2334 | pr_reg_list) { | ||
2335 | |||
2336 | core_scsi3_ua_allocate( | ||
2337 | pr_reg_p->pr_reg_nacl, | ||
2338 | pr_reg_p->pr_res_mapped_lun, | ||
2339 | 0x2A, | ||
2340 | ASCQ_2AH_RESERVATIONS_RELEASED); | ||
2341 | } | ||
2342 | } | 2262 | } |
2343 | spin_unlock(&pr_tmpl->registration_lock); | 2263 | } |
2264 | spin_unlock(&pr_tmpl->registration_lock); | ||
2344 | 2265 | ||
2345 | if (!aptpl) { | 2266 | if (!aptpl) { |
2346 | pr_tmpl->pr_aptpl_active = 0; | 2267 | pr_tmpl->pr_aptpl_active = 0; |
2347 | core_scsi3_update_and_write_aptpl(dev, NULL, 0); | 2268 | core_scsi3_update_and_write_aptpl(dev, NULL, 0); |
2348 | pr_debug("SPC-3 PR: Set APTPL Bit Deactivated" | 2269 | pr_debug("SPC-3 PR: Set APTPL Bit Deactivated" |
2349 | " for UNREGISTER\n"); | 2270 | " for UNREGISTER\n"); |
2350 | return 0; | 2271 | return 0; |
2351 | } | 2272 | } |
2352 | 2273 | ||
2353 | ret = core_scsi3_update_and_write_aptpl(dev, | 2274 | if (!core_scsi3_update_and_write_aptpl(dev, &pr_aptpl_buf[0], |
2354 | &pr_aptpl_buf[0], | 2275 | pr_tmpl->pr_aptpl_buf_len)) { |
2355 | pr_tmpl->pr_aptpl_buf_len); | 2276 | pr_tmpl->pr_aptpl_active = 1; |
2356 | if (!ret) { | 2277 | pr_debug("SPC-3 PR: Set APTPL Bit Activated" |
2357 | pr_tmpl->pr_aptpl_active = 1; | 2278 | " for UNREGISTER\n"); |
2358 | pr_debug("SPC-3 PR: Set APTPL Bit Activated" | 2279 | } |
2359 | " for UNREGISTER\n"); | ||
2360 | } | ||
2361 | 2280 | ||
2362 | kfree(pr_aptpl_buf); | 2281 | goto out_free_aptpl_buf; |
2363 | return ret; | 2282 | } |
2364 | } else { | ||
2365 | /* | ||
2366 | * Increment PRgeneration counter for struct se_device" | ||
2367 | * upon a successful REGISTER, see spc4r17 section 6.3.2 | ||
2368 | * READ_KEYS service action. | ||
2369 | */ | ||
2370 | pr_reg->pr_res_generation = core_scsi3_pr_generation( | ||
2371 | cmd->se_dev); | ||
2372 | pr_reg->pr_res_key = sa_res_key; | ||
2373 | pr_debug("SPC-3 PR [%s] REGISTER%s: Changed Reservation" | ||
2374 | " Key for %s to: 0x%016Lx PRgeneration:" | ||
2375 | " 0x%08x\n", cmd->se_tfo->get_fabric_name(), | ||
2376 | (ignore_key) ? "_AND_IGNORE_EXISTING_KEY" : "", | ||
2377 | pr_reg->pr_reg_nacl->initiatorname, | ||
2378 | pr_reg->pr_res_key, pr_reg->pr_res_generation); | ||
2379 | |||
2380 | if (!aptpl) { | ||
2381 | pr_tmpl->pr_aptpl_active = 0; | ||
2382 | core_scsi3_update_and_write_aptpl(dev, NULL, 0); | ||
2383 | core_scsi3_put_pr_reg(pr_reg); | ||
2384 | pr_debug("SPC-3 PR: Set APTPL Bit Deactivated" | ||
2385 | " for REGISTER\n"); | ||
2386 | return 0; | ||
2387 | } | ||
2388 | 2283 | ||
2389 | ret = core_scsi3_update_and_write_aptpl(dev, | 2284 | /* |
2390 | &pr_aptpl_buf[0], | 2285 | * Increment PRgeneration counter for struct se_device" |
2391 | pr_tmpl->pr_aptpl_buf_len); | 2286 | * upon a successful REGISTER, see spc4r17 section 6.3.2 |
2392 | if (!ret) { | 2287 | * READ_KEYS service action. |
2393 | pr_tmpl->pr_aptpl_active = 1; | 2288 | */ |
2394 | pr_debug("SPC-3 PR: Set APTPL Bit Activated" | 2289 | pr_reg->pr_res_generation = core_scsi3_pr_generation(cmd->se_dev); |
2395 | " for REGISTER\n"); | 2290 | pr_reg->pr_res_key = sa_res_key; |
2396 | } | 2291 | pr_debug("SPC-3 PR [%s] REGISTER%s: Changed Reservation" |
2292 | " Key for %s to: 0x%016Lx PRgeneration:" | ||
2293 | " 0x%08x\n", cmd->se_tfo->get_fabric_name(), | ||
2294 | (ignore_key) ? "_AND_IGNORE_EXISTING_KEY" : "", | ||
2295 | pr_reg->pr_reg_nacl->initiatorname, | ||
2296 | pr_reg->pr_res_key, pr_reg->pr_res_generation); | ||
2397 | 2297 | ||
2398 | kfree(pr_aptpl_buf); | 2298 | if (!aptpl) { |
2399 | core_scsi3_put_pr_reg(pr_reg); | 2299 | pr_tmpl->pr_aptpl_active = 0; |
2400 | } | 2300 | core_scsi3_update_and_write_aptpl(dev, NULL, 0); |
2301 | pr_debug("SPC-3 PR: Set APTPL Bit Deactivated" | ||
2302 | " for REGISTER\n"); | ||
2303 | ret = 0; | ||
2304 | goto out_put_pr_reg; | ||
2401 | } | 2305 | } |
2402 | return 0; | 2306 | |
2307 | if (!core_scsi3_update_and_write_aptpl(dev, &pr_aptpl_buf[0], | ||
2308 | pr_tmpl->pr_aptpl_buf_len)) { | ||
2309 | pr_tmpl->pr_aptpl_active = 1; | ||
2310 | pr_debug("SPC-3 PR: Set APTPL Bit Activated" | ||
2311 | " for REGISTER\n"); | ||
2312 | } | ||
2313 | |||
2314 | out_free_aptpl_buf: | ||
2315 | kfree(pr_aptpl_buf); | ||
2316 | ret = 0; | ||
2317 | out_put_pr_reg: | ||
2318 | core_scsi3_put_pr_reg(pr_reg); | ||
2319 | return ret; | ||
2403 | } | 2320 | } |
2404 | 2321 | ||
2405 | unsigned char *core_scsi3_pr_dump_type(int type) | 2322 | unsigned char *core_scsi3_pr_dump_type(int type) |
@@ -2424,26 +2341,23 @@ unsigned char *core_scsi3_pr_dump_type(int type) | |||
2424 | return "Unknown SPC-3 PR Type"; | 2341 | return "Unknown SPC-3 PR Type"; |
2425 | } | 2342 | } |
2426 | 2343 | ||
2427 | static int core_scsi3_pro_reserve( | 2344 | static sense_reason_t |
2428 | struct se_cmd *cmd, | 2345 | core_scsi3_pro_reserve(struct se_cmd *cmd, int type, int scope, u64 res_key) |
2429 | struct se_device *dev, | ||
2430 | int type, | ||
2431 | int scope, | ||
2432 | u64 res_key) | ||
2433 | { | 2346 | { |
2347 | struct se_device *dev = cmd->se_dev; | ||
2434 | struct se_session *se_sess = cmd->se_sess; | 2348 | struct se_session *se_sess = cmd->se_sess; |
2435 | struct se_lun *se_lun = cmd->se_lun; | 2349 | struct se_lun *se_lun = cmd->se_lun; |
2436 | struct t10_pr_registration *pr_reg, *pr_res_holder; | 2350 | struct t10_pr_registration *pr_reg, *pr_res_holder; |
2437 | struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr; | 2351 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
2438 | char i_buf[PR_REG_ISID_ID_LEN]; | 2352 | char i_buf[PR_REG_ISID_ID_LEN]; |
2439 | int ret, prf_isid; | 2353 | sense_reason_t ret; |
2354 | int prf_isid; | ||
2440 | 2355 | ||
2441 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); | 2356 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); |
2442 | 2357 | ||
2443 | if (!se_sess || !se_lun) { | 2358 | if (!se_sess || !se_lun) { |
2444 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); | 2359 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); |
2445 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 2360 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2446 | return -EINVAL; | ||
2447 | } | 2361 | } |
2448 | /* | 2362 | /* |
2449 | * Locate the existing *pr_reg via struct se_node_acl pointers | 2363 | * Locate the existing *pr_reg via struct se_node_acl pointers |
@@ -2453,8 +2367,7 @@ static int core_scsi3_pro_reserve( | |||
2453 | if (!pr_reg) { | 2367 | if (!pr_reg) { |
2454 | pr_err("SPC-3 PR: Unable to locate" | 2368 | pr_err("SPC-3 PR: Unable to locate" |
2455 | " PR_REGISTERED *pr_reg for RESERVE\n"); | 2369 | " PR_REGISTERED *pr_reg for RESERVE\n"); |
2456 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 2370 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2457 | return -EINVAL; | ||
2458 | } | 2371 | } |
2459 | /* | 2372 | /* |
2460 | * From spc4r17 Section 5.7.9: Reserving: | 2373 | * From spc4r17 Section 5.7.9: Reserving: |
@@ -2469,9 +2382,8 @@ static int core_scsi3_pro_reserve( | |||
2469 | pr_err("SPC-3 PR RESERVE: Received res_key: 0x%016Lx" | 2382 | pr_err("SPC-3 PR RESERVE: Received res_key: 0x%016Lx" |
2470 | " does not match existing SA REGISTER res_key:" | 2383 | " does not match existing SA REGISTER res_key:" |
2471 | " 0x%016Lx\n", res_key, pr_reg->pr_res_key); | 2384 | " 0x%016Lx\n", res_key, pr_reg->pr_res_key); |
2472 | core_scsi3_put_pr_reg(pr_reg); | 2385 | ret = TCM_RESERVATION_CONFLICT; |
2473 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2386 | goto out_put_pr_reg; |
2474 | return -EINVAL; | ||
2475 | } | 2387 | } |
2476 | /* | 2388 | /* |
2477 | * From spc4r17 Section 5.7.9: Reserving: | 2389 | * From spc4r17 Section 5.7.9: Reserving: |
@@ -2485,9 +2397,8 @@ static int core_scsi3_pro_reserve( | |||
2485 | */ | 2397 | */ |
2486 | if (scope != PR_SCOPE_LU_SCOPE) { | 2398 | if (scope != PR_SCOPE_LU_SCOPE) { |
2487 | pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); | 2399 | pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); |
2488 | core_scsi3_put_pr_reg(pr_reg); | 2400 | ret = TCM_INVALID_PARAMETER_LIST; |
2489 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 2401 | goto out_put_pr_reg; |
2490 | return -EINVAL; | ||
2491 | } | 2402 | } |
2492 | /* | 2403 | /* |
2493 | * See if we have an existing PR reservation holder pointer at | 2404 | * See if we have an existing PR reservation holder pointer at |
@@ -2518,9 +2429,8 @@ static int core_scsi3_pro_reserve( | |||
2518 | pr_res_holder->pr_reg_nacl->initiatorname); | 2429 | pr_res_holder->pr_reg_nacl->initiatorname); |
2519 | 2430 | ||
2520 | spin_unlock(&dev->dev_reservation_lock); | 2431 | spin_unlock(&dev->dev_reservation_lock); |
2521 | core_scsi3_put_pr_reg(pr_reg); | 2432 | ret = TCM_RESERVATION_CONFLICT; |
2522 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2433 | goto out_put_pr_reg; |
2523 | return -EINVAL; | ||
2524 | } | 2434 | } |
2525 | /* | 2435 | /* |
2526 | * From spc4r17 Section 5.7.9: Reserving: | 2436 | * From spc4r17 Section 5.7.9: Reserving: |
@@ -2542,9 +2452,8 @@ static int core_scsi3_pro_reserve( | |||
2542 | pr_res_holder->pr_reg_nacl->initiatorname); | 2452 | pr_res_holder->pr_reg_nacl->initiatorname); |
2543 | 2453 | ||
2544 | spin_unlock(&dev->dev_reservation_lock); | 2454 | spin_unlock(&dev->dev_reservation_lock); |
2545 | core_scsi3_put_pr_reg(pr_reg); | 2455 | ret = TCM_RESERVATION_CONFLICT; |
2546 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2456 | goto out_put_pr_reg; |
2547 | return -EINVAL; | ||
2548 | } | 2457 | } |
2549 | /* | 2458 | /* |
2550 | * From spc4r17 Section 5.7.9: Reserving: | 2459 | * From spc4r17 Section 5.7.9: Reserving: |
@@ -2557,8 +2466,8 @@ static int core_scsi3_pro_reserve( | |||
2557 | * shall completethe command with GOOD status. | 2466 | * shall completethe command with GOOD status. |
2558 | */ | 2467 | */ |
2559 | spin_unlock(&dev->dev_reservation_lock); | 2468 | spin_unlock(&dev->dev_reservation_lock); |
2560 | core_scsi3_put_pr_reg(pr_reg); | 2469 | ret = 0; |
2561 | return 0; | 2470 | goto out_put_pr_reg; |
2562 | } | 2471 | } |
2563 | /* | 2472 | /* |
2564 | * Otherwise, our *pr_reg becomes the PR reservation holder for said | 2473 | * Otherwise, our *pr_reg becomes the PR reservation holder for said |
@@ -2582,27 +2491,24 @@ static int core_scsi3_pro_reserve( | |||
2582 | spin_unlock(&dev->dev_reservation_lock); | 2491 | spin_unlock(&dev->dev_reservation_lock); |
2583 | 2492 | ||
2584 | if (pr_tmpl->pr_aptpl_active) { | 2493 | if (pr_tmpl->pr_aptpl_active) { |
2585 | ret = core_scsi3_update_and_write_aptpl(cmd->se_dev, | 2494 | if (!core_scsi3_update_and_write_aptpl(cmd->se_dev, |
2586 | &pr_reg->pr_aptpl_buf[0], | 2495 | &pr_reg->pr_aptpl_buf[0], |
2587 | pr_tmpl->pr_aptpl_buf_len); | 2496 | pr_tmpl->pr_aptpl_buf_len)) { |
2588 | if (!ret) | ||
2589 | pr_debug("SPC-3 PR: Updated APTPL metadata" | 2497 | pr_debug("SPC-3 PR: Updated APTPL metadata" |
2590 | " for RESERVE\n"); | 2498 | " for RESERVE\n"); |
2499 | } | ||
2591 | } | 2500 | } |
2592 | 2501 | ||
2502 | ret = 0; | ||
2503 | out_put_pr_reg: | ||
2593 | core_scsi3_put_pr_reg(pr_reg); | 2504 | core_scsi3_put_pr_reg(pr_reg); |
2594 | return 0; | 2505 | return ret; |
2595 | } | 2506 | } |
2596 | 2507 | ||
2597 | static int core_scsi3_emulate_pro_reserve( | 2508 | static sense_reason_t |
2598 | struct se_cmd *cmd, | 2509 | core_scsi3_emulate_pro_reserve(struct se_cmd *cmd, int type, int scope, |
2599 | int type, | 2510 | u64 res_key) |
2600 | int scope, | ||
2601 | u64 res_key) | ||
2602 | { | 2511 | { |
2603 | struct se_device *dev = cmd->se_dev; | ||
2604 | int ret = 0; | ||
2605 | |||
2606 | switch (type) { | 2512 | switch (type) { |
2607 | case PR_TYPE_WRITE_EXCLUSIVE: | 2513 | case PR_TYPE_WRITE_EXCLUSIVE: |
2608 | case PR_TYPE_EXCLUSIVE_ACCESS: | 2514 | case PR_TYPE_EXCLUSIVE_ACCESS: |
@@ -2610,16 +2516,12 @@ static int core_scsi3_emulate_pro_reserve( | |||
2610 | case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY: | 2516 | case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY: |
2611 | case PR_TYPE_WRITE_EXCLUSIVE_ALLREG: | 2517 | case PR_TYPE_WRITE_EXCLUSIVE_ALLREG: |
2612 | case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG: | 2518 | case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG: |
2613 | ret = core_scsi3_pro_reserve(cmd, dev, type, scope, res_key); | 2519 | return core_scsi3_pro_reserve(cmd, type, scope, res_key); |
2614 | break; | ||
2615 | default: | 2520 | default: |
2616 | pr_err("SPC-3 PR: Unknown Service Action RESERVE Type:" | 2521 | pr_err("SPC-3 PR: Unknown Service Action RESERVE Type:" |
2617 | " 0x%02x\n", type); | 2522 | " 0x%02x\n", type); |
2618 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 2523 | return TCM_INVALID_CDB_FIELD; |
2619 | return -EINVAL; | ||
2620 | } | 2524 | } |
2621 | |||
2622 | return ret; | ||
2623 | } | 2525 | } |
2624 | 2526 | ||
2625 | /* | 2527 | /* |
@@ -2657,23 +2559,21 @@ static void __core_scsi3_complete_pro_release( | |||
2657 | pr_reg->pr_res_holder = pr_reg->pr_res_type = pr_reg->pr_res_scope = 0; | 2559 | pr_reg->pr_res_holder = pr_reg->pr_res_type = pr_reg->pr_res_scope = 0; |
2658 | } | 2560 | } |
2659 | 2561 | ||
2660 | static int core_scsi3_emulate_pro_release( | 2562 | static sense_reason_t |
2661 | struct se_cmd *cmd, | 2563 | core_scsi3_emulate_pro_release(struct se_cmd *cmd, int type, int scope, |
2662 | int type, | 2564 | u64 res_key) |
2663 | int scope, | ||
2664 | u64 res_key) | ||
2665 | { | 2565 | { |
2666 | struct se_device *dev = cmd->se_dev; | 2566 | struct se_device *dev = cmd->se_dev; |
2667 | struct se_session *se_sess = cmd->se_sess; | 2567 | struct se_session *se_sess = cmd->se_sess; |
2668 | struct se_lun *se_lun = cmd->se_lun; | 2568 | struct se_lun *se_lun = cmd->se_lun; |
2669 | struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_res_holder; | 2569 | struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_res_holder; |
2670 | struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr; | 2570 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
2671 | int ret, all_reg = 0; | 2571 | int all_reg = 0; |
2572 | sense_reason_t ret = 0; | ||
2672 | 2573 | ||
2673 | if (!se_sess || !se_lun) { | 2574 | if (!se_sess || !se_lun) { |
2674 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); | 2575 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); |
2675 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 2576 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2676 | return -EINVAL; | ||
2677 | } | 2577 | } |
2678 | /* | 2578 | /* |
2679 | * Locate the existing *pr_reg via struct se_node_acl pointers | 2579 | * Locate the existing *pr_reg via struct se_node_acl pointers |
@@ -2682,8 +2582,7 @@ static int core_scsi3_emulate_pro_release( | |||
2682 | if (!pr_reg) { | 2582 | if (!pr_reg) { |
2683 | pr_err("SPC-3 PR: Unable to locate" | 2583 | pr_err("SPC-3 PR: Unable to locate" |
2684 | " PR_REGISTERED *pr_reg for RELEASE\n"); | 2584 | " PR_REGISTERED *pr_reg for RELEASE\n"); |
2685 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 2585 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2686 | return -EINVAL; | ||
2687 | } | 2586 | } |
2688 | /* | 2587 | /* |
2689 | * From spc4r17 Section 5.7.11.2 Releasing: | 2588 | * From spc4r17 Section 5.7.11.2 Releasing: |
@@ -2704,8 +2603,7 @@ static int core_scsi3_emulate_pro_release( | |||
2704 | * No persistent reservation, return GOOD status. | 2603 | * No persistent reservation, return GOOD status. |
2705 | */ | 2604 | */ |
2706 | spin_unlock(&dev->dev_reservation_lock); | 2605 | spin_unlock(&dev->dev_reservation_lock); |
2707 | core_scsi3_put_pr_reg(pr_reg); | 2606 | goto out_put_pr_reg; |
2708 | return 0; | ||
2709 | } | 2607 | } |
2710 | if ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || | 2608 | if ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || |
2711 | (pr_res_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) | 2609 | (pr_res_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) |
@@ -2718,9 +2616,9 @@ static int core_scsi3_emulate_pro_release( | |||
2718 | * persistent reservation holder. return GOOD status. | 2616 | * persistent reservation holder. return GOOD status. |
2719 | */ | 2617 | */ |
2720 | spin_unlock(&dev->dev_reservation_lock); | 2618 | spin_unlock(&dev->dev_reservation_lock); |
2721 | core_scsi3_put_pr_reg(pr_reg); | 2619 | goto out_put_pr_reg; |
2722 | return 0; | ||
2723 | } | 2620 | } |
2621 | |||
2724 | /* | 2622 | /* |
2725 | * From spc4r17 Section 5.7.11.2 Releasing: | 2623 | * From spc4r17 Section 5.7.11.2 Releasing: |
2726 | * | 2624 | * |
@@ -2740,9 +2638,8 @@ static int core_scsi3_emulate_pro_release( | |||
2740 | " does not match existing SA REGISTER res_key:" | 2638 | " does not match existing SA REGISTER res_key:" |
2741 | " 0x%016Lx\n", res_key, pr_reg->pr_res_key); | 2639 | " 0x%016Lx\n", res_key, pr_reg->pr_res_key); |
2742 | spin_unlock(&dev->dev_reservation_lock); | 2640 | spin_unlock(&dev->dev_reservation_lock); |
2743 | core_scsi3_put_pr_reg(pr_reg); | 2641 | ret = TCM_RESERVATION_CONFLICT; |
2744 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2642 | goto out_put_pr_reg; |
2745 | return -EINVAL; | ||
2746 | } | 2643 | } |
2747 | /* | 2644 | /* |
2748 | * From spc4r17 Section 5.7.11.2 Releasing and above: | 2645 | * From spc4r17 Section 5.7.11.2 Releasing and above: |
@@ -2763,9 +2660,8 @@ static int core_scsi3_emulate_pro_release( | |||
2763 | pr_res_holder->pr_reg_nacl->initiatorname); | 2660 | pr_res_holder->pr_reg_nacl->initiatorname); |
2764 | 2661 | ||
2765 | spin_unlock(&dev->dev_reservation_lock); | 2662 | spin_unlock(&dev->dev_reservation_lock); |
2766 | core_scsi3_put_pr_reg(pr_reg); | 2663 | ret = TCM_RESERVATION_CONFLICT; |
2767 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2664 | goto out_put_pr_reg; |
2768 | return -EINVAL; | ||
2769 | } | 2665 | } |
2770 | /* | 2666 | /* |
2771 | * In response to a persistent reservation release request from the | 2667 | * In response to a persistent reservation release request from the |
@@ -2818,25 +2714,23 @@ static int core_scsi3_emulate_pro_release( | |||
2818 | 2714 | ||
2819 | write_aptpl: | 2715 | write_aptpl: |
2820 | if (pr_tmpl->pr_aptpl_active) { | 2716 | if (pr_tmpl->pr_aptpl_active) { |
2821 | ret = core_scsi3_update_and_write_aptpl(cmd->se_dev, | 2717 | if (!core_scsi3_update_and_write_aptpl(cmd->se_dev, |
2822 | &pr_reg->pr_aptpl_buf[0], | 2718 | &pr_reg->pr_aptpl_buf[0], pr_tmpl->pr_aptpl_buf_len)) { |
2823 | pr_tmpl->pr_aptpl_buf_len); | ||
2824 | if (!ret) | ||
2825 | pr_debug("SPC-3 PR: Updated APTPL metadata for RELEASE\n"); | 2719 | pr_debug("SPC-3 PR: Updated APTPL metadata for RELEASE\n"); |
2720 | } | ||
2826 | } | 2721 | } |
2827 | 2722 | out_put_pr_reg: | |
2828 | core_scsi3_put_pr_reg(pr_reg); | 2723 | core_scsi3_put_pr_reg(pr_reg); |
2829 | return 0; | 2724 | return ret; |
2830 | } | 2725 | } |
2831 | 2726 | ||
2832 | static int core_scsi3_emulate_pro_clear( | 2727 | static sense_reason_t |
2833 | struct se_cmd *cmd, | 2728 | core_scsi3_emulate_pro_clear(struct se_cmd *cmd, u64 res_key) |
2834 | u64 res_key) | ||
2835 | { | 2729 | { |
2836 | struct se_device *dev = cmd->se_dev; | 2730 | struct se_device *dev = cmd->se_dev; |
2837 | struct se_node_acl *pr_reg_nacl; | 2731 | struct se_node_acl *pr_reg_nacl; |
2838 | struct se_session *se_sess = cmd->se_sess; | 2732 | struct se_session *se_sess = cmd->se_sess; |
2839 | struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr; | 2733 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
2840 | struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_reg_n, *pr_res_holder; | 2734 | struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_reg_n, *pr_res_holder; |
2841 | u32 pr_res_mapped_lun = 0; | 2735 | u32 pr_res_mapped_lun = 0; |
2842 | int calling_it_nexus = 0; | 2736 | int calling_it_nexus = 0; |
@@ -2848,8 +2742,7 @@ static int core_scsi3_emulate_pro_clear( | |||
2848 | if (!pr_reg_n) { | 2742 | if (!pr_reg_n) { |
2849 | pr_err("SPC-3 PR: Unable to locate" | 2743 | pr_err("SPC-3 PR: Unable to locate" |
2850 | " PR_REGISTERED *pr_reg for CLEAR\n"); | 2744 | " PR_REGISTERED *pr_reg for CLEAR\n"); |
2851 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 2745 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2852 | return -EINVAL; | ||
2853 | } | 2746 | } |
2854 | /* | 2747 | /* |
2855 | * From spc4r17 section 5.7.11.6, Clearing: | 2748 | * From spc4r17 section 5.7.11.6, Clearing: |
@@ -2868,8 +2761,7 @@ static int core_scsi3_emulate_pro_clear( | |||
2868 | " existing SA REGISTER res_key:" | 2761 | " existing SA REGISTER res_key:" |
2869 | " 0x%016Lx\n", res_key, pr_reg_n->pr_res_key); | 2762 | " 0x%016Lx\n", res_key, pr_reg_n->pr_res_key); |
2870 | core_scsi3_put_pr_reg(pr_reg_n); | 2763 | core_scsi3_put_pr_reg(pr_reg_n); |
2871 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2764 | return TCM_RESERVATION_CONFLICT; |
2872 | return -EINVAL; | ||
2873 | } | 2765 | } |
2874 | /* | 2766 | /* |
2875 | * a) Release the persistent reservation, if any; | 2767 | * a) Release the persistent reservation, if any; |
@@ -2993,28 +2885,22 @@ static void core_scsi3_release_preempt_and_abort( | |||
2993 | } | 2885 | } |
2994 | } | 2886 | } |
2995 | 2887 | ||
2996 | static int core_scsi3_pro_preempt( | 2888 | static sense_reason_t |
2997 | struct se_cmd *cmd, | 2889 | core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, |
2998 | int type, | 2890 | u64 sa_res_key, int abort) |
2999 | int scope, | ||
3000 | u64 res_key, | ||
3001 | u64 sa_res_key, | ||
3002 | int abort) | ||
3003 | { | 2891 | { |
3004 | struct se_device *dev = cmd->se_dev; | 2892 | struct se_device *dev = cmd->se_dev; |
3005 | struct se_node_acl *pr_reg_nacl; | 2893 | struct se_node_acl *pr_reg_nacl; |
3006 | struct se_session *se_sess = cmd->se_sess; | 2894 | struct se_session *se_sess = cmd->se_sess; |
3007 | LIST_HEAD(preempt_and_abort_list); | 2895 | LIST_HEAD(preempt_and_abort_list); |
3008 | struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_reg_n, *pr_res_holder; | 2896 | struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_reg_n, *pr_res_holder; |
3009 | struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr; | 2897 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
3010 | u32 pr_res_mapped_lun = 0; | 2898 | u32 pr_res_mapped_lun = 0; |
3011 | int all_reg = 0, calling_it_nexus = 0, released_regs = 0; | 2899 | int all_reg = 0, calling_it_nexus = 0, released_regs = 0; |
3012 | int prh_type = 0, prh_scope = 0, ret; | 2900 | int prh_type = 0, prh_scope = 0; |
3013 | 2901 | ||
3014 | if (!se_sess) { | 2902 | if (!se_sess) |
3015 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 2903 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3016 | return -EINVAL; | ||
3017 | } | ||
3018 | 2904 | ||
3019 | pr_reg_n = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl, | 2905 | pr_reg_n = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl, |
3020 | se_sess); | 2906 | se_sess); |
@@ -3022,19 +2908,16 @@ static int core_scsi3_pro_preempt( | |||
3022 | pr_err("SPC-3 PR: Unable to locate" | 2908 | pr_err("SPC-3 PR: Unable to locate" |
3023 | " PR_REGISTERED *pr_reg for PREEMPT%s\n", | 2909 | " PR_REGISTERED *pr_reg for PREEMPT%s\n", |
3024 | (abort) ? "_AND_ABORT" : ""); | 2910 | (abort) ? "_AND_ABORT" : ""); |
3025 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2911 | return TCM_RESERVATION_CONFLICT; |
3026 | return -EINVAL; | ||
3027 | } | 2912 | } |
3028 | if (pr_reg_n->pr_res_key != res_key) { | 2913 | if (pr_reg_n->pr_res_key != res_key) { |
3029 | core_scsi3_put_pr_reg(pr_reg_n); | 2914 | core_scsi3_put_pr_reg(pr_reg_n); |
3030 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2915 | return TCM_RESERVATION_CONFLICT; |
3031 | return -EINVAL; | ||
3032 | } | 2916 | } |
3033 | if (scope != PR_SCOPE_LU_SCOPE) { | 2917 | if (scope != PR_SCOPE_LU_SCOPE) { |
3034 | pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); | 2918 | pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); |
3035 | core_scsi3_put_pr_reg(pr_reg_n); | 2919 | core_scsi3_put_pr_reg(pr_reg_n); |
3036 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 2920 | return TCM_INVALID_PARAMETER_LIST; |
3037 | return -EINVAL; | ||
3038 | } | 2921 | } |
3039 | 2922 | ||
3040 | spin_lock(&dev->dev_reservation_lock); | 2923 | spin_lock(&dev->dev_reservation_lock); |
@@ -3047,8 +2930,7 @@ static int core_scsi3_pro_preempt( | |||
3047 | if (!all_reg && !sa_res_key) { | 2930 | if (!all_reg && !sa_res_key) { |
3048 | spin_unlock(&dev->dev_reservation_lock); | 2931 | spin_unlock(&dev->dev_reservation_lock); |
3049 | core_scsi3_put_pr_reg(pr_reg_n); | 2932 | core_scsi3_put_pr_reg(pr_reg_n); |
3050 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 2933 | return TCM_INVALID_PARAMETER_LIST; |
3051 | return -EINVAL; | ||
3052 | } | 2934 | } |
3053 | /* | 2935 | /* |
3054 | * From spc4r17, section 5.7.11.4.4 Removing Registrations: | 2936 | * From spc4r17, section 5.7.11.4.4 Removing Registrations: |
@@ -3142,8 +3024,7 @@ static int core_scsi3_pro_preempt( | |||
3142 | if (!released_regs) { | 3024 | if (!released_regs) { |
3143 | spin_unlock(&dev->dev_reservation_lock); | 3025 | spin_unlock(&dev->dev_reservation_lock); |
3144 | core_scsi3_put_pr_reg(pr_reg_n); | 3026 | core_scsi3_put_pr_reg(pr_reg_n); |
3145 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 3027 | return TCM_RESERVATION_CONFLICT; |
3146 | return -EINVAL; | ||
3147 | } | 3028 | } |
3148 | /* | 3029 | /* |
3149 | * For an existing all registrants type reservation | 3030 | * For an existing all registrants type reservation |
@@ -3162,13 +3043,13 @@ static int core_scsi3_pro_preempt( | |||
3162 | spin_unlock(&dev->dev_reservation_lock); | 3043 | spin_unlock(&dev->dev_reservation_lock); |
3163 | 3044 | ||
3164 | if (pr_tmpl->pr_aptpl_active) { | 3045 | if (pr_tmpl->pr_aptpl_active) { |
3165 | ret = core_scsi3_update_and_write_aptpl(cmd->se_dev, | 3046 | if (!core_scsi3_update_and_write_aptpl(cmd->se_dev, |
3166 | &pr_reg_n->pr_aptpl_buf[0], | 3047 | &pr_reg_n->pr_aptpl_buf[0], |
3167 | pr_tmpl->pr_aptpl_buf_len); | 3048 | pr_tmpl->pr_aptpl_buf_len)) { |
3168 | if (!ret) | ||
3169 | pr_debug("SPC-3 PR: Updated APTPL" | 3049 | pr_debug("SPC-3 PR: Updated APTPL" |
3170 | " metadata for PREEMPT%s\n", (abort) ? | 3050 | " metadata for PREEMPT%s\n", (abort) ? |
3171 | "_AND_ABORT" : ""); | 3051 | "_AND_ABORT" : ""); |
3052 | } | ||
3172 | } | 3053 | } |
3173 | 3054 | ||
3174 | core_scsi3_put_pr_reg(pr_reg_n); | 3055 | core_scsi3_put_pr_reg(pr_reg_n); |
@@ -3298,12 +3179,12 @@ static int core_scsi3_pro_preempt( | |||
3298 | } | 3179 | } |
3299 | 3180 | ||
3300 | if (pr_tmpl->pr_aptpl_active) { | 3181 | if (pr_tmpl->pr_aptpl_active) { |
3301 | ret = core_scsi3_update_and_write_aptpl(cmd->se_dev, | 3182 | if (!core_scsi3_update_and_write_aptpl(cmd->se_dev, |
3302 | &pr_reg_n->pr_aptpl_buf[0], | 3183 | &pr_reg_n->pr_aptpl_buf[0], |
3303 | pr_tmpl->pr_aptpl_buf_len); | 3184 | pr_tmpl->pr_aptpl_buf_len)) { |
3304 | if (!ret) | ||
3305 | pr_debug("SPC-3 PR: Updated APTPL metadata for PREEMPT" | 3185 | pr_debug("SPC-3 PR: Updated APTPL metadata for PREEMPT" |
3306 | "%s\n", (abort) ? "_AND_ABORT" : ""); | 3186 | "%s\n", abort ? "_AND_ABORT" : ""); |
3187 | } | ||
3307 | } | 3188 | } |
3308 | 3189 | ||
3309 | core_scsi3_put_pr_reg(pr_reg_n); | 3190 | core_scsi3_put_pr_reg(pr_reg_n); |
@@ -3311,16 +3192,10 @@ static int core_scsi3_pro_preempt( | |||
3311 | return 0; | 3192 | return 0; |
3312 | } | 3193 | } |
3313 | 3194 | ||
3314 | static int core_scsi3_emulate_pro_preempt( | 3195 | static sense_reason_t |
3315 | struct se_cmd *cmd, | 3196 | core_scsi3_emulate_pro_preempt(struct se_cmd *cmd, int type, int scope, |
3316 | int type, | 3197 | u64 res_key, u64 sa_res_key, int abort) |
3317 | int scope, | ||
3318 | u64 res_key, | ||
3319 | u64 sa_res_key, | ||
3320 | int abort) | ||
3321 | { | 3198 | { |
3322 | int ret = 0; | ||
3323 | |||
3324 | switch (type) { | 3199 | switch (type) { |
3325 | case PR_TYPE_WRITE_EXCLUSIVE: | 3200 | case PR_TYPE_WRITE_EXCLUSIVE: |
3326 | case PR_TYPE_EXCLUSIVE_ACCESS: | 3201 | case PR_TYPE_EXCLUSIVE_ACCESS: |
@@ -3328,26 +3203,19 @@ static int core_scsi3_emulate_pro_preempt( | |||
3328 | case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY: | 3203 | case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY: |
3329 | case PR_TYPE_WRITE_EXCLUSIVE_ALLREG: | 3204 | case PR_TYPE_WRITE_EXCLUSIVE_ALLREG: |
3330 | case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG: | 3205 | case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG: |
3331 | ret = core_scsi3_pro_preempt(cmd, type, scope, | 3206 | return core_scsi3_pro_preempt(cmd, type, scope, res_key, |
3332 | res_key, sa_res_key, abort); | 3207 | sa_res_key, abort); |
3333 | break; | ||
3334 | default: | 3208 | default: |
3335 | pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s" | 3209 | pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s" |
3336 | " Type: 0x%02x\n", (abort) ? "_AND_ABORT" : "", type); | 3210 | " Type: 0x%02x\n", (abort) ? "_AND_ABORT" : "", type); |
3337 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 3211 | return TCM_INVALID_CDB_FIELD; |
3338 | return -EINVAL; | ||
3339 | } | 3212 | } |
3340 | |||
3341 | return ret; | ||
3342 | } | 3213 | } |
3343 | 3214 | ||
3344 | 3215 | ||
3345 | static int core_scsi3_emulate_pro_register_and_move( | 3216 | static sense_reason_t |
3346 | struct se_cmd *cmd, | 3217 | core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key, |
3347 | u64 res_key, | 3218 | u64 sa_res_key, int aptpl, int unreg) |
3348 | u64 sa_res_key, | ||
3349 | int aptpl, | ||
3350 | int unreg) | ||
3351 | { | 3219 | { |
3352 | struct se_session *se_sess = cmd->se_sess; | 3220 | struct se_session *se_sess = cmd->se_sess; |
3353 | struct se_device *dev = cmd->se_dev; | 3221 | struct se_device *dev = cmd->se_dev; |
@@ -3358,20 +3226,21 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3358 | struct se_portal_group *se_tpg, *dest_se_tpg = NULL; | 3226 | struct se_portal_group *se_tpg, *dest_se_tpg = NULL; |
3359 | struct target_core_fabric_ops *dest_tf_ops = NULL, *tf_ops; | 3227 | struct target_core_fabric_ops *dest_tf_ops = NULL, *tf_ops; |
3360 | struct t10_pr_registration *pr_reg, *pr_res_holder, *dest_pr_reg; | 3228 | struct t10_pr_registration *pr_reg, *pr_res_holder, *dest_pr_reg; |
3361 | struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr; | 3229 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
3362 | unsigned char *buf; | 3230 | unsigned char *buf; |
3363 | unsigned char *initiator_str; | 3231 | unsigned char *initiator_str; |
3364 | char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN]; | 3232 | char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN]; |
3365 | u32 tid_len, tmp_tid_len; | 3233 | u32 tid_len, tmp_tid_len; |
3366 | int new_reg = 0, type, scope, ret, matching_iname, prf_isid; | 3234 | int new_reg = 0, type, scope, matching_iname, prf_isid; |
3235 | sense_reason_t ret; | ||
3367 | unsigned short rtpi; | 3236 | unsigned short rtpi; |
3368 | unsigned char proto_ident; | 3237 | unsigned char proto_ident; |
3369 | 3238 | ||
3370 | if (!se_sess || !se_lun) { | 3239 | if (!se_sess || !se_lun) { |
3371 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); | 3240 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); |
3372 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 3241 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3373 | return -EINVAL; | ||
3374 | } | 3242 | } |
3243 | |||
3375 | memset(dest_iport, 0, 64); | 3244 | memset(dest_iport, 0, 64); |
3376 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); | 3245 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); |
3377 | se_tpg = se_sess->se_tpg; | 3246 | se_tpg = se_sess->se_tpg; |
@@ -3387,8 +3256,7 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3387 | if (!pr_reg) { | 3256 | if (!pr_reg) { |
3388 | pr_err("SPC-3 PR: Unable to locate PR_REGISTERED" | 3257 | pr_err("SPC-3 PR: Unable to locate PR_REGISTERED" |
3389 | " *pr_reg for REGISTER_AND_MOVE\n"); | 3258 | " *pr_reg for REGISTER_AND_MOVE\n"); |
3390 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 3259 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3391 | return -EINVAL; | ||
3392 | } | 3260 | } |
3393 | /* | 3261 | /* |
3394 | * The provided reservation key much match the existing reservation key | 3262 | * The provided reservation key much match the existing reservation key |
@@ -3398,9 +3266,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3398 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received" | 3266 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received" |
3399 | " res_key: 0x%016Lx does not match existing SA REGISTER" | 3267 | " res_key: 0x%016Lx does not match existing SA REGISTER" |
3400 | " res_key: 0x%016Lx\n", res_key, pr_reg->pr_res_key); | 3268 | " res_key: 0x%016Lx\n", res_key, pr_reg->pr_res_key); |
3401 | core_scsi3_put_pr_reg(pr_reg); | 3269 | ret = TCM_RESERVATION_CONFLICT; |
3402 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 3270 | goto out_put_pr_reg; |
3403 | return -EINVAL; | ||
3404 | } | 3271 | } |
3405 | /* | 3272 | /* |
3406 | * The service active reservation key needs to be non zero | 3273 | * The service active reservation key needs to be non zero |
@@ -3408,9 +3275,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3408 | if (!sa_res_key) { | 3275 | if (!sa_res_key) { |
3409 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received zero" | 3276 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received zero" |
3410 | " sa_res_key\n"); | 3277 | " sa_res_key\n"); |
3411 | core_scsi3_put_pr_reg(pr_reg); | 3278 | ret = TCM_INVALID_PARAMETER_LIST; |
3412 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3279 | goto out_put_pr_reg; |
3413 | return -EINVAL; | ||
3414 | } | 3280 | } |
3415 | 3281 | ||
3416 | /* | 3282 | /* |
@@ -3419,6 +3285,11 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3419 | * information. | 3285 | * information. |
3420 | */ | 3286 | */ |
3421 | buf = transport_kmap_data_sg(cmd); | 3287 | buf = transport_kmap_data_sg(cmd); |
3288 | if (!buf) { | ||
3289 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
3290 | goto out_put_pr_reg; | ||
3291 | } | ||
3292 | |||
3422 | rtpi = (buf[18] & 0xff) << 8; | 3293 | rtpi = (buf[18] & 0xff) << 8; |
3423 | rtpi |= buf[19] & 0xff; | 3294 | rtpi |= buf[19] & 0xff; |
3424 | tid_len = (buf[20] & 0xff) << 24; | 3295 | tid_len = (buf[20] & 0xff) << 24; |
@@ -3432,9 +3303,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3432 | pr_err("SPC-3 PR: Illegal tid_len: %u + 24 byte header" | 3303 | pr_err("SPC-3 PR: Illegal tid_len: %u + 24 byte header" |
3433 | " does not equal CDB data_length: %u\n", tid_len, | 3304 | " does not equal CDB data_length: %u\n", tid_len, |
3434 | cmd->data_length); | 3305 | cmd->data_length); |
3435 | core_scsi3_put_pr_reg(pr_reg); | 3306 | ret = TCM_INVALID_PARAMETER_LIST; |
3436 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3307 | goto out_put_pr_reg; |
3437 | return -EINVAL; | ||
3438 | } | 3308 | } |
3439 | 3309 | ||
3440 | spin_lock(&dev->se_port_lock); | 3310 | spin_lock(&dev->se_port_lock); |
@@ -3452,15 +3322,13 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3452 | smp_mb__after_atomic_inc(); | 3322 | smp_mb__after_atomic_inc(); |
3453 | spin_unlock(&dev->se_port_lock); | 3323 | spin_unlock(&dev->se_port_lock); |
3454 | 3324 | ||
3455 | ret = core_scsi3_tpg_depend_item(dest_se_tpg); | 3325 | if (core_scsi3_tpg_depend_item(dest_se_tpg)) { |
3456 | if (ret != 0) { | ||
3457 | pr_err("core_scsi3_tpg_depend_item() failed" | 3326 | pr_err("core_scsi3_tpg_depend_item() failed" |
3458 | " for dest_se_tpg\n"); | 3327 | " for dest_se_tpg\n"); |
3459 | atomic_dec(&dest_se_tpg->tpg_pr_ref_count); | 3328 | atomic_dec(&dest_se_tpg->tpg_pr_ref_count); |
3460 | smp_mb__after_atomic_dec(); | 3329 | smp_mb__after_atomic_dec(); |
3461 | core_scsi3_put_pr_reg(pr_reg); | 3330 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3462 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 3331 | goto out_put_pr_reg; |
3463 | return -EINVAL; | ||
3464 | } | 3332 | } |
3465 | 3333 | ||
3466 | spin_lock(&dev->se_port_lock); | 3334 | spin_lock(&dev->se_port_lock); |
@@ -3472,12 +3340,15 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3472 | pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate" | 3340 | pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate" |
3473 | " fabric ops from Relative Target Port Identifier:" | 3341 | " fabric ops from Relative Target Port Identifier:" |
3474 | " %hu\n", rtpi); | 3342 | " %hu\n", rtpi); |
3475 | core_scsi3_put_pr_reg(pr_reg); | 3343 | ret = TCM_INVALID_PARAMETER_LIST; |
3476 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3344 | goto out_put_pr_reg; |
3477 | return -EINVAL; | ||
3478 | } | 3345 | } |
3479 | 3346 | ||
3480 | buf = transport_kmap_data_sg(cmd); | 3347 | buf = transport_kmap_data_sg(cmd); |
3348 | if (!buf) { | ||
3349 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
3350 | goto out_put_pr_reg; | ||
3351 | } | ||
3481 | proto_ident = (buf[24] & 0x0f); | 3352 | proto_ident = (buf[24] & 0x0f); |
3482 | 3353 | ||
3483 | pr_debug("SPC-3 PR REGISTER_AND_MOVE: Extracted Protocol Identifier:" | 3354 | pr_debug("SPC-3 PR REGISTER_AND_MOVE: Extracted Protocol Identifier:" |
@@ -3489,16 +3360,14 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3489 | " from fabric: %s\n", proto_ident, | 3360 | " from fabric: %s\n", proto_ident, |
3490 | dest_tf_ops->get_fabric_proto_ident(dest_se_tpg), | 3361 | dest_tf_ops->get_fabric_proto_ident(dest_se_tpg), |
3491 | dest_tf_ops->get_fabric_name()); | 3362 | dest_tf_ops->get_fabric_name()); |
3492 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3363 | ret = TCM_INVALID_PARAMETER_LIST; |
3493 | ret = -EINVAL; | ||
3494 | goto out; | 3364 | goto out; |
3495 | } | 3365 | } |
3496 | if (dest_tf_ops->tpg_parse_pr_out_transport_id == NULL) { | 3366 | if (dest_tf_ops->tpg_parse_pr_out_transport_id == NULL) { |
3497 | pr_err("SPC-3 PR REGISTER_AND_MOVE: Fabric does not" | 3367 | pr_err("SPC-3 PR REGISTER_AND_MOVE: Fabric does not" |
3498 | " containg a valid tpg_parse_pr_out_transport_id" | 3368 | " containg a valid tpg_parse_pr_out_transport_id" |
3499 | " function pointer\n"); | 3369 | " function pointer\n"); |
3500 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 3370 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3501 | ret = -EINVAL; | ||
3502 | goto out; | 3371 | goto out; |
3503 | } | 3372 | } |
3504 | initiator_str = dest_tf_ops->tpg_parse_pr_out_transport_id(dest_se_tpg, | 3373 | initiator_str = dest_tf_ops->tpg_parse_pr_out_transport_id(dest_se_tpg, |
@@ -3506,8 +3375,7 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3506 | if (!initiator_str) { | 3375 | if (!initiator_str) { |
3507 | pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate" | 3376 | pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate" |
3508 | " initiator_str from Transport ID\n"); | 3377 | " initiator_str from Transport ID\n"); |
3509 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3378 | ret = TCM_INVALID_PARAMETER_LIST; |
3510 | ret = -EINVAL; | ||
3511 | goto out; | 3379 | goto out; |
3512 | } | 3380 | } |
3513 | 3381 | ||
@@ -3536,8 +3404,7 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3536 | pr_err("SPC-3 PR REGISTER_AND_MOVE: TransportID: %s" | 3404 | pr_err("SPC-3 PR REGISTER_AND_MOVE: TransportID: %s" |
3537 | " matches: %s on received I_T Nexus\n", initiator_str, | 3405 | " matches: %s on received I_T Nexus\n", initiator_str, |
3538 | pr_reg_nacl->initiatorname); | 3406 | pr_reg_nacl->initiatorname); |
3539 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3407 | ret = TCM_INVALID_PARAMETER_LIST; |
3540 | ret = -EINVAL; | ||
3541 | goto out; | 3408 | goto out; |
3542 | } | 3409 | } |
3543 | if (!strcmp(iport_ptr, pr_reg->pr_reg_isid)) { | 3410 | if (!strcmp(iport_ptr, pr_reg->pr_reg_isid)) { |
@@ -3545,8 +3412,7 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3545 | " matches: %s %s on received I_T Nexus\n", | 3412 | " matches: %s %s on received I_T Nexus\n", |
3546 | initiator_str, iport_ptr, pr_reg_nacl->initiatorname, | 3413 | initiator_str, iport_ptr, pr_reg_nacl->initiatorname, |
3547 | pr_reg->pr_reg_isid); | 3414 | pr_reg->pr_reg_isid); |
3548 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3415 | ret = TCM_INVALID_PARAMETER_LIST; |
3549 | ret = -EINVAL; | ||
3550 | goto out; | 3416 | goto out; |
3551 | } | 3417 | } |
3552 | after_iport_check: | 3418 | after_iport_check: |
@@ -3566,19 +3432,17 @@ after_iport_check: | |||
3566 | pr_err("Unable to locate %s dest_node_acl for" | 3432 | pr_err("Unable to locate %s dest_node_acl for" |
3567 | " TransportID%s\n", dest_tf_ops->get_fabric_name(), | 3433 | " TransportID%s\n", dest_tf_ops->get_fabric_name(), |
3568 | initiator_str); | 3434 | initiator_str); |
3569 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3435 | ret = TCM_INVALID_PARAMETER_LIST; |
3570 | ret = -EINVAL; | ||
3571 | goto out; | 3436 | goto out; |
3572 | } | 3437 | } |
3573 | ret = core_scsi3_nodeacl_depend_item(dest_node_acl); | 3438 | |
3574 | if (ret != 0) { | 3439 | if (core_scsi3_nodeacl_depend_item(dest_node_acl)) { |
3575 | pr_err("core_scsi3_nodeacl_depend_item() for" | 3440 | pr_err("core_scsi3_nodeacl_depend_item() for" |
3576 | " dest_node_acl\n"); | 3441 | " dest_node_acl\n"); |
3577 | atomic_dec(&dest_node_acl->acl_pr_ref_count); | 3442 | atomic_dec(&dest_node_acl->acl_pr_ref_count); |
3578 | smp_mb__after_atomic_dec(); | 3443 | smp_mb__after_atomic_dec(); |
3579 | dest_node_acl = NULL; | 3444 | dest_node_acl = NULL; |
3580 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3445 | ret = TCM_INVALID_PARAMETER_LIST; |
3581 | ret = -EINVAL; | ||
3582 | goto out; | 3446 | goto out; |
3583 | } | 3447 | } |
3584 | 3448 | ||
@@ -3594,19 +3458,16 @@ after_iport_check: | |||
3594 | if (!dest_se_deve) { | 3458 | if (!dest_se_deve) { |
3595 | pr_err("Unable to locate %s dest_se_deve from RTPI:" | 3459 | pr_err("Unable to locate %s dest_se_deve from RTPI:" |
3596 | " %hu\n", dest_tf_ops->get_fabric_name(), rtpi); | 3460 | " %hu\n", dest_tf_ops->get_fabric_name(), rtpi); |
3597 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3461 | ret = TCM_INVALID_PARAMETER_LIST; |
3598 | ret = -EINVAL; | ||
3599 | goto out; | 3462 | goto out; |
3600 | } | 3463 | } |
3601 | 3464 | ||
3602 | ret = core_scsi3_lunacl_depend_item(dest_se_deve); | 3465 | if (core_scsi3_lunacl_depend_item(dest_se_deve)) { |
3603 | if (ret < 0) { | ||
3604 | pr_err("core_scsi3_lunacl_depend_item() failed\n"); | 3466 | pr_err("core_scsi3_lunacl_depend_item() failed\n"); |
3605 | atomic_dec(&dest_se_deve->pr_ref_count); | 3467 | atomic_dec(&dest_se_deve->pr_ref_count); |
3606 | smp_mb__after_atomic_dec(); | 3468 | smp_mb__after_atomic_dec(); |
3607 | dest_se_deve = NULL; | 3469 | dest_se_deve = NULL; |
3608 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 3470 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3609 | ret = -EINVAL; | ||
3610 | goto out; | 3471 | goto out; |
3611 | } | 3472 | } |
3612 | 3473 | ||
@@ -3625,8 +3486,7 @@ after_iport_check: | |||
3625 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: No reservation" | 3486 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: No reservation" |
3626 | " currently held\n"); | 3487 | " currently held\n"); |
3627 | spin_unlock(&dev->dev_reservation_lock); | 3488 | spin_unlock(&dev->dev_reservation_lock); |
3628 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 3489 | ret = TCM_INVALID_CDB_FIELD; |
3629 | ret = -EINVAL; | ||
3630 | goto out; | 3490 | goto out; |
3631 | } | 3491 | } |
3632 | /* | 3492 | /* |
@@ -3639,8 +3499,7 @@ after_iport_check: | |||
3639 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Calling I_T" | 3499 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Calling I_T" |
3640 | " Nexus is not reservation holder\n"); | 3500 | " Nexus is not reservation holder\n"); |
3641 | spin_unlock(&dev->dev_reservation_lock); | 3501 | spin_unlock(&dev->dev_reservation_lock); |
3642 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 3502 | ret = TCM_RESERVATION_CONFLICT; |
3643 | ret = -EINVAL; | ||
3644 | goto out; | 3503 | goto out; |
3645 | } | 3504 | } |
3646 | /* | 3505 | /* |
@@ -3658,8 +3517,7 @@ after_iport_check: | |||
3658 | " reservation for type: %s\n", | 3517 | " reservation for type: %s\n", |
3659 | core_scsi3_pr_dump_type(pr_res_holder->pr_res_type)); | 3518 | core_scsi3_pr_dump_type(pr_res_holder->pr_res_type)); |
3660 | spin_unlock(&dev->dev_reservation_lock); | 3519 | spin_unlock(&dev->dev_reservation_lock); |
3661 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 3520 | ret = TCM_RESERVATION_CONFLICT; |
3662 | ret = -EINVAL; | ||
3663 | goto out; | 3521 | goto out; |
3664 | } | 3522 | } |
3665 | pr_res_nacl = pr_res_holder->pr_reg_nacl; | 3523 | pr_res_nacl = pr_res_holder->pr_reg_nacl; |
@@ -3691,13 +3549,11 @@ after_iport_check: | |||
3691 | dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl, | 3549 | dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl, |
3692 | iport_ptr); | 3550 | iport_ptr); |
3693 | if (!dest_pr_reg) { | 3551 | if (!dest_pr_reg) { |
3694 | ret = core_scsi3_alloc_registration(cmd->se_dev, | 3552 | if (core_scsi3_alloc_registration(cmd->se_dev, |
3695 | dest_node_acl, dest_se_deve, iport_ptr, | 3553 | dest_node_acl, dest_se_deve, iport_ptr, |
3696 | sa_res_key, 0, aptpl, 2, 1); | 3554 | sa_res_key, 0, aptpl, 2, 1)) { |
3697 | if (ret != 0) { | ||
3698 | spin_unlock(&dev->dev_reservation_lock); | 3555 | spin_unlock(&dev->dev_reservation_lock); |
3699 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3556 | ret = TCM_INVALID_PARAMETER_LIST; |
3700 | ret = -EINVAL; | ||
3701 | goto out; | 3557 | goto out; |
3702 | } | 3558 | } |
3703 | dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl, | 3559 | dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl, |
@@ -3768,12 +3624,12 @@ after_iport_check: | |||
3768 | " REGISTER_AND_MOVE\n"); | 3624 | " REGISTER_AND_MOVE\n"); |
3769 | } else { | 3625 | } else { |
3770 | pr_tmpl->pr_aptpl_active = 1; | 3626 | pr_tmpl->pr_aptpl_active = 1; |
3771 | ret = core_scsi3_update_and_write_aptpl(cmd->se_dev, | 3627 | if (!core_scsi3_update_and_write_aptpl(cmd->se_dev, |
3772 | &dest_pr_reg->pr_aptpl_buf[0], | 3628 | &dest_pr_reg->pr_aptpl_buf[0], |
3773 | pr_tmpl->pr_aptpl_buf_len); | 3629 | pr_tmpl->pr_aptpl_buf_len)) { |
3774 | if (!ret) | ||
3775 | pr_debug("SPC-3 PR: Set APTPL Bit Activated for" | 3630 | pr_debug("SPC-3 PR: Set APTPL Bit Activated for" |
3776 | " REGISTER_AND_MOVE\n"); | 3631 | " REGISTER_AND_MOVE\n"); |
3632 | } | ||
3777 | } | 3633 | } |
3778 | 3634 | ||
3779 | transport_kunmap_data_sg(cmd); | 3635 | transport_kunmap_data_sg(cmd); |
@@ -3788,6 +3644,8 @@ out: | |||
3788 | if (dest_node_acl) | 3644 | if (dest_node_acl) |
3789 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 3645 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
3790 | core_scsi3_tpg_undepend_item(dest_se_tpg); | 3646 | core_scsi3_tpg_undepend_item(dest_se_tpg); |
3647 | |||
3648 | out_put_pr_reg: | ||
3791 | core_scsi3_put_pr_reg(pr_reg); | 3649 | core_scsi3_put_pr_reg(pr_reg); |
3792 | return ret; | 3650 | return ret; |
3793 | } | 3651 | } |
@@ -3805,14 +3663,15 @@ static unsigned long long core_scsi3_extract_reservation_key(unsigned char *cdb) | |||
3805 | /* | 3663 | /* |
3806 | * See spc4r17 section 6.14 Table 170 | 3664 | * See spc4r17 section 6.14 Table 170 |
3807 | */ | 3665 | */ |
3808 | int target_scsi3_emulate_pr_out(struct se_cmd *cmd) | 3666 | sense_reason_t |
3667 | target_scsi3_emulate_pr_out(struct se_cmd *cmd) | ||
3809 | { | 3668 | { |
3810 | unsigned char *cdb = &cmd->t_task_cdb[0]; | 3669 | unsigned char *cdb = &cmd->t_task_cdb[0]; |
3811 | unsigned char *buf; | 3670 | unsigned char *buf; |
3812 | u64 res_key, sa_res_key; | 3671 | u64 res_key, sa_res_key; |
3813 | int sa, scope, type, aptpl; | 3672 | int sa, scope, type, aptpl; |
3814 | int spec_i_pt = 0, all_tg_pt = 0, unreg = 0; | 3673 | int spec_i_pt = 0, all_tg_pt = 0, unreg = 0; |
3815 | int ret; | 3674 | sense_reason_t ret; |
3816 | 3675 | ||
3817 | /* | 3676 | /* |
3818 | * Following spc2r20 5.5.1 Reservations overview: | 3677 | * Following spc2r20 5.5.1 Reservations overview: |
@@ -3823,32 +3682,26 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd) | |||
3823 | * initiator or service action and shall terminate with a RESERVATION | 3682 | * initiator or service action and shall terminate with a RESERVATION |
3824 | * CONFLICT status. | 3683 | * CONFLICT status. |
3825 | */ | 3684 | */ |
3826 | if (cmd->se_dev->dev_flags & DF_SPC2_RESERVATIONS) { | 3685 | if (cmd->se_dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) { |
3827 | pr_err("Received PERSISTENT_RESERVE CDB while legacy" | 3686 | pr_err("Received PERSISTENT_RESERVE CDB while legacy" |
3828 | " SPC-2 reservation is held, returning" | 3687 | " SPC-2 reservation is held, returning" |
3829 | " RESERVATION_CONFLICT\n"); | 3688 | " RESERVATION_CONFLICT\n"); |
3830 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 3689 | return TCM_RESERVATION_CONFLICT; |
3831 | ret = -EINVAL; | ||
3832 | goto out; | ||
3833 | } | 3690 | } |
3834 | 3691 | ||
3835 | /* | 3692 | /* |
3836 | * FIXME: A NULL struct se_session pointer means an this is not coming from | 3693 | * FIXME: A NULL struct se_session pointer means an this is not coming from |
3837 | * a $FABRIC_MOD's nexus, but from internal passthrough ops. | 3694 | * a $FABRIC_MOD's nexus, but from internal passthrough ops. |
3838 | */ | 3695 | */ |
3839 | if (!cmd->se_sess) { | 3696 | if (!cmd->se_sess) |
3840 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 3697 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3841 | ret = -EINVAL; | ||
3842 | goto out; | ||
3843 | } | ||
3844 | 3698 | ||
3845 | if (cmd->data_length < 24) { | 3699 | if (cmd->data_length < 24) { |
3846 | pr_warn("SPC-PR: Received PR OUT parameter list" | 3700 | pr_warn("SPC-PR: Received PR OUT parameter list" |
3847 | " length too small: %u\n", cmd->data_length); | 3701 | " length too small: %u\n", cmd->data_length); |
3848 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3702 | return TCM_INVALID_PARAMETER_LIST; |
3849 | ret = -EINVAL; | ||
3850 | goto out; | ||
3851 | } | 3703 | } |
3704 | |||
3852 | /* | 3705 | /* |
3853 | * From the PERSISTENT_RESERVE_OUT command descriptor block (CDB) | 3706 | * From the PERSISTENT_RESERVE_OUT command descriptor block (CDB) |
3854 | */ | 3707 | */ |
@@ -3857,6 +3710,9 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd) | |||
3857 | type = (cdb[2] & 0x0f); | 3710 | type = (cdb[2] & 0x0f); |
3858 | 3711 | ||
3859 | buf = transport_kmap_data_sg(cmd); | 3712 | buf = transport_kmap_data_sg(cmd); |
3713 | if (!buf) | ||
3714 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
3715 | |||
3860 | /* | 3716 | /* |
3861 | * From PERSISTENT_RESERVE_OUT parameter list (payload) | 3717 | * From PERSISTENT_RESERVE_OUT parameter list (payload) |
3862 | */ | 3718 | */ |
@@ -3880,11 +3736,8 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd) | |||
3880 | /* | 3736 | /* |
3881 | * SPEC_I_PT=1 is only valid for Service action: REGISTER | 3737 | * SPEC_I_PT=1 is only valid for Service action: REGISTER |
3882 | */ | 3738 | */ |
3883 | if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER)) { | 3739 | if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER)) |
3884 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3740 | return TCM_INVALID_PARAMETER_LIST; |
3885 | ret = -EINVAL; | ||
3886 | goto out; | ||
3887 | } | ||
3888 | 3741 | ||
3889 | /* | 3742 | /* |
3890 | * From spc4r17 section 6.14: | 3743 | * From spc4r17 section 6.14: |
@@ -3899,10 +3752,9 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd) | |||
3899 | (cmd->data_length != 24)) { | 3752 | (cmd->data_length != 24)) { |
3900 | pr_warn("SPC-PR: Received PR OUT illegal parameter" | 3753 | pr_warn("SPC-PR: Received PR OUT illegal parameter" |
3901 | " list length: %u\n", cmd->data_length); | 3754 | " list length: %u\n", cmd->data_length); |
3902 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3755 | return TCM_INVALID_PARAMETER_LIST; |
3903 | ret = -EINVAL; | ||
3904 | goto out; | ||
3905 | } | 3756 | } |
3757 | |||
3906 | /* | 3758 | /* |
3907 | * (core_scsi3_emulate_pro_* function parameters | 3759 | * (core_scsi3_emulate_pro_* function parameters |
3908 | * are defined by spc4r17 Table 174: | 3760 | * are defined by spc4r17 Table 174: |
@@ -3941,12 +3793,9 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd) | |||
3941 | default: | 3793 | default: |
3942 | pr_err("Unknown PERSISTENT_RESERVE_OUT service" | 3794 | pr_err("Unknown PERSISTENT_RESERVE_OUT service" |
3943 | " action: 0x%02x\n", cdb[1] & 0x1f); | 3795 | " action: 0x%02x\n", cdb[1] & 0x1f); |
3944 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 3796 | return TCM_INVALID_CDB_FIELD; |
3945 | ret = -EINVAL; | ||
3946 | break; | ||
3947 | } | 3797 | } |
3948 | 3798 | ||
3949 | out: | ||
3950 | if (!ret) | 3799 | if (!ret) |
3951 | target_complete_cmd(cmd, GOOD); | 3800 | target_complete_cmd(cmd, GOOD); |
3952 | return ret; | 3801 | return ret; |
@@ -3957,10 +3806,10 @@ out: | |||
3957 | * | 3806 | * |
3958 | * See spc4r17 section 5.7.6.2 and section 6.13.2, Table 160 | 3807 | * See spc4r17 section 5.7.6.2 and section 6.13.2, Table 160 |
3959 | */ | 3808 | */ |
3960 | static int core_scsi3_pri_read_keys(struct se_cmd *cmd) | 3809 | static sense_reason_t |
3810 | core_scsi3_pri_read_keys(struct se_cmd *cmd) | ||
3961 | { | 3811 | { |
3962 | struct se_device *se_dev = cmd->se_dev; | 3812 | struct se_device *dev = cmd->se_dev; |
3963 | struct se_subsystem_dev *su_dev = se_dev->se_sub_dev; | ||
3964 | struct t10_pr_registration *pr_reg; | 3813 | struct t10_pr_registration *pr_reg; |
3965 | unsigned char *buf; | 3814 | unsigned char *buf; |
3966 | u32 add_len = 0, off = 8; | 3815 | u32 add_len = 0, off = 8; |
@@ -3968,18 +3817,20 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd) | |||
3968 | if (cmd->data_length < 8) { | 3817 | if (cmd->data_length < 8) { |
3969 | pr_err("PRIN SA READ_KEYS SCSI Data Length: %u" | 3818 | pr_err("PRIN SA READ_KEYS SCSI Data Length: %u" |
3970 | " too small\n", cmd->data_length); | 3819 | " too small\n", cmd->data_length); |
3971 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 3820 | return TCM_INVALID_CDB_FIELD; |
3972 | return -EINVAL; | ||
3973 | } | 3821 | } |
3974 | 3822 | ||
3975 | buf = transport_kmap_data_sg(cmd); | 3823 | buf = transport_kmap_data_sg(cmd); |
3976 | buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff); | 3824 | if (!buf) |
3977 | buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff); | 3825 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3978 | buf[2] = ((su_dev->t10_pr.pr_generation >> 8) & 0xff); | ||
3979 | buf[3] = (su_dev->t10_pr.pr_generation & 0xff); | ||
3980 | 3826 | ||
3981 | spin_lock(&su_dev->t10_pr.registration_lock); | 3827 | buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff); |
3982 | list_for_each_entry(pr_reg, &su_dev->t10_pr.registration_list, | 3828 | buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff); |
3829 | buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff); | ||
3830 | buf[3] = (dev->t10_pr.pr_generation & 0xff); | ||
3831 | |||
3832 | spin_lock(&dev->t10_pr.registration_lock); | ||
3833 | list_for_each_entry(pr_reg, &dev->t10_pr.registration_list, | ||
3983 | pr_reg_list) { | 3834 | pr_reg_list) { |
3984 | /* | 3835 | /* |
3985 | * Check for overflow of 8byte PRI READ_KEYS payload and | 3836 | * Check for overflow of 8byte PRI READ_KEYS payload and |
@@ -3999,7 +3850,7 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd) | |||
3999 | 3850 | ||
4000 | add_len += 8; | 3851 | add_len += 8; |
4001 | } | 3852 | } |
4002 | spin_unlock(&su_dev->t10_pr.registration_lock); | 3853 | spin_unlock(&dev->t10_pr.registration_lock); |
4003 | 3854 | ||
4004 | buf[4] = ((add_len >> 24) & 0xff); | 3855 | buf[4] = ((add_len >> 24) & 0xff); |
4005 | buf[5] = ((add_len >> 16) & 0xff); | 3856 | buf[5] = ((add_len >> 16) & 0xff); |
@@ -4016,10 +3867,10 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd) | |||
4016 | * | 3867 | * |
4017 | * See spc4r17 section 5.7.6.3 and section 6.13.3.2 Table 161 and 162 | 3868 | * See spc4r17 section 5.7.6.3 and section 6.13.3.2 Table 161 and 162 |
4018 | */ | 3869 | */ |
4019 | static int core_scsi3_pri_read_reservation(struct se_cmd *cmd) | 3870 | static sense_reason_t |
3871 | core_scsi3_pri_read_reservation(struct se_cmd *cmd) | ||
4020 | { | 3872 | { |
4021 | struct se_device *se_dev = cmd->se_dev; | 3873 | struct se_device *dev = cmd->se_dev; |
4022 | struct se_subsystem_dev *su_dev = se_dev->se_sub_dev; | ||
4023 | struct t10_pr_registration *pr_reg; | 3874 | struct t10_pr_registration *pr_reg; |
4024 | unsigned char *buf; | 3875 | unsigned char *buf; |
4025 | u64 pr_res_key; | 3876 | u64 pr_res_key; |
@@ -4028,18 +3879,20 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd) | |||
4028 | if (cmd->data_length < 8) { | 3879 | if (cmd->data_length < 8) { |
4029 | pr_err("PRIN SA READ_RESERVATIONS SCSI Data Length: %u" | 3880 | pr_err("PRIN SA READ_RESERVATIONS SCSI Data Length: %u" |
4030 | " too small\n", cmd->data_length); | 3881 | " too small\n", cmd->data_length); |
4031 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 3882 | return TCM_INVALID_CDB_FIELD; |
4032 | return -EINVAL; | ||
4033 | } | 3883 | } |
4034 | 3884 | ||
4035 | buf = transport_kmap_data_sg(cmd); | 3885 | buf = transport_kmap_data_sg(cmd); |
4036 | buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff); | 3886 | if (!buf) |
4037 | buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff); | 3887 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
4038 | buf[2] = ((su_dev->t10_pr.pr_generation >> 8) & 0xff); | ||
4039 | buf[3] = (su_dev->t10_pr.pr_generation & 0xff); | ||
4040 | 3888 | ||
4041 | spin_lock(&se_dev->dev_reservation_lock); | 3889 | buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff); |
4042 | pr_reg = se_dev->dev_pr_res_holder; | 3890 | buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff); |
3891 | buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff); | ||
3892 | buf[3] = (dev->t10_pr.pr_generation & 0xff); | ||
3893 | |||
3894 | spin_lock(&dev->dev_reservation_lock); | ||
3895 | pr_reg = dev->dev_pr_res_holder; | ||
4043 | if (pr_reg) { | 3896 | if (pr_reg) { |
4044 | /* | 3897 | /* |
4045 | * Set the hardcoded Additional Length | 3898 | * Set the hardcoded Additional Length |
@@ -4090,7 +3943,7 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd) | |||
4090 | } | 3943 | } |
4091 | 3944 | ||
4092 | err: | 3945 | err: |
4093 | spin_unlock(&se_dev->dev_reservation_lock); | 3946 | spin_unlock(&dev->dev_reservation_lock); |
4094 | transport_kunmap_data_sg(cmd); | 3947 | transport_kunmap_data_sg(cmd); |
4095 | 3948 | ||
4096 | return 0; | 3949 | return 0; |
@@ -4101,21 +3954,23 @@ err: | |||
4101 | * | 3954 | * |
4102 | * See spc4r17 section 6.13.4 Table 165 | 3955 | * See spc4r17 section 6.13.4 Table 165 |
4103 | */ | 3956 | */ |
4104 | static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd) | 3957 | static sense_reason_t |
3958 | core_scsi3_pri_report_capabilities(struct se_cmd *cmd) | ||
4105 | { | 3959 | { |
4106 | struct se_device *dev = cmd->se_dev; | 3960 | struct se_device *dev = cmd->se_dev; |
4107 | struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr; | 3961 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
4108 | unsigned char *buf; | 3962 | unsigned char *buf; |
4109 | u16 add_len = 8; /* Hardcoded to 8. */ | 3963 | u16 add_len = 8; /* Hardcoded to 8. */ |
4110 | 3964 | ||
4111 | if (cmd->data_length < 6) { | 3965 | if (cmd->data_length < 6) { |
4112 | pr_err("PRIN SA REPORT_CAPABILITIES SCSI Data Length:" | 3966 | pr_err("PRIN SA REPORT_CAPABILITIES SCSI Data Length:" |
4113 | " %u too small\n", cmd->data_length); | 3967 | " %u too small\n", cmd->data_length); |
4114 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 3968 | return TCM_INVALID_CDB_FIELD; |
4115 | return -EINVAL; | ||
4116 | } | 3969 | } |
4117 | 3970 | ||
4118 | buf = transport_kmap_data_sg(cmd); | 3971 | buf = transport_kmap_data_sg(cmd); |
3972 | if (!buf) | ||
3973 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
4119 | 3974 | ||
4120 | buf[0] = ((add_len << 8) & 0xff); | 3975 | buf[0] = ((add_len << 8) & 0xff); |
4121 | buf[1] = (add_len & 0xff); | 3976 | buf[1] = (add_len & 0xff); |
@@ -4157,14 +4012,14 @@ static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd) | |||
4157 | * | 4012 | * |
4158 | * See spc4r17 section 6.13.5 Table 168 and 169 | 4013 | * See spc4r17 section 6.13.5 Table 168 and 169 |
4159 | */ | 4014 | */ |
4160 | static int core_scsi3_pri_read_full_status(struct se_cmd *cmd) | 4015 | static sense_reason_t |
4016 | core_scsi3_pri_read_full_status(struct se_cmd *cmd) | ||
4161 | { | 4017 | { |
4162 | struct se_device *se_dev = cmd->se_dev; | 4018 | struct se_device *dev = cmd->se_dev; |
4163 | struct se_node_acl *se_nacl; | 4019 | struct se_node_acl *se_nacl; |
4164 | struct se_subsystem_dev *su_dev = se_dev->se_sub_dev; | ||
4165 | struct se_portal_group *se_tpg; | 4020 | struct se_portal_group *se_tpg; |
4166 | struct t10_pr_registration *pr_reg, *pr_reg_tmp; | 4021 | struct t10_pr_registration *pr_reg, *pr_reg_tmp; |
4167 | struct t10_reservation *pr_tmpl = &se_dev->se_sub_dev->t10_pr; | 4022 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
4168 | unsigned char *buf; | 4023 | unsigned char *buf; |
4169 | u32 add_desc_len = 0, add_len = 0, desc_len, exp_desc_len; | 4024 | u32 add_desc_len = 0, add_len = 0, desc_len, exp_desc_len; |
4170 | u32 off = 8; /* off into first Full Status descriptor */ | 4025 | u32 off = 8; /* off into first Full Status descriptor */ |
@@ -4173,16 +4028,17 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd) | |||
4173 | if (cmd->data_length < 8) { | 4028 | if (cmd->data_length < 8) { |
4174 | pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u" | 4029 | pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u" |
4175 | " too small\n", cmd->data_length); | 4030 | " too small\n", cmd->data_length); |
4176 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 4031 | return TCM_INVALID_CDB_FIELD; |
4177 | return -EINVAL; | ||
4178 | } | 4032 | } |
4179 | 4033 | ||
4180 | buf = transport_kmap_data_sg(cmd); | 4034 | buf = transport_kmap_data_sg(cmd); |
4035 | if (!buf) | ||
4036 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
4181 | 4037 | ||
4182 | buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff); | 4038 | buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff); |
4183 | buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff); | 4039 | buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff); |
4184 | buf[2] = ((su_dev->t10_pr.pr_generation >> 8) & 0xff); | 4040 | buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff); |
4185 | buf[3] = (su_dev->t10_pr.pr_generation & 0xff); | 4041 | buf[3] = (dev->t10_pr.pr_generation & 0xff); |
4186 | 4042 | ||
4187 | spin_lock(&pr_tmpl->registration_lock); | 4043 | spin_lock(&pr_tmpl->registration_lock); |
4188 | list_for_each_entry_safe(pr_reg, pr_reg_tmp, | 4044 | list_for_each_entry_safe(pr_reg, pr_reg_tmp, |
@@ -4303,9 +4159,10 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd) | |||
4303 | return 0; | 4159 | return 0; |
4304 | } | 4160 | } |
4305 | 4161 | ||
4306 | int target_scsi3_emulate_pr_in(struct se_cmd *cmd) | 4162 | sense_reason_t |
4163 | target_scsi3_emulate_pr_in(struct se_cmd *cmd) | ||
4307 | { | 4164 | { |
4308 | int ret; | 4165 | sense_reason_t ret; |
4309 | 4166 | ||
4310 | /* | 4167 | /* |
4311 | * Following spc2r20 5.5.1 Reservations overview: | 4168 | * Following spc2r20 5.5.1 Reservations overview: |
@@ -4316,12 +4173,11 @@ int target_scsi3_emulate_pr_in(struct se_cmd *cmd) | |||
4316 | * initiator or service action and shall terminate with a RESERVATION | 4173 | * initiator or service action and shall terminate with a RESERVATION |
4317 | * CONFLICT status. | 4174 | * CONFLICT status. |
4318 | */ | 4175 | */ |
4319 | if (cmd->se_dev->dev_flags & DF_SPC2_RESERVATIONS) { | 4176 | if (cmd->se_dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) { |
4320 | pr_err("Received PERSISTENT_RESERVE CDB while legacy" | 4177 | pr_err("Received PERSISTENT_RESERVE CDB while legacy" |
4321 | " SPC-2 reservation is held, returning" | 4178 | " SPC-2 reservation is held, returning" |
4322 | " RESERVATION_CONFLICT\n"); | 4179 | " RESERVATION_CONFLICT\n"); |
4323 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 4180 | return TCM_RESERVATION_CONFLICT; |
4324 | return -EINVAL; | ||
4325 | } | 4181 | } |
4326 | 4182 | ||
4327 | switch (cmd->t_task_cdb[1] & 0x1f) { | 4183 | switch (cmd->t_task_cdb[1] & 0x1f) { |
@@ -4340,9 +4196,7 @@ int target_scsi3_emulate_pr_in(struct se_cmd *cmd) | |||
4340 | default: | 4196 | default: |
4341 | pr_err("Unknown PERSISTENT_RESERVE_IN service" | 4197 | pr_err("Unknown PERSISTENT_RESERVE_IN service" |
4342 | " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f); | 4198 | " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f); |
4343 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 4199 | return TCM_INVALID_CDB_FIELD; |
4344 | ret = -EINVAL; | ||
4345 | break; | ||
4346 | } | 4200 | } |
4347 | 4201 | ||
4348 | if (!ret) | 4202 | if (!ret) |
@@ -4350,56 +4204,25 @@ int target_scsi3_emulate_pr_in(struct se_cmd *cmd) | |||
4350 | return ret; | 4204 | return ret; |
4351 | } | 4205 | } |
4352 | 4206 | ||
4353 | static int core_pt_reservation_check(struct se_cmd *cmd, u32 *pr_res_type) | 4207 | sense_reason_t |
4354 | { | 4208 | target_check_reservation(struct se_cmd *cmd) |
4355 | return 0; | ||
4356 | } | ||
4357 | |||
4358 | static int core_pt_seq_non_holder( | ||
4359 | struct se_cmd *cmd, | ||
4360 | unsigned char *cdb, | ||
4361 | u32 pr_reg_type) | ||
4362 | { | 4209 | { |
4363 | return 0; | 4210 | struct se_device *dev = cmd->se_dev; |
4364 | } | 4211 | sense_reason_t ret; |
4365 | 4212 | ||
4366 | int core_setup_reservations(struct se_device *dev, int force_pt) | 4213 | if (!cmd->se_sess) |
4367 | { | 4214 | return 0; |
4368 | struct se_subsystem_dev *su_dev = dev->se_sub_dev; | 4215 | if (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE) |
4369 | struct t10_reservation *rest = &su_dev->t10_pr; | 4216 | return 0; |
4370 | /* | 4217 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) |
4371 | * If this device is from Target_Core_Mod/pSCSI, use the reservations | ||
4372 | * of the Underlying SCSI hardware. In Linux/SCSI terms, this can | ||
4373 | * cause a problem because libata and some SATA RAID HBAs appear | ||
4374 | * under Linux/SCSI, but to emulate reservations themselves. | ||
4375 | */ | ||
4376 | if (((dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) && | ||
4377 | !(dev->se_sub_dev->se_dev_attrib.emulate_reservations)) || force_pt) { | ||
4378 | rest->res_type = SPC_PASSTHROUGH; | ||
4379 | rest->pr_ops.t10_reservation_check = &core_pt_reservation_check; | ||
4380 | rest->pr_ops.t10_seq_non_holder = &core_pt_seq_non_holder; | ||
4381 | pr_debug("%s: Using SPC_PASSTHROUGH, no reservation" | ||
4382 | " emulation\n", dev->transport->name); | ||
4383 | return 0; | 4218 | return 0; |
4384 | } | ||
4385 | /* | ||
4386 | * If SPC-3 or above is reported by real or emulated struct se_device, | ||
4387 | * use emulated Persistent Reservations. | ||
4388 | */ | ||
4389 | if (dev->transport->get_device_rev(dev) >= SCSI_3) { | ||
4390 | rest->res_type = SPC3_PERSISTENT_RESERVATIONS; | ||
4391 | rest->pr_ops.t10_reservation_check = &core_scsi3_pr_reservation_check; | ||
4392 | rest->pr_ops.t10_seq_non_holder = &core_scsi3_pr_seq_non_holder; | ||
4393 | pr_debug("%s: Using SPC3_PERSISTENT_RESERVATIONS" | ||
4394 | " emulation\n", dev->transport->name); | ||
4395 | } else { | ||
4396 | rest->res_type = SPC2_RESERVATIONS; | ||
4397 | rest->pr_ops.t10_reservation_check = &core_scsi2_reservation_check; | ||
4398 | rest->pr_ops.t10_seq_non_holder = | ||
4399 | &core_scsi2_reservation_seq_non_holder; | ||
4400 | pr_debug("%s: Using SPC2_RESERVATIONS emulation\n", | ||
4401 | dev->transport->name); | ||
4402 | } | ||
4403 | 4219 | ||
4404 | return 0; | 4220 | spin_lock(&dev->dev_reservation_lock); |
4221 | if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) | ||
4222 | ret = target_scsi2_reservation_check(cmd); | ||
4223 | else | ||
4224 | ret = target_scsi3_pr_reservation_check(cmd); | ||
4225 | spin_unlock(&dev->dev_reservation_lock); | ||
4226 | |||
4227 | return ret; | ||
4405 | } | 4228 | } |
diff --git a/drivers/target/target_core_pr.h b/drivers/target/target_core_pr.h index af6c460d886d..b4a004247ab2 100644 --- a/drivers/target/target_core_pr.h +++ b/drivers/target/target_core_pr.h | |||
@@ -47,8 +47,8 @@ extern struct kmem_cache *t10_pr_reg_cache; | |||
47 | 47 | ||
48 | extern int core_pr_dump_initiator_port(struct t10_pr_registration *, | 48 | extern int core_pr_dump_initiator_port(struct t10_pr_registration *, |
49 | char *, u32); | 49 | char *, u32); |
50 | extern int target_scsi2_reservation_release(struct se_cmd *); | 50 | extern sense_reason_t target_scsi2_reservation_release(struct se_cmd *); |
51 | extern int target_scsi2_reservation_reserve(struct se_cmd *); | 51 | extern sense_reason_t target_scsi2_reservation_reserve(struct se_cmd *); |
52 | extern int core_scsi3_alloc_aptpl_registration( | 52 | extern int core_scsi3_alloc_aptpl_registration( |
53 | struct t10_reservation *, u64, | 53 | struct t10_reservation *, u64, |
54 | unsigned char *, unsigned char *, u32, | 54 | unsigned char *, unsigned char *, u32, |
@@ -61,8 +61,8 @@ extern void core_scsi3_free_pr_reg_from_nacl(struct se_device *, | |||
61 | extern void core_scsi3_free_all_registrations(struct se_device *); | 61 | extern void core_scsi3_free_all_registrations(struct se_device *); |
62 | extern unsigned char *core_scsi3_pr_dump_type(int); | 62 | extern unsigned char *core_scsi3_pr_dump_type(int); |
63 | 63 | ||
64 | extern int target_scsi3_emulate_pr_in(struct se_cmd *); | 64 | extern sense_reason_t target_scsi3_emulate_pr_in(struct se_cmd *); |
65 | extern int target_scsi3_emulate_pr_out(struct se_cmd *); | 65 | extern sense_reason_t target_scsi3_emulate_pr_out(struct se_cmd *); |
66 | extern int core_setup_reservations(struct se_device *, int); | 66 | extern sense_reason_t target_check_reservation(struct se_cmd *); |
67 | 67 | ||
68 | #endif /* TARGET_CORE_PR_H */ | 68 | #endif /* TARGET_CORE_PR_H */ |
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 617c086a8a02..2bcfd79cf595 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c | |||
@@ -3,10 +3,7 @@ | |||
3 | * | 3 | * |
4 | * This file contains the generic target mode <-> Linux SCSI subsystem plugin. | 4 | * This file contains the generic target mode <-> Linux SCSI subsystem plugin. |
5 | * | 5 | * |
6 | * Copyright (c) 2003, 2004, 2005 PyX Technologies, Inc. | 6 | * (c) Copyright 2003-2012 RisingTide Systems LLC. |
7 | * Copyright (c) 2005, 2006, 2007 SBE, Inc. | ||
8 | * Copyright (c) 2007-2010 Rising Tide Systems | ||
9 | * Copyright (c) 2008-2010 Linux-iSCSI.org | ||
10 | * | 7 | * |
11 | * Nicholas A. Bellinger <nab@kernel.org> | 8 | * Nicholas A. Bellinger <nab@kernel.org> |
12 | * | 9 | * |
@@ -53,9 +50,14 @@ | |||
53 | 50 | ||
54 | #define ISPRINT(a) ((a >= ' ') && (a <= '~')) | 51 | #define ISPRINT(a) ((a >= ' ') && (a <= '~')) |
55 | 52 | ||
53 | static inline struct pscsi_dev_virt *PSCSI_DEV(struct se_device *dev) | ||
54 | { | ||
55 | return container_of(dev, struct pscsi_dev_virt, dev); | ||
56 | } | ||
57 | |||
56 | static struct se_subsystem_api pscsi_template; | 58 | static struct se_subsystem_api pscsi_template; |
57 | 59 | ||
58 | static int pscsi_execute_cmd(struct se_cmd *cmd); | 60 | static sense_reason_t pscsi_execute_cmd(struct se_cmd *cmd); |
59 | static void pscsi_req_done(struct request *, int); | 61 | static void pscsi_req_done(struct request *, int); |
60 | 62 | ||
61 | /* pscsi_attach_hba(): | 63 | /* pscsi_attach_hba(): |
@@ -219,7 +221,7 @@ pscsi_get_inquiry_vpd_serial(struct scsi_device *sdev, struct t10_wwn *wwn) | |||
219 | 221 | ||
220 | snprintf(&wwn->unit_serial[0], INQUIRY_VPD_SERIAL_LEN, "%s", &buf[4]); | 222 | snprintf(&wwn->unit_serial[0], INQUIRY_VPD_SERIAL_LEN, "%s", &buf[4]); |
221 | 223 | ||
222 | wwn->t10_sub_dev->su_dev_flags |= SDF_FIRMWARE_VPD_UNIT_SERIAL; | 224 | wwn->t10_dev->dev_flags |= DF_FIRMWARE_VPD_UNIT_SERIAL; |
223 | 225 | ||
224 | kfree(buf); | 226 | kfree(buf); |
225 | return 0; | 227 | return 0; |
@@ -299,23 +301,13 @@ out: | |||
299 | kfree(buf); | 301 | kfree(buf); |
300 | } | 302 | } |
301 | 303 | ||
302 | /* pscsi_add_device_to_list(): | 304 | static int pscsi_add_device_to_list(struct se_device *dev, |
303 | * | 305 | struct scsi_device *sd) |
304 | * | ||
305 | */ | ||
306 | static struct se_device *pscsi_add_device_to_list( | ||
307 | struct se_hba *hba, | ||
308 | struct se_subsystem_dev *se_dev, | ||
309 | struct pscsi_dev_virt *pdv, | ||
310 | struct scsi_device *sd, | ||
311 | int dev_flags) | ||
312 | { | 306 | { |
313 | struct se_device *dev; | 307 | struct pscsi_dev_virt *pdv = PSCSI_DEV(dev); |
314 | struct se_dev_limits dev_limits; | 308 | struct request_queue *q = sd->request_queue; |
315 | struct request_queue *q; | ||
316 | struct queue_limits *limits; | ||
317 | 309 | ||
318 | memset(&dev_limits, 0, sizeof(struct se_dev_limits)); | 310 | pdv->pdv_sd = sd; |
319 | 311 | ||
320 | if (!sd->queue_depth) { | 312 | if (!sd->queue_depth) { |
321 | sd->queue_depth = PSCSI_DEFAULT_QUEUEDEPTH; | 313 | sd->queue_depth = PSCSI_DEFAULT_QUEUEDEPTH; |
@@ -324,54 +316,27 @@ static struct se_device *pscsi_add_device_to_list( | |||
324 | " queue_depth to %d\n", sd->channel, sd->id, | 316 | " queue_depth to %d\n", sd->channel, sd->id, |
325 | sd->lun, sd->queue_depth); | 317 | sd->lun, sd->queue_depth); |
326 | } | 318 | } |
327 | /* | 319 | |
328 | * Setup the local scope queue_limits from struct request_queue->limits | 320 | dev->dev_attrib.hw_block_size = sd->sector_size; |
329 | * to pass into transport_add_device_to_core_hba() as struct se_dev_limits. | 321 | dev->dev_attrib.hw_max_sectors = |
330 | */ | 322 | min_t(int, sd->host->max_sectors, queue_max_hw_sectors(q)); |
331 | q = sd->request_queue; | 323 | dev->dev_attrib.hw_queue_depth = sd->queue_depth; |
332 | limits = &dev_limits.limits; | ||
333 | limits->logical_block_size = sd->sector_size; | ||
334 | limits->max_hw_sectors = min_t(int, sd->host->max_sectors, queue_max_hw_sectors(q)); | ||
335 | limits->max_sectors = min_t(int, sd->host->max_sectors, queue_max_sectors(q)); | ||
336 | dev_limits.hw_queue_depth = sd->queue_depth; | ||
337 | dev_limits.queue_depth = sd->queue_depth; | ||
338 | /* | ||
339 | * Setup our standard INQUIRY info into se_dev->t10_wwn | ||
340 | */ | ||
341 | pscsi_set_inquiry_info(sd, &se_dev->t10_wwn); | ||
342 | 324 | ||
343 | /* | 325 | /* |
344 | * Set the pointer pdv->pdv_sd to from passed struct scsi_device, | 326 | * Setup our standard INQUIRY info into se_dev->t10_wwn |
345 | * which has already been referenced with Linux SCSI code with | ||
346 | * scsi_device_get() in this file's pscsi_create_virtdevice(). | ||
347 | * | ||
348 | * The passthrough operations called by the transport_add_device_* | ||
349 | * function below will require this pointer to be set for passthroug | ||
350 | * ops. | ||
351 | * | ||
352 | * For the shutdown case in pscsi_free_device(), this struct | ||
353 | * scsi_device reference is released with Linux SCSI code | ||
354 | * scsi_device_put() and the pdv->pdv_sd cleared. | ||
355 | */ | 327 | */ |
356 | pdv->pdv_sd = sd; | 328 | pscsi_set_inquiry_info(sd, &dev->t10_wwn); |
357 | dev = transport_add_device_to_core_hba(hba, &pscsi_template, | ||
358 | se_dev, dev_flags, pdv, | ||
359 | &dev_limits, NULL, NULL); | ||
360 | if (!dev) { | ||
361 | pdv->pdv_sd = NULL; | ||
362 | return NULL; | ||
363 | } | ||
364 | 329 | ||
365 | /* | 330 | /* |
366 | * Locate VPD WWN Information used for various purposes within | 331 | * Locate VPD WWN Information used for various purposes within |
367 | * the Storage Engine. | 332 | * the Storage Engine. |
368 | */ | 333 | */ |
369 | if (!pscsi_get_inquiry_vpd_serial(sd, &se_dev->t10_wwn)) { | 334 | if (!pscsi_get_inquiry_vpd_serial(sd, &dev->t10_wwn)) { |
370 | /* | 335 | /* |
371 | * If VPD Unit Serial returned GOOD status, try | 336 | * If VPD Unit Serial returned GOOD status, try |
372 | * VPD Device Identification page (0x83). | 337 | * VPD Device Identification page (0x83). |
373 | */ | 338 | */ |
374 | pscsi_get_inquiry_vpd_device_ident(sd, &se_dev->t10_wwn); | 339 | pscsi_get_inquiry_vpd_device_ident(sd, &dev->t10_wwn); |
375 | } | 340 | } |
376 | 341 | ||
377 | /* | 342 | /* |
@@ -379,10 +344,11 @@ static struct se_device *pscsi_add_device_to_list( | |||
379 | */ | 344 | */ |
380 | if (sd->type == TYPE_TAPE) | 345 | if (sd->type == TYPE_TAPE) |
381 | pscsi_tape_read_blocksize(dev, sd); | 346 | pscsi_tape_read_blocksize(dev, sd); |
382 | return dev; | 347 | return 0; |
383 | } | 348 | } |
384 | 349 | ||
385 | static void *pscsi_allocate_virtdevice(struct se_hba *hba, const char *name) | 350 | static struct se_device *pscsi_alloc_device(struct se_hba *hba, |
351 | const char *name) | ||
386 | { | 352 | { |
387 | struct pscsi_dev_virt *pdv; | 353 | struct pscsi_dev_virt *pdv; |
388 | 354 | ||
@@ -391,139 +357,125 @@ static void *pscsi_allocate_virtdevice(struct se_hba *hba, const char *name) | |||
391 | pr_err("Unable to allocate memory for struct pscsi_dev_virt\n"); | 357 | pr_err("Unable to allocate memory for struct pscsi_dev_virt\n"); |
392 | return NULL; | 358 | return NULL; |
393 | } | 359 | } |
394 | pdv->pdv_se_hba = hba; | ||
395 | 360 | ||
396 | pr_debug("PSCSI: Allocated pdv: %p for %s\n", pdv, name); | 361 | pr_debug("PSCSI: Allocated pdv: %p for %s\n", pdv, name); |
397 | return pdv; | 362 | return &pdv->dev; |
398 | } | 363 | } |
399 | 364 | ||
400 | /* | 365 | /* |
401 | * Called with struct Scsi_Host->host_lock called. | 366 | * Called with struct Scsi_Host->host_lock called. |
402 | */ | 367 | */ |
403 | static struct se_device *pscsi_create_type_disk( | 368 | static int pscsi_create_type_disk(struct se_device *dev, struct scsi_device *sd) |
404 | struct scsi_device *sd, | ||
405 | struct pscsi_dev_virt *pdv, | ||
406 | struct se_subsystem_dev *se_dev, | ||
407 | struct se_hba *hba) | ||
408 | __releases(sh->host_lock) | 369 | __releases(sh->host_lock) |
409 | { | 370 | { |
410 | struct se_device *dev; | 371 | struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; |
411 | struct pscsi_hba_virt *phv = pdv->pdv_se_hba->hba_ptr; | 372 | struct pscsi_dev_virt *pdv = PSCSI_DEV(dev); |
412 | struct Scsi_Host *sh = sd->host; | 373 | struct Scsi_Host *sh = sd->host; |
413 | struct block_device *bd; | 374 | struct block_device *bd; |
414 | u32 dev_flags = 0; | 375 | int ret; |
415 | 376 | ||
416 | if (scsi_device_get(sd)) { | 377 | if (scsi_device_get(sd)) { |
417 | pr_err("scsi_device_get() failed for %d:%d:%d:%d\n", | 378 | pr_err("scsi_device_get() failed for %d:%d:%d:%d\n", |
418 | sh->host_no, sd->channel, sd->id, sd->lun); | 379 | sh->host_no, sd->channel, sd->id, sd->lun); |
419 | spin_unlock_irq(sh->host_lock); | 380 | spin_unlock_irq(sh->host_lock); |
420 | return NULL; | 381 | return -EIO; |
421 | } | 382 | } |
422 | spin_unlock_irq(sh->host_lock); | 383 | spin_unlock_irq(sh->host_lock); |
423 | /* | 384 | /* |
424 | * Claim exclusive struct block_device access to struct scsi_device | 385 | * Claim exclusive struct block_device access to struct scsi_device |
425 | * for TYPE_DISK using supplied udev_path | 386 | * for TYPE_DISK using supplied udev_path |
426 | */ | 387 | */ |
427 | bd = blkdev_get_by_path(se_dev->se_dev_udev_path, | 388 | bd = blkdev_get_by_path(dev->udev_path, |
428 | FMODE_WRITE|FMODE_READ|FMODE_EXCL, pdv); | 389 | FMODE_WRITE|FMODE_READ|FMODE_EXCL, pdv); |
429 | if (IS_ERR(bd)) { | 390 | if (IS_ERR(bd)) { |
430 | pr_err("pSCSI: blkdev_get_by_path() failed\n"); | 391 | pr_err("pSCSI: blkdev_get_by_path() failed\n"); |
431 | scsi_device_put(sd); | 392 | scsi_device_put(sd); |
432 | return NULL; | 393 | return PTR_ERR(bd); |
433 | } | 394 | } |
434 | pdv->pdv_bd = bd; | 395 | pdv->pdv_bd = bd; |
435 | 396 | ||
436 | dev = pscsi_add_device_to_list(hba, se_dev, pdv, sd, dev_flags); | 397 | ret = pscsi_add_device_to_list(dev, sd); |
437 | if (!dev) { | 398 | if (ret) { |
438 | blkdev_put(pdv->pdv_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL); | 399 | blkdev_put(pdv->pdv_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL); |
439 | scsi_device_put(sd); | 400 | scsi_device_put(sd); |
440 | return NULL; | 401 | return ret; |
441 | } | 402 | } |
403 | |||
442 | pr_debug("CORE_PSCSI[%d] - Added TYPE_DISK for %d:%d:%d:%d\n", | 404 | pr_debug("CORE_PSCSI[%d] - Added TYPE_DISK for %d:%d:%d:%d\n", |
443 | phv->phv_host_id, sh->host_no, sd->channel, sd->id, sd->lun); | 405 | phv->phv_host_id, sh->host_no, sd->channel, sd->id, sd->lun); |
444 | 406 | return 0; | |
445 | return dev; | ||
446 | } | 407 | } |
447 | 408 | ||
448 | /* | 409 | /* |
449 | * Called with struct Scsi_Host->host_lock called. | 410 | * Called with struct Scsi_Host->host_lock called. |
450 | */ | 411 | */ |
451 | static struct se_device *pscsi_create_type_rom( | 412 | static int pscsi_create_type_rom(struct se_device *dev, struct scsi_device *sd) |
452 | struct scsi_device *sd, | ||
453 | struct pscsi_dev_virt *pdv, | ||
454 | struct se_subsystem_dev *se_dev, | ||
455 | struct se_hba *hba) | ||
456 | __releases(sh->host_lock) | 413 | __releases(sh->host_lock) |
457 | { | 414 | { |
458 | struct se_device *dev; | 415 | struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; |
459 | struct pscsi_hba_virt *phv = pdv->pdv_se_hba->hba_ptr; | ||
460 | struct Scsi_Host *sh = sd->host; | 416 | struct Scsi_Host *sh = sd->host; |
461 | u32 dev_flags = 0; | 417 | int ret; |
462 | 418 | ||
463 | if (scsi_device_get(sd)) { | 419 | if (scsi_device_get(sd)) { |
464 | pr_err("scsi_device_get() failed for %d:%d:%d:%d\n", | 420 | pr_err("scsi_device_get() failed for %d:%d:%d:%d\n", |
465 | sh->host_no, sd->channel, sd->id, sd->lun); | 421 | sh->host_no, sd->channel, sd->id, sd->lun); |
466 | spin_unlock_irq(sh->host_lock); | 422 | spin_unlock_irq(sh->host_lock); |
467 | return NULL; | 423 | return -EIO; |
468 | } | 424 | } |
469 | spin_unlock_irq(sh->host_lock); | 425 | spin_unlock_irq(sh->host_lock); |
470 | 426 | ||
471 | dev = pscsi_add_device_to_list(hba, se_dev, pdv, sd, dev_flags); | 427 | ret = pscsi_add_device_to_list(dev, sd); |
472 | if (!dev) { | 428 | if (ret) { |
473 | scsi_device_put(sd); | 429 | scsi_device_put(sd); |
474 | return NULL; | 430 | return ret; |
475 | } | 431 | } |
476 | pr_debug("CORE_PSCSI[%d] - Added Type: %s for %d:%d:%d:%d\n", | 432 | pr_debug("CORE_PSCSI[%d] - Added Type: %s for %d:%d:%d:%d\n", |
477 | phv->phv_host_id, scsi_device_type(sd->type), sh->host_no, | 433 | phv->phv_host_id, scsi_device_type(sd->type), sh->host_no, |
478 | sd->channel, sd->id, sd->lun); | 434 | sd->channel, sd->id, sd->lun); |
479 | 435 | ||
480 | return dev; | 436 | return 0; |
481 | } | 437 | } |
482 | 438 | ||
483 | /* | 439 | /* |
484 | *Called with struct Scsi_Host->host_lock called. | 440 | * Called with struct Scsi_Host->host_lock called. |
485 | */ | 441 | */ |
486 | static struct se_device *pscsi_create_type_other( | 442 | static int pscsi_create_type_other(struct se_device *dev, |
487 | struct scsi_device *sd, | 443 | struct scsi_device *sd) |
488 | struct pscsi_dev_virt *pdv, | ||
489 | struct se_subsystem_dev *se_dev, | ||
490 | struct se_hba *hba) | ||
491 | __releases(sh->host_lock) | 444 | __releases(sh->host_lock) |
492 | { | 445 | { |
493 | struct se_device *dev; | 446 | struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; |
494 | struct pscsi_hba_virt *phv = pdv->pdv_se_hba->hba_ptr; | ||
495 | struct Scsi_Host *sh = sd->host; | 447 | struct Scsi_Host *sh = sd->host; |
496 | u32 dev_flags = 0; | 448 | int ret; |
497 | 449 | ||
498 | spin_unlock_irq(sh->host_lock); | 450 | spin_unlock_irq(sh->host_lock); |
499 | dev = pscsi_add_device_to_list(hba, se_dev, pdv, sd, dev_flags); | 451 | ret = pscsi_add_device_to_list(dev, sd); |
500 | if (!dev) | 452 | if (ret) |
501 | return NULL; | 453 | return ret; |
502 | 454 | ||
503 | pr_debug("CORE_PSCSI[%d] - Added Type: %s for %d:%d:%d:%d\n", | 455 | pr_debug("CORE_PSCSI[%d] - Added Type: %s for %d:%d:%d:%d\n", |
504 | phv->phv_host_id, scsi_device_type(sd->type), sh->host_no, | 456 | phv->phv_host_id, scsi_device_type(sd->type), sh->host_no, |
505 | sd->channel, sd->id, sd->lun); | 457 | sd->channel, sd->id, sd->lun); |
506 | 458 | return 0; | |
507 | return dev; | ||
508 | } | 459 | } |
509 | 460 | ||
510 | static struct se_device *pscsi_create_virtdevice( | 461 | static int pscsi_configure_device(struct se_device *dev) |
511 | struct se_hba *hba, | ||
512 | struct se_subsystem_dev *se_dev, | ||
513 | void *p) | ||
514 | { | 462 | { |
515 | struct pscsi_dev_virt *pdv = p; | 463 | struct se_hba *hba = dev->se_hba; |
516 | struct se_device *dev; | 464 | struct pscsi_dev_virt *pdv = PSCSI_DEV(dev); |
517 | struct scsi_device *sd; | 465 | struct scsi_device *sd; |
518 | struct pscsi_hba_virt *phv = hba->hba_ptr; | 466 | struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; |
519 | struct Scsi_Host *sh = phv->phv_lld_host; | 467 | struct Scsi_Host *sh = phv->phv_lld_host; |
520 | int legacy_mode_enable = 0; | 468 | int legacy_mode_enable = 0; |
469 | int ret; | ||
521 | 470 | ||
522 | if (!pdv) { | 471 | if (!(pdv->pdv_flags & PDF_HAS_CHANNEL_ID) || |
523 | pr_err("Unable to locate struct pscsi_dev_virt" | 472 | !(pdv->pdv_flags & PDF_HAS_TARGET_ID) || |
524 | " parameter\n"); | 473 | !(pdv->pdv_flags & PDF_HAS_LUN_ID)) { |
525 | return ERR_PTR(-EINVAL); | 474 | pr_err("Missing scsi_channel_id=, scsi_target_id= and" |
475 | " scsi_lun_id= parameters\n"); | ||
476 | return -EINVAL; | ||
526 | } | 477 | } |
478 | |||
527 | /* | 479 | /* |
528 | * If not running in PHV_LLD_SCSI_HOST_NO mode, locate the | 480 | * If not running in PHV_LLD_SCSI_HOST_NO mode, locate the |
529 | * struct Scsi_Host we will need to bring the TCM/pSCSI object online | 481 | * struct Scsi_Host we will need to bring the TCM/pSCSI object online |
@@ -532,16 +484,16 @@ static struct se_device *pscsi_create_virtdevice( | |||
532 | if (phv->phv_mode == PHV_LLD_SCSI_HOST_NO) { | 484 | if (phv->phv_mode == PHV_LLD_SCSI_HOST_NO) { |
533 | pr_err("pSCSI: Unable to locate struct" | 485 | pr_err("pSCSI: Unable to locate struct" |
534 | " Scsi_Host for PHV_LLD_SCSI_HOST_NO\n"); | 486 | " Scsi_Host for PHV_LLD_SCSI_HOST_NO\n"); |
535 | return ERR_PTR(-ENODEV); | 487 | return -ENODEV; |
536 | } | 488 | } |
537 | /* | 489 | /* |
538 | * For the newer PHV_VIRTUAL_HOST_ID struct scsi_device | 490 | * For the newer PHV_VIRTUAL_HOST_ID struct scsi_device |
539 | * reference, we enforce that udev_path has been set | 491 | * reference, we enforce that udev_path has been set |
540 | */ | 492 | */ |
541 | if (!(se_dev->su_dev_flags & SDF_USING_UDEV_PATH)) { | 493 | if (!(dev->dev_flags & DF_USING_UDEV_PATH)) { |
542 | pr_err("pSCSI: udev_path attribute has not" | 494 | pr_err("pSCSI: udev_path attribute has not" |
543 | " been set before ENABLE=1\n"); | 495 | " been set before ENABLE=1\n"); |
544 | return ERR_PTR(-EINVAL); | 496 | return -EINVAL; |
545 | } | 497 | } |
546 | /* | 498 | /* |
547 | * If no scsi_host_id= was passed for PHV_VIRTUAL_HOST_ID, | 499 | * If no scsi_host_id= was passed for PHV_VIRTUAL_HOST_ID, |
@@ -549,17 +501,14 @@ static struct se_device *pscsi_create_virtdevice( | |||
549 | * and enable for PHV_LLD_SCSI_HOST_NO mode. | 501 | * and enable for PHV_LLD_SCSI_HOST_NO mode. |
550 | */ | 502 | */ |
551 | if (!(pdv->pdv_flags & PDF_HAS_VIRT_HOST_ID)) { | 503 | if (!(pdv->pdv_flags & PDF_HAS_VIRT_HOST_ID)) { |
552 | spin_lock(&hba->device_lock); | 504 | if (hba->dev_count) { |
553 | if (!list_empty(&hba->hba_dev_list)) { | ||
554 | pr_err("pSCSI: Unable to set hba_mode" | 505 | pr_err("pSCSI: Unable to set hba_mode" |
555 | " with active devices\n"); | 506 | " with active devices\n"); |
556 | spin_unlock(&hba->device_lock); | 507 | return -EEXIST; |
557 | return ERR_PTR(-EEXIST); | ||
558 | } | 508 | } |
559 | spin_unlock(&hba->device_lock); | ||
560 | 509 | ||
561 | if (pscsi_pmode_enable_hba(hba, 1) != 1) | 510 | if (pscsi_pmode_enable_hba(hba, 1) != 1) |
562 | return ERR_PTR(-ENODEV); | 511 | return -ENODEV; |
563 | 512 | ||
564 | legacy_mode_enable = 1; | 513 | legacy_mode_enable = 1; |
565 | hba->hba_flags |= HBA_FLAGS_PSCSI_MODE; | 514 | hba->hba_flags |= HBA_FLAGS_PSCSI_MODE; |
@@ -569,14 +518,14 @@ static struct se_device *pscsi_create_virtdevice( | |||
569 | if (IS_ERR(sh)) { | 518 | if (IS_ERR(sh)) { |
570 | pr_err("pSCSI: Unable to locate" | 519 | pr_err("pSCSI: Unable to locate" |
571 | " pdv_host_id: %d\n", pdv->pdv_host_id); | 520 | " pdv_host_id: %d\n", pdv->pdv_host_id); |
572 | return ERR_CAST(sh); | 521 | return PTR_ERR(sh); |
573 | } | 522 | } |
574 | } | 523 | } |
575 | } else { | 524 | } else { |
576 | if (phv->phv_mode == PHV_VIRTUAL_HOST_ID) { | 525 | if (phv->phv_mode == PHV_VIRTUAL_HOST_ID) { |
577 | pr_err("pSCSI: PHV_VIRTUAL_HOST_ID set while" | 526 | pr_err("pSCSI: PHV_VIRTUAL_HOST_ID set while" |
578 | " struct Scsi_Host exists\n"); | 527 | " struct Scsi_Host exists\n"); |
579 | return ERR_PTR(-EEXIST); | 528 | return -EEXIST; |
580 | } | 529 | } |
581 | } | 530 | } |
582 | 531 | ||
@@ -593,17 +542,17 @@ static struct se_device *pscsi_create_virtdevice( | |||
593 | */ | 542 | */ |
594 | switch (sd->type) { | 543 | switch (sd->type) { |
595 | case TYPE_DISK: | 544 | case TYPE_DISK: |
596 | dev = pscsi_create_type_disk(sd, pdv, se_dev, hba); | 545 | ret = pscsi_create_type_disk(dev, sd); |
597 | break; | 546 | break; |
598 | case TYPE_ROM: | 547 | case TYPE_ROM: |
599 | dev = pscsi_create_type_rom(sd, pdv, se_dev, hba); | 548 | ret = pscsi_create_type_rom(dev, sd); |
600 | break; | 549 | break; |
601 | default: | 550 | default: |
602 | dev = pscsi_create_type_other(sd, pdv, se_dev, hba); | 551 | ret = pscsi_create_type_other(dev, sd); |
603 | break; | 552 | break; |
604 | } | 553 | } |
605 | 554 | ||
606 | if (!dev) { | 555 | if (ret) { |
607 | if (phv->phv_mode == PHV_VIRTUAL_HOST_ID) | 556 | if (phv->phv_mode == PHV_VIRTUAL_HOST_ID) |
608 | scsi_host_put(sh); | 557 | scsi_host_put(sh); |
609 | else if (legacy_mode_enable) { | 558 | else if (legacy_mode_enable) { |
@@ -611,9 +560,9 @@ static struct se_device *pscsi_create_virtdevice( | |||
611 | hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE; | 560 | hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE; |
612 | } | 561 | } |
613 | pdv->pdv_sd = NULL; | 562 | pdv->pdv_sd = NULL; |
614 | return ERR_PTR(-ENODEV); | 563 | return ret; |
615 | } | 564 | } |
616 | return dev; | 565 | return 0; |
617 | } | 566 | } |
618 | spin_unlock_irq(sh->host_lock); | 567 | spin_unlock_irq(sh->host_lock); |
619 | 568 | ||
@@ -627,17 +576,13 @@ static struct se_device *pscsi_create_virtdevice( | |||
627 | hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE; | 576 | hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE; |
628 | } | 577 | } |
629 | 578 | ||
630 | return ERR_PTR(-ENODEV); | 579 | return -ENODEV; |
631 | } | 580 | } |
632 | 581 | ||
633 | /* pscsi_free_device(): (Part of se_subsystem_api_t template) | 582 | static void pscsi_free_device(struct se_device *dev) |
634 | * | ||
635 | * | ||
636 | */ | ||
637 | static void pscsi_free_device(void *p) | ||
638 | { | 583 | { |
639 | struct pscsi_dev_virt *pdv = p; | 584 | struct pscsi_dev_virt *pdv = PSCSI_DEV(dev); |
640 | struct pscsi_hba_virt *phv = pdv->pdv_se_hba->hba_ptr; | 585 | struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; |
641 | struct scsi_device *sd = pdv->pdv_sd; | 586 | struct scsi_device *sd = pdv->pdv_sd; |
642 | 587 | ||
643 | if (sd) { | 588 | if (sd) { |
@@ -670,7 +615,7 @@ static void pscsi_free_device(void *p) | |||
670 | static void pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg, | 615 | static void pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg, |
671 | unsigned char *sense_buffer) | 616 | unsigned char *sense_buffer) |
672 | { | 617 | { |
673 | struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr; | 618 | struct pscsi_dev_virt *pdv = PSCSI_DEV(cmd->se_dev); |
674 | struct scsi_device *sd = pdv->pdv_sd; | 619 | struct scsi_device *sd = pdv->pdv_sd; |
675 | int result; | 620 | int result; |
676 | struct pscsi_plugin_task *pt = cmd->priv; | 621 | struct pscsi_plugin_task *pt = cmd->priv; |
@@ -694,7 +639,11 @@ static void pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg, | |||
694 | if (((cdb[0] == MODE_SENSE) || (cdb[0] == MODE_SENSE_10)) && | 639 | if (((cdb[0] == MODE_SENSE) || (cdb[0] == MODE_SENSE_10)) && |
695 | (status_byte(result) << 1) == SAM_STAT_GOOD) { | 640 | (status_byte(result) << 1) == SAM_STAT_GOOD) { |
696 | if (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) { | 641 | if (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) { |
697 | unsigned char *buf = transport_kmap_data_sg(cmd); | 642 | unsigned char *buf; |
643 | |||
644 | buf = transport_kmap_data_sg(cmd); | ||
645 | if (!buf) | ||
646 | ; /* XXX: TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE */ | ||
698 | 647 | ||
699 | if (cdb[0] == MODE_SENSE_10) { | 648 | if (cdb[0] == MODE_SENSE_10) { |
700 | if (!(buf[3] & 0x80)) | 649 | if (!(buf[3] & 0x80)) |
@@ -770,13 +719,11 @@ static match_table_t tokens = { | |||
770 | {Opt_err, NULL} | 719 | {Opt_err, NULL} |
771 | }; | 720 | }; |
772 | 721 | ||
773 | static ssize_t pscsi_set_configfs_dev_params(struct se_hba *hba, | 722 | static ssize_t pscsi_set_configfs_dev_params(struct se_device *dev, |
774 | struct se_subsystem_dev *se_dev, | 723 | const char *page, ssize_t count) |
775 | const char *page, | ||
776 | ssize_t count) | ||
777 | { | 724 | { |
778 | struct pscsi_dev_virt *pdv = se_dev->se_dev_su_ptr; | 725 | struct pscsi_dev_virt *pdv = PSCSI_DEV(dev); |
779 | struct pscsi_hba_virt *phv = hba->hba_ptr; | 726 | struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; |
780 | char *orig, *ptr, *opts; | 727 | char *orig, *ptr, *opts; |
781 | substring_t args[MAX_OPT_ARGS]; | 728 | substring_t args[MAX_OPT_ARGS]; |
782 | int ret = 0, arg, token; | 729 | int ret = 0, arg, token; |
@@ -841,29 +788,10 @@ out: | |||
841 | return (!ret) ? count : ret; | 788 | return (!ret) ? count : ret; |
842 | } | 789 | } |
843 | 790 | ||
844 | static ssize_t pscsi_check_configfs_dev_params( | 791 | static ssize_t pscsi_show_configfs_dev_params(struct se_device *dev, char *b) |
845 | struct se_hba *hba, | ||
846 | struct se_subsystem_dev *se_dev) | ||
847 | { | 792 | { |
848 | struct pscsi_dev_virt *pdv = se_dev->se_dev_su_ptr; | 793 | struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; |
849 | 794 | struct pscsi_dev_virt *pdv = PSCSI_DEV(dev); | |
850 | if (!(pdv->pdv_flags & PDF_HAS_CHANNEL_ID) || | ||
851 | !(pdv->pdv_flags & PDF_HAS_TARGET_ID) || | ||
852 | !(pdv->pdv_flags & PDF_HAS_LUN_ID)) { | ||
853 | pr_err("Missing scsi_channel_id=, scsi_target_id= and" | ||
854 | " scsi_lun_id= parameters\n"); | ||
855 | return -EINVAL; | ||
856 | } | ||
857 | |||
858 | return 0; | ||
859 | } | ||
860 | |||
861 | static ssize_t pscsi_show_configfs_dev_params(struct se_hba *hba, | ||
862 | struct se_subsystem_dev *se_dev, | ||
863 | char *b) | ||
864 | { | ||
865 | struct pscsi_hba_virt *phv = hba->hba_ptr; | ||
866 | struct pscsi_dev_virt *pdv = se_dev->se_dev_su_ptr; | ||
867 | struct scsi_device *sd = pdv->pdv_sd; | 795 | struct scsi_device *sd = pdv->pdv_sd; |
868 | unsigned char host_id[16]; | 796 | unsigned char host_id[16]; |
869 | ssize_t bl; | 797 | ssize_t bl; |
@@ -929,11 +857,11 @@ static inline struct bio *pscsi_get_bio(int sg_num) | |||
929 | return bio; | 857 | return bio; |
930 | } | 858 | } |
931 | 859 | ||
932 | static int pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, | 860 | static sense_reason_t |
933 | u32 sgl_nents, enum dma_data_direction data_direction, | 861 | pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, |
934 | struct bio **hbio) | 862 | enum dma_data_direction data_direction, struct bio **hbio) |
935 | { | 863 | { |
936 | struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr; | 864 | struct pscsi_dev_virt *pdv = PSCSI_DEV(cmd->se_dev); |
937 | struct bio *bio = NULL, *tbio = NULL; | 865 | struct bio *bio = NULL, *tbio = NULL; |
938 | struct page *page; | 866 | struct page *page; |
939 | struct scatterlist *sg; | 867 | struct scatterlist *sg; |
@@ -1019,7 +947,7 @@ static int pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, | |||
1019 | } | 947 | } |
1020 | } | 948 | } |
1021 | 949 | ||
1022 | return sgl_nents; | 950 | return 0; |
1023 | fail: | 951 | fail: |
1024 | while (*hbio) { | 952 | while (*hbio) { |
1025 | bio = *hbio; | 953 | bio = *hbio; |
@@ -1027,8 +955,7 @@ fail: | |||
1027 | bio->bi_next = NULL; | 955 | bio->bi_next = NULL; |
1028 | bio_endio(bio, 0); /* XXX: should be error */ | 956 | bio_endio(bio, 0); /* XXX: should be error */ |
1029 | } | 957 | } |
1030 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 958 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1031 | return -ENOMEM; | ||
1032 | } | 959 | } |
1033 | 960 | ||
1034 | /* | 961 | /* |
@@ -1055,17 +982,13 @@ static inline void pscsi_clear_cdb_lun(unsigned char *cdb) | |||
1055 | } | 982 | } |
1056 | } | 983 | } |
1057 | 984 | ||
1058 | static int pscsi_parse_cdb(struct se_cmd *cmd) | 985 | static sense_reason_t |
986 | pscsi_parse_cdb(struct se_cmd *cmd) | ||
1059 | { | 987 | { |
1060 | unsigned char *cdb = cmd->t_task_cdb; | 988 | unsigned char *cdb = cmd->t_task_cdb; |
1061 | unsigned int dummy_size; | ||
1062 | int ret; | ||
1063 | 989 | ||
1064 | if (cmd->se_cmd_flags & SCF_BIDI) { | 990 | if (cmd->se_cmd_flags & SCF_BIDI) |
1065 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | 991 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
1066 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | ||
1067 | return -EINVAL; | ||
1068 | } | ||
1069 | 992 | ||
1070 | pscsi_clear_cdb_lun(cdb); | 993 | pscsi_clear_cdb_lun(cdb); |
1071 | 994 | ||
@@ -1076,10 +999,8 @@ static int pscsi_parse_cdb(struct se_cmd *cmd) | |||
1076 | */ | 999 | */ |
1077 | switch (cdb[0]) { | 1000 | switch (cdb[0]) { |
1078 | case REPORT_LUNS: | 1001 | case REPORT_LUNS: |
1079 | ret = spc_parse_cdb(cmd, &dummy_size); | 1002 | cmd->execute_cmd = spc_emulate_report_luns; |
1080 | if (ret) | 1003 | return 0; |
1081 | return ret; | ||
1082 | break; | ||
1083 | case READ_6: | 1004 | case READ_6: |
1084 | case READ_10: | 1005 | case READ_10: |
1085 | case READ_12: | 1006 | case READ_12: |
@@ -1093,22 +1014,21 @@ static int pscsi_parse_cdb(struct se_cmd *cmd) | |||
1093 | /* FALLTHROUGH*/ | 1014 | /* FALLTHROUGH*/ |
1094 | default: | 1015 | default: |
1095 | cmd->execute_cmd = pscsi_execute_cmd; | 1016 | cmd->execute_cmd = pscsi_execute_cmd; |
1096 | break; | 1017 | return 0; |
1097 | } | 1018 | } |
1098 | |||
1099 | return 0; | ||
1100 | } | 1019 | } |
1101 | 1020 | ||
1102 | static int pscsi_execute_cmd(struct se_cmd *cmd) | 1021 | static sense_reason_t |
1022 | pscsi_execute_cmd(struct se_cmd *cmd) | ||
1103 | { | 1023 | { |
1104 | struct scatterlist *sgl = cmd->t_data_sg; | 1024 | struct scatterlist *sgl = cmd->t_data_sg; |
1105 | u32 sgl_nents = cmd->t_data_nents; | 1025 | u32 sgl_nents = cmd->t_data_nents; |
1106 | enum dma_data_direction data_direction = cmd->data_direction; | 1026 | enum dma_data_direction data_direction = cmd->data_direction; |
1107 | struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr; | 1027 | struct pscsi_dev_virt *pdv = PSCSI_DEV(cmd->se_dev); |
1108 | struct pscsi_plugin_task *pt; | 1028 | struct pscsi_plugin_task *pt; |
1109 | struct request *req; | 1029 | struct request *req; |
1110 | struct bio *hbio; | 1030 | struct bio *hbio; |
1111 | int ret; | 1031 | sense_reason_t ret; |
1112 | 1032 | ||
1113 | /* | 1033 | /* |
1114 | * Dynamically alloc cdb space, since it may be larger than | 1034 | * Dynamically alloc cdb space, since it may be larger than |
@@ -1116,8 +1036,7 @@ static int pscsi_execute_cmd(struct se_cmd *cmd) | |||
1116 | */ | 1036 | */ |
1117 | pt = kzalloc(sizeof(*pt) + scsi_command_size(cmd->t_task_cdb), GFP_KERNEL); | 1037 | pt = kzalloc(sizeof(*pt) + scsi_command_size(cmd->t_task_cdb), GFP_KERNEL); |
1118 | if (!pt) { | 1038 | if (!pt) { |
1119 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1039 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1120 | return -ENOMEM; | ||
1121 | } | 1040 | } |
1122 | cmd->priv = pt; | 1041 | cmd->priv = pt; |
1123 | 1042 | ||
@@ -1131,24 +1050,21 @@ static int pscsi_execute_cmd(struct se_cmd *cmd) | |||
1131 | if (!req || IS_ERR(req)) { | 1050 | if (!req || IS_ERR(req)) { |
1132 | pr_err("PSCSI: blk_get_request() failed: %ld\n", | 1051 | pr_err("PSCSI: blk_get_request() failed: %ld\n", |
1133 | req ? IS_ERR(req) : -ENOMEM); | 1052 | req ? IS_ERR(req) : -ENOMEM); |
1134 | cmd->scsi_sense_reason = | 1053 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1135 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1136 | goto fail; | 1054 | goto fail; |
1137 | } | 1055 | } |
1138 | } else { | 1056 | } else { |
1139 | BUG_ON(!cmd->data_length); | 1057 | BUG_ON(!cmd->data_length); |
1140 | 1058 | ||
1141 | ret = pscsi_map_sg(cmd, sgl, sgl_nents, data_direction, &hbio); | 1059 | ret = pscsi_map_sg(cmd, sgl, sgl_nents, data_direction, &hbio); |
1142 | if (ret < 0) { | 1060 | if (ret) |
1143 | cmd->scsi_sense_reason = | ||
1144 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1145 | goto fail; | 1061 | goto fail; |
1146 | } | ||
1147 | 1062 | ||
1148 | req = blk_make_request(pdv->pdv_sd->request_queue, hbio, | 1063 | req = blk_make_request(pdv->pdv_sd->request_queue, hbio, |
1149 | GFP_KERNEL); | 1064 | GFP_KERNEL); |
1150 | if (IS_ERR(req)) { | 1065 | if (IS_ERR(req)) { |
1151 | pr_err("pSCSI: blk_make_request() failed\n"); | 1066 | pr_err("pSCSI: blk_make_request() failed\n"); |
1067 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1152 | goto fail_free_bio; | 1068 | goto fail_free_bio; |
1153 | } | 1069 | } |
1154 | } | 1070 | } |
@@ -1179,22 +1095,10 @@ fail_free_bio: | |||
1179 | bio->bi_next = NULL; | 1095 | bio->bi_next = NULL; |
1180 | bio_endio(bio, 0); /* XXX: should be error */ | 1096 | bio_endio(bio, 0); /* XXX: should be error */ |
1181 | } | 1097 | } |
1182 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1098 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1183 | fail: | 1099 | fail: |
1184 | kfree(pt); | 1100 | kfree(pt); |
1185 | return -ENOMEM; | 1101 | return ret; |
1186 | } | ||
1187 | |||
1188 | /* pscsi_get_device_rev(): | ||
1189 | * | ||
1190 | * | ||
1191 | */ | ||
1192 | static u32 pscsi_get_device_rev(struct se_device *dev) | ||
1193 | { | ||
1194 | struct pscsi_dev_virt *pdv = dev->dev_ptr; | ||
1195 | struct scsi_device *sd = pdv->pdv_sd; | ||
1196 | |||
1197 | return (sd->scsi_level - 1) ? sd->scsi_level - 1 : 1; | ||
1198 | } | 1102 | } |
1199 | 1103 | ||
1200 | /* pscsi_get_device_type(): | 1104 | /* pscsi_get_device_type(): |
@@ -1203,7 +1107,7 @@ static u32 pscsi_get_device_rev(struct se_device *dev) | |||
1203 | */ | 1107 | */ |
1204 | static u32 pscsi_get_device_type(struct se_device *dev) | 1108 | static u32 pscsi_get_device_type(struct se_device *dev) |
1205 | { | 1109 | { |
1206 | struct pscsi_dev_virt *pdv = dev->dev_ptr; | 1110 | struct pscsi_dev_virt *pdv = PSCSI_DEV(dev); |
1207 | struct scsi_device *sd = pdv->pdv_sd; | 1111 | struct scsi_device *sd = pdv->pdv_sd; |
1208 | 1112 | ||
1209 | return sd->type; | 1113 | return sd->type; |
@@ -1211,7 +1115,7 @@ static u32 pscsi_get_device_type(struct se_device *dev) | |||
1211 | 1115 | ||
1212 | static sector_t pscsi_get_blocks(struct se_device *dev) | 1116 | static sector_t pscsi_get_blocks(struct se_device *dev) |
1213 | { | 1117 | { |
1214 | struct pscsi_dev_virt *pdv = dev->dev_ptr; | 1118 | struct pscsi_dev_virt *pdv = PSCSI_DEV(dev); |
1215 | 1119 | ||
1216 | if (pdv->pdv_bd && pdv->pdv_bd->bd_part) | 1120 | if (pdv->pdv_bd && pdv->pdv_bd->bd_part) |
1217 | return pdv->pdv_bd->bd_part->nr_sects; | 1121 | return pdv->pdv_bd->bd_part->nr_sects; |
@@ -1243,7 +1147,6 @@ static void pscsi_req_done(struct request *req, int uptodate) | |||
1243 | pr_debug("PSCSI Host Byte exception at cmd: %p CDB:" | 1147 | pr_debug("PSCSI Host Byte exception at cmd: %p CDB:" |
1244 | " 0x%02x Result: 0x%08x\n", cmd, pt->pscsi_cdb[0], | 1148 | " 0x%02x Result: 0x%08x\n", cmd, pt->pscsi_cdb[0], |
1245 | pt->pscsi_result); | 1149 | pt->pscsi_result); |
1246 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | ||
1247 | target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION); | 1150 | target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION); |
1248 | break; | 1151 | break; |
1249 | } | 1152 | } |
@@ -1259,15 +1162,13 @@ static struct se_subsystem_api pscsi_template = { | |||
1259 | .attach_hba = pscsi_attach_hba, | 1162 | .attach_hba = pscsi_attach_hba, |
1260 | .detach_hba = pscsi_detach_hba, | 1163 | .detach_hba = pscsi_detach_hba, |
1261 | .pmode_enable_hba = pscsi_pmode_enable_hba, | 1164 | .pmode_enable_hba = pscsi_pmode_enable_hba, |
1262 | .allocate_virtdevice = pscsi_allocate_virtdevice, | 1165 | .alloc_device = pscsi_alloc_device, |
1263 | .create_virtdevice = pscsi_create_virtdevice, | 1166 | .configure_device = pscsi_configure_device, |
1264 | .free_device = pscsi_free_device, | 1167 | .free_device = pscsi_free_device, |
1265 | .transport_complete = pscsi_transport_complete, | 1168 | .transport_complete = pscsi_transport_complete, |
1266 | .parse_cdb = pscsi_parse_cdb, | 1169 | .parse_cdb = pscsi_parse_cdb, |
1267 | .check_configfs_dev_params = pscsi_check_configfs_dev_params, | ||
1268 | .set_configfs_dev_params = pscsi_set_configfs_dev_params, | 1170 | .set_configfs_dev_params = pscsi_set_configfs_dev_params, |
1269 | .show_configfs_dev_params = pscsi_show_configfs_dev_params, | 1171 | .show_configfs_dev_params = pscsi_show_configfs_dev_params, |
1270 | .get_device_rev = pscsi_get_device_rev, | ||
1271 | .get_device_type = pscsi_get_device_type, | 1172 | .get_device_type = pscsi_get_device_type, |
1272 | .get_blocks = pscsi_get_blocks, | 1173 | .get_blocks = pscsi_get_blocks, |
1273 | }; | 1174 | }; |
diff --git a/drivers/target/target_core_pscsi.h b/drivers/target/target_core_pscsi.h index bc1e5e11eca0..1bd757dff8ee 100644 --- a/drivers/target/target_core_pscsi.h +++ b/drivers/target/target_core_pscsi.h | |||
@@ -37,6 +37,7 @@ struct pscsi_plugin_task { | |||
37 | #define PDF_HAS_VIRT_HOST_ID 0x20 | 37 | #define PDF_HAS_VIRT_HOST_ID 0x20 |
38 | 38 | ||
39 | struct pscsi_dev_virt { | 39 | struct pscsi_dev_virt { |
40 | struct se_device dev; | ||
40 | int pdv_flags; | 41 | int pdv_flags; |
41 | int pdv_host_id; | 42 | int pdv_host_id; |
42 | int pdv_channel_id; | 43 | int pdv_channel_id; |
@@ -44,7 +45,6 @@ struct pscsi_dev_virt { | |||
44 | int pdv_lun_id; | 45 | int pdv_lun_id; |
45 | struct block_device *pdv_bd; | 46 | struct block_device *pdv_bd; |
46 | struct scsi_device *pdv_sd; | 47 | struct scsi_device *pdv_sd; |
47 | struct se_hba *pdv_se_hba; | ||
48 | } ____cacheline_aligned; | 48 | } ____cacheline_aligned; |
49 | 49 | ||
50 | typedef enum phv_modes { | 50 | typedef enum phv_modes { |
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index d00bbe33ff8b..0457de362e68 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c | |||
@@ -4,10 +4,7 @@ | |||
4 | * This file contains the Storage Engine <-> Ramdisk transport | 4 | * This file contains the Storage Engine <-> Ramdisk transport |
5 | * specific functions. | 5 | * specific functions. |
6 | * | 6 | * |
7 | * Copyright (c) 2003, 2004, 2005 PyX Technologies, Inc. | 7 | * (c) Copyright 2003-2012 RisingTide Systems LLC. |
8 | * Copyright (c) 2005, 2006, 2007 SBE, Inc. | ||
9 | * Copyright (c) 2007-2010 Rising Tide Systems | ||
10 | * Copyright (c) 2008-2010 Linux-iSCSI.org | ||
11 | * | 8 | * |
12 | * Nicholas A. Bellinger <nab@kernel.org> | 9 | * Nicholas A. Bellinger <nab@kernel.org> |
13 | * | 10 | * |
@@ -41,7 +38,10 @@ | |||
41 | 38 | ||
42 | #include "target_core_rd.h" | 39 | #include "target_core_rd.h" |
43 | 40 | ||
44 | static struct se_subsystem_api rd_mcp_template; | 41 | static inline struct rd_dev *RD_DEV(struct se_device *dev) |
42 | { | ||
43 | return container_of(dev, struct rd_dev, dev); | ||
44 | } | ||
45 | 45 | ||
46 | /* rd_attach_hba(): (Part of se_subsystem_api_t template) | 46 | /* rd_attach_hba(): (Part of se_subsystem_api_t template) |
47 | * | 47 | * |
@@ -196,7 +196,7 @@ static int rd_build_device_space(struct rd_dev *rd_dev) | |||
196 | return 0; | 196 | return 0; |
197 | } | 197 | } |
198 | 198 | ||
199 | static void *rd_allocate_virtdevice(struct se_hba *hba, const char *name) | 199 | static struct se_device *rd_alloc_device(struct se_hba *hba, const char *name) |
200 | { | 200 | { |
201 | struct rd_dev *rd_dev; | 201 | struct rd_dev *rd_dev; |
202 | struct rd_host *rd_host = hba->hba_ptr; | 202 | struct rd_host *rd_host = hba->hba_ptr; |
@@ -209,39 +209,27 @@ static void *rd_allocate_virtdevice(struct se_hba *hba, const char *name) | |||
209 | 209 | ||
210 | rd_dev->rd_host = rd_host; | 210 | rd_dev->rd_host = rd_host; |
211 | 211 | ||
212 | return rd_dev; | 212 | return &rd_dev->dev; |
213 | } | 213 | } |
214 | 214 | ||
215 | static struct se_device *rd_create_virtdevice(struct se_hba *hba, | 215 | static int rd_configure_device(struct se_device *dev) |
216 | struct se_subsystem_dev *se_dev, void *p) | ||
217 | { | 216 | { |
218 | struct se_device *dev; | 217 | struct rd_dev *rd_dev = RD_DEV(dev); |
219 | struct se_dev_limits dev_limits; | 218 | struct rd_host *rd_host = dev->se_hba->hba_ptr; |
220 | struct rd_dev *rd_dev = p; | 219 | int ret; |
221 | struct rd_host *rd_host = hba->hba_ptr; | ||
222 | int dev_flags = 0, ret; | ||
223 | char prod[16], rev[4]; | ||
224 | 220 | ||
225 | memset(&dev_limits, 0, sizeof(struct se_dev_limits)); | 221 | if (!(rd_dev->rd_flags & RDF_HAS_PAGE_COUNT)) { |
222 | pr_debug("Missing rd_pages= parameter\n"); | ||
223 | return -EINVAL; | ||
224 | } | ||
226 | 225 | ||
227 | ret = rd_build_device_space(rd_dev); | 226 | ret = rd_build_device_space(rd_dev); |
228 | if (ret < 0) | 227 | if (ret < 0) |
229 | goto fail; | 228 | goto fail; |
230 | 229 | ||
231 | snprintf(prod, 16, "RAMDISK-MCP"); | 230 | dev->dev_attrib.hw_block_size = RD_BLOCKSIZE; |
232 | snprintf(rev, 4, "%s", RD_MCP_VERSION); | 231 | dev->dev_attrib.hw_max_sectors = UINT_MAX; |
233 | 232 | dev->dev_attrib.hw_queue_depth = RD_MAX_DEVICE_QUEUE_DEPTH; | |
234 | dev_limits.limits.logical_block_size = RD_BLOCKSIZE; | ||
235 | dev_limits.limits.max_hw_sectors = UINT_MAX; | ||
236 | dev_limits.limits.max_sectors = UINT_MAX; | ||
237 | dev_limits.hw_queue_depth = RD_MAX_DEVICE_QUEUE_DEPTH; | ||
238 | dev_limits.queue_depth = RD_DEVICE_QUEUE_DEPTH; | ||
239 | |||
240 | dev = transport_add_device_to_core_hba(hba, | ||
241 | &rd_mcp_template, se_dev, dev_flags, rd_dev, | ||
242 | &dev_limits, prod, rev); | ||
243 | if (!dev) | ||
244 | goto fail; | ||
245 | 233 | ||
246 | rd_dev->rd_dev_id = rd_host->rd_host_dev_id_count++; | 234 | rd_dev->rd_dev_id = rd_host->rd_host_dev_id_count++; |
247 | 235 | ||
@@ -251,16 +239,16 @@ static struct se_device *rd_create_virtdevice(struct se_hba *hba, | |||
251 | rd_dev->sg_table_count, | 239 | rd_dev->sg_table_count, |
252 | (unsigned long)(rd_dev->rd_page_count * PAGE_SIZE)); | 240 | (unsigned long)(rd_dev->rd_page_count * PAGE_SIZE)); |
253 | 241 | ||
254 | return dev; | 242 | return 0; |
255 | 243 | ||
256 | fail: | 244 | fail: |
257 | rd_release_device_space(rd_dev); | 245 | rd_release_device_space(rd_dev); |
258 | return ERR_PTR(ret); | 246 | return ret; |
259 | } | 247 | } |
260 | 248 | ||
261 | static void rd_free_device(void *p) | 249 | static void rd_free_device(struct se_device *dev) |
262 | { | 250 | { |
263 | struct rd_dev *rd_dev = p; | 251 | struct rd_dev *rd_dev = RD_DEV(dev); |
264 | 252 | ||
265 | rd_release_device_space(rd_dev); | 253 | rd_release_device_space(rd_dev); |
266 | kfree(rd_dev); | 254 | kfree(rd_dev); |
@@ -284,13 +272,14 @@ static struct rd_dev_sg_table *rd_get_sg_table(struct rd_dev *rd_dev, u32 page) | |||
284 | return NULL; | 272 | return NULL; |
285 | } | 273 | } |
286 | 274 | ||
287 | static int rd_execute_rw(struct se_cmd *cmd) | 275 | static sense_reason_t |
276 | rd_execute_rw(struct se_cmd *cmd) | ||
288 | { | 277 | { |
289 | struct scatterlist *sgl = cmd->t_data_sg; | 278 | struct scatterlist *sgl = cmd->t_data_sg; |
290 | u32 sgl_nents = cmd->t_data_nents; | 279 | u32 sgl_nents = cmd->t_data_nents; |
291 | enum dma_data_direction data_direction = cmd->data_direction; | 280 | enum dma_data_direction data_direction = cmd->data_direction; |
292 | struct se_device *se_dev = cmd->se_dev; | 281 | struct se_device *se_dev = cmd->se_dev; |
293 | struct rd_dev *dev = se_dev->dev_ptr; | 282 | struct rd_dev *dev = RD_DEV(se_dev); |
294 | struct rd_dev_sg_table *table; | 283 | struct rd_dev_sg_table *table; |
295 | struct scatterlist *rd_sg; | 284 | struct scatterlist *rd_sg; |
296 | struct sg_mapping_iter m; | 285 | struct sg_mapping_iter m; |
@@ -300,14 +289,14 @@ static int rd_execute_rw(struct se_cmd *cmd) | |||
300 | u32 src_len; | 289 | u32 src_len; |
301 | u64 tmp; | 290 | u64 tmp; |
302 | 291 | ||
303 | tmp = cmd->t_task_lba * se_dev->se_sub_dev->se_dev_attrib.block_size; | 292 | tmp = cmd->t_task_lba * se_dev->dev_attrib.block_size; |
304 | rd_offset = do_div(tmp, PAGE_SIZE); | 293 | rd_offset = do_div(tmp, PAGE_SIZE); |
305 | rd_page = tmp; | 294 | rd_page = tmp; |
306 | rd_size = cmd->data_length; | 295 | rd_size = cmd->data_length; |
307 | 296 | ||
308 | table = rd_get_sg_table(dev, rd_page); | 297 | table = rd_get_sg_table(dev, rd_page); |
309 | if (!table) | 298 | if (!table) |
310 | return -EINVAL; | 299 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
311 | 300 | ||
312 | rd_sg = &table->sg_table[rd_page - table->page_start_offset]; | 301 | rd_sg = &table->sg_table[rd_page - table->page_start_offset]; |
313 | 302 | ||
@@ -357,7 +346,7 @@ static int rd_execute_rw(struct se_cmd *cmd) | |||
357 | table = rd_get_sg_table(dev, rd_page); | 346 | table = rd_get_sg_table(dev, rd_page); |
358 | if (!table) { | 347 | if (!table) { |
359 | sg_miter_stop(&m); | 348 | sg_miter_stop(&m); |
360 | return -EINVAL; | 349 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
361 | } | 350 | } |
362 | 351 | ||
363 | /* since we increment, the first sg entry is correct */ | 352 | /* since we increment, the first sg entry is correct */ |
@@ -378,13 +367,10 @@ static match_table_t tokens = { | |||
378 | {Opt_err, NULL} | 367 | {Opt_err, NULL} |
379 | }; | 368 | }; |
380 | 369 | ||
381 | static ssize_t rd_set_configfs_dev_params( | 370 | static ssize_t rd_set_configfs_dev_params(struct se_device *dev, |
382 | struct se_hba *hba, | 371 | const char *page, ssize_t count) |
383 | struct se_subsystem_dev *se_dev, | ||
384 | const char *page, | ||
385 | ssize_t count) | ||
386 | { | 372 | { |
387 | struct rd_dev *rd_dev = se_dev->se_dev_su_ptr; | 373 | struct rd_dev *rd_dev = RD_DEV(dev); |
388 | char *orig, *ptr, *opts; | 374 | char *orig, *ptr, *opts; |
389 | substring_t args[MAX_OPT_ARGS]; | 375 | substring_t args[MAX_OPT_ARGS]; |
390 | int ret = 0, arg, token; | 376 | int ret = 0, arg, token; |
@@ -417,24 +403,10 @@ static ssize_t rd_set_configfs_dev_params( | |||
417 | return (!ret) ? count : ret; | 403 | return (!ret) ? count : ret; |
418 | } | 404 | } |
419 | 405 | ||
420 | static ssize_t rd_check_configfs_dev_params(struct se_hba *hba, struct se_subsystem_dev *se_dev) | 406 | static ssize_t rd_show_configfs_dev_params(struct se_device *dev, char *b) |
421 | { | 407 | { |
422 | struct rd_dev *rd_dev = se_dev->se_dev_su_ptr; | 408 | struct rd_dev *rd_dev = RD_DEV(dev); |
423 | 409 | ||
424 | if (!(rd_dev->rd_flags & RDF_HAS_PAGE_COUNT)) { | ||
425 | pr_debug("Missing rd_pages= parameter\n"); | ||
426 | return -EINVAL; | ||
427 | } | ||
428 | |||
429 | return 0; | ||
430 | } | ||
431 | |||
432 | static ssize_t rd_show_configfs_dev_params( | ||
433 | struct se_hba *hba, | ||
434 | struct se_subsystem_dev *se_dev, | ||
435 | char *b) | ||
436 | { | ||
437 | struct rd_dev *rd_dev = se_dev->se_dev_su_ptr; | ||
438 | ssize_t bl = sprintf(b, "TCM RamDisk ID: %u RamDisk Makeup: rd_mcp\n", | 410 | ssize_t bl = sprintf(b, "TCM RamDisk ID: %u RamDisk Makeup: rd_mcp\n", |
439 | rd_dev->rd_dev_id); | 411 | rd_dev->rd_dev_id); |
440 | bl += sprintf(b + bl, " PAGES/PAGE_SIZE: %u*%lu" | 412 | bl += sprintf(b + bl, " PAGES/PAGE_SIZE: %u*%lu" |
@@ -443,48 +415,40 @@ static ssize_t rd_show_configfs_dev_params( | |||
443 | return bl; | 415 | return bl; |
444 | } | 416 | } |
445 | 417 | ||
446 | static u32 rd_get_device_rev(struct se_device *dev) | ||
447 | { | ||
448 | return SCSI_SPC_2; /* Returns SPC-3 in Initiator Data */ | ||
449 | } | ||
450 | |||
451 | static u32 rd_get_device_type(struct se_device *dev) | ||
452 | { | ||
453 | return TYPE_DISK; | ||
454 | } | ||
455 | |||
456 | static sector_t rd_get_blocks(struct se_device *dev) | 418 | static sector_t rd_get_blocks(struct se_device *dev) |
457 | { | 419 | { |
458 | struct rd_dev *rd_dev = dev->dev_ptr; | 420 | struct rd_dev *rd_dev = RD_DEV(dev); |
421 | |||
459 | unsigned long long blocks_long = ((rd_dev->rd_page_count * PAGE_SIZE) / | 422 | unsigned long long blocks_long = ((rd_dev->rd_page_count * PAGE_SIZE) / |
460 | dev->se_sub_dev->se_dev_attrib.block_size) - 1; | 423 | dev->dev_attrib.block_size) - 1; |
461 | 424 | ||
462 | return blocks_long; | 425 | return blocks_long; |
463 | } | 426 | } |
464 | 427 | ||
465 | static struct spc_ops rd_spc_ops = { | 428 | static struct sbc_ops rd_sbc_ops = { |
466 | .execute_rw = rd_execute_rw, | 429 | .execute_rw = rd_execute_rw, |
467 | }; | 430 | }; |
468 | 431 | ||
469 | static int rd_parse_cdb(struct se_cmd *cmd) | 432 | static sense_reason_t |
433 | rd_parse_cdb(struct se_cmd *cmd) | ||
470 | { | 434 | { |
471 | return sbc_parse_cdb(cmd, &rd_spc_ops); | 435 | return sbc_parse_cdb(cmd, &rd_sbc_ops); |
472 | } | 436 | } |
473 | 437 | ||
474 | static struct se_subsystem_api rd_mcp_template = { | 438 | static struct se_subsystem_api rd_mcp_template = { |
475 | .name = "rd_mcp", | 439 | .name = "rd_mcp", |
440 | .inquiry_prod = "RAMDISK-MCP", | ||
441 | .inquiry_rev = RD_MCP_VERSION, | ||
476 | .transport_type = TRANSPORT_PLUGIN_VHBA_VDEV, | 442 | .transport_type = TRANSPORT_PLUGIN_VHBA_VDEV, |
477 | .attach_hba = rd_attach_hba, | 443 | .attach_hba = rd_attach_hba, |
478 | .detach_hba = rd_detach_hba, | 444 | .detach_hba = rd_detach_hba, |
479 | .allocate_virtdevice = rd_allocate_virtdevice, | 445 | .alloc_device = rd_alloc_device, |
480 | .create_virtdevice = rd_create_virtdevice, | 446 | .configure_device = rd_configure_device, |
481 | .free_device = rd_free_device, | 447 | .free_device = rd_free_device, |
482 | .parse_cdb = rd_parse_cdb, | 448 | .parse_cdb = rd_parse_cdb, |
483 | .check_configfs_dev_params = rd_check_configfs_dev_params, | ||
484 | .set_configfs_dev_params = rd_set_configfs_dev_params, | 449 | .set_configfs_dev_params = rd_set_configfs_dev_params, |
485 | .show_configfs_dev_params = rd_show_configfs_dev_params, | 450 | .show_configfs_dev_params = rd_show_configfs_dev_params, |
486 | .get_device_rev = rd_get_device_rev, | 451 | .get_device_type = sbc_get_device_type, |
487 | .get_device_type = rd_get_device_type, | ||
488 | .get_blocks = rd_get_blocks, | 452 | .get_blocks = rd_get_blocks, |
489 | }; | 453 | }; |
490 | 454 | ||
diff --git a/drivers/target/target_core_rd.h b/drivers/target/target_core_rd.h index 21458125fe51..933b38b6e563 100644 --- a/drivers/target/target_core_rd.h +++ b/drivers/target/target_core_rd.h | |||
@@ -24,6 +24,7 @@ struct rd_dev_sg_table { | |||
24 | #define RDF_HAS_PAGE_COUNT 0x01 | 24 | #define RDF_HAS_PAGE_COUNT 0x01 |
25 | 25 | ||
26 | struct rd_dev { | 26 | struct rd_dev { |
27 | struct se_device dev; | ||
27 | u32 rd_flags; | 28 | u32 rd_flags; |
28 | /* Unique Ramdisk Device ID in Ramdisk HBA */ | 29 | /* Unique Ramdisk Device ID in Ramdisk HBA */ |
29 | u32 rd_dev_id; | 30 | u32 rd_dev_id; |
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 868f8aa04f13..26a6d183ccb1 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
@@ -1,10 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * SCSI Block Commands (SBC) parsing and emulation. | 2 | * SCSI Block Commands (SBC) parsing and emulation. |
3 | * | 3 | * |
4 | * Copyright (c) 2002, 2003, 2004, 2005 PyX Technologies, Inc. | 4 | * (c) Copyright 2002-2012 RisingTide Systems LLC. |
5 | * Copyright (c) 2005, 2006, 2007 SBE, Inc. | ||
6 | * Copyright (c) 2007-2010 Rising Tide Systems | ||
7 | * Copyright (c) 2008-2010 Linux-iSCSI.org | ||
8 | * | 5 | * |
9 | * Nicholas A. Bellinger <nab@kernel.org> | 6 | * Nicholas A. Bellinger <nab@kernel.org> |
10 | * | 7 | * |
@@ -37,7 +34,8 @@ | |||
37 | #include "target_core_ua.h" | 34 | #include "target_core_ua.h" |
38 | 35 | ||
39 | 36 | ||
40 | static int sbc_emulate_readcapacity(struct se_cmd *cmd) | 37 | static sense_reason_t |
38 | sbc_emulate_readcapacity(struct se_cmd *cmd) | ||
41 | { | 39 | { |
42 | struct se_device *dev = cmd->se_dev; | 40 | struct se_device *dev = cmd->se_dev; |
43 | unsigned long long blocks_long = dev->transport->get_blocks(dev); | 41 | unsigned long long blocks_long = dev->transport->get_blocks(dev); |
@@ -54,22 +52,24 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd) | |||
54 | buf[1] = (blocks >> 16) & 0xff; | 52 | buf[1] = (blocks >> 16) & 0xff; |
55 | buf[2] = (blocks >> 8) & 0xff; | 53 | buf[2] = (blocks >> 8) & 0xff; |
56 | buf[3] = blocks & 0xff; | 54 | buf[3] = blocks & 0xff; |
57 | buf[4] = (dev->se_sub_dev->se_dev_attrib.block_size >> 24) & 0xff; | 55 | buf[4] = (dev->dev_attrib.block_size >> 24) & 0xff; |
58 | buf[5] = (dev->se_sub_dev->se_dev_attrib.block_size >> 16) & 0xff; | 56 | buf[5] = (dev->dev_attrib.block_size >> 16) & 0xff; |
59 | buf[6] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff; | 57 | buf[6] = (dev->dev_attrib.block_size >> 8) & 0xff; |
60 | buf[7] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff; | 58 | buf[7] = dev->dev_attrib.block_size & 0xff; |
61 | 59 | ||
62 | rbuf = transport_kmap_data_sg(cmd); | 60 | rbuf = transport_kmap_data_sg(cmd); |
63 | if (rbuf) { | 61 | if (!rbuf) |
64 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); | 62 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
65 | transport_kunmap_data_sg(cmd); | 63 | |
66 | } | 64 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); |
65 | transport_kunmap_data_sg(cmd); | ||
67 | 66 | ||
68 | target_complete_cmd(cmd, GOOD); | 67 | target_complete_cmd(cmd, GOOD); |
69 | return 0; | 68 | return 0; |
70 | } | 69 | } |
71 | 70 | ||
72 | static int sbc_emulate_readcapacity_16(struct se_cmd *cmd) | 71 | static sense_reason_t |
72 | sbc_emulate_readcapacity_16(struct se_cmd *cmd) | ||
73 | { | 73 | { |
74 | struct se_device *dev = cmd->se_dev; | 74 | struct se_device *dev = cmd->se_dev; |
75 | unsigned char *rbuf; | 75 | unsigned char *rbuf; |
@@ -85,28 +85,29 @@ static int sbc_emulate_readcapacity_16(struct se_cmd *cmd) | |||
85 | buf[5] = (blocks >> 16) & 0xff; | 85 | buf[5] = (blocks >> 16) & 0xff; |
86 | buf[6] = (blocks >> 8) & 0xff; | 86 | buf[6] = (blocks >> 8) & 0xff; |
87 | buf[7] = blocks & 0xff; | 87 | buf[7] = blocks & 0xff; |
88 | buf[8] = (dev->se_sub_dev->se_dev_attrib.block_size >> 24) & 0xff; | 88 | buf[8] = (dev->dev_attrib.block_size >> 24) & 0xff; |
89 | buf[9] = (dev->se_sub_dev->se_dev_attrib.block_size >> 16) & 0xff; | 89 | buf[9] = (dev->dev_attrib.block_size >> 16) & 0xff; |
90 | buf[10] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff; | 90 | buf[10] = (dev->dev_attrib.block_size >> 8) & 0xff; |
91 | buf[11] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff; | 91 | buf[11] = dev->dev_attrib.block_size & 0xff; |
92 | /* | 92 | /* |
93 | * Set Thin Provisioning Enable bit following sbc3r22 in section | 93 | * Set Thin Provisioning Enable bit following sbc3r22 in section |
94 | * READ CAPACITY (16) byte 14 if emulate_tpu or emulate_tpws is enabled. | 94 | * READ CAPACITY (16) byte 14 if emulate_tpu or emulate_tpws is enabled. |
95 | */ | 95 | */ |
96 | if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws) | 96 | if (dev->dev_attrib.emulate_tpu || dev->dev_attrib.emulate_tpws) |
97 | buf[14] = 0x80; | 97 | buf[14] = 0x80; |
98 | 98 | ||
99 | rbuf = transport_kmap_data_sg(cmd); | 99 | rbuf = transport_kmap_data_sg(cmd); |
100 | if (rbuf) { | 100 | if (!rbuf) |
101 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); | 101 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
102 | transport_kunmap_data_sg(cmd); | 102 | |
103 | } | 103 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); |
104 | transport_kunmap_data_sg(cmd); | ||
104 | 105 | ||
105 | target_complete_cmd(cmd, GOOD); | 106 | target_complete_cmd(cmd, GOOD); |
106 | return 0; | 107 | return 0; |
107 | } | 108 | } |
108 | 109 | ||
109 | int spc_get_write_same_sectors(struct se_cmd *cmd) | 110 | sector_t spc_get_write_same_sectors(struct se_cmd *cmd) |
110 | { | 111 | { |
111 | u32 num_blocks; | 112 | u32 num_blocks; |
112 | 113 | ||
@@ -129,7 +130,8 @@ int spc_get_write_same_sectors(struct se_cmd *cmd) | |||
129 | } | 130 | } |
130 | EXPORT_SYMBOL(spc_get_write_same_sectors); | 131 | EXPORT_SYMBOL(spc_get_write_same_sectors); |
131 | 132 | ||
132 | static int sbc_emulate_verify(struct se_cmd *cmd) | 133 | static sense_reason_t |
134 | sbc_emulate_noop(struct se_cmd *cmd) | ||
133 | { | 135 | { |
134 | target_complete_cmd(cmd, GOOD); | 136 | target_complete_cmd(cmd, GOOD); |
135 | return 0; | 137 | return 0; |
@@ -137,7 +139,7 @@ static int sbc_emulate_verify(struct se_cmd *cmd) | |||
137 | 139 | ||
138 | static inline u32 sbc_get_size(struct se_cmd *cmd, u32 sectors) | 140 | static inline u32 sbc_get_size(struct se_cmd *cmd, u32 sectors) |
139 | { | 141 | { |
140 | return cmd->se_dev->se_sub_dev->se_dev_attrib.block_size * sectors; | 142 | return cmd->se_dev->dev_attrib.block_size * sectors; |
141 | } | 143 | } |
142 | 144 | ||
143 | static int sbc_check_valid_sectors(struct se_cmd *cmd) | 145 | static int sbc_check_valid_sectors(struct se_cmd *cmd) |
@@ -146,7 +148,7 @@ static int sbc_check_valid_sectors(struct se_cmd *cmd) | |||
146 | unsigned long long end_lba; | 148 | unsigned long long end_lba; |
147 | u32 sectors; | 149 | u32 sectors; |
148 | 150 | ||
149 | sectors = cmd->data_length / dev->se_sub_dev->se_dev_attrib.block_size; | 151 | sectors = cmd->data_length / dev->dev_attrib.block_size; |
150 | end_lba = dev->transport->get_blocks(dev) + 1; | 152 | end_lba = dev->transport->get_blocks(dev) + 1; |
151 | 153 | ||
152 | if (cmd->t_task_lba + sectors > end_lba) { | 154 | if (cmd->t_task_lba + sectors > end_lba) { |
@@ -230,26 +232,37 @@ static inline unsigned long long transport_lba_64_ext(unsigned char *cdb) | |||
230 | return ((unsigned long long)__v2) | (unsigned long long)__v1 << 32; | 232 | return ((unsigned long long)__v2) | (unsigned long long)__v1 << 32; |
231 | } | 233 | } |
232 | 234 | ||
233 | static int sbc_write_same_supported(struct se_device *dev, | 235 | static sense_reason_t |
234 | unsigned char *flags) | 236 | sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *ops) |
235 | { | 237 | { |
238 | unsigned int sectors = spc_get_write_same_sectors(cmd); | ||
239 | |||
236 | if ((flags[0] & 0x04) || (flags[0] & 0x02)) { | 240 | if ((flags[0] & 0x04) || (flags[0] & 0x02)) { |
237 | pr_err("WRITE_SAME PBDATA and LBDATA" | 241 | pr_err("WRITE_SAME PBDATA and LBDATA" |
238 | " bits not supported for Block Discard" | 242 | " bits not supported for Block Discard" |
239 | " Emulation\n"); | 243 | " Emulation\n"); |
240 | return -ENOSYS; | 244 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
245 | } | ||
246 | if (sectors > cmd->se_dev->dev_attrib.max_write_same_len) { | ||
247 | pr_warn("WRITE_SAME sectors: %u exceeds max_write_same_len: %u\n", | ||
248 | sectors, cmd->se_dev->dev_attrib.max_write_same_len); | ||
249 | return TCM_INVALID_CDB_FIELD; | ||
241 | } | 250 | } |
242 | |||
243 | /* | 251 | /* |
244 | * Currently for the emulated case we only accept | 252 | * Special case for WRITE_SAME w/ UNMAP=1 that ends up getting |
245 | * tpws with the UNMAP=1 bit set. | 253 | * translated into block discard requests within backend code. |
246 | */ | 254 | */ |
247 | if (!(flags[0] & 0x08)) { | 255 | if (flags[0] & 0x08) { |
248 | pr_err("WRITE_SAME w/o UNMAP bit not" | 256 | if (!ops->execute_write_same_unmap) |
249 | " supported for Block Discard Emulation\n"); | 257 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
250 | return -ENOSYS; | 258 | |
259 | cmd->execute_cmd = ops->execute_write_same_unmap; | ||
260 | return 0; | ||
251 | } | 261 | } |
262 | if (!ops->execute_write_same) | ||
263 | return TCM_UNSUPPORTED_SCSI_OPCODE; | ||
252 | 264 | ||
265 | cmd->execute_cmd = ops->execute_write_same; | ||
253 | return 0; | 266 | return 0; |
254 | } | 267 | } |
255 | 268 | ||
@@ -307,14 +320,14 @@ out: | |||
307 | kfree(buf); | 320 | kfree(buf); |
308 | } | 321 | } |
309 | 322 | ||
310 | int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops) | 323 | sense_reason_t |
324 | sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | ||
311 | { | 325 | { |
312 | struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev; | ||
313 | struct se_device *dev = cmd->se_dev; | 326 | struct se_device *dev = cmd->se_dev; |
314 | unsigned char *cdb = cmd->t_task_cdb; | 327 | unsigned char *cdb = cmd->t_task_cdb; |
315 | unsigned int size; | 328 | unsigned int size; |
316 | u32 sectors = 0; | 329 | u32 sectors = 0; |
317 | int ret; | 330 | sense_reason_t ret; |
318 | 331 | ||
319 | switch (cdb[0]) { | 332 | switch (cdb[0]) { |
320 | case READ_6: | 333 | case READ_6: |
@@ -373,9 +386,9 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops) | |||
373 | cmd->execute_cmd = ops->execute_rw; | 386 | cmd->execute_cmd = ops->execute_rw; |
374 | break; | 387 | break; |
375 | case XDWRITEREAD_10: | 388 | case XDWRITEREAD_10: |
376 | if ((cmd->data_direction != DMA_TO_DEVICE) || | 389 | if (cmd->data_direction != DMA_TO_DEVICE || |
377 | !(cmd->se_cmd_flags & SCF_BIDI)) | 390 | !(cmd->se_cmd_flags & SCF_BIDI)) |
378 | goto out_invalid_cdb_field; | 391 | return TCM_INVALID_CDB_FIELD; |
379 | sectors = transport_get_sectors_10(cdb); | 392 | sectors = transport_get_sectors_10(cdb); |
380 | 393 | ||
381 | cmd->t_task_lba = transport_lba_32(cdb); | 394 | cmd->t_task_lba = transport_lba_32(cdb); |
@@ -413,27 +426,24 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops) | |||
413 | cmd->se_cmd_flags |= SCF_FUA; | 426 | cmd->se_cmd_flags |= SCF_FUA; |
414 | break; | 427 | break; |
415 | case WRITE_SAME_32: | 428 | case WRITE_SAME_32: |
416 | if (!ops->execute_write_same) | ||
417 | goto out_unsupported_cdb; | ||
418 | |||
419 | sectors = transport_get_sectors_32(cdb); | 429 | sectors = transport_get_sectors_32(cdb); |
420 | if (!sectors) { | 430 | if (!sectors) { |
421 | pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not" | 431 | pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not" |
422 | " supported\n"); | 432 | " supported\n"); |
423 | goto out_invalid_cdb_field; | 433 | return TCM_INVALID_CDB_FIELD; |
424 | } | 434 | } |
425 | 435 | ||
426 | size = sbc_get_size(cmd, 1); | 436 | size = sbc_get_size(cmd, 1); |
427 | cmd->t_task_lba = get_unaligned_be64(&cdb[12]); | 437 | cmd->t_task_lba = get_unaligned_be64(&cdb[12]); |
428 | 438 | ||
429 | if (sbc_write_same_supported(dev, &cdb[10]) < 0) | 439 | ret = sbc_setup_write_same(cmd, &cdb[10], ops); |
430 | goto out_unsupported_cdb; | 440 | if (ret) |
431 | cmd->execute_cmd = ops->execute_write_same; | 441 | return ret; |
432 | break; | 442 | break; |
433 | default: | 443 | default: |
434 | pr_err("VARIABLE_LENGTH_CMD service action" | 444 | pr_err("VARIABLE_LENGTH_CMD service action" |
435 | " 0x%04x not supported\n", service_action); | 445 | " 0x%04x not supported\n", service_action); |
436 | goto out_unsupported_cdb; | 446 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
437 | } | 447 | } |
438 | break; | 448 | break; |
439 | } | 449 | } |
@@ -449,7 +459,7 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops) | |||
449 | default: | 459 | default: |
450 | pr_err("Unsupported SA: 0x%02x\n", | 460 | pr_err("Unsupported SA: 0x%02x\n", |
451 | cmd->t_task_cdb[1] & 0x1f); | 461 | cmd->t_task_cdb[1] & 0x1f); |
452 | goto out_invalid_cdb_field; | 462 | return TCM_INVALID_CDB_FIELD; |
453 | } | 463 | } |
454 | size = (cdb[10] << 24) | (cdb[11] << 16) | | 464 | size = (cdb[10] << 24) | (cdb[11] << 16) | |
455 | (cdb[12] << 8) | cdb[13]; | 465 | (cdb[12] << 8) | cdb[13]; |
@@ -457,7 +467,7 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops) | |||
457 | case SYNCHRONIZE_CACHE: | 467 | case SYNCHRONIZE_CACHE: |
458 | case SYNCHRONIZE_CACHE_16: | 468 | case SYNCHRONIZE_CACHE_16: |
459 | if (!ops->execute_sync_cache) | 469 | if (!ops->execute_sync_cache) |
460 | goto out_unsupported_cdb; | 470 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
461 | 471 | ||
462 | /* | 472 | /* |
463 | * Extract LBA and range to be flushed for emulated SYNCHRONIZE_CACHE | 473 | * Extract LBA and range to be flushed for emulated SYNCHRONIZE_CACHE |
@@ -478,42 +488,36 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops) | |||
478 | */ | 488 | */ |
479 | if (cmd->t_task_lba || sectors) { | 489 | if (cmd->t_task_lba || sectors) { |
480 | if (sbc_check_valid_sectors(cmd) < 0) | 490 | if (sbc_check_valid_sectors(cmd) < 0) |
481 | goto out_invalid_cdb_field; | 491 | return TCM_INVALID_CDB_FIELD; |
482 | } | 492 | } |
483 | cmd->execute_cmd = ops->execute_sync_cache; | 493 | cmd->execute_cmd = ops->execute_sync_cache; |
484 | break; | 494 | break; |
485 | case UNMAP: | 495 | case UNMAP: |
486 | if (!ops->execute_unmap) | 496 | if (!ops->execute_unmap) |
487 | goto out_unsupported_cdb; | 497 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
488 | 498 | ||
489 | size = get_unaligned_be16(&cdb[7]); | 499 | size = get_unaligned_be16(&cdb[7]); |
490 | cmd->execute_cmd = ops->execute_unmap; | 500 | cmd->execute_cmd = ops->execute_unmap; |
491 | break; | 501 | break; |
492 | case WRITE_SAME_16: | 502 | case WRITE_SAME_16: |
493 | if (!ops->execute_write_same) | ||
494 | goto out_unsupported_cdb; | ||
495 | |||
496 | sectors = transport_get_sectors_16(cdb); | 503 | sectors = transport_get_sectors_16(cdb); |
497 | if (!sectors) { | 504 | if (!sectors) { |
498 | pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not supported\n"); | 505 | pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not supported\n"); |
499 | goto out_invalid_cdb_field; | 506 | return TCM_INVALID_CDB_FIELD; |
500 | } | 507 | } |
501 | 508 | ||
502 | size = sbc_get_size(cmd, 1); | 509 | size = sbc_get_size(cmd, 1); |
503 | cmd->t_task_lba = get_unaligned_be64(&cdb[2]); | 510 | cmd->t_task_lba = get_unaligned_be64(&cdb[2]); |
504 | 511 | ||
505 | if (sbc_write_same_supported(dev, &cdb[1]) < 0) | 512 | ret = sbc_setup_write_same(cmd, &cdb[1], ops); |
506 | goto out_unsupported_cdb; | 513 | if (ret) |
507 | cmd->execute_cmd = ops->execute_write_same; | 514 | return ret; |
508 | break; | 515 | break; |
509 | case WRITE_SAME: | 516 | case WRITE_SAME: |
510 | if (!ops->execute_write_same) | ||
511 | goto out_unsupported_cdb; | ||
512 | |||
513 | sectors = transport_get_sectors_10(cdb); | 517 | sectors = transport_get_sectors_10(cdb); |
514 | if (!sectors) { | 518 | if (!sectors) { |
515 | pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not supported\n"); | 519 | pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not supported\n"); |
516 | goto out_invalid_cdb_field; | 520 | return TCM_INVALID_CDB_FIELD; |
517 | } | 521 | } |
518 | 522 | ||
519 | size = sbc_get_size(cmd, 1); | 523 | size = sbc_get_size(cmd, 1); |
@@ -523,13 +527,25 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops) | |||
523 | * Follow sbcr26 with WRITE_SAME (10) and check for the existence | 527 | * Follow sbcr26 with WRITE_SAME (10) and check for the existence |
524 | * of byte 1 bit 3 UNMAP instead of original reserved field | 528 | * of byte 1 bit 3 UNMAP instead of original reserved field |
525 | */ | 529 | */ |
526 | if (sbc_write_same_supported(dev, &cdb[1]) < 0) | 530 | ret = sbc_setup_write_same(cmd, &cdb[1], ops); |
527 | goto out_unsupported_cdb; | 531 | if (ret) |
528 | cmd->execute_cmd = ops->execute_write_same; | 532 | return ret; |
529 | break; | 533 | break; |
530 | case VERIFY: | 534 | case VERIFY: |
531 | size = 0; | 535 | size = 0; |
532 | cmd->execute_cmd = sbc_emulate_verify; | 536 | cmd->execute_cmd = sbc_emulate_noop; |
537 | break; | ||
538 | case REZERO_UNIT: | ||
539 | case SEEK_6: | ||
540 | case SEEK_10: | ||
541 | /* | ||
542 | * There are still clients out there which use these old SCSI-2 | ||
543 | * commands. This mainly happens when running VMs with legacy | ||
544 | * guest systems, connected via SCSI command pass-through to | ||
545 | * iSCSI targets. Make them happy and return status GOOD. | ||
546 | */ | ||
547 | size = 0; | ||
548 | cmd->execute_cmd = sbc_emulate_noop; | ||
533 | break; | 549 | break; |
534 | default: | 550 | default: |
535 | ret = spc_parse_cdb(cmd, &size); | 551 | ret = spc_parse_cdb(cmd, &size); |
@@ -539,24 +555,24 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops) | |||
539 | 555 | ||
540 | /* reject any command that we don't have a handler for */ | 556 | /* reject any command that we don't have a handler for */ |
541 | if (!(cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && !cmd->execute_cmd) | 557 | if (!(cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && !cmd->execute_cmd) |
542 | goto out_unsupported_cdb; | 558 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
543 | 559 | ||
544 | if (cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) { | 560 | if (cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) { |
545 | unsigned long long end_lba; | 561 | unsigned long long end_lba; |
546 | 562 | ||
547 | if (sectors > su_dev->se_dev_attrib.fabric_max_sectors) { | 563 | if (sectors > dev->dev_attrib.fabric_max_sectors) { |
548 | printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" | 564 | printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" |
549 | " big sectors %u exceeds fabric_max_sectors:" | 565 | " big sectors %u exceeds fabric_max_sectors:" |
550 | " %u\n", cdb[0], sectors, | 566 | " %u\n", cdb[0], sectors, |
551 | su_dev->se_dev_attrib.fabric_max_sectors); | 567 | dev->dev_attrib.fabric_max_sectors); |
552 | goto out_invalid_cdb_field; | 568 | return TCM_INVALID_CDB_FIELD; |
553 | } | 569 | } |
554 | if (sectors > su_dev->se_dev_attrib.hw_max_sectors) { | 570 | if (sectors > dev->dev_attrib.hw_max_sectors) { |
555 | printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" | 571 | printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" |
556 | " big sectors %u exceeds backend hw_max_sectors:" | 572 | " big sectors %u exceeds backend hw_max_sectors:" |
557 | " %u\n", cdb[0], sectors, | 573 | " %u\n", cdb[0], sectors, |
558 | su_dev->se_dev_attrib.hw_max_sectors); | 574 | dev->dev_attrib.hw_max_sectors); |
559 | goto out_invalid_cdb_field; | 575 | return TCM_INVALID_CDB_FIELD; |
560 | } | 576 | } |
561 | 577 | ||
562 | end_lba = dev->transport->get_blocks(dev) + 1; | 578 | end_lba = dev->transport->get_blocks(dev) + 1; |
@@ -564,25 +580,18 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops) | |||
564 | pr_err("cmd exceeds last lba %llu " | 580 | pr_err("cmd exceeds last lba %llu " |
565 | "(lba %llu, sectors %u)\n", | 581 | "(lba %llu, sectors %u)\n", |
566 | end_lba, cmd->t_task_lba, sectors); | 582 | end_lba, cmd->t_task_lba, sectors); |
567 | goto out_invalid_cdb_field; | 583 | return TCM_INVALID_CDB_FIELD; |
568 | } | 584 | } |
569 | 585 | ||
570 | size = sbc_get_size(cmd, sectors); | 586 | size = sbc_get_size(cmd, sectors); |
571 | } | 587 | } |
572 | 588 | ||
573 | ret = target_cmd_size_check(cmd, size); | 589 | return target_cmd_size_check(cmd, size); |
574 | if (ret < 0) | ||
575 | return ret; | ||
576 | |||
577 | return 0; | ||
578 | |||
579 | out_unsupported_cdb: | ||
580 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
581 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | ||
582 | return -EINVAL; | ||
583 | out_invalid_cdb_field: | ||
584 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
585 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
586 | return -EINVAL; | ||
587 | } | 590 | } |
588 | EXPORT_SYMBOL(sbc_parse_cdb); | 591 | EXPORT_SYMBOL(sbc_parse_cdb); |
592 | |||
593 | u32 sbc_get_device_type(struct se_device *dev) | ||
594 | { | ||
595 | return TYPE_DISK; | ||
596 | } | ||
597 | EXPORT_SYMBOL(sbc_get_device_type); | ||
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 9229bd9ad61b..84f9e96e8ace 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c | |||
@@ -1,10 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * SCSI Primary Commands (SPC) parsing and emulation. | 2 | * SCSI Primary Commands (SPC) parsing and emulation. |
3 | * | 3 | * |
4 | * Copyright (c) 2002, 2003, 2004, 2005 PyX Technologies, Inc. | 4 | * (c) Copyright 2002-2012 RisingTide Systems LLC. |
5 | * Copyright (c) 2005, 2006, 2007 SBE, Inc. | ||
6 | * Copyright (c) 2007-2010 Rising Tide Systems | ||
7 | * Copyright (c) 2008-2010 Linux-iSCSI.org | ||
8 | * | 5 | * |
9 | * Nicholas A. Bellinger <nab@kernel.org> | 6 | * Nicholas A. Bellinger <nab@kernel.org> |
10 | * | 7 | * |
@@ -69,7 +66,8 @@ static void spc_fill_alua_data(struct se_port *port, unsigned char *buf) | |||
69 | spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); | 66 | spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); |
70 | } | 67 | } |
71 | 68 | ||
72 | static int spc_emulate_inquiry_std(struct se_cmd *cmd, char *buf) | 69 | static sense_reason_t |
70 | spc_emulate_inquiry_std(struct se_cmd *cmd, char *buf) | ||
73 | { | 71 | { |
74 | struct se_lun *lun = cmd->se_lun; | 72 | struct se_lun *lun = cmd->se_lun; |
75 | struct se_device *dev = cmd->se_dev; | 73 | struct se_device *dev = cmd->se_dev; |
@@ -78,7 +76,7 @@ static int spc_emulate_inquiry_std(struct se_cmd *cmd, char *buf) | |||
78 | if (dev->transport->get_device_type(dev) == TYPE_TAPE) | 76 | if (dev->transport->get_device_type(dev) == TYPE_TAPE) |
79 | buf[1] = 0x80; | 77 | buf[1] = 0x80; |
80 | 78 | ||
81 | buf[2] = dev->transport->get_device_rev(dev); | 79 | buf[2] = 0x05; /* SPC-3 */ |
82 | 80 | ||
83 | /* | 81 | /* |
84 | * NORMACA and HISUP = 0, RESPONSE DATA FORMAT = 2 | 82 | * NORMACA and HISUP = 0, RESPONSE DATA FORMAT = 2 |
@@ -95,34 +93,32 @@ static int spc_emulate_inquiry_std(struct se_cmd *cmd, char *buf) | |||
95 | /* | 93 | /* |
96 | * Enable SCCS and TPGS fields for Emulated ALUA | 94 | * Enable SCCS and TPGS fields for Emulated ALUA |
97 | */ | 95 | */ |
98 | if (dev->se_sub_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) | 96 | spc_fill_alua_data(lun->lun_sep, buf); |
99 | spc_fill_alua_data(lun->lun_sep, buf); | ||
100 | 97 | ||
101 | buf[7] = 0x2; /* CmdQue=1 */ | 98 | buf[7] = 0x2; /* CmdQue=1 */ |
102 | 99 | ||
103 | snprintf(&buf[8], 8, "LIO-ORG"); | 100 | snprintf(&buf[8], 8, "LIO-ORG"); |
104 | snprintf(&buf[16], 16, "%s", dev->se_sub_dev->t10_wwn.model); | 101 | snprintf(&buf[16], 16, "%s", dev->t10_wwn.model); |
105 | snprintf(&buf[32], 4, "%s", dev->se_sub_dev->t10_wwn.revision); | 102 | snprintf(&buf[32], 4, "%s", dev->t10_wwn.revision); |
106 | buf[4] = 31; /* Set additional length to 31 */ | 103 | buf[4] = 31; /* Set additional length to 31 */ |
107 | 104 | ||
108 | return 0; | 105 | return 0; |
109 | } | 106 | } |
110 | 107 | ||
111 | /* unit serial number */ | 108 | /* unit serial number */ |
112 | static int spc_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf) | 109 | static sense_reason_t |
110 | spc_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf) | ||
113 | { | 111 | { |
114 | struct se_device *dev = cmd->se_dev; | 112 | struct se_device *dev = cmd->se_dev; |
115 | u16 len = 0; | 113 | u16 len = 0; |
116 | 114 | ||
117 | if (dev->se_sub_dev->su_dev_flags & | 115 | if (dev->dev_flags & DF_EMULATED_VPD_UNIT_SERIAL) { |
118 | SDF_EMULATED_VPD_UNIT_SERIAL) { | ||
119 | u32 unit_serial_len; | 116 | u32 unit_serial_len; |
120 | 117 | ||
121 | unit_serial_len = strlen(dev->se_sub_dev->t10_wwn.unit_serial); | 118 | unit_serial_len = strlen(dev->t10_wwn.unit_serial); |
122 | unit_serial_len++; /* For NULL Terminator */ | 119 | unit_serial_len++; /* For NULL Terminator */ |
123 | 120 | ||
124 | len += sprintf(&buf[4], "%s", | 121 | len += sprintf(&buf[4], "%s", dev->t10_wwn.unit_serial); |
125 | dev->se_sub_dev->t10_wwn.unit_serial); | ||
126 | len++; /* Extra Byte for NULL Terminator */ | 122 | len++; /* Extra Byte for NULL Terminator */ |
127 | buf[3] = len; | 123 | buf[3] = len; |
128 | } | 124 | } |
@@ -132,7 +128,7 @@ static int spc_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf) | |||
132 | static void spc_parse_naa_6h_vendor_specific(struct se_device *dev, | 128 | static void spc_parse_naa_6h_vendor_specific(struct se_device *dev, |
133 | unsigned char *buf) | 129 | unsigned char *buf) |
134 | { | 130 | { |
135 | unsigned char *p = &dev->se_sub_dev->t10_wwn.unit_serial[0]; | 131 | unsigned char *p = &dev->t10_wwn.unit_serial[0]; |
136 | int cnt; | 132 | int cnt; |
137 | bool next = true; | 133 | bool next = true; |
138 | 134 | ||
@@ -164,7 +160,8 @@ static void spc_parse_naa_6h_vendor_specific(struct se_device *dev, | |||
164 | * Device identification VPD, for a complete list of | 160 | * Device identification VPD, for a complete list of |
165 | * DESIGNATOR TYPEs see spc4r17 Table 459. | 161 | * DESIGNATOR TYPEs see spc4r17 Table 459. |
166 | */ | 162 | */ |
167 | static int spc_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf) | 163 | static sense_reason_t |
164 | spc_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf) | ||
168 | { | 165 | { |
169 | struct se_device *dev = cmd->se_dev; | 166 | struct se_device *dev = cmd->se_dev; |
170 | struct se_lun *lun = cmd->se_lun; | 167 | struct se_lun *lun = cmd->se_lun; |
@@ -173,7 +170,7 @@ static int spc_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf) | |||
173 | struct t10_alua_lu_gp_member *lu_gp_mem; | 170 | struct t10_alua_lu_gp_member *lu_gp_mem; |
174 | struct t10_alua_tg_pt_gp *tg_pt_gp; | 171 | struct t10_alua_tg_pt_gp *tg_pt_gp; |
175 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; | 172 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; |
176 | unsigned char *prod = &dev->se_sub_dev->t10_wwn.model[0]; | 173 | unsigned char *prod = &dev->t10_wwn.model[0]; |
177 | u32 prod_len; | 174 | u32 prod_len; |
178 | u32 unit_serial_len, off = 0; | 175 | u32 unit_serial_len, off = 0; |
179 | u16 len = 0, id_len; | 176 | u16 len = 0, id_len; |
@@ -188,7 +185,7 @@ static int spc_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf) | |||
188 | * /sys/kernel/config/target/core/$HBA/$DEV/wwn/vpd_unit_serial | 185 | * /sys/kernel/config/target/core/$HBA/$DEV/wwn/vpd_unit_serial |
189 | * value in order to return the NAA id. | 186 | * value in order to return the NAA id. |
190 | */ | 187 | */ |
191 | if (!(dev->se_sub_dev->su_dev_flags & SDF_EMULATED_VPD_UNIT_SERIAL)) | 188 | if (!(dev->dev_flags & DF_EMULATED_VPD_UNIT_SERIAL)) |
192 | goto check_t10_vend_desc; | 189 | goto check_t10_vend_desc; |
193 | 190 | ||
194 | /* CODE SET == Binary */ | 191 | /* CODE SET == Binary */ |
@@ -236,14 +233,12 @@ check_t10_vend_desc: | |||
236 | prod_len += strlen(prod); | 233 | prod_len += strlen(prod); |
237 | prod_len++; /* For : */ | 234 | prod_len++; /* For : */ |
238 | 235 | ||
239 | if (dev->se_sub_dev->su_dev_flags & | 236 | if (dev->dev_flags & DF_EMULATED_VPD_UNIT_SERIAL) { |
240 | SDF_EMULATED_VPD_UNIT_SERIAL) { | 237 | unit_serial_len = strlen(&dev->t10_wwn.unit_serial[0]); |
241 | unit_serial_len = | ||
242 | strlen(&dev->se_sub_dev->t10_wwn.unit_serial[0]); | ||
243 | unit_serial_len++; /* For NULL Terminator */ | 238 | unit_serial_len++; /* For NULL Terminator */ |
244 | 239 | ||
245 | id_len += sprintf(&buf[off+12], "%s:%s", prod, | 240 | id_len += sprintf(&buf[off+12], "%s:%s", prod, |
246 | &dev->se_sub_dev->t10_wwn.unit_serial[0]); | 241 | &dev->t10_wwn.unit_serial[0]); |
247 | } | 242 | } |
248 | buf[off] = 0x2; /* ASCII */ | 243 | buf[off] = 0x2; /* ASCII */ |
249 | buf[off+1] = 0x1; /* T10 Vendor ID */ | 244 | buf[off+1] = 0x1; /* T10 Vendor ID */ |
@@ -298,10 +293,6 @@ check_t10_vend_desc: | |||
298 | * Get the PROTOCOL IDENTIFIER as defined by spc4r17 | 293 | * Get the PROTOCOL IDENTIFIER as defined by spc4r17 |
299 | * section 7.5.1 Table 362 | 294 | * section 7.5.1 Table 362 |
300 | */ | 295 | */ |
301 | if (dev->se_sub_dev->t10_alua.alua_type != | ||
302 | SPC3_ALUA_EMULATED) | ||
303 | goto check_scsi_name; | ||
304 | |||
305 | tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; | 296 | tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; |
306 | if (!tg_pt_gp_mem) | 297 | if (!tg_pt_gp_mem) |
307 | goto check_lu_gp; | 298 | goto check_lu_gp; |
@@ -415,20 +406,22 @@ check_scsi_name: | |||
415 | } | 406 | } |
416 | 407 | ||
417 | /* Extended INQUIRY Data VPD Page */ | 408 | /* Extended INQUIRY Data VPD Page */ |
418 | static int spc_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) | 409 | static sense_reason_t |
410 | spc_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) | ||
419 | { | 411 | { |
420 | buf[3] = 0x3c; | 412 | buf[3] = 0x3c; |
421 | /* Set HEADSUP, ORDSUP, SIMPSUP */ | 413 | /* Set HEADSUP, ORDSUP, SIMPSUP */ |
422 | buf[5] = 0x07; | 414 | buf[5] = 0x07; |
423 | 415 | ||
424 | /* If WriteCache emulation is enabled, set V_SUP */ | 416 | /* If WriteCache emulation is enabled, set V_SUP */ |
425 | if (cmd->se_dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) | 417 | if (cmd->se_dev->dev_attrib.emulate_write_cache > 0) |
426 | buf[6] = 0x01; | 418 | buf[6] = 0x01; |
427 | return 0; | 419 | return 0; |
428 | } | 420 | } |
429 | 421 | ||
430 | /* Block Limits VPD page */ | 422 | /* Block Limits VPD page */ |
431 | static int spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) | 423 | static sense_reason_t |
424 | spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) | ||
432 | { | 425 | { |
433 | struct se_device *dev = cmd->se_dev; | 426 | struct se_device *dev = cmd->se_dev; |
434 | u32 max_sectors; | 427 | u32 max_sectors; |
@@ -439,7 +432,7 @@ static int spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) | |||
439 | * emulate_tpu=1 or emulate_tpws=1 we will be expect a | 432 | * emulate_tpu=1 or emulate_tpws=1 we will be expect a |
440 | * different page length for Thin Provisioning. | 433 | * different page length for Thin Provisioning. |
441 | */ | 434 | */ |
442 | if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws) | 435 | if (dev->dev_attrib.emulate_tpu || dev->dev_attrib.emulate_tpws) |
443 | have_tp = 1; | 436 | have_tp = 1; |
444 | 437 | ||
445 | buf[0] = dev->transport->get_device_type(dev); | 438 | buf[0] = dev->transport->get_device_type(dev); |
@@ -456,62 +449,70 @@ static int spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) | |||
456 | /* | 449 | /* |
457 | * Set MAXIMUM TRANSFER LENGTH | 450 | * Set MAXIMUM TRANSFER LENGTH |
458 | */ | 451 | */ |
459 | max_sectors = min(dev->se_sub_dev->se_dev_attrib.fabric_max_sectors, | 452 | max_sectors = min(dev->dev_attrib.fabric_max_sectors, |
460 | dev->se_sub_dev->se_dev_attrib.hw_max_sectors); | 453 | dev->dev_attrib.hw_max_sectors); |
461 | put_unaligned_be32(max_sectors, &buf[8]); | 454 | put_unaligned_be32(max_sectors, &buf[8]); |
462 | 455 | ||
463 | /* | 456 | /* |
464 | * Set OPTIMAL TRANSFER LENGTH | 457 | * Set OPTIMAL TRANSFER LENGTH |
465 | */ | 458 | */ |
466 | put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.optimal_sectors, &buf[12]); | 459 | put_unaligned_be32(dev->dev_attrib.optimal_sectors, &buf[12]); |
467 | 460 | ||
468 | /* | 461 | /* |
469 | * Exit now if we don't support TP. | 462 | * Exit now if we don't support TP. |
470 | */ | 463 | */ |
471 | if (!have_tp) | 464 | if (!have_tp) |
472 | return 0; | 465 | goto max_write_same; |
473 | 466 | ||
474 | /* | 467 | /* |
475 | * Set MAXIMUM UNMAP LBA COUNT | 468 | * Set MAXIMUM UNMAP LBA COUNT |
476 | */ | 469 | */ |
477 | put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.max_unmap_lba_count, &buf[20]); | 470 | put_unaligned_be32(dev->dev_attrib.max_unmap_lba_count, &buf[20]); |
478 | 471 | ||
479 | /* | 472 | /* |
480 | * Set MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT | 473 | * Set MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT |
481 | */ | 474 | */ |
482 | put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count, | 475 | put_unaligned_be32(dev->dev_attrib.max_unmap_block_desc_count, |
483 | &buf[24]); | 476 | &buf[24]); |
484 | 477 | ||
485 | /* | 478 | /* |
486 | * Set OPTIMAL UNMAP GRANULARITY | 479 | * Set OPTIMAL UNMAP GRANULARITY |
487 | */ | 480 | */ |
488 | put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.unmap_granularity, &buf[28]); | 481 | put_unaligned_be32(dev->dev_attrib.unmap_granularity, &buf[28]); |
489 | 482 | ||
490 | /* | 483 | /* |
491 | * UNMAP GRANULARITY ALIGNMENT | 484 | * UNMAP GRANULARITY ALIGNMENT |
492 | */ | 485 | */ |
493 | put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.unmap_granularity_alignment, | 486 | put_unaligned_be32(dev->dev_attrib.unmap_granularity_alignment, |
494 | &buf[32]); | 487 | &buf[32]); |
495 | if (dev->se_sub_dev->se_dev_attrib.unmap_granularity_alignment != 0) | 488 | if (dev->dev_attrib.unmap_granularity_alignment != 0) |
496 | buf[32] |= 0x80; /* Set the UGAVALID bit */ | 489 | buf[32] |= 0x80; /* Set the UGAVALID bit */ |
497 | 490 | ||
491 | /* | ||
492 | * MAXIMUM WRITE SAME LENGTH | ||
493 | */ | ||
494 | max_write_same: | ||
495 | put_unaligned_be64(dev->dev_attrib.max_write_same_len, &buf[36]); | ||
496 | |||
498 | return 0; | 497 | return 0; |
499 | } | 498 | } |
500 | 499 | ||
501 | /* Block Device Characteristics VPD page */ | 500 | /* Block Device Characteristics VPD page */ |
502 | static int spc_emulate_evpd_b1(struct se_cmd *cmd, unsigned char *buf) | 501 | static sense_reason_t |
502 | spc_emulate_evpd_b1(struct se_cmd *cmd, unsigned char *buf) | ||
503 | { | 503 | { |
504 | struct se_device *dev = cmd->se_dev; | 504 | struct se_device *dev = cmd->se_dev; |
505 | 505 | ||
506 | buf[0] = dev->transport->get_device_type(dev); | 506 | buf[0] = dev->transport->get_device_type(dev); |
507 | buf[3] = 0x3c; | 507 | buf[3] = 0x3c; |
508 | buf[5] = dev->se_sub_dev->se_dev_attrib.is_nonrot ? 1 : 0; | 508 | buf[5] = dev->dev_attrib.is_nonrot ? 1 : 0; |
509 | 509 | ||
510 | return 0; | 510 | return 0; |
511 | } | 511 | } |
512 | 512 | ||
513 | /* Thin Provisioning VPD */ | 513 | /* Thin Provisioning VPD */ |
514 | static int spc_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) | 514 | static sense_reason_t |
515 | spc_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) | ||
515 | { | 516 | { |
516 | struct se_device *dev = cmd->se_dev; | 517 | struct se_device *dev = cmd->se_dev; |
517 | 518 | ||
@@ -546,7 +547,7 @@ static int spc_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) | |||
546 | * the UNMAP command (see 5.25). A TPU bit set to zero indicates | 547 | * the UNMAP command (see 5.25). A TPU bit set to zero indicates |
547 | * that the device server does not support the UNMAP command. | 548 | * that the device server does not support the UNMAP command. |
548 | */ | 549 | */ |
549 | if (dev->se_sub_dev->se_dev_attrib.emulate_tpu != 0) | 550 | if (dev->dev_attrib.emulate_tpu != 0) |
550 | buf[5] = 0x80; | 551 | buf[5] = 0x80; |
551 | 552 | ||
552 | /* | 553 | /* |
@@ -555,17 +556,18 @@ static int spc_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) | |||
555 | * A TPWS bit set to zero indicates that the device server does not | 556 | * A TPWS bit set to zero indicates that the device server does not |
556 | * support the use of the WRITE SAME (16) command to unmap LBAs. | 557 | * support the use of the WRITE SAME (16) command to unmap LBAs. |
557 | */ | 558 | */ |
558 | if (dev->se_sub_dev->se_dev_attrib.emulate_tpws != 0) | 559 | if (dev->dev_attrib.emulate_tpws != 0) |
559 | buf[5] |= 0x40; | 560 | buf[5] |= 0x40; |
560 | 561 | ||
561 | return 0; | 562 | return 0; |
562 | } | 563 | } |
563 | 564 | ||
564 | static int spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf); | 565 | static sense_reason_t |
566 | spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf); | ||
565 | 567 | ||
566 | static struct { | 568 | static struct { |
567 | uint8_t page; | 569 | uint8_t page; |
568 | int (*emulate)(struct se_cmd *, unsigned char *); | 570 | sense_reason_t (*emulate)(struct se_cmd *, unsigned char *); |
569 | } evpd_handlers[] = { | 571 | } evpd_handlers[] = { |
570 | { .page = 0x00, .emulate = spc_emulate_evpd_00 }, | 572 | { .page = 0x00, .emulate = spc_emulate_evpd_00 }, |
571 | { .page = 0x80, .emulate = spc_emulate_evpd_80 }, | 573 | { .page = 0x80, .emulate = spc_emulate_evpd_80 }, |
@@ -577,7 +579,8 @@ static struct { | |||
577 | }; | 579 | }; |
578 | 580 | ||
579 | /* supported vital product data pages */ | 581 | /* supported vital product data pages */ |
580 | static int spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) | 582 | static sense_reason_t |
583 | spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) | ||
581 | { | 584 | { |
582 | int p; | 585 | int p; |
583 | 586 | ||
@@ -586,8 +589,7 @@ static int spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) | |||
586 | * Registered Extended LUN WWN has been set via ConfigFS | 589 | * Registered Extended LUN WWN has been set via ConfigFS |
587 | * during device creation/restart. | 590 | * during device creation/restart. |
588 | */ | 591 | */ |
589 | if (cmd->se_dev->se_sub_dev->su_dev_flags & | 592 | if (cmd->se_dev->dev_flags & DF_EMULATED_VPD_UNIT_SERIAL) { |
590 | SDF_EMULATED_VPD_UNIT_SERIAL) { | ||
591 | buf[3] = ARRAY_SIZE(evpd_handlers); | 593 | buf[3] = ARRAY_SIZE(evpd_handlers); |
592 | for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p) | 594 | for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p) |
593 | buf[p + 4] = evpd_handlers[p].page; | 595 | buf[p + 4] = evpd_handlers[p].page; |
@@ -596,14 +598,18 @@ static int spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) | |||
596 | return 0; | 598 | return 0; |
597 | } | 599 | } |
598 | 600 | ||
599 | static int spc_emulate_inquiry(struct se_cmd *cmd) | 601 | static sense_reason_t |
602 | spc_emulate_inquiry(struct se_cmd *cmd) | ||
600 | { | 603 | { |
601 | struct se_device *dev = cmd->se_dev; | 604 | struct se_device *dev = cmd->se_dev; |
602 | struct se_portal_group *tpg = cmd->se_lun->lun_sep->sep_tpg; | 605 | struct se_portal_group *tpg = cmd->se_lun->lun_sep->sep_tpg; |
603 | unsigned char *rbuf; | 606 | unsigned char *rbuf; |
604 | unsigned char *cdb = cmd->t_task_cdb; | 607 | unsigned char *cdb = cmd->t_task_cdb; |
605 | unsigned char buf[SE_INQUIRY_BUF]; | 608 | unsigned char buf[SE_INQUIRY_BUF]; |
606 | int p, ret; | 609 | sense_reason_t ret; |
610 | int p; | ||
611 | |||
612 | memset(buf, 0, SE_INQUIRY_BUF); | ||
607 | 613 | ||
608 | if (dev == tpg->tpg_virt_lun0.lun_se_dev) | 614 | if (dev == tpg->tpg_virt_lun0.lun_se_dev) |
609 | buf[0] = 0x3f; /* Not connected */ | 615 | buf[0] = 0x3f; /* Not connected */ |
@@ -614,8 +620,7 @@ static int spc_emulate_inquiry(struct se_cmd *cmd) | |||
614 | if (cdb[2]) { | 620 | if (cdb[2]) { |
615 | pr_err("INQUIRY with EVPD==0 but PAGE CODE=%02x\n", | 621 | pr_err("INQUIRY with EVPD==0 but PAGE CODE=%02x\n", |
616 | cdb[2]); | 622 | cdb[2]); |
617 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 623 | ret = TCM_INVALID_CDB_FIELD; |
618 | ret = -EINVAL; | ||
619 | goto out; | 624 | goto out; |
620 | } | 625 | } |
621 | 626 | ||
@@ -632,33 +637,43 @@ static int spc_emulate_inquiry(struct se_cmd *cmd) | |||
632 | } | 637 | } |
633 | 638 | ||
634 | pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]); | 639 | pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]); |
635 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 640 | ret = TCM_INVALID_CDB_FIELD; |
636 | ret = -EINVAL; | ||
637 | 641 | ||
638 | out: | 642 | out: |
639 | rbuf = transport_kmap_data_sg(cmd); | 643 | rbuf = transport_kmap_data_sg(cmd); |
640 | if (rbuf) { | 644 | if (!rbuf) |
641 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); | 645 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
642 | transport_kunmap_data_sg(cmd); | 646 | |
643 | } | 647 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); |
648 | transport_kunmap_data_sg(cmd); | ||
644 | 649 | ||
645 | if (!ret) | 650 | if (!ret) |
646 | target_complete_cmd(cmd, GOOD); | 651 | target_complete_cmd(cmd, GOOD); |
647 | return ret; | 652 | return ret; |
648 | } | 653 | } |
649 | 654 | ||
650 | static int spc_modesense_rwrecovery(unsigned char *p) | 655 | static int spc_modesense_rwrecovery(struct se_device *dev, u8 pc, u8 *p) |
651 | { | 656 | { |
652 | p[0] = 0x01; | 657 | p[0] = 0x01; |
653 | p[1] = 0x0a; | 658 | p[1] = 0x0a; |
654 | 659 | ||
660 | /* No changeable values for now */ | ||
661 | if (pc == 1) | ||
662 | goto out; | ||
663 | |||
664 | out: | ||
655 | return 12; | 665 | return 12; |
656 | } | 666 | } |
657 | 667 | ||
658 | static int spc_modesense_control(struct se_device *dev, unsigned char *p) | 668 | static int spc_modesense_control(struct se_device *dev, u8 pc, u8 *p) |
659 | { | 669 | { |
660 | p[0] = 0x0a; | 670 | p[0] = 0x0a; |
661 | p[1] = 0x0a; | 671 | p[1] = 0x0a; |
672 | |||
673 | /* No changeable values for now */ | ||
674 | if (pc == 1) | ||
675 | goto out; | ||
676 | |||
662 | p[2] = 2; | 677 | p[2] = 2; |
663 | /* | 678 | /* |
664 | * From spc4r23, 7.4.7 Control mode page | 679 | * From spc4r23, 7.4.7 Control mode page |
@@ -688,7 +703,7 @@ static int spc_modesense_control(struct se_device *dev, unsigned char *p) | |||
688 | * command sequence order shall be explicitly handled by the application client | 703 | * command sequence order shall be explicitly handled by the application client |
689 | * through the selection of appropriate ommands and task attributes. | 704 | * through the selection of appropriate ommands and task attributes. |
690 | */ | 705 | */ |
691 | p[3] = (dev->se_sub_dev->se_dev_attrib.emulate_rest_reord == 1) ? 0x00 : 0x10; | 706 | p[3] = (dev->dev_attrib.emulate_rest_reord == 1) ? 0x00 : 0x10; |
692 | /* | 707 | /* |
693 | * From spc4r17, section 7.4.6 Control mode Page | 708 | * From spc4r17, section 7.4.6 Control mode Page |
694 | * | 709 | * |
@@ -718,8 +733,8 @@ static int spc_modesense_control(struct se_device *dev, unsigned char *p) | |||
718 | * for a BUSY, TASK SET FULL, or RESERVATION CONFLICT status regardless | 733 | * for a BUSY, TASK SET FULL, or RESERVATION CONFLICT status regardless |
719 | * to the number of commands completed with one of those status codes. | 734 | * to the number of commands completed with one of those status codes. |
720 | */ | 735 | */ |
721 | p[4] = (dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl == 2) ? 0x30 : | 736 | p[4] = (dev->dev_attrib.emulate_ua_intlck_ctrl == 2) ? 0x30 : |
722 | (dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl == 1) ? 0x20 : 0x00; | 737 | (dev->dev_attrib.emulate_ua_intlck_ctrl == 1) ? 0x20 : 0x00; |
723 | /* | 738 | /* |
724 | * From spc4r17, section 7.4.6 Control mode Page | 739 | * From spc4r17, section 7.4.6 Control mode Page |
725 | * | 740 | * |
@@ -732,25 +747,56 @@ static int spc_modesense_control(struct se_device *dev, unsigned char *p) | |||
732 | * which the command was received shall be completed with TASK ABORTED | 747 | * which the command was received shall be completed with TASK ABORTED |
733 | * status (see SAM-4). | 748 | * status (see SAM-4). |
734 | */ | 749 | */ |
735 | p[5] = (dev->se_sub_dev->se_dev_attrib.emulate_tas) ? 0x40 : 0x00; | 750 | p[5] = (dev->dev_attrib.emulate_tas) ? 0x40 : 0x00; |
736 | p[8] = 0xff; | 751 | p[8] = 0xff; |
737 | p[9] = 0xff; | 752 | p[9] = 0xff; |
738 | p[11] = 30; | 753 | p[11] = 30; |
739 | 754 | ||
755 | out: | ||
740 | return 12; | 756 | return 12; |
741 | } | 757 | } |
742 | 758 | ||
743 | static int spc_modesense_caching(struct se_device *dev, unsigned char *p) | 759 | static int spc_modesense_caching(struct se_device *dev, u8 pc, u8 *p) |
744 | { | 760 | { |
745 | p[0] = 0x08; | 761 | p[0] = 0x08; |
746 | p[1] = 0x12; | 762 | p[1] = 0x12; |
747 | if (dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) | 763 | |
764 | /* No changeable values for now */ | ||
765 | if (pc == 1) | ||
766 | goto out; | ||
767 | |||
768 | if (dev->dev_attrib.emulate_write_cache > 0) | ||
748 | p[2] = 0x04; /* Write Cache Enable */ | 769 | p[2] = 0x04; /* Write Cache Enable */ |
749 | p[12] = 0x20; /* Disabled Read Ahead */ | 770 | p[12] = 0x20; /* Disabled Read Ahead */ |
750 | 771 | ||
772 | out: | ||
751 | return 20; | 773 | return 20; |
752 | } | 774 | } |
753 | 775 | ||
776 | static int spc_modesense_informational_exceptions(struct se_device *dev, u8 pc, unsigned char *p) | ||
777 | { | ||
778 | p[0] = 0x1c; | ||
779 | p[1] = 0x0a; | ||
780 | |||
781 | /* No changeable values for now */ | ||
782 | if (pc == 1) | ||
783 | goto out; | ||
784 | |||
785 | out: | ||
786 | return 12; | ||
787 | } | ||
788 | |||
789 | static struct { | ||
790 | uint8_t page; | ||
791 | uint8_t subpage; | ||
792 | int (*emulate)(struct se_device *, u8, unsigned char *); | ||
793 | } modesense_handlers[] = { | ||
794 | { .page = 0x01, .subpage = 0x00, .emulate = spc_modesense_rwrecovery }, | ||
795 | { .page = 0x08, .subpage = 0x00, .emulate = spc_modesense_caching }, | ||
796 | { .page = 0x0a, .subpage = 0x00, .emulate = spc_modesense_control }, | ||
797 | { .page = 0x1c, .subpage = 0x00, .emulate = spc_modesense_informational_exceptions }, | ||
798 | }; | ||
799 | |||
754 | static void spc_modesense_write_protect(unsigned char *buf, int type) | 800 | static void spc_modesense_write_protect(unsigned char *buf, int type) |
755 | { | 801 | { |
756 | /* | 802 | /* |
@@ -777,82 +823,224 @@ static void spc_modesense_dpofua(unsigned char *buf, int type) | |||
777 | } | 823 | } |
778 | } | 824 | } |
779 | 825 | ||
780 | static int spc_emulate_modesense(struct se_cmd *cmd) | 826 | static int spc_modesense_blockdesc(unsigned char *buf, u64 blocks, u32 block_size) |
827 | { | ||
828 | *buf++ = 8; | ||
829 | put_unaligned_be32(min(blocks, 0xffffffffull), buf); | ||
830 | buf += 4; | ||
831 | put_unaligned_be32(block_size, buf); | ||
832 | return 9; | ||
833 | } | ||
834 | |||
835 | static int spc_modesense_long_blockdesc(unsigned char *buf, u64 blocks, u32 block_size) | ||
836 | { | ||
837 | if (blocks <= 0xffffffff) | ||
838 | return spc_modesense_blockdesc(buf + 3, blocks, block_size) + 3; | ||
839 | |||
840 | *buf++ = 1; /* LONGLBA */ | ||
841 | buf += 2; | ||
842 | *buf++ = 16; | ||
843 | put_unaligned_be64(blocks, buf); | ||
844 | buf += 12; | ||
845 | put_unaligned_be32(block_size, buf); | ||
846 | |||
847 | return 17; | ||
848 | } | ||
849 | |||
850 | static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd) | ||
781 | { | 851 | { |
782 | struct se_device *dev = cmd->se_dev; | 852 | struct se_device *dev = cmd->se_dev; |
783 | char *cdb = cmd->t_task_cdb; | 853 | char *cdb = cmd->t_task_cdb; |
784 | unsigned char *rbuf; | 854 | unsigned char *buf, *map_buf; |
785 | int type = dev->transport->get_device_type(dev); | 855 | int type = dev->transport->get_device_type(dev); |
786 | int ten = (cmd->t_task_cdb[0] == MODE_SENSE_10); | 856 | int ten = (cmd->t_task_cdb[0] == MODE_SENSE_10); |
787 | u32 offset = ten ? 8 : 4; | 857 | bool dbd = !!(cdb[1] & 0x08); |
858 | bool llba = ten ? !!(cdb[1] & 0x10) : false; | ||
859 | u8 pc = cdb[2] >> 6; | ||
860 | u8 page = cdb[2] & 0x3f; | ||
861 | u8 subpage = cdb[3]; | ||
788 | int length = 0; | 862 | int length = 0; |
789 | unsigned char buf[SE_MODE_PAGE_BUF]; | 863 | int ret; |
790 | 864 | int i; | |
791 | memset(buf, 0, SE_MODE_PAGE_BUF); | ||
792 | 865 | ||
793 | switch (cdb[2] & 0x3f) { | 866 | map_buf = transport_kmap_data_sg(cmd); |
794 | case 0x01: | 867 | if (!map_buf) |
795 | length = spc_modesense_rwrecovery(&buf[offset]); | 868 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
796 | break; | 869 | /* |
797 | case 0x08: | 870 | * If SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC is not set, then we |
798 | length = spc_modesense_caching(dev, &buf[offset]); | 871 | * know we actually allocated a full page. Otherwise, if the |
799 | break; | 872 | * data buffer is too small, allocate a temporary buffer so we |
800 | case 0x0a: | 873 | * don't have to worry about overruns in all our INQUIRY |
801 | length = spc_modesense_control(dev, &buf[offset]); | 874 | * emulation handling. |
802 | break; | 875 | */ |
803 | case 0x3f: | 876 | if (cmd->data_length < SE_MODE_PAGE_BUF && |
804 | length = spc_modesense_rwrecovery(&buf[offset]); | 877 | (cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC)) { |
805 | length += spc_modesense_caching(dev, &buf[offset+length]); | 878 | buf = kzalloc(SE_MODE_PAGE_BUF, GFP_KERNEL); |
806 | length += spc_modesense_control(dev, &buf[offset+length]); | 879 | if (!buf) { |
807 | break; | 880 | transport_kunmap_data_sg(cmd); |
808 | default: | 881 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
809 | pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n", | 882 | } |
810 | cdb[2] & 0x3f, cdb[3]); | 883 | } else { |
811 | cmd->scsi_sense_reason = TCM_UNKNOWN_MODE_PAGE; | 884 | buf = map_buf; |
812 | return -EINVAL; | ||
813 | } | 885 | } |
814 | offset += length; | 886 | /* |
815 | 887 | * Skip over MODE DATA LENGTH + MEDIUM TYPE fields to byte 3 for | |
816 | if (ten) { | 888 | * MODE_SENSE_10 and byte 2 for MODE_SENSE (6). |
817 | offset -= 2; | 889 | */ |
818 | buf[0] = (offset >> 8) & 0xff; | 890 | length = ten ? 3 : 2; |
819 | buf[1] = offset & 0xff; | 891 | |
820 | offset += 2; | 892 | /* DEVICE-SPECIFIC PARAMETER */ |
821 | 893 | if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) || | |
822 | if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) || | 894 | (cmd->se_deve && |
823 | (cmd->se_deve && | 895 | (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY))) |
824 | (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY))) | 896 | spc_modesense_write_protect(&buf[length], type); |
825 | spc_modesense_write_protect(&buf[3], type); | 897 | |
826 | 898 | if ((dev->dev_attrib.emulate_write_cache > 0) && | |
827 | if ((dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) && | 899 | (dev->dev_attrib.emulate_fua_write > 0)) |
828 | (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0)) | 900 | spc_modesense_dpofua(&buf[length], type); |
829 | spc_modesense_dpofua(&buf[3], type); | 901 | |
902 | ++length; | ||
903 | |||
904 | /* BLOCK DESCRIPTOR */ | ||
905 | |||
906 | /* | ||
907 | * For now we only include a block descriptor for disk (SBC) | ||
908 | * devices; other command sets use a slightly different format. | ||
909 | */ | ||
910 | if (!dbd && type == TYPE_DISK) { | ||
911 | u64 blocks = dev->transport->get_blocks(dev); | ||
912 | u32 block_size = dev->dev_attrib.block_size; | ||
913 | |||
914 | if (ten) { | ||
915 | if (llba) { | ||
916 | length += spc_modesense_long_blockdesc(&buf[length], | ||
917 | blocks, block_size); | ||
918 | } else { | ||
919 | length += 3; | ||
920 | length += spc_modesense_blockdesc(&buf[length], | ||
921 | blocks, block_size); | ||
922 | } | ||
923 | } else { | ||
924 | length += spc_modesense_blockdesc(&buf[length], blocks, | ||
925 | block_size); | ||
926 | } | ||
830 | } else { | 927 | } else { |
831 | offset -= 1; | 928 | if (ten) |
832 | buf[0] = offset & 0xff; | 929 | length += 4; |
833 | offset += 1; | 930 | else |
834 | 931 | length += 1; | |
835 | if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) || | ||
836 | (cmd->se_deve && | ||
837 | (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY))) | ||
838 | spc_modesense_write_protect(&buf[2], type); | ||
839 | |||
840 | if ((dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) && | ||
841 | (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0)) | ||
842 | spc_modesense_dpofua(&buf[2], type); | ||
843 | } | 932 | } |
844 | 933 | ||
845 | rbuf = transport_kmap_data_sg(cmd); | 934 | if (page == 0x3f) { |
846 | if (rbuf) { | 935 | if (subpage != 0x00 && subpage != 0xff) { |
847 | memcpy(rbuf, buf, min(offset, cmd->data_length)); | 936 | pr_warn("MODE_SENSE: Invalid subpage code: 0x%02x\n", subpage); |
848 | transport_kunmap_data_sg(cmd); | 937 | kfree(buf); |
938 | transport_kunmap_data_sg(cmd); | ||
939 | return TCM_INVALID_CDB_FIELD; | ||
940 | } | ||
941 | |||
942 | for (i = 0; i < ARRAY_SIZE(modesense_handlers); ++i) { | ||
943 | /* | ||
944 | * Tricky way to say all subpage 00h for | ||
945 | * subpage==0, all subpages for subpage==0xff | ||
946 | * (and we just checked above that those are | ||
947 | * the only two possibilities). | ||
948 | */ | ||
949 | if ((modesense_handlers[i].subpage & ~subpage) == 0) { | ||
950 | ret = modesense_handlers[i].emulate(dev, pc, &buf[length]); | ||
951 | if (!ten && length + ret >= 255) | ||
952 | break; | ||
953 | length += ret; | ||
954 | } | ||
955 | } | ||
956 | |||
957 | goto set_length; | ||
958 | } | ||
959 | |||
960 | for (i = 0; i < ARRAY_SIZE(modesense_handlers); ++i) | ||
961 | if (modesense_handlers[i].page == page && | ||
962 | modesense_handlers[i].subpage == subpage) { | ||
963 | length += modesense_handlers[i].emulate(dev, pc, &buf[length]); | ||
964 | goto set_length; | ||
965 | } | ||
966 | |||
967 | /* | ||
968 | * We don't intend to implement: | ||
969 | * - obsolete page 03h "format parameters" (checked by Solaris) | ||
970 | */ | ||
971 | if (page != 0x03) | ||
972 | pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n", | ||
973 | page, subpage); | ||
974 | |||
975 | transport_kunmap_data_sg(cmd); | ||
976 | return TCM_UNKNOWN_MODE_PAGE; | ||
977 | |||
978 | set_length: | ||
979 | if (ten) | ||
980 | put_unaligned_be16(length - 2, buf); | ||
981 | else | ||
982 | buf[0] = length - 1; | ||
983 | |||
984 | if (buf != map_buf) { | ||
985 | memcpy(map_buf, buf, cmd->data_length); | ||
986 | kfree(buf); | ||
849 | } | 987 | } |
850 | 988 | ||
989 | transport_kunmap_data_sg(cmd); | ||
851 | target_complete_cmd(cmd, GOOD); | 990 | target_complete_cmd(cmd, GOOD); |
852 | return 0; | 991 | return 0; |
853 | } | 992 | } |
854 | 993 | ||
855 | static int spc_emulate_request_sense(struct se_cmd *cmd) | 994 | static sense_reason_t spc_emulate_modeselect(struct se_cmd *cmd) |
995 | { | ||
996 | struct se_device *dev = cmd->se_dev; | ||
997 | char *cdb = cmd->t_task_cdb; | ||
998 | bool ten = cdb[0] == MODE_SELECT_10; | ||
999 | int off = ten ? 8 : 4; | ||
1000 | bool pf = !!(cdb[1] & 0x10); | ||
1001 | u8 page, subpage; | ||
1002 | unsigned char *buf; | ||
1003 | unsigned char tbuf[SE_MODE_PAGE_BUF]; | ||
1004 | int length; | ||
1005 | int ret = 0; | ||
1006 | int i; | ||
1007 | |||
1008 | buf = transport_kmap_data_sg(cmd); | ||
1009 | if (!buf) | ||
1010 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1011 | |||
1012 | if (!pf) { | ||
1013 | ret = TCM_INVALID_CDB_FIELD; | ||
1014 | goto out; | ||
1015 | } | ||
1016 | |||
1017 | page = buf[off] & 0x3f; | ||
1018 | subpage = buf[off] & 0x40 ? buf[off + 1] : 0; | ||
1019 | |||
1020 | for (i = 0; i < ARRAY_SIZE(modesense_handlers); ++i) | ||
1021 | if (modesense_handlers[i].page == page && | ||
1022 | modesense_handlers[i].subpage == subpage) { | ||
1023 | memset(tbuf, 0, SE_MODE_PAGE_BUF); | ||
1024 | length = modesense_handlers[i].emulate(dev, 0, tbuf); | ||
1025 | goto check_contents; | ||
1026 | } | ||
1027 | |||
1028 | ret = TCM_UNKNOWN_MODE_PAGE; | ||
1029 | goto out; | ||
1030 | |||
1031 | check_contents: | ||
1032 | if (memcmp(buf + off, tbuf, length)) | ||
1033 | ret = TCM_INVALID_PARAMETER_LIST; | ||
1034 | |||
1035 | out: | ||
1036 | transport_kunmap_data_sg(cmd); | ||
1037 | |||
1038 | if (!ret) | ||
1039 | target_complete_cmd(cmd, GOOD); | ||
1040 | return ret; | ||
1041 | } | ||
1042 | |||
1043 | static sense_reason_t spc_emulate_request_sense(struct se_cmd *cmd) | ||
856 | { | 1044 | { |
857 | unsigned char *cdb = cmd->t_task_cdb; | 1045 | unsigned char *cdb = cmd->t_task_cdb; |
858 | unsigned char *rbuf; | 1046 | unsigned char *rbuf; |
@@ -864,19 +1052,14 @@ static int spc_emulate_request_sense(struct se_cmd *cmd) | |||
864 | if (cdb[1] & 0x01) { | 1052 | if (cdb[1] & 0x01) { |
865 | pr_err("REQUEST_SENSE description emulation not" | 1053 | pr_err("REQUEST_SENSE description emulation not" |
866 | " supported\n"); | 1054 | " supported\n"); |
867 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 1055 | return TCM_INVALID_CDB_FIELD; |
868 | return -ENOSYS; | ||
869 | } | 1056 | } |
870 | 1057 | ||
871 | rbuf = transport_kmap_data_sg(cmd); | 1058 | rbuf = transport_kmap_data_sg(cmd); |
872 | if (cmd->scsi_sense_reason != 0) { | 1059 | if (!rbuf) |
873 | /* | 1060 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
874 | * Out of memory. We will fail with CHECK CONDITION, so | 1061 | |
875 | * we must not clear the unit attention condition. | 1062 | if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) { |
876 | */ | ||
877 | target_complete_cmd(cmd, CHECK_CONDITION); | ||
878 | return 0; | ||
879 | } else if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) { | ||
880 | /* | 1063 | /* |
881 | * CURRENT ERROR, UNIT ATTENTION | 1064 | * CURRENT ERROR, UNIT ATTENTION |
882 | */ | 1065 | */ |
@@ -903,33 +1086,97 @@ static int spc_emulate_request_sense(struct se_cmd *cmd) | |||
903 | buf[7] = 0x0A; | 1086 | buf[7] = 0x0A; |
904 | } | 1087 | } |
905 | 1088 | ||
906 | if (rbuf) { | 1089 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); |
907 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); | 1090 | transport_kunmap_data_sg(cmd); |
908 | transport_kunmap_data_sg(cmd); | 1091 | |
1092 | target_complete_cmd(cmd, GOOD); | ||
1093 | return 0; | ||
1094 | } | ||
1095 | |||
1096 | sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd) | ||
1097 | { | ||
1098 | struct se_dev_entry *deve; | ||
1099 | struct se_session *sess = cmd->se_sess; | ||
1100 | unsigned char *buf; | ||
1101 | u32 lun_count = 0, offset = 8, i; | ||
1102 | |||
1103 | if (cmd->data_length < 16) { | ||
1104 | pr_warn("REPORT LUNS allocation length %u too small\n", | ||
1105 | cmd->data_length); | ||
1106 | return TCM_INVALID_CDB_FIELD; | ||
1107 | } | ||
1108 | |||
1109 | buf = transport_kmap_data_sg(cmd); | ||
1110 | if (!buf) | ||
1111 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1112 | |||
1113 | /* | ||
1114 | * If no struct se_session pointer is present, this struct se_cmd is | ||
1115 | * coming via a target_core_mod PASSTHROUGH op, and not through | ||
1116 | * a $FABRIC_MOD. In that case, report LUN=0 only. | ||
1117 | */ | ||
1118 | if (!sess) { | ||
1119 | int_to_scsilun(0, (struct scsi_lun *)&buf[offset]); | ||
1120 | lun_count = 1; | ||
1121 | goto done; | ||
1122 | } | ||
1123 | |||
1124 | spin_lock_irq(&sess->se_node_acl->device_list_lock); | ||
1125 | for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { | ||
1126 | deve = sess->se_node_acl->device_list[i]; | ||
1127 | if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS)) | ||
1128 | continue; | ||
1129 | /* | ||
1130 | * We determine the correct LUN LIST LENGTH even once we | ||
1131 | * have reached the initial allocation length. | ||
1132 | * See SPC2-R20 7.19. | ||
1133 | */ | ||
1134 | lun_count++; | ||
1135 | if ((offset + 8) > cmd->data_length) | ||
1136 | continue; | ||
1137 | |||
1138 | int_to_scsilun(deve->mapped_lun, (struct scsi_lun *)&buf[offset]); | ||
1139 | offset += 8; | ||
909 | } | 1140 | } |
1141 | spin_unlock_irq(&sess->se_node_acl->device_list_lock); | ||
1142 | |||
1143 | /* | ||
1144 | * See SPC3 r07, page 159. | ||
1145 | */ | ||
1146 | done: | ||
1147 | lun_count *= 8; | ||
1148 | buf[0] = ((lun_count >> 24) & 0xff); | ||
1149 | buf[1] = ((lun_count >> 16) & 0xff); | ||
1150 | buf[2] = ((lun_count >> 8) & 0xff); | ||
1151 | buf[3] = (lun_count & 0xff); | ||
1152 | transport_kunmap_data_sg(cmd); | ||
910 | 1153 | ||
911 | target_complete_cmd(cmd, GOOD); | 1154 | target_complete_cmd(cmd, GOOD); |
912 | return 0; | 1155 | return 0; |
913 | } | 1156 | } |
1157 | EXPORT_SYMBOL(spc_emulate_report_luns); | ||
914 | 1158 | ||
915 | static int spc_emulate_testunitready(struct se_cmd *cmd) | 1159 | static sense_reason_t |
1160 | spc_emulate_testunitready(struct se_cmd *cmd) | ||
916 | { | 1161 | { |
917 | target_complete_cmd(cmd, GOOD); | 1162 | target_complete_cmd(cmd, GOOD); |
918 | return 0; | 1163 | return 0; |
919 | } | 1164 | } |
920 | 1165 | ||
921 | int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) | 1166 | sense_reason_t |
1167 | spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) | ||
922 | { | 1168 | { |
923 | struct se_device *dev = cmd->se_dev; | 1169 | struct se_device *dev = cmd->se_dev; |
924 | struct se_subsystem_dev *su_dev = dev->se_sub_dev; | ||
925 | unsigned char *cdb = cmd->t_task_cdb; | 1170 | unsigned char *cdb = cmd->t_task_cdb; |
926 | 1171 | ||
927 | switch (cdb[0]) { | 1172 | switch (cdb[0]) { |
928 | case MODE_SELECT: | 1173 | case MODE_SELECT: |
929 | *size = cdb[4]; | 1174 | *size = cdb[4]; |
1175 | cmd->execute_cmd = spc_emulate_modeselect; | ||
930 | break; | 1176 | break; |
931 | case MODE_SELECT_10: | 1177 | case MODE_SELECT_10: |
932 | *size = (cdb[7] << 8) + cdb[8]; | 1178 | *size = (cdb[7] << 8) + cdb[8]; |
1179 | cmd->execute_cmd = spc_emulate_modeselect; | ||
933 | break; | 1180 | break; |
934 | case MODE_SENSE: | 1181 | case MODE_SENSE: |
935 | *size = cdb[4]; | 1182 | *size = cdb[4]; |
@@ -944,14 +1191,12 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) | |||
944 | *size = (cdb[7] << 8) + cdb[8]; | 1191 | *size = (cdb[7] << 8) + cdb[8]; |
945 | break; | 1192 | break; |
946 | case PERSISTENT_RESERVE_IN: | 1193 | case PERSISTENT_RESERVE_IN: |
947 | if (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS) | ||
948 | cmd->execute_cmd = target_scsi3_emulate_pr_in; | ||
949 | *size = (cdb[7] << 8) + cdb[8]; | 1194 | *size = (cdb[7] << 8) + cdb[8]; |
1195 | cmd->execute_cmd = target_scsi3_emulate_pr_in; | ||
950 | break; | 1196 | break; |
951 | case PERSISTENT_RESERVE_OUT: | 1197 | case PERSISTENT_RESERVE_OUT: |
952 | if (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS) | ||
953 | cmd->execute_cmd = target_scsi3_emulate_pr_out; | ||
954 | *size = (cdb[7] << 8) + cdb[8]; | 1198 | *size = (cdb[7] << 8) + cdb[8]; |
1199 | cmd->execute_cmd = target_scsi3_emulate_pr_out; | ||
955 | break; | 1200 | break; |
956 | case RELEASE: | 1201 | case RELEASE: |
957 | case RELEASE_10: | 1202 | case RELEASE_10: |
@@ -960,8 +1205,7 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) | |||
960 | else | 1205 | else |
961 | *size = cmd->data_length; | 1206 | *size = cmd->data_length; |
962 | 1207 | ||
963 | if (su_dev->t10_pr.res_type != SPC_PASSTHROUGH) | 1208 | cmd->execute_cmd = target_scsi2_reservation_release; |
964 | cmd->execute_cmd = target_scsi2_reservation_release; | ||
965 | break; | 1209 | break; |
966 | case RESERVE: | 1210 | case RESERVE: |
967 | case RESERVE_10: | 1211 | case RESERVE_10: |
@@ -974,15 +1218,7 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) | |||
974 | else | 1218 | else |
975 | *size = cmd->data_length; | 1219 | *size = cmd->data_length; |
976 | 1220 | ||
977 | /* | 1221 | cmd->execute_cmd = target_scsi2_reservation_reserve; |
978 | * Setup the legacy emulated handler for SPC-2 and | ||
979 | * >= SPC-3 compatible reservation handling (CRH=1) | ||
980 | * Otherwise, we assume the underlying SCSI logic is | ||
981 | * is running in SPC_PASSTHROUGH, and wants reservations | ||
982 | * emulation disabled. | ||
983 | */ | ||
984 | if (su_dev->t10_pr.res_type != SPC_PASSTHROUGH) | ||
985 | cmd->execute_cmd = target_scsi2_reservation_reserve; | ||
986 | break; | 1222 | break; |
987 | case REQUEST_SENSE: | 1223 | case REQUEST_SENSE: |
988 | *size = cdb[4]; | 1224 | *size = cdb[4]; |
@@ -995,8 +1231,7 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) | |||
995 | * Do implict HEAD_OF_QUEUE processing for INQUIRY. | 1231 | * Do implict HEAD_OF_QUEUE processing for INQUIRY. |
996 | * See spc4r17 section 5.3 | 1232 | * See spc4r17 section 5.3 |
997 | */ | 1233 | */ |
998 | if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) | 1234 | cmd->sam_task_attr = MSG_HEAD_TAG; |
999 | cmd->sam_task_attr = MSG_HEAD_TAG; | ||
1000 | cmd->execute_cmd = spc_emulate_inquiry; | 1235 | cmd->execute_cmd = spc_emulate_inquiry; |
1001 | break; | 1236 | break; |
1002 | case SECURITY_PROTOCOL_IN: | 1237 | case SECURITY_PROTOCOL_IN: |
@@ -1018,14 +1253,13 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) | |||
1018 | *size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8]; | 1253 | *size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8]; |
1019 | break; | 1254 | break; |
1020 | case REPORT_LUNS: | 1255 | case REPORT_LUNS: |
1021 | cmd->execute_cmd = target_report_luns; | 1256 | cmd->execute_cmd = spc_emulate_report_luns; |
1022 | *size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; | 1257 | *size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; |
1023 | /* | 1258 | /* |
1024 | * Do implict HEAD_OF_QUEUE processing for REPORT_LUNS | 1259 | * Do implict HEAD_OF_QUEUE processing for REPORT_LUNS |
1025 | * See spc4r17 section 5.3 | 1260 | * See spc4r17 section 5.3 |
1026 | */ | 1261 | */ |
1027 | if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) | 1262 | cmd->sam_task_attr = MSG_HEAD_TAG; |
1028 | cmd->sam_task_attr = MSG_HEAD_TAG; | ||
1029 | break; | 1263 | break; |
1030 | case TEST_UNIT_READY: | 1264 | case TEST_UNIT_READY: |
1031 | cmd->execute_cmd = spc_emulate_testunitready; | 1265 | cmd->execute_cmd = spc_emulate_testunitready; |
@@ -1037,8 +1271,7 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) | |||
1037 | * MAINTENANCE_IN from SCC-2 | 1271 | * MAINTENANCE_IN from SCC-2 |
1038 | * Check for emulated MI_REPORT_TARGET_PGS | 1272 | * Check for emulated MI_REPORT_TARGET_PGS |
1039 | */ | 1273 | */ |
1040 | if ((cdb[1] & 0x1f) == MI_REPORT_TARGET_PGS && | 1274 | if ((cdb[1] & 0x1f) == MI_REPORT_TARGET_PGS) { |
1041 | su_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) { | ||
1042 | cmd->execute_cmd = | 1275 | cmd->execute_cmd = |
1043 | target_emulate_report_target_port_groups; | 1276 | target_emulate_report_target_port_groups; |
1044 | } | 1277 | } |
@@ -1056,8 +1289,7 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) | |||
1056 | * MAINTENANCE_OUT from SCC-2 | 1289 | * MAINTENANCE_OUT from SCC-2 |
1057 | * Check for emulated MO_SET_TARGET_PGS. | 1290 | * Check for emulated MO_SET_TARGET_PGS. |
1058 | */ | 1291 | */ |
1059 | if (cdb[1] == MO_SET_TARGET_PGS && | 1292 | if (cdb[1] == MO_SET_TARGET_PGS) { |
1060 | su_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) { | ||
1061 | cmd->execute_cmd = | 1293 | cmd->execute_cmd = |
1062 | target_emulate_set_target_port_groups; | 1294 | target_emulate_set_target_port_groups; |
1063 | } | 1295 | } |
@@ -1073,9 +1305,7 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) | |||
1073 | pr_warn("TARGET_CORE[%s]: Unsupported SCSI Opcode" | 1305 | pr_warn("TARGET_CORE[%s]: Unsupported SCSI Opcode" |
1074 | " 0x%02x, sending CHECK_CONDITION.\n", | 1306 | " 0x%02x, sending CHECK_CONDITION.\n", |
1075 | cmd->se_tfo->get_fabric_name(), cdb[0]); | 1307 | cmd->se_tfo->get_fabric_name(), cdb[0]); |
1076 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | 1308 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
1077 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | ||
1078 | return -EINVAL; | ||
1079 | } | 1309 | } |
1080 | 1310 | ||
1081 | return 0; | 1311 | return 0; |
diff --git a/drivers/target/target_core_stat.c b/drivers/target/target_core_stat.c index cb6b0036ae95..d154ce797180 100644 --- a/drivers/target/target_core_stat.c +++ b/drivers/target/target_core_stat.c | |||
@@ -1,13 +1,10 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | * Filename: target_core_stat.c | 2 | * Filename: target_core_stat.c |
3 | * | 3 | * |
4 | * Copyright (c) 2011 Rising Tide Systems | ||
5 | * Copyright (c) 2011 Linux-iSCSI.org | ||
6 | * | ||
7 | * Modern ConfigFS group context specific statistics based on original | 4 | * Modern ConfigFS group context specific statistics based on original |
8 | * target_core_mib.c code | 5 | * target_core_mib.c code |
9 | * | 6 | * |
10 | * Copyright (c) 2006-2007 SBE, Inc. All Rights Reserved. | 7 | * (c) Copyright 2006-2012 RisingTide Systems LLC. |
11 | * | 8 | * |
12 | * Nicholas A. Bellinger <nab@linux-iscsi.org> | 9 | * Nicholas A. Bellinger <nab@linux-iscsi.org> |
13 | * | 10 | * |
@@ -80,13 +77,9 @@ static struct target_stat_scsi_dev_attribute \ | |||
80 | static ssize_t target_stat_scsi_dev_show_attr_inst( | 77 | static ssize_t target_stat_scsi_dev_show_attr_inst( |
81 | struct se_dev_stat_grps *sgrps, char *page) | 78 | struct se_dev_stat_grps *sgrps, char *page) |
82 | { | 79 | { |
83 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 80 | struct se_device *dev = |
84 | struct se_subsystem_dev, dev_stat_grps); | 81 | container_of(sgrps, struct se_device, dev_stat_grps); |
85 | struct se_hba *hba = se_subdev->se_dev_hba; | 82 | struct se_hba *hba = dev->se_hba; |
86 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
87 | |||
88 | if (!dev) | ||
89 | return -ENODEV; | ||
90 | 83 | ||
91 | return snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index); | 84 | return snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index); |
92 | } | 85 | } |
@@ -95,12 +88,8 @@ DEV_STAT_SCSI_DEV_ATTR_RO(inst); | |||
95 | static ssize_t target_stat_scsi_dev_show_attr_indx( | 88 | static ssize_t target_stat_scsi_dev_show_attr_indx( |
96 | struct se_dev_stat_grps *sgrps, char *page) | 89 | struct se_dev_stat_grps *sgrps, char *page) |
97 | { | 90 | { |
98 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 91 | struct se_device *dev = |
99 | struct se_subsystem_dev, dev_stat_grps); | 92 | container_of(sgrps, struct se_device, dev_stat_grps); |
100 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
101 | |||
102 | if (!dev) | ||
103 | return -ENODEV; | ||
104 | 93 | ||
105 | return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index); | 94 | return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index); |
106 | } | 95 | } |
@@ -109,13 +98,6 @@ DEV_STAT_SCSI_DEV_ATTR_RO(indx); | |||
109 | static ssize_t target_stat_scsi_dev_show_attr_role( | 98 | static ssize_t target_stat_scsi_dev_show_attr_role( |
110 | struct se_dev_stat_grps *sgrps, char *page) | 99 | struct se_dev_stat_grps *sgrps, char *page) |
111 | { | 100 | { |
112 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | ||
113 | struct se_subsystem_dev, dev_stat_grps); | ||
114 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
115 | |||
116 | if (!dev) | ||
117 | return -ENODEV; | ||
118 | |||
119 | return snprintf(page, PAGE_SIZE, "Target\n"); | 101 | return snprintf(page, PAGE_SIZE, "Target\n"); |
120 | } | 102 | } |
121 | DEV_STAT_SCSI_DEV_ATTR_RO(role); | 103 | DEV_STAT_SCSI_DEV_ATTR_RO(role); |
@@ -123,12 +105,8 @@ DEV_STAT_SCSI_DEV_ATTR_RO(role); | |||
123 | static ssize_t target_stat_scsi_dev_show_attr_ports( | 105 | static ssize_t target_stat_scsi_dev_show_attr_ports( |
124 | struct se_dev_stat_grps *sgrps, char *page) | 106 | struct se_dev_stat_grps *sgrps, char *page) |
125 | { | 107 | { |
126 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 108 | struct se_device *dev = |
127 | struct se_subsystem_dev, dev_stat_grps); | 109 | container_of(sgrps, struct se_device, dev_stat_grps); |
128 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
129 | |||
130 | if (!dev) | ||
131 | return -ENODEV; | ||
132 | 110 | ||
133 | return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_port_count); | 111 | return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_port_count); |
134 | } | 112 | } |
@@ -176,13 +154,9 @@ static struct target_stat_scsi_tgt_dev_attribute \ | |||
176 | static ssize_t target_stat_scsi_tgt_dev_show_attr_inst( | 154 | static ssize_t target_stat_scsi_tgt_dev_show_attr_inst( |
177 | struct se_dev_stat_grps *sgrps, char *page) | 155 | struct se_dev_stat_grps *sgrps, char *page) |
178 | { | 156 | { |
179 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 157 | struct se_device *dev = |
180 | struct se_subsystem_dev, dev_stat_grps); | 158 | container_of(sgrps, struct se_device, dev_stat_grps); |
181 | struct se_hba *hba = se_subdev->se_dev_hba; | 159 | struct se_hba *hba = dev->se_hba; |
182 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
183 | |||
184 | if (!dev) | ||
185 | return -ENODEV; | ||
186 | 160 | ||
187 | return snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index); | 161 | return snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index); |
188 | } | 162 | } |
@@ -191,12 +165,8 @@ DEV_STAT_SCSI_TGT_DEV_ATTR_RO(inst); | |||
191 | static ssize_t target_stat_scsi_tgt_dev_show_attr_indx( | 165 | static ssize_t target_stat_scsi_tgt_dev_show_attr_indx( |
192 | struct se_dev_stat_grps *sgrps, char *page) | 166 | struct se_dev_stat_grps *sgrps, char *page) |
193 | { | 167 | { |
194 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 168 | struct se_device *dev = |
195 | struct se_subsystem_dev, dev_stat_grps); | 169 | container_of(sgrps, struct se_device, dev_stat_grps); |
196 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
197 | |||
198 | if (!dev) | ||
199 | return -ENODEV; | ||
200 | 170 | ||
201 | return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index); | 171 | return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index); |
202 | } | 172 | } |
@@ -205,13 +175,6 @@ DEV_STAT_SCSI_TGT_DEV_ATTR_RO(indx); | |||
205 | static ssize_t target_stat_scsi_tgt_dev_show_attr_num_lus( | 175 | static ssize_t target_stat_scsi_tgt_dev_show_attr_num_lus( |
206 | struct se_dev_stat_grps *sgrps, char *page) | 176 | struct se_dev_stat_grps *sgrps, char *page) |
207 | { | 177 | { |
208 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | ||
209 | struct se_subsystem_dev, dev_stat_grps); | ||
210 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
211 | |||
212 | if (!dev) | ||
213 | return -ENODEV; | ||
214 | |||
215 | return snprintf(page, PAGE_SIZE, "%u\n", LU_COUNT); | 178 | return snprintf(page, PAGE_SIZE, "%u\n", LU_COUNT); |
216 | } | 179 | } |
217 | DEV_STAT_SCSI_TGT_DEV_ATTR_RO(num_lus); | 180 | DEV_STAT_SCSI_TGT_DEV_ATTR_RO(num_lus); |
@@ -219,60 +182,27 @@ DEV_STAT_SCSI_TGT_DEV_ATTR_RO(num_lus); | |||
219 | static ssize_t target_stat_scsi_tgt_dev_show_attr_status( | 182 | static ssize_t target_stat_scsi_tgt_dev_show_attr_status( |
220 | struct se_dev_stat_grps *sgrps, char *page) | 183 | struct se_dev_stat_grps *sgrps, char *page) |
221 | { | 184 | { |
222 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 185 | struct se_device *dev = |
223 | struct se_subsystem_dev, dev_stat_grps); | 186 | container_of(sgrps, struct se_device, dev_stat_grps); |
224 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
225 | char status[16]; | ||
226 | 187 | ||
227 | if (!dev) | 188 | if (dev->export_count) |
228 | return -ENODEV; | 189 | return snprintf(page, PAGE_SIZE, "activated"); |
229 | 190 | else | |
230 | switch (dev->dev_status) { | 191 | return snprintf(page, PAGE_SIZE, "deactivated"); |
231 | case TRANSPORT_DEVICE_ACTIVATED: | ||
232 | strcpy(status, "activated"); | ||
233 | break; | ||
234 | case TRANSPORT_DEVICE_DEACTIVATED: | ||
235 | strcpy(status, "deactivated"); | ||
236 | break; | ||
237 | case TRANSPORT_DEVICE_SHUTDOWN: | ||
238 | strcpy(status, "shutdown"); | ||
239 | break; | ||
240 | case TRANSPORT_DEVICE_OFFLINE_ACTIVATED: | ||
241 | case TRANSPORT_DEVICE_OFFLINE_DEACTIVATED: | ||
242 | strcpy(status, "offline"); | ||
243 | break; | ||
244 | default: | ||
245 | sprintf(status, "unknown(%d)", dev->dev_status); | ||
246 | break; | ||
247 | } | ||
248 | |||
249 | return snprintf(page, PAGE_SIZE, "%s\n", status); | ||
250 | } | 192 | } |
251 | DEV_STAT_SCSI_TGT_DEV_ATTR_RO(status); | 193 | DEV_STAT_SCSI_TGT_DEV_ATTR_RO(status); |
252 | 194 | ||
253 | static ssize_t target_stat_scsi_tgt_dev_show_attr_non_access_lus( | 195 | static ssize_t target_stat_scsi_tgt_dev_show_attr_non_access_lus( |
254 | struct se_dev_stat_grps *sgrps, char *page) | 196 | struct se_dev_stat_grps *sgrps, char *page) |
255 | { | 197 | { |
256 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 198 | struct se_device *dev = |
257 | struct se_subsystem_dev, dev_stat_grps); | 199 | container_of(sgrps, struct se_device, dev_stat_grps); |
258 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
259 | int non_accessible_lus; | 200 | int non_accessible_lus; |
260 | 201 | ||
261 | if (!dev) | 202 | if (dev->export_count) |
262 | return -ENODEV; | ||
263 | |||
264 | switch (dev->dev_status) { | ||
265 | case TRANSPORT_DEVICE_ACTIVATED: | ||
266 | non_accessible_lus = 0; | 203 | non_accessible_lus = 0; |
267 | break; | 204 | else |
268 | case TRANSPORT_DEVICE_DEACTIVATED: | ||
269 | case TRANSPORT_DEVICE_SHUTDOWN: | ||
270 | case TRANSPORT_DEVICE_OFFLINE_ACTIVATED: | ||
271 | case TRANSPORT_DEVICE_OFFLINE_DEACTIVATED: | ||
272 | default: | ||
273 | non_accessible_lus = 1; | 205 | non_accessible_lus = 1; |
274 | break; | ||
275 | } | ||
276 | 206 | ||
277 | return snprintf(page, PAGE_SIZE, "%u\n", non_accessible_lus); | 207 | return snprintf(page, PAGE_SIZE, "%u\n", non_accessible_lus); |
278 | } | 208 | } |
@@ -281,12 +211,8 @@ DEV_STAT_SCSI_TGT_DEV_ATTR_RO(non_access_lus); | |||
281 | static ssize_t target_stat_scsi_tgt_dev_show_attr_resets( | 211 | static ssize_t target_stat_scsi_tgt_dev_show_attr_resets( |
282 | struct se_dev_stat_grps *sgrps, char *page) | 212 | struct se_dev_stat_grps *sgrps, char *page) |
283 | { | 213 | { |
284 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 214 | struct se_device *dev = |
285 | struct se_subsystem_dev, dev_stat_grps); | 215 | container_of(sgrps, struct se_device, dev_stat_grps); |
286 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
287 | |||
288 | if (!dev) | ||
289 | return -ENODEV; | ||
290 | 216 | ||
291 | return snprintf(page, PAGE_SIZE, "%u\n", dev->num_resets); | 217 | return snprintf(page, PAGE_SIZE, "%u\n", dev->num_resets); |
292 | } | 218 | } |
@@ -335,13 +261,9 @@ static struct target_stat_scsi_lu_attribute target_stat_scsi_lu_##_name = \ | |||
335 | static ssize_t target_stat_scsi_lu_show_attr_inst( | 261 | static ssize_t target_stat_scsi_lu_show_attr_inst( |
336 | struct se_dev_stat_grps *sgrps, char *page) | 262 | struct se_dev_stat_grps *sgrps, char *page) |
337 | { | 263 | { |
338 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 264 | struct se_device *dev = |
339 | struct se_subsystem_dev, dev_stat_grps); | 265 | container_of(sgrps, struct se_device, dev_stat_grps); |
340 | struct se_hba *hba = se_subdev->se_dev_hba; | 266 | struct se_hba *hba = dev->se_hba; |
341 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
342 | |||
343 | if (!dev) | ||
344 | return -ENODEV; | ||
345 | 267 | ||
346 | return snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index); | 268 | return snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index); |
347 | } | 269 | } |
@@ -350,12 +272,8 @@ DEV_STAT_SCSI_LU_ATTR_RO(inst); | |||
350 | static ssize_t target_stat_scsi_lu_show_attr_dev( | 272 | static ssize_t target_stat_scsi_lu_show_attr_dev( |
351 | struct se_dev_stat_grps *sgrps, char *page) | 273 | struct se_dev_stat_grps *sgrps, char *page) |
352 | { | 274 | { |
353 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 275 | struct se_device *dev = |
354 | struct se_subsystem_dev, dev_stat_grps); | 276 | container_of(sgrps, struct se_device, dev_stat_grps); |
355 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
356 | |||
357 | if (!dev) | ||
358 | return -ENODEV; | ||
359 | 277 | ||
360 | return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index); | 278 | return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index); |
361 | } | 279 | } |
@@ -364,13 +282,6 @@ DEV_STAT_SCSI_LU_ATTR_RO(dev); | |||
364 | static ssize_t target_stat_scsi_lu_show_attr_indx( | 282 | static ssize_t target_stat_scsi_lu_show_attr_indx( |
365 | struct se_dev_stat_grps *sgrps, char *page) | 283 | struct se_dev_stat_grps *sgrps, char *page) |
366 | { | 284 | { |
367 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | ||
368 | struct se_subsystem_dev, dev_stat_grps); | ||
369 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
370 | |||
371 | if (!dev) | ||
372 | return -ENODEV; | ||
373 | |||
374 | return snprintf(page, PAGE_SIZE, "%u\n", SCSI_LU_INDEX); | 285 | return snprintf(page, PAGE_SIZE, "%u\n", SCSI_LU_INDEX); |
375 | } | 286 | } |
376 | DEV_STAT_SCSI_LU_ATTR_RO(indx); | 287 | DEV_STAT_SCSI_LU_ATTR_RO(indx); |
@@ -378,12 +289,6 @@ DEV_STAT_SCSI_LU_ATTR_RO(indx); | |||
378 | static ssize_t target_stat_scsi_lu_show_attr_lun( | 289 | static ssize_t target_stat_scsi_lu_show_attr_lun( |
379 | struct se_dev_stat_grps *sgrps, char *page) | 290 | struct se_dev_stat_grps *sgrps, char *page) |
380 | { | 291 | { |
381 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | ||
382 | struct se_subsystem_dev, dev_stat_grps); | ||
383 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
384 | |||
385 | if (!dev) | ||
386 | return -ENODEV; | ||
387 | /* FIXME: scsiLuDefaultLun */ | 292 | /* FIXME: scsiLuDefaultLun */ |
388 | return snprintf(page, PAGE_SIZE, "%llu\n", (unsigned long long)0); | 293 | return snprintf(page, PAGE_SIZE, "%llu\n", (unsigned long long)0); |
389 | } | 294 | } |
@@ -392,35 +297,28 @@ DEV_STAT_SCSI_LU_ATTR_RO(lun); | |||
392 | static ssize_t target_stat_scsi_lu_show_attr_lu_name( | 297 | static ssize_t target_stat_scsi_lu_show_attr_lu_name( |
393 | struct se_dev_stat_grps *sgrps, char *page) | 298 | struct se_dev_stat_grps *sgrps, char *page) |
394 | { | 299 | { |
395 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 300 | struct se_device *dev = |
396 | struct se_subsystem_dev, dev_stat_grps); | 301 | container_of(sgrps, struct se_device, dev_stat_grps); |
397 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
398 | 302 | ||
399 | if (!dev) | ||
400 | return -ENODEV; | ||
401 | /* scsiLuWwnName */ | 303 | /* scsiLuWwnName */ |
402 | return snprintf(page, PAGE_SIZE, "%s\n", | 304 | return snprintf(page, PAGE_SIZE, "%s\n", |
403 | (strlen(dev->se_sub_dev->t10_wwn.unit_serial)) ? | 305 | (strlen(dev->t10_wwn.unit_serial)) ? |
404 | dev->se_sub_dev->t10_wwn.unit_serial : "None"); | 306 | dev->t10_wwn.unit_serial : "None"); |
405 | } | 307 | } |
406 | DEV_STAT_SCSI_LU_ATTR_RO(lu_name); | 308 | DEV_STAT_SCSI_LU_ATTR_RO(lu_name); |
407 | 309 | ||
408 | static ssize_t target_stat_scsi_lu_show_attr_vend( | 310 | static ssize_t target_stat_scsi_lu_show_attr_vend( |
409 | struct se_dev_stat_grps *sgrps, char *page) | 311 | struct se_dev_stat_grps *sgrps, char *page) |
410 | { | 312 | { |
411 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 313 | struct se_device *dev = |
412 | struct se_subsystem_dev, dev_stat_grps); | 314 | container_of(sgrps, struct se_device, dev_stat_grps); |
413 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
414 | int i; | 315 | int i; |
415 | char str[sizeof(dev->se_sub_dev->t10_wwn.vendor)+1]; | 316 | char str[sizeof(dev->t10_wwn.vendor)+1]; |
416 | |||
417 | if (!dev) | ||
418 | return -ENODEV; | ||
419 | 317 | ||
420 | /* scsiLuVendorId */ | 318 | /* scsiLuVendorId */ |
421 | for (i = 0; i < sizeof(dev->se_sub_dev->t10_wwn.vendor); i++) | 319 | for (i = 0; i < sizeof(dev->t10_wwn.vendor); i++) |
422 | str[i] = ISPRINT(dev->se_sub_dev->t10_wwn.vendor[i]) ? | 320 | str[i] = ISPRINT(dev->t10_wwn.vendor[i]) ? |
423 | dev->se_sub_dev->t10_wwn.vendor[i] : ' '; | 321 | dev->t10_wwn.vendor[i] : ' '; |
424 | str[i] = '\0'; | 322 | str[i] = '\0'; |
425 | return snprintf(page, PAGE_SIZE, "%s\n", str); | 323 | return snprintf(page, PAGE_SIZE, "%s\n", str); |
426 | } | 324 | } |
@@ -429,19 +327,15 @@ DEV_STAT_SCSI_LU_ATTR_RO(vend); | |||
429 | static ssize_t target_stat_scsi_lu_show_attr_prod( | 327 | static ssize_t target_stat_scsi_lu_show_attr_prod( |
430 | struct se_dev_stat_grps *sgrps, char *page) | 328 | struct se_dev_stat_grps *sgrps, char *page) |
431 | { | 329 | { |
432 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 330 | struct se_device *dev = |
433 | struct se_subsystem_dev, dev_stat_grps); | 331 | container_of(sgrps, struct se_device, dev_stat_grps); |
434 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
435 | int i; | 332 | int i; |
436 | char str[sizeof(dev->se_sub_dev->t10_wwn.model)+1]; | 333 | char str[sizeof(dev->t10_wwn.model)+1]; |
437 | |||
438 | if (!dev) | ||
439 | return -ENODEV; | ||
440 | 334 | ||
441 | /* scsiLuProductId */ | 335 | /* scsiLuProductId */ |
442 | for (i = 0; i < sizeof(dev->se_sub_dev->t10_wwn.vendor); i++) | 336 | for (i = 0; i < sizeof(dev->t10_wwn.vendor); i++) |
443 | str[i] = ISPRINT(dev->se_sub_dev->t10_wwn.model[i]) ? | 337 | str[i] = ISPRINT(dev->t10_wwn.model[i]) ? |
444 | dev->se_sub_dev->t10_wwn.model[i] : ' '; | 338 | dev->t10_wwn.model[i] : ' '; |
445 | str[i] = '\0'; | 339 | str[i] = '\0'; |
446 | return snprintf(page, PAGE_SIZE, "%s\n", str); | 340 | return snprintf(page, PAGE_SIZE, "%s\n", str); |
447 | } | 341 | } |
@@ -450,19 +344,15 @@ DEV_STAT_SCSI_LU_ATTR_RO(prod); | |||
450 | static ssize_t target_stat_scsi_lu_show_attr_rev( | 344 | static ssize_t target_stat_scsi_lu_show_attr_rev( |
451 | struct se_dev_stat_grps *sgrps, char *page) | 345 | struct se_dev_stat_grps *sgrps, char *page) |
452 | { | 346 | { |
453 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 347 | struct se_device *dev = |
454 | struct se_subsystem_dev, dev_stat_grps); | 348 | container_of(sgrps, struct se_device, dev_stat_grps); |
455 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
456 | int i; | 349 | int i; |
457 | char str[sizeof(dev->se_sub_dev->t10_wwn.revision)+1]; | 350 | char str[sizeof(dev->t10_wwn.revision)+1]; |
458 | |||
459 | if (!dev) | ||
460 | return -ENODEV; | ||
461 | 351 | ||
462 | /* scsiLuRevisionId */ | 352 | /* scsiLuRevisionId */ |
463 | for (i = 0; i < sizeof(dev->se_sub_dev->t10_wwn.revision); i++) | 353 | for (i = 0; i < sizeof(dev->t10_wwn.revision); i++) |
464 | str[i] = ISPRINT(dev->se_sub_dev->t10_wwn.revision[i]) ? | 354 | str[i] = ISPRINT(dev->t10_wwn.revision[i]) ? |
465 | dev->se_sub_dev->t10_wwn.revision[i] : ' '; | 355 | dev->t10_wwn.revision[i] : ' '; |
466 | str[i] = '\0'; | 356 | str[i] = '\0'; |
467 | return snprintf(page, PAGE_SIZE, "%s\n", str); | 357 | return snprintf(page, PAGE_SIZE, "%s\n", str); |
468 | } | 358 | } |
@@ -471,12 +361,8 @@ DEV_STAT_SCSI_LU_ATTR_RO(rev); | |||
471 | static ssize_t target_stat_scsi_lu_show_attr_dev_type( | 361 | static ssize_t target_stat_scsi_lu_show_attr_dev_type( |
472 | struct se_dev_stat_grps *sgrps, char *page) | 362 | struct se_dev_stat_grps *sgrps, char *page) |
473 | { | 363 | { |
474 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 364 | struct se_device *dev = |
475 | struct se_subsystem_dev, dev_stat_grps); | 365 | container_of(sgrps, struct se_device, dev_stat_grps); |
476 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
477 | |||
478 | if (!dev) | ||
479 | return -ENODEV; | ||
480 | 366 | ||
481 | /* scsiLuPeripheralType */ | 367 | /* scsiLuPeripheralType */ |
482 | return snprintf(page, PAGE_SIZE, "%u\n", | 368 | return snprintf(page, PAGE_SIZE, "%u\n", |
@@ -487,30 +373,18 @@ DEV_STAT_SCSI_LU_ATTR_RO(dev_type); | |||
487 | static ssize_t target_stat_scsi_lu_show_attr_status( | 373 | static ssize_t target_stat_scsi_lu_show_attr_status( |
488 | struct se_dev_stat_grps *sgrps, char *page) | 374 | struct se_dev_stat_grps *sgrps, char *page) |
489 | { | 375 | { |
490 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 376 | struct se_device *dev = |
491 | struct se_subsystem_dev, dev_stat_grps); | 377 | container_of(sgrps, struct se_device, dev_stat_grps); |
492 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
493 | |||
494 | if (!dev) | ||
495 | return -ENODEV; | ||
496 | 378 | ||
497 | /* scsiLuStatus */ | 379 | /* scsiLuStatus */ |
498 | return snprintf(page, PAGE_SIZE, "%s\n", | 380 | return snprintf(page, PAGE_SIZE, "%s\n", |
499 | (dev->dev_status == TRANSPORT_DEVICE_ACTIVATED) ? | 381 | (dev->export_count) ? "available" : "notavailable"); |
500 | "available" : "notavailable"); | ||
501 | } | 382 | } |
502 | DEV_STAT_SCSI_LU_ATTR_RO(status); | 383 | DEV_STAT_SCSI_LU_ATTR_RO(status); |
503 | 384 | ||
504 | static ssize_t target_stat_scsi_lu_show_attr_state_bit( | 385 | static ssize_t target_stat_scsi_lu_show_attr_state_bit( |
505 | struct se_dev_stat_grps *sgrps, char *page) | 386 | struct se_dev_stat_grps *sgrps, char *page) |
506 | { | 387 | { |
507 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | ||
508 | struct se_subsystem_dev, dev_stat_grps); | ||
509 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
510 | |||
511 | if (!dev) | ||
512 | return -ENODEV; | ||
513 | |||
514 | /* scsiLuState */ | 388 | /* scsiLuState */ |
515 | return snprintf(page, PAGE_SIZE, "exposed\n"); | 389 | return snprintf(page, PAGE_SIZE, "exposed\n"); |
516 | } | 390 | } |
@@ -519,12 +393,8 @@ DEV_STAT_SCSI_LU_ATTR_RO(state_bit); | |||
519 | static ssize_t target_stat_scsi_lu_show_attr_num_cmds( | 393 | static ssize_t target_stat_scsi_lu_show_attr_num_cmds( |
520 | struct se_dev_stat_grps *sgrps, char *page) | 394 | struct se_dev_stat_grps *sgrps, char *page) |
521 | { | 395 | { |
522 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 396 | struct se_device *dev = |
523 | struct se_subsystem_dev, dev_stat_grps); | 397 | container_of(sgrps, struct se_device, dev_stat_grps); |
524 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
525 | |||
526 | if (!dev) | ||
527 | return -ENODEV; | ||
528 | 398 | ||
529 | /* scsiLuNumCommands */ | 399 | /* scsiLuNumCommands */ |
530 | return snprintf(page, PAGE_SIZE, "%llu\n", | 400 | return snprintf(page, PAGE_SIZE, "%llu\n", |
@@ -535,12 +405,8 @@ DEV_STAT_SCSI_LU_ATTR_RO(num_cmds); | |||
535 | static ssize_t target_stat_scsi_lu_show_attr_read_mbytes( | 405 | static ssize_t target_stat_scsi_lu_show_attr_read_mbytes( |
536 | struct se_dev_stat_grps *sgrps, char *page) | 406 | struct se_dev_stat_grps *sgrps, char *page) |
537 | { | 407 | { |
538 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 408 | struct se_device *dev = |
539 | struct se_subsystem_dev, dev_stat_grps); | 409 | container_of(sgrps, struct se_device, dev_stat_grps); |
540 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
541 | |||
542 | if (!dev) | ||
543 | return -ENODEV; | ||
544 | 410 | ||
545 | /* scsiLuReadMegaBytes */ | 411 | /* scsiLuReadMegaBytes */ |
546 | return snprintf(page, PAGE_SIZE, "%u\n", (u32)(dev->read_bytes >> 20)); | 412 | return snprintf(page, PAGE_SIZE, "%u\n", (u32)(dev->read_bytes >> 20)); |
@@ -550,12 +416,8 @@ DEV_STAT_SCSI_LU_ATTR_RO(read_mbytes); | |||
550 | static ssize_t target_stat_scsi_lu_show_attr_write_mbytes( | 416 | static ssize_t target_stat_scsi_lu_show_attr_write_mbytes( |
551 | struct se_dev_stat_grps *sgrps, char *page) | 417 | struct se_dev_stat_grps *sgrps, char *page) |
552 | { | 418 | { |
553 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 419 | struct se_device *dev = |
554 | struct se_subsystem_dev, dev_stat_grps); | 420 | container_of(sgrps, struct se_device, dev_stat_grps); |
555 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
556 | |||
557 | if (!dev) | ||
558 | return -ENODEV; | ||
559 | 421 | ||
560 | /* scsiLuWrittenMegaBytes */ | 422 | /* scsiLuWrittenMegaBytes */ |
561 | return snprintf(page, PAGE_SIZE, "%u\n", (u32)(dev->write_bytes >> 20)); | 423 | return snprintf(page, PAGE_SIZE, "%u\n", (u32)(dev->write_bytes >> 20)); |
@@ -565,12 +427,8 @@ DEV_STAT_SCSI_LU_ATTR_RO(write_mbytes); | |||
565 | static ssize_t target_stat_scsi_lu_show_attr_resets( | 427 | static ssize_t target_stat_scsi_lu_show_attr_resets( |
566 | struct se_dev_stat_grps *sgrps, char *page) | 428 | struct se_dev_stat_grps *sgrps, char *page) |
567 | { | 429 | { |
568 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 430 | struct se_device *dev = |
569 | struct se_subsystem_dev, dev_stat_grps); | 431 | container_of(sgrps, struct se_device, dev_stat_grps); |
570 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
571 | |||
572 | if (!dev) | ||
573 | return -ENODEV; | ||
574 | 432 | ||
575 | /* scsiLuInResets */ | 433 | /* scsiLuInResets */ |
576 | return snprintf(page, PAGE_SIZE, "%u\n", dev->num_resets); | 434 | return snprintf(page, PAGE_SIZE, "%u\n", dev->num_resets); |
@@ -580,13 +438,6 @@ DEV_STAT_SCSI_LU_ATTR_RO(resets); | |||
580 | static ssize_t target_stat_scsi_lu_show_attr_full_stat( | 438 | static ssize_t target_stat_scsi_lu_show_attr_full_stat( |
581 | struct se_dev_stat_grps *sgrps, char *page) | 439 | struct se_dev_stat_grps *sgrps, char *page) |
582 | { | 440 | { |
583 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | ||
584 | struct se_subsystem_dev, dev_stat_grps); | ||
585 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
586 | |||
587 | if (!dev) | ||
588 | return -ENODEV; | ||
589 | |||
590 | /* FIXME: scsiLuOutTaskSetFullStatus */ | 441 | /* FIXME: scsiLuOutTaskSetFullStatus */ |
591 | return snprintf(page, PAGE_SIZE, "%u\n", 0); | 442 | return snprintf(page, PAGE_SIZE, "%u\n", 0); |
592 | } | 443 | } |
@@ -595,13 +446,6 @@ DEV_STAT_SCSI_LU_ATTR_RO(full_stat); | |||
595 | static ssize_t target_stat_scsi_lu_show_attr_hs_num_cmds( | 446 | static ssize_t target_stat_scsi_lu_show_attr_hs_num_cmds( |
596 | struct se_dev_stat_grps *sgrps, char *page) | 447 | struct se_dev_stat_grps *sgrps, char *page) |
597 | { | 448 | { |
598 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | ||
599 | struct se_subsystem_dev, dev_stat_grps); | ||
600 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
601 | |||
602 | if (!dev) | ||
603 | return -ENODEV; | ||
604 | |||
605 | /* FIXME: scsiLuHSInCommands */ | 449 | /* FIXME: scsiLuHSInCommands */ |
606 | return snprintf(page, PAGE_SIZE, "%u\n", 0); | 450 | return snprintf(page, PAGE_SIZE, "%u\n", 0); |
607 | } | 451 | } |
@@ -610,12 +454,8 @@ DEV_STAT_SCSI_LU_ATTR_RO(hs_num_cmds); | |||
610 | static ssize_t target_stat_scsi_lu_show_attr_creation_time( | 454 | static ssize_t target_stat_scsi_lu_show_attr_creation_time( |
611 | struct se_dev_stat_grps *sgrps, char *page) | 455 | struct se_dev_stat_grps *sgrps, char *page) |
612 | { | 456 | { |
613 | struct se_subsystem_dev *se_subdev = container_of(sgrps, | 457 | struct se_device *dev = |
614 | struct se_subsystem_dev, dev_stat_grps); | 458 | container_of(sgrps, struct se_device, dev_stat_grps); |
615 | struct se_device *dev = se_subdev->se_dev_ptr; | ||
616 | |||
617 | if (!dev) | ||
618 | return -ENODEV; | ||
619 | 459 | ||
620 | /* scsiLuCreationTime */ | 460 | /* scsiLuCreationTime */ |
621 | return snprintf(page, PAGE_SIZE, "%u\n", (u32)(((u32)dev->creation_time - | 461 | return snprintf(page, PAGE_SIZE, "%u\n", (u32)(((u32)dev->creation_time - |
@@ -662,20 +502,20 @@ static struct config_item_type target_stat_scsi_lu_cit = { | |||
662 | * Called from target_core_configfs.c:target_core_make_subdev() to setup | 502 | * Called from target_core_configfs.c:target_core_make_subdev() to setup |
663 | * the target statistics groups + configfs CITs located in target_core_stat.c | 503 | * the target statistics groups + configfs CITs located in target_core_stat.c |
664 | */ | 504 | */ |
665 | void target_stat_setup_dev_default_groups(struct se_subsystem_dev *se_subdev) | 505 | void target_stat_setup_dev_default_groups(struct se_device *dev) |
666 | { | 506 | { |
667 | struct config_group *dev_stat_grp = &se_subdev->dev_stat_grps.stat_group; | 507 | struct config_group *dev_stat_grp = &dev->dev_stat_grps.stat_group; |
668 | 508 | ||
669 | config_group_init_type_name(&se_subdev->dev_stat_grps.scsi_dev_group, | 509 | config_group_init_type_name(&dev->dev_stat_grps.scsi_dev_group, |
670 | "scsi_dev", &target_stat_scsi_dev_cit); | 510 | "scsi_dev", &target_stat_scsi_dev_cit); |
671 | config_group_init_type_name(&se_subdev->dev_stat_grps.scsi_tgt_dev_group, | 511 | config_group_init_type_name(&dev->dev_stat_grps.scsi_tgt_dev_group, |
672 | "scsi_tgt_dev", &target_stat_scsi_tgt_dev_cit); | 512 | "scsi_tgt_dev", &target_stat_scsi_tgt_dev_cit); |
673 | config_group_init_type_name(&se_subdev->dev_stat_grps.scsi_lu_group, | 513 | config_group_init_type_name(&dev->dev_stat_grps.scsi_lu_group, |
674 | "scsi_lu", &target_stat_scsi_lu_cit); | 514 | "scsi_lu", &target_stat_scsi_lu_cit); |
675 | 515 | ||
676 | dev_stat_grp->default_groups[0] = &se_subdev->dev_stat_grps.scsi_dev_group; | 516 | dev_stat_grp->default_groups[0] = &dev->dev_stat_grps.scsi_dev_group; |
677 | dev_stat_grp->default_groups[1] = &se_subdev->dev_stat_grps.scsi_tgt_dev_group; | 517 | dev_stat_grp->default_groups[1] = &dev->dev_stat_grps.scsi_tgt_dev_group; |
678 | dev_stat_grp->default_groups[2] = &se_subdev->dev_stat_grps.scsi_lu_group; | 518 | dev_stat_grp->default_groups[2] = &dev->dev_stat_grps.scsi_lu_group; |
679 | dev_stat_grp->default_groups[3] = NULL; | 519 | dev_stat_grp->default_groups[3] = NULL; |
680 | } | 520 | } |
681 | 521 | ||
@@ -1161,7 +1001,7 @@ static ssize_t target_stat_scsi_transport_show_attr_dev_name( | |||
1161 | return -ENODEV; | 1001 | return -ENODEV; |
1162 | } | 1002 | } |
1163 | tpg = sep->sep_tpg; | 1003 | tpg = sep->sep_tpg; |
1164 | wwn = &dev->se_sub_dev->t10_wwn; | 1004 | wwn = &dev->t10_wwn; |
1165 | /* scsiTransportDevName */ | 1005 | /* scsiTransportDevName */ |
1166 | ret = snprintf(page, PAGE_SIZE, "%s+%s\n", | 1006 | ret = snprintf(page, PAGE_SIZE, "%s+%s\n", |
1167 | tpg->se_tpg_tfo->tpg_get_wwn(tpg), | 1007 | tpg->se_tpg_tfo->tpg_get_wwn(tpg), |
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index 1c59a3c23b2c..c6e0293ffdb0 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c | |||
@@ -3,8 +3,7 @@ | |||
3 | * | 3 | * |
4 | * This file contains SPC-3 task management infrastructure | 4 | * This file contains SPC-3 task management infrastructure |
5 | * | 5 | * |
6 | * Copyright (c) 2009,2010 Rising Tide Systems | 6 | * (c) Copyright 2009-2012 RisingTide Systems LLC. |
7 | * Copyright (c) 2009,2010 Linux-iSCSI.org | ||
8 | * | 7 | * |
9 | * Nicholas A. Bellinger <nab@kernel.org> | 8 | * Nicholas A. Bellinger <nab@kernel.org> |
10 | * | 9 | * |
@@ -140,15 +139,15 @@ void core_tmr_abort_task( | |||
140 | printk("ABORT_TASK: Found referenced %s task_tag: %u\n", | 139 | printk("ABORT_TASK: Found referenced %s task_tag: %u\n", |
141 | se_cmd->se_tfo->get_fabric_name(), ref_tag); | 140 | se_cmd->se_tfo->get_fabric_name(), ref_tag); |
142 | 141 | ||
143 | spin_lock_irq(&se_cmd->t_state_lock); | 142 | spin_lock(&se_cmd->t_state_lock); |
144 | if (se_cmd->transport_state & CMD_T_COMPLETE) { | 143 | if (se_cmd->transport_state & CMD_T_COMPLETE) { |
145 | printk("ABORT_TASK: ref_tag: %u already complete, skipping\n", ref_tag); | 144 | printk("ABORT_TASK: ref_tag: %u already complete, skipping\n", ref_tag); |
146 | spin_unlock_irq(&se_cmd->t_state_lock); | 145 | spin_unlock(&se_cmd->t_state_lock); |
147 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); | 146 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); |
148 | goto out; | 147 | goto out; |
149 | } | 148 | } |
150 | se_cmd->transport_state |= CMD_T_ABORTED; | 149 | se_cmd->transport_state |= CMD_T_ABORTED; |
151 | spin_unlock_irq(&se_cmd->t_state_lock); | 150 | spin_unlock(&se_cmd->t_state_lock); |
152 | 151 | ||
153 | list_del_init(&se_cmd->se_cmd_list); | 152 | list_del_init(&se_cmd->se_cmd_list); |
154 | kref_get(&se_cmd->cmd_kref); | 153 | kref_get(&se_cmd->cmd_kref); |
@@ -371,7 +370,7 @@ int core_tmr_lun_reset( | |||
371 | * which the command was received shall be completed with TASK ABORTED | 370 | * which the command was received shall be completed with TASK ABORTED |
372 | * status (see SAM-4). | 371 | * status (see SAM-4). |
373 | */ | 372 | */ |
374 | tas = dev->se_sub_dev->se_dev_attrib.emulate_tas; | 373 | tas = dev->dev_attrib.emulate_tas; |
375 | /* | 374 | /* |
376 | * Determine if this se_tmr is coming from a $FABRIC_MOD | 375 | * Determine if this se_tmr is coming from a $FABRIC_MOD |
377 | * or struct se_device passthrough.. | 376 | * or struct se_device passthrough.. |
@@ -399,10 +398,10 @@ int core_tmr_lun_reset( | |||
399 | * LOGICAL UNIT RESET | 398 | * LOGICAL UNIT RESET |
400 | */ | 399 | */ |
401 | if (!preempt_and_abort_list && | 400 | if (!preempt_and_abort_list && |
402 | (dev->dev_flags & DF_SPC2_RESERVATIONS)) { | 401 | (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)) { |
403 | spin_lock(&dev->dev_reservation_lock); | 402 | spin_lock(&dev->dev_reservation_lock); |
404 | dev->dev_reserved_node_acl = NULL; | 403 | dev->dev_reserved_node_acl = NULL; |
405 | dev->dev_flags &= ~DF_SPC2_RESERVATIONS; | 404 | dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS; |
406 | spin_unlock(&dev->dev_reservation_lock); | 405 | spin_unlock(&dev->dev_reservation_lock); |
407 | pr_debug("LUN_RESET: SCSI-2 Released reservation\n"); | 406 | pr_debug("LUN_RESET: SCSI-2 Released reservation\n"); |
408 | } | 407 | } |
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index a531fe282b1e..5192ac0337f7 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c | |||
@@ -3,10 +3,7 @@ | |||
3 | * | 3 | * |
4 | * This file contains generic Target Portal Group related functions. | 4 | * This file contains generic Target Portal Group related functions. |
5 | * | 5 | * |
6 | * Copyright (c) 2002, 2003, 2004, 2005 PyX Technologies, Inc. | 6 | * (c) Copyright 2002-2012 RisingTide Systems LLC. |
7 | * Copyright (c) 2005, 2006, 2007 SBE, Inc. | ||
8 | * Copyright (c) 2007-2010 Rising Tide Systems | ||
9 | * Copyright (c) 2008-2010 Linux-iSCSI.org | ||
10 | * | 7 | * |
11 | * Nicholas A. Bellinger <nab@kernel.org> | 8 | * Nicholas A. Bellinger <nab@kernel.org> |
12 | * | 9 | * |
@@ -619,6 +616,29 @@ int core_tpg_set_initiator_node_queue_depth( | |||
619 | } | 616 | } |
620 | EXPORT_SYMBOL(core_tpg_set_initiator_node_queue_depth); | 617 | EXPORT_SYMBOL(core_tpg_set_initiator_node_queue_depth); |
621 | 618 | ||
619 | /* core_tpg_set_initiator_node_tag(): | ||
620 | * | ||
621 | * Initiator nodeacl tags are not used internally, but may be used by | ||
622 | * userspace to emulate aliases or groups. | ||
623 | * Returns length of newly-set tag or -EINVAL. | ||
624 | */ | ||
625 | int core_tpg_set_initiator_node_tag( | ||
626 | struct se_portal_group *tpg, | ||
627 | struct se_node_acl *acl, | ||
628 | const char *new_tag) | ||
629 | { | ||
630 | if (strlen(new_tag) >= MAX_ACL_TAG_SIZE) | ||
631 | return -EINVAL; | ||
632 | |||
633 | if (!strncmp("NULL", new_tag, 4)) { | ||
634 | acl->acl_tag[0] = '\0'; | ||
635 | return 0; | ||
636 | } | ||
637 | |||
638 | return snprintf(acl->acl_tag, MAX_ACL_TAG_SIZE, "%s", new_tag); | ||
639 | } | ||
640 | EXPORT_SYMBOL(core_tpg_set_initiator_node_tag); | ||
641 | |||
622 | static int core_tpg_setup_virtual_lun0(struct se_portal_group *se_tpg) | 642 | static int core_tpg_setup_virtual_lun0(struct se_portal_group *se_tpg) |
623 | { | 643 | { |
624 | /* Set in core_dev_setup_virtual_lun0() */ | 644 | /* Set in core_dev_setup_virtual_lun0() */ |
@@ -672,6 +692,7 @@ int core_tpg_register( | |||
672 | for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { | 692 | for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { |
673 | lun = se_tpg->tpg_lun_list[i]; | 693 | lun = se_tpg->tpg_lun_list[i]; |
674 | lun->unpacked_lun = i; | 694 | lun->unpacked_lun = i; |
695 | lun->lun_link_magic = SE_LUN_LINK_MAGIC; | ||
675 | lun->lun_status = TRANSPORT_LUN_STATUS_FREE; | 696 | lun->lun_status = TRANSPORT_LUN_STATUS_FREE; |
676 | atomic_set(&lun->lun_acl_count, 0); | 697 | atomic_set(&lun->lun_acl_count, 0); |
677 | init_completion(&lun->lun_shutdown_comp); | 698 | init_completion(&lun->lun_shutdown_comp); |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index c33baff86aa6..bd587b70661a 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -3,10 +3,7 @@ | |||
3 | * | 3 | * |
4 | * This file contains the Generic Target Engine Core. | 4 | * This file contains the Generic Target Engine Core. |
5 | * | 5 | * |
6 | * Copyright (c) 2002, 2003, 2004, 2005 PyX Technologies, Inc. | 6 | * (c) Copyright 2002-2012 RisingTide Systems LLC. |
7 | * Copyright (c) 2005, 2006, 2007 SBE, Inc. | ||
8 | * Copyright (c) 2007-2010 Rising Tide Systems | ||
9 | * Copyright (c) 2008-2010 Linux-iSCSI.org | ||
10 | * | 7 | * |
11 | * Nicholas A. Bellinger <nab@kernel.org> | 8 | * Nicholas A. Bellinger <nab@kernel.org> |
12 | * | 9 | * |
@@ -70,7 +67,6 @@ static void transport_handle_queue_full(struct se_cmd *cmd, | |||
70 | static int transport_generic_get_mem(struct se_cmd *cmd); | 67 | static int transport_generic_get_mem(struct se_cmd *cmd); |
71 | static int target_get_sess_cmd(struct se_session *, struct se_cmd *, bool); | 68 | static int target_get_sess_cmd(struct se_session *, struct se_cmd *, bool); |
72 | static void transport_put_cmd(struct se_cmd *cmd); | 69 | static void transport_put_cmd(struct se_cmd *cmd); |
73 | static int transport_set_sense_codes(struct se_cmd *cmd, u8 asc, u8 ascq); | ||
74 | static void target_complete_ok_work(struct work_struct *work); | 70 | static void target_complete_ok_work(struct work_struct *work); |
75 | 71 | ||
76 | int init_se_kmem_caches(void) | 72 | int init_se_kmem_caches(void) |
@@ -297,7 +293,7 @@ void transport_register_session( | |||
297 | } | 293 | } |
298 | EXPORT_SYMBOL(transport_register_session); | 294 | EXPORT_SYMBOL(transport_register_session); |
299 | 295 | ||
300 | void target_release_session(struct kref *kref) | 296 | static void target_release_session(struct kref *kref) |
301 | { | 297 | { |
302 | struct se_session *se_sess = container_of(kref, | 298 | struct se_session *se_sess = container_of(kref, |
303 | struct se_session, sess_kref); | 299 | struct se_session, sess_kref); |
@@ -545,9 +541,6 @@ static void transport_lun_remove_cmd(struct se_cmd *cmd) | |||
545 | 541 | ||
546 | void transport_cmd_finish_abort(struct se_cmd *cmd, int remove) | 542 | void transport_cmd_finish_abort(struct se_cmd *cmd, int remove) |
547 | { | 543 | { |
548 | if (!(cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) | ||
549 | transport_lun_remove_cmd(cmd); | ||
550 | |||
551 | if (transport_cmd_check_stop_to_fabric(cmd)) | 544 | if (transport_cmd_check_stop_to_fabric(cmd)) |
552 | return; | 545 | return; |
553 | if (remove) | 546 | if (remove) |
@@ -558,7 +551,8 @@ static void target_complete_failure_work(struct work_struct *work) | |||
558 | { | 551 | { |
559 | struct se_cmd *cmd = container_of(work, struct se_cmd, work); | 552 | struct se_cmd *cmd = container_of(work, struct se_cmd, work); |
560 | 553 | ||
561 | transport_generic_request_failure(cmd); | 554 | transport_generic_request_failure(cmd, |
555 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE); | ||
562 | } | 556 | } |
563 | 557 | ||
564 | /* | 558 | /* |
@@ -626,7 +620,6 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) | |||
626 | complete(&cmd->t_transport_stop_comp); | 620 | complete(&cmd->t_transport_stop_comp); |
627 | return; | 621 | return; |
628 | } else if (cmd->transport_state & CMD_T_FAILED) { | 622 | } else if (cmd->transport_state & CMD_T_FAILED) { |
629 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
630 | INIT_WORK(&cmd->work, target_complete_failure_work); | 623 | INIT_WORK(&cmd->work, target_complete_failure_work); |
631 | } else { | 624 | } else { |
632 | INIT_WORK(&cmd->work, target_complete_ok_work); | 625 | INIT_WORK(&cmd->work, target_complete_ok_work); |
@@ -659,7 +652,7 @@ static void target_add_to_state_list(struct se_cmd *cmd) | |||
659 | static void transport_write_pending_qf(struct se_cmd *cmd); | 652 | static void transport_write_pending_qf(struct se_cmd *cmd); |
660 | static void transport_complete_qf(struct se_cmd *cmd); | 653 | static void transport_complete_qf(struct se_cmd *cmd); |
661 | 654 | ||
662 | static void target_qf_do_work(struct work_struct *work) | 655 | void target_qf_do_work(struct work_struct *work) |
663 | { | 656 | { |
664 | struct se_device *dev = container_of(work, struct se_device, | 657 | struct se_device *dev = container_of(work, struct se_device, |
665 | qf_work_queue); | 658 | qf_work_queue); |
@@ -712,29 +705,15 @@ void transport_dump_dev_state( | |||
712 | int *bl) | 705 | int *bl) |
713 | { | 706 | { |
714 | *bl += sprintf(b + *bl, "Status: "); | 707 | *bl += sprintf(b + *bl, "Status: "); |
715 | switch (dev->dev_status) { | 708 | if (dev->export_count) |
716 | case TRANSPORT_DEVICE_ACTIVATED: | ||
717 | *bl += sprintf(b + *bl, "ACTIVATED"); | 709 | *bl += sprintf(b + *bl, "ACTIVATED"); |
718 | break; | 710 | else |
719 | case TRANSPORT_DEVICE_DEACTIVATED: | ||
720 | *bl += sprintf(b + *bl, "DEACTIVATED"); | 711 | *bl += sprintf(b + *bl, "DEACTIVATED"); |
721 | break; | ||
722 | case TRANSPORT_DEVICE_SHUTDOWN: | ||
723 | *bl += sprintf(b + *bl, "SHUTDOWN"); | ||
724 | break; | ||
725 | case TRANSPORT_DEVICE_OFFLINE_ACTIVATED: | ||
726 | case TRANSPORT_DEVICE_OFFLINE_DEACTIVATED: | ||
727 | *bl += sprintf(b + *bl, "OFFLINE"); | ||
728 | break; | ||
729 | default: | ||
730 | *bl += sprintf(b + *bl, "UNKNOWN=%d", dev->dev_status); | ||
731 | break; | ||
732 | } | ||
733 | 712 | ||
734 | *bl += sprintf(b + *bl, " Max Queue Depth: %d", dev->queue_depth); | 713 | *bl += sprintf(b + *bl, " Max Queue Depth: %d", dev->queue_depth); |
735 | *bl += sprintf(b + *bl, " SectorSize: %u HwMaxSectors: %u\n", | 714 | *bl += sprintf(b + *bl, " SectorSize: %u HwMaxSectors: %u\n", |
736 | dev->se_sub_dev->se_dev_attrib.block_size, | 715 | dev->dev_attrib.block_size, |
737 | dev->se_sub_dev->se_dev_attrib.hw_max_sectors); | 716 | dev->dev_attrib.hw_max_sectors); |
738 | *bl += sprintf(b + *bl, " "); | 717 | *bl += sprintf(b + *bl, " "); |
739 | } | 718 | } |
740 | 719 | ||
@@ -991,186 +970,8 @@ transport_set_vpd_ident(struct t10_vpd *vpd, unsigned char *page_83) | |||
991 | } | 970 | } |
992 | EXPORT_SYMBOL(transport_set_vpd_ident); | 971 | EXPORT_SYMBOL(transport_set_vpd_ident); |
993 | 972 | ||
994 | static void core_setup_task_attr_emulation(struct se_device *dev) | 973 | sense_reason_t |
995 | { | 974 | target_cmd_size_check(struct se_cmd *cmd, unsigned int size) |
996 | /* | ||
997 | * If this device is from Target_Core_Mod/pSCSI, disable the | ||
998 | * SAM Task Attribute emulation. | ||
999 | * | ||
1000 | * This is currently not available in upsream Linux/SCSI Target | ||
1001 | * mode code, and is assumed to be disabled while using TCM/pSCSI. | ||
1002 | */ | ||
1003 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { | ||
1004 | dev->dev_task_attr_type = SAM_TASK_ATTR_PASSTHROUGH; | ||
1005 | return; | ||
1006 | } | ||
1007 | |||
1008 | dev->dev_task_attr_type = SAM_TASK_ATTR_EMULATED; | ||
1009 | pr_debug("%s: Using SAM_TASK_ATTR_EMULATED for SPC: 0x%02x" | ||
1010 | " device\n", dev->transport->name, | ||
1011 | dev->transport->get_device_rev(dev)); | ||
1012 | } | ||
1013 | |||
1014 | static void scsi_dump_inquiry(struct se_device *dev) | ||
1015 | { | ||
1016 | struct t10_wwn *wwn = &dev->se_sub_dev->t10_wwn; | ||
1017 | char buf[17]; | ||
1018 | int i, device_type; | ||
1019 | /* | ||
1020 | * Print Linux/SCSI style INQUIRY formatting to the kernel ring buffer | ||
1021 | */ | ||
1022 | for (i = 0; i < 8; i++) | ||
1023 | if (wwn->vendor[i] >= 0x20) | ||
1024 | buf[i] = wwn->vendor[i]; | ||
1025 | else | ||
1026 | buf[i] = ' '; | ||
1027 | buf[i] = '\0'; | ||
1028 | pr_debug(" Vendor: %s\n", buf); | ||
1029 | |||
1030 | for (i = 0; i < 16; i++) | ||
1031 | if (wwn->model[i] >= 0x20) | ||
1032 | buf[i] = wwn->model[i]; | ||
1033 | else | ||
1034 | buf[i] = ' '; | ||
1035 | buf[i] = '\0'; | ||
1036 | pr_debug(" Model: %s\n", buf); | ||
1037 | |||
1038 | for (i = 0; i < 4; i++) | ||
1039 | if (wwn->revision[i] >= 0x20) | ||
1040 | buf[i] = wwn->revision[i]; | ||
1041 | else | ||
1042 | buf[i] = ' '; | ||
1043 | buf[i] = '\0'; | ||
1044 | pr_debug(" Revision: %s\n", buf); | ||
1045 | |||
1046 | device_type = dev->transport->get_device_type(dev); | ||
1047 | pr_debug(" Type: %s ", scsi_device_type(device_type)); | ||
1048 | pr_debug(" ANSI SCSI revision: %02x\n", | ||
1049 | dev->transport->get_device_rev(dev)); | ||
1050 | } | ||
1051 | |||
1052 | struct se_device *transport_add_device_to_core_hba( | ||
1053 | struct se_hba *hba, | ||
1054 | struct se_subsystem_api *transport, | ||
1055 | struct se_subsystem_dev *se_dev, | ||
1056 | u32 device_flags, | ||
1057 | void *transport_dev, | ||
1058 | struct se_dev_limits *dev_limits, | ||
1059 | const char *inquiry_prod, | ||
1060 | const char *inquiry_rev) | ||
1061 | { | ||
1062 | int force_pt; | ||
1063 | struct se_device *dev; | ||
1064 | |||
1065 | dev = kzalloc(sizeof(struct se_device), GFP_KERNEL); | ||
1066 | if (!dev) { | ||
1067 | pr_err("Unable to allocate memory for se_dev_t\n"); | ||
1068 | return NULL; | ||
1069 | } | ||
1070 | |||
1071 | dev->dev_flags = device_flags; | ||
1072 | dev->dev_status |= TRANSPORT_DEVICE_DEACTIVATED; | ||
1073 | dev->dev_ptr = transport_dev; | ||
1074 | dev->se_hba = hba; | ||
1075 | dev->se_sub_dev = se_dev; | ||
1076 | dev->transport = transport; | ||
1077 | INIT_LIST_HEAD(&dev->dev_list); | ||
1078 | INIT_LIST_HEAD(&dev->dev_sep_list); | ||
1079 | INIT_LIST_HEAD(&dev->dev_tmr_list); | ||
1080 | INIT_LIST_HEAD(&dev->delayed_cmd_list); | ||
1081 | INIT_LIST_HEAD(&dev->state_list); | ||
1082 | INIT_LIST_HEAD(&dev->qf_cmd_list); | ||
1083 | spin_lock_init(&dev->execute_task_lock); | ||
1084 | spin_lock_init(&dev->delayed_cmd_lock); | ||
1085 | spin_lock_init(&dev->dev_reservation_lock); | ||
1086 | spin_lock_init(&dev->dev_status_lock); | ||
1087 | spin_lock_init(&dev->se_port_lock); | ||
1088 | spin_lock_init(&dev->se_tmr_lock); | ||
1089 | spin_lock_init(&dev->qf_cmd_lock); | ||
1090 | atomic_set(&dev->dev_ordered_id, 0); | ||
1091 | |||
1092 | se_dev_set_default_attribs(dev, dev_limits); | ||
1093 | |||
1094 | dev->dev_index = scsi_get_new_index(SCSI_DEVICE_INDEX); | ||
1095 | dev->creation_time = get_jiffies_64(); | ||
1096 | spin_lock_init(&dev->stats_lock); | ||
1097 | |||
1098 | spin_lock(&hba->device_lock); | ||
1099 | list_add_tail(&dev->dev_list, &hba->hba_dev_list); | ||
1100 | hba->dev_count++; | ||
1101 | spin_unlock(&hba->device_lock); | ||
1102 | /* | ||
1103 | * Setup the SAM Task Attribute emulation for struct se_device | ||
1104 | */ | ||
1105 | core_setup_task_attr_emulation(dev); | ||
1106 | /* | ||
1107 | * Force PR and ALUA passthrough emulation with internal object use. | ||
1108 | */ | ||
1109 | force_pt = (hba->hba_flags & HBA_FLAGS_INTERNAL_USE); | ||
1110 | /* | ||
1111 | * Setup the Reservations infrastructure for struct se_device | ||
1112 | */ | ||
1113 | core_setup_reservations(dev, force_pt); | ||
1114 | /* | ||
1115 | * Setup the Asymmetric Logical Unit Assignment for struct se_device | ||
1116 | */ | ||
1117 | if (core_setup_alua(dev, force_pt) < 0) | ||
1118 | goto err_dev_list; | ||
1119 | |||
1120 | /* | ||
1121 | * Startup the struct se_device processing thread | ||
1122 | */ | ||
1123 | dev->tmr_wq = alloc_workqueue("tmr-%s", WQ_MEM_RECLAIM | WQ_UNBOUND, 1, | ||
1124 | dev->transport->name); | ||
1125 | if (!dev->tmr_wq) { | ||
1126 | pr_err("Unable to create tmr workqueue for %s\n", | ||
1127 | dev->transport->name); | ||
1128 | goto err_dev_list; | ||
1129 | } | ||
1130 | /* | ||
1131 | * Setup work_queue for QUEUE_FULL | ||
1132 | */ | ||
1133 | INIT_WORK(&dev->qf_work_queue, target_qf_do_work); | ||
1134 | /* | ||
1135 | * Preload the initial INQUIRY const values if we are doing | ||
1136 | * anything virtual (IBLOCK, FILEIO, RAMDISK), but not for TCM/pSCSI | ||
1137 | * passthrough because this is being provided by the backend LLD. | ||
1138 | * This is required so that transport_get_inquiry() copies these | ||
1139 | * originals once back into DEV_T10_WWN(dev) for the virtual device | ||
1140 | * setup. | ||
1141 | */ | ||
1142 | if (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) { | ||
1143 | if (!inquiry_prod || !inquiry_rev) { | ||
1144 | pr_err("All non TCM/pSCSI plugins require" | ||
1145 | " INQUIRY consts\n"); | ||
1146 | goto err_wq; | ||
1147 | } | ||
1148 | |||
1149 | strncpy(&dev->se_sub_dev->t10_wwn.vendor[0], "LIO-ORG", 8); | ||
1150 | strncpy(&dev->se_sub_dev->t10_wwn.model[0], inquiry_prod, 16); | ||
1151 | strncpy(&dev->se_sub_dev->t10_wwn.revision[0], inquiry_rev, 4); | ||
1152 | } | ||
1153 | scsi_dump_inquiry(dev); | ||
1154 | |||
1155 | return dev; | ||
1156 | |||
1157 | err_wq: | ||
1158 | destroy_workqueue(dev->tmr_wq); | ||
1159 | err_dev_list: | ||
1160 | spin_lock(&hba->device_lock); | ||
1161 | list_del(&dev->dev_list); | ||
1162 | hba->dev_count--; | ||
1163 | spin_unlock(&hba->device_lock); | ||
1164 | |||
1165 | se_release_vpd_for_dev(dev); | ||
1166 | |||
1167 | kfree(dev); | ||
1168 | |||
1169 | return NULL; | ||
1170 | } | ||
1171 | EXPORT_SYMBOL(transport_add_device_to_core_hba); | ||
1172 | |||
1173 | int target_cmd_size_check(struct se_cmd *cmd, unsigned int size) | ||
1174 | { | 975 | { |
1175 | struct se_device *dev = cmd->se_dev; | 976 | struct se_device *dev = cmd->se_dev; |
1176 | 977 | ||
@@ -1185,18 +986,18 @@ int target_cmd_size_check(struct se_cmd *cmd, unsigned int size) | |||
1185 | if (cmd->data_direction == DMA_TO_DEVICE) { | 986 | if (cmd->data_direction == DMA_TO_DEVICE) { |
1186 | pr_err("Rejecting underflow/overflow" | 987 | pr_err("Rejecting underflow/overflow" |
1187 | " WRITE data\n"); | 988 | " WRITE data\n"); |
1188 | goto out_invalid_cdb_field; | 989 | return TCM_INVALID_CDB_FIELD; |
1189 | } | 990 | } |
1190 | /* | 991 | /* |
1191 | * Reject READ_* or WRITE_* with overflow/underflow for | 992 | * Reject READ_* or WRITE_* with overflow/underflow for |
1192 | * type SCF_SCSI_DATA_CDB. | 993 | * type SCF_SCSI_DATA_CDB. |
1193 | */ | 994 | */ |
1194 | if (dev->se_sub_dev->se_dev_attrib.block_size != 512) { | 995 | if (dev->dev_attrib.block_size != 512) { |
1195 | pr_err("Failing OVERFLOW/UNDERFLOW for LBA op" | 996 | pr_err("Failing OVERFLOW/UNDERFLOW for LBA op" |
1196 | " CDB on non 512-byte sector setup subsystem" | 997 | " CDB on non 512-byte sector setup subsystem" |
1197 | " plugin: %s\n", dev->transport->name); | 998 | " plugin: %s\n", dev->transport->name); |
1198 | /* Returns CHECK_CONDITION + INVALID_CDB_FIELD */ | 999 | /* Returns CHECK_CONDITION + INVALID_CDB_FIELD */ |
1199 | goto out_invalid_cdb_field; | 1000 | return TCM_INVALID_CDB_FIELD; |
1200 | } | 1001 | } |
1201 | /* | 1002 | /* |
1202 | * For the overflow case keep the existing fabric provided | 1003 | * For the overflow case keep the existing fabric provided |
@@ -1216,10 +1017,6 @@ int target_cmd_size_check(struct se_cmd *cmd, unsigned int size) | |||
1216 | 1017 | ||
1217 | return 0; | 1018 | return 0; |
1218 | 1019 | ||
1219 | out_invalid_cdb_field: | ||
1220 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1221 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
1222 | return -EINVAL; | ||
1223 | } | 1020 | } |
1224 | 1021 | ||
1225 | /* | 1022 | /* |
@@ -1259,45 +1056,41 @@ void transport_init_se_cmd( | |||
1259 | } | 1056 | } |
1260 | EXPORT_SYMBOL(transport_init_se_cmd); | 1057 | EXPORT_SYMBOL(transport_init_se_cmd); |
1261 | 1058 | ||
1262 | static int transport_check_alloc_task_attr(struct se_cmd *cmd) | 1059 | static sense_reason_t |
1060 | transport_check_alloc_task_attr(struct se_cmd *cmd) | ||
1263 | { | 1061 | { |
1062 | struct se_device *dev = cmd->se_dev; | ||
1063 | |||
1264 | /* | 1064 | /* |
1265 | * Check if SAM Task Attribute emulation is enabled for this | 1065 | * Check if SAM Task Attribute emulation is enabled for this |
1266 | * struct se_device storage object | 1066 | * struct se_device storage object |
1267 | */ | 1067 | */ |
1268 | if (cmd->se_dev->dev_task_attr_type != SAM_TASK_ATTR_EMULATED) | 1068 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) |
1269 | return 0; | 1069 | return 0; |
1270 | 1070 | ||
1271 | if (cmd->sam_task_attr == MSG_ACA_TAG) { | 1071 | if (cmd->sam_task_attr == MSG_ACA_TAG) { |
1272 | pr_debug("SAM Task Attribute ACA" | 1072 | pr_debug("SAM Task Attribute ACA" |
1273 | " emulation is not supported\n"); | 1073 | " emulation is not supported\n"); |
1274 | return -EINVAL; | 1074 | return TCM_INVALID_CDB_FIELD; |
1275 | } | 1075 | } |
1276 | /* | 1076 | /* |
1277 | * Used to determine when ORDERED commands should go from | 1077 | * Used to determine when ORDERED commands should go from |
1278 | * Dormant to Active status. | 1078 | * Dormant to Active status. |
1279 | */ | 1079 | */ |
1280 | cmd->se_ordered_id = atomic_inc_return(&cmd->se_dev->dev_ordered_id); | 1080 | cmd->se_ordered_id = atomic_inc_return(&dev->dev_ordered_id); |
1281 | smp_mb__after_atomic_inc(); | 1081 | smp_mb__after_atomic_inc(); |
1282 | pr_debug("Allocated se_ordered_id: %u for Task Attr: 0x%02x on %s\n", | 1082 | pr_debug("Allocated se_ordered_id: %u for Task Attr: 0x%02x on %s\n", |
1283 | cmd->se_ordered_id, cmd->sam_task_attr, | 1083 | cmd->se_ordered_id, cmd->sam_task_attr, |
1284 | cmd->se_dev->transport->name); | 1084 | dev->transport->name); |
1285 | return 0; | 1085 | return 0; |
1286 | } | 1086 | } |
1287 | 1087 | ||
1288 | /* target_setup_cmd_from_cdb(): | 1088 | sense_reason_t |
1289 | * | 1089 | target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb) |
1290 | * Called from fabric RX Thread. | ||
1291 | */ | ||
1292 | int target_setup_cmd_from_cdb( | ||
1293 | struct se_cmd *cmd, | ||
1294 | unsigned char *cdb) | ||
1295 | { | 1090 | { |
1296 | struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev; | 1091 | struct se_device *dev = cmd->se_dev; |
1297 | u32 pr_reg_type = 0; | ||
1298 | u8 alua_ascq = 0; | ||
1299 | unsigned long flags; | 1092 | unsigned long flags; |
1300 | int ret; | 1093 | sense_reason_t ret; |
1301 | 1094 | ||
1302 | /* | 1095 | /* |
1303 | * Ensure that the received CDB is less than the max (252 + 8) bytes | 1096 | * Ensure that the received CDB is less than the max (252 + 8) bytes |
@@ -1307,9 +1100,7 @@ int target_setup_cmd_from_cdb( | |||
1307 | pr_err("Received SCSI CDB with command_size: %d that" | 1100 | pr_err("Received SCSI CDB with command_size: %d that" |
1308 | " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n", | 1101 | " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n", |
1309 | scsi_command_size(cdb), SCSI_MAX_VARLEN_CDB_SIZE); | 1102 | scsi_command_size(cdb), SCSI_MAX_VARLEN_CDB_SIZE); |
1310 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | 1103 | return TCM_INVALID_CDB_FIELD; |
1311 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
1312 | return -EINVAL; | ||
1313 | } | 1104 | } |
1314 | /* | 1105 | /* |
1315 | * If the received CDB is larger than TCM_MAX_COMMAND_SIZE, | 1106 | * If the received CDB is larger than TCM_MAX_COMMAND_SIZE, |
@@ -1324,10 +1115,7 @@ int target_setup_cmd_from_cdb( | |||
1324 | " %u > sizeof(cmd->__t_task_cdb): %lu ops\n", | 1115 | " %u > sizeof(cmd->__t_task_cdb): %lu ops\n", |
1325 | scsi_command_size(cdb), | 1116 | scsi_command_size(cdb), |
1326 | (unsigned long)sizeof(cmd->__t_task_cdb)); | 1117 | (unsigned long)sizeof(cmd->__t_task_cdb)); |
1327 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | 1118 | return TCM_OUT_OF_RESOURCES; |
1328 | cmd->scsi_sense_reason = | ||
1329 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1330 | return -ENOMEM; | ||
1331 | } | 1119 | } |
1332 | } else | 1120 | } else |
1333 | cmd->t_task_cdb = &cmd->__t_task_cdb[0]; | 1121 | cmd->t_task_cdb = &cmd->__t_task_cdb[0]; |
@@ -1339,70 +1127,30 @@ int target_setup_cmd_from_cdb( | |||
1339 | /* | 1127 | /* |
1340 | * Check for an existing UNIT ATTENTION condition | 1128 | * Check for an existing UNIT ATTENTION condition |
1341 | */ | 1129 | */ |
1342 | if (core_scsi3_ua_check(cmd, cdb) < 0) { | 1130 | ret = target_scsi3_ua_check(cmd); |
1343 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | 1131 | if (ret) |
1344 | cmd->scsi_sense_reason = TCM_CHECK_CONDITION_UNIT_ATTENTION; | 1132 | return ret; |
1345 | return -EINVAL; | ||
1346 | } | ||
1347 | 1133 | ||
1348 | ret = su_dev->t10_alua.alua_state_check(cmd, cdb, &alua_ascq); | 1134 | ret = target_alua_state_check(cmd); |
1349 | if (ret != 0) { | 1135 | if (ret) |
1350 | /* | 1136 | return ret; |
1351 | * Set SCSI additional sense code (ASC) to 'LUN Not Accessible'; | ||
1352 | * The ALUA additional sense code qualifier (ASCQ) is determined | ||
1353 | * by the ALUA primary or secondary access state.. | ||
1354 | */ | ||
1355 | if (ret > 0) { | ||
1356 | pr_debug("[%s]: ALUA TG Port not available, " | ||
1357 | "SenseKey: NOT_READY, ASC/ASCQ: " | ||
1358 | "0x04/0x%02x\n", | ||
1359 | cmd->se_tfo->get_fabric_name(), alua_ascq); | ||
1360 | |||
1361 | transport_set_sense_codes(cmd, 0x04, alua_ascq); | ||
1362 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1363 | cmd->scsi_sense_reason = TCM_CHECK_CONDITION_NOT_READY; | ||
1364 | return -EINVAL; | ||
1365 | } | ||
1366 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1367 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
1368 | return -EINVAL; | ||
1369 | } | ||
1370 | 1137 | ||
1371 | /* | 1138 | ret = target_check_reservation(cmd); |
1372 | * Check status for SPC-3 Persistent Reservations | 1139 | if (ret) |
1373 | */ | 1140 | return ret; |
1374 | if (su_dev->t10_pr.pr_ops.t10_reservation_check(cmd, &pr_reg_type)) { | ||
1375 | if (su_dev->t10_pr.pr_ops.t10_seq_non_holder( | ||
1376 | cmd, cdb, pr_reg_type) != 0) { | ||
1377 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1378 | cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT; | ||
1379 | cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT; | ||
1380 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | ||
1381 | return -EBUSY; | ||
1382 | } | ||
1383 | /* | ||
1384 | * This means the CDB is allowed for the SCSI Initiator port | ||
1385 | * when said port is *NOT* holding the legacy SPC-2 or | ||
1386 | * SPC-3 Persistent Reservation. | ||
1387 | */ | ||
1388 | } | ||
1389 | 1141 | ||
1390 | ret = cmd->se_dev->transport->parse_cdb(cmd); | 1142 | ret = dev->transport->parse_cdb(cmd); |
1391 | if (ret < 0) | 1143 | if (ret) |
1144 | return ret; | ||
1145 | |||
1146 | ret = transport_check_alloc_task_attr(cmd); | ||
1147 | if (ret) | ||
1392 | return ret; | 1148 | return ret; |
1393 | 1149 | ||
1394 | spin_lock_irqsave(&cmd->t_state_lock, flags); | 1150 | spin_lock_irqsave(&cmd->t_state_lock, flags); |
1395 | cmd->se_cmd_flags |= SCF_SUPPORTED_SAM_OPCODE; | 1151 | cmd->se_cmd_flags |= SCF_SUPPORTED_SAM_OPCODE; |
1396 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 1152 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
1397 | 1153 | ||
1398 | /* | ||
1399 | * Check for SAM Task Attribute Emulation | ||
1400 | */ | ||
1401 | if (transport_check_alloc_task_attr(cmd) < 0) { | ||
1402 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1403 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
1404 | return -EINVAL; | ||
1405 | } | ||
1406 | spin_lock(&cmd->se_lun->lun_sep_lock); | 1154 | spin_lock(&cmd->se_lun->lun_sep_lock); |
1407 | if (cmd->se_lun->lun_sep) | 1155 | if (cmd->se_lun->lun_sep) |
1408 | cmd->se_lun->lun_sep->sep_stats.cmd_pdus++; | 1156 | cmd->se_lun->lun_sep->sep_stats.cmd_pdus++; |
@@ -1418,7 +1166,7 @@ EXPORT_SYMBOL(target_setup_cmd_from_cdb); | |||
1418 | int transport_handle_cdb_direct( | 1166 | int transport_handle_cdb_direct( |
1419 | struct se_cmd *cmd) | 1167 | struct se_cmd *cmd) |
1420 | { | 1168 | { |
1421 | int ret; | 1169 | sense_reason_t ret; |
1422 | 1170 | ||
1423 | if (!cmd->se_lun) { | 1171 | if (!cmd->se_lun) { |
1424 | dump_stack(); | 1172 | dump_stack(); |
@@ -1448,13 +1196,41 @@ int transport_handle_cdb_direct( | |||
1448 | * and call transport_generic_request_failure() if necessary.. | 1196 | * and call transport_generic_request_failure() if necessary.. |
1449 | */ | 1197 | */ |
1450 | ret = transport_generic_new_cmd(cmd); | 1198 | ret = transport_generic_new_cmd(cmd); |
1451 | if (ret < 0) | 1199 | if (ret) |
1452 | transport_generic_request_failure(cmd); | 1200 | transport_generic_request_failure(cmd, ret); |
1453 | |||
1454 | return 0; | 1201 | return 0; |
1455 | } | 1202 | } |
1456 | EXPORT_SYMBOL(transport_handle_cdb_direct); | 1203 | EXPORT_SYMBOL(transport_handle_cdb_direct); |
1457 | 1204 | ||
1205 | static sense_reason_t | ||
1206 | transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *sgl, | ||
1207 | u32 sgl_count, struct scatterlist *sgl_bidi, u32 sgl_bidi_count) | ||
1208 | { | ||
1209 | if (!sgl || !sgl_count) | ||
1210 | return 0; | ||
1211 | |||
1212 | /* | ||
1213 | * Reject SCSI data overflow with map_mem_to_cmd() as incoming | ||
1214 | * scatterlists already have been set to follow what the fabric | ||
1215 | * passes for the original expected data transfer length. | ||
1216 | */ | ||
1217 | if (cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { | ||
1218 | pr_warn("Rejecting SCSI DATA overflow for fabric using" | ||
1219 | " SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC\n"); | ||
1220 | return TCM_INVALID_CDB_FIELD; | ||
1221 | } | ||
1222 | |||
1223 | cmd->t_data_sg = sgl; | ||
1224 | cmd->t_data_nents = sgl_count; | ||
1225 | |||
1226 | if (sgl_bidi && sgl_bidi_count) { | ||
1227 | cmd->t_bidi_data_sg = sgl_bidi; | ||
1228 | cmd->t_bidi_data_nents = sgl_bidi_count; | ||
1229 | } | ||
1230 | cmd->se_cmd_flags |= SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC; | ||
1231 | return 0; | ||
1232 | } | ||
1233 | |||
1458 | /* | 1234 | /* |
1459 | * target_submit_cmd_map_sgls - lookup unpacked lun and submit uninitialized | 1235 | * target_submit_cmd_map_sgls - lookup unpacked lun and submit uninitialized |
1460 | * se_cmd + use pre-allocated SGL memory. | 1236 | * se_cmd + use pre-allocated SGL memory. |
@@ -1487,7 +1263,8 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess | |||
1487 | struct scatterlist *sgl_bidi, u32 sgl_bidi_count) | 1263 | struct scatterlist *sgl_bidi, u32 sgl_bidi_count) |
1488 | { | 1264 | { |
1489 | struct se_portal_group *se_tpg; | 1265 | struct se_portal_group *se_tpg; |
1490 | int rc; | 1266 | sense_reason_t rc; |
1267 | int ret; | ||
1491 | 1268 | ||
1492 | se_tpg = se_sess->se_tpg; | 1269 | se_tpg = se_sess->se_tpg; |
1493 | BUG_ON(!se_tpg); | 1270 | BUG_ON(!se_tpg); |
@@ -1508,9 +1285,9 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess | |||
1508 | * for fabrics using TARGET_SCF_ACK_KREF that expect a second | 1285 | * for fabrics using TARGET_SCF_ACK_KREF that expect a second |
1509 | * kref_put() to happen during fabric packet acknowledgement. | 1286 | * kref_put() to happen during fabric packet acknowledgement. |
1510 | */ | 1287 | */ |
1511 | rc = target_get_sess_cmd(se_sess, se_cmd, (flags & TARGET_SCF_ACK_KREF)); | 1288 | ret = target_get_sess_cmd(se_sess, se_cmd, (flags & TARGET_SCF_ACK_KREF)); |
1512 | if (rc) | 1289 | if (ret) |
1513 | return rc; | 1290 | return ret; |
1514 | /* | 1291 | /* |
1515 | * Signal bidirectional data payloads to target-core | 1292 | * Signal bidirectional data payloads to target-core |
1516 | */ | 1293 | */ |
@@ -1519,16 +1296,16 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess | |||
1519 | /* | 1296 | /* |
1520 | * Locate se_lun pointer and attach it to struct se_cmd | 1297 | * Locate se_lun pointer and attach it to struct se_cmd |
1521 | */ | 1298 | */ |
1522 | if (transport_lookup_cmd_lun(se_cmd, unpacked_lun) < 0) { | 1299 | rc = transport_lookup_cmd_lun(se_cmd, unpacked_lun); |
1523 | transport_send_check_condition_and_sense(se_cmd, | 1300 | if (rc) { |
1524 | se_cmd->scsi_sense_reason, 0); | 1301 | transport_send_check_condition_and_sense(se_cmd, rc, 0); |
1525 | target_put_sess_cmd(se_sess, se_cmd); | 1302 | target_put_sess_cmd(se_sess, se_cmd); |
1526 | return 0; | 1303 | return 0; |
1527 | } | 1304 | } |
1528 | 1305 | ||
1529 | rc = target_setup_cmd_from_cdb(se_cmd, cdb); | 1306 | rc = target_setup_cmd_from_cdb(se_cmd, cdb); |
1530 | if (rc != 0) { | 1307 | if (rc != 0) { |
1531 | transport_generic_request_failure(se_cmd); | 1308 | transport_generic_request_failure(se_cmd, rc); |
1532 | return 0; | 1309 | return 0; |
1533 | } | 1310 | } |
1534 | /* | 1311 | /* |
@@ -1563,7 +1340,7 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess | |||
1563 | rc = transport_generic_map_mem_to_cmd(se_cmd, sgl, sgl_count, | 1340 | rc = transport_generic_map_mem_to_cmd(se_cmd, sgl, sgl_count, |
1564 | sgl_bidi, sgl_bidi_count); | 1341 | sgl_bidi, sgl_bidi_count); |
1565 | if (rc != 0) { | 1342 | if (rc != 0) { |
1566 | transport_generic_request_failure(se_cmd); | 1343 | transport_generic_request_failure(se_cmd, rc); |
1567 | return 0; | 1344 | return 0; |
1568 | } | 1345 | } |
1569 | } | 1346 | } |
@@ -1616,7 +1393,8 @@ static void target_complete_tmr_failure(struct work_struct *work) | |||
1616 | 1393 | ||
1617 | se_cmd->se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST; | 1394 | se_cmd->se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST; |
1618 | se_cmd->se_tfo->queue_tm_rsp(se_cmd); | 1395 | se_cmd->se_tfo->queue_tm_rsp(se_cmd); |
1619 | transport_generic_free_cmd(se_cmd, 0); | 1396 | |
1397 | transport_cmd_check_stop_to_fabric(se_cmd); | ||
1620 | } | 1398 | } |
1621 | 1399 | ||
1622 | /** | 1400 | /** |
@@ -1710,16 +1488,17 @@ bool target_stop_cmd(struct se_cmd *cmd, unsigned long *flags) | |||
1710 | /* | 1488 | /* |
1711 | * Handle SAM-esque emulation for generic transport request failures. | 1489 | * Handle SAM-esque emulation for generic transport request failures. |
1712 | */ | 1490 | */ |
1713 | void transport_generic_request_failure(struct se_cmd *cmd) | 1491 | void transport_generic_request_failure(struct se_cmd *cmd, |
1492 | sense_reason_t sense_reason) | ||
1714 | { | 1493 | { |
1715 | int ret = 0; | 1494 | int ret = 0; |
1716 | 1495 | ||
1717 | pr_debug("-----[ Storage Engine Exception for cmd: %p ITT: 0x%08x" | 1496 | pr_debug("-----[ Storage Engine Exception for cmd: %p ITT: 0x%08x" |
1718 | " CDB: 0x%02x\n", cmd, cmd->se_tfo->get_task_tag(cmd), | 1497 | " CDB: 0x%02x\n", cmd, cmd->se_tfo->get_task_tag(cmd), |
1719 | cmd->t_task_cdb[0]); | 1498 | cmd->t_task_cdb[0]); |
1720 | pr_debug("-----[ i_state: %d t_state: %d scsi_sense_reason: %d\n", | 1499 | pr_debug("-----[ i_state: %d t_state: %d sense_reason: %d\n", |
1721 | cmd->se_tfo->get_cmd_state(cmd), | 1500 | cmd->se_tfo->get_cmd_state(cmd), |
1722 | cmd->t_state, cmd->scsi_sense_reason); | 1501 | cmd->t_state, sense_reason); |
1723 | pr_debug("-----[ CMD_T_ACTIVE: %d CMD_T_STOP: %d CMD_T_SENT: %d\n", | 1502 | pr_debug("-----[ CMD_T_ACTIVE: %d CMD_T_STOP: %d CMD_T_SENT: %d\n", |
1724 | (cmd->transport_state & CMD_T_ACTIVE) != 0, | 1503 | (cmd->transport_state & CMD_T_ACTIVE) != 0, |
1725 | (cmd->transport_state & CMD_T_STOP) != 0, | 1504 | (cmd->transport_state & CMD_T_STOP) != 0, |
@@ -1728,10 +1507,9 @@ void transport_generic_request_failure(struct se_cmd *cmd) | |||
1728 | /* | 1507 | /* |
1729 | * For SAM Task Attribute emulation for failed struct se_cmd | 1508 | * For SAM Task Attribute emulation for failed struct se_cmd |
1730 | */ | 1509 | */ |
1731 | if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) | 1510 | transport_complete_task_attr(cmd); |
1732 | transport_complete_task_attr(cmd); | ||
1733 | 1511 | ||
1734 | switch (cmd->scsi_sense_reason) { | 1512 | switch (sense_reason) { |
1735 | case TCM_NON_EXISTENT_LUN: | 1513 | case TCM_NON_EXISTENT_LUN: |
1736 | case TCM_UNSUPPORTED_SCSI_OPCODE: | 1514 | case TCM_UNSUPPORTED_SCSI_OPCODE: |
1737 | case TCM_INVALID_CDB_FIELD: | 1515 | case TCM_INVALID_CDB_FIELD: |
@@ -1744,6 +1522,9 @@ void transport_generic_request_failure(struct se_cmd *cmd) | |||
1744 | case TCM_CHECK_CONDITION_UNIT_ATTENTION: | 1522 | case TCM_CHECK_CONDITION_UNIT_ATTENTION: |
1745 | case TCM_CHECK_CONDITION_NOT_READY: | 1523 | case TCM_CHECK_CONDITION_NOT_READY: |
1746 | break; | 1524 | break; |
1525 | case TCM_OUT_OF_RESOURCES: | ||
1526 | sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1527 | break; | ||
1747 | case TCM_RESERVATION_CONFLICT: | 1528 | case TCM_RESERVATION_CONFLICT: |
1748 | /* | 1529 | /* |
1749 | * No SENSE Data payload for this case, set SCSI Status | 1530 | * No SENSE Data payload for this case, set SCSI Status |
@@ -1760,7 +1541,7 @@ void transport_generic_request_failure(struct se_cmd *cmd) | |||
1760 | * See spc4r17, section 7.4.6 Control Mode Page, Table 349 | 1541 | * See spc4r17, section 7.4.6 Control Mode Page, Table 349 |
1761 | */ | 1542 | */ |
1762 | if (cmd->se_sess && | 1543 | if (cmd->se_sess && |
1763 | cmd->se_dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl == 2) | 1544 | cmd->se_dev->dev_attrib.emulate_ua_intlck_ctrl == 2) |
1764 | core_scsi3_ua_allocate(cmd->se_sess->se_node_acl, | 1545 | core_scsi3_ua_allocate(cmd->se_sess->se_node_acl, |
1765 | cmd->orig_fe_lun, 0x2C, | 1546 | cmd->orig_fe_lun, 0x2C, |
1766 | ASCQ_2CH_PREVIOUS_RESERVATION_CONFLICT_STATUS); | 1547 | ASCQ_2CH_PREVIOUS_RESERVATION_CONFLICT_STATUS); |
@@ -1771,13 +1552,12 @@ void transport_generic_request_failure(struct se_cmd *cmd) | |||
1771 | goto check_stop; | 1552 | goto check_stop; |
1772 | default: | 1553 | default: |
1773 | pr_err("Unknown transport error for CDB 0x%02x: %d\n", | 1554 | pr_err("Unknown transport error for CDB 0x%02x: %d\n", |
1774 | cmd->t_task_cdb[0], cmd->scsi_sense_reason); | 1555 | cmd->t_task_cdb[0], sense_reason); |
1775 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | 1556 | sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; |
1776 | break; | 1557 | break; |
1777 | } | 1558 | } |
1778 | 1559 | ||
1779 | ret = transport_send_check_condition_and_sense(cmd, | 1560 | ret = transport_send_check_condition_and_sense(cmd, sense_reason, 0); |
1780 | cmd->scsi_sense_reason, 0); | ||
1781 | if (ret == -EAGAIN || ret == -ENOMEM) | 1561 | if (ret == -EAGAIN || ret == -ENOMEM) |
1782 | goto queue_full; | 1562 | goto queue_full; |
1783 | 1563 | ||
@@ -1795,67 +1575,30 @@ EXPORT_SYMBOL(transport_generic_request_failure); | |||
1795 | 1575 | ||
1796 | static void __target_execute_cmd(struct se_cmd *cmd) | 1576 | static void __target_execute_cmd(struct se_cmd *cmd) |
1797 | { | 1577 | { |
1798 | int error = 0; | 1578 | sense_reason_t ret; |
1799 | 1579 | ||
1800 | spin_lock_irq(&cmd->t_state_lock); | 1580 | spin_lock_irq(&cmd->t_state_lock); |
1801 | cmd->transport_state |= (CMD_T_BUSY|CMD_T_SENT); | 1581 | cmd->transport_state |= (CMD_T_BUSY|CMD_T_SENT); |
1802 | spin_unlock_irq(&cmd->t_state_lock); | 1582 | spin_unlock_irq(&cmd->t_state_lock); |
1803 | 1583 | ||
1804 | if (cmd->execute_cmd) | 1584 | if (cmd->execute_cmd) { |
1805 | error = cmd->execute_cmd(cmd); | 1585 | ret = cmd->execute_cmd(cmd); |
1806 | 1586 | if (ret) { | |
1807 | if (error) { | 1587 | spin_lock_irq(&cmd->t_state_lock); |
1808 | spin_lock_irq(&cmd->t_state_lock); | 1588 | cmd->transport_state &= ~(CMD_T_BUSY|CMD_T_SENT); |
1809 | cmd->transport_state &= ~(CMD_T_BUSY|CMD_T_SENT); | 1589 | spin_unlock_irq(&cmd->t_state_lock); |
1810 | spin_unlock_irq(&cmd->t_state_lock); | ||
1811 | 1590 | ||
1812 | transport_generic_request_failure(cmd); | 1591 | transport_generic_request_failure(cmd, ret); |
1592 | } | ||
1813 | } | 1593 | } |
1814 | } | 1594 | } |
1815 | 1595 | ||
1816 | void target_execute_cmd(struct se_cmd *cmd) | 1596 | static bool target_handle_task_attr(struct se_cmd *cmd) |
1817 | { | 1597 | { |
1818 | struct se_device *dev = cmd->se_dev; | 1598 | struct se_device *dev = cmd->se_dev; |
1819 | 1599 | ||
1820 | /* | 1600 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) |
1821 | * If the received CDB has aleady been aborted stop processing it here. | 1601 | return false; |
1822 | */ | ||
1823 | if (transport_check_aborted_status(cmd, 1)) | ||
1824 | return; | ||
1825 | |||
1826 | /* | ||
1827 | * Determine if IOCTL context caller in requesting the stopping of this | ||
1828 | * command for LUN shutdown purposes. | ||
1829 | */ | ||
1830 | spin_lock_irq(&cmd->t_state_lock); | ||
1831 | if (cmd->transport_state & CMD_T_LUN_STOP) { | ||
1832 | pr_debug("%s:%d CMD_T_LUN_STOP for ITT: 0x%08x\n", | ||
1833 | __func__, __LINE__, cmd->se_tfo->get_task_tag(cmd)); | ||
1834 | |||
1835 | cmd->transport_state &= ~CMD_T_ACTIVE; | ||
1836 | spin_unlock_irq(&cmd->t_state_lock); | ||
1837 | complete(&cmd->transport_lun_stop_comp); | ||
1838 | return; | ||
1839 | } | ||
1840 | /* | ||
1841 | * Determine if frontend context caller is requesting the stopping of | ||
1842 | * this command for frontend exceptions. | ||
1843 | */ | ||
1844 | if (cmd->transport_state & CMD_T_STOP) { | ||
1845 | pr_debug("%s:%d CMD_T_STOP for ITT: 0x%08x\n", | ||
1846 | __func__, __LINE__, | ||
1847 | cmd->se_tfo->get_task_tag(cmd)); | ||
1848 | |||
1849 | spin_unlock_irq(&cmd->t_state_lock); | ||
1850 | complete(&cmd->t_transport_stop_comp); | ||
1851 | return; | ||
1852 | } | ||
1853 | |||
1854 | cmd->t_state = TRANSPORT_PROCESSING; | ||
1855 | spin_unlock_irq(&cmd->t_state_lock); | ||
1856 | |||
1857 | if (dev->dev_task_attr_type != SAM_TASK_ATTR_EMULATED) | ||
1858 | goto execute; | ||
1859 | 1602 | ||
1860 | /* | 1603 | /* |
1861 | * Check for the existence of HEAD_OF_QUEUE, and if true return 1 | 1604 | * Check for the existence of HEAD_OF_QUEUE, and if true return 1 |
@@ -1866,7 +1609,7 @@ void target_execute_cmd(struct se_cmd *cmd) | |||
1866 | pr_debug("Added HEAD_OF_QUEUE for CDB: 0x%02x, " | 1609 | pr_debug("Added HEAD_OF_QUEUE for CDB: 0x%02x, " |
1867 | "se_ordered_id: %u\n", | 1610 | "se_ordered_id: %u\n", |
1868 | cmd->t_task_cdb[0], cmd->se_ordered_id); | 1611 | cmd->t_task_cdb[0], cmd->se_ordered_id); |
1869 | goto execute; | 1612 | return false; |
1870 | case MSG_ORDERED_TAG: | 1613 | case MSG_ORDERED_TAG: |
1871 | atomic_inc(&dev->dev_ordered_sync); | 1614 | atomic_inc(&dev->dev_ordered_sync); |
1872 | smp_mb__after_atomic_inc(); | 1615 | smp_mb__after_atomic_inc(); |
@@ -1880,7 +1623,7 @@ void target_execute_cmd(struct se_cmd *cmd) | |||
1880 | * exist that need to be completed first. | 1623 | * exist that need to be completed first. |
1881 | */ | 1624 | */ |
1882 | if (!atomic_read(&dev->simple_cmds)) | 1625 | if (!atomic_read(&dev->simple_cmds)) |
1883 | goto execute; | 1626 | return false; |
1884 | break; | 1627 | break; |
1885 | default: | 1628 | default: |
1886 | /* | 1629 | /* |
@@ -1891,23 +1634,64 @@ void target_execute_cmd(struct se_cmd *cmd) | |||
1891 | break; | 1634 | break; |
1892 | } | 1635 | } |
1893 | 1636 | ||
1894 | if (atomic_read(&dev->dev_ordered_sync) != 0) { | 1637 | if (atomic_read(&dev->dev_ordered_sync) == 0) |
1895 | spin_lock(&dev->delayed_cmd_lock); | 1638 | return false; |
1896 | list_add_tail(&cmd->se_delayed_node, &dev->delayed_cmd_list); | ||
1897 | spin_unlock(&dev->delayed_cmd_lock); | ||
1898 | 1639 | ||
1899 | pr_debug("Added CDB: 0x%02x Task Attr: 0x%02x to" | 1640 | spin_lock(&dev->delayed_cmd_lock); |
1900 | " delayed CMD list, se_ordered_id: %u\n", | 1641 | list_add_tail(&cmd->se_delayed_node, &dev->delayed_cmd_list); |
1901 | cmd->t_task_cdb[0], cmd->sam_task_attr, | 1642 | spin_unlock(&dev->delayed_cmd_lock); |
1902 | cmd->se_ordered_id); | 1643 | |
1644 | pr_debug("Added CDB: 0x%02x Task Attr: 0x%02x to" | ||
1645 | " delayed CMD list, se_ordered_id: %u\n", | ||
1646 | cmd->t_task_cdb[0], cmd->sam_task_attr, | ||
1647 | cmd->se_ordered_id); | ||
1648 | return true; | ||
1649 | } | ||
1650 | |||
1651 | void target_execute_cmd(struct se_cmd *cmd) | ||
1652 | { | ||
1653 | /* | ||
1654 | * If the received CDB has aleady been aborted stop processing it here. | ||
1655 | */ | ||
1656 | if (transport_check_aborted_status(cmd, 1)) { | ||
1657 | complete(&cmd->transport_lun_stop_comp); | ||
1903 | return; | 1658 | return; |
1904 | } | 1659 | } |
1905 | 1660 | ||
1906 | execute: | ||
1907 | /* | 1661 | /* |
1908 | * Otherwise, no ORDERED task attributes exist.. | 1662 | * Determine if IOCTL context caller in requesting the stopping of this |
1663 | * command for LUN shutdown purposes. | ||
1664 | */ | ||
1665 | spin_lock_irq(&cmd->t_state_lock); | ||
1666 | if (cmd->transport_state & CMD_T_LUN_STOP) { | ||
1667 | pr_debug("%s:%d CMD_T_LUN_STOP for ITT: 0x%08x\n", | ||
1668 | __func__, __LINE__, cmd->se_tfo->get_task_tag(cmd)); | ||
1669 | |||
1670 | cmd->transport_state &= ~CMD_T_ACTIVE; | ||
1671 | spin_unlock_irq(&cmd->t_state_lock); | ||
1672 | complete(&cmd->transport_lun_stop_comp); | ||
1673 | return; | ||
1674 | } | ||
1675 | /* | ||
1676 | * Determine if frontend context caller is requesting the stopping of | ||
1677 | * this command for frontend exceptions. | ||
1909 | */ | 1678 | */ |
1910 | __target_execute_cmd(cmd); | 1679 | if (cmd->transport_state & CMD_T_STOP) { |
1680 | pr_debug("%s:%d CMD_T_STOP for ITT: 0x%08x\n", | ||
1681 | __func__, __LINE__, | ||
1682 | cmd->se_tfo->get_task_tag(cmd)); | ||
1683 | |||
1684 | spin_unlock_irq(&cmd->t_state_lock); | ||
1685 | complete(&cmd->t_transport_stop_comp); | ||
1686 | return; | ||
1687 | } | ||
1688 | |||
1689 | cmd->t_state = TRANSPORT_PROCESSING; | ||
1690 | cmd->transport_state |= CMD_T_ACTIVE; | ||
1691 | spin_unlock_irq(&cmd->t_state_lock); | ||
1692 | |||
1693 | if (!target_handle_task_attr(cmd)) | ||
1694 | __target_execute_cmd(cmd); | ||
1911 | } | 1695 | } |
1912 | EXPORT_SYMBOL(target_execute_cmd); | 1696 | EXPORT_SYMBOL(target_execute_cmd); |
1913 | 1697 | ||
@@ -1946,6 +1730,9 @@ static void transport_complete_task_attr(struct se_cmd *cmd) | |||
1946 | { | 1730 | { |
1947 | struct se_device *dev = cmd->se_dev; | 1731 | struct se_device *dev = cmd->se_dev; |
1948 | 1732 | ||
1733 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) | ||
1734 | return; | ||
1735 | |||
1949 | if (cmd->sam_task_attr == MSG_SIMPLE_TAG) { | 1736 | if (cmd->sam_task_attr == MSG_SIMPLE_TAG) { |
1950 | atomic_dec(&dev->simple_cmds); | 1737 | atomic_dec(&dev->simple_cmds); |
1951 | smp_mb__after_atomic_dec(); | 1738 | smp_mb__after_atomic_dec(); |
@@ -1974,8 +1761,7 @@ static void transport_complete_qf(struct se_cmd *cmd) | |||
1974 | { | 1761 | { |
1975 | int ret = 0; | 1762 | int ret = 0; |
1976 | 1763 | ||
1977 | if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) | 1764 | transport_complete_task_attr(cmd); |
1978 | transport_complete_task_attr(cmd); | ||
1979 | 1765 | ||
1980 | if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) { | 1766 | if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) { |
1981 | ret = cmd->se_tfo->queue_status(cmd); | 1767 | ret = cmd->se_tfo->queue_status(cmd); |
@@ -2033,8 +1819,8 @@ static void target_complete_ok_work(struct work_struct *work) | |||
2033 | * delayed execution list after a HEAD_OF_QUEUE or ORDERED Task | 1819 | * delayed execution list after a HEAD_OF_QUEUE or ORDERED Task |
2034 | * Attribute. | 1820 | * Attribute. |
2035 | */ | 1821 | */ |
2036 | if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) | 1822 | transport_complete_task_attr(cmd); |
2037 | transport_complete_task_attr(cmd); | 1823 | |
2038 | /* | 1824 | /* |
2039 | * Check to schedule QUEUE_FULL work, or execute an existing | 1825 | * Check to schedule QUEUE_FULL work, or execute an existing |
2040 | * cmd->transport_qf_callback() | 1826 | * cmd->transport_qf_callback() |
@@ -2182,9 +1968,10 @@ static void transport_put_cmd(struct se_cmd *cmd) | |||
2182 | unsigned long flags; | 1968 | unsigned long flags; |
2183 | 1969 | ||
2184 | spin_lock_irqsave(&cmd->t_state_lock, flags); | 1970 | spin_lock_irqsave(&cmd->t_state_lock, flags); |
2185 | if (atomic_read(&cmd->t_fe_count)) { | 1971 | if (atomic_read(&cmd->t_fe_count) && |
2186 | if (!atomic_dec_and_test(&cmd->t_fe_count)) | 1972 | !atomic_dec_and_test(&cmd->t_fe_count)) { |
2187 | goto out_busy; | 1973 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
1974 | return; | ||
2188 | } | 1975 | } |
2189 | 1976 | ||
2190 | if (cmd->transport_state & CMD_T_DEV_ACTIVE) { | 1977 | if (cmd->transport_state & CMD_T_DEV_ACTIVE) { |
@@ -2196,56 +1983,7 @@ static void transport_put_cmd(struct se_cmd *cmd) | |||
2196 | transport_free_pages(cmd); | 1983 | transport_free_pages(cmd); |
2197 | transport_release_cmd(cmd); | 1984 | transport_release_cmd(cmd); |
2198 | return; | 1985 | return; |
2199 | out_busy: | ||
2200 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
2201 | } | ||
2202 | |||
2203 | /* | ||
2204 | * transport_generic_map_mem_to_cmd - Use fabric-alloced pages instead of | ||
2205 | * allocating in the core. | ||
2206 | * @cmd: Associated se_cmd descriptor | ||
2207 | * @mem: SGL style memory for TCM WRITE / READ | ||
2208 | * @sg_mem_num: Number of SGL elements | ||
2209 | * @mem_bidi_in: SGL style memory for TCM BIDI READ | ||
2210 | * @sg_mem_bidi_num: Number of BIDI READ SGL elements | ||
2211 | * | ||
2212 | * Return: nonzero return cmd was rejected for -ENOMEM or inproper usage | ||
2213 | * of parameters. | ||
2214 | */ | ||
2215 | int transport_generic_map_mem_to_cmd( | ||
2216 | struct se_cmd *cmd, | ||
2217 | struct scatterlist *sgl, | ||
2218 | u32 sgl_count, | ||
2219 | struct scatterlist *sgl_bidi, | ||
2220 | u32 sgl_bidi_count) | ||
2221 | { | ||
2222 | if (!sgl || !sgl_count) | ||
2223 | return 0; | ||
2224 | |||
2225 | /* | ||
2226 | * Reject SCSI data overflow with map_mem_to_cmd() as incoming | ||
2227 | * scatterlists already have been set to follow what the fabric | ||
2228 | * passes for the original expected data transfer length. | ||
2229 | */ | ||
2230 | if (cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { | ||
2231 | pr_warn("Rejecting SCSI DATA overflow for fabric using" | ||
2232 | " SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC\n"); | ||
2233 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
2234 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
2235 | return -EINVAL; | ||
2236 | } | ||
2237 | |||
2238 | cmd->t_data_sg = sgl; | ||
2239 | cmd->t_data_nents = sgl_count; | ||
2240 | |||
2241 | if (sgl_bidi && sgl_bidi_count) { | ||
2242 | cmd->t_bidi_data_sg = sgl_bidi; | ||
2243 | cmd->t_bidi_data_nents = sgl_bidi_count; | ||
2244 | } | ||
2245 | cmd->se_cmd_flags |= SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC; | ||
2246 | return 0; | ||
2247 | } | 1986 | } |
2248 | EXPORT_SYMBOL(transport_generic_map_mem_to_cmd); | ||
2249 | 1987 | ||
2250 | void *transport_kmap_data_sg(struct se_cmd *cmd) | 1988 | void *transport_kmap_data_sg(struct se_cmd *cmd) |
2251 | { | 1989 | { |
@@ -2267,10 +2005,8 @@ void *transport_kmap_data_sg(struct se_cmd *cmd) | |||
2267 | 2005 | ||
2268 | /* >1 page. use vmap */ | 2006 | /* >1 page. use vmap */ |
2269 | pages = kmalloc(sizeof(*pages) * cmd->t_data_nents, GFP_KERNEL); | 2007 | pages = kmalloc(sizeof(*pages) * cmd->t_data_nents, GFP_KERNEL); |
2270 | if (!pages) { | 2008 | if (!pages) |
2271 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
2272 | return NULL; | 2009 | return NULL; |
2273 | } | ||
2274 | 2010 | ||
2275 | /* convert sg[] to pages[] */ | 2011 | /* convert sg[] to pages[] */ |
2276 | for_each_sg(cmd->t_data_sg, sg, cmd->t_data_nents, i) { | 2012 | for_each_sg(cmd->t_data_sg, sg, cmd->t_data_nents, i) { |
@@ -2279,10 +2015,8 @@ void *transport_kmap_data_sg(struct se_cmd *cmd) | |||
2279 | 2015 | ||
2280 | cmd->t_data_vmap = vmap(pages, cmd->t_data_nents, VM_MAP, PAGE_KERNEL); | 2016 | cmd->t_data_vmap = vmap(pages, cmd->t_data_nents, VM_MAP, PAGE_KERNEL); |
2281 | kfree(pages); | 2017 | kfree(pages); |
2282 | if (!cmd->t_data_vmap) { | 2018 | if (!cmd->t_data_vmap) |
2283 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
2284 | return NULL; | 2019 | return NULL; |
2285 | } | ||
2286 | 2020 | ||
2287 | return cmd->t_data_vmap + cmd->t_data_sg[0].offset; | 2021 | return cmd->t_data_vmap + cmd->t_data_sg[0].offset; |
2288 | } | 2022 | } |
@@ -2348,7 +2082,8 @@ out: | |||
2348 | * might not have the payload yet, so notify the fabric via a call to | 2082 | * might not have the payload yet, so notify the fabric via a call to |
2349 | * ->write_pending instead. Otherwise place it on the execution queue. | 2083 | * ->write_pending instead. Otherwise place it on the execution queue. |
2350 | */ | 2084 | */ |
2351 | int transport_generic_new_cmd(struct se_cmd *cmd) | 2085 | sense_reason_t |
2086 | transport_generic_new_cmd(struct se_cmd *cmd) | ||
2352 | { | 2087 | { |
2353 | int ret = 0; | 2088 | int ret = 0; |
2354 | 2089 | ||
@@ -2361,7 +2096,7 @@ int transport_generic_new_cmd(struct se_cmd *cmd) | |||
2361 | cmd->data_length) { | 2096 | cmd->data_length) { |
2362 | ret = transport_generic_get_mem(cmd); | 2097 | ret = transport_generic_get_mem(cmd); |
2363 | if (ret < 0) | 2098 | if (ret < 0) |
2364 | goto out_fail; | 2099 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2365 | } | 2100 | } |
2366 | 2101 | ||
2367 | atomic_inc(&cmd->t_fe_count); | 2102 | atomic_inc(&cmd->t_fe_count); |
@@ -2387,14 +2122,11 @@ int transport_generic_new_cmd(struct se_cmd *cmd) | |||
2387 | if (ret == -EAGAIN || ret == -ENOMEM) | 2122 | if (ret == -EAGAIN || ret == -ENOMEM) |
2388 | goto queue_full; | 2123 | goto queue_full; |
2389 | 2124 | ||
2390 | if (ret < 0) | 2125 | /* fabric drivers should only return -EAGAIN or -ENOMEM as error */ |
2391 | return ret; | 2126 | WARN_ON(ret); |
2392 | return 1; | 2127 | |
2128 | return (!ret) ? 0 : TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
2393 | 2129 | ||
2394 | out_fail: | ||
2395 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
2396 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
2397 | return -EINVAL; | ||
2398 | queue_full: | 2130 | queue_full: |
2399 | pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd); | 2131 | pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd); |
2400 | cmd->t_state = TRANSPORT_COMPLETE_QF_WP; | 2132 | cmd->t_state = TRANSPORT_COMPLETE_QF_WP; |
@@ -2838,21 +2570,9 @@ static int transport_get_sense_codes( | |||
2838 | return 0; | 2570 | return 0; |
2839 | } | 2571 | } |
2840 | 2572 | ||
2841 | static int transport_set_sense_codes( | 2573 | int |
2842 | struct se_cmd *cmd, | 2574 | transport_send_check_condition_and_sense(struct se_cmd *cmd, |
2843 | u8 asc, | 2575 | sense_reason_t reason, int from_transport) |
2844 | u8 ascq) | ||
2845 | { | ||
2846 | cmd->scsi_asc = asc; | ||
2847 | cmd->scsi_ascq = ascq; | ||
2848 | |||
2849 | return 0; | ||
2850 | } | ||
2851 | |||
2852 | int transport_send_check_condition_and_sense( | ||
2853 | struct se_cmd *cmd, | ||
2854 | u8 reason, | ||
2855 | int from_transport) | ||
2856 | { | 2576 | { |
2857 | unsigned char *buffer = cmd->sense_buffer; | 2577 | unsigned char *buffer = cmd->sense_buffer; |
2858 | unsigned long flags; | 2578 | unsigned long flags; |
@@ -2877,6 +2597,16 @@ int transport_send_check_condition_and_sense( | |||
2877 | * SENSE KEY values from include/scsi/scsi.h | 2597 | * SENSE KEY values from include/scsi/scsi.h |
2878 | */ | 2598 | */ |
2879 | switch (reason) { | 2599 | switch (reason) { |
2600 | case TCM_NO_SENSE: | ||
2601 | /* CURRENT ERROR */ | ||
2602 | buffer[0] = 0x70; | ||
2603 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2604 | /* Not Ready */ | ||
2605 | buffer[SPC_SENSE_KEY_OFFSET] = NOT_READY; | ||
2606 | /* NO ADDITIONAL SENSE INFORMATION */ | ||
2607 | buffer[SPC_ASC_KEY_OFFSET] = 0; | ||
2608 | buffer[SPC_ASCQ_KEY_OFFSET] = 0; | ||
2609 | break; | ||
2880 | case TCM_NON_EXISTENT_LUN: | 2610 | case TCM_NON_EXISTENT_LUN: |
2881 | /* CURRENT ERROR */ | 2611 | /* CURRENT ERROR */ |
2882 | buffer[0] = 0x70; | 2612 | buffer[0] = 0x70; |
@@ -3023,7 +2753,7 @@ int transport_send_check_condition_and_sense( | |||
3023 | /* ILLEGAL REQUEST */ | 2753 | /* ILLEGAL REQUEST */ |
3024 | buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; | 2754 | buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; |
3025 | /* LOGICAL UNIT COMMUNICATION FAILURE */ | 2755 | /* LOGICAL UNIT COMMUNICATION FAILURE */ |
3026 | buffer[SPC_ASC_KEY_OFFSET] = 0x80; | 2756 | buffer[SPC_ASC_KEY_OFFSET] = 0x08; |
3027 | break; | 2757 | break; |
3028 | } | 2758 | } |
3029 | /* | 2759 | /* |
@@ -3043,23 +2773,19 @@ EXPORT_SYMBOL(transport_send_check_condition_and_sense); | |||
3043 | 2773 | ||
3044 | int transport_check_aborted_status(struct se_cmd *cmd, int send_status) | 2774 | int transport_check_aborted_status(struct se_cmd *cmd, int send_status) |
3045 | { | 2775 | { |
3046 | int ret = 0; | 2776 | if (!(cmd->transport_state & CMD_T_ABORTED)) |
2777 | return 0; | ||
3047 | 2778 | ||
3048 | if (cmd->transport_state & CMD_T_ABORTED) { | 2779 | if (!send_status || (cmd->se_cmd_flags & SCF_SENT_DELAYED_TAS)) |
3049 | if (!send_status || | 2780 | return 1; |
3050 | (cmd->se_cmd_flags & SCF_SENT_DELAYED_TAS)) | ||
3051 | return 1; | ||
3052 | 2781 | ||
3053 | pr_debug("Sending delayed SAM_STAT_TASK_ABORTED" | 2782 | pr_debug("Sending delayed SAM_STAT_TASK_ABORTED status for CDB: 0x%02x ITT: 0x%08x\n", |
3054 | " status for CDB: 0x%02x ITT: 0x%08x\n", | 2783 | cmd->t_task_cdb[0], cmd->se_tfo->get_task_tag(cmd)); |
3055 | cmd->t_task_cdb[0], | ||
3056 | cmd->se_tfo->get_task_tag(cmd)); | ||
3057 | 2784 | ||
3058 | cmd->se_cmd_flags |= SCF_SENT_DELAYED_TAS; | 2785 | cmd->se_cmd_flags |= SCF_SENT_DELAYED_TAS; |
3059 | cmd->se_tfo->queue_status(cmd); | 2786 | cmd->se_tfo->queue_status(cmd); |
3060 | ret = 1; | 2787 | |
3061 | } | 2788 | return 1; |
3062 | return ret; | ||
3063 | } | 2789 | } |
3064 | EXPORT_SYMBOL(transport_check_aborted_status); | 2790 | EXPORT_SYMBOL(transport_check_aborted_status); |
3065 | 2791 | ||
@@ -3068,7 +2794,7 @@ void transport_send_task_abort(struct se_cmd *cmd) | |||
3068 | unsigned long flags; | 2794 | unsigned long flags; |
3069 | 2795 | ||
3070 | spin_lock_irqsave(&cmd->t_state_lock, flags); | 2796 | spin_lock_irqsave(&cmd->t_state_lock, flags); |
3071 | if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) { | 2797 | if (cmd->se_cmd_flags & (SCF_SENT_CHECK_CONDITION | SCF_SENT_DELAYED_TAS)) { |
3072 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 2798 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
3073 | return; | 2799 | return; |
3074 | } | 2800 | } |
@@ -3088,6 +2814,8 @@ void transport_send_task_abort(struct se_cmd *cmd) | |||
3088 | } | 2814 | } |
3089 | cmd->scsi_status = SAM_STAT_TASK_ABORTED; | 2815 | cmd->scsi_status = SAM_STAT_TASK_ABORTED; |
3090 | 2816 | ||
2817 | transport_lun_remove_cmd(cmd); | ||
2818 | |||
3091 | pr_debug("Setting SAM_STAT_TASK_ABORTED status for CDB: 0x%02x," | 2819 | pr_debug("Setting SAM_STAT_TASK_ABORTED status for CDB: 0x%02x," |
3092 | " ITT: 0x%08x\n", cmd->t_task_cdb[0], | 2820 | " ITT: 0x%08x\n", cmd->t_task_cdb[0], |
3093 | cmd->se_tfo->get_task_tag(cmd)); | 2821 | cmd->se_tfo->get_task_tag(cmd)); |
diff --git a/drivers/target/target_core_ua.c b/drivers/target/target_core_ua.c index 6666a0c74f60..bf0e390ce2d7 100644 --- a/drivers/target/target_core_ua.c +++ b/drivers/target/target_core_ua.c | |||
@@ -3,8 +3,7 @@ | |||
3 | * | 3 | * |
4 | * This file contains logic for SPC-3 Unit Attention emulation | 4 | * This file contains logic for SPC-3 Unit Attention emulation |
5 | * | 5 | * |
6 | * Copyright (c) 2009,2010 Rising Tide Systems | 6 | * (c) Copyright 2009-2012 RisingTide Systems LLC. |
7 | * Copyright (c) 2009,2010 Linux-iSCSI.org | ||
8 | * | 7 | * |
9 | * Nicholas A. Bellinger <nab@kernel.org> | 8 | * Nicholas A. Bellinger <nab@kernel.org> |
10 | * | 9 | * |
@@ -38,9 +37,8 @@ | |||
38 | #include "target_core_pr.h" | 37 | #include "target_core_pr.h" |
39 | #include "target_core_ua.h" | 38 | #include "target_core_ua.h" |
40 | 39 | ||
41 | int core_scsi3_ua_check( | 40 | sense_reason_t |
42 | struct se_cmd *cmd, | 41 | target_scsi3_ua_check(struct se_cmd *cmd) |
43 | unsigned char *cdb) | ||
44 | { | 42 | { |
45 | struct se_dev_entry *deve; | 43 | struct se_dev_entry *deve; |
46 | struct se_session *sess = cmd->se_sess; | 44 | struct se_session *sess = cmd->se_sess; |
@@ -71,16 +69,14 @@ int core_scsi3_ua_check( | |||
71 | * was received, then the device server shall process the command | 69 | * was received, then the device server shall process the command |
72 | * and either: | 70 | * and either: |
73 | */ | 71 | */ |
74 | switch (cdb[0]) { | 72 | switch (cmd->t_task_cdb[0]) { |
75 | case INQUIRY: | 73 | case INQUIRY: |
76 | case REPORT_LUNS: | 74 | case REPORT_LUNS: |
77 | case REQUEST_SENSE: | 75 | case REQUEST_SENSE: |
78 | return 0; | 76 | return 0; |
79 | default: | 77 | default: |
80 | return -EINVAL; | 78 | return TCM_CHECK_CONDITION_UNIT_ATTENTION; |
81 | } | 79 | } |
82 | |||
83 | return -EINVAL; | ||
84 | } | 80 | } |
85 | 81 | ||
86 | int core_scsi3_ua_allocate( | 82 | int core_scsi3_ua_allocate( |
@@ -237,7 +233,7 @@ void core_scsi3_ua_for_check_condition( | |||
237 | * highest priority UNIT_ATTENTION and ASC/ASCQ without | 233 | * highest priority UNIT_ATTENTION and ASC/ASCQ without |
238 | * clearing it. | 234 | * clearing it. |
239 | */ | 235 | */ |
240 | if (dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl != 0) { | 236 | if (dev->dev_attrib.emulate_ua_intlck_ctrl != 0) { |
241 | *asc = ua->ua_asc; | 237 | *asc = ua->ua_asc; |
242 | *ascq = ua->ua_ascq; | 238 | *ascq = ua->ua_ascq; |
243 | break; | 239 | break; |
@@ -265,8 +261,8 @@ void core_scsi3_ua_for_check_condition( | |||
265 | " INTLCK_CTRL: %d, mapped LUN: %u, got CDB: 0x%02x" | 261 | " INTLCK_CTRL: %d, mapped LUN: %u, got CDB: 0x%02x" |
266 | " reported ASC: 0x%02x, ASCQ: 0x%02x\n", | 262 | " reported ASC: 0x%02x, ASCQ: 0x%02x\n", |
267 | nacl->se_tpg->se_tpg_tfo->get_fabric_name(), | 263 | nacl->se_tpg->se_tpg_tfo->get_fabric_name(), |
268 | (dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl != 0) ? "Reporting" : | 264 | (dev->dev_attrib.emulate_ua_intlck_ctrl != 0) ? "Reporting" : |
269 | "Releasing", dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl, | 265 | "Releasing", dev->dev_attrib.emulate_ua_intlck_ctrl, |
270 | cmd->orig_fe_lun, cmd->t_task_cdb[0], *asc, *ascq); | 266 | cmd->orig_fe_lun, cmd->t_task_cdb[0], *asc, *ascq); |
271 | } | 267 | } |
272 | 268 | ||
diff --git a/drivers/target/target_core_ua.h b/drivers/target/target_core_ua.h index 6e6b03460a1a..0204952fe4d3 100644 --- a/drivers/target/target_core_ua.h +++ b/drivers/target/target_core_ua.h | |||
@@ -26,7 +26,7 @@ | |||
26 | 26 | ||
27 | extern struct kmem_cache *se_ua_cache; | 27 | extern struct kmem_cache *se_ua_cache; |
28 | 28 | ||
29 | extern int core_scsi3_ua_check(struct se_cmd *, unsigned char *); | 29 | extern sense_reason_t target_scsi3_ua_check(struct se_cmd *); |
30 | extern int core_scsi3_ua_allocate(struct se_node_acl *, u32, u8, u8); | 30 | extern int core_scsi3_ua_allocate(struct se_node_acl *, u32, u8, u8); |
31 | extern void core_scsi3_ua_release_all(struct se_dev_entry *); | 31 | extern void core_scsi3_ua_release_all(struct se_dev_entry *); |
32 | extern void core_scsi3_ua_for_check_condition(struct se_cmd *, u8 *, u8 *); | 32 | extern void core_scsi3_ua_for_check_condition(struct se_cmd *, u8 *, u8 *); |
diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c index 9585010964ec..6659dd36e806 100644 --- a/drivers/target/tcm_fc/tfc_sess.c +++ b/drivers/target/tcm_fc/tfc_sess.c | |||
@@ -355,11 +355,11 @@ static int ft_prli_locked(struct fc_rport_priv *rdata, u32 spp_len, | |||
355 | 355 | ||
356 | tport = ft_tport_create(rdata->local_port); | 356 | tport = ft_tport_create(rdata->local_port); |
357 | if (!tport) | 357 | if (!tport) |
358 | return 0; /* not a target for this local port */ | 358 | goto not_target; /* not a target for this local port */ |
359 | 359 | ||
360 | acl = ft_acl_get(tport->tpg, rdata); | 360 | acl = ft_acl_get(tport->tpg, rdata); |
361 | if (!acl) | 361 | if (!acl) |
362 | return 0; | 362 | goto not_target; /* no target for this remote */ |
363 | 363 | ||
364 | if (!rspp) | 364 | if (!rspp) |
365 | goto fill; | 365 | goto fill; |
@@ -396,12 +396,18 @@ static int ft_prli_locked(struct fc_rport_priv *rdata, u32 spp_len, | |||
396 | 396 | ||
397 | /* | 397 | /* |
398 | * OR in our service parameters with other provider (initiator), if any. | 398 | * OR in our service parameters with other provider (initiator), if any. |
399 | * TBD XXX - indicate RETRY capability? | ||
400 | */ | 399 | */ |
401 | fill: | 400 | fill: |
402 | fcp_parm = ntohl(spp->spp_params); | 401 | fcp_parm = ntohl(spp->spp_params); |
402 | fcp_parm &= ~FCP_SPPF_RETRY; | ||
403 | spp->spp_params = htonl(fcp_parm | FCP_SPPF_TARG_FCN); | 403 | spp->spp_params = htonl(fcp_parm | FCP_SPPF_TARG_FCN); |
404 | return FC_SPP_RESP_ACK; | 404 | return FC_SPP_RESP_ACK; |
405 | |||
406 | not_target: | ||
407 | fcp_parm = ntohl(spp->spp_params); | ||
408 | fcp_parm &= ~FCP_SPPF_TARG_FCN; | ||
409 | spp->spp_params = htonl(fcp_parm); | ||
410 | return 0; | ||
405 | } | 411 | } |
406 | 412 | ||
407 | /** | 413 | /** |
@@ -430,7 +436,6 @@ static void ft_sess_rcu_free(struct rcu_head *rcu) | |||
430 | { | 436 | { |
431 | struct ft_sess *sess = container_of(rcu, struct ft_sess, rcu); | 437 | struct ft_sess *sess = container_of(rcu, struct ft_sess, rcu); |
432 | 438 | ||
433 | transport_deregister_session(sess->se_sess); | ||
434 | kfree(sess); | 439 | kfree(sess); |
435 | } | 440 | } |
436 | 441 | ||
@@ -438,6 +443,7 @@ static void ft_sess_free(struct kref *kref) | |||
438 | { | 443 | { |
439 | struct ft_sess *sess = container_of(kref, struct ft_sess, kref); | 444 | struct ft_sess *sess = container_of(kref, struct ft_sess, kref); |
440 | 445 | ||
446 | transport_deregister_session(sess->se_sess); | ||
441 | call_rcu(&sess->rcu, ft_sess_rcu_free); | 447 | call_rcu(&sess->rcu, ft_sess_rcu_free); |
442 | } | 448 | } |
443 | 449 | ||