From db6b0b80abcbde56c371b392404f73bef2a0d72d Mon Sep 17 00:00:00 2001 From: Greg Joyce Date: Tue, 25 Feb 2025 17:48:21 -0600 Subject: [PATCH] sed: extended discovery feature code printing Added ability to discover and print details of all specified level 0 features. Signed-off-by: Greg Joyce --- plugins/sed/sed.c | 10 +- plugins/sed/sedopal_cmd.c | 508 +++++++++++++++++++++++++++++++++++-- plugins/sed/sedopal_cmd.h | 2 + plugins/sed/sedopal_spec.h | 313 ++++++++++++++++++++++- 4 files changed, 798 insertions(+), 35 deletions(-) diff --git a/plugins/sed/sed.c b/plugins/sed/sed.c index a616cf2270..695ed94169 100644 --- a/plugins/sed/sed.c +++ b/plugins/sed/sed.c @@ -50,6 +50,14 @@ OPT_ARGS(lock_opts) = { OPT_END() }; +OPT_ARGS(discovery_opts) = { + OPT_FLAG("verbose", 'v', &sedopal_discovery_verbose, + "Print extended discovery information"), + OPT_FLAG("udev", 'u', &sedopal_discovery_udev, + "Print locking information in form suitable for udev rules"), + OPT_END() +}; + /* * Open the NVMe device specified on the command line. It must be the * NVMe block device (e.g. /dev/nvme0n1). @@ -80,7 +88,7 @@ static int sed_opal_discover(int argc, char **argv, struct command *cmd, const char *desc = "Query SED device and display locking features"; struct nvme_dev *dev; - err = sed_opal_open_device(&dev, argc, argv, desc, no_opts); + err = sed_opal_open_device(&dev, argc, argv, desc, discovery_opts); if (err) return err; diff --git a/plugins/sed/sedopal_cmd.c b/plugins/sed/sedopal_cmd.c index 63dbf11996..9d60853a71 100644 --- a/plugins/sed/sedopal_cmd.c +++ b/plugins/sed/sedopal_cmd.c @@ -39,6 +39,36 @@ bool sedopal_psid_revert; */ bool sedopal_lock_ro; +/* + * Verbose discovery + */ +bool sedopal_discovery_verbose; + +/* + * discovery with udev output + */ +bool sedopal_discovery_udev; + +struct sedopal_feature_parser { + uint32_t features; + void *tper_desc; + void *locking_desc; + void *geometry_reporting_desc; + void *opalv1_desc; + void *single_user_mode_desc; + void *datastore_desc; + void *opalv2_desc; + void *opalite_desc; + void *pyrite_v1_desc; + void *pyrite_v2_desc; + void *ruby_desc; + void *locking_lba_desc; + void *block_sid_auth_desc; + void *config_ns_desc; + void *data_removal_desc; + void *ns_geometry_desc; +}; + /* * Map method status codes to error text */ @@ -484,15 +514,447 @@ int sedopal_cmd_password(int fd) /* * Print the state of locking features. */ -void sedopal_print_locking_features(uint8_t features) +void sedopal_print_locking_features(void *data) +{ + struct locking_desc *ld = (struct locking_desc *)data; + uint8_t features = ld->features; + + if (!sedopal_discovery_udev) { + printf("Locking Features:\n"); + printf("\tLocking Supported : %s\n", + (features & OPAL_FEATURE_LOCKING_SUPPORTED) ? + "yes" : "no"); + printf("\tLocking Feature Enabled : %s\n", + (features & OPAL_FEATURE_LOCKING_ENABLED) ? + "yes" : "no"); + printf("\tLocked : %s\n", + (features & OPAL_FEATURE_LOCKED) ? "yes" : "no"); + printf("\tMedia Encryption : %s\n", + (features & OPAL_FEATURE_MEDIA_ENCRYPT) ? "yes" : "no"); + printf("\tMBR Enabled : %s\n", + (features & OPAL_FEATURE_MBR_ENABLED) ? "yes" : "no"); + printf("\tMBR Done : %s\n", + (features & OPAL_FEATURE_MBR_DONE) ? "yes" : "no"); + } else { + printf("DEV_SED_LOCKED=%s\n", + (features & OPAL_FEATURE_LOCKING_ENABLED) ? + "ENABLED" : "DISABLED"); + printf("DEV_SED_LOCKING=%s\n", + (features & OPAL_FEATURE_LOCKING_ENABLED) ? + "ENABLED" : "DISABLED"); + printf("DEV_SED_LOCKING_SUPP=%s\n", + (features & OPAL_FEATURE_LOCKING_SUPPORTED) ? + "ENABLED" : "DISABLED"); + printf("DEV_SED_LOCKING_LOCKED=%s\n", + (features & OPAL_FEATURE_LOCKED) ? + "ENABLED" : "DISABLED"); + } +} + +/* + * Print the TPer feature. + */ +void sedopal_print_tper(void *data) +{ + struct tper_desc *td = (struct tper_desc *)data; + + printf("\nSED TPER:\n"); + printf("\tSync Supported : %s\n", + (td->feature & TPER_FEATURE_SYNC) ? "yes" : "no"); + printf("\tAsync Supported : %s\n", + (td->feature & TPER_FEATURE_ASYNC) ? "yes" : "no"); + printf("\tACK/NAK Supported : %s\n", + (td->feature & TPER_FEATURE_ACKNAK) ? "yes" : "no"); + printf("\tBuffer Management Supported : %s\n", + (td->feature & TPER_FEATURE_BUF_MGMT) ? "yes" : "no"); + printf("\tStreaming Supported : %s\n", + (td->feature & TPER_FEATURE_STREAMING) ? "yes" : "no"); + printf("\tComID Management Supported : %s\n", + (td->feature & TPER_FEATURE_COMID_MGMT) ? "yes" : "no"); +} + +/* + * Print the Geometry feature. + */ +void sedopal_print_geometry(void *data) +{ + struct geometry_reporting_desc *gd; + + gd = (struct geometry_reporting_desc *)data; + + printf("\nSED Geometry:\n"); + printf("\tAlignment Required : %s\n", + (gd->align & GEOMETRY_ALIGNMENT_REQUIRED) ? "yes" : "no"); + printf("\tLogical Block Size : %u\n", + be32toh(gd->logical_block_size)); + printf("\tAlignment Granularity : %lx\n", + be64toh(gd->alignment_granularity)); + printf("\tLowest Aligned LBA : %lx\n", + be64toh(gd->lowest_aligned_lba)); +} + +/* + * Print the opal v1 feature. + */ +void sedopal_print_opal_v1(void *data) +{ + struct opalv1_desc *v1d = (struct opalv1_desc *)data; + + printf("\nSED OPAL V1.0:\n"); + printf("\tBase Comid : %d\n", + be16toh(v1d->base_comid)); + printf("\tNumber of Comids : %d\n", + be16toh(v1d->num_comids)); +} + +/* + * Print the opal v2 feature. + */ +void sedopal_print_opal_v2(void *data) +{ + struct opalv2_desc *v2d = (struct opalv2_desc *)data; + + printf("\nSED OPAL V2.0:\n"); + printf("\tRange Crossing : %d\n", + !(v2d->flags & OPAL_V2_RANGE_CROSSING)); + printf("\tBase Comid : %d\n", + be16toh(v2d->base_comid)); + printf("\tNumber of Comids : %d\n", + be16toh(v2d->num_comids)); + printf("\tNumber of Admin Authorities : %d\n", + be16toh(v2d->num_locking_sp_admin_auth)); + printf("\tNumber of User Authorities : %d\n", + be16toh(v2d->num_locking_sp_user_auth)); + printf("\tInit pin : %d\n", + v2d->initial_cpin_sid_ind); + printf("\tRevert pin : %d\n", + v2d->initial_cpin_sid_revert); +} + +/* + * Print the ruby feature. + */ +void sedopal_print_ruby(void *data) { - printf("Locking Features:\n"); - printf("\tLocking Supported: %s\n", - (features & OPAL_FEATURE_LOCKING_SUPPORTED) ? "Yes" : "No"); - printf("\tLocking Feature Enabled: %s\n", - (features & OPAL_FEATURE_LOCKING_ENABLED) ? "Yes" : "No"); - printf("\tLocked: %s\n", - (features & OPAL_FEATURE_LOCKED) ? "Yes" : "No"); + struct ruby_desc *rd = (struct ruby_desc *)data; + + printf("\nRuby:\n"); + printf("\tRange Crossing : %d\n", + !(rd->flags & RUBY_RANGE_CROSSING)); + printf("\tBase Comid : %d\n", + be16toh(rd->base_comid)); + printf("\tNumber of Comids : %d\n", + be16toh(rd->num_comids)); + printf("\tNumber of Admin Authorities : %d\n", + be16toh(rd->num_locking_sp_admin_auth)); + printf("\tNumber of User Authorities : %d\n", + be16toh(rd->num_locking_sp_user_auth)); + printf("\tInit pin : %d\n", + rd->initial_cpin_sid_ind); + printf("\tRevert pin : %d\n", + rd->initial_cpin_sid_revert); +} + +/* + * Print the opalite feature. + */ +void sedopal_print_opalite(void *data) +{ + struct opalite_desc *old = (struct opalite_desc *)data; + + printf("\nSED Opalite:\n"); + printf("\tBase Comid : %d\n", + be16toh(old->base_comid)); + printf("\tNumber of Comids : %d\n", + be16toh(old->num_comids)); + printf("\tInit pin : %d\n", + old->initial_cpin_sid_ind); + printf("\tRevert pin : %d\n", + old->initial_cpin_sid_revert); +} + +/* + * Print the pyrite v1 feature. + */ +void sedopal_print_pyrite_v1(void *data) +{ + struct pyrite_v1_desc *p1d = (struct pyrite_v1_desc *)data; + + printf("\nPyrite V1:\n"); + printf("\tBase Comid : %d\n", + be16toh(p1d->base_comid)); + printf("\tNumber of Comids : %d\n", + be16toh(p1d->num_comids)); + printf("\tInit pin : %d\n", + p1d->initial_cpin_sid_ind); + printf("\tRevert pin : %d\n", + p1d->initial_cpin_sid_revert); +} + +/* + * Print the pyrite v2 feature. + */ +void sedopal_print_pyrite_v2(void *data) +{ + struct pyrite_v2_desc *p2d = (struct pyrite_v2_desc *)data; + + printf("\nPyrite V2:\n"); + printf("\tBase Comid : %d\n", + be16toh(p2d->base_comid)); + printf("\tNumber of Comids : %d\n", + be16toh(p2d->num_comids)); + printf("\tInit pin : %d\n", + p2d->initial_cpin_sid_ind); + printf("\tRevert pin : %d\n", + p2d->initial_cpin_sid_revert); +} + +/* + * Print the single user mode feature. + */ +void sedopal_print_sum(void *data) +{ + struct single_user_mode_desc *sumd; + + sumd = (struct single_user_mode_desc *)data; + + printf("\nSingle User Mode (SUM):\n"); + printf("\tNumber of Locking Objects : %u\n", + be32toh(sumd->num_locking_objects)); + printf("\tAny Locking Objects in SUM? : %s\n", + (sumd->flags & SUM_FEATURE_ANY) ? "yes" : "no"); + printf("\tAll Locking Objects in SUM? : %s\n", + (sumd->flags & SUM_FEATURE_ALL) ? "yes" : "no"); + printf("\tUser Authority of Objects : %s\n", + (sumd->flags & SUM_FEATURE_POLICY) ? "yes" : "no"); +} + +/* + * Print the data store table feature. + */ +void sedopal_print_datastore(void *data) +{ + struct datastore_desc *dsd = (struct datastore_desc *)data; + + printf("\nData Store Table:\n"); + printf("\tNumber of Tables Supported : %u\n", + be16toh(dsd->max_tables)); + printf("\tMax Size of Tables : %u\n", + be32toh(dsd->max_table_size)); + printf("\tTable Size Alignment : %u\n", + be32toh(dsd->table_alignment)); +} + +/* + * Print the block SID authentication feature. + */ +void sedopal_print_sid_auth(void *data) +{ + struct block_sid_auth_desc *sid_auth_d; + + sid_auth_d = (struct block_sid_auth_desc *)data; + + printf("\nSED Block SID Authentication:\n"); + printf("\tSID value equal MSID : %s\n", + (sid_auth_d->states & BLOCK_SID_VALUE_STATE) ? "yes" : "no"); + printf("\tSID auth blocked : %s\n", + (sid_auth_d->states & BLOCK_SID_BLOCKED_STATE) ? "yes" : "no"); + printf("\tHW reset selected : %s\n", + (sid_auth_d->hw_reset & BLOCK_SID_HW_RESET) ? "yes" : "no"); +} + +/* + * Print the Locking LBA Ranges Control feature + */ +void sedopal_print_locking_lba(void *data) +{ + /* + * There currently isn't any definition of the level 0 content + * of this feature, so defer any printing. + */ +} + +/* + * Print the configurable namespace locking feature. + */ +void sedopal_print_config_ns(void *data) +{ + struct config_ns_desc *nsd = (struct config_ns_desc *)data; + + printf("\nSED Configurable Namespace Locking:\n"); + printf("\tNon-global Locking Support : %s\n", + (nsd->flags & CONFIG_NS_RANGE_C) ? "yes" : "no"); + printf("\tNon-global Lock objects exist : %s\n", + (nsd->flags & CONFIG_NS_RANGE_P) ? "yes" : "no"); + printf("\tMaximum Key Count : %d\n", + be32toh(nsd->max_key_count)); + printf("\tUnused Key Count : %d\n", + be32toh(nsd->unused_key_count)); +} + +/* + * Print the data removal mechanism feature. + */ +void sedopal_print_data_removal(void *data) +{ + struct data_removal_desc *drd = (struct data_removal_desc *)data; + + printf("\nSED Data Removal Mechanism:\n"); + printf("\tRemoval Operation Processing : %s\n", + (drd->flags & DATA_REMOVAL_OPER_PROCESSING) ? "yes" : "no"); + printf("\tRemoval Operation Interrupted : %s\n", + (drd->flags & DATA_REMOVAL_OPER_INTERRUPTED) ? "yes" : "no"); + printf("\tData Removal Mechanism : %x\n", + drd->removal_mechanism); + printf("\tData Removal Format : %x\n", + drd->format); + printf("\tData Removal Time (Bit 0) : %x\n", + be16toh(drd->time_mechanism_bit0)); + printf("\tData Removal Time (Bit 1) : %x\n", + be16toh(drd->time_mechanism_bit1)); + printf("\tData Removal Time (Bit 2) : %x\n", + be16toh(drd->time_mechanism_bit2)); + printf("\tData Removal Time (Bit 5) : %x\n", + be16toh(drd->time_mechanism_bit5)); +} + +/* + * Print the namespace geometry feature. + */ +void sedopal_print_ns_geometry(void *data) +{ + struct ns_geometry_desc *nsgd = (struct ns_geometry_desc *)data; + + printf("\nSED Namespace Geometry:\n"); + printf("\tAlignment Required : %s\n", + (nsgd->align & NS_GEOMETRY_ALIGNMENT_REQUIRED) ? "yes" : "no"); + printf("\tLogical Block Size : %x\n", + be32toh(nsgd->logical_block_size)); + printf("\tAlignment Granularity : %lx\n", + be64toh(nsgd->alignment_granularity)); + printf("\tLowest Aligned LBA : %lx\n", + be64toh(nsgd->lowest_aligned_lba)); +} + +void sedopal_parse_features(struct level_0_discovery_features *feat, + struct sedopal_feature_parser *sfp) +{ + uint16_t code = be16toh(feat->code); + + switch (code) { + case OPAL_FEATURE_CODE_LOCKING: + sfp->features |= OPAL_FEATURE_LOCKING; + sfp->locking_desc = (void *)(feat + 1); + break; + case OPAL_FEATURE_CODE_OPALV1: + sfp->features |= OPAL_FEATURE_OPALV1; + sfp->opalv1_desc = (void *)(feat + 1); + break; + case OPAL_FEATURE_CODE_OPALV2: + sfp->features |= OPAL_FEATURE_OPALV2; + sfp->opalv2_desc = (void *)(feat + 1); + break; + case OPAL_FEATURE_CODE_TPER: + sfp->features |= OPAL_FEATURE_TPER; + sfp->tper_desc = (void *)(feat + 1); + break; + case OPAL_FEATURE_CODE_GEOMETRY: + sfp->features |= OPAL_FEATURE_GEOMETRY; + sfp->geometry_reporting_desc = (void *)(feat + 1); + break; + case OPAL_FEATURE_CODE_SINGLE_USER_MODE: + sfp->features |= OPAL_FEATURE_SINGLE_USER_MODE; + sfp->single_user_mode_desc = (void *)(feat + 1); + break; + case OPAL_FEATURE_CODE_DATA_STORE: + sfp->features |= OPAL_FEATURE_DATA_STORE; + sfp->datastore_desc = (void *)(feat + 1); + break; + case OPAL_FEATURE_CODE_OPALITE: + sfp->features |= OPAL_FEATURE_OPALITE; + sfp->opalite_desc = (void *)(feat + 1); + break; + case OPAL_FEATURE_CODE_PYRITE_V1: + sfp->features |= OPAL_FEATURE_PYRITE_V1; + sfp->pyrite_v1_desc = (void *)(feat + 1); + break; + case OPAL_FEATURE_CODE_PYRITE_V2: + sfp->features |= OPAL_FEATURE_PYRITE_V2; + sfp->pyrite_v2_desc = (void *)(feat + 1); + break; + case OPAL_FEATURE_CODE_RUBY: + sfp->features |= OPAL_FEATURE_RUBY; + sfp->ruby_desc = (void *)(feat + 1); + break; + case OPAL_FEATURE_CODE_LOCKING_LBA: + sfp->features |= OPAL_FEATURE_LOCKING_LBA; + sfp->locking_lba_desc = (void *)(feat + 1); + break; + case OPAL_FEATURE_CODE_BLOCK_SID_AUTH: + sfp->features |= OPAL_FEATURE_BLOCK_SID_AUTH; + sfp->block_sid_auth_desc = (void *)(feat + 1); + break; + case OPAL_FEATURE_CODE_CONFIG_NS_LOCKING: + sfp->features |= OPAL_FEATURE_CONFIG_NS_LOCKING; + sfp->config_ns_desc = (void *)(feat + 1); + break; + case OPAL_FEATURE_CODE_DATA_REMOVAL: + sfp->features |= OPAL_FEATURE_DATA_REMOVAL; + sfp->data_removal_desc = (void *)(feat + 1); + break; + case OPAL_FEATURE_CODE_NS_GEOMETRY: + sfp->features |= OPAL_FEATURE_NS_GEOMETRY; + sfp->ns_geometry_desc = (void *)(feat + 1); + break; + + default: + break; + } +} + +void sedopal_print_features(struct sedopal_feature_parser *sfp) +{ + if (sfp->features & OPAL_FEATURE_OPALV1) + sedopal_print_opal_v1(sfp->opalv1_desc); + + if (sfp->features & OPAL_FEATURE_OPALV2) + sedopal_print_opal_v2(sfp->opalv2_desc); + + if (sfp->features & OPAL_FEATURE_TPER) + sedopal_print_tper(sfp->tper_desc); + + if (sfp->features & OPAL_FEATURE_GEOMETRY) + sedopal_print_geometry(sfp->geometry_reporting_desc); + + if (sfp->features & OPAL_FEATURE_OPALITE) + sedopal_print_opalite(sfp->opalite_desc); + + if (sfp->features & OPAL_FEATURE_SINGLE_USER_MODE) + sedopal_print_sum(sfp->single_user_mode_desc); + + if (sfp->features & OPAL_FEATURE_DATA_STORE) + sedopal_print_datastore(sfp->datastore_desc); + + if (sfp->features & OPAL_FEATURE_BLOCK_SID_AUTH) + sedopal_print_sid_auth(sfp->block_sid_auth_desc); + + if (sfp->features & OPAL_FEATURE_RUBY) + sedopal_print_ruby(sfp->ruby_desc); + + if (sfp->features & OPAL_FEATURE_PYRITE_V1) + sedopal_print_pyrite_v1(sfp->pyrite_v1_desc); + + if (sfp->features & OPAL_FEATURE_PYRITE_V2) + sedopal_print_pyrite_v2(sfp->pyrite_v2_desc); + + if (sfp->features & OPAL_FEATURE_LOCKING_LBA) + sedopal_print_locking_lba(sfp->locking_lba_desc); + + if (sfp->features & OPAL_FEATURE_CONFIG_NS_LOCKING) + sedopal_print_config_ns(sfp->config_ns_desc); + + if (sfp->features & OPAL_FEATURE_NS_GEOMETRY) + sedopal_print_ns_geometry(sfp->ns_geometry_desc); } /* @@ -503,14 +965,12 @@ int sedopal_cmd_discover(int fd) { #ifdef IOC_OPAL_DISCOVERY int rc, feat_length; - bool sedopal_locking_supported = false; struct opal_discovery discover; struct level_0_discovery_header *dh; struct level_0_discovery_features *feat; struct level_0_discovery_features *feat_end; - uint16_t code; - uint8_t locking_flags = 0; char buf[4096]; + struct sedopal_feature_parser sfp = {}; discover.data = (uintptr_t)buf; discover.size = sizeof(buf); @@ -536,28 +996,24 @@ int sedopal_cmd_discover(int fd) * iterate through all the features that were returned */ while (feat < feat_end) { - code = be16toh(feat->code); + sedopal_parse_features(feat, &sfp); feat_length = feat->length + 4 /* hdr */; - switch (code) { - case OPAL_FEATURE_CODE_LOCKING: - locking_flags = feat->feature; - break; - case OPAL_FEATURE_CODE_OPALV2: - sedopal_locking_supported = true; - break; - default: - break; - } - - feat = (struct level_0_discovery_features *)((char *)feat + feat_length); + feat = (struct level_0_discovery_features *) + ((char *)feat + feat_length); } rc = 0; - if (!sedopal_locking_supported) { + if (!(sfp.features & OPAL_SED_LOCKING_SUPPORT)) { fprintf(stderr, "Error: device does not support SED Opal\n"); rc = -1; } else - sedopal_print_locking_features(locking_flags); + sedopal_print_locking_features(sfp.locking_desc); + + if (!sedopal_discovery_verbose) + return rc; + + sedopal_print_features(&sfp); + return rc; #else /* IOC_OPAL_DISCOVERY */ diff --git a/plugins/sed/sedopal_cmd.h b/plugins/sed/sedopal_cmd.h index 2be433240c..2efa6bce76 100644 --- a/plugins/sed/sedopal_cmd.h +++ b/plugins/sed/sedopal_cmd.h @@ -18,6 +18,8 @@ extern bool sedopal_ask_new_key; extern bool sedopal_destructive_revert; extern bool sedopal_psid_revert; extern bool sedopal_lock_ro; +extern bool sedopal_discovery_verbose; +extern bool sedopal_discovery_udev; /* * Sub-commands supported by the sedopal command diff --git a/plugins/sed/sedopal_spec.h b/plugins/sed/sedopal_spec.h index 75230607bf..aa4b905d0c 100644 --- a/plugins/sed/sedopal_spec.h +++ b/plugins/sed/sedopal_spec.h @@ -3,6 +3,8 @@ #ifndef _SED_OPAL_SPEC_H #define _SED_OPAL_SPEC_H +#include + /* * TCP Storage Architecture Core Specification Version 2.01 * section 5.1.5 Method Status Codes @@ -31,6 +33,31 @@ enum sed_status_codes { SED_STATUS_NO_METHOD_STATUS = 0x89, }; +/* + * level 0 feature flags + */ +#define OPAL_FEATURE_TPER 0x0001 +#define OPAL_FEATURE_LOCKING 0x0002 +#define OPAL_FEATURE_GEOMETRY 0x0004 +#define OPAL_FEATURE_OPALV1 0x0008 +#define OPAL_FEATURE_SINGLE_USER_MODE 0x0010 +#define OPAL_FEATURE_DATA_STORE 0x0020 +#define OPAL_FEATURE_OPALV2 0x0040 +#define OPAL_FEATURE_OPALITE 0x0080 +#define OPAL_FEATURE_PYRITE_V1 0x0100 +#define OPAL_FEATURE_PYRITE_V2 0x0200 +#define OPAL_FEATURE_RUBY 0x0400 +#define OPAL_FEATURE_LOCKING_LBA 0x0800 +#define OPAL_FEATURE_BLOCK_SID_AUTH 0x1000 +#define OPAL_FEATURE_CONFIG_NS_LOCKING 0x2000 +#define OPAL_FEATURE_DATA_REMOVAL 0x4000 +#define OPAL_FEATURE_NS_GEOMETRY 0x8000 + +#define OPAL_SED_LOCKING_SUPPORT \ + (OPAL_FEATURE_OPALV1 | OPAL_FEATURE_OPALV2 | \ + OPAL_FEATURE_RUBY | OPAL_FEATURE_PYRITE_V1 | \ + OPAL_FEATURE_PYRITE_V2 | OPAL_FEATURE_LOCKING) + /* * Definitions from TCG Opal Specification v2.0.2 */ @@ -38,24 +65,43 @@ enum sed_status_codes { /* * level 0 feature codes - section 3.1.1 */ -#define OPAL_FEATURE_CODE_LOCKING 0x0002 -#define OPAL_FEATURE_CODE_OPALV2 0x0203 +#define OPAL_FEATURE_CODE_TPER 0x0001 +#define OPAL_FEATURE_CODE_LOCKING 0x0002 +#define OPAL_FEATURE_CODE_GEOMETRY 0x0003 + +#define OPAL_FEATURE_CODE_OPALV1 0x0200 +#define OPAL_FEATURE_CODE_SINGLE_USER_MODE 0x0201 +#define OPAL_FEATURE_CODE_DATA_STORE 0x0202 +#define OPAL_FEATURE_CODE_OPALV2 0x0203 + +#define OPAL_FEATURE_CODE_OPALITE 0x0301 +#define OPAL_FEATURE_CODE_PYRITE_V1 0x0302 +#define OPAL_FEATURE_CODE_PYRITE_V2 0x0303 +#define OPAL_FEATURE_CODE_RUBY 0x0304 + +#define OPAL_FEATURE_CODE_LOCKING_LBA 0x0401 +#define OPAL_FEATURE_CODE_BLOCK_SID_AUTH 0x0402 +#define OPAL_FEATURE_CODE_CONFIG_NS_LOCKING 0x0403 +#define OPAL_FEATURE_CODE_DATA_REMOVAL 0x0404 +#define OPAL_FEATURE_CODE_NS_GEOMETRY 0x0405 /* locking features */ #define OPAL_FEATURE_LOCKING_SUPPORTED 0x01 #define OPAL_FEATURE_LOCKING_ENABLED 0x02 #define OPAL_FEATURE_LOCKED 0x04 - +#define OPAL_FEATURE_MEDIA_ENCRYPT 0x08 +#define OPAL_FEATURE_MBR_ENABLED 0x10 +#define OPAL_FEATURE_MBR_DONE 0x20 /* - * discovery header as specified in section 3.1.1.1 + * discovery header as specified in section 3.1.1 */ struct level_0_discovery_header { uint32_t parameter_length; uint32_t revision; uint64_t reserved; uint8_t vendor_specific[32]; -}; +} __packed; /* * level 0 features as specified in section 3.1.1.3 @@ -64,8 +110,259 @@ struct level_0_discovery_features { uint16_t code; uint8_t version; uint8_t length; - uint8_t feature; - uint8_t reserved[11]; -}; +} __packed; + +#define TPER_FEATURE_SYNC 0x0001 +#define TPER_FEATURE_ASYNC 0x0002 +#define TPER_FEATURE_ACKNAK 0x0004 +#define TPER_FEATURE_BUF_MGMT 0x0008 +#define TPER_FEATURE_STREAMING 0x0010 +#define TPER_FEATURE_COMID_MGMT 0x0040 + +/* + * 3.1.1.2 + * + * feature code 0x0001 + */ +struct tper_desc { + uint8_t feature; + uint8_t reserved[11]; +} __packed; + +/* + * 3.1.1.3 + * + * feature code 0x0002 + */ +struct locking_desc { + uint8_t features; + uint8_t reserved[11]; +} __packed; + +/* + * 3.1.1.4 + * + * feature code 0x0003 + */ +#define GEOMETRY_ALIGNMENT_REQUIRED 0x01 + +struct geometry_reporting_desc { + uint8_t align; + uint8_t reserved[7]; + uint32_t logical_block_size; + uint64_t alignment_granularity; + uint64_t lowest_aligned_lba; +} __packed; + +/* + * 3.1.1.5 + * + * feature code 0x0203 + */ +#define OPAL_V2_RANGE_CROSSING 0x01 + +struct opalv2_desc { + uint16_t base_comid; + uint16_t num_comids; + uint8_t flags; + uint16_t num_locking_sp_admin_auth; + uint16_t num_locking_sp_user_auth; + uint8_t initial_cpin_sid_ind; + uint8_t initial_cpin_sid_revert; + uint8_t reserved_future[5]; +} __packed; + +/* + * 3.1.1.5 + * + * feature code 0x0200 + */ +struct opalv1_desc { + uint16_t base_comid; + uint16_t num_comids; +} __packed; + +/* + * TCG Opal SSC Feature Set v1.00 : Single User Mode + * section 4.2.1 + * + * feature code 0x0201 + */ +#define SUM_FEATURE_ANY 0x0001 +#define SUM_FEATURE_ALL 0x0002 +#define SUM_FEATURE_POLICY 0x0004 + +struct single_user_mode_desc { + uint32_t num_locking_objects; + uint8_t flags; + uint8_t reserved[7]; +} __packed; + +/* + * TCG Opal SSC Feature Set v1.00 : Additional DataStore Tables + * section 4.2.1 + * + * feature code 0x0202 + */ +struct datastore_desc { + uint16_t reserved; + uint16_t max_tables; + uint32_t max_table_size; + uint32_t table_alignment; +} __packed; + +/* + * TCG Storage Security Subsystem Class: Opalite + * section 3.1.1.4 + * + * feature code 0x0301 + */ +struct opalite_desc { + uint16_t base_comid; + uint16_t num_comids; + uint8_t reserved[5]; + uint8_t initial_cpin_sid_ind; + uint8_t initial_cpin_sid_revert; + uint8_t reserved_future[5]; +} __packed; + +/* + * TCG Storage Security Subsystem Class: Pyrite version 1 + * section 3.1.1.4 + * + * feature code 0x0302 + */ +struct pyrite_v1_desc { + uint16_t base_comid; + uint16_t num_comids; + uint8_t reserved[5]; + uint8_t initial_cpin_sid_ind; + uint8_t initial_cpin_sid_revert; + uint8_t reserved_future[5]; +} __packed; + +/* + * TCG Storage Security Subsystem Class: Pyrite version 2 + * section 3.1.1.4 + * + * feature code 0x0303 + */ +struct pyrite_v2_desc { + uint16_t base_comid; + uint16_t num_comids; + uint8_t reserved[5]; + uint8_t initial_cpin_sid_ind; + uint8_t initial_cpin_sid_revert; + uint8_t reserved_future[5]; +} __packed; + +/* + * TCG Ruby SSC Feature Set v1.00 + * section 3.1.1.5 + * + * feature code 0x0304 + */ +#define RUBY_RANGE_CROSSING 0x01 + +struct ruby_desc { + uint16_t base_comid; + uint16_t num_comids; + uint8_t flags; + uint16_t num_locking_sp_admin_auth; + uint16_t num_locking_sp_user_auth; + uint8_t initial_cpin_sid_ind; + uint8_t initial_cpin_sid_revert; + uint8_t reserved_future[5]; +} __packed; + +/* + * TCG Storage Enterprise SSC Feature Set Locking LBA Ranges Control + * section 4.1.1 + * + * feature code 0x0401 + */ +struct locking_lba_desc { + uint8_t reserved; + uint8_t reserved_range_control[11]; +} __packed; + +/* + * TCG Storage Feature Set: Block SID Authentication + * section 4.1.1 + * + * feature code 0x0402 + */ +#define BLOCK_SID_VALUE_STATE 0x0001 +#define BLOCK_SID_BLOCKED_STATE 0x0002 +#define BLOCK_SID_HW_RESET 0x0001 + +struct block_sid_auth_desc { + uint8_t states; + uint8_t hw_reset; +} __packed; + +/* + * TCG Storage Opal SSC Feature Set: Configurable Namespace Locking + * section 4.2.1 + * + * feature code 0x0403 + */ +#define CONFIG_NS_RANGE_C 0x0080 +#define CONFIG_NS_RANGE_P 0x0040 + +struct config_ns_desc { + uint8_t flags; + uint8_t reserved[3]; + uint32_t max_key_count; + uint32_t unused_key_count; + uint32_t max_ranges_per_ns; +} __packed; + +/* + * TCG Storage Security Subsystem Class: Opal version 2.02 + * section 3.1.1.6 + * + * feature code 0x0404 + */ +#define DATA_REMOVAL_OPER_PROCESSING 0x01 +#define DATA_REMOVAL_OPER_INTERRUPTED 0x02 +#define DATA_REMOVAL_TIME_BIT0 0x01 +#define DATA_REMOVAL_TIME_BIT1 0x02 +#define DATA_REMOVAL_TIME_BIT2 0x04 +#define DATA_REMOVAL_TIME_BIT5 0x20 + +#define DATA_REMOVAL_MECHANISM_OVERWRITE 0x01 +#define DATA_REMOVAL_MECHANISM_BLOCK_ERASE 0x02 +#define DATA_REMOVAL_MECHANISM_CRYPTO_ERASE 0x04 +#define DATA_REMOVAL_MECHANISM_VENDOR_ERASE 0x10 + +struct data_removal_desc { + uint8_t reserved; + uint8_t flags; + uint8_t removal_mechanism; + uint8_t format; + uint16_t time_mechanism_bit0; + uint16_t time_mechanism_bit1; + uint16_t time_mechanism_bit2; + uint8_t reserved_mech[4]; + uint16_t time_mechanism_bit5; + uint8_t future_reserved[16]; +} __packed; + +/* + * TCG Storage Opal SSC Feature Set: Configurable Namespace Locking + * section 4.2.1 + * + * feature code 0x0405 + */ +#define NS_GEOMETRY_ALIGNMENT_REQUIRED 0x01 + +struct ns_geometry_desc { + uint8_t align; + uint8_t reserved[7]; + uint32_t logical_block_size; + uint64_t alignment_granularity; + uint64_t lowest_aligned_lba; +} __packed; #endif /* _SED_OPAL_SPEC_H */