Commit 01ddd112 authored by Changpeng Liu's avatar Changpeng Liu Committed by Tomasz Zawadzki
Browse files

nvme/opal: refactor level 0 discovery data structures



No actual logic change except re-define some data structures.

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


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 80ec5489
Loading
Loading
Loading
Loading
+40 −45
Original line number Diff line number Diff line
@@ -880,77 +880,72 @@ update_firmware_image(void)
}

static void
opal_dump_info(struct spdk_opal_info *opal)
opal_dump_info(struct spdk_opal_d0_features_info *feat)
{
	if (!opal->opal_ssc_dev) {
		SPDK_ERRLOG("This device is not Opal enabled. Not Supported!\n");
		return;
	}

	if (opal->tper) {
	if (feat->tper.hdr.code) {
		printf("\nOpal TPer feature:\n");
		printf("ACKNACK = %s", (opal->tper_acknack ? "Y, " : "N, "));
		printf("ASYNC = %s", (opal->tper_async ? "Y, " : "N, "));
		printf("BufferManagement = %s\n", (opal->tper_buffer_mgt ? "Y, " : "N, "));
		printf("ComIDManagement = %s", (opal->tper_comid_mgt ? "Y, " : "N, "));
		printf("Streaming = %s", (opal->tper_streaming ? "Y, " : "N, "));
		printf("Sync = %s\n", (opal->tper_sync ? "Y" : "N"));
		printf("ACKNACK = %s", (feat->tper.acknack ? "Y, " : "N, "));
		printf("ASYNC = %s", (feat->tper.async ? "Y, " : "N, "));
		printf("BufferManagement = %s\n", (feat->tper.buffer_management ? "Y, " : "N, "));
		printf("ComIDManagement = %s", (feat->tper.comid_management ? "Y, " : "N, "));
		printf("Streaming = %s", (feat->tper.streaming ? "Y, " : "N, "));
		printf("Sync = %s\n", (feat->tper.sync ? "Y" : "N"));
		printf("\n");
	}

	if (opal->locking) {
	if (feat->locking.hdr.code) {
		printf("Opal Locking feature:\n");
		printf("Locked = %s", (opal->locking_locked ? "Y, " : "N, "));
		printf("Locking Enabled = %s", (opal->locking_locking_enabled ? "Y, " : "N, "));
		printf("Locking supported = %s\n", (opal->locking_locking_supported ? "Y" : "N"));
		printf("Locked = %s", (feat->locking.locked ? "Y, " : "N, "));
		printf("Locking Enabled = %s", (feat->locking.locking_enabled ? "Y, " : "N, "));
		printf("Locking supported = %s\n", (feat->locking.locking_supported ? "Y" : "N"));

		printf("MBR done = %s", (opal->locking_mbr_done ? "Y, " : "N, "));
		printf("MBR enabled = %s", (opal->locking_mbr_enabled ? "Y, " : "N, "));
		printf("Media encrypt = %s\n", (opal->locking_media_encrypt ? "Y" : "N"));
		printf("MBR done = %s", (feat->locking.mbr_done ? "Y, " : "N, "));
		printf("MBR enabled = %s", (feat->locking.mbr_enabled ? "Y, " : "N, "));
		printf("Media encrypt = %s\n", (feat->locking.media_encryption ? "Y" : "N"));
		printf("\n");
	}

	if (opal->geometry) {
	if (feat->geo.hdr.code) {
		printf("Opal Geometry feature:\n");
		printf("Align = %s", (opal->geometry_align ? "Y, " : "N, "));
		printf("Logical block size = %d, ", opal->geometry_logical_block_size);
		printf("Lowest aligned LBA = %ld\n", opal->geometry_lowest_aligned_lba);
		printf("Align = %s", (feat->geo.alignment_granularity ? "Y, " : "N, "));
		printf("Logical block size = %d, ", from_be32(&feat->geo.logical_block_size));
		printf("Lowest aligned LBA = %ld\n", from_be64(&feat->geo.lowest_aligned_lba));
		printf("\n");
	}

	if (opal->single_user_mode) {
	if (feat->single_user.hdr.code) {
		printf("Opal Single User Mode feature:\n");
		printf("Any in SUM = %s", (opal->single_user_any ? "Y, " : "N, "));
		printf("All in SUM = %s", (opal->single_user_all ? "Y, " : "N, "));
		printf("Policy: %s Authority,\n", (opal->single_user_policy ? "Admin" : "Users"));
		printf("Number of locking objects = %d\n ", opal->single_user_locking_objects);
		printf("Any in SUM = %s", (feat->single_user.any ? "Y, " : "N, "));
		printf("All in SUM = %s", (feat->single_user.all ? "Y, " : "N, "));
		printf("Policy: %s Authority,\n", (feat->single_user.policy ? "Admin" : "Users"));
		printf("Number of locking objects = %d\n ", from_be32(&feat->single_user.num_locking_objects));
		printf("\n");
	}

	if (opal->datastore) {
	if (feat->datastore.hdr.code) {
		printf("Opal DataStore feature:\n");
		printf("Table alignment = %d, ", opal->datastore_alignment);
		printf("Max number of tables = %d, ", opal->datastore_max_tables);
		printf("Max size of tables = %d\n", opal->datastore_max_table_size);
		printf("Table alignment = %d, ", from_be32(&feat->datastore.alignment));
		printf("Max number of tables = %d, ", from_be16(&feat->datastore.max_tables));
		printf("Max size of tables = %d\n", from_be32(&feat->datastore.max_table_size));
		printf("\n");
	}

	if (opal->opal_v100) {
	if (feat->v100.hdr.code) {
		printf("Opal V100 feature:\n");
		printf("Base comID = %d, ", opal->opal_v100_base_comid);
		printf("Number of comIDs = %d, ", opal->opal_v100_num_comid);
		printf("Range crossing = %s\n", (opal->opal_v100_range_crossing ? "N" : "Y"));
		printf("Base comID = %d, ", from_be16(&feat->v100.base_comid));
		printf("Number of comIDs = %d, ", from_be16(&feat->v100.number_comids));
		printf("Range crossing = %s\n", (feat->v100.range_crossing ? "N" : "Y"));
		printf("\n");
	}

	if (opal->opal_v200) {
	if (feat->v200.hdr.code) {
		printf("Opal V200 feature:\n");
		printf("Base comID = %d, ", opal->opal_v200_base_comid);
		printf("Number of comIDs = %d, ", opal->opal_v200_num_comid);
		printf("Initial PIN = %d,\n", opal->opal_v200_initial_pin);
		printf("Reverted PIN = %d, ", opal->opal_v200_reverted_pin);
		printf("Number of admins = %d, ", opal->opal_v200_num_admin);
		printf("Number of users = %d\n", opal->opal_v200_num_user);
		printf("Base comID = %d, ", from_be16(&feat->v200.base_comid));
		printf("Number of comIDs = %d, ", from_be16(&feat->v200.num_comids));
		printf("Initial PIN = %d,\n", feat->v200.initial_pin);
		printf("Reverted PIN = %d, ", feat->v200.reverted_pin);
		printf("Number of admins = %d, ", from_be16(&feat->v200.num_locking_admin_auth));
		printf("Number of users = %d\n", from_be16(&feat->v200.num_locking_user_auth));
		printf("\n");
	}
}
@@ -987,7 +982,7 @@ opal_scan(struct dev *iter)
			printf("\n\nOpal Supported:\n");
			display_controller(iter, CONTROLLER_DISPLAY_SIMPLISTIC);
			spdk_opal_cmd_scan(iter->opal_dev);
			opal_dump_info(spdk_opal_get_info(iter->opal_dev));
			opal_dump_info(spdk_opal_get_d0_features_info(iter->opal_dev));
		}
		spdk_opal_close(iter->opal_dev);
	} else {
+10 −45
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#include "spdk/log.h"
#include "spdk/endian.h"
#include "spdk/string.h"
#include "spdk/opal_spec.h"

#define SPDK_OPAL_NOT_SUPPORTED 0xFF

@@ -72,50 +73,14 @@ static const char *const spdk_opal_errors[] = {
	"AUTHORITY LOCKED OUT",
};

struct spdk_opal_info {
	uint8_t tper : 1;
	uint8_t locking : 1;
	uint8_t geometry : 1;
	uint8_t single_user_mode : 1;
	uint8_t datastore : 1;
	uint8_t opal_v200 : 1;
	uint8_t opal_v100 : 1;
	uint8_t vendor_specific : 1;
	uint8_t opal_ssc_dev : 1;
	uint8_t tper_acknack : 1;
	uint8_t tper_async : 1;
	uint8_t tper_buffer_mgt : 1;
	uint8_t tper_comid_mgt : 1;
	uint8_t tper_streaming : 1;
	uint8_t tper_sync : 1;
	uint8_t locking_locked : 1;
	uint8_t locking_locking_enabled : 1;
	uint8_t locking_locking_supported : 1;
	uint8_t locking_mbr_done : 1;
	uint8_t locking_mbr_enabled : 1;
	uint8_t locking_media_encrypt : 1;
	uint8_t geometry_align : 1;
	uint64_t geometry_alignment_granularity;
	uint32_t geometry_logical_block_size;
	uint64_t geometry_lowest_aligned_lba;
	uint8_t single_user_any : 1;
	uint8_t single_user_all : 1;
	uint8_t single_user_policy : 1;
	uint32_t single_user_locking_objects;
	uint16_t datastore_max_tables;
	uint32_t datastore_max_table_size;
	uint32_t datastore_alignment;
	uint16_t opal_v100_base_comid;
	uint16_t opal_v100_num_comid;
	uint8_t opal_v100_range_crossing : 1;
	uint16_t opal_v200_base_comid;
	uint16_t opal_v200_num_comid;
	uint8_t opal_v200_initial_pin;
	uint8_t opal_v200_reverted_pin;
	uint16_t opal_v200_num_admin;
	uint16_t opal_v200_num_user;
	uint8_t opal_v200_range_crossing : 1;
	uint16_t vu_feature_code; /* vendor specific feature */
struct spdk_opal_d0_features_info {
	struct spdk_opal_d0_tper_feat tper;
	struct spdk_opal_d0_locking_feat locking;
	struct spdk_opal_d0_single_user_mode_feat single_user;
	struct spdk_opal_d0_geo_feat geo;
	struct spdk_opal_d0_datastore_feat datastore;
	struct spdk_opal_d0_v100_feat v100;
	struct spdk_opal_d0_v200_feat v200;
};

enum spdk_opal_lock_state {
@@ -169,7 +134,7 @@ typedef void (*spdk_opal_revert_cb)(struct spdk_opal_dev *dev, void *ctx, int rc
struct spdk_opal_dev *spdk_opal_init_dev(void *dev_handler);

void spdk_opal_close(struct spdk_opal_dev *dev);
struct spdk_opal_info *spdk_opal_get_info(struct spdk_opal_dev *dev);
struct spdk_opal_d0_features_info *spdk_opal_get_d0_features_info(struct spdk_opal_dev *dev);

bool spdk_opal_supported(struct spdk_opal_dev *dev);

+10 −63
Original line number Diff line number Diff line
@@ -747,16 +747,8 @@ static void
opal_check_tper(struct spdk_opal_dev *dev, const void *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;
	opal_info->tper = 1;
	opal_info->tper_acknack = tper->acknack;
	opal_info->tper_async = tper->async;
	opal_info->tper_buffer_mgt = tper->buffer_management;
	opal_info->tper_comid_mgt = tper->comid_management;
	opal_info->tper_streaming = tper->streaming;
	opal_info->tper_sync = tper->sync;
	dev->feat_info.tper = *tper;
}

/*
@@ -767,18 +759,13 @@ opal_check_sum(struct spdk_opal_dev *dev, const void *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;

	if (num_locking_objects == 0) {
		SPDK_NOTICELOG("Need at least one locking object.\n");
		return false;
	}

	opal_info->single_user_mode = 1;
	opal_info->single_user_locking_objects = num_locking_objects;
	opal_info->single_user_any = sum->any;
	opal_info->single_user_all = sum->all;
	opal_info->single_user_policy = sum->policy;
	dev->feat_info.single_user = *sum;

	return true;
}
@@ -787,58 +774,38 @@ static void
opal_check_lock(struct spdk_opal_dev *dev, const void *data)
{
	const struct spdk_opal_d0_locking_feat *lock = data;
	struct spdk_opal_info *opal_info = dev->opal_info;

	opal_info->locking = 1;
	opal_info->locking_locked = lock->locked;
	opal_info->locking_locking_enabled = lock->locking_enabled;
	opal_info->locking_locking_supported = lock->locking_supported;
	opal_info->locking_mbr_done = lock->mbr_done;
	opal_info->locking_mbr_enabled = lock->mbr_enabled;
	opal_info->locking_media_encrypt = lock->media_encryption;
	dev->feat_info.locking = *lock;
}

static void
opal_check_geometry(struct spdk_opal_dev *dev, const void *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);

	dev->align = align;
	dev->lowest_lba = lowest_lba;

	opal_info->geometry = 1;
	opal_info->geometry_align = geo->align;
	opal_info->geometry_logical_block_size = from_be32(&geo->logical_block_size);
	opal_info->geometry_lowest_aligned_lba = lowest_lba;
	opal_info->geometry_alignment_granularity = align;
	dev->feat_info.geo = *geo;
}

static void
opal_check_datastore(struct spdk_opal_dev *dev, const void *data)
{
	const struct spdk_opal_d0_datastore_feat *datastore = data;
	struct spdk_opal_info *opal_info = dev->opal_info;

	opal_info->datastore = 1;
	opal_info->datastore_max_tables = from_be16(&datastore->max_tables);
	opal_info->datastore_max_table_size = from_be32(&datastore->max_table_size);
	opal_info->datastore_alignment = from_be32(&datastore->alignment);
	dev->feat_info.datastore = *datastore;
}

static uint16_t
opal_get_comid_v100(struct spdk_opal_dev *dev, const void *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);

	opal_info->opal_v100 = 1;
	opal_info->opal_v100_base_comid = base_comid;
	opal_info->opal_v100_num_comid = from_be16(&v100->number_comids);
	opal_info->opal_v100_range_crossing = v100->range_crossing;
	dev->feat_info.v100 = *v100;

	return base_comid;
}
@@ -847,18 +814,9 @@ static uint16_t
opal_get_comid_v200(struct spdk_opal_dev *dev, const void *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);

	opal_info->opal_v200 = 1;
	opal_info->opal_v200_base_comid = base_comid;
	opal_info->opal_v200_num_comid = from_be16(&v200->num_comids);
	opal_info->opal_v200_range_crossing = v200->range_crossing;
	opal_info->opal_v200_num_admin = from_be16(&v200->num_locking_admin_auth);
	opal_info->opal_v200_num_user = from_be16(&v200->num_locking_user_auth);

	opal_info->opal_v200_initial_pin = v200->initial_pin;
	opal_info->opal_v200_reverted_pin = v200->reverted_pin;
	dev->feat_info.v200 = *v200;

	return base_comid;
}
@@ -999,7 +957,6 @@ spdk_opal_close(struct spdk_opal_dev *dev)
			spdk_opal_free_locking_range_info(dev, i);
		}
	}
	free(dev->opal_info);
	free(dev);
}

@@ -1886,7 +1843,6 @@ struct spdk_opal_dev *
spdk_opal_init_dev(void *dev_handler)
{
	struct spdk_opal_dev *dev;
	struct spdk_opal_info *info;

	dev = calloc(1, sizeof(*dev));
	if (!dev) {
@@ -1896,14 +1852,6 @@ spdk_opal_init_dev(void *dev_handler)

	dev->dev_handler = dev_handler;

	info = calloc(1, sizeof(struct spdk_opal_info));
	if (info == NULL) {
		free(dev);
		SPDK_ERRLOG("Memory allocation failed\n");
		return NULL;
	}

	dev->opal_info = info;
	if (opal_check_support(dev) != 0) {
		SPDK_INFOLOG(SPDK_LOG_OPAL, "Opal is not supported on this device\n");
		dev->supported = false;
@@ -1911,7 +1859,6 @@ spdk_opal_init_dev(void *dev_handler)

	if (pthread_mutex_init(&dev->mutex_lock, NULL)) {
		SPDK_ERRLOG("Mutex init failed\n");
		free(dev->opal_info);
		free(dev);
		return NULL;
	}
@@ -2630,10 +2577,10 @@ end:
	return ret;
}

struct spdk_opal_info *
spdk_opal_get_info(struct spdk_opal_dev *dev)
struct spdk_opal_d0_features_info *
spdk_opal_get_d0_features_info(struct spdk_opal_dev *dev)
{
	return dev->opal_info;
	return &dev->feat_info;
}

bool
+1 −1
Original line number Diff line number Diff line
@@ -284,7 +284,7 @@ struct spdk_opal_dev {
	size_t prev_d_len;
	void *prev_data;

	struct spdk_opal_info *opal_info;
	struct spdk_opal_d0_features_info feat_info;

	uint64_t timeout;   /* seconds */
	uint8_t max_ranges; /* max locking range number */