From: Konstantin Shelekhin Date: Thu, 13 May 2021 19:28:04 +0000 (+0300) Subject: scsi: target: core: Add the VERSION DESCRIPTOR fields to the INQUIRY data X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=b790a56d66eaac4a1ac6c558575fd0a694b06159;p=linux.git scsi: target: core: Add the VERSION DESCRIPTOR fields to the INQUIRY data Extend the standard INQUIRY data to 96 bytes and fill in the VERSION DESCRIPTOR fields. The layout follows SPC-4: - SCSI architecture standard - SCSI transport protocol standard - SCSI primary command set standard - SCSI device type command set standard All version descriptor values are defined as "no version claimed" because some initiators fail to recognize anything else. [mkp: whitespace] Link: https://lore.kernel.org/r/20210513192804.1252142-3-k.shelekhin@yadro.com Reviewed-by: Roman Bolshakov Signed-off-by: Konstantin Shelekhin Signed-off-by: Martin K. Petersen --- diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 0f30b71f0acc8..2cb141ed68f5e 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -47,10 +47,32 @@ static void spc_fill_alua_data(struct se_lun *lun, unsigned char *buf) spin_unlock(&lun->lun_tg_pt_gp_lock); } +static u16 +spc_find_scsi_transport_vd(int proto_id) +{ + switch (proto_id) { + case SCSI_PROTOCOL_FCP: + return SCSI_VERSION_DESCRIPTOR_FCP4; + case SCSI_PROTOCOL_ISCSI: + return SCSI_VERSION_DESCRIPTOR_ISCSI; + case SCSI_PROTOCOL_SAS: + return SCSI_VERSION_DESCRIPTOR_SAS3; + case SCSI_PROTOCOL_SBP: + return SCSI_VERSION_DESCRIPTOR_SBP3; + case SCSI_PROTOCOL_SRP: + return SCSI_VERSION_DESCRIPTOR_SRP; + default: + pr_warn("Cannot find VERSION DESCRIPTOR value for unknown SCSI" + " transport PROTOCOL IDENTIFIER %#x\n", proto_id); + return 0; + } +} + sense_reason_t spc_emulate_inquiry_std(struct se_cmd *cmd, unsigned char *buf) { struct se_lun *lun = cmd->se_lun; + struct se_portal_group *tpg = lun->lun_tpg; struct se_device *dev = cmd->se_dev; struct se_session *sess = cmd->se_sess; @@ -108,7 +130,17 @@ spc_emulate_inquiry_std(struct se_cmd *cmd, unsigned char *buf) strnlen(dev->t10_wwn.model, INQUIRY_MODEL_LEN)); memcpy(&buf[32], dev->t10_wwn.revision, strnlen(dev->t10_wwn.revision, INQUIRY_REVISION_LEN)); - buf[4] = 31; /* Set additional length to 31 */ + + /* + * Set the VERSION DESCRIPTOR fields + */ + put_unaligned_be16(SCSI_VERSION_DESCRIPTOR_SAM5, &buf[58]); + put_unaligned_be16(spc_find_scsi_transport_vd(tpg->proto_id), &buf[60]); + put_unaligned_be16(SCSI_VERSION_DESCRIPTOR_SPC4, &buf[62]); + if (cmd->se_dev->transport->get_device_type(dev) == TYPE_DISK) + put_unaligned_be16(SCSI_VERSION_DESCRIPTOR_SBC3, &buf[64]); + + buf[4] = 91; /* Set additional length to 91 */ return 0; } diff --git a/include/scsi/scsi_proto.h b/include/scsi/scsi_proto.h index c368601119322..5c106c4f249e2 100644 --- a/include/scsi/scsi_proto.h +++ b/include/scsi/scsi_proto.h @@ -341,4 +341,16 @@ enum zbc_zone_cond { ZBC_ZONE_COND_OFFLINE = 0xf, }; +/* Version descriptor values for INQUIRY */ +enum scsi_version_descriptor { + SCSI_VERSION_DESCRIPTOR_FCP4 = 0x0a40, + SCSI_VERSION_DESCRIPTOR_ISCSI = 0x0960, + SCSI_VERSION_DESCRIPTOR_SAM5 = 0x00a0, + SCSI_VERSION_DESCRIPTOR_SAS3 = 0x0c60, + SCSI_VERSION_DESCRIPTOR_SBC3 = 0x04c0, + SCSI_VERSION_DESCRIPTOR_SBP3 = 0x0980, + SCSI_VERSION_DESCRIPTOR_SPC4 = 0x0460, + SCSI_VERSION_DESCRIPTOR_SRP = 0x0940 +}; + #endif /* _SCSI_PROTO_H_ */