From 01ddd1120a929b81ee8f5475e226232a2250b1e4 Mon Sep 17 00:00:00 2001 From: Changpeng Liu Date: Tue, 3 Mar 2020 21:02:26 +0800 Subject: [PATCH] nvme/opal: refactor level 0 discovery data structures No actual logic change except re-define some data structures. Change-Id: Id0a483071591beee675cbc3ef368ac1fb723cfe0 Signed-off-by: Changpeng Liu Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1099 Tested-by: SPDK CI Jenkins Reviewed-by: Shuhei Matsumoto Reviewed-by: Jim Harris --- examples/nvme/nvme_manage/nvme_manage.c | 85 ++++++++++++------------- include/spdk/opal.h | 55 +++------------- lib/nvme/nvme_opal.c | 73 +++------------------ lib/nvme/nvme_opal_internal.h | 2 +- 4 files changed, 61 insertions(+), 154 deletions(-) diff --git a/examples/nvme/nvme_manage/nvme_manage.c b/examples/nvme/nvme_manage/nvme_manage.c index fbb568102..e765b709d 100644 --- a/examples/nvme/nvme_manage/nvme_manage.c +++ b/examples/nvme/nvme_manage/nvme_manage.c @@ -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 { diff --git a/include/spdk/opal.h b/include/spdk/opal.h index e0e59a19b..95c253c4e 100644 --- a/include/spdk/opal.h +++ b/include/spdk/opal.h @@ -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); diff --git a/lib/nvme/nvme_opal.c b/lib/nvme/nvme_opal.c index 867a837c4..b31dd85fc 100644 --- a/lib/nvme/nvme_opal.c +++ b/lib/nvme/nvme_opal.c @@ -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 diff --git a/lib/nvme/nvme_opal_internal.h b/lib/nvme/nvme_opal_internal.h index 73cc6194f..83bdafbfa 100644 --- a/lib/nvme/nvme_opal_internal.h +++ b/lib/nvme/nvme_opal_internal.h @@ -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 */