target: move transport ID handling to the core
Now that struct se_portal_group contains a protocol identifier field we can take all the code to format an parse protocol identifiers in CDBs into common code instead of leaving this to low-level drivers. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
2aeeafae6b
commit
2650d71e24
@ -60,8 +60,6 @@ def tcm_mod_build_FC_include(fabric_mod_dir_var, fabric_mod_name):
|
||||
buf += "};\n"
|
||||
buf += "\n"
|
||||
buf += "struct " + fabric_mod_name + "_lport {\n"
|
||||
buf += " /* SCSI protocol the lport is providing */\n"
|
||||
buf += " u8 lport_proto_id;\n"
|
||||
buf += " /* Binary World Wide unique Port Name for FC Target Lport */\n"
|
||||
buf += " u64 lport_wwpn;\n"
|
||||
buf += " /* ASCII formatted WWPN for FC Target Lport */\n"
|
||||
@ -105,8 +103,6 @@ def tcm_mod_build_SAS_include(fabric_mod_dir_var, fabric_mod_name):
|
||||
buf += " struct se_portal_group se_tpg;\n"
|
||||
buf += "};\n\n"
|
||||
buf += "struct " + fabric_mod_name + "_tport {\n"
|
||||
buf += " /* SCSI protocol the tport is providing */\n"
|
||||
buf += " u8 tport_proto_id;\n"
|
||||
buf += " /* Binary World Wide unique Port Name for SAS Target port */\n"
|
||||
buf += " u64 tport_wwpn;\n"
|
||||
buf += " /* ASCII formatted WWPN for SAS Target port */\n"
|
||||
@ -150,8 +146,6 @@ def tcm_mod_build_iSCSI_include(fabric_mod_dir_var, fabric_mod_name):
|
||||
buf += " struct se_portal_group se_tpg;\n"
|
||||
buf += "};\n\n"
|
||||
buf += "struct " + fabric_mod_name + "_tport {\n"
|
||||
buf += " /* SCSI protocol the tport is providing */\n"
|
||||
buf += " u8 tport_proto_id;\n"
|
||||
buf += " /* ASCII formatted TargetName for IQN */\n"
|
||||
buf += " char tport_name[" + fabric_mod_name.upper() + "_NAMELEN];\n"
|
||||
buf += " /* Returned by " + fabric_mod_name + "_make_tport() */\n"
|
||||
@ -303,9 +297,6 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name):
|
||||
buf += " .get_fabric_name = " + fabric_mod_name + "_get_fabric_name,\n"
|
||||
buf += " .tpg_get_wwn = " + fabric_mod_name + "_get_fabric_wwn,\n"
|
||||
buf += " .tpg_get_tag = " + fabric_mod_name + "_get_tag,\n"
|
||||
buf += " .tpg_get_pr_transport_id = " + fabric_mod_name + "_get_pr_transport_id,\n"
|
||||
buf += " .tpg_get_pr_transport_id_len = " + fabric_mod_name + "_get_pr_transport_id_len,\n"
|
||||
buf += " .tpg_parse_pr_out_transport_id = " + fabric_mod_name + "_parse_pr_out_transport_id,\n"
|
||||
buf += " .tpg_check_demo_mode = " + fabric_mod_name + "_check_false,\n"
|
||||
buf += " .tpg_check_demo_mode_cache = " + fabric_mod_name + "_check_true,\n"
|
||||
buf += " .tpg_check_demo_mode_write_protect = " + fabric_mod_name + "_check_true,\n"
|
||||
@ -478,118 +469,6 @@ def tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir_var, fabric_mod_name):
|
||||
buf += "}\n\n"
|
||||
bufi += "u16 " + fabric_mod_name + "_get_tag(struct se_portal_group *);\n"
|
||||
|
||||
if re.search('get_pr_transport_id\)\(', fo):
|
||||
buf += "u32 " + fabric_mod_name + "_get_pr_transport_id(\n"
|
||||
buf += " struct se_portal_group *se_tpg,\n"
|
||||
buf += " struct se_node_acl *se_nacl,\n"
|
||||
buf += " struct t10_pr_registration *pr_reg,\n"
|
||||
buf += " int *format_code,\n"
|
||||
buf += " unsigned char *buf)\n"
|
||||
buf += "{\n"
|
||||
buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
|
||||
buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
|
||||
buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n"
|
||||
buf += " int ret = 0;\n\n"
|
||||
buf += " switch (" + fabric_mod_port + "->" + fabric_mod_port + "_proto_id) {\n"
|
||||
if proto_ident == "FC":
|
||||
buf += " case SCSI_PROTOCOL_FCP:\n"
|
||||
buf += " default:\n"
|
||||
buf += " ret = fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg,\n"
|
||||
buf += " format_code, buf);\n"
|
||||
buf += " break;\n"
|
||||
elif proto_ident == "SAS":
|
||||
buf += " case SCSI_PROTOCOL_SAS:\n"
|
||||
buf += " default:\n"
|
||||
buf += " ret = sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,\n"
|
||||
buf += " format_code, buf);\n"
|
||||
buf += " break;\n"
|
||||
elif proto_ident == "iSCSI":
|
||||
buf += " case SCSI_PROTOCOL_ISCSI:\n"
|
||||
buf += " default:\n"
|
||||
buf += " ret = iscsi_get_pr_transport_id(se_tpg, se_nacl, pr_reg,\n"
|
||||
buf += " format_code, buf);\n"
|
||||
buf += " break;\n"
|
||||
|
||||
buf += " }\n\n"
|
||||
buf += " return ret;\n"
|
||||
buf += "}\n\n"
|
||||
bufi += "u32 " + fabric_mod_name + "_get_pr_transport_id(struct se_portal_group *,\n"
|
||||
bufi += " struct se_node_acl *, struct t10_pr_registration *,\n"
|
||||
bufi += " int *, unsigned char *);\n"
|
||||
|
||||
if re.search('get_pr_transport_id_len\)\(', fo):
|
||||
buf += "u32 " + fabric_mod_name + "_get_pr_transport_id_len(\n"
|
||||
buf += " struct se_portal_group *se_tpg,\n"
|
||||
buf += " struct se_node_acl *se_nacl,\n"
|
||||
buf += " struct t10_pr_registration *pr_reg,\n"
|
||||
buf += " int *format_code)\n"
|
||||
buf += "{\n"
|
||||
buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
|
||||
buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
|
||||
buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n"
|
||||
buf += " int ret = 0;\n\n"
|
||||
buf += " switch (" + fabric_mod_port + "->" + fabric_mod_port + "_proto_id) {\n"
|
||||
if proto_ident == "FC":
|
||||
buf += " case SCSI_PROTOCOL_FCP:\n"
|
||||
buf += " default:\n"
|
||||
buf += " ret = fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,\n"
|
||||
buf += " format_code);\n"
|
||||
buf += " break;\n"
|
||||
elif proto_ident == "SAS":
|
||||
buf += " case SCSI_PROTOCOL_SAS:\n"
|
||||
buf += " default:\n"
|
||||
buf += " ret = sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,\n"
|
||||
buf += " format_code);\n"
|
||||
buf += " break;\n"
|
||||
elif proto_ident == "iSCSI":
|
||||
buf += " case SCSI_PROTOCOL_ISCSI:\n"
|
||||
buf += " default:\n"
|
||||
buf += " ret = iscsi_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,\n"
|
||||
buf += " format_code);\n"
|
||||
buf += " break;\n"
|
||||
|
||||
|
||||
buf += " }\n\n"
|
||||
buf += " return ret;\n"
|
||||
buf += "}\n\n"
|
||||
bufi += "u32 " + fabric_mod_name + "_get_pr_transport_id_len(struct se_portal_group *,\n"
|
||||
bufi += " struct se_node_acl *, struct t10_pr_registration *,\n"
|
||||
bufi += " int *);\n"
|
||||
|
||||
if re.search('parse_pr_out_transport_id\)\(', fo):
|
||||
buf += "char *" + fabric_mod_name + "_parse_pr_out_transport_id(\n"
|
||||
buf += " struct se_portal_group *se_tpg,\n"
|
||||
buf += " const char *buf,\n"
|
||||
buf += " u32 *out_tid_len,\n"
|
||||
buf += " char **port_nexus_ptr)\n"
|
||||
buf += "{\n"
|
||||
buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
|
||||
buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
|
||||
buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n"
|
||||
buf += " char *tid = NULL;\n\n"
|
||||
buf += " switch (" + fabric_mod_port + "->" + fabric_mod_port + "_proto_id) {\n"
|
||||
if proto_ident == "FC":
|
||||
buf += " case SCSI_PROTOCOL_FCP:\n"
|
||||
buf += " default:\n"
|
||||
buf += " tid = fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,\n"
|
||||
buf += " port_nexus_ptr);\n"
|
||||
elif proto_ident == "SAS":
|
||||
buf += " case SCSI_PROTOCOL_SAS:\n"
|
||||
buf += " default:\n"
|
||||
buf += " tid = sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,\n"
|
||||
buf += " port_nexus_ptr);\n"
|
||||
elif proto_ident == "iSCSI":
|
||||
buf += " case SCSI_PROTOCOL_ISCSI:\n"
|
||||
buf += " default:\n"
|
||||
buf += " tid = iscsi_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,\n"
|
||||
buf += " port_nexus_ptr);\n"
|
||||
|
||||
buf += " }\n\n"
|
||||
buf += " return tid;\n"
|
||||
buf += "}\n\n"
|
||||
bufi += "char *" + fabric_mod_name + "_parse_pr_out_transport_id(struct se_portal_group *,\n"
|
||||
bufi += " const char *, u32 *, char **);\n"
|
||||
|
||||
if re.search('tpg_get_inst_index\)\(', fo):
|
||||
buf += "u32 " + fabric_mod_name + "_tpg_get_inst_index(struct se_portal_group *se_tpg)\n"
|
||||
buf += "{\n"
|
||||
|
@ -3406,42 +3406,6 @@ static u16 srpt_get_tag(struct se_portal_group *tpg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u32 srpt_get_pr_transport_id(struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code, unsigned char *buf)
|
||||
{
|
||||
struct srpt_node_acl *nacl;
|
||||
struct spc_rdma_transport_id *tr_id;
|
||||
|
||||
nacl = container_of(se_nacl, struct srpt_node_acl, nacl);
|
||||
tr_id = (void *)buf;
|
||||
tr_id->protocol_identifier = SCSI_TRANSPORTID_PROTOCOLID_SRP;
|
||||
memcpy(tr_id->i_port_id, nacl->i_port_id, sizeof(tr_id->i_port_id));
|
||||
return sizeof(*tr_id);
|
||||
}
|
||||
|
||||
static u32 srpt_get_pr_transport_id_len(struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code)
|
||||
{
|
||||
*format_code = 0;
|
||||
return sizeof(struct spc_rdma_transport_id);
|
||||
}
|
||||
|
||||
static char *srpt_parse_pr_out_transport_id(struct se_portal_group *se_tpg,
|
||||
const char *buf, u32 *out_tid_len,
|
||||
char **port_nexus_ptr)
|
||||
{
|
||||
struct spc_rdma_transport_id *tr_id;
|
||||
|
||||
*port_nexus_ptr = NULL;
|
||||
*out_tid_len = sizeof(struct spc_rdma_transport_id);
|
||||
tr_id = (void *)buf;
|
||||
return (char *)tr_id->i_port_id;
|
||||
}
|
||||
|
||||
static u32 srpt_tpg_get_inst_index(struct se_portal_group *se_tpg)
|
||||
{
|
||||
return 1;
|
||||
@ -3860,9 +3824,6 @@ static const struct target_core_fabric_ops srpt_template = {
|
||||
.get_fabric_name = srpt_get_fabric_name,
|
||||
.tpg_get_wwn = srpt_get_fabric_wwn,
|
||||
.tpg_get_tag = srpt_get_tag,
|
||||
.tpg_get_pr_transport_id = srpt_get_pr_transport_id,
|
||||
.tpg_get_pr_transport_id_len = srpt_get_pr_transport_id_len,
|
||||
.tpg_parse_pr_out_transport_id = srpt_parse_pr_out_transport_id,
|
||||
.tpg_check_demo_mode = srpt_check_false,
|
||||
.tpg_check_demo_mode_cache = srpt_check_true,
|
||||
.tpg_check_demo_mode_write_protect = srpt_check_true,
|
||||
|
@ -422,22 +422,4 @@ struct srpt_node_acl {
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
/*
|
||||
* SRP-releated SCSI persistent reservation definitions.
|
||||
*
|
||||
* See also SPC4r28, section 7.6.1 (Protocol specific parameters introduction).
|
||||
* See also SPC4r28, section 7.6.4.5 (TransportID for initiator ports using
|
||||
* SCSI over an RDMA interface).
|
||||
*/
|
||||
|
||||
enum {
|
||||
SCSI_TRANSPORTID_PROTOCOLID_SRP = 4,
|
||||
};
|
||||
|
||||
struct spc_rdma_transport_id {
|
||||
uint8_t protocol_identifier;
|
||||
uint8_t reserved[7];
|
||||
uint8_t i_port_id[16];
|
||||
};
|
||||
|
||||
#endif /* IB_SRPT_H */
|
||||
|
@ -206,73 +206,6 @@ static u16 tcm_qla2xxx_get_tag(struct se_portal_group *se_tpg)
|
||||
return tpg->lport_tpgt;
|
||||
}
|
||||
|
||||
static u32 tcm_qla2xxx_get_pr_transport_id(
|
||||
struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code,
|
||||
unsigned char *buf)
|
||||
{
|
||||
struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
|
||||
struct tcm_qla2xxx_tpg, se_tpg);
|
||||
struct tcm_qla2xxx_lport *lport = tpg->lport;
|
||||
int ret = 0;
|
||||
|
||||
switch (lport->lport_proto_id) {
|
||||
case SCSI_PROTOCOL_FCP:
|
||||
default:
|
||||
ret = fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
|
||||
format_code, buf);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u32 tcm_qla2xxx_get_pr_transport_id_len(
|
||||
struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code)
|
||||
{
|
||||
struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
|
||||
struct tcm_qla2xxx_tpg, se_tpg);
|
||||
struct tcm_qla2xxx_lport *lport = tpg->lport;
|
||||
int ret = 0;
|
||||
|
||||
switch (lport->lport_proto_id) {
|
||||
case SCSI_PROTOCOL_FCP:
|
||||
default:
|
||||
ret = fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
|
||||
format_code);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *tcm_qla2xxx_parse_pr_out_transport_id(
|
||||
struct se_portal_group *se_tpg,
|
||||
const char *buf,
|
||||
u32 *out_tid_len,
|
||||
char **port_nexus_ptr)
|
||||
{
|
||||
struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
|
||||
struct tcm_qla2xxx_tpg, se_tpg);
|
||||
struct tcm_qla2xxx_lport *lport = tpg->lport;
|
||||
char *tid = NULL;
|
||||
|
||||
switch (lport->lport_proto_id) {
|
||||
case SCSI_PROTOCOL_FCP:
|
||||
default:
|
||||
tid = fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
|
||||
port_nexus_ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
return tid;
|
||||
}
|
||||
|
||||
static int tcm_qla2xxx_check_demo_mode(struct se_portal_group *se_tpg)
|
||||
{
|
||||
struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
|
||||
@ -1913,9 +1846,6 @@ static const struct target_core_fabric_ops tcm_qla2xxx_ops = {
|
||||
.get_fabric_name = tcm_qla2xxx_get_fabric_name,
|
||||
.tpg_get_wwn = tcm_qla2xxx_get_fabric_wwn,
|
||||
.tpg_get_tag = tcm_qla2xxx_get_tag,
|
||||
.tpg_get_pr_transport_id = tcm_qla2xxx_get_pr_transport_id,
|
||||
.tpg_get_pr_transport_id_len = tcm_qla2xxx_get_pr_transport_id_len,
|
||||
.tpg_parse_pr_out_transport_id = tcm_qla2xxx_parse_pr_out_transport_id,
|
||||
.tpg_check_demo_mode = tcm_qla2xxx_check_demo_mode,
|
||||
.tpg_check_demo_mode_cache = tcm_qla2xxx_check_demo_mode_cache,
|
||||
.tpg_check_demo_mode_write_protect =
|
||||
@ -1963,9 +1893,6 @@ static const struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = {
|
||||
.get_fabric_name = tcm_qla2xxx_npiv_get_fabric_name,
|
||||
.tpg_get_wwn = tcm_qla2xxx_get_fabric_wwn,
|
||||
.tpg_get_tag = tcm_qla2xxx_get_tag,
|
||||
.tpg_get_pr_transport_id = tcm_qla2xxx_get_pr_transport_id,
|
||||
.tpg_get_pr_transport_id_len = tcm_qla2xxx_get_pr_transport_id_len,
|
||||
.tpg_parse_pr_out_transport_id = tcm_qla2xxx_parse_pr_out_transport_id,
|
||||
.tpg_check_demo_mode = tcm_qla2xxx_check_demo_mode,
|
||||
.tpg_check_demo_mode_cache = tcm_qla2xxx_check_demo_mode_cache,
|
||||
.tpg_check_demo_mode_write_protect = tcm_qla2xxx_check_demo_mode,
|
||||
|
@ -57,8 +57,6 @@ struct tcm_qla2xxx_fc_loopid {
|
||||
};
|
||||
|
||||
struct tcm_qla2xxx_lport {
|
||||
/* SCSI protocol the lport is providing */
|
||||
u8 lport_proto_id;
|
||||
/* Binary World Wide unique Port Name for FC Target Lport */
|
||||
u64 lport_wwpn;
|
||||
/* Binary World Wide unique Port Name for FC NPIV Target Lport */
|
||||
|
@ -1921,9 +1921,6 @@ const struct target_core_fabric_ops iscsi_ops = {
|
||||
.tpg_get_wwn = lio_tpg_get_endpoint_wwn,
|
||||
.tpg_get_tag = lio_tpg_get_tag,
|
||||
.tpg_get_default_depth = lio_tpg_get_default_depth,
|
||||
.tpg_get_pr_transport_id = iscsi_get_pr_transport_id,
|
||||
.tpg_get_pr_transport_id_len = iscsi_get_pr_transport_id_len,
|
||||
.tpg_parse_pr_out_transport_id = iscsi_parse_pr_out_transport_id,
|
||||
.tpg_check_demo_mode = lio_tpg_check_demo_mode,
|
||||
.tpg_check_demo_mode_cache = lio_tpg_check_demo_mode_cache,
|
||||
.tpg_check_demo_mode_write_protect =
|
||||
|
@ -542,95 +542,6 @@ static u16 tcm_loop_get_tag(struct se_portal_group *se_tpg)
|
||||
return tl_tpg(se_tpg)->tl_tpgt;
|
||||
}
|
||||
|
||||
static u32 tcm_loop_get_pr_transport_id(
|
||||
struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code,
|
||||
unsigned char *buf)
|
||||
{
|
||||
struct tcm_loop_hba *tl_hba = tl_tpg(se_tpg)->tl_hba;
|
||||
|
||||
switch (tl_hba->tl_proto_id) {
|
||||
case SCSI_PROTOCOL_SAS:
|
||||
return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
|
||||
format_code, buf);
|
||||
case SCSI_PROTOCOL_FCP:
|
||||
return fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
|
||||
format_code, buf);
|
||||
case SCSI_PROTOCOL_ISCSI:
|
||||
return iscsi_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
|
||||
format_code, buf);
|
||||
default:
|
||||
pr_err("Unknown tl_proto_id: 0x%02x, using"
|
||||
" SAS emulation\n", tl_hba->tl_proto_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
|
||||
format_code, buf);
|
||||
}
|
||||
|
||||
static u32 tcm_loop_get_pr_transport_id_len(
|
||||
struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code)
|
||||
{
|
||||
struct tcm_loop_hba *tl_hba = tl_tpg(se_tpg)->tl_hba;
|
||||
|
||||
switch (tl_hba->tl_proto_id) {
|
||||
case SCSI_PROTOCOL_SAS:
|
||||
return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
|
||||
format_code);
|
||||
case SCSI_PROTOCOL_FCP:
|
||||
return fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
|
||||
format_code);
|
||||
case SCSI_PROTOCOL_ISCSI:
|
||||
return iscsi_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
|
||||
format_code);
|
||||
default:
|
||||
pr_err("Unknown tl_proto_id: 0x%02x, using"
|
||||
" SAS emulation\n", tl_hba->tl_proto_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
|
||||
format_code);
|
||||
}
|
||||
|
||||
/*
|
||||
* Used for handling SCSI fabric dependent TransportIDs in SPC-3 and above
|
||||
* Persistent Reservation SPEC_I_PT=1 and PROUT REGISTER_AND_MOVE operations.
|
||||
*/
|
||||
static char *tcm_loop_parse_pr_out_transport_id(
|
||||
struct se_portal_group *se_tpg,
|
||||
const char *buf,
|
||||
u32 *out_tid_len,
|
||||
char **port_nexus_ptr)
|
||||
{
|
||||
struct tcm_loop_hba *tl_hba = tl_tpg(se_tpg)->tl_hba;
|
||||
|
||||
switch (tl_hba->tl_proto_id) {
|
||||
case SCSI_PROTOCOL_SAS:
|
||||
return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
|
||||
port_nexus_ptr);
|
||||
case SCSI_PROTOCOL_FCP:
|
||||
return fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
|
||||
port_nexus_ptr);
|
||||
case SCSI_PROTOCOL_ISCSI:
|
||||
return iscsi_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
|
||||
port_nexus_ptr);
|
||||
default:
|
||||
pr_err("Unknown tl_proto_id: 0x%02x, using"
|
||||
" SAS emulation\n", tl_hba->tl_proto_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
|
||||
port_nexus_ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returning (1) here allows for target_core_mod struct se_node_acl to be generated
|
||||
* based upon the incoming fabric dependent SCSI Initiator Port
|
||||
@ -1332,9 +1243,6 @@ static const struct target_core_fabric_ops loop_ops = {
|
||||
.get_fabric_name = tcm_loop_get_fabric_name,
|
||||
.tpg_get_wwn = tcm_loop_get_endpoint_wwn,
|
||||
.tpg_get_tag = tcm_loop_get_tag,
|
||||
.tpg_get_pr_transport_id = tcm_loop_get_pr_transport_id,
|
||||
.tpg_get_pr_transport_id_len = tcm_loop_get_pr_transport_id_len,
|
||||
.tpg_parse_pr_out_transport_id = tcm_loop_parse_pr_out_transport_id,
|
||||
.tpg_check_demo_mode = tcm_loop_check_demo_mode,
|
||||
.tpg_check_demo_mode_cache = tcm_loop_check_demo_mode_cache,
|
||||
.tpg_check_demo_mode_write_protect =
|
||||
|
@ -1832,73 +1832,6 @@ static int sbp_check_stop_free(struct se_cmd *se_cmd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u32 sbp_get_pr_transport_id(
|
||||
struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code,
|
||||
unsigned char *buf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Set PROTOCOL IDENTIFIER to 3h for SBP
|
||||
*/
|
||||
buf[0] = SCSI_PROTOCOL_SBP;
|
||||
/*
|
||||
* From spc4r17, 7.5.4.4 TransportID for initiator ports using SCSI
|
||||
* over IEEE 1394
|
||||
*/
|
||||
ret = hex2bin(&buf[8], se_nacl->initiatorname, 8);
|
||||
if (ret < 0)
|
||||
pr_debug("sbp transport_id: invalid hex string\n");
|
||||
|
||||
/*
|
||||
* The IEEE 1394 Transport ID is a hardcoded 24-byte length
|
||||
*/
|
||||
return 24;
|
||||
}
|
||||
|
||||
static u32 sbp_get_pr_transport_id_len(
|
||||
struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code)
|
||||
{
|
||||
*format_code = 0;
|
||||
/*
|
||||
* From spc4r17, 7.5.4.4 TransportID for initiator ports using SCSI
|
||||
* over IEEE 1394
|
||||
*
|
||||
* The SBP Transport ID is a hardcoded 24-byte length
|
||||
*/
|
||||
return 24;
|
||||
}
|
||||
|
||||
/*
|
||||
* Used for handling SCSI fabric dependent TransportIDs in SPC-3 and above
|
||||
* Persistent Reservation SPEC_I_PT=1 and PROUT REGISTER_AND_MOVE operations.
|
||||
*/
|
||||
static char *sbp_parse_pr_out_transport_id(
|
||||
struct se_portal_group *se_tpg,
|
||||
const char *buf,
|
||||
u32 *out_tid_len,
|
||||
char **port_nexus_ptr)
|
||||
{
|
||||
/*
|
||||
* Assume the FORMAT CODE 00b from spc4r17, 7.5.4.4 TransportID
|
||||
* for initiator ports using SCSI over SBP Serial SCSI Protocol
|
||||
*
|
||||
* The TransportID for a IEEE 1394 Initiator Port is of fixed size of
|
||||
* 24 bytes, and IEEE 1394 does not contain a I_T nexus identifier,
|
||||
* so we return the **port_nexus_ptr set to NULL.
|
||||
*/
|
||||
*port_nexus_ptr = NULL;
|
||||
*out_tid_len = 24;
|
||||
|
||||
return (char *)&buf[8];
|
||||
}
|
||||
|
||||
static int sbp_count_se_tpg_luns(struct se_portal_group *tpg)
|
||||
{
|
||||
int i, count = 0;
|
||||
@ -2432,9 +2365,6 @@ static const struct target_core_fabric_ops sbp_ops = {
|
||||
.get_fabric_name = sbp_get_fabric_name,
|
||||
.tpg_get_wwn = sbp_get_fabric_wwn,
|
||||
.tpg_get_tag = sbp_get_tag,
|
||||
.tpg_get_pr_transport_id = sbp_get_pr_transport_id,
|
||||
.tpg_get_pr_transport_id_len = sbp_get_pr_transport_id_len,
|
||||
.tpg_parse_pr_out_transport_id = sbp_parse_pr_out_transport_id,
|
||||
.tpg_check_demo_mode = sbp_check_true,
|
||||
.tpg_check_demo_mode_cache = sbp_check_true,
|
||||
.tpg_check_demo_mode_write_protect = sbp_check_false,
|
||||
|
@ -326,14 +326,6 @@ static int target_fabric_tf_ops_check(const struct target_core_fabric_ops *tfo)
|
||||
pr_err("Missing tfo->tpg_get_tag()\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!tfo->tpg_get_pr_transport_id) {
|
||||
pr_err("Missing tfo->tpg_get_pr_transport_id()\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!tfo->tpg_get_pr_transport_id_len) {
|
||||
pr_err("Missing tfo->tpg_get_pr_transport_id_len()\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!tfo->tpg_check_demo_mode) {
|
||||
pr_err("Missing tfo->tpg_check_demo_mode()\n");
|
||||
return -EINVAL;
|
||||
|
@ -24,6 +24,11 @@
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* See SPC4, section 7.5 "Protocol specific parameters" for details
|
||||
* on the formats implemented in this file.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/ctype.h>
|
||||
@ -39,103 +44,26 @@
|
||||
#include "target_core_internal.h"
|
||||
#include "target_core_pr.h"
|
||||
|
||||
/*
|
||||
* Handlers for Serial Attached SCSI (SAS)
|
||||
*/
|
||||
u32 sas_get_pr_transport_id(
|
||||
struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
|
||||
static int sas_get_pr_transport_id(
|
||||
struct se_node_acl *nacl,
|
||||
int *format_code,
|
||||
unsigned char *buf)
|
||||
{
|
||||
unsigned char *ptr;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Set PROTOCOL IDENTIFIER to 6h for SAS
|
||||
*/
|
||||
buf[0] = 0x06;
|
||||
/*
|
||||
* From spc4r17, 7.5.4.7 TransportID for initiator ports using SCSI
|
||||
* over SAS Serial SCSI Protocol
|
||||
*/
|
||||
ptr = &se_nacl->initiatorname[4]; /* Skip over 'naa. prefix */
|
||||
/* Skip over 'naa. prefix */
|
||||
ret = hex2bin(&buf[4], &nacl->initiatorname[4], 8);
|
||||
if (ret) {
|
||||
pr_debug("%s: invalid hex string\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = hex2bin(&buf[4], ptr, 8);
|
||||
if (ret < 0)
|
||||
pr_debug("sas transport_id: invalid hex string\n");
|
||||
|
||||
/*
|
||||
* The SAS Transport ID is a hardcoded 24-byte length
|
||||
*/
|
||||
return 24;
|
||||
}
|
||||
EXPORT_SYMBOL(sas_get_pr_transport_id);
|
||||
|
||||
u32 sas_get_pr_transport_id_len(
|
||||
struct se_portal_group *se_tpg,
|
||||
static int fc_get_pr_transport_id(
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code)
|
||||
{
|
||||
*format_code = 0;
|
||||
/*
|
||||
* From spc4r17, 7.5.4.7 TransportID for initiator ports using SCSI
|
||||
* over SAS Serial SCSI Protocol
|
||||
*
|
||||
* The SAS Transport ID is a hardcoded 24-byte length
|
||||
*/
|
||||
return 24;
|
||||
}
|
||||
EXPORT_SYMBOL(sas_get_pr_transport_id_len);
|
||||
|
||||
/*
|
||||
* Used for handling SCSI fabric dependent TransportIDs in SPC-3 and above
|
||||
* Persistent Reservation SPEC_I_PT=1 and PROUT REGISTER_AND_MOVE operations.
|
||||
*/
|
||||
char *sas_parse_pr_out_transport_id(
|
||||
struct se_portal_group *se_tpg,
|
||||
const char *buf,
|
||||
u32 *out_tid_len,
|
||||
char **port_nexus_ptr)
|
||||
{
|
||||
/*
|
||||
* Assume the FORMAT CODE 00b from spc4r17, 7.5.4.7 TransportID
|
||||
* for initiator ports using SCSI over SAS Serial SCSI Protocol
|
||||
*
|
||||
* The TransportID for a SAS Initiator Port is of fixed size of
|
||||
* 24 bytes, and SAS does not contain a I_T nexus identifier,
|
||||
* so we return the **port_nexus_ptr set to NULL.
|
||||
*/
|
||||
*port_nexus_ptr = NULL;
|
||||
*out_tid_len = 24;
|
||||
|
||||
return (char *)&buf[4];
|
||||
}
|
||||
EXPORT_SYMBOL(sas_parse_pr_out_transport_id);
|
||||
|
||||
/*
|
||||
* Handlers for Fibre Channel Protocol (FCP)
|
||||
*/
|
||||
u32 fc_get_pr_transport_id_len(
|
||||
struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code)
|
||||
{
|
||||
*format_code = 0;
|
||||
/*
|
||||
* The FC Transport ID is a hardcoded 24-byte length
|
||||
*/
|
||||
return 24;
|
||||
}
|
||||
EXPORT_SYMBOL(fc_get_pr_transport_id_len);
|
||||
|
||||
u32 fc_get_pr_transport_id(
|
||||
struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code,
|
||||
unsigned char *buf)
|
||||
{
|
||||
@ -144,24 +72,20 @@ u32 fc_get_pr_transport_id(
|
||||
u32 off = 8;
|
||||
|
||||
/*
|
||||
* PROTOCOL IDENTIFIER is 0h for FCP-2
|
||||
*
|
||||
* From spc4r17, 7.5.4.2 TransportID for initiator ports using
|
||||
* SCSI over Fibre Channel
|
||||
*
|
||||
* We convert the ASCII formatted N Port name into a binary
|
||||
* encoded TransportID.
|
||||
*/
|
||||
ptr = &se_nacl->initiatorname[0];
|
||||
|
||||
for (i = 0; i < 24; ) {
|
||||
if (!strncmp(&ptr[i], ":", 1)) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
ret = hex2bin(&buf[off++], &ptr[i], 1);
|
||||
if (ret < 0)
|
||||
pr_debug("fc transport_id: invalid hex string\n");
|
||||
if (ret < 0) {
|
||||
pr_debug("%s: invalid hex string\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
i += 2;
|
||||
}
|
||||
/*
|
||||
@ -169,31 +93,52 @@ u32 fc_get_pr_transport_id(
|
||||
*/
|
||||
return 24;
|
||||
}
|
||||
EXPORT_SYMBOL(fc_get_pr_transport_id);
|
||||
|
||||
char *fc_parse_pr_out_transport_id(
|
||||
struct se_portal_group *se_tpg,
|
||||
const char *buf,
|
||||
u32 *out_tid_len,
|
||||
char **port_nexus_ptr)
|
||||
static int sbp_get_pr_transport_id(
|
||||
struct se_node_acl *nacl,
|
||||
int *format_code,
|
||||
unsigned char *buf)
|
||||
{
|
||||
/*
|
||||
* The TransportID for a FC N Port is of fixed size of
|
||||
* 24 bytes, and FC does not contain a I_T nexus identifier,
|
||||
* so we return the **port_nexus_ptr set to NULL.
|
||||
*/
|
||||
*port_nexus_ptr = NULL;
|
||||
*out_tid_len = 24;
|
||||
int ret;
|
||||
|
||||
return (char *)&buf[8];
|
||||
ret = hex2bin(&buf[8], nacl->initiatorname, 8);
|
||||
if (ret) {
|
||||
pr_debug("%s: invalid hex string\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 24;
|
||||
}
|
||||
EXPORT_SYMBOL(fc_parse_pr_out_transport_id);
|
||||
|
||||
/*
|
||||
* Handlers for Internet Small Computer Systems Interface (iSCSI)
|
||||
*/
|
||||
u32 iscsi_get_pr_transport_id(
|
||||
struct se_portal_group *se_tpg,
|
||||
static int srp_get_pr_transport_id(
|
||||
struct se_node_acl *nacl,
|
||||
int *format_code,
|
||||
unsigned char *buf)
|
||||
{
|
||||
const char *p;
|
||||
unsigned len, count, leading_zero_bytes;
|
||||
int rc;
|
||||
|
||||
p = nacl->initiatorname;
|
||||
if (strncasecmp(p, "0x", 2) == 0)
|
||||
p += 2;
|
||||
len = strlen(p);
|
||||
if (len % 2)
|
||||
return -EINVAL;
|
||||
|
||||
count = min(len / 2, 16U);
|
||||
leading_zero_bytes = 16 - count;
|
||||
memset(buf + 8, 0, leading_zero_bytes);
|
||||
rc = hex2bin(buf + 8 + leading_zero_bytes, p, count);
|
||||
if (rc < 0) {
|
||||
pr_debug("hex2bin failed for %s: %d\n", __func__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 24;
|
||||
}
|
||||
|
||||
static int iscsi_get_pr_transport_id(
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code,
|
||||
@ -203,10 +148,6 @@ u32 iscsi_get_pr_transport_id(
|
||||
u16 len = 0;
|
||||
|
||||
spin_lock_irq(&se_nacl->nacl_sess_lock);
|
||||
/*
|
||||
* Set PROTOCOL IDENTIFIER to 5h for iSCSI
|
||||
*/
|
||||
buf[0] = 0x05;
|
||||
/*
|
||||
* From spc4r17 Section 7.5.4.6: TransportID for initiator
|
||||
* ports using SCSI over iSCSI.
|
||||
@ -286,10 +227,8 @@ u32 iscsi_get_pr_transport_id(
|
||||
|
||||
return len;
|
||||
}
|
||||
EXPORT_SYMBOL(iscsi_get_pr_transport_id);
|
||||
|
||||
u32 iscsi_get_pr_transport_id_len(
|
||||
struct se_portal_group *se_tpg,
|
||||
static int iscsi_get_pr_transport_id_len(
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code)
|
||||
@ -332,9 +271,8 @@ u32 iscsi_get_pr_transport_id_len(
|
||||
|
||||
return len;
|
||||
}
|
||||
EXPORT_SYMBOL(iscsi_get_pr_transport_id_len);
|
||||
|
||||
char *iscsi_parse_pr_out_transport_id(
|
||||
static char *iscsi_parse_pr_out_transport_id(
|
||||
struct se_portal_group *se_tpg,
|
||||
const char *buf,
|
||||
u32 *out_tid_len,
|
||||
@ -421,4 +359,79 @@ char *iscsi_parse_pr_out_transport_id(
|
||||
|
||||
return (char *)&buf[4];
|
||||
}
|
||||
EXPORT_SYMBOL(iscsi_parse_pr_out_transport_id);
|
||||
|
||||
int target_get_pr_transport_id_len(struct se_node_acl *nacl,
|
||||
struct t10_pr_registration *pr_reg, int *format_code)
|
||||
{
|
||||
switch (nacl->se_tpg->proto_id) {
|
||||
case SCSI_PROTOCOL_FCP:
|
||||
case SCSI_PROTOCOL_SBP:
|
||||
case SCSI_PROTOCOL_SRP:
|
||||
case SCSI_PROTOCOL_SAS:
|
||||
break;
|
||||
case SCSI_PROTOCOL_ISCSI:
|
||||
return iscsi_get_pr_transport_id_len(nacl, pr_reg, format_code);
|
||||
default:
|
||||
pr_err("Unknown proto_id: 0x%02x\n", nacl->se_tpg->proto_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Most transports use a fixed length 24 byte identifier.
|
||||
*/
|
||||
*format_code = 0;
|
||||
return 24;
|
||||
}
|
||||
|
||||
int target_get_pr_transport_id(struct se_node_acl *nacl,
|
||||
struct t10_pr_registration *pr_reg, int *format_code,
|
||||
unsigned char *buf)
|
||||
{
|
||||
switch (nacl->se_tpg->proto_id) {
|
||||
case SCSI_PROTOCOL_SAS:
|
||||
return sas_get_pr_transport_id(nacl, format_code, buf);
|
||||
case SCSI_PROTOCOL_SBP:
|
||||
return sbp_get_pr_transport_id(nacl, format_code, buf);
|
||||
case SCSI_PROTOCOL_SRP:
|
||||
return srp_get_pr_transport_id(nacl, format_code, buf);
|
||||
case SCSI_PROTOCOL_FCP:
|
||||
return fc_get_pr_transport_id(nacl, format_code, buf);
|
||||
case SCSI_PROTOCOL_ISCSI:
|
||||
return iscsi_get_pr_transport_id(nacl, pr_reg, format_code,
|
||||
buf);
|
||||
default:
|
||||
pr_err("Unknown proto_id: 0x%02x\n", nacl->se_tpg->proto_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
|
||||
const char *buf, u32 *out_tid_len, char **port_nexus_ptr)
|
||||
{
|
||||
u32 offset;
|
||||
|
||||
switch (tpg->proto_id) {
|
||||
case SCSI_PROTOCOL_SAS:
|
||||
/*
|
||||
* Assume the FORMAT CODE 00b from spc4r17, 7.5.4.7 TransportID
|
||||
* for initiator ports using SCSI over SAS Serial SCSI Protocol.
|
||||
*/
|
||||
offset = 4;
|
||||
break;
|
||||
case SCSI_PROTOCOL_SBP:
|
||||
case SCSI_PROTOCOL_SRP:
|
||||
case SCSI_PROTOCOL_FCP:
|
||||
offset = 8;
|
||||
break;
|
||||
case SCSI_PROTOCOL_ISCSI:
|
||||
return iscsi_parse_pr_out_transport_id(tpg, buf, out_tid_len,
|
||||
port_nexus_ptr);
|
||||
default:
|
||||
pr_err("Unknown proto_id: 0x%02x\n", tpg->proto_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*port_nexus_ptr = NULL;
|
||||
*out_tid_len = 24;
|
||||
return buf + offset;
|
||||
}
|
||||
|
@ -38,6 +38,15 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name);
|
||||
int target_configure_device(struct se_device *dev);
|
||||
void target_free_device(struct se_device *);
|
||||
|
||||
/* target_core_fabric_lib.c */
|
||||
int target_get_pr_transport_id_len(struct se_node_acl *nacl,
|
||||
struct t10_pr_registration *pr_reg, int *format_code);
|
||||
int target_get_pr_transport_id(struct se_node_acl *nacl,
|
||||
struct t10_pr_registration *pr_reg, int *format_code,
|
||||
unsigned char *buf);
|
||||
const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
|
||||
const char *buf, u32 *out_tid_len, char **port_nexus_ptr);
|
||||
|
||||
/* target_core_hba.c */
|
||||
struct se_hba *core_alloc_hba(const char *, u32, u32);
|
||||
int core_delete_hba(struct se_hba *);
|
||||
|
@ -1445,9 +1445,8 @@ core_scsi3_decode_spec_i_port(
|
||||
struct t10_pr_registration *pr_reg_tmp, *pr_reg_tmp_safe;
|
||||
LIST_HEAD(tid_dest_list);
|
||||
struct pr_transport_id_holder *tidh_new, *tidh, *tidh_tmp;
|
||||
const struct target_core_fabric_ops *tmp_tf_ops;
|
||||
unsigned char *buf;
|
||||
unsigned char *ptr, *i_str = NULL, proto_ident;
|
||||
unsigned char *buf, *ptr, proto_ident;
|
||||
const unsigned char *i_str;
|
||||
char *iport_ptr = NULL, i_buf[PR_REG_ISID_ID_LEN];
|
||||
sense_reason_t ret;
|
||||
u32 tpdl, tid_len = 0;
|
||||
@ -1533,11 +1532,7 @@ core_scsi3_decode_spec_i_port(
|
||||
tmp_tpg = tmp_port->sep_tpg;
|
||||
if (!tmp_tpg)
|
||||
continue;
|
||||
tmp_tf_ops = tmp_tpg->se_tpg_tfo;
|
||||
if (!tmp_tf_ops)
|
||||
continue;
|
||||
if (!tmp_tf_ops->tpg_parse_pr_out_transport_id)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Look for the matching proto_ident provided by
|
||||
* the received TransportID
|
||||
@ -1546,9 +1541,8 @@ core_scsi3_decode_spec_i_port(
|
||||
continue;
|
||||
dest_rtpi = tmp_port->sep_rtpi;
|
||||
|
||||
i_str = tmp_tf_ops->tpg_parse_pr_out_transport_id(
|
||||
tmp_tpg, (const char *)ptr, &tid_len,
|
||||
&iport_ptr);
|
||||
i_str = target_parse_pr_out_transport_id(tmp_tpg,
|
||||
(const char *)ptr, &tid_len, &iport_ptr);
|
||||
if (!i_str)
|
||||
continue;
|
||||
|
||||
@ -3105,7 +3099,7 @@ core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key,
|
||||
struct t10_pr_registration *pr_reg, *pr_res_holder, *dest_pr_reg;
|
||||
struct t10_reservation *pr_tmpl = &dev->t10_pr;
|
||||
unsigned char *buf;
|
||||
unsigned char *initiator_str;
|
||||
const unsigned char *initiator_str;
|
||||
char *iport_ptr = NULL, i_buf[PR_REG_ISID_ID_LEN];
|
||||
u32 tid_len, tmp_tid_len;
|
||||
int new_reg = 0, type, scope, matching_iname;
|
||||
@ -3237,14 +3231,7 @@ core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key,
|
||||
ret = TCM_INVALID_PARAMETER_LIST;
|
||||
goto out;
|
||||
}
|
||||
if (dest_tf_ops->tpg_parse_pr_out_transport_id == NULL) {
|
||||
pr_err("SPC-3 PR REGISTER_AND_MOVE: Fabric does not"
|
||||
" containg a valid tpg_parse_pr_out_transport_id"
|
||||
" function pointer\n");
|
||||
ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
initiator_str = dest_tf_ops->tpg_parse_pr_out_transport_id(dest_se_tpg,
|
||||
initiator_str = target_parse_pr_out_transport_id(dest_se_tpg,
|
||||
(const char *)&buf[24], &tmp_tid_len, &iport_ptr);
|
||||
if (!initiator_str) {
|
||||
pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate"
|
||||
@ -3881,9 +3868,10 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd)
|
||||
struct t10_pr_registration *pr_reg, *pr_reg_tmp;
|
||||
struct t10_reservation *pr_tmpl = &dev->t10_pr;
|
||||
unsigned char *buf;
|
||||
u32 add_desc_len = 0, add_len = 0, desc_len, exp_desc_len;
|
||||
u32 add_desc_len = 0, add_len = 0;
|
||||
u32 off = 8; /* off into first Full Status descriptor */
|
||||
int format_code = 0, pr_res_type = 0, pr_res_scope = 0;
|
||||
int exp_desc_len, desc_len;
|
||||
bool all_reg = false;
|
||||
|
||||
if (cmd->data_length < 8) {
|
||||
@ -3928,10 +3916,10 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd)
|
||||
* Determine expected length of $FABRIC_MOD specific
|
||||
* TransportID full status descriptor..
|
||||
*/
|
||||
exp_desc_len = se_tpg->se_tpg_tfo->tpg_get_pr_transport_id_len(
|
||||
se_tpg, se_nacl, pr_reg, &format_code);
|
||||
|
||||
if ((exp_desc_len + add_len) > cmd->data_length) {
|
||||
exp_desc_len = target_get_pr_transport_id_len(se_nacl, pr_reg,
|
||||
&format_code);
|
||||
if (exp_desc_len < 0 ||
|
||||
exp_desc_len + add_len > cmd->data_length) {
|
||||
pr_warn("SPC-3 PRIN READ_FULL_STATUS ran"
|
||||
" out of buffer: %d\n", cmd->data_length);
|
||||
spin_lock(&pr_tmpl->registration_lock);
|
||||
@ -3995,14 +3983,19 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd)
|
||||
} else
|
||||
off += 2; /* Skip over RELATIVE TARGET PORT IDENTIFIER */
|
||||
|
||||
buf[off+4] = se_tpg->proto_id;
|
||||
|
||||
/*
|
||||
* Now, have the $FABRIC_MOD fill in the protocol identifier
|
||||
* Now, have the $FABRIC_MOD fill in the transport ID.
|
||||
*/
|
||||
desc_len = se_tpg->se_tpg_tfo->tpg_get_pr_transport_id(se_tpg,
|
||||
se_nacl, pr_reg, &format_code, &buf[off+4]);
|
||||
desc_len = target_get_pr_transport_id(se_nacl, pr_reg,
|
||||
&format_code, &buf[off+4]);
|
||||
|
||||
spin_lock(&pr_tmpl->registration_lock);
|
||||
atomic_dec_mb(&pr_reg->pr_res_holders);
|
||||
|
||||
if (desc_len < 0)
|
||||
break;
|
||||
/*
|
||||
* Set the ADDITIONAL DESCRIPTOR LENGTH
|
||||
*/
|
||||
|
@ -454,9 +454,6 @@ static const struct target_core_fabric_ops ft_fabric_ops = {
|
||||
.get_fabric_name = ft_get_fabric_name,
|
||||
.tpg_get_wwn = ft_get_fabric_wwn,
|
||||
.tpg_get_tag = ft_get_tag,
|
||||
.tpg_get_pr_transport_id = fc_get_pr_transport_id,
|
||||
.tpg_get_pr_transport_id_len = fc_get_pr_transport_id_len,
|
||||
.tpg_parse_pr_out_transport_id = fc_parse_pr_out_transport_id,
|
||||
.tpg_check_demo_mode = ft_check_false,
|
||||
.tpg_check_demo_mode_cache = ft_check_false,
|
||||
.tpg_check_demo_mode_write_protect = ft_check_false,
|
||||
|
@ -1290,72 +1290,6 @@ static u16 usbg_get_tag(struct se_portal_group *se_tpg)
|
||||
return tpg->tport_tpgt;
|
||||
}
|
||||
|
||||
static u32 usbg_get_pr_transport_id(
|
||||
struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code,
|
||||
unsigned char *buf)
|
||||
{
|
||||
struct usbg_tpg *tpg = container_of(se_tpg,
|
||||
struct usbg_tpg, se_tpg);
|
||||
struct usbg_tport *tport = tpg->tport;
|
||||
int ret = 0;
|
||||
|
||||
switch (tport->tport_proto_id) {
|
||||
case SCSI_PROTOCOL_SAS:
|
||||
default:
|
||||
ret = sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
|
||||
format_code, buf);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u32 usbg_get_pr_transport_id_len(
|
||||
struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code)
|
||||
{
|
||||
struct usbg_tpg *tpg = container_of(se_tpg,
|
||||
struct usbg_tpg, se_tpg);
|
||||
struct usbg_tport *tport = tpg->tport;
|
||||
int ret = 0;
|
||||
|
||||
switch (tport->tport_proto_id) {
|
||||
case SCSI_PROTOCOL_SAS:
|
||||
default:
|
||||
ret = sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
|
||||
format_code);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *usbg_parse_pr_out_transport_id(
|
||||
struct se_portal_group *se_tpg,
|
||||
const char *buf,
|
||||
u32 *out_tid_len,
|
||||
char **port_nexus_ptr)
|
||||
{
|
||||
struct usbg_tpg *tpg = container_of(se_tpg,
|
||||
struct usbg_tpg, se_tpg);
|
||||
struct usbg_tport *tport = tpg->tport;
|
||||
char *tid = NULL;
|
||||
|
||||
switch (tport->tport_proto_id) {
|
||||
case SCSI_PROTOCOL_SAS:
|
||||
default:
|
||||
tid = sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
|
||||
port_nexus_ptr);
|
||||
}
|
||||
|
||||
return tid;
|
||||
}
|
||||
|
||||
static u32 usbg_tpg_get_inst_index(struct se_portal_group *se_tpg)
|
||||
{
|
||||
return 1;
|
||||
@ -1491,8 +1425,12 @@ static struct se_portal_group *usbg_make_tpg(
|
||||
tpg->tport = tport;
|
||||
tpg->tport_tpgt = tpgt;
|
||||
|
||||
/*
|
||||
* SPC doesn't assign a protocol identifier for USB-SCSI, so we
|
||||
* pretend to be SAS..
|
||||
*/
|
||||
ret = core_tpg_register(&usbg_ops, wwn, &tpg->se_tpg,
|
||||
tport->tport_proto_id);
|
||||
SCSI_PROTOCOL_SAS);
|
||||
if (ret < 0) {
|
||||
destroy_workqueue(tpg->workqueue);
|
||||
kfree(tpg);
|
||||
@ -1788,9 +1726,6 @@ static const struct target_core_fabric_ops usbg_ops = {
|
||||
.get_fabric_name = usbg_get_fabric_name,
|
||||
.tpg_get_wwn = usbg_get_fabric_wwn,
|
||||
.tpg_get_tag = usbg_get_tag,
|
||||
.tpg_get_pr_transport_id = usbg_get_pr_transport_id,
|
||||
.tpg_get_pr_transport_id_len = usbg_get_pr_transport_id_len,
|
||||
.tpg_parse_pr_out_transport_id = usbg_parse_pr_out_transport_id,
|
||||
.tpg_check_demo_mode = usbg_check_true,
|
||||
.tpg_check_demo_mode_cache = usbg_check_false,
|
||||
.tpg_check_demo_mode_write_protect = usbg_check_false,
|
||||
|
@ -44,8 +44,6 @@ struct usbg_tpg {
|
||||
};
|
||||
|
||||
struct usbg_tport {
|
||||
/* SCSI protocol the tport is providing */
|
||||
u8 tport_proto_id;
|
||||
/* Binary World Wide unique Port Name for SAS Target port */
|
||||
u64 tport_wwpn;
|
||||
/* ASCII formatted WWPN for SAS Target port */
|
||||
|
@ -304,97 +304,6 @@ static u16 vhost_scsi_get_tpgt(struct se_portal_group *se_tpg)
|
||||
return tpg->tport_tpgt;
|
||||
}
|
||||
|
||||
static u32
|
||||
vhost_scsi_get_pr_transport_id(struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code,
|
||||
unsigned char *buf)
|
||||
{
|
||||
struct vhost_scsi_tpg *tpg = container_of(se_tpg,
|
||||
struct vhost_scsi_tpg, se_tpg);
|
||||
struct vhost_scsi_tport *tport = tpg->tport;
|
||||
|
||||
switch (tport->tport_proto_id) {
|
||||
case SCSI_PROTOCOL_SAS:
|
||||
return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
|
||||
format_code, buf);
|
||||
case SCSI_PROTOCOL_FCP:
|
||||
return fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
|
||||
format_code, buf);
|
||||
case SCSI_PROTOCOL_ISCSI:
|
||||
return iscsi_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
|
||||
format_code, buf);
|
||||
default:
|
||||
pr_err("Unknown tport_proto_id: 0x%02x, using"
|
||||
" SAS emulation\n", tport->tport_proto_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
|
||||
format_code, buf);
|
||||
}
|
||||
|
||||
static u32
|
||||
vhost_scsi_get_pr_transport_id_len(struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code)
|
||||
{
|
||||
struct vhost_scsi_tpg *tpg = container_of(se_tpg,
|
||||
struct vhost_scsi_tpg, se_tpg);
|
||||
struct vhost_scsi_tport *tport = tpg->tport;
|
||||
|
||||
switch (tport->tport_proto_id) {
|
||||
case SCSI_PROTOCOL_SAS:
|
||||
return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
|
||||
format_code);
|
||||
case SCSI_PROTOCOL_FCP:
|
||||
return fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
|
||||
format_code);
|
||||
case SCSI_PROTOCOL_ISCSI:
|
||||
return iscsi_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
|
||||
format_code);
|
||||
default:
|
||||
pr_err("Unknown tport_proto_id: 0x%02x, using"
|
||||
" SAS emulation\n", tport->tport_proto_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
|
||||
format_code);
|
||||
}
|
||||
|
||||
static char *
|
||||
vhost_scsi_parse_pr_out_transport_id(struct se_portal_group *se_tpg,
|
||||
const char *buf,
|
||||
u32 *out_tid_len,
|
||||
char **port_nexus_ptr)
|
||||
{
|
||||
struct vhost_scsi_tpg *tpg = container_of(se_tpg,
|
||||
struct vhost_scsi_tpg, se_tpg);
|
||||
struct vhost_scsi_tport *tport = tpg->tport;
|
||||
|
||||
switch (tport->tport_proto_id) {
|
||||
case SCSI_PROTOCOL_SAS:
|
||||
return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
|
||||
port_nexus_ptr);
|
||||
case SCSI_PROTOCOL_FCP:
|
||||
return fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
|
||||
port_nexus_ptr);
|
||||
case SCSI_PROTOCOL_ISCSI:
|
||||
return iscsi_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
|
||||
port_nexus_ptr);
|
||||
default:
|
||||
pr_err("Unknown tport_proto_id: 0x%02x, using"
|
||||
" SAS emulation\n", tport->tport_proto_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
|
||||
port_nexus_ptr);
|
||||
}
|
||||
|
||||
static int vhost_scsi_check_prot_fabric_only(struct se_portal_group *se_tpg)
|
||||
{
|
||||
struct vhost_scsi_tpg *tpg = container_of(se_tpg,
|
||||
@ -2224,9 +2133,6 @@ static struct target_core_fabric_ops vhost_scsi_ops = {
|
||||
.get_fabric_name = vhost_scsi_get_fabric_name,
|
||||
.tpg_get_wwn = vhost_scsi_get_fabric_wwn,
|
||||
.tpg_get_tag = vhost_scsi_get_tpgt,
|
||||
.tpg_get_pr_transport_id = vhost_scsi_get_pr_transport_id,
|
||||
.tpg_get_pr_transport_id_len = vhost_scsi_get_pr_transport_id_len,
|
||||
.tpg_parse_pr_out_transport_id = vhost_scsi_parse_pr_out_transport_id,
|
||||
.tpg_check_demo_mode = vhost_scsi_check_true,
|
||||
.tpg_check_demo_mode_cache = vhost_scsi_check_true,
|
||||
.tpg_check_demo_mode_write_protect = vhost_scsi_check_false,
|
||||
|
@ -1270,97 +1270,6 @@ static u16 scsiback_get_tag(struct se_portal_group *se_tpg)
|
||||
return tpg->tport_tpgt;
|
||||
}
|
||||
|
||||
static u32
|
||||
scsiback_get_pr_transport_id(struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code,
|
||||
unsigned char *buf)
|
||||
{
|
||||
struct scsiback_tpg *tpg = container_of(se_tpg,
|
||||
struct scsiback_tpg, se_tpg);
|
||||
struct scsiback_tport *tport = tpg->tport;
|
||||
|
||||
switch (tport->tport_proto_id) {
|
||||
case SCSI_PROTOCOL_SAS:
|
||||
return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
|
||||
format_code, buf);
|
||||
case SCSI_PROTOCOL_FCP:
|
||||
return fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
|
||||
format_code, buf);
|
||||
case SCSI_PROTOCOL_ISCSI:
|
||||
return iscsi_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
|
||||
format_code, buf);
|
||||
default:
|
||||
pr_err("Unknown tport_proto_id: 0x%02x, using SAS emulation\n",
|
||||
tport->tport_proto_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
|
||||
format_code, buf);
|
||||
}
|
||||
|
||||
static u32
|
||||
scsiback_get_pr_transport_id_len(struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code)
|
||||
{
|
||||
struct scsiback_tpg *tpg = container_of(se_tpg,
|
||||
struct scsiback_tpg, se_tpg);
|
||||
struct scsiback_tport *tport = tpg->tport;
|
||||
|
||||
switch (tport->tport_proto_id) {
|
||||
case SCSI_PROTOCOL_SAS:
|
||||
return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
|
||||
format_code);
|
||||
case SCSI_PROTOCOL_FCP:
|
||||
return fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
|
||||
format_code);
|
||||
case SCSI_PROTOCOL_ISCSI:
|
||||
return iscsi_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
|
||||
format_code);
|
||||
default:
|
||||
pr_err("Unknown tport_proto_id: 0x%02x, using SAS emulation\n",
|
||||
tport->tport_proto_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
|
||||
format_code);
|
||||
}
|
||||
|
||||
static char *
|
||||
scsiback_parse_pr_out_transport_id(struct se_portal_group *se_tpg,
|
||||
const char *buf,
|
||||
u32 *out_tid_len,
|
||||
char **port_nexus_ptr)
|
||||
{
|
||||
struct scsiback_tpg *tpg = container_of(se_tpg,
|
||||
struct scsiback_tpg, se_tpg);
|
||||
struct scsiback_tport *tport = tpg->tport;
|
||||
|
||||
switch (tport->tport_proto_id) {
|
||||
case SCSI_PROTOCOL_SAS:
|
||||
return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
|
||||
port_nexus_ptr);
|
||||
case SCSI_PROTOCOL_FCP:
|
||||
return fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
|
||||
port_nexus_ptr);
|
||||
case SCSI_PROTOCOL_ISCSI:
|
||||
return iscsi_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
|
||||
port_nexus_ptr);
|
||||
default:
|
||||
pr_err("Unknown tport_proto_id: 0x%02x, using SAS emulation\n",
|
||||
tport->tport_proto_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
|
||||
port_nexus_ptr);
|
||||
}
|
||||
|
||||
static struct se_wwn *
|
||||
scsiback_make_tport(struct target_fabric_configfs *tf,
|
||||
struct config_group *group,
|
||||
@ -1909,9 +1818,6 @@ static const struct target_core_fabric_ops scsiback_ops = {
|
||||
.get_fabric_name = scsiback_get_fabric_name,
|
||||
.tpg_get_wwn = scsiback_get_fabric_wwn,
|
||||
.tpg_get_tag = scsiback_get_tag,
|
||||
.tpg_get_pr_transport_id = scsiback_get_pr_transport_id,
|
||||
.tpg_get_pr_transport_id_len = scsiback_get_pr_transport_id_len,
|
||||
.tpg_parse_pr_out_transport_id = scsiback_parse_pr_out_transport_id,
|
||||
.tpg_check_demo_mode = scsiback_check_true,
|
||||
.tpg_check_demo_mode_cache = scsiback_check_true,
|
||||
.tpg_check_demo_mode_write_protect = scsiback_check_false,
|
||||
|
@ -9,15 +9,6 @@ struct target_core_fabric_ops {
|
||||
char *(*tpg_get_wwn)(struct se_portal_group *);
|
||||
u16 (*tpg_get_tag)(struct se_portal_group *);
|
||||
u32 (*tpg_get_default_depth)(struct se_portal_group *);
|
||||
u32 (*tpg_get_pr_transport_id)(struct se_portal_group *,
|
||||
struct se_node_acl *,
|
||||
struct t10_pr_registration *, int *,
|
||||
unsigned char *);
|
||||
u32 (*tpg_get_pr_transport_id_len)(struct se_portal_group *,
|
||||
struct se_node_acl *,
|
||||
struct t10_pr_registration *, int *);
|
||||
char *(*tpg_parse_pr_out_transport_id)(struct se_portal_group *,
|
||||
const char *, u32 *, char **);
|
||||
int (*tpg_check_demo_mode)(struct se_portal_group *);
|
||||
int (*tpg_check_demo_mode_cache)(struct se_portal_group *);
|
||||
int (*tpg_check_demo_mode_write_protect)(struct se_portal_group *);
|
||||
@ -177,30 +168,6 @@ int core_tpg_register(const struct target_core_fabric_ops *,
|
||||
struct se_wwn *, struct se_portal_group *, int);
|
||||
int core_tpg_deregister(struct se_portal_group *);
|
||||
|
||||
/* SAS helpers */
|
||||
u32 sas_get_pr_transport_id(struct se_portal_group *, struct se_node_acl *,
|
||||
struct t10_pr_registration *, int *, unsigned char *);
|
||||
u32 sas_get_pr_transport_id_len(struct se_portal_group *, struct se_node_acl *,
|
||||
struct t10_pr_registration *, int *);
|
||||
char *sas_parse_pr_out_transport_id(struct se_portal_group *, const char *,
|
||||
u32 *, char **);
|
||||
|
||||
/* FC helpers */
|
||||
u32 fc_get_pr_transport_id(struct se_portal_group *, struct se_node_acl *,
|
||||
struct t10_pr_registration *, int *, unsigned char *);
|
||||
u32 fc_get_pr_transport_id_len(struct se_portal_group *, struct se_node_acl *,
|
||||
struct t10_pr_registration *, int *);
|
||||
char *fc_parse_pr_out_transport_id(struct se_portal_group *, const char *,
|
||||
u32 *, char **);
|
||||
|
||||
/* iSCSI helpers */
|
||||
u32 iscsi_get_pr_transport_id(struct se_portal_group *, struct se_node_acl *,
|
||||
struct t10_pr_registration *, int *, unsigned char *);
|
||||
u32 iscsi_get_pr_transport_id_len(struct se_portal_group *, struct se_node_acl *,
|
||||
struct t10_pr_registration *, int *);
|
||||
char *iscsi_parse_pr_out_transport_id(struct se_portal_group *, const char *,
|
||||
u32 *, char **);
|
||||
|
||||
/*
|
||||
* The LIO target core uses DMA_TO_DEVICE to mean that data is going
|
||||
* to the target (eg handling a WRITE) and DMA_FROM_DEVICE to mean
|
||||
|
Loading…
Reference in New Issue
Block a user