From 80ec5489ae763ebc59ddcacc09dddb98e92121ca Mon Sep 17 00:00:00 2001 From: Changpeng Liu Date: Tue, 3 Mar 2020 00:21:47 +0800 Subject: [PATCH] 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: Changpeng Liu Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1074 Tested-by: SPDK CI Jenkins Reviewed-by: Shuhei Matsumoto Reviewed-by: Jim Harris --- include/spdk/opal_spec.h | 79 ++++++++++++++++------------------- lib/nvme/nvme_opal.c | 67 +++++++++++++---------------- lib/nvme/nvme_opal_internal.h | 10 ----- 3 files changed, 65 insertions(+), 91 deletions(-) diff --git a/include/spdk/opal_spec.h b/include/spdk/opal_spec.h index 86a31a4ec..f9e948f3b 100644 --- a/include/spdk/opal_spec.h +++ b/include/spdk/opal_spec.h @@ -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"); + +/* + * Level 0 Discovery Feature Header + */ +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_d0_tper_features { - uint16_t feature_code; - uint8_t reserved_0 : 4; - uint8_t version : 4; - uint8_t length; +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 diff --git a/lib/nvme/nvme_opal.c b/lib/nvme/nvme_opal.c index 2933404ef..867a837c4 100644 --- a/lib/nvme/nvme_opal.c +++ b/lib/nvme/nvme_opal.c @@ -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; diff --git a/lib/nvme/nvme_opal_internal.h b/lib/nvme/nvme_opal_internal.h index d03b96d67..73cc6194f 100644 --- a/lib/nvme/nvme_opal_internal.h +++ b/lib/nvme/nvme_opal_internal.h @@ -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;