Spdk/include/spdk/nvme_ocssd_spec.h

415 lines
9.6 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.
*/
/**
* \file
* Open-Channel specification definitions
*/
#ifndef SPDK_NVME_OCSSD_SPEC_H
#define SPDK_NVME_OCSSD_SPEC_H
#include "spdk/stdinc.h"
#ifdef __cplusplus
extern "C" {
#endif
#include "spdk/assert.h"
#include "spdk/nvme_spec.h"
/** A maximum number of LBAs that can be issued by vector I/O commands */
#define SPDK_NVME_OCSSD_MAX_LBAL_ENTRIES 64
struct spdk_ocssd_dev_lba_fmt {
/** Contiguous number of bits assigned to Group addressing */
uint8_t grp_len;
/** Contiguous number of bits assigned to PU addressing */
uint8_t pu_len;
/** Contiguous number of bits assigned to Chunk addressing */
uint8_t chk_len;
/** Contiguous number of bits assigned to logical blocks within Chunk */
uint8_t lbk_len;
uint8_t reserved[4];
};
SPDK_STATIC_ASSERT(sizeof(struct spdk_ocssd_dev_lba_fmt) == 8, "Incorrect size");
struct spdk_ocssd_geometry_data {
/** Major Version Number */
uint8_t mjr;
/** Minor Version Number */
uint8_t mnr;
uint8_t reserved1[6];
/** LBA format */
struct spdk_ocssd_dev_lba_fmt lbaf;
/** Media and Controller Capabilities */
struct {
/* Supports the Vector Chunk Copy I/O Command */
uint32_t vec_chk_cpy : 1;
/* Supports multiple resets when a chunk is in its free state */
uint32_t multi_reset : 1;
uint32_t reserved : 30;
} mccap;
uint8_t reserved2[12];
/** Wear-level Index Delta Threshold */
uint8_t wit;
uint8_t reserved3[31];
/** Number of Groups */
uint16_t num_grp;
/** Number of parallel units per group */
uint16_t num_pu;
/** Number of chunks per parallel unit */
uint32_t num_chk;
/** Chunk Size */
uint32_t clba;
uint8_t reserved4[52];
/** Minimum Write Size */
uint32_t ws_min;
/** Optimal Write Size */
uint32_t ws_opt;
/** Cache Minimum Write Size Units */
uint32_t mw_cunits;
/** Maximum Open Chunks */
uint32_t maxoc;
/** Maximum Open Chunks per PU */
uint32_t maxocpu;
uint8_t reserved5[44];
/** tRD Typical */
uint32_t trdt;
/** tRD Max */
uint32_t trdm;
/** tWR Typical */
uint32_t twrt;
/** tWR Max */
uint32_t twrm;
/** tCRS Typical */
uint32_t tcrst;
/** tCRS Max */
uint32_t tcrsm;
/** bytes 216-255: reserved for performance related metrics */
uint8_t reserved6[40];
uint8_t reserved7[3071 - 255];
/** bytes 3072-4095: Vendor Specific */
uint8_t vs[4095 - 3071];
};
SPDK_STATIC_ASSERT(sizeof(struct spdk_ocssd_geometry_data) == 4096, "Incorrect size");
struct spdk_ocssd_chunk_information_entry {
/** Chunk State */
struct {
/** if set to 1 chunk is free */
uint8_t free : 1;
/** if set to 1 chunk is closed */
uint8_t closed : 1;
/** if set to 1 chunk is open */
uint8_t open : 1;
/** if set to 1 chunk is offline */
uint8_t offline : 1;
uint8_t reserved : 4;
} cs;
/** Chunk Type */
struct {
/** If set to 1 chunk must be written sequentially */
uint8_t seq_write : 1;
/** If set to 1 chunk allows random writes */
uint8_t rnd_write : 1;
uint8_t reserved1 : 2;
/**
* If set to 1 chunk deviates from the chunk size reported
* in identify geometry command.
*/
uint8_t size_deviate : 1;
uint8_t reserved2 : 3;
} ct;
/** Wear-level Index */
uint8_t wli;
uint8_t reserved[5];
/** Starting LBA */
uint64_t slba;
/** Number of blocks in chunk */
uint64_t cnlb;
/** Write Pointer */
uint64_t wp;
};
SPDK_STATIC_ASSERT(sizeof(struct spdk_ocssd_chunk_information_entry) == 32, "Incorrect size");
struct spdk_ocssd_chunk_notification_entry {
/**
* This is a 64-bit incrementing notification count, indicating a
* unique identifier for this notification. The counter begins at 1h
* and is incremented for each unique event
*/
uint64_t nc;
/** This field points to the chunk that has its state updated */
uint64_t lba;
/**
* This field indicates the namespace id that the event is associated
* with
*/
uint32_t nsid;
/** Field that indicate the state of the block */
struct {
/**
* If set to 1, then the error rate of the chunk has been
* changed to low
*/
uint8_t error_rate_low : 1;
/**
* If set to 1, then the error rate of the chunk has been
* changed to medium
*/
uint8_t error_rate_medium : 1;
/**
* If set to 1, then the error rate of the chunk has been
* changed to high
*/
uint8_t error_rate_high : 1;
/**
* If set to 1, then the error rate of the chunk has been
* changed to unrecoverable
*/
uint8_t unrecoverable : 1;
/**
* If set to 1, then the chunk has been refreshed by the
* device
*/
uint8_t refreshed : 1;
uint8_t rsvd : 3;
/**
* If set to 1 then the chunk's wear-level index is outside
* the average wear-level index threshold defined by the
* controller
*/
uint8_t wit_exceeded : 1;
uint8_t rsvd2 : 7;
} state;
/**
* The address provided is covering either logical block, chunk, or
* parallel unit
*/
struct {
/** If set to 1, the LBA covers the logical block */
uint8_t lblk : 1;
/** If set to 1, the LBA covers the respecting chunk */
uint8_t chunk : 1;
/**
* If set to 1, the LBA covers the respecting parallel unit
* including all chunks
*/
uint8_t pu : 1;
uint8_t rsvd : 5;
} mask;
uint8_t rsvd[9];
/**
* This field indicates the number of logical chunks to be written.
* This is a 0's based value. This field is only valid if mask bit 0 is
* set. The number of blocks addressed shall not be outside the boundary
* of the specified chunk.
*/
uint16_t nlb;
uint8_t rsvd2[30];
};
SPDK_STATIC_ASSERT(sizeof(struct spdk_ocssd_chunk_notification_entry) == 64, "Incorrect size");
/**
* Vector completion queue entry
*/
struct spdk_ocssd_vector_cpl {
/* dword 0,1 */
uint64_t lba_status; /* completion status bit array */
/* dword 2 */
uint16_t sqhd; /* submission queue head pointer */
uint16_t sqid; /* submission queue identifier */
/* dword 3 */
uint16_t cid; /* command identifier */
struct spdk_nvme_status status;
};
SPDK_STATIC_ASSERT(sizeof(struct spdk_ocssd_vector_cpl) == 16, "Incorrect size");
/**
* OCSSD admin command set opcodes
*/
enum spdk_ocssd_admin_opcode {
SPDK_OCSSD_OPC_GEOMETRY = 0xE2
};
/**
* OCSSD I/O command set opcodes
*/
enum spdk_ocssd_io_opcode {
SPDK_OCSSD_OPC_VECTOR_RESET = 0x90,
SPDK_OCSSD_OPC_VECTOR_WRITE = 0x91,
SPDK_OCSSD_OPC_VECTOR_READ = 0x92,
SPDK_OCSSD_OPC_VECTOR_COPY = 0x93
};
/**
* Log page identifiers for SPDK_NVME_OPC_GET_LOG_PAGE
*/
enum spdk_ocssd_log_page {
/** Chunk Information */
SPDK_OCSSD_LOG_CHUNK_INFO = 0xCA,
/** Chunk Notification Log */
SPDK_OCSSD_LOG_CHUNK_NOTIFICATION = 0xD0,
};
/**
* OCSSD feature identifiers
* Defines OCSSD specific features that may be configured with Set Features and
* retrieved with Get Features.
*/
enum spdk_ocssd_feat {
/** Media Feedback feature identifier */
SPDK_OCSSD_FEAT_MEDIA_FEEDBACK = 0xCA
};
/**
* OCSSD media error status codes extension.
* Additional error codes for status code type 2h (media errors)
*/
enum spdk_ocssd_media_error_status_code {
/**
* The chunk was either marked offline by the reset or the state
* of the chunk is already offline.
*/
SPDK_OCSSD_SC_OFFLINE_CHUNK = 0xC0,
/**
* Invalid reset if chunk state is either Free or Open
*/
SPDK_OCSSD_SC_INVALID_RESET = 0xC1,
/**
* Write failed, chunk remains open.
* Host should proceed to write to next write unit.
*/
SPDK_OCSSD_SC_WRITE_FAIL_WRITE_NEXT_UNIT = 0xF0,
/**
* The writes ended prematurely. The chunk state is set to closed.
* The host can read up to the value of the write pointer.
*/
SPDK_OCSSD_SC_WRITE_FAIL_CHUNK_EARLY_CLOSE = 0xF1,
/**
* The write corresponds to a write out of order within an open
* chunk or the write is to a closed or offline chunk.
*/
SPDK_OCSSD_SC_OUT_OF_ORDER_WRITE = 0xF2,
/**
* The data retrieved is nearing its limit for reading.
* The limit is vendor specific, and only provides a hint
* to the host that should refresh its data in the future.
*/
SPDK_OCSSD_SC_READ_HIGH_ECC = 0xD0,
};
#define SPDK_OCSSD_IO_FLAGS_LIMITED_RETRY (1U << 31)
#ifdef __cplusplus
}
#endif
#endif