Commit 80ec5489 authored by Changpeng Liu's avatar Changpeng Liu Committed by Tomasz Zawadzki
Browse files

opal_spec: optimize level 0 discovery data structure definition



Also uses ComPacket header to check the received data, no actual
function changes.

Change-Id: I905fc6b8bb4656d48d43ff4ff8d1f705b9b595b9
Signed-off-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1074


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 996248fd
Loading
Loading
Loading
Loading
+35 −44
Original line number Diff line number Diff line
@@ -186,24 +186,33 @@ enum spdk_opal_token {
 * TCG Storage Architecture Core Spec v2.01 r1.00
 * Table-39 Level0 Discovery Header Format
 */
struct spdk_d0_header {
struct spdk_opal_d0_hdr {
	uint32_t length;
	uint32_t revision;
	uint32_t reserved_0;
	uint32_t reserved_1;
	uint8_t vendor_specfic[32];
};
SPDK_STATIC_ASSERT(sizeof(struct spdk_d0_header) == 48, "Incorrect size");
SPDK_STATIC_ASSERT(sizeof(struct spdk_opal_d0_hdr) == 48, "Incorrect size");

/*
 * TCG Storage Architecture Core Spec v2.01 r1.00
 * Table-42 TPer Feature Descriptor
 * Level 0 Discovery Feature Header
 */
struct __attribute__((packed)) spdk_d0_tper_features {
	uint16_t feature_code;
	uint8_t reserved_0 : 4;
struct spdk_opal_d0_feat_hdr {
	uint16_t	code;
	uint8_t		reserved : 4;
	uint8_t		version : 4;
	uint8_t		length;
};
SPDK_STATIC_ASSERT(sizeof(struct spdk_opal_d0_feat_hdr) == 4, "Incorrect size");


/*
 * TCG Storage Architecture Core Spec v2.01 r1.00
 * Table-42 TPer Feature Descriptor
 */
struct __attribute__((packed)) spdk_opal_d0_tper_feat {
	struct spdk_opal_d0_feat_hdr hdr;
	uint8_t sync : 1;
	uint8_t async : 1;
	uint8_t acknack : 1;
@@ -217,17 +226,14 @@ struct __attribute__((packed)) spdk_d0_tper_features {
	uint32_t reserved_4;
	uint32_t reserved_5;
};
SPDK_STATIC_ASSERT(sizeof(struct spdk_d0_tper_features) == 16, "Incorrect size");
SPDK_STATIC_ASSERT(sizeof(struct spdk_opal_d0_tper_feat) == 16, "Incorrect size");

/*
 * TCG Storage Architecture Core Spec v2.01 r1.00
 * Table-43 Locking Feature Descriptor
 */
struct __attribute__((packed)) spdk_d0_locking_features {
	uint16_t feature_code;
	uint8_t reserved_0 : 4;
	uint8_t version : 4;
	uint8_t length;
struct __attribute__((packed)) spdk_opal_d0_locking_feat {
	struct spdk_opal_d0_feat_hdr hdr;
	uint8_t locking_supported : 1;
	uint8_t locking_enabled : 1;
	uint8_t locked : 1;
@@ -241,17 +247,14 @@ struct __attribute__((packed)) spdk_d0_locking_features {
	uint32_t reserved_4;
	uint32_t reserved_5;
};
SPDK_STATIC_ASSERT(sizeof(struct spdk_d0_locking_features) == 16, "Incorrect size");
SPDK_STATIC_ASSERT(sizeof(struct spdk_opal_d0_locking_feat) == 16, "Incorrect size");

/*
 * TCG Storage Opal Feature Set Single User Mode v1.00 r2.00
 * 4.2.1 Single User Mode Feature Descriptor
 */
struct __attribute__((packed)) spdk_d0_sum {
	uint16_t feature_code;
	uint8_t reserved_0 : 4;
	uint8_t version : 4;
	uint8_t length;
struct __attribute__((packed)) spdk_opal_d0_single_user_mode_feat {
	struct spdk_opal_d0_feat_hdr hdr;
	uint32_t num_locking_objects;
	uint8_t any : 1;
	uint8_t all : 1;
@@ -262,17 +265,14 @@ struct __attribute__((packed)) spdk_d0_sum {
	uint16_t reserved_3;
	uint32_t reserved_4;
};
SPDK_STATIC_ASSERT(sizeof(struct spdk_d0_sum) == 16, "Incorrect size");
SPDK_STATIC_ASSERT(sizeof(struct spdk_opal_d0_single_user_mode_feat) == 16, "Incorrect size");

/*
 * TCG Storage Opal v2.01 r1.00
 * 3.1.1.4 Geometry Reporting Feature
 */
struct __attribute__((packed)) spdk_d0_geo_features {
	uint16_t feature_code;
	uint8_t reserved_0 : 4;
	uint8_t version : 4;
	uint8_t length;
struct __attribute__((packed)) spdk_opal_d0_geo_feat {
	struct spdk_opal_d0_feat_hdr hdr;
	uint8_t align : 1;
	uint8_t reserved_1 : 7;
	uint8_t reserved_2[7];
@@ -280,33 +280,27 @@ struct __attribute__((packed)) spdk_d0_geo_features {
	uint64_t alignment_granularity;
	uint64_t lowest_aligned_lba;
};
SPDK_STATIC_ASSERT(sizeof(struct spdk_d0_geo_features) == 32, "Incorrect size");
SPDK_STATIC_ASSERT(sizeof(struct spdk_opal_d0_geo_feat) == 32, "Incorrect size");

/*
 * TCG Storage Opal Feature Set Additional DataStore Tables v1.00 r1.00
 * 4.1.1 DataStore Table Feature Descriptor
 */
struct __attribute__((packed)) spdk_d0_datastore_features {
	uint16_t feature_code;
	uint8_t reserved_0 : 4;
	uint8_t version : 4;
	uint8_t length;
struct __attribute__((packed)) spdk_opal_d0_datastore_feat {
	struct spdk_opal_d0_feat_hdr hdr;
	uint16_t reserved_1;
	uint16_t max_tables;
	uint32_t max_table_size;
	uint32_t alignment;
};
SPDK_STATIC_ASSERT(sizeof(struct spdk_d0_datastore_features) == 16, "Incorrect size");
SPDK_STATIC_ASSERT(sizeof(struct spdk_opal_d0_datastore_feat) == 16, "Incorrect size");

/*
 * Opal SSC 1.00 r3.00 Final
 * 3.1.1.4 Opal SSC Feature
 */
struct __attribute__((packed)) spdk_d0_opal_v100 {
	uint16_t feature_code;
	uint8_t reserved_0 : 4;
	uint8_t version : 4;
	uint8_t length;
struct __attribute__((packed)) spdk_opal_d0_v100_feat {
	struct spdk_opal_d0_feat_hdr hdr;
	uint16_t base_comid;
	uint16_t number_comids;
	uint8_t range_crossing : 1;
@@ -317,18 +311,15 @@ struct __attribute__((packed)) spdk_d0_opal_v100 {
	uint32_t reserved_4;
	uint32_t reserved_5;
};
SPDK_STATIC_ASSERT(sizeof(struct spdk_d0_opal_v100) == 20, "Incorrect size");
SPDK_STATIC_ASSERT(sizeof(struct spdk_opal_d0_v100_feat) == 20, "Incorrect size");

/*
 * TCG Storage Opal v2.01 r1.00
 * 3.1.1.4 Geometry Reporting Feature
 * 3.1.1.5 Opal SSC V2.00 Feature
 */
struct __attribute__((packed)) spdk_d0_opal_v200 {
	uint16_t featureCode;
	uint8_t reserved_0 : 4;
	uint8_t version : 4;
	uint8_t length;
struct __attribute__((packed)) spdk_opal_d0_v200_feat {
	struct spdk_opal_d0_feat_hdr hdr;
	uint16_t base_comid;
	uint16_t num_comids;
	uint8_t range_crossing : 1;
@@ -341,7 +332,7 @@ struct __attribute__((packed)) spdk_d0_opal_v200 {
	uint8_t reserved_2;
	uint32_t reserved_3;
};
SPDK_STATIC_ASSERT(sizeof(struct spdk_d0_opal_v200) == 20, "Incorrect size");
SPDK_STATIC_ASSERT(sizeof(struct spdk_opal_d0_v200_feat) == 20, "Incorrect size");

/*
 * TCG Storage Architecture Core Spec v2.01 r1.00
+30 −37
Original line number Diff line number Diff line
@@ -83,7 +83,7 @@ static int
opal_recv_cmd(struct spdk_opal_dev *dev)
{
	void *response = dev->resp;
	struct spdk_opal_header *header = response;
	struct spdk_opal_compacket *header = response;
	int ret = 0;
	uint64_t start = spdk_get_ticks();
	uint64_t now;
@@ -96,11 +96,11 @@ opal_recv_cmd(struct spdk_opal_dev *dev)
			return ret;
		}
		SPDK_DEBUGLOG(SPDK_LOG_OPAL, "outstanding_data=%d, minTransfer=%d\n",
			      header->com_packet.outstanding_data,
			      header->com_packet.min_transfer);
			      header->outstanding_data,
			      header->min_transfer);

		if (header->com_packet.outstanding_data == 0 &&
		    header->com_packet.min_transfer == 0) {
		if (header->outstanding_data == 0 &&
		    header->min_transfer == 0) {
			return 0;	/* return if all the response data are ready by tper and received by host */
		} else {	/* check timeout */
			now = spdk_get_ticks();
@@ -746,7 +746,7 @@ opal_build_locking_range(uint8_t *buffer, size_t length, uint8_t locking_range)
static void
opal_check_tper(struct spdk_opal_dev *dev, const void *data)
{
	const struct spdk_d0_tper_features *tper = data;
	const struct spdk_opal_d0_tper_feat *tper = data;
	struct spdk_opal_info *opal_info = dev->opal_info;

	opal_info->opal_ssc_dev = 1;
@@ -765,7 +765,7 @@ opal_check_tper(struct spdk_opal_dev *dev, const void *data)
static bool
opal_check_sum(struct spdk_opal_dev *dev, const void *data)
{
	const struct spdk_d0_sum *sum = data;
	const struct spdk_opal_d0_single_user_mode_feat *sum = data;
	uint32_t num_locking_objects = from_be32(&sum->num_locking_objects);
	struct spdk_opal_info *opal_info = dev->opal_info;

@@ -786,7 +786,7 @@ opal_check_sum(struct spdk_opal_dev *dev, const void *data)
static void
opal_check_lock(struct spdk_opal_dev *dev, const void *data)
{
	const struct spdk_d0_locking_features *lock = data;
	const struct spdk_opal_d0_locking_feat *lock = data;
	struct spdk_opal_info *opal_info = dev->opal_info;

	opal_info->locking = 1;
@@ -801,7 +801,7 @@ opal_check_lock(struct spdk_opal_dev *dev, const void *data)
static void
opal_check_geometry(struct spdk_opal_dev *dev, const void *data)
{
	const struct spdk_d0_geo_features *geo = data;
	const struct spdk_opal_d0_geo_feat *geo = data;
	struct spdk_opal_info *opal_info = dev->opal_info;
	uint64_t align = from_be64(&geo->alignment_granularity);
	uint64_t lowest_lba = from_be64(&geo->lowest_aligned_lba);
@@ -819,7 +819,7 @@ opal_check_geometry(struct spdk_opal_dev *dev, const void *data)
static void
opal_check_datastore(struct spdk_opal_dev *dev, const void *data)
{
	const struct spdk_d0_datastore_features *datastore = data;
	const struct spdk_opal_d0_datastore_feat *datastore = data;
	struct spdk_opal_info *opal_info = dev->opal_info;

	opal_info->datastore = 1;
@@ -831,7 +831,7 @@ opal_check_datastore(struct spdk_opal_dev *dev, const void *data)
static uint16_t
opal_get_comid_v100(struct spdk_opal_dev *dev, const void *data)
{
	const struct spdk_d0_opal_v100 *v100 = data;
	const struct spdk_opal_d0_v100_feat *v100 = data;
	struct spdk_opal_info *opal_info = dev->opal_info;
	uint16_t base_comid = from_be16(&v100->base_comid);

@@ -846,7 +846,7 @@ opal_get_comid_v100(struct spdk_opal_dev *dev, const void *data)
static uint16_t
opal_get_comid_v200(struct spdk_opal_dev *dev, const void *data)
{
	const struct spdk_d0_opal_v200 *v200 = data;
	const struct spdk_opal_d0_v200_feat *v200 = data;
	struct spdk_opal_info *opal_info = dev->opal_info;
	uint16_t base_comid = from_be16(&v200->base_comid);

@@ -866,8 +866,9 @@ opal_get_comid_v200(struct spdk_opal_dev *dev, const void *data)
static int
opal_discovery0_end(struct spdk_opal_dev *dev)
{
	bool found_com_id = false, supported = false, single_user = false;
	const struct spdk_d0_header *hdr = (struct spdk_d0_header *)dev->resp;
	bool supported = false, single_user = false;
	const struct spdk_opal_d0_hdr *hdr = (struct spdk_opal_d0_hdr *)dev->resp;
	struct spdk_opal_d0_feat_hdr *feat_hdr;
	const uint8_t *epos = dev->resp, *cpos = dev->resp;
	uint16_t comid = 0;
	uint32_t hlen = from_be32(&(hdr->length));
@@ -882,40 +883,37 @@ opal_discovery0_end(struct spdk_opal_dev *dev)
	cpos += sizeof(*hdr); /* current position on buffer */

	while (cpos < epos) {
		const union spdk_discovery0_features *body =
				(const union spdk_discovery0_features *)cpos;
		uint16_t feature_code = from_be16(&(body->tper.feature_code));
		feat_hdr = (struct spdk_opal_d0_feat_hdr *)cpos;
		uint16_t feat_code = from_be16(&feat_hdr->code);

		switch (feature_code) {
		switch (feat_code) {
		case FEATURECODE_TPER:
			opal_check_tper(dev, body);
			opal_check_tper(dev, cpos);
			break;
		case FEATURECODE_SINGLEUSER:
			single_user = opal_check_sum(dev, body);
			single_user = opal_check_sum(dev, cpos);
			break;
		case FEATURECODE_GEOMETRY:
			opal_check_geometry(dev, body);
			opal_check_geometry(dev, cpos);
			break;
		case FEATURECODE_LOCKING:
			opal_check_lock(dev, body);
			opal_check_lock(dev, cpos);
			break;
		case FEATURECODE_DATASTORE:
			opal_check_datastore(dev, body);
			opal_check_datastore(dev, cpos);
			break;
		case FEATURECODE_OPALV100:
			comid = opal_get_comid_v100(dev, body);
			found_com_id = true;
			comid = opal_get_comid_v100(dev, cpos);
			supported = true;
			break;
		case FEATURECODE_OPALV200:
			comid = opal_get_comid_v200(dev, body);
			found_com_id = true;
			comid = opal_get_comid_v200(dev, cpos);
			supported = true;
			break;
		default:
			SPDK_INFOLOG(SPDK_LOG_OPAL, "Unknow feature code: %d\n", feature_code);
			SPDK_INFOLOG(SPDK_LOG_OPAL, "Unknow feature code: %d\n", feat_code);
		}
		cpos += body->tper.length + 4;
		cpos += feat_hdr->length + sizeof(*feat_hdr);
	}

	if (supported == false) {
@@ -927,11 +925,6 @@ opal_discovery0_end(struct spdk_opal_dev *dev)
		SPDK_INFOLOG(SPDK_LOG_OPAL, "Single User Mode Not Supported\n");
	}

	if (found_com_id == false) {
		SPDK_ERRLOG("Could not find OPAL comid for device. Returning early\n");
		return -EINVAL;
	}

	dev->comid = comid;
	return 0;
}
@@ -2121,7 +2114,7 @@ int
spdk_opal_revert_poll(struct spdk_opal_dev *dev)
{
	void *response = dev->resp;
	struct spdk_opal_header *header = response;
	struct spdk_opal_compacket *header = response;
	int ret;

	assert(dev->revert_cb_fn);
@@ -2134,8 +2127,8 @@ spdk_opal_revert_poll(struct spdk_opal_dev *dev)
		return 0;
	}

	if (header->com_packet.outstanding_data == 0 &&
	    header->com_packet.min_transfer == 0) {
	if (header->outstanding_data == 0 &&
	    header->min_transfer == 0) {
		ret = opal_parse_and_check_status(dev, NULL);
		dev->revert_cb_fn(dev, dev->ctx, ret);
		return 0;
+0 −10
Original line number Diff line number Diff line
@@ -118,16 +118,6 @@ enum opal_method_enum {
	RANDOM_METHOD,
};

union spdk_discovery0_features {
	struct spdk_d0_tper_features tper;
	struct spdk_d0_locking_features locking;
	struct spdk_d0_geo_features geometry;
	struct spdk_d0_datastore_features datastore;
	struct spdk_d0_sum  sumode;
	struct spdk_d0_opal_v200 opalv200;
	struct spdk_d0_opal_v100 opalv100;
};

struct opal_common_session {
	uint32_t sum; /* single user mode */
	uint32_t who;