numam-spdk/lib/nvme/nvme_opal_internal.h

294 lines
8.1 KiB
C
Raw Normal View History

/*-
* BSD LICENSE
*
* Copyright (c) Intel Corporation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SPDK_OPAL_INTERNAL_H
#define SPDK_OPAL_INTERNAL_H
#include "spdk/opal_spec.h"
#include "spdk/opal.h"
#include "spdk/scsi_spec.h"
#define IO_BUFFER_LENGTH 2048
#define MAX_TOKS 64
#define OPAL_KEY_MAX 256
#define OPAL_UID_LENGTH 8
#define SPDK_OPAL_TPER_TIMEOUT 600 /* seconds */
#define GENERIC_HOST_SESSION_NUM 0x69
#define OPAL_INVAL_PARAM 12
#define SPDK_DTAERROR_NO_METHOD_STATUS 0x89
enum opal_token_type {
OPAL_DTA_TOKENID_BYTESTRING = 0xE0,
OPAL_DTA_TOKENID_SINT = 0xE1,
OPAL_DTA_TOKENID_UINT = 0xE2,
OPAL_DTA_TOKENID_TOKEN = 0xE3, /* actual token is returned */
OPAL_DTA_TOKENID_INVALID = 0X0,
};
enum opal_atom_width {
OPAL_WIDTH_TINY, /* 1 byte in length */
OPAL_WIDTH_SHORT, /* a 1-byte header and contain up to 15 bytes of data */
OPAL_WIDTH_MEDIUM, /* a 2-byte header and contain up to 2047 bytes of data */
OPAL_WIDTH_LONG, /* a 4-byte header and which contain up to 16,777,215 bytes of data */
OPAL_WIDTH_TOKEN
};
enum opal_uid_enum {
/* users */
UID_SMUID,
UID_THISSP,
UID_ADMINSP,
UID_LOCKINGSP,
UID_ANYBODY,
UID_SID,
UID_ADMIN1,
UID_USER1,
UID_USER2,
/* tables */
UID_LOCKINGRANGE_GLOBAL,
UID_LOCKINGRANGE_ACE_RDLOCKED,
UID_LOCKINGRANGE_ACE_WRLOCKED,
UID_MBRCONTROL,
UID_MBR,
UID_AUTHORITY_TABLE,
UID_C_PIN_TABLE,
UID_LOCKING_INFO_TABLE,
UID_PSID,
/* C_PIN_TABLE object ID's */
UID_C_PIN_MSID,
UID_C_PIN_SID,
UID_C_PIN_ADMIN1,
UID_C_PIN_USER1,
/* half UID's (only first 4 bytes used) */
UID_HALF_AUTHORITY_OBJ_REF,
UID_HALF_BOOLEAN_ACE,
};
/* enum for indexing the spdk_opal_method array */
enum opal_method_enum {
PROPERTIES_METHOD,
STARTSESSION_METHOD,
REVERT_METHOD,
ACTIVATE_METHOD,
NEXT_METHOD,
GETACL_METHOD,
GENKEY_METHOD,
REVERTSP_METHOD,
GET_METHOD,
SET_METHOD,
AUTHENTICATE_METHOD,
RANDOM_METHOD,
ERASE_METHOD,
};
struct spdk_opal_key {
uint8_t locking_range;
uint8_t key_len;
uint8_t _padding[6];
uint8_t key[OPAL_KEY_MAX];
};
struct opal_common_session {
uint32_t sum; /* single user mode */
uint32_t who;
struct spdk_opal_key opal_key;
};
struct spdk_opal_new_pw_session {
struct opal_common_session old_session;
struct opal_common_session new_session;
};
const uint8_t spdk_opal_uid[][OPAL_UID_LENGTH] = {
/* users */
[UID_SMUID] = /* Session Manager UID */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff },
[UID_THISSP] =
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
[UID_ADMINSP] =
{ 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x01 },
[UID_LOCKINGSP] =
{ 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x02 },
[UID_ANYBODY] =
{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01 },
[UID_SID] = /* Security Identifier UID */
{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06 },
[UID_ADMIN1] =
{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x01 },
[UID_USER1] =
{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x01 },
[UID_USER2] =
{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x02 },
/* tables */
[UID_LOCKINGRANGE_GLOBAL] =
{ 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x01 },
[UID_LOCKINGRANGE_ACE_RDLOCKED] =
{ 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xE0, 0x01 },
[UID_LOCKINGRANGE_ACE_WRLOCKED] =
{ 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xE8, 0x01 },
[UID_MBRCONTROL] =
{ 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x01 },
[UID_MBR] =
{ 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00 },
[UID_AUTHORITY_TABLE] =
{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00},
[UID_C_PIN_TABLE] =
{ 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00},
[UID_LOCKING_INFO_TABLE] =
{ 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x01 },
[UID_PSID] =
{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0xff, 0x01 },
/* C_PIN_TABLE object ID's */
[UID_C_PIN_MSID] =
{ 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x84, 0x02},
[UID_C_PIN_SID] =
{ 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01},
[UID_C_PIN_ADMIN1] =
{ 0x00, 0x00, 0x00, 0x0B, 0x00, 0x01, 0x00, 0x01},
[UID_C_PIN_USER1] =
{ 0x00, 0x00, 0x00, 0x0B, 0x00, 0x03, 0x00, 0x01},
/* half UID's (only first 4 bytes used) */
[UID_HALF_AUTHORITY_OBJ_REF] =
{ 0x00, 0x00, 0x0C, 0x05, 0xff, 0xff, 0xff, 0xff },
[UID_HALF_BOOLEAN_ACE] =
{ 0x00, 0x00, 0x04, 0x0E, 0xff, 0xff, 0xff, 0xff },
};
/*
* TCG Storage SSC Methods.
*/
const uint8_t spdk_opal_method[][OPAL_UID_LENGTH] = {
[PROPERTIES_METHOD] =
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01 },
[STARTSESSION_METHOD] =
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02 },
[REVERT_METHOD] =
{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x02 },
[ACTIVATE_METHOD] =
{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x03 },
[NEXT_METHOD] =
{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08 },
[GETACL_METHOD] =
{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0d },
[GENKEY_METHOD] =
{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10 },
[REVERTSP_METHOD] =
{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11 },
[GET_METHOD] =
{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16 },
[SET_METHOD] =
{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x17 },
[AUTHENTICATE_METHOD] =
{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1c },
[RANDOM_METHOD] =
{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x01 },
[ERASE_METHOD] =
{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x08, 0x03 },
};
/*
* Response token
*/
struct spdk_opal_resp_token {
const uint8_t *pos;
uint8_t _padding[7];
union {
uint64_t unsigned_num;
int64_t signed_num;
} stored;
size_t len; /* header + data */
enum opal_token_type type;
enum opal_atom_width width;
};
struct spdk_opal_resp_parsed {
int num;
struct spdk_opal_resp_token resp_tokens[MAX_TOKS];
};
struct opal_locking_range_setup_session {
uint8_t id;
uint8_t _padding[7];
uint64_t range_start;
uint64_t range_length;
bool read_lock_enabled;
bool write_lock_enabled;
struct opal_common_session session;
};
/* header of a response */
struct spdk_opal_header {
struct spdk_opal_compacket com_packet;
struct spdk_opal_packet packet;
struct spdk_opal_data_subpacket sub_packet;
};
struct opal_session {
uint32_t hsn;
uint32_t tsn;
size_t cmd_pos;
uint8_t cmd[IO_BUFFER_LENGTH];
uint8_t resp[IO_BUFFER_LENGTH];
struct spdk_opal_resp_parsed parsed_resp;
};
struct spdk_opal_dev {
bool supported;
struct spdk_nvme_ctrlr *ctrlr;
uint16_t comid;
/* Only one session can be supported */
struct opal_session sess;
struct spdk_opal_d0_features_info feat_info;
uint64_t timeout; /* seconds */
uint8_t max_ranges; /* max locking range number */
struct spdk_opal_locking_range_info locking_ranges[SPDK_OPAL_MAX_LOCKING_RANGE];
pthread_mutex_t mutex_lock; /* some structs are accessed by current thread only */
};
#endif