Commit b790a56d authored by Konstantin Shelekhin's avatar Konstantin Shelekhin Committed by Martin K. Petersen
Browse files

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: default avatarRoman Bolshakov <r.bolshakov@yadro.com>
Signed-off-by: default avatarKonstantin Shelekhin <k.shelekhin@yadro.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 64ae33ef
Loading
Loading
Loading
Loading
+33 −1
Original line number Diff line number Diff line
@@ -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;
}
+12 −0
Original line number Diff line number Diff line
@@ -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_ */