From 531ba156de326210e4807b701183eaf2f506cf2a Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 10 Oct 2025 18:13:16 +0200 Subject: [SERVER] iscsi refactor: First working version Work towards simplifying the iscsi implementation has begun. Goals are: - Simpler and easier to understand resource/lifecycle management of allocations - Single-threaded architecture, making locking unnecessary - Moving as many allocations as possible to the stack - Making the call-stack more shallow for easier tracking of code flow --- src/server/iscsi.h | 9831 +++++++++++----------------------------------------- 1 file changed, 2116 insertions(+), 7715 deletions(-) (limited to 'src/server/iscsi.h') diff --git a/src/server/iscsi.h b/src/server/iscsi.h index ded2d1d..0c279fe 100644 --- a/src/server/iscsi.h +++ b/src/server/iscsi.h @@ -32,10 +32,6 @@ #ifndef DNBD3_ISCSI_H_ #define DNBD3_ISCSI_H_ -#ifdef __cplusplus -extern "C" { -#endif - #include #include #include @@ -48,23 +44,23 @@ extern "C" { #include "image.h" #if defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) - // GCC-compatible compiler, targeting x86/x86-64 - #include + // GCC-compatible compiler, targeting x86/x86-64 + #include #elif defined(__GNUC__) && defined(__ARM_NEON__) - // GCC-compatible compiler, targeting ARM with NEON - #include + // GCC-compatible compiler, targeting ARM with NEON + #include #elif defined(__GNUC__) && defined(__IWMMXT__) - // GCC-compatible compiler, targeting ARM with WMMX - #include + // GCC-compatible compiler, targeting ARM with WMMX + #include #elif (defined(__GNUC__) || defined(__xlC__)) && (defined(__VEC__) || defined(__ALTIVEC__)) - // XLC or GCC-compatible compiler, targeting PowerPC with VMX/VSX - #include + // XLC or GCC-compatible compiler, targeting PowerPC with VMX/VSX + #include #elif defined(__GNUC__) && defined(__SPE__) - // GCC-compatible compiler, targeting PowerPC with SPE - #include + // GCC-compatible compiler, targeting PowerPC with SPE + #include #elif defined(_MSC_VER) - // Microsoft C/C++-compatible compiler - #include + // Microsoft C/C++-compatible compiler + #include #endif #if defined(__BIG_ENDIAN__) || (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN) || (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) @@ -241,76 +237,6 @@ static inline bool iscsi_is_pow2(const uint32_t value) return ((value & (value - 1UL)) == 0UL); } -/** - * @brief Rounds up a positive 32-bit integer value to the nearest power of two. - * - * This function is used to ensure that - * a value is always a power of two by - * rounding up.\n - * An input value of zero is NOT - * handled correctly. - * - * @param[in] value Positive value to round up to - * the nearest power of two. - * @return Rounded up nearest power of two. - */ -static inline uint32_t iscsi_align_pow2_ceil(const uint32_t value) -{ - uint32_t num_value = (value - 1UL); // 1UL << (lg(value - 1UL) + 1UL) - - num_value |= (num_value >> 1UL); - num_value |= (num_value >> 2UL); - num_value |= (num_value >> 4UL); - num_value |= (num_value >> 8UL); - num_value |= (num_value >> 16UL); - - return ++num_value; -} - -/** - * @brief Calculates the shift factor for a power of two value. - * - * This function is used to determine - * the shift factor to use instead of - * using very slow multiplication, - * division and modulo operations. - * - * @param[in] value Value to retrieve the - * the shift factor for. May NOT be - * zero in which case the result is - * undefined. - * @return The shift count to use as a - * replacement for multiplication - * and division. - */ -static inline uint32_t iscsi_get_log2_of_pow2(const uint32_t value) -{ -#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) || defined(__INTEL_COMPILER) || defined(__ECC) -// GCC, CLang or Intel Compiler - return (((sizeof(uint32_t) * CHAR_BIT) - 1UL) - (uint32_t) __builtin_clz( value )); -#elif defined(_MSC_VER) -// MSVC - uint32_t shift; - - _BitScanReverse( &shift, value ); - - return (((sizeof(uint32_t) * CHAR_BIT) - 1UL) - shift); -#else -// Other compilers (use slow parallel calculation method with logical OR, bit shift, logcal AND) - uint32_t shift = ((value & 0xAAAAAAAAUL) != 0UL); - - shift |= ((value & 0xCCCCCCCCUL) != 0UL) << 1UL; - shift |= ((value & 0xF0F0F0F0UL) != 0UL) << 2UL; - shift |= ((value & 0xFF00FF00UL) != 0UL) << 3UL; - shift |= ((value & 0xFFFF0000UL) != 0UL) << 4UL; - - return shift; -#endif -} - - -/// Determines the container of member b in struct a of type x. -#define ISCSI_CONTAINER(x, a, b) ((x *) (((uint8_t *) (a)) - offsetof(x, b))) /// Determines the next offset after member b of struct a. #define ISCSI_NEXT_OFFSET(a, b) (offsetof(struct a, b) + sizeof(((struct a *) 0)->b)) @@ -365,434 +291,7 @@ static inline uint32_t iscsi_get_log2_of_pow2(const uint32_t value) /// Determines the length of a zero terminated string at compile time. -#define ISCSI_STRLEN(x) ((sizeof(x) / sizeof(uint8_t)) - sizeof(uint8_t)) - - -uint8_t *iscsi_vsprintf_append_realloc(char *buf, const char *format, va_list args); // Allocates and appends a buffer and sprintf's it -uint8_t *iscsi_sprintf_append_realloc(char *buf, const char *format, ...); // Allocates and appends a buffer and sprintf's it -uint8_t *iscsi_vsprintf_alloc(const char *format, va_list args); // Allocates a buffer and sprintf's it -uint8_t *iscsi_sprintf_alloc(const char *format, ... ); // Allocates a buffer and sprintf's it -void iscsi_strcpy_pad(char *dst, const char *src, const size_t size, const int pad); // Copies a string with additional padding character to fill in a specified size - - -/// Shift factor for default capacity. -#define ISCSI_HASHMAP_DEFAULT_CAPACITY_SHIFT 5UL - -/// Default capacity is 32 buckets. -#define ISCSI_HASHMAP_DEFAULT_CAPACITY (1UL << (ISCSI_HASHMAP_DEFAULT_CAPACITY_SHIFT)) - -/// Number of bits to shift left when resizing. -#define ISCSI_HASHMAP_RESIZE_SHIFT 1UL - -/// Key data shift value for alignment enforcement. -#define ISCSI_HASHMAP_KEY_ALIGN_SHIFT 3UL - -/// Key data size MUST be multiple of 8 bytes by now. -#define ISCSI_HASHMAP_KEY_ALIGN (1UL << (ISCSI_HASHMAP_KEY_ALIGN_SHIFT)) - - -/// Initial hash code. -#define ISCSI_HASHMAP_HASH_INITIAL 0x811C9DC5UL - -/// Value to multiply hash code with. -#define ISCSI_HASHMAP_HASH_MUL 0xBF58476D1CE4E5B9ULL - - -typedef struct iscsi_node iscsi_node; - - -/** - * @brief Doubly linked list node structure. - * - * This structure is used by the iSCSI doubly linked list - * implementation in order to maintain the elements. - */ -typedef struct iscsi_node { - /// Successor node in node list. Must be first element. - iscsi_node *succ; - - /// Predecessor node in node list. Must be second element. - iscsi_node *pred; -} iscsi_node; - - -/** - * @brief Doubly linked list structure. - * - * This structure is used by the iSCSI doubly linked list - * implementation in order to maintain the elements. - */ -typedef struct iscsi_list { - /// Head of linked list. Must be first element. - iscsi_node *head; - - /// Tail of linked list. Must be second element and always be NULL. - iscsi_node *tail; - - /// Tail predecessor of linked list. Must be third element. - iscsi_node *pred; -} iscsi_list; - - -/// foreach( ( list => entry ) usage style forward iterator over all nodes in a doubly linked list. -#define iscsi_list_foreach(list, entry) for ( (entry) = (list)->head; (entry)->succ != NULL; (entry) = (entry)->succ ) - -/// foreach( ( list => (typeof(entry)) as field ) usage style forward iterator over all nodes in a doubly linked list embedded into another structure with default node field name. -#define iscsi_list_foreach_field(list, entry, field) for ( (entry) = (__typeof__(entry)) (list)->head; (__typeof__(entry)) (entry)->field.succ != NULL; (entry) = (__typeof__(entry)) (entry)->field.succ ) - -/// foreach( ( list => (typeof(entry)) entry->node.succ ) usage style forward iterator over all nodes in a doubly linked list embedded into another structure with default node field name. -#define iscsi_list_foreach_node(list, entry) iscsi_list_foreach_field(list, entry, node) - -/// foreach( ( list => entry ) usage style forward iterator over all nodes in a doubly linked list. -#define iscsi_list_foreach_safe(list, entry, tmp) for ( (entry) = (list)->head; ((entry)->succ != NULL) && ((tmp) = (entry)->succ, true); (entry) = (tmp) ) - -/// foreach( ( list => (typeof(entry)) as field ) usage style forward iterator over all nodes in a doubly linked list embedded into another structure with default node field name. -#define iscsi_list_foreach_safe_field(list, entry, field, tmp) for ( (entry) = (__typeof__(entry)) (list)->head; ((entry)->field.succ != NULL) && ((tmp) = (__typeof__(entry)) (entry)->field.succ, true); (entry) = (tmp) ) - -/// foreach( ( list => (typeof(entry)) entry->node.succ ) usage style forward iterator over all nodes in a doubly linked list embedded into another structure with default node field name. -#define iscsi_list_foreach_safe_node(list, entry, tmp) iscsi_list_foreach_safe_field(list, entry, node, tmp) - - -/** - * @brief Initializes a doubly linked list for usage. - * - * This function sets the head of the list to - * the pointer of the list's tail, the tail - * itself to NULL and the predecessor to the - * pointer of the list's head. - * - * @param[in] list Pointer to idoubly linked list to - * initialize. May NOT be NULL, so be careful. - * */ -static inline void iscsi_list_create(iscsi_list *list) -{ - list->head = (iscsi_node *) &list->tail; - list->tail = NULL; - list->pred = (iscsi_node *) &list->head; -} - -/** - * @brief Clears an already initialized doubly linked list. - * - * This function sets the head of the list to - * the pointer of the list's tail and the - * predecessor to the pointer of the list's - * head. - * - * @param[in] list Pointer to idoubly linked list to - * initialize. May NOT be NULL, so be careful. - * */ -static inline void iscsi_list_clear(iscsi_list *list) -{ - list->head = (iscsi_node *) &list->tail; - list->pred = (iscsi_node *) &list->head; -} - -/** - * @brief Adds a node at the head of a doubly linked list. - * - * This function sets the head of the list to - * the node and adjusts the list and node - * pointers accordingly. - * - * @param[in] list Pointer to doubly linked list to add to - * the head. May NOT be NULL, so be careful. - * @param[in] node Pointer to node to add to the head of - * the list. NULL is NOT allowed here, take - * caution. - */ -static inline void iscsi_list_push(iscsi_list *list, iscsi_node *node) -{ - iscsi_node *head = list->head; - - list->head = node; - head->pred = node; - - node->succ = head; - node->pred = (iscsi_node *) &list->head; -} - -/** - * @brief Adds a node at the tail of a doubly linked list. - * - * This function sets the tail of the list to - * the node and adjusts the list and node - * pointers accordingly. - * - * @param[in] list Pointer to doubly linked list to add to - * the tail. May NOT be NULL, so be careful. - * @param[in] node Pointer to node to add to the tail of - * the list. NULL is NOT allowed here, take - * caution. - */ -static inline void iscsi_list_enqueue(iscsi_list *list, iscsi_node *node) -{ - iscsi_node *tail = list->pred; - - list->pred = node; - tail->succ = node; - - node->succ = (iscsi_node *) &list->tail; - node->pred = tail; -} - -/** - * @brief Inserts a node into a doubly linked list before an already existing node. - * - * This function sets the successor of the - * new node to the successor of the - * existing predecessor node and the - * predecessor of the new node to the - * the existing predecessor node itself - * and adjusts the list pointers - * accordingly. - * - * @param[in] list Pointer to doubly linked list to insert the - * node into. May NOT be NULL, so be careful. - * @param[in] node Pointer to node to be inserted into the - * list. NULL is NOT allowed here, take - * caution. - * @param[in] pred Pointer to node which should be the - * previous node of the new inserted node. - * May be NULL in which case the new node - * is inserted at the head of the list. - */ -static inline void iscsi_list_insert(iscsi_list *list, iscsi_node *node, iscsi_node *pred) -{ - if ( pred == NULL ) { - iscsi_node *head = list->head; - - list->head = node; - head->pred = node; - - node->succ = head; - node->pred = (iscsi_node *) &list->head; - - return; - } - - iscsi_node *tail = pred->succ; - - if ( tail == NULL ) { - tail = pred->pred; - - node->succ = pred; - node->pred = tail; - - pred->pred = node; - tail->succ = node; - - return; - } - - node->succ = tail; - node->pred = pred; - - tail->pred = node; - pred->succ = node; -} - -/** - * @brief Removes the node from the head of a doubly linked list. - * - * This function sets the head of the list to - * its successor and adjusts the list and - * node pointers accordingly. - * - * @param[in] list Pointer to doubly linked list to remove the - * head from. May NOT be NULL, so be careful. - */ -static inline void iscsi_list_pop(iscsi_list *list) -{ - iscsi_node *head = list->head; - iscsi_node *node = head->succ; - - if ( node == NULL ) - return; - - list->head = node; - - node->pred = (iscsi_node *) &list->head; -} - -/** - * @brief Removes the node from the tail of a doubly linked list. - * - * This function sets the tail of the list to - * its predecessor and adjusts the list and - * node pointers accordingly. - * - * @param[in] list Pointer to doubly linked list to remove the - * tail from. May NOT be NULL, so be careful. - */ -static inline void iscsi_list_dequeue(iscsi_list *list) -{ - iscsi_node *tail = list->pred; - iscsi_node *node = tail->pred; - - if ( node == NULL ) - return; - - list->pred = node; - - node->succ = (iscsi_node *) &list->tail; -} - -/** - * @brief Removes a specified node from a doubly linked list. - * - * This function sets the successor of the - * node's predecessor and the predecessor - * of the node's successor by adjusting - * the list and node pointers accordingly. - * - * @param[in] node Pointer to node to be removed from - * the list. May NOT be NULL, so - * be careful. - */ -static inline void iscsi_list_remove(iscsi_node *node) -{ - iscsi_node *succ = node->succ; - iscsi_node *pred = node->pred; - - pred->succ = succ; - succ->pred = pred; -} - -/** - * @brief Checks whether a doubly linked list is empty. - * - * Whenever this function returns false, - * iscsi_list_peek will return a pointer - * to the first node in the list. - * - * @param[in] list Pointer to doubly linked list to check if - * empty. May NOT be NULL, so be careful. - * @retval true The doubly linked list is empty. - * @retval false The doubly linked list contains nodes. - */ -static inline bool iscsi_list_empty(const iscsi_list *list) -{ - return (list->head->succ == NULL); -} - -/** - * @brief Gets the node from the head of a doubly linked list. - * - * This function returns NULL if the list is - * empty. - * - * @param[in] list Pointer to doubly linked list to get the - * head from. May NOT be NULL, so be careful. - * @return Pointer to doubly linked list node of the - * head or NULL if the list is empty. - */ -static inline iscsi_node *iscsi_list_peek(const iscsi_list *list) -{ - iscsi_node *head = list->head; - - return (head->succ != NULL) ? head : NULL; -} - - -/** - * @brief Hash map bucket containing key, value and hash code. - * - * This structure is used by the iSCSI hash map implementation - * in order to maintain the elements. - */ -typedef struct iscsi_hashmap_bucket { - /// Next bucket, MUST be first element. - iscsi_node node; - - /// Data used as key, MUST be aligned to 8 bytes and zero padded. - uint8_t *key; - - /// Size of key. - size_t key_size; - - /// Hash code for the key. - uint32_t hash; - - /// Associate4d value to the key, NULL is allowed. - uint8_t *value; -} iscsi_hashmap_bucket; - -/** - * @brief Hash map containing an expandable list of buckets - * - * This structure is used by the ultra performant hash map - * implementation. It uses a linked list allowing fast - * insertions. Elements can be removed. - */ -typedef struct iscsi_hashmap { - /// Linked list containing the hash map buckets. - iscsi_hashmap_bucket *buckets; - - /// Doubly linked list for fast insertion. - iscsi_list list; - - /// Last inserted unique identifier (primary key). - uint64_t last_insert_id; - - /// Current bucket capacity, MUST be a power of two. - uint capacity; - - /// Current capacity threshold triggering resize operation. - uint cap_load; - - /// Current count of buckets. - uint count; -} iscsi_hashmap; - -/** - * @brief Callback for iterating over map, freeing and removing entries. user_data is free for personal use. - * - * Callback function. This is a pointer to a - * function for various purposes like iterating - * through a hash map. It is also used for replacing - * already existing keys or for key removal. - * - * @param[in] key Pointer to zero padded key. NULL is - * an invalid pointer here, so be careful. - * @param[in] key_size Number of bytes for the key, MUST - * be a multiple of 8 bytes which is NOT checked, so - * be careful. - * @param[in] value Value of the key, NULL is allowed. - * @param[in,out] user_data User data to be used by the - * callback function. User data can be modified if - * desired and may also be NULL if the callback - * function handles this case. See the documentation - * of the callback implementation for details. - * @return A negative result indicates as fatal error, - * 0 means successful operation and a positive value - * indicates a non-fatal error or a warning. - */ -typedef int (*iscsi_hashmap_callback)(uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *user_data); - -iscsi_hashmap *iscsi_hashmap_create(const uint capacity); // Creates an empty hash map with either specified or default capacity -void iscsi_hashmap_destroy(iscsi_hashmap *map); // Deallocates the hash map objects and buckets, not elements - // Use iscsi_hashmap_iterate to deallocate the elements themselves - -uint8_t *iscsi_hashmap_key_create(const uint8_t *data, const size_t len); // Creates a key suitable for hashmap usage (ensures 8-byte boundary and zero padding) -void iscsi_hashmap_key_create_id(iscsi_hashmap *map, uint64_t *key); // Creates an unique key identifier suitable for hashmap usage (ensures 8-byte boundary and zero padding) -void iscsi_hashmap_key_destroy(uint8_t *key); // Deallocates all resources acquired by iscsi_hashmap_create_key -int iscsi_hashmap_key_destroy_callback(uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *user_data); // Deallocates a key in a hash map -int iscsi_hashmap_destroy_value_callback(uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *user_data); // Deallocates a value in a hash map -int iscsi_hashmap_key_destroy_value_callback(uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *user_data); // Deallocates a key / value pair in a hash map by calling free (default destructor) - -int iscsi_hashmap_put(iscsi_hashmap *map, uint8_t *key, const size_t key_size, uint8_t *value); // Assigns key / value pair to hash map at the tail of doubly linked list without making copies -int iscsi_hashmap_get_put(iscsi_hashmap *map, uint8_t *key, const size_t key_size, uint8_t **out_in_value); // Assigns key / value pair to hash map at the tail of doubly linked list without making copies -int iscsi_hashmap_put_free(iscsi_hashmap *map, uint8_t *key, const size_t key_size, uint8_t *value, iscsi_hashmap_callback callback, uint8_t *user_data); // Assigns key / value pair to hash map without making copies with callback function in case the key already exists -bool iscsi_hashmap_contains(iscsi_hashmap *map, const uint8_t *key, const size_t key_size); // Checks whether a specified key exists -int iscsi_hashmap_get(iscsi_hashmap *map, const uint8_t *key, const size_t key_size, uint8_t **out_value); // Retrieves the value of a specified key - -void iscsi_hashmap_remove(iscsi_hashmap *map, const uint8_t *key, const size_t key_size); // Removes an element both from the doubly linked list and by setting the key to NULL -void iscsi_hashmap_remove_free(iscsi_hashmap *map, const uint8_t *key, const size_t key_size, iscsi_hashmap_callback callback, uint8_t *user_data); // Removes an element both from the doubly linked list and by setting the key to NULL and invokes a callback function before actual removal - -uint iscsi_hashmap_size(const iscsi_hashmap *map); // Retrieves the number of elements of the hash map - -int iscsi_hashmap_iterate(iscsi_hashmap *map, iscsi_hashmap_callback callback, uint8_t *user_data); // Iterator with callback function invoked on each element +#define ISCSI_STRLEN(x) ((sizeof(x) / sizeof(uint8_t)) - 1) /* iSCSI protocol stuff (all WORD/DWORD/QWORD values are big endian by default @@ -805,7 +304,7 @@ int iscsi_hashmap_iterate(iscsi_hashmap *map, iscsi_hashmap_callback callback, u #define ISCSI_MAX_AHS_SIZE (255UL << 2UL) /// iSCSI DataSegment maximum allowed size. -#define ISCSI_MAX_DS_SIZE 16777215UL +#define ISCSI_MAX_DS_SIZE 16777215 /// iSCSI packet data alignment (BHS, AHS and DataSegment). #define ISCSI_ALIGN_SIZE 4UL @@ -815,10 +314,10 @@ int iscsi_hashmap_iterate(iscsi_hashmap *map, iscsi_hashmap_callback callback, u /// iSCSI Default receive DataSegment (DS) size in bytes. -#define ISCSI_DEFAULT_RECV_DS_LEN 8192UL +#define ISCSI_DEFAULT_RECV_DS_LEN 131072UL /// iSCSI default maximum DataSegment receive length in bytes. -#define ISCSI_DEFAULT_MAX_RECV_DS_LEN 65536UL +#define ISCSI_DEFAULT_MAX_RECV_DS_LEN 524288UL /// iSCSI default maximum Ready To Transfer (R2T) active tasks. @@ -941,6 +440,7 @@ int iscsi_hashmap_iterate(iscsi_hashmap *map, iscsi_hashmap_callback callback, u /// iSCSI opcode flags (I) Immediate bit: For Request PDUs, the I bit set to 1 is an immediate delivery marker. #define ISCSI_OPCODE_FLAGS_IMMEDIATE (1 << 6L) +#define ASSERT_IS_BHS(structname) _Static_assert( sizeof(structname) == ISCSI_BHS_SIZE, #structname " messed up" ) /** * @brief iSCSI Basic Header Segment packet data. @@ -951,32 +451,34 @@ int iscsi_hashmap_iterate(iscsi_hashmap *map, iscsi_hashmap_callback callback, u * has been determined. */ typedef struct __attribute__((packed)) iscsi_bhs_packet { - /// Command opcode. - uint8_t opcode; + /// Command opcode. + uint8_t opcode; - /// Opcode-specific fields. - uint8_t opcode_fields[3]; + /// Opcode-specific fields. + uint8_t opcode_fields[3]; - /// Total length of AHS (Advanced Header Segment). - uint8_t total_ahs_len; + /// Total length of AHS (Advanced Header Segment). + uint8_t total_ahs_len; - /// Length of Data Segment. - uint8_t ds_len[3]; + /// Length of Data Segment. + uint8_t ds_len[3]; - union { - /// SCSI LUN bit mask. - uint64_t lun; + union { + /// SCSI LUN bit mask. + uint64_t lun; - /// Opcode-specific fields. - uint8_t opcode_spec[8]; - } lun_opcode; + /// Opcode-specific fields. + uint8_t opcode_spec[8]; + } lun_opcode; - /// Initiator Task Tag (ITT). - uint32_t init_task_tag; + /// Initiator Task Tag (ITT). + uint32_t init_task_tag; - /// Opcode-specific fields. - uint8_t opcode_spec_fields[28]; + /// Opcode-specific fields. + uint8_t opcode_spec_fields[28]; } iscsi_bhs_packet; +ASSERT_IS_BHS( iscsi_bhs_packet ); + /// iSCSI AHS type: Extended Command Descriptor Block (CDB). @@ -995,61 +497,19 @@ typedef struct __attribute__((packed)) iscsi_bhs_packet { * has been determined. */ typedef struct __attribute__((packed)) iscsi_ahs_packet { - /// AHSLength. - uint16_t len; + /// AHSLength. + uint16_t len; - /// AHSType. - uint8_t type; + /// AHSType. + uint8_t type; - /// AHS-Specific. - uint8_t specific; + /// AHS-Specific. + uint8_t specific; - /// AHS-Specific data. - uint8_t data[0]; + /// AHS-Specific data. + uint8_t data[0]; } iscsi_ahs_packet; - -/** - * @brief iSCSI Extended CDB AHS packet data structure. - * - * This type of AHS MUST NOT be used if the CDBLength is less than 17. - * The length includes the reserved byte 3. - */ -typedef struct __attribute__((packed)) iscsi_ext_cdb_ahs_packet { - /// AHSLength: AHSLength - (CDBLength - 15). - uint16_t len; - - // AHSType: Identifier (always 1 according to iSCSI specifications). - uint8_t type; - - /// Reserved for future usage, always MUST be 0. - uint8_t reserved; - - /// ExtendedCDB. - uint8_t data[0]; -} iscsi_ext_cdb_ahs_packet; - -/** - * @brief iSCSI Bidirectional Read Expected Data Transfer Length AHS packet data structure. - * - * This structure is used to determine the bidirectional read - * expected data transfer length. - */ -typedef struct __attribute__((packed)) iscsi_bidi_read_exp_xfer_ahs_packet { - /// AHSLength: Always 5 according to iSCSI specifications for now. - uint16_t len; - - /// AHSType: Always 2 according to iSCSI specifications for now. - uint8_t type; // Identifier (always 0x02 according to specs) - - /// Reserved for future usage, always MUST be 0. - uint8_t reserved; - - /// Bidirectional Read Expected Data Transfer Length. - uint32_t bidi_read_exp_xfer_len; -} iscsi_bidi_read_exp_xfer_ahs_packet; - - /** * @brief DataSegment Error: Unexpected unsolicited data. * @@ -1091,84 +551,6 @@ typedef struct __attribute__((packed)) iscsi_bidi_read_exp_xfer_ahs_packet { */ #define ISCSI_DS_ERROR_INCORRECT_AMOUNT_OF_DATA_ASCQ 0x0D - -/** - * @brief DataSegment Error: Protocol Service CRC error. - * - * Certain iSCSI conditions result in the command being terminated at - * the target (response code of Command Completed at Target) with a SCSI - * CHECK CONDITION Status as outlined in the following definitions - * (Sense key: Aborted Command 0x0B). - */ -#define ISCSI_DS_ERROR_PROTOCOL_SERVICE_CRC_ERROR_ASC 0x47 - -/** - * @brief DataSegment Error: Protocol Service CRC error. - * - * Certain iSCSI conditions result in the command being terminated at - * the target (response code of Command Completed at Target) with a SCSI - * CHECK CONDITION Status as outlined in the following definitions - * (Sense key: Aborted Command 0x0B). - */ -#define ISCSI_DS_ERROR_PROTOCOL_SERVICE_CRC_ERROR_ASCQ 0x05 - - -/** - * @brief DataSegment Error: Selective Negative / Sequence Number Acknowledgment (SNACK) rejected. - * - * Certain iSCSI conditions result in the command being terminated at - * the target (response code of Command Completed at Target) with a SCSI - * CHECK CONDITION Status as outlined in the following definitions - * (Sense key: Aborted Command 0x0B). - */ -#define ISCSI_DS_ERROR_SNACK_REJECTED_ASC 0x11 - -/** - * @brief DataSegment Error: Selective Negative / Sequence Number Acknowledgment (SNACK) rejected. - * - * Certain iSCSI conditions result in the command being terminated at - * the target (response code of Command Completed at Target) with a SCSI - * CHECK CONDITION Status as outlined in the following definitions - * (Sense key: Aborted Command 0x0B). - */ -#define ISCSI_DS_ERROR_SNACK_REJECTED_ASCQ 0x13 - - -/** - * @brief iSCSI header digest in case CRC32C has been negotiated. - * - * Optional header and data digests protect the integrity of the header - * and data, respectively. The digests, if present, are located, - * respectively, after the header and PDU-specific data and cover, - * respectively, the header and the PDU data, each including the padding - * bytes, if any. - * - * The existence and type of digests are negotiated during the Login - * Phase. - */ -typedef struct __attribute__((packed)) iscsi_header_digest { - /// Header digest is a CRC32C for ensuring integrity. - uint32_t crc32c; -} iscsi_header_digest; - -/** - * @brief iSCSI data digest in case CRC32C has been negotiated. - * - * Optional header and data digests protect the integrity of the header - * and data, respectively. The digests, if present, are located, - * respectively, after the header and PDU-specific data and cover, - * respectively, the header and the PDU data, each including the padding - * bytes, if any. - * - * The existence and type of digests are negotiated during the Login - * Phase. - */ -typedef struct __attribute__((packed)) iscsi_data_digest { - /// Data digest is a CRC32C for ensuring integrity. - uint32_t crc32c; -} iscsi_data_digest; - - /** * @brief iSCSI SCSI CDB packet data structure. * @@ -1177,11 +559,11 @@ typedef struct __attribute__((packed)) iscsi_data_digest { * MUST be used to contain the CDB spillover. */ typedef struct __attribute__((packed)) iscsi_scsi_cdb { - /// SCSI opcode. - uint8_t opcode; + /// SCSI opcode. + uint8_t opcode; - /// Additional op-code specific data. - uint8_t data[0]; + /// Additional op-code specific data. + uint8_t data[0]; } iscsi_scsi_cdb; @@ -1198,20 +580,20 @@ typedef struct __attribute__((packed)) iscsi_scsi_cdb { * There are 6 bytes in the CDB field for this command. */ typedef struct __attribute__((packed)) iscsi_scsi_cdb_inquiry { - /// SCSI opcode. - iscsi_scsi_cdb cdb; + /// SCSI opcode. + iscsi_scsi_cdb cdb; - /// Logical Unit Number (LUN), CMMDT and EVPD. - uint8_t lun_flags; + /// Logical Unit Number (LUN), CMMDT and EVPD. + uint8_t lun_flags; - /// Page code. - uint8_t page_code; + /// Page code. + uint8_t page_code; - /// Allocation length in bytes. - uint16_t alloc_len; + /// Allocation length in bytes. + uint16_t alloc_len; - /// Control. - uint8_t control; + /// Control. + uint8_t control; } iscsi_scsi_cdb_inquiry; @@ -1221,17 +603,17 @@ typedef struct __attribute__((packed)) iscsi_scsi_cdb_inquiry { * There are 6 bytes in the CDB field for this command. */ typedef struct __attribute__((packed)) iscsi_scsi_cdb_read_write_6 { - /// SCSI opcode. - iscsi_scsi_cdb cdb; + /// SCSI opcode. + iscsi_scsi_cdb cdb; - /// Logical Block Address (LBA). - uint8_t lba[3]; + /// Logical Block Address (LBA). + uint8_t lba[3]; - /// Transfer length in bytes. - uint8_t xfer_len; + /// Transfer length in bytes. + uint8_t xfer_len; - /// Control. - uint8_t control; + /// Control. + uint8_t control; } iscsi_scsi_cdb_read_write_6; @@ -1241,23 +623,23 @@ typedef struct __attribute__((packed)) iscsi_scsi_cdb_read_write_6 { * There are 10 bytes in the CDB field for this command. */ typedef struct __attribute__((packed)) iscsi_scsi_cdb_read_write_10 { - /// SCSI opcode. - iscsi_scsi_cdb cdb; + /// SCSI opcode. + iscsi_scsi_cdb cdb; - /// Flags. - int8_t flags; + /// Flags. + int8_t flags; - /// Logical Block Address (LBA). - uint32_t lba; + /// Logical Block Address (LBA). + uint32_t lba; - /// Group number. - int8_t group_num; + /// Group number. + int8_t group_num; - /// Transfer length in bytes. - uint16_t xfer_len; + /// Transfer length in bytes. + uint16_t xfer_len; - /// Control. - uint8_t control; + /// Control. + uint8_t control; } iscsi_scsi_cdb_read_write_10; @@ -1267,23 +649,23 @@ typedef struct __attribute__((packed)) iscsi_scsi_cdb_read_write_10 { * There are 12 bytes in the CDB field for this command. */ typedef struct __attribute__((packed)) iscsi_scsi_cdb_read_write_12 { - /// SCSI opcode. - iscsi_scsi_cdb cdb; + /// SCSI opcode. + iscsi_scsi_cdb cdb; - /// Flags. - int8_t flags; + /// Flags. + int8_t flags; - /// Logical Block Address (LBA). - uint32_t lba; + /// Logical Block Address (LBA). + uint32_t lba; - /// Transfer length in bytes. - uint32_t xfer_len; + /// Transfer length in bytes. + uint32_t xfer_len; - /// Restricted for MMC-6 and group number. - int8_t restrict_group_num; + /// Restricted for MMC-6 and group number. + int8_t restrict_group_num; - /// Control. - uint8_t control; + /// Control. + uint8_t control; } iscsi_scsi_cdb_read_write_12; @@ -1293,23 +675,23 @@ typedef struct __attribute__((packed)) iscsi_scsi_cdb_read_write_12 { * There are 16 bytes in the CDB field for this command. */ typedef struct __attribute__((packed)) iscsi_scsi_cdb_read_write_16 { - /// SCSI opcode. - iscsi_scsi_cdb cdb; + /// SCSI opcode. + iscsi_scsi_cdb cdb; - /// Flags. - int8_t flags; + /// Flags. + int8_t flags; - /// Logical Block Address (LBA). - uint64_t lba; + /// Logical Block Address (LBA). + uint64_t lba; - /// Transfer length in bytes. - uint32_t xfer_len; + /// Transfer length in bytes. + uint32_t xfer_len; - /// Restricted for MMC-6 and group number. - int8_t restrict_group_num; + /// Restricted for MMC-6 and group number. + int8_t restrict_group_num; - /// Control. - uint8_t control; + /// Control. + uint8_t control; } iscsi_scsi_cdb_read_write_16; @@ -1329,100 +711,46 @@ typedef struct __attribute__((packed)) iscsi_scsi_cdb_read_write_16 { * There are 12 bytes in the CDB field for this command. */ typedef struct __attribute__((packed)) iscsi_scsi_cdb_report_luns { - /// SCSI opcode. - iscsi_scsi_cdb cdb; + /// SCSI opcode. + iscsi_scsi_cdb cdb; - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved; + /// Reserved for future usage (always MUST be 0 for now). + uint8_t reserved; - /// Select report. - uint8_t select_report; + /// Select report. + uint8_t select_report; - /// Reserved for future usage (always MUST be 0 for now). - uint16_t reserved2; + /// Reserved for future usage (always MUST be 0 for now). + uint16_t reserved2; - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved3; + /// Reserved for future usage (always MUST be 0 for now). + uint8_t reserved3; - /// Allocation length in bytes. - uint32_t alloc_len; + /// Allocation length in bytes. + uint32_t alloc_len; - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved4; + /// Reserved for future usage (always MUST be 0 for now). + uint8_t reserved4; - /// Control. - uint8_t control; + /// Control. + uint8_t control; } iscsi_scsi_cdb_report_luns; -/// iSCSI SCSI Command Descriptor Block (CDB) for COMPARE AND WRITE command flags: Force Unit Access (FUA). -#define ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_FUA (1 << 3L) - -/// iSCSI SCSI Command Descriptor Block (CDB) for COMPARE AND WRITE command flags: Disable Page Out (DPO). -#define ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_DPO (1 << 4L) +/// iSCSI SCSI Command Descriptor Block (CDB) for SERVICE ACTION IN(16) command service action: READ CAPACITY(16). +#define ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_READ_CAPACITY_16 0x10 -/// iSCSI SCSI Command Descriptor Block (CDB) for COMPARE AND WRITE command write protect flags: First bit of the three bits. -#define ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_WRPROTECT_FIRST_BIT 5 +/// iSCSI SCSI Command Descriptor Block (CDB) for SERVICE ACTION IN(16) command service action: READ LONG(16). +#define ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_READ_LONG_16 0x11 -/// iSCSI SCSI Command Descriptor Block (CDB) for COMPARE AND WRITE command write protect flags: Last bit of the three bits. -#define ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_WRPROTECT_LAST_BIT ((ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_WRPROTECT_FIRST_BIT) + 3 - 1) +/// iSCSI SCSI Command Descriptor Block (CDB) for SERVICE ACTION IN(16) command service action: First bit of the five bits. +#define ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_FIRST_BIT 0 -/// iSCSI SCSI Command Descriptor Block (CDB) for COMPARE AND WRITE command write protect flags: Bit mask. -#define ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_WRPROTECT_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_WRPROTECT_FIRST_BIT, ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_WRPROTECT_LAST_BIT)) +/// iSCSI SCSI Command Descriptor Block (CDB) for SERVICE ACTION IN(16) command service action: Last bit of the five bits. +#define ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_LAST_BIT ((ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_FIRST_BIT) + 5 - 1) -/// iSCSI SCSI Command Descriptor Block (CDB) for COMPARE AND WRITE command write protect flags: Extracts the write protect bits. -#define ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_GET_WRPROTECT(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_WRPROTECT_FIRST_BIT, ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_WRPROTECT_LAST_BIT)) - -/// iSCSI SCSI Command Descriptor Block (CDB) for COMPARE AND WRITE command write protect flags: Stores into the write protect bits. -#define ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_PUT_WRPROTECT(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_WRPROTECT_FIRST_BIT, ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_WRPROTECT_LAST_BIT)) - - -/** - * @brief iSCSI SCSI CDB packet data structure for SCSI COMPARE AND WRITE command. - * - * There are 16 bytes in the CDB field for this command. - */ -typedef struct __attribute__((packed)) iscsi_scsi_cdb_cmp_write { - /// SCSI opcode. - iscsi_scsi_cdb cdb; - - /// Flags. - int8_t flags; - - /// Logical Block Address (LBA). - uint64_t lba; - - /// Reserved for future usage (always MUST be 0 for now). - uint16_t reserved; - - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved2; - - /// Number of blocks in bytes. - uint8_t num_blocks; - - /// Restricted for MMC-6 and group number. - int8_t restrict_group_num; - - /// Control. - uint8_t control; -} iscsi_scsi_cdb_cmp_write; - - -/// iSCSI SCSI Command Descriptor Block (CDB) for SERVICE ACTION IN(16) command service action: READ CAPACITY(16). -#define ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_READ_CAPACITY_16 0x10 - -/// iSCSI SCSI Command Descriptor Block (CDB) for SERVICE ACTION IN(16) command service action: READ LONG(16). -#define ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_READ_LONG_16 0x11 - -/// iSCSI SCSI Command Descriptor Block (CDB) for SERVICE ACTION IN(16) command service action: First bit of the five bits. -#define ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_FIRST_BIT 0 - -/// iSCSI SCSI Command Descriptor Block (CDB) for SERVICE ACTION IN(16) command service action: Last bit of the five bits. -#define ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_LAST_BIT ((ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_FIRST_BIT) + 5 - 1) - -/// iSCSI SCSI Command Descriptor Block (CDB) for SERVICE ACTION IN(16) command service action: Bit mask. -#define ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_FIRST_BIT, ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_LAST_BIT)) +/// iSCSI SCSI Command Descriptor Block (CDB) for SERVICE ACTION IN(16) command service action: Bit mask. +#define ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_FIRST_BIT, ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_LAST_BIT)) /// iSCSI SCSI Command Descriptor Block (CDB) for SERVICE ACTION IN(16) command service action: Extracts the service action bits. #define ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_GET_ACTION(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_FIRST_BIT, ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_LAST_BIT)) @@ -1437,196 +765,26 @@ typedef struct __attribute__((packed)) iscsi_scsi_cdb_cmp_write { * There are 16 bytes in the CDB field for this command. */ typedef struct __attribute__((packed)) iscsi_scsi_cdb_service_action_in_16 { - /// SCSI opcode. - iscsi_scsi_cdb cdb; + /// SCSI opcode. + iscsi_scsi_cdb cdb; - /// Service action. - uint8_t action; + /// Service action. + uint8_t action; - /// Logical Block Address (LBA), obselete by now. - uint64_t lba; + /// Logical Block Address (LBA), obselete by now. + uint64_t lba; - /// Allocation length in bytes. - uint32_t alloc_len; + /// Allocation length in bytes. + uint32_t alloc_len; - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved; + /// Reserved for future usage (always MUST be 0 for now). + uint8_t reserved; - /// Control. - uint8_t control; + /// Control. + uint8_t control; } iscsi_scsi_cdb_service_action_in_16; -/** - * @brief iSCSI SCSI CDB packet data structure for SCSI SYNCHRONIZE CACHE(10) command. - * - * There are 10 bytes in the CDB field for this command. - */ -typedef struct __attribute__((packed)) iscsi_scsi_cdb_sync_cache_10 { - /// SCSI opcode. - iscsi_scsi_cdb cdb; - - /// Flags. - int8_t flags; - - /// Logical Block Address (LBA). - uint32_t lba; - - /// Group number. - int8_t group_num; - - /// Transfer length in bytes. - uint16_t xfer_len; - - /// Control. - uint8_t control; -} iscsi_scsi_cdb_sync_cache_10; - - -/** - * @brief iSCSI SCSI CDB packet data structure for SCSI SYNCHRONIZE CACHE(16) command. - * - * There are 16 bytes in the CDB field for this command. - */ -typedef struct __attribute__((packed)) iscsi_scsi_cdb_sync_cache_16 { - /// SCSI opcode. - iscsi_scsi_cdb cdb; - - /// Flags. - int8_t flags; - - /// Logical Block Address (LBA). - uint64_t lba; - - /// Transfer length in bytes. - uint32_t xfer_len; - - /// Group number. - int8_t group_num; - - /// Control. - uint8_t control; -} iscsi_scsi_cdb_sync_cache_16; - - -/** - * @brief iSCSI SCSI CDB packet data structure for SCSI WRITE SAME(10) command. - * - * There are 10 bytes in the CDB field for this command. - */ -typedef struct __attribute__((packed)) iscsi_scsi_cdb_write_same_10 { - /// SCSI opcode. - iscsi_scsi_cdb cdb; - - /// Flags. - int8_t flags; - - /// Logical Block Address (LBA). - uint32_t lba; - - /// Group number. - int8_t group_num; - - /// Transfer length in bytes. - uint16_t xfer_len; - - /// Control. - uint8_t control; -} iscsi_scsi_cdb_write_same_10; - - -/** - * @brief iSCSI SCSI CDB packet data structure for SCSI WRITE SAME(16) command. - * - * There are 16 bytes in the CDB field for this command. - */ -typedef struct __attribute__((packed)) iscsi_scsi_cdb_write_same_16 { - /// SCSI opcode. - iscsi_scsi_cdb cdb; - - /// Flags. - int8_t flags; - - /// Logical Block Address (LBA). - uint64_t lba; - - /// Transfer length in bytes. - uint32_t xfer_len; - - /// Group number. - int8_t group_num; - - /// Control. - uint8_t control; -} iscsi_scsi_cdb_write_same_16; - - -/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SELECT(6) command flags: Save Pages (SP). -#define ISCSI_SCSI_CDB_MODE_SELECT_6_FLAGS_SP (1 << 0) - -/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SELECT(6) command flags: Revert To Defaults (RTD). -#define ISCSI_SCSI_CDB_MODE_SELECT_6_FLAGS_RTD (1 << 1) - -/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SELECT(6) command flags: Page Format (PF). -#define ISCSI_SCSI_CDB_MODE_SELECT_6_FLAGS_PF (1 << 4) - - -/** - * @brief iSCSI SCSI CDB packet data structure for SCSI MODE SELECT(6) command. - * - * There are 6 bytes in the CDB field for this command. - */ -typedef struct __attribute__((packed)) iscsi_scsi_cdb_mode_select_6 { - /// SCSI opcode. - iscsi_scsi_cdb cdb; - - /// Flags. - int8_t flags; - - /// Reserved for future usage (always MUST be 0 for now). - uint16_t reserved; - - /// Parameter list length in bytes. - uint8_t param_list_len; - - /// Control. - uint8_t control; -} iscsi_scsi_cdb_mode_select_6; - - -/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SELECT(10) command flags: Save Pages (SP). -#define ISCSI_SCSI_CDB_MODE_SELECT_10_FLAGS_SP (1 << 0) - -/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SELECT(10) command flags: Page Format (PF). -#define ISCSI_SCSI_CDB_MODE_SELECT_10_FLAGS_PF (1 << 4) - - -/** - * @brief iSCSI SCSI CDB packet data structure for SCSI MODE SELECT(10) command. - * - * There are 10 bytes in the CDB field for this command. - */ -typedef struct __attribute__((packed)) iscsi_scsi_cdb_mode_select_10 { - /// SCSI opcode. - iscsi_scsi_cdb cdb; - - /// Flags. - int8_t flags; - - /// Reserved for future usage (always MUST be 0 for now). - uint32_t reserved; - - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved2; - - /// Parameter list length in bytes. - uint16_t param_list_len; - - /// Control. - uint8_t control; -} iscsi_scsi_cdb_mode_select_10; - - /// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(6) command flags: Disable Block Descriptors (DBD). #define ISCSI_SCSI_CDB_MODE_SENSE_6_FLAGS_DBD (1 << 3) @@ -1680,23 +838,23 @@ typedef struct __attribute__((packed)) iscsi_scsi_cdb_mode_select_10 { * There are 6 bytes in the CDB field for this command. */ typedef struct __attribute__((packed)) iscsi_scsi_cdb_mode_sense_6 { - /// SCSI opcode. - iscsi_scsi_cdb cdb; + /// SCSI opcode. + iscsi_scsi_cdb cdb; - /// Flags. - int8_t flags; + /// Flags. + int8_t flags; - /// Page code and page control. - uint8_t page_code_control; + /// Page code and page control. + uint8_t page_code_control; - /// Sub page code. - uint8_t sub_page_code; + /// Sub page code. + uint8_t sub_page_code; - /// Allocation length in bytes. - uint8_t alloc_len; + /// Allocation length in bytes. + uint8_t alloc_len; - /// Control. - uint8_t control; + /// Control. + uint8_t control; } iscsi_scsi_cdb_mode_sense_6; @@ -1756,654 +914,249 @@ typedef struct __attribute__((packed)) iscsi_scsi_cdb_mode_sense_6 { * There are 10 bytes in the CDB field for this command. */ typedef struct __attribute__((packed)) iscsi_scsi_cdb_mode_sense_10 { - /// SCSI opcode. - iscsi_scsi_cdb cdb; + /// SCSI opcode. + iscsi_scsi_cdb cdb; - /// Flags. - int8_t flags; + /// Flags. + int8_t flags; - /// Page code and page control. - uint8_t page_code_control; + /// Page code and page control. + uint8_t page_code_control; - /// Sub page code. - uint8_t sub_page_code; + /// Sub page code. + uint8_t sub_page_code; - /// Reserved for future usage (always MUST be 0 for now). - uint16_t reserved; + /// Reserved for future usage (always MUST be 0 for now). + uint16_t reserved; - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved2; + /// Reserved for future usage (always MUST be 0 for now). + uint8_t reserved2; - /// Allocation length in bytes. - uint16_t alloc_len; + /// Allocation length in bytes. + uint16_t alloc_len; - /// Control. - uint8_t control; + /// Control. + uint8_t control; } iscsi_scsi_cdb_mode_sense_10; -/// iSCSI SCSI Command Descriptor Block (CDB) for REQUEST SENSE command flags: Descriptor Format (DESC). -#define ISCSI_SCSI_CDB_REQ_SENSE_FLAGS_DESC (1 << 0) - - /** - * @brief iSCSI SCSI CDB packet data structure for SCSI REQUEST SENSE command. + * @brief iSCSI SCSI DataSegment Command packet structure. * - * There are 6 bytes in the CDB field for this command. + * iSCSI targets MUST support and enable Autosense. If Status is CHECK + * CONDITION (0x02), then the data segment MUST contain sense data for + * the failed command. + * + * For some iSCSI responses, the response data segment MAY contain some + * response-related information (e.g., for a target failure, it may + * contain a vendor-specific detailed description of the failure). */ -typedef struct __attribute__((packed)) iscsi_scsi_cdb_req_sense { - /// SCSI opcode. - iscsi_scsi_cdb cdb; - - /// Flags. - int8_t flags; - - /// Reserved for future usage (always MUST be 0 for now). - uint16_t reserved; - - /// Allocation length in bytes. - uint8_t alloc_len; - - /// Control. - uint8_t control; -} iscsi_scsi_cdb_req_sense; - +typedef struct __attribute__((packed)) iscsi_scsi_ds_cmd_data { + /// SenseLength: This field indicates the length of Sense Data. + uint16_t len; -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution flags: Reply immediately after CDB check (IMMED). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_EXEC_FLAGS_IMMED (1 << 0) + /// The Sense Data contains detailed information about a CHECK CONDITION. SPC3 specifies the format and content of the Sense Data. + uint8_t sense_data[0]; + /// Response Data. + uint8_t res_data[0]; +} iscsi_scsi_ds_cmd_data; -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution power condition modifier: Process the START and LOEJ bits. -#define ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_PROC_START_LOEJ_BITS 0x0 -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution power condition modifier: Cause the logical unit to transition to the active power condition (see SPC5). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_ACTIVE 0x0 +/// iSCSI SCSI Basic Inquiry Data peripheral type: Direct access device. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_DIRECT 0x00 -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution power condition modifier: Cause the logical unit to transition to the idle_a power condition (see SPC5). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_IDLE_A 0x0 +/// iSCSI SCSI Basic Inquiry Data peripheral type: Sequential access device. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_SEQ 0x01 -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution power condition modifier: Cause the logical unit to transition to the idle_b power condition (see SPC5). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_IDLE_B 0x1 +/// iSCSI SCSI Basic Inquiry Data peripheral type: Printer device. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_PRINTER 0x02 -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution power condition modifier: Cause the logical unit to transition to the idle_c power condition (see SPC5). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_IDLE_C 0x2 +/// iSCSI SCSI Basic Inquiry Data peripheral type: Processor device. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_PROCESSOR 0x03 -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution power condition modifier: Cause the logical unit to transition to the standby_z power condition (see SPC5). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_STANDBY_Z 0x0 +/// iSCSI SCSI Basic Inquiry Data peripheral type: Write once device. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_WORM 0x04 -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution power condition modifier: Cause the logical unit to transition to the standby_b power condition (see SPC5). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_STANDBY_Y 0x1 +/// iSCSI SCSI Basic Inquiry Data peripheral type: Read only direct access (e.g. CD-ROM) device. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_RO_DIRECT 0x05 -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution power condition modifier: Initialize and start all of the idle and standby condition timers that are enabled (see SPC5). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_LU_CONTROL 0x0 +/// iSCSI SCSI Basic Inquiry Data peripheral type: Scanner device. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_SCANNER 0x06 -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution power condition modifier: Force the idle_a condition timer to be set to zero (see SPC5). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_FORCE_IDLE_A_0 0x0 +/// iSCSI SCSI Basic Inquiry Data peripheral type: Optical memory device. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_OPTICAL 0x07 -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution power condition modifier: Force the idle_b condition timer to be set to zero (see SPC5). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_FORCE_IDLE_B_0 0x1 +/// iSCSI SCSI Basic Inquiry Data peripheral type: Medium changer device. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_CHANGER 0x08 -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution power condition modifier: Force the idle_c condition timer to be set to zero (see SPC5). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_FORCE_IDLE_C_0 0x2 +/// iSCSI SCSI Basic Inquiry Data peripheral type: Communications device. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_COMM 0x09 -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution power condition modifier: Force the standby_z condition timer to be set to zero (see SPC5). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_FORCE_STANDBY_Z_0 0x0 +/// iSCSI SCSI Basic Inquiry Data peripheral type: Unknown or no device. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_UNKNOWN 0x1F -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution power condition modifier: Force the standby_y condition timer to be set to zero (see SPC5). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_FORCE_STANDBY_Y_0 0x1 +/// iSCSI SCSI Basic Inquiry Data peripheral type: First bit of the five bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_FIRST_BIT 0 -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution power condition modifier: First bit of the four bits. -#define ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_FIRST_BIT 0 +/// iSCSI SCSI Basic Inquiry Data peripheral type: Last bit of the five bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_LAST_BIT ((ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_FIRST_BIT) + 5 - 1) -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution power condition modifier: Last bit of the four bits. -#define ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_LAST_BIT ((ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_FIRST_BIT) + 4 - 1) +/// iSCSI SCSI Basic Inquiry Data peripheral type: Bit mask. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_LAST_BIT)) -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution power condition modifier: Bit mask. -#define ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_FIRST_BIT, ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_LAST_BIT)) +/// iSCSI SCSI Basic Inquiry Data peripheral type: Extracts the peripheral device type bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_GET_PERIPHERAL_TYPE(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_LAST_BIT)) -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution power condition modifier: Extracts the power condition modifier bits. -#define ISCSI_SCSI_CDB_START_STOP_UNIT_GET_POWER_COND_MOD(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_FIRST_BIT, ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_LAST_BIT)) +/// iSCSI SCSI Basic Inquiry Data peripheral type: Stores into the peripheral device type bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PUT_PERIPHERAL_TYPE(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_LAST_BIT)) -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution power condition modifier: Stores into the power condition modifier bits. -#define ISCSI_SCSI_CDB_START_STOP_UNIT_PUT_POWER_COND_MOD(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_FIRST_BIT, ISCSI_SCSI_CDB_START_STOP_UNIT_POWER_COND_MOD_LAST_BIT)) +/// iSCSI SCSI Basic Inquiry Data peripheral identifier: The specified peripheral device type is currently connected to this logical unit, or connection state could not be determined. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_POSSIBLE 0x0 +/// iSCSI SCSI Basic Inquiry Data peripheral identifier: The target is capable of supporting the specified peripheral device type on this logical unit, but not connected. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_SUPPORTED 0x1 -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution flags: START. -#define ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_START (1 << 0) +/// iSCSI SCSI Basic Inquiry Data peripheral identifier: The target is not capable of supporting a physical device on this logical unit. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_NEVER 0x3 -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution flags: LOad EJect (LOEJ). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_LOEJ (1 << 1) +/// iSCSI SCSI Basic Inquiry Data peripheral identifier: Vendor specific. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_VENDOR_UNIQ 0x4 -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution flags: Do not flush caches until a power condition that prevents accessing the medium is entered (NO_FLUSH). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_NO_FLUSH (1 << 2) +/// iSCSI SCSI Basic Inquiry Data peripheral identifier: First bit of the three bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_FIRST_BIT 5 -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution flags power condition: Process the START and LOEJ bits (START_VALID). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_POWER_COND_START_VALID 0x0 +/// iSCSI SCSI Basic Inquiry Data peripheral identifier: Last bit of the three bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_LAST_BIT ((ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_FIRST_BIT) + 3 - 1) -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution flags power condition: Cause the logical unit to transition to the active power condition (see SPC5). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_POWER_COND_ACTIVE 0x1 +/// iSCSI SCSI Basic Inquiry Data peripheral identifier: Bit mask. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_LAST_BIT)) -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution flags power condition: Cause the logical unit to transition to the idle_a to idle_c power conditions (see SPC5). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_POWER_COND_IDLE 0x2 +/// iSCSI SCSI Basic Inquiry Data peripheral identifier: Extracts the peripheral device identifier bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_GET_PERIPHERAL_ID(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_LAST_BIT)) -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution flags power condition: Cause the logical unit to transition to the standby_z and standby_y power conditions (see SPC5). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_POWER_COND_STANDBY 0x3 +/// iSCSI SCSI Basic Inquiry Data peripheral identifier: Stores into the peripheral device identifier bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PUT_PERIPHERAL_ID(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_LAST_BIT)) -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution flags power condition: Obselete. -#define ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_POWER_COND_OBSELETE 0x5 -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution flags power condition: Initialize and start all of the idle and standby condition timers that are enabled (see SPC5). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_POWER_COND_LU_CONTROL 0x7 +/// iSCSI SCSI Basic Inquiry Data peripheral type modifier: First bit of the seven bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_FIRST_BIT 0 -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution flags power condition: Force the idle_a to idle_c condition timers to be set to zero (see SPC5). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_POWER_COND_FORCE_IDLE_0 0xA +/// iSCSI SCSI Basic Inquiry Data peripheral type modifier: Last bit of the seven bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_LAST_BIT ((ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_FIRST_BIT) + 7 - 1) -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution flags power condition: Force the standby_z and standby_y condition timers to be set to zero (see SPC5). -#define ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_POWER_COND_FORCE_STANDBY_0 0xB +/// iSCSI SCSI Basic Inquiry Data peripheral type modifier: Bit mask. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_LAST_BIT)) -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution flags power condition: First bit of the four bits. -#define ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_POWER_COND_FIRST_BIT 4 +/// iSCSI SCSI Basic Inquiry Data peripheral identifier: Extracts the peripheral type modifier bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_GET_PERIPHERAL_TYPE_MOD(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_LAST_BIT)) -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution flags power condition: Last bit of the four bits. -#define ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_POWER_COND_LAST_BIT ((ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_POWER_COND_FIRST_BIT) + 8 - 1) +/// iSCSI SCSI Basic Inquiry Data peripheral identifier: Stores into the peripheral type modifier bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PUT_PERIPHERAL_TYPE_MOD(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_LAST_BIT)) -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution flags power condition: Bit mask. -#define ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_POWER_COND_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_POWER_COND_FIRST_BIT, ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_POWER_COND_LAST_BIT)) +/// iSCSI SCSI Basic Inquiry Data peripheral type modifier: Removable media. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_FLAGS_REMOVABLE_MEDIA (1 << 7) -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution flags power condition: Extracts the power condition bits. -#define ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_GET_POWER_COND(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_POWER_COND_FIRST_BIT, ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_POWER_COND_LAST_BIT)) -/// iSCSI SCSI Command Descriptor Block (CDB) for START STOP UNIT command execution flags power condition: Stores into the power condition bits. -#define ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_PUT_POWER_COND(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_POWER_COND_FIRST_BIT, ISCSI_SCSI_CDB_START_STOP_UNIT_FLAGS_POWER_COND_LAST_BIT)) +/// iSCSI SCSI Basic Inquiry Data ANSI version: None. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_NONE 0x0 +/// iSCSI SCSI Basic Inquiry Data ANSI version: SPC. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_SPC 0x3 -/** - * @brief iSCSI SCSI CDB packet data structure for SCSI START STOP UNIT command. - * - * There are 6 bytes in the CDB field for this command. - */ -typedef struct __attribute__((packed)) iscsi_scsi_cdb_start_stop_unit { - /// SCSI opcode. - iscsi_scsi_cdb cdb; +/// iSCSI SCSI Basic Inquiry Data ANSI version: SPC2. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_SPC2 0x4 - /// Execution flags. - int8_t exec_flags; +/// iSCSI SCSI Basic Inquiry Data ANSI version: SPC3. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_SPC3 0x5 - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved; +/// iSCSI SCSI Basic Inquiry Data ANSI version: SPC4. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_SPC4 0x6 - /// Power condition modifier. - uint8_t power_cond_mod; +/// iSCSI SCSI Basic Inquiry Data ANSI version: SPC5. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_SPC5 0x7 - /// Flags. - int8_t flags; +/// iSCSI SCSI Basic Inquiry Data ANSI version: First bit of the three bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_FIRST_BIT 0 - /// Control. - uint8_t control; -} iscsi_scsi_cdb_start_stop_unit; +/// iSCSI SCSI Basic Inquiry Data ANSI version: Last bit of the three bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_LAST_BIT ((ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_FIRST_BIT) + 3 - 1) +/// iSCSI SCSI Basic Inquiry Data ANSI version: Bit mask. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_LAST_BIT)) -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE OUT command service action: Register - Register a reservation key without making a reservation. -#define ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_REGISTER 0x00 +/// iSCSI SCSI Basic Inquiry Data ANSI version: Extracts the ANSI version bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_GET_VERSION_ANSI(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_LAST_BIT)) -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE OUT command service action: Reserve - Create a persistent reservation of the specified scope and type. -#define ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_RESERVE 0x01 +/// iSCSI SCSI Basic Inquiry Data ANSI version: Stores into the ANSI version bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PUT_VERSION_ANSI(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_LAST_BIT)) -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE OUT command service action: Release - Releases the selected reservation for the requesting initiator. -#define ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_RELEASE 0x02 +/// iSCSI SCSI Basic Inquiry Data ECMA version: First bit of the three bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ECMA_FIRST_BIT 3 -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE OUT command service action: Clear – Clears all reservations keys and all persistent reservations. -#define ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_CLEAR 0x03 +/// iSCSI SCSI Basic Inquiry Data ECMA version: Last bit of the three bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ECMA_LAST_BIT ((ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ECMA_FIRST_BIT) + 3 - 1) -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE OUT command service action: Preempt – Preempt reservations from another initiator. -#define ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_PREEMPT 0x04 +/// iSCSI SCSI Basic Inquiry Data ECMA version: Bit mask. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ECMA_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ECMA_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ECMA_LAST_BIT)) -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE OUT command service action: Preempt reservations from another initiator and abort all tasks for all initiators with the specified reservation key. -#define ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_PREEMPT_ABORT 0x05 +/// iSCSI SCSI Basic Inquiry Data ECMA version: Extracts the ECMA version bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_GET_VERSION_ECMA(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ECMA_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ECMA_LAST_BIT)) -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE OUT command service action: Register and Ignore Existing Key – Register a new reservation key and discard existing reservation key. -#define ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_REGISTER_IGNORE_EXIST_KEY 0x06 +/// iSCSI SCSI Basic Inquiry Data ECMA version: Stores into the ECMA version bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PUT_VERSION_ECMA(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ECMA_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ECMA_LAST_BIT)) -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE OUT command service action: Register and Move Registers - Registers a reservation key for another I_T nexus and moves the persistent reservation to that I-T nexus. -#define ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_REGISTER_MOVE_REGS 0x07 +/// iSCSI SCSI Basic Inquiry Data ISO version: First bit of the two bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ISO_FIRST_BIT 6 -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE OUT command service action: First bit of the five bits. -#define ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_FIRST_BIT 0 +/// iSCSI SCSI Basic Inquiry Data ISO version: Last bit of the two bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ISO_LAST_BIT ((ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ISO_FIRST_BIT) + 2 - 1) -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE OUT command service action: Last bit of the five bits. -#define ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_LAST_BIT ((ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_FIRST_BIT) + 5 - 1) +/// iSCSI SCSI Basic Inquiry Data ISO version: Bit mask. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ISO_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ISO_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ISO_LAST_BIT)) -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE OUT command service action: Bit mask. -#define ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_FIRST_BIT, ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_LAST_BIT)) +/// iSCSI SCSI Basic Inquiry Data ISO version: Extracts the ISO version bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_GET_VERSION_ISO(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ISO_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ISO_LAST_BIT)) -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE OUT command service action: Extracts the service action bits. -#define ISCSI_SCSI_CDB_PR_RESERVE_OUT_GET_ACTION(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_FIRST_BIT, ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_LAST_BIT)) +/// iSCSI SCSI Basic Inquiry Data ISO version: Stores into the ISO version bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PUT_VERSION_ISO(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ISO_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ISO_LAST_BIT)) -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE OUT command service action: Stores into the service action bits. -#define ISCSI_SCSI_CDB_PR_RESERVE_OUT_PUT_ACTION(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_FIRST_BIT, ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_LAST_BIT)) +/// iSCSI SCSI Basic Inquiry Data response data format flags: This structure complies with SCSI-1 specifications. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_LEVEL_0 0x00 -/** - * @brief iSCSI SCSI CDB packet data structure for SCSI PERSISTENT RESERVE OUT command. - * - * There are 10 bytes in the CDB field for this command. - */ -typedef struct __attribute__((packed)) iscsi_scsi_cdb_pr_reserve_out { - /// SCSI opcode. - iscsi_scsi_cdb cdb; +/// iSCSI SCSI Basic Inquiry Data response data format flags: This structure complies with CCS pseudo specifications. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_CCS 0x01 - /// Service action. - uint8_t action; +/// iSCSI SCSI Basic Inquiry Data response data format flags: This structure complies with SCSI-2/3 specifications. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_SCSI_2 0x02 - /// Scope and reservation type. - uint8_t scope_type; +/// iSCSI SCSI Basic Inquiry Data response data format flags: First bit of the four bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_FIRST_BIT 0 - /// Reserved for future usage (always MUST be 0 for now). - uint16_t reserved; +/// iSCSI SCSI Basic Inquiry Data response data format flags: Last bit of the four bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_LAST_BIT ((ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_FIRST_BIT) + 4 - 1) - /// Parameter list length in bytes. - uint32_t param_list_len; +/// iSCSI SCSI Basic Inquiry Data response data format flags: Bit mask. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_LAST_BIT)) - /// Control. - uint8_t control; -} iscsi_scsi_cdb_pr_reserve_out; +/// iSCSI SCSI Basic Inquiry Data response data format flags: Extracts the response data format flags bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_GET_RESPONSE_DATA_FMT_FLAGS(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_LAST_BIT)) +/// iSCSI SCSI Basic Inquiry Data response data format flags: Stores into the response data format flags bits. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PUT_RESPONSE_DATA_FMT_FLAGS(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_LAST_BIT)) -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE IN command service action: Read keys - Reads all registered reservation keys (i.e. registrations) as described in SPC5. -#define ISCSI_SCSI_CDB_PR_RESERVE_IN_ACTION_READ_KEYS 0x00 +/// iSCSI SCSI Basic Inquiry Data response data format flags: Hierarchical Support. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_HISUP (1 << 4) -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE IN command service action: Read reservations - Reads the current persistent reservations as described in SPC5. -#define ISCSI_SCSI_CDB_PR_RESERVE_IN_ACTION_READ_RESERVATIONS 0x01 +/// iSCSI SCSI Basic Inquiry Data response data format flags: Normal ACA Supported. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_NORMACA (1 << 5) -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE IN command service action: Report capabilities - Returns capability information. -#define ISCSI_SCSI_CDB_PR_RESERVE_IN_ACTION_READ_REPORT_CAPABILITIES 0x02 +/// iSCSI SCSI Basic Inquiry Data response data format flags: TERMINATE I/O PROCESS message device support. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_TERMINATE_IO_PROC_MSG (1 << 6) -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE IN command service action: Read full status – Reads complete information about all registrations and the persistent reservations, if any. -#define ISCSI_SCSI_CDB_PR_RESERVE_IN_ACTION_READ_FULL_STATUS 0x03 - -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE IN command service action: First bit of the five bits. -#define ISCSI_SCSI_CDB_PR_RESERVE_IN_ACTION_FIRST_BIT 0 - -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE IN command service action: Last bit of the five bits. -#define ISCSI_SCSI_CDB_PR_RESERVE_IN_ACTION_LAST_BIT ((ISCSI_SCSI_CDB_PR_RESERVE_IN_ACTION_FIRST_BIT) + 5 - 1) - -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE IN command service action: Bit mask. -#define ISCSI_SCSI_CDB_PR_RESERVE_IN_ACTION_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_CDB_PR_RESERVE_IN_ACTION_FIRST_BIT, ISCSI_SCSI_CDB_PR_RESERVE_IN_ACTION_LAST_BIT)) - -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE IN command service action: Extracts the service action bits. -#define ISCSI_SCSI_CDB_PR_RESERVE_IN_GET_ACTION(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_CDB_PR_RESERVE_IN_ACTION_FIRST_BIT, ISCSI_SCSI_CDB_PR_RESERVE_IN_ACTION_LAST_BIT)) - -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE IN command service action: Stores into the service action bits. -#define ISCSI_SCSI_CDB_PR_RESERVE_IN_PUT_ACTION(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_CDB_PR_RESERVE_IN_ACTION_FIRST_BIT, ISCSI_SCSI_CDB_PR_RESERVE_IN_ACTION_LAST_BIT)) - - -/** - * @brief iSCSI SCSI CDB packet data structure for SCSI PERSISTENT RESERVE IN command. - * - * There are 10 bytes in the CDB field for this command. - */ -typedef struct __attribute__((packed)) iscsi_scsi_cdb_pr_reserve_in { - /// SCSI opcode. - iscsi_scsi_cdb cdb; - - /// Service action. - uint8_t action; - - /// Reserved for future usage (always MUST be 0 for now). - uint32_t reserved; - - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved2; - - /// Parameter list length in bytes. - uint16_t param_list_len; - - /// Control. - uint8_t control; -} iscsi_scsi_cdb_pr_reserve_in; - - -/** - * @brief iSCSI SCSI CDB packet data structure for SCSI RESERVE(6) command. - * - * There are 6 bytes in the CDB field for this command. - */ -typedef struct __attribute__((packed)) iscsi_scsi_cdb_pr_reserve_6 { - /// SCSI opcode. - iscsi_scsi_cdb cdb; - - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved_obselete; - - /// Obselete byte. - uint8_t obselete; - - /// Obselete word. - uint16_t obselete2; - - /// Control. - uint8_t control; -} iscsi_scsi_cdb_pr_reserve_6; - - -/// iSCSI SCSI Command Descriptor Block (CDB) for RESERVE(10) command flags: Long identifier larger than 255 (LONGID). -#define ISCSI_SCSI_CDB_RESERVE_10_FLAGS_LONGID (1 << 1) - -/// iSCSI SCSI Command Descriptor Block (CDB) for RESERVE(10) command flags: Third-party reservation (3RDPTY). -#define ISCSI_SCSI_CDB_RESERVE_10_FLAGS_3RDPTY (1 << 4) - - -/** - * @brief iSCSI SCSI CDB packet data structure for SCSI RESERVE(10) command. - * - * There are 10 bytes in the CDB field for this command. - */ -typedef struct __attribute__((packed)) iscsi_scsi_cdb_pr_reserve_10 { - /// SCSI opcode. - iscsi_scsi_cdb cdb; - - /// Flags. - int8_t flags; - - /// Obselete. - uint8_t obselete; - - /// Third-party device identifier. - uint8_t third_party_dev_id; - - /// Reserved for future usage (always MUST be 0 for now). - uint16_t reserved; - - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved2; - - /// Parameter list length in bytes. - uint16_t param_list_len; - - /// Control. - uint8_t control; -} iscsi_scsi_cdb_pr_reserve_10; - - -/** - * @brief iSCSI SCSI CDB packet data structure for SCSI RELEASE(6) command. - * - * There are 6 bytes in the CDB field for this command. - */ -typedef struct __attribute__((packed)) iscsi_scsi_cdb_pr_release_6 { - /// SCSI opcode. - iscsi_scsi_cdb cdb; - - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved_obselete; - - /// Obselete byte. - uint8_t obselete; - - /// Obselete word. - uint16_t obselete2; - - /// Control. - uint8_t control; -} iscsi_scsi_cdb_pr_release_6; - - -/// iSCSI SCSI Command Descriptor Block (CDB) for RELEASE(10) command flags: Long identifier larger than 255 (LONGID). -#define ISCSI_SCSI_CDB_RELEASE_10_FLAGS_LONGID (1 << 1) - -/// iSCSI SCSI Command Descriptor Block (CDB) for RELEASE(10) command flags: Third-party reservation (3RDPTY). -#define ISCSI_SCSI_CDB_RELEASE_10_FLAGS_3RDPTY (1 << 4) - - -/** - * @brief iSCSI SCSI CDB packet data structure for SCSI RELEASE(10) command. - * - * There are 10 bytes in the CDB field for this command. - */ -typedef struct __attribute__((packed)) iscsi_scsi_cdb_pr_release_10 { - /// SCSI opcode. - iscsi_scsi_cdb cdb; - - /// Flags. - int8_t flags; - - /// Obselete. - uint8_t obselete; - - /// Third-party device identifier. - uint8_t third_party_dev_id; - - /// Reserved for future usage (always MUST be 0 for now). - uint16_t reserved; - - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved2; - - /// Parameter list length in bytes. - uint16_t param_list_len; - - /// Control. - uint8_t control; -} iscsi_scsi_cdb_pr_release_10; - - -/** - * @brief iSCSI SCSI DataSegment Command packet structure. - * - * iSCSI targets MUST support and enable Autosense. If Status is CHECK - * CONDITION (0x02), then the data segment MUST contain sense data for - * the failed command. - * - * For some iSCSI responses, the response data segment MAY contain some - * response-related information (e.g., for a target failure, it may - * contain a vendor-specific detailed description of the failure). - */ -typedef struct __attribute__((packed)) iscsi_scsi_ds_cmd_data { - /// SenseLength: This field indicates the length of Sense Data. - uint16_t len; - - /// The Sense Data contains detailed information about a CHECK CONDITION. SPC3 specifies the format and content of the Sense Data. - uint8_t sense_data[0]; - - /// Response Data. - uint8_t res_data[0]; -} iscsi_scsi_ds_cmd_data; - - -/// iSCSI SCSI Basic Inquiry Data peripheral type: Direct access device. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_DIRECT 0x00 - -/// iSCSI SCSI Basic Inquiry Data peripheral type: Sequential access device. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_SEQ 0x01 - -/// iSCSI SCSI Basic Inquiry Data peripheral type: Printer device. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_PRINTER 0x02 - -/// iSCSI SCSI Basic Inquiry Data peripheral type: Processor device. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_PROCESSOR 0x03 - -/// iSCSI SCSI Basic Inquiry Data peripheral type: Write once device. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_WORM 0x04 - -/// iSCSI SCSI Basic Inquiry Data peripheral type: Read only direct access (e.g. CD-ROM) device. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_RO_DIRECT 0x05 - -/// iSCSI SCSI Basic Inquiry Data peripheral type: Scanner device. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_SCANNER 0x06 - -/// iSCSI SCSI Basic Inquiry Data peripheral type: Optical memory device. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_OPTICAL 0x07 - -/// iSCSI SCSI Basic Inquiry Data peripheral type: Medium changer device. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_CHANGER 0x08 - -/// iSCSI SCSI Basic Inquiry Data peripheral type: Communications device. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_COMM 0x09 - -/// iSCSI SCSI Basic Inquiry Data peripheral type: Unknown or no device. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_UNKNOWN 0x1F - -/// iSCSI SCSI Basic Inquiry Data peripheral type: First bit of the five bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_FIRST_BIT 0 - -/// iSCSI SCSI Basic Inquiry Data peripheral type: Last bit of the five bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_LAST_BIT ((ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_FIRST_BIT) + 5 - 1) - -/// iSCSI SCSI Basic Inquiry Data peripheral type: Bit mask. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_LAST_BIT)) - -/// iSCSI SCSI Basic Inquiry Data peripheral type: Extracts the peripheral device type bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_GET_PERIPHERAL_TYPE(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_LAST_BIT)) - -/// iSCSI SCSI Basic Inquiry Data peripheral type: Stores into the peripheral device type bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PUT_PERIPHERAL_TYPE(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_LAST_BIT)) - -/// iSCSI SCSI Basic Inquiry Data peripheral identifier: The specified peripheral device type is currently connected to this logical unit, or connection state could not be determined. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_POSSIBLE 0x0 - -/// iSCSI SCSI Basic Inquiry Data peripheral identifier: The target is capable of supporting the specified peripheral device type on this logical unit, but not connected. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_SUPPORTED 0x1 - -/// iSCSI SCSI Basic Inquiry Data peripheral identifier: The target is not capable of supporting a physical device on this logical unit. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_NEVER 0x3 - -/// iSCSI SCSI Basic Inquiry Data peripheral identifier: Vendor specific. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_VENDOR_UNIQ 0x4 - -/// iSCSI SCSI Basic Inquiry Data peripheral identifier: First bit of the three bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_FIRST_BIT 5 - -/// iSCSI SCSI Basic Inquiry Data peripheral identifier: Last bit of the three bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_LAST_BIT ((ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_FIRST_BIT) + 3 - 1) - -/// iSCSI SCSI Basic Inquiry Data peripheral identifier: Bit mask. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_LAST_BIT)) - -/// iSCSI SCSI Basic Inquiry Data peripheral identifier: Extracts the peripheral device identifier bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_GET_PERIPHERAL_ID(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_LAST_BIT)) - -/// iSCSI SCSI Basic Inquiry Data peripheral identifier: Stores into the peripheral device identifier bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PUT_PERIPHERAL_ID(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_ID_LAST_BIT)) - - -/// iSCSI SCSI Basic Inquiry Data peripheral type modifier: First bit of the seven bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_FIRST_BIT 0 - -/// iSCSI SCSI Basic Inquiry Data peripheral type modifier: Last bit of the seven bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_LAST_BIT ((ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_FIRST_BIT) + 7 - 1) - -/// iSCSI SCSI Basic Inquiry Data peripheral type modifier: Bit mask. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_LAST_BIT)) - -/// iSCSI SCSI Basic Inquiry Data peripheral identifier: Extracts the peripheral type modifier bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_GET_PERIPHERAL_TYPE_MOD(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_LAST_BIT)) - -/// iSCSI SCSI Basic Inquiry Data peripheral identifier: Stores into the peripheral type modifier bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PUT_PERIPHERAL_TYPE_MOD(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_LAST_BIT)) - -/// iSCSI SCSI Basic Inquiry Data peripheral type modifier: Removable media. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PERIPHERAL_TYPE_MOD_FLAGS_REMOVABLE_MEDIA (1 << 7) - - -/// iSCSI SCSI Basic Inquiry Data ANSI version: None. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_NONE 0x0 - -/// iSCSI SCSI Basic Inquiry Data ANSI version: SPC. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_SPC 0x3 - -/// iSCSI SCSI Basic Inquiry Data ANSI version: SPC2. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_SPC2 0x4 - -/// iSCSI SCSI Basic Inquiry Data ANSI version: SPC3. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_SPC3 0x5 - -/// iSCSI SCSI Basic Inquiry Data ANSI version: SPC4. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_SPC4 0x6 - -/// iSCSI SCSI Basic Inquiry Data ANSI version: SPC5. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_SPC5 0x7 - -/// iSCSI SCSI Basic Inquiry Data ANSI version: First bit of the three bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_FIRST_BIT 0 - -/// iSCSI SCSI Basic Inquiry Data ANSI version: Last bit of the three bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_LAST_BIT ((ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_FIRST_BIT) + 3 - 1) - -/// iSCSI SCSI Basic Inquiry Data ANSI version: Bit mask. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_LAST_BIT)) - -/// iSCSI SCSI Basic Inquiry Data ANSI version: Extracts the ANSI version bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_GET_VERSION_ANSI(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_LAST_BIT)) - -/// iSCSI SCSI Basic Inquiry Data ANSI version: Stores into the ANSI version bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PUT_VERSION_ANSI(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ANSI_LAST_BIT)) - -/// iSCSI SCSI Basic Inquiry Data ECMA version: First bit of the three bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ECMA_FIRST_BIT 3 - -/// iSCSI SCSI Basic Inquiry Data ECMA version: Last bit of the three bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ECMA_LAST_BIT ((ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ECMA_FIRST_BIT) + 3 - 1) - -/// iSCSI SCSI Basic Inquiry Data ECMA version: Bit mask. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ECMA_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ECMA_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ECMA_LAST_BIT)) - -/// iSCSI SCSI Basic Inquiry Data ECMA version: Extracts the ECMA version bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_GET_VERSION_ECMA(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ECMA_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ECMA_LAST_BIT)) - -/// iSCSI SCSI Basic Inquiry Data ECMA version: Stores into the ECMA version bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PUT_VERSION_ECMA(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ECMA_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ECMA_LAST_BIT)) - -/// iSCSI SCSI Basic Inquiry Data ISO version: First bit of the two bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ISO_FIRST_BIT 6 - -/// iSCSI SCSI Basic Inquiry Data ISO version: Last bit of the two bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ISO_LAST_BIT ((ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ISO_FIRST_BIT) + 2 - 1) - -/// iSCSI SCSI Basic Inquiry Data ISO version: Bit mask. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ISO_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ISO_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ISO_LAST_BIT)) - -/// iSCSI SCSI Basic Inquiry Data ISO version: Extracts the ISO version bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_GET_VERSION_ISO(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ISO_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ISO_LAST_BIT)) - -/// iSCSI SCSI Basic Inquiry Data ISO version: Stores into the ISO version bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PUT_VERSION_ISO(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ISO_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_VERSION_ISO_LAST_BIT)) - - -/// iSCSI SCSI Basic Inquiry Data response data format flags: This structure complies with SCSI-1 specifications. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_LEVEL_0 0x00 - -/// iSCSI SCSI Basic Inquiry Data response data format flags: This structure complies with CCS pseudo specifications. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_CCS 0x01 - -/// iSCSI SCSI Basic Inquiry Data response data format flags: This structure complies with SCSI-2/3 specifications. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_SCSI_2 0x02 - -/// iSCSI SCSI Basic Inquiry Data response data format flags: First bit of the four bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_FIRST_BIT 0 - -/// iSCSI SCSI Basic Inquiry Data response data format flags: Last bit of the four bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_LAST_BIT ((ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_FIRST_BIT) + 4 - 1) - -/// iSCSI SCSI Basic Inquiry Data response data format flags: Bit mask. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_LAST_BIT)) - -/// iSCSI SCSI Basic Inquiry Data response data format flags: Extracts the response data format flags bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_GET_RESPONSE_DATA_FMT_FLAGS(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_LAST_BIT)) - -/// iSCSI SCSI Basic Inquiry Data response data format flags: Stores into the response data format flags bits. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_PUT_RESPONSE_DATA_FMT_FLAGS(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_FIRST_BIT, ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_LAST_BIT)) - -/// iSCSI SCSI Basic Inquiry Data response data format flags: Hierarchical Support. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_HISUP (1 << 4) - -/// iSCSI SCSI Basic Inquiry Data response data format flags: Normal ACA Supported. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_NORMACA (1 << 5) - -/// iSCSI SCSI Basic Inquiry Data response data format flags: TERMINATE I/O PROCESS message device support. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_TERMINATE_IO_PROC_MSG (1 << 6) - -/// iSCSI SCSI Basic Inquiry Data response data format flags: Asynchronous Event Notification device support. -#define ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_ASYNC_EVENT_NOTIFY (1 << 7) +/// iSCSI SCSI Basic Inquiry Data response data format flags: Asynchronous Event Notification device support. +#define ISCSI_SCSI_BASIC_INQUIRY_DATA_RESPONSE_DATA_FMT_FLAGS_ASYNC_EVENT_NOTIFY (1 << 7) /** @@ -2414,20 +1167,20 @@ typedef struct __attribute__((packed)) iscsi_scsi_ds_cmd_data { * cleared. */ typedef struct __attribute__((packed)) iscsi_scsi_basic_inquiry_data_packet { - /// Peripheral device type and qualifier. - uint8_t peripheral_type_id; + /// Peripheral device type and qualifier. + uint8_t peripheral_type_id; - /// Peripheral device type modifier and removable media bit. - int8_t peripheral_type_mod_flags; + /// Peripheral device type modifier and removable media bit. + int8_t peripheral_type_mod_flags; - /// ANSI-Approved, ECMA and ISO version. - uint8_t version; + /// ANSI-Approved, ECMA and ISO version. + uint8_t version; - /// Response data format, HISUP, NORMACA, AENC and TrmIOP flags. - int8_t response_data_fmt_flags; + /// Response data format, HISUP, NORMACA, AENC and TrmIOP flags. + int8_t response_data_fmt_flags; - /// Additional length in bytes. - uint8_t add_len; + /// Additional length in bytes. + uint8_t add_len; } iscsi_scsi_basic_inquiry_data_packet; @@ -2503,26 +1256,26 @@ typedef struct __attribute__((packed)) iscsi_scsi_basic_inquiry_data_packet { * cleared. */ typedef struct __attribute__((packed)) iscsi_scsi_std_inquiry_data_packet { - /// iSCSI SCSI basic inquiry data packet. - iscsi_scsi_basic_inquiry_data_packet basic_inquiry; + /// iSCSI SCSI basic inquiry data packet. + iscsi_scsi_basic_inquiry_data_packet basic_inquiry; - /// PROTECT, 3PC, TPGS, ACC and SCCS. - uint8_t tpgs_flags; + /// PROTECT, 3PC, TPGS, ACC and SCCS. + uint8_t tpgs_flags; - /// MULTIP, VS and ENCSERV. - int8_t services_flags; + /// MULTIP, VS and ENCSERV. + int8_t services_flags; - /// Flags. - int8_t flags; + /// Flags. + int8_t flags; - /// Vendor identification. - uint8_t vendor_id[8]; + /// Vendor identification. + uint8_t vendor_id[8]; - /// Product identification. - uint8_t product_id[16]; + /// Product identification. + uint8_t product_id[16]; - /// Product revision level. - uint8_t product_rev_level[4]; + /// Product revision level. + uint8_t product_rev_level[4]; } iscsi_scsi_std_inquiry_data_packet; @@ -2551,29 +1304,29 @@ typedef struct __attribute__((packed)) iscsi_scsi_std_inquiry_data_packet { * cleared. */ typedef struct __attribute__((packed)) iscsi_scsi_ext_inquiry_data_packet { - /// iSCSI SCSI standard inquiry data packet. - iscsi_scsi_std_inquiry_data_packet std_inquiry; + /// iSCSI SCSI standard inquiry data packet. + iscsi_scsi_std_inquiry_data_packet std_inquiry; - /// Vendor specific. - uint8_t vendor_spec[20]; + /// Vendor specific. + uint8_t vendor_spec[20]; - /// Flags. - int8_t flags; + /// Flags. + int8_t flags; - /// Reserved for future usage (always MUST be 0). - uint8_t reserved; + /// Reserved for future usage (always MUST be 0). + uint8_t reserved; - /// Version descriptors. - uint16_t version_desc[8]; + /// Version descriptors. + uint16_t version_desc[8]; - /// Reserved for future usage (always MUST be 0). - uint64_t reserved2[2]; + /// Reserved for future usage (always MUST be 0). + uint64_t reserved2[2]; - /// Reserved for future usage (always MUST be 0). - uint32_t reserved3; + /// Reserved for future usage (always MUST be 0). + uint32_t reserved3; - /// Reserved for future usage (always MUST be 0). - uint16_t reserved4; + /// Reserved for future usage (always MUST be 0). + uint16_t reserved4; } iscsi_scsi_ext_inquiry_data_packet; @@ -2699,17 +1452,17 @@ typedef struct __attribute__((packed)) iscsi_scsi_ext_inquiry_data_packet { * set. */ typedef struct __attribute__((packed)) iscsi_scsi_vpd_page_inquiry_data_packet { - /// Peripheral device type and qualifier. - uint8_t peripheral_type_id; + /// Peripheral device type and qualifier. + uint8_t peripheral_type_id; - /// Page code. - uint8_t page_code; + /// Page code. + uint8_t page_code; - /// Allocation length in bytes. - uint16_t alloc_len; + /// Allocation length in bytes. + uint16_t alloc_len; - /// Parameters. - uint8_t params[0]; + /// Parameters. + uint8_t params[0]; } iscsi_scsi_vpd_page_inquiry_data_packet; @@ -2834,20 +1587,20 @@ typedef struct __attribute__((packed)) iscsi_scsi_vpd_page_inquiry_data_packet { * set. */ typedef struct __attribute__((packed)) iscsi_scsi_vpd_page_design_desc_inquiry_data_packet { - /// Protocol identifier and code set. - uint8_t protocol_id_code_set; + /// Protocol identifier and code set. + uint8_t protocol_id_code_set; - /// Flags. - int8_t flags; + /// Flags. + int8_t flags; - /// Reserved for future usage (always MUST be 0). - uint8_t reserved; + /// Reserved for future usage (always MUST be 0). + uint8_t reserved; - /// Length in bytes. - uint8_t len; + /// Length in bytes. + uint8_t len; - /// Designation descriptor. - uint8_t desc[0]; + /// Designation descriptor. + uint8_t desc[0]; } iscsi_scsi_vpd_page_design_desc_inquiry_data_packet; @@ -2859,8 +1612,8 @@ typedef struct __attribute__((packed)) iscsi_scsi_vpd_page_design_desc_inquiry_d * set. */ typedef struct __attribute__((packed)) iscsi_scsi_vpd_page_design_desc_ieee_naa_ext_inquiry_data_packet { - /// IEEE NAA Extended. - uint64_t ieee_naa_ext; + /// IEEE NAA Extended. + uint64_t ieee_naa_ext; } iscsi_scsi_vpd_page_design_desc_ieee_naa_ext_inquiry_data_packet; @@ -2872,14 +1625,14 @@ typedef struct __attribute__((packed)) iscsi_scsi_vpd_page_design_desc_ieee_naa_ * set. */ typedef struct __attribute__((packed)) iscsi_scsi_vpd_page_design_desc_t10_vendor_id_inquiry_data_packet { - /// Vendor identification. - uint8_t vendor_id[8]; + /// Vendor identification. + uint8_t vendor_id[8]; - /// Product identification. - uint8_t product_id[16]; + /// Product identification. + uint8_t product_id[16]; - /// Unit serial number. - uint8_t unit_serial_num[32]; + /// Unit serial number. + uint8_t unit_serial_num[32]; } iscsi_scsi_vpd_page_design_desc_t10_vendor_id_inquiry_data_packet; @@ -2891,11 +1644,11 @@ typedef struct __attribute__((packed)) iscsi_scsi_vpd_page_design_desc_t10_vendo * set. */ typedef struct __attribute__((packed)) iscsi_scsi_vpd_page_design_desc_rel_target_port_inquiry_data_packet { - /// Reserved for future usage (always MUST be 0). - uint16_t reserved; + /// Reserved for future usage (always MUST be 0). + uint16_t reserved; - /// Port index. - uint16_t index; + /// Port index. + uint16_t index; } iscsi_scsi_vpd_page_design_desc_rel_target_port_inquiry_data_packet; @@ -2907,11 +1660,11 @@ typedef struct __attribute__((packed)) iscsi_scsi_vpd_page_design_desc_rel_targe * set. */ typedef struct __attribute__((packed)) iscsi_scsi_vpd_page_design_desc_target_port_group_inquiry_data_packet { - /// Reserved for future usage (always MUST be 0). - uint16_t reserved; + /// Reserved for future usage (always MUST be 0). + uint16_t reserved; - /// Port group index. - uint16_t index; + /// Port group index. + uint16_t index; } iscsi_scsi_vpd_page_design_desc_target_port_group_inquiry_data_packet; @@ -2923,11 +1676,11 @@ typedef struct __attribute__((packed)) iscsi_scsi_vpd_page_design_desc_target_po * set. */ typedef struct __attribute__((packed)) iscsi_scsi_vpd_page_design_desc_logical_unit_group_inquiry_data_packet { - /// Reserved for future usage (always MUST be 0). - uint16_t reserved; + /// Reserved for future usage (always MUST be 0). + uint16_t reserved; - /// Logical unit identifier. - uint16_t id; + /// Logical unit identifier. + uint16_t id; } iscsi_scsi_vpd_page_design_desc_logical_unit_group_inquiry_data_packet; @@ -3075,296 +1828,47 @@ typedef struct __attribute__((packed)) iscsi_scsi_vpd_page_design_desc_logical_u * set. */ typedef struct __attribute__((packed)) iscsi_scsi_vpd_page_ext_inquiry_data_packet { - /// Peripheral device type and qualifier. - uint8_t peripheral_type_id; + /// Peripheral device type and qualifier. + uint8_t peripheral_type_id; - /// Page code. - uint8_t page_code; + /// Page code. + uint8_t page_code; - /// Reserved for future usage (always MUST be 0). - uint8_t reserved; + /// Reserved for future usage (always MUST be 0). + uint8_t reserved; - /// Page length in bytes. - uint8_t page_len; + /// Page length in bytes. + uint8_t page_len; - /// Check flags. - int8_t check_flags; + /// Check flags. + int8_t check_flags; - /// Support flags. - int8_t support_flags; + /// Support flags. + int8_t support_flags; - /// More support flags. - int8_t support_flags_2; + /// More support flags. + int8_t support_flags_2; - /// LUICLR. - uint8_t luiclr; + /// LUICLR. + uint8_t luiclr; - /// CBCS. - uint8_t cbcs; + /// CBCS. + uint8_t cbcs; - /// Micro DL. - uint8_t micro_dl; + /// Micro DL. + uint8_t micro_dl; - /// Reserved for future usage (always MUST be 0). - uint64_t reserved2[6]; + /// Reserved for future usage (always MUST be 0). + uint64_t reserved2[6]; - /// Reserved for future usage (always MUST be 0). - uint32_t reserved3; + /// Reserved for future usage (always MUST be 0). + uint32_t reserved3; - /// Reserved for future usage (always MUST be 0). - uint16_t reserved4; + /// Reserved for future usage (always MUST be 0). + uint16_t reserved4; } iscsi_scsi_vpd_page_ext_inquiry_data_packet; -/// iSCSI SCSI Vital Product Data (VPD) Mode Page Policy Descriptor Inquiry Data policy page code: First bit of the six bits. -#define ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_POLICY_PAGE_CODE_FIRST_BIT 0 - -/// iSCSI SCSI Vital Product Data (VPD) Mode Page Policy Descriptor Inquiry Data policy page code: Last bit of the six bits. -#define ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_POLICY_PAGE_CODE_LAST_BIT ((ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_POLICY_PAGE_CODE_FIRST_BIT) + 6 - 1) - -/// iSCSI SCSI Vital Product Data (VPD) Mode Page Policy Descriptor Inquiry Data policy page code: Bit mask. -#define ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_POLICY_PAGE_CODE_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_POLICY_PAGE_CODE_FIRST_BIT, ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_POLICY_PAGE_CODE_LAST_BIT)) - -/// iSCSI SCSI Vital Product Data (VPD) Mode Page Policy Descriptor Inquiry Data policy page code: Extracts the policy page code bits. -#define ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_GET_POLICY_PAGE_CODE(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_POLICY_PAGE_CODE_FIRST_BIT, ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_POLICY_PAGE_CODE_LAST_BIT)) - -/// iSCSI SCSI Vital Product Data (VPD) Mode Page Policy Descriptor Inquiry Data policy page code: Stores into the policy page code bits. -#define ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_PUT_POLICY_PAGE_CODE(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_POLICY_PAGE_CODE_FIRST_BIT, ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_POLICY_PAGE_CODE_LAST_BIT)) - - -/// iSCSI SCSI Vital Product Data (VPD) Mode Page Policy Descriptor Inquiry Data flags mode page policy: First bit of the two bits. -#define ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_FLAGS_MODE_PAGE_POLICY_FIRST_BIT 0 - -/// iSCSI SCSI Vital Product Data (VPD) Mode Page Policy Descriptor Inquiry Data flags mode page policy: Last bit of the two bits. -#define ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_FLAGS_MODE_PAGE_POLICY_LAST_BIT ((ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_FLAGS_MODE_PAGE_POLICY_FIRST_BIT) + 2 - 1) - -/// iSCSI SCSI Vital Product Data (VPD) Mode Page Policy Descriptor Inquiry Data flags mode page policy: Bit mask. -#define ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_FLAGS_MODE_PAGE_POLICY_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_FLAGS_MODE_PAGE_POLICY_FIRST_BIT, ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_FLAGS_MODE_PAGE_POLICY_LAST_BIT)) - -/// iSCSI SCSI Vital Product Data (VPD) Mode Page Policy Descriptor Inquiry Data flags mode page policy: Extracts the mode page policy bits. -#define ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_FLAGS_GET_MODE_PAGE_POLICY(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_FLAGS_MODE_PAGE_POLICY_FIRST_BIT, ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_FLAGS_MODE_PAGE_POLICY_LAST_BIT)) - -/// iSCSI SCSI Vital Product Data (VPD) Mode Page Policy Descriptor Inquiry Data flags mode page policy: Stores into the mode page policy bits. -#define ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_FLAGS_PUT_MODE_PAGE_POLICY(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_FLAGS_MODE_PAGE_POLICY_FIRST_BIT, ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_FLAGS_MODE_PAGE_POLICY_LAST_BIT)) - -/// iSCSI SCSI Vital Product Data (VPD) Mode Page Policy Descriptor Inquiry Data flag: Multiple Logical Units Share (MLUS). -#define ISCSI_SCSI_VPD_MODE_PAGE_POLICY_DESC_INQUIRY_DATA_FLAGS_MLUS (1 << 7) - - -/** - * @brief iSCSI SCSI Vital Product Data (VPD) Mode Page Policy Descriptor Inquiry data packet. - * - * This structure is used by the SCSI INQUIRY command - * in order to fill in the result if the EVPD bit is - * set. - */ -typedef struct __attribute__((packed)) iscsi_scsi_vpd_mode_page_policy_desc_inquiry_data_packet { - /// Policy page code. - uint8_t page_code; - - /// Policy sub page code. - uint8_t sub_page_code; - - /// Policy flags. - int8_t flags; - - /// Reserved for future usage (always MUST be 0). - uint8_t reserved; -} iscsi_scsi_vpd_mode_page_policy_desc_inquiry_data_packet; - - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data protocol identifier: iSCSI. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_PROTOCOL_ID_ISCSI 0x05 - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data protocol identifier: First bit of the four bits. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_PROTOCOL_ID_FIRST_BIT 0 - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data protocol identifier: Last bit of the four bits. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_PROTOCOL_ID_LAST_BIT ((ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_PROTOCOL_ID_FIRST_BIT) + 4 - 1) - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data protocol identifier: Bit mask. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_PROTOCOL_ID_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_PROTOCOL_ID_FIRST_BIT, ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_PROTOCOL_ID_LAST_BIT)) - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data protocol identifier: Extracts the protocol identifier bits. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_GET_PROTOCOL_ID(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_PROTOCOL_ID_FIRST_BIT, ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_PROTOCOL_ID_LAST_BIT)) - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data protocol identifier: Stores into the protocol identifier bits. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_PUT_PROTOCOL_ID(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_PROTOCOL_ID_FIRST_BIT, ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_PROTOCOL_ID_LAST_BIT)) - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data code set: Binary encoding. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_CODE_SET_BINARY 0x01 - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data code set: ASCII encoding. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_CODE_SET_ASCII 0x02 - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data code set: UTF-8 encoding. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_CODE_SET_UTF8 0x03 - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data code set: First bit of the four bits. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_CODE_SET_FIRST_BIT 4 - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data code set: Last bit of the four bits. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_CODE_SET_LAST_BIT ((ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_CODE_SET_FIRST_BIT) + 8 - 1) - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data code set: Bit mask. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_CODE_SET_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_CODE_SET_FIRST_BIT, ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_CODE_SET_LAST_BIT)) - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data code set: Extracts the protocol identifier bits. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_GET_CODE_SET(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_CODE_SET_FIRST_BIT, ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_CODE_SET_LAST_BIT)) - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data code set: Stores into the protocol identifier bits. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_PUT_CODE_SET(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_CODE_SET_FIRST_BIT, ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_CODE_SET_LAST_BIT)) - - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags type: Vendor specific. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_TYPE_VENDOR_SPEC 0x00 - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags type: T10 vendor identifier. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_TYPE_T10_VENDOR_ID 0x01 - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags type: EUI64. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_TYPE_EUI64 0x02 - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags type: NAA. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_TYPE_NAA 0x03 - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags type: Relative target port. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_TYPE_REL_TARGET_PORT 0x04 - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags type: Target port group. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_TYPE_TARGET_PORT_GROUP 0x05 - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags type: Logical unit group. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_TYPE_LOGICAL_UNIT_GROUP 0x06 - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags type: MD5 logical unit. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_TYPE_MD5_LOGICAL_UNIT 0x07 - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags type: SCSI name. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_TYPE_SCSI_NAME 0x08 - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags type: First bit of the four bits. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_TYPE_FIRST_BIT 0 - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags type: Last bit of the four bits. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_TYPE_LAST_BIT ((ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_TYPE_FIRST_BIT) + 4 - 1) - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags type: Bit mask. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_TYPE_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_TYPE_FIRST_BIT, ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_TYPE_LAST_BIT)) - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags type: Extracts the type bits. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_GET_TYPE(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_TYPE_FIRST_BIT, ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_TYPE_LAST_BIT)) - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags type: Stores into the type bits. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_PUT_TYPE(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_TYPE_FIRST_BIT, ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_TYPE_LAST_BIT)) - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags association: Logical unit. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_ASSOC_LOGICAL_UNIT 0x0 - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags association: Target port. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_ASSOC_TARGET_PORT 0x1 - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags association: Target device. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_ASSOC_TARGET_DEVICE 0x2 - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags association: First bit of the two bits. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_ASSOC_FIRST_BIT 4 - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags association: Last bit of the two bits. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_ASSOC_LAST_BIT ((ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_ASSOC_FIRST_BIT) + 6 - 1) - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags association: Bit mask. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_ASSOC_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_ASSOC_FIRST_BIT, ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_ASSOC_LAST_BIT)) - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags association: Extracts the association bits. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_GET_ASSOC(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_ASSOC_FIRST_BIT, ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_ASSOC_LAST_BIT)) - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags association: Stores into the association bits. -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_PUT_ASSOC(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_ASSOC_FIRST_BIT, ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_ASSOC_LAST_BIT)) - -/// iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data flags: Protocol Identifier Valid (PIV). -#define ISCSI_SCSI_VPD_SCSI_TARGET_PORT_DESIGN_DESC_INQUIRY_DATA_FLAGS_PIV (1 << 7) - - -/** - * @brief iSCSI SCSI Vital Product Data (VPD) SCSI Target Port Designation Descriptor Inquiry data packet. - * - * This structure is used by the SCSI INQUIRY command - * in order to fill in the result if the EVPD bit is - * set. - */ -typedef struct __attribute__((packed)) iscsi_scsi_vpd_scsi_target_port_design_dec_inquiry_data_packet { - /// Protocol identifier and code set. - uint8_t protocol_id_code_set; - - /// Flags. - int8_t flags; - - /// Reserved for future usage (always MUST be 0). - uint8_t reserved; - - /// Length in bytes. - uint8_t len; - - /// Designator. - uint8_t design[0]; -} iscsi_scsi_vpd_scsi_target_port_design_dec_inquiry_data_packet; - - -/** - * @brief iSCSI SCSI Vital Product Data (VPD) SCSI Port Designation Descriptor Inquiry data packet. - * - * This structure is used by the SCSI INQUIRY command - * in order to fill in the result if the EVPD bit is - * set. - */ -typedef struct __attribute__((packed)) iscsi_scsi_vpd_scsi_port_design_dec_inquiry_data_packet { - /// Reserved for future usage (always MUST be 0). - uint16_t reserved; - - /// Relative port identifier. - uint16_t rel_port_id; - - /// Reserved for future usage (always MUST be 0). - uint16_t reserved2; - - /// Initiator port length in bytes. - uint16_t init_port_len; - - /// Initiator port identifier. - uint16_t init_port_id[0]; - - /// Reserved for future usage (always MUST be 0). - uint16_t reserved3; - - /// SCSI Target Port Designation Descriptor length in bytes. - uint16_t target_desc_len; - - /// SCSI Target Port Designation Descriptor. - iscsi_scsi_vpd_scsi_target_port_design_dec_inquiry_data_packet target_desc[0]; -} iscsi_scsi_vpd_scsi_port_design_dec_inquiry_data_packet; - - -/** - * @brief iSCSI SCSI command INQUIRY Vital Product Data (VPD) SCSI Port Designation Descriptor entry fill. - * - * This structure is used by iterating through - * all iSCSI device ports in order to fill in - * the INQUIRY Vital Product Data (VPD) SCSI - * Port Designation Descriptor structure. - */ -typedef struct iscsi_scsi_emu_primary_inquiry_ports_fill { - /// Pointer to current Vital Product Data (VPD) SCSI Port Designation Descriptor entry packet data. - iscsi_scsi_vpd_scsi_port_design_dec_inquiry_data_packet *port_entry; - - /// Total length of Vital Product Data (VPD) SCSI Port Designation Descriptor entry packet data in bytes. - uint alloc_len; - - /// Total remaining allocation length for packet data in bytes. - uint len; -} iscsi_scsi_emu_primary_inquiry_ports_fill; - - /// iSCSI SCSI Vital Product Data (VPD) Page Block Limits Inquiry data UNMAP Granularity Alignment: First bit of the thirty one bits. #define ISCSI_SCSI_VPD_PAGE_BLOCK_LIMITS_INQUIRY_DATA_UNMAP_GRANULARITY_ALIGN_FIRST_BIT 0L @@ -3392,44 +1896,44 @@ typedef struct iscsi_scsi_emu_primary_inquiry_ports_fill { * set. */ typedef struct __attribute__((packed)) iscsi_scsi_vpd_page_block_limits_inquiry_data_packet { - /// Flags. - int8_t flags; + /// Flags. + int8_t flags; - /// Maximum COMPARE AND WRITE length in logical blocks. - uint8_t max_cmp_write_len; + /// Maximum COMPARE AND WRITE length in logical blocks. + uint8_t max_cmp_write_len; - /// Optimal transfer length granularity in logical blocks. - uint16_t optimal_granularity_xfer_len; + /// Optimal transfer length granularity in logical blocks. + uint16_t optimal_granularity_xfer_len; - /// Maximum transfer length in logical blocks. - uint32_t max_xfer_len; + /// Maximum transfer length in logical blocks. + uint32_t max_xfer_len; - /// Optimal transfer length in logical blocks. - uint32_t optimal_xfer_len; + /// Optimal transfer length in logical blocks. + uint32_t optimal_xfer_len; - /// Maximum prefetch length in logical blocks. - uint32_t max_prefetch_len; + /// Maximum prefetch length in logical blocks. + uint32_t max_prefetch_len; - /// Maximum UNMAP LBA count in LBAs. - uint32_t max_unmap_lba_cnt; + /// Maximum UNMAP LBA count in LBAs. + uint32_t max_unmap_lba_cnt; - /// Maximum UNMAP block descriptor count in block descriptors. - uint32_t max_unmap_block_desc_cnt; + /// Maximum UNMAP block descriptor count in block descriptors. + uint32_t max_unmap_block_desc_cnt; - /// Optimal UNMAP granularity in logical blocks. - uint32_t optimal_unmap_granularity; + /// Optimal UNMAP granularity in logical blocks. + uint32_t optimal_unmap_granularity; - /// UNMAP granularity alignment (first LBA) and UGAVALID bit. - uint32_t unmap_granularity_align_ugavalid; + /// UNMAP granularity alignment (first LBA) and UGAVALID bit. + uint32_t unmap_granularity_align_ugavalid; - /// Maximum WRITE SAME length in logical blocks. - uint64_t max_write_same_len; + /// Maximum WRITE SAME length in logical blocks. + uint64_t max_write_same_len; - /// Reserved for future usage (always MUST be 0). - uint64_t reserved[2]; + /// Reserved for future usage (always MUST be 0). + uint64_t reserved[2]; - /// Reserved for future usage (always MUST be 0). - uint32_t reserved2; + /// Reserved for future usage (always MUST be 0). + uint32_t reserved2; } iscsi_scsi_vpd_page_block_limits_inquiry_data_packet; /// iSCSI SCSI Vital Product Data (VPD) Page Block Device Characteristics Inquiry data medium rotation rate: Medium rotation rate is not reported. @@ -3525,131 +2029,32 @@ typedef struct __attribute__((packed)) iscsi_scsi_vpd_page_block_limits_inquiry_ * set. */ typedef struct __attribute__((packed)) iscsi_scsi_vpd_page_block_dev_chars_inquiry_data_packet { - /// Medium rotation rate. - uint16_t medium_rotation_rate; + /// Medium rotation rate. + uint16_t medium_rotation_rate; - /// Product type. - uint8_t product_type; + /// Product type. + uint8_t product_type; - /// Flags. - int8_t flags; + /// Flags. + int8_t flags; - /// Support flags. - uint8_t support_flags; + /// Support flags. + uint8_t support_flags; - /// Reserved for future usage (always MUST be 0). - uint64_t reserved[6]; + /// Reserved for future usage (always MUST be 0). + uint64_t reserved[6]; - /// Reserved for future usage (always MUST be 0). - uint32_t reserved2; + /// Reserved for future usage (always MUST be 0). + uint32_t reserved2; - /// Reserved for future usage (always MUST be 0). - uint16_t reserved3; + /// Reserved for future usage (always MUST be 0). + uint16_t reserved3; - /// Reserved for future usage (always MUST be 0). - uint8_t reserved4; + /// Reserved for future usage (always MUST be 0). + uint8_t reserved4; } iscsi_scsi_vpd_page_block_dev_chars_inquiry_data_packet; -/// iSCSI SCSI Vital Product Data (VPD) Page Thin Provision Inquiry data flags: Descriptor Present (DP). -#define ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_FLAGS_DP (1 << 0) - -/// iSCSI SCSI Vital Product Data (VPD) Page Thin Provision Inquiry data flags: Anchor Supported (ANC_SUP). -#define ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_FLAGS_ANC_SUP (1 << 1) - -/// iSCSI SCSI Vital Product Data (VPD) Page Thin Provision Inquiry data flags: Logical Block Provisioning Read Zeros (LBPRZ). -#define ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_FLAGS_LBPRZ (1 << 2) - -/// iSCSI SCSI Vital Product Data (VPD) Page Thin Provision Inquiry data flags: Logical Block Provisioning WRITE SAME(10) (LBPWS10). -#define ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_FLAGS_LBPWS10 (1 << 5) - -/// iSCSI SCSI Vital Product Data (VPD) Page Thin Provision Inquiry data flags: Logical Block Provisioning WRITE SAME (LBPWS). -#define ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_FLAGS_LBPWS (1 << 6) - -/// iSCSI SCSI Vital Product Data (VPD) Page Thin Provision Inquiry data flags: Logical Block Provisioning UNMAP (LBPU). -#define ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_FLAGS_LBPU (1 << 7) - - -/// iSCSI SCSI Vital Product Data (VPD) Page Thin Provision Inquiry data provision type: The device server does NOT report a provisioning type. -#define ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_PROVISION_TYPE_PROVISIONING_NOT_REPORTED 0x0 - -/// iSCSI SCSI Vital Product Data (VPD) Page Thin Provision Inquiry data provision type: The logical unit is resource provisioned (see SBC3). -#define ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_PROVISION_TYPE_RESOURCE_PROVISIONING 0x1 - -/// iSCSI SCSI Vital Product Data (VPD) Page Thin Provision Inquiry data provision type: The logical unit is thin provisioned (see SBC3). -#define ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_PROVISION_TYPE_THIN_PROVISIONING 0x2 - -/// iSCSI SCSI Vital Product Data (VPD) Page Thin Provision Inquiry data provision type: First bit of the three bits. -#define ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_PROVISION_TYPE_FIRST_BIT 0 - -/// iSCSI SCSI Vital Product Data (VPD) Page Thin Provision Inquiry data provision type: Last bit of the three bits. -#define ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_PROVISION_TYPE_LAST_BIT ((ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_PROVISION_TYPE_FIRST_BIT) + 3 - 1) - -/// iSCSI SCSI Vital Product Data (VPD) Page Thin Provision Inquiry data provision type: Bit mask. -#define ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_PROVISION_TYPE_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_PROVISION_TYPE_FIRST_BIT, ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_PROVISION_TYPE_LAST_BIT)) - -/// iSCSI SCSI Vital Product Data (VPD) Page Thin Provision Inquiry data provision type: Extracts the provision type bits. -#define ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_GET_PROVISION_TYPE(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_PROVISION_TYPE_FIRST_BIT, ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_PROVISION_TYPE_LAST_BIT)) - -/// iSCSI SCSI Vital Product Data (VPD) Page Thin Provision Inquiry data provision type: Stores into the provision type bits. -#define ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_PUT_PROVISION_TYPE(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_PROVISION_TYPE_FIRST_BIT, ISCSI_SCSI_VPD_PAGE_THIN_PROVISION_INQUIRY_DATA_PROVISION_TYPE_LAST_BIT)) - - -/** - * @brief iSCSI SCSI Vital Product Data (VPD) Page Thin Provision Inquiry data packet. - * - * This structure is used by the SCSI INQUIRY command - * in order to fill in the result if the EVPD bit is - * set. - */ -typedef struct __attribute__((packed)) iscsi_scsi_vpd_page_thin_provision_inquiry_data_packet { - /// Threshold exponent. - uint8_t threshold_exponent; - - /// Flags. - int8_t flags; - - /// Provision type. - uint8_t provision_type; - - /// Reserved for future usage (always MUST be 0). - uint8_t reserved; - - /// Provision group descriptors. - uint8_t provision_group_desc[0]; -} iscsi_scsi_vpd_page_thin_provision_inquiry_data_packet; - - -/** - * @brief iSCSI SCSI Sense Event data packet. - * - * For a SCSI event, this data accompanies the report in the data - * segment and identifies the condition. - * - * For an iSCSI event, additional vendor-unique data MAY accompany the - * Async event. Initiators MAY ignore the data when not understood, - * while processing the rest of the PDU. - * - * If the DataSegmentLength is not 0, the format of the DataSegment is - * as follows: - */ -typedef struct __attribute__((packed)) iscsi_scsi_sense_event_data_packet { - /** - * @brief SenseLength. - * - * This is the length of Sense Data. When the Sense Data field is empty - * (e.g., the event is not a SCSI event), SenseLength is 0. - */ - uint16_t sense_len; - - /// Sense Data. - uint16_t sense_data[0]; - - /// iSCSI Event Data. - uint16_t event_data[0]; -} iscsi_scsi_sense_event_data_packet; - - /// iSCSI SCSI sense data response code: Current format. #define ISCSI_SCSI_SENSE_DATA_RESPONSE_CODE_CURRENT_FMT 0x70 @@ -3707,20 +2112,20 @@ typedef struct __attribute__((packed)) iscsi_scsi_sense_event_data_packet { * all SCSI sense data. */ typedef struct __attribute__((packed)) iscsi_scsi_sense_data_packet { - /// Response code. - int8_t response_code; + /// Response code. + int8_t response_code; - /// Reserved for future usage (always MUST be 0). - uint8_t reserved; + /// Reserved for future usage (always MUST be 0). + uint8_t reserved; - /// Sense key and flags. - int8_t sense_key_flags; + /// Sense key and flags. + int8_t sense_key_flags; - /// Information. - uint32_t info; + /// Information. + uint32_t info; - /// Additional sense length in bytes. - uint8_t add_len; + /// Additional sense length in bytes. + uint8_t add_len; } iscsi_scsi_sense_data_packet; /// iSCSI SCSI maximum sense data length. @@ -3753,26 +2158,26 @@ typedef struct __attribute__((packed)) iscsi_scsi_sense_data_packet { * the check condition status code. */ typedef struct __attribute__((packed)) iscsi_scsi_sense_data_check_cond_packet { - /// Basic SCSI sense data packet. - iscsi_scsi_sense_data_packet sense_data; + /// Basic SCSI sense data packet. + iscsi_scsi_sense_data_packet sense_data; - /// Information. - uint32_t cmd_spec_info; + /// Information. + uint32_t cmd_spec_info; - /// Additional Sense Code (ASC). - uint8_t asc; + /// Additional Sense Code (ASC). + uint8_t asc; - /// Additional Sense Code Qualifier (ASCQ). - uint8_t ascq; + /// Additional Sense Code Qualifier (ASCQ). + uint8_t ascq; - /// Field replaceable unit code. - uint8_t field_rep_unit_code; + /// Field replaceable unit code. + uint32_t field_rep_unit_code; - /// Sense key specific. - uint8_t sense_key_spec_flags; + /// Sense key specific. + uint8_t sense_key_spec_flags; - /// Sense key specific. - uint16_t sense_key_spec; + /// Sense key specific. + uint16_t sense_key_spec; } iscsi_scsi_sense_data_check_cond_packet; @@ -3783,11 +2188,11 @@ typedef struct __attribute__((packed)) iscsi_scsi_sense_data_check_cond_packet { * and block length in bytes. */ typedef struct __attribute__((packed)) iscsi_scsi_read_capacity_10_parameter_data_packet { - /// Last valid Logical Block Address (LBA). - uint32_t lba; + /// Last valid Logical Block Address (LBA). + uint32_t lba; - /// Block length in bytes. - uint32_t block_len; + /// Block length in bytes. + uint32_t block_len; } iscsi_scsi_read_capacity_10_parameter_data_packet; @@ -3885,23 +2290,23 @@ typedef struct __attribute__((packed)) iscsi_scsi_read_capacity_10_parameter_dat * block length in bytes and LBP information. */ typedef struct __attribute__((packed)) iscsi_scsi_service_action_in_16_parameter_data_packet { - /// Last valid Logical Block Address (LBA). - uint64_t lba; + /// Last valid Logical Block Address (LBA). + uint64_t lba; - /// Block length in bytes. - uint32_t block_len; + /// Block length in bytes. + uint32_t block_len; - /// Flags: RC_BASIS, P_TYPE and PROT_EN. - int8_t flags; + /// Flags: RC_BASIS, P_TYPE and PROT_EN. + int8_t flags; - /// P_I_EXPONENT and logical blocks per physical block exponent. - uint8_t exponents; + /// P_I_EXPONENT and logical blocks per physical block exponent. + uint8_t exponents; - /// Logical Block Provisioning Management Enabled (LBPME), Logical Block Provisioning Read Zeros (LBPRZ) and Lowest Aligned Logical Block Address (LALBA). - uint16_t lbp_lalba; + /// Logical Block Provisioning Management Enabled (LBPME), Logical Block Provisioning Read Zeros (LBPRZ) and Lowest Aligned Logical Block Address (LALBA). + uint16_t lbp_lalba; - /// Reserved for future usage (always MUST be 0 for now). - uint64_t reserved[2]; + /// Reserved for future usage (always MUST be 0 for now). + uint64_t reserved[2]; } iscsi_scsi_service_action_in_16_parameter_data_packet; @@ -3912,49 +2317,24 @@ typedef struct __attribute__((packed)) iscsi_scsi_service_action_in_16_parameter * LUN list in bytes. */ typedef struct __attribute__((packed)) iscsi_scsi_report_luns_parameter_data_lun_list_packet { - /// Number of LUN's following this packet in bytes. - uint32_t lun_list_len; + /// Number of LUN's following this packet in bytes. + uint32_t lun_list_len; - /// Reserved for future usage (always MUST be 0 for now). - uint32_t reserved; + /// Reserved for future usage (always MUST be 0 for now). + uint32_t reserved; } iscsi_scsi_report_luns_parameter_data_lun_list_packet; -/** - * @brief iSCSI SCSI command REPORT LUNS parameter data LUN entry packet data. - * - * This returns a single LUN entry of the - * LUN list. - */ -typedef struct __attribute__((packed)) iscsi_scsi_report_luns_parameter_data_lun_entry_packet { - /// Logical Unit Number (LUN). - uint64_t lun; -} iscsi_scsi_report_luns_parameter_data_lun_entry_packet; - - -/** - * @brief iSCSI SCSI command REPORT LUNS parameter data LUN entry fill. - * - * This structure is used by iterating through - * all iSCSI LUNs in order to fill in the - * REPORT LUNS parameter data structure. - */ -typedef struct iscsi_scsi_emu_primary_report_luns_fill { - /// Pointer to LUN list packet data. - iscsi_scsi_report_luns_parameter_data_lun_list_packet *lun_list; - - /// Pointer to current LUN entry packet data. - iscsi_scsi_report_luns_parameter_data_lun_entry_packet *lun_entry; - - /// Total length of LUN entry packet data in bytes. - uint32_t len; - - /// Total remaining allocation length for packet data in bytes. - uint alloc_len; - - /// Select report. - uint select_report; -} iscsi_scsi_emu_primary_report_luns_fill; +/** + * @brief iSCSI SCSI command REPORT LUNS parameter data LUN entry packet data. + * + * This returns a single LUN entry of the + * LUN list. + */ +typedef struct __attribute__((packed)) iscsi_scsi_report_luns_parameter_data_lun_entry_packet { + /// Logical Unit Number (LUN). + uint64_t lun; +} iscsi_scsi_report_luns_parameter_data_lun_entry_packet; /** @@ -3963,8 +2343,8 @@ typedef struct iscsi_scsi_emu_primary_report_luns_fill { * This returns 32-bit vendor specific data. */ typedef struct __attribute__((packed)) iscsi_scsi_mode_select_6_parameter_list_packet { - /// Vendor specific data. - uint32_t vendor_data; + /// Vendor specific data. + uint32_t vendor_data; } iscsi_scsi_mode_select_6_parameter_list_packet; @@ -3974,8 +2354,8 @@ typedef struct __attribute__((packed)) iscsi_scsi_mode_select_6_parameter_list_p * This returns 64-bit vendor specific data. */ typedef struct __attribute__((packed)) iscsi_scsi_mode_select_10_parameter_list_packet { - /// Vendor specific data. - uint64_t vendor_data; + /// Vendor specific data. + uint64_t vendor_data; } iscsi_scsi_mode_select_10_parameter_list_packet; @@ -3993,17 +2373,17 @@ typedef struct __attribute__((packed)) iscsi_scsi_mode_select_10_parameter_list_ * data. */ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_6_parameter_header_data_packet { - /// Mode data length in bytes. - uint8_t mode_data_len; + /// Mode data length in bytes. + uint8_t mode_data_len; - /// Medium type. - uint8_t medium_type; + /// Medium type. + uint8_t medium_type; - /// Flags. - int8_t flags; + /// Flags. + int8_t flags; - /// Block descriptor length in bytes. - uint8_t block_desc_len; + /// Block descriptor length in bytes. + uint8_t block_desc_len; } iscsi_scsi_mode_sense_6_parameter_header_data_packet; @@ -4025,23 +2405,23 @@ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_6_parameter_header_ * data. */ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_10_parameter_header_data_packet { - /// Mode data length in bytes. - uint16_t mode_data_len; + /// Mode data length in bytes. + uint16_t mode_data_len; - /// Medium type. - uint8_t medium_type; + /// Medium type. + uint8_t medium_type; - /// Flags. - int8_t flags; + /// Flags. + int8_t flags; - /// Long Logical Block Address (LONGLBA). - uint8_t long_lba; + /// Long Logical Block Address (LONGLBA). + uint8_t long_lba; - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved; + /// Reserved for future usage (always MUST be 0 for now). + uint8_t reserved; - /// Block descriptor length in bytes. - uint16_t block_desc_len; + /// Block descriptor length in bytes. + uint16_t block_desc_len; } iscsi_scsi_mode_sense_10_parameter_header_data_packet; @@ -4053,14 +2433,14 @@ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_10_parameter_header * descriptor data. */ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_lba_parameter_block_desc_data_packet { - /// Number of blocks in logical blocks. - uint32_t num_blocks; + /// Number of blocks in logical blocks. + uint32_t num_blocks; - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved; + /// Reserved for future usage (always MUST be 0 for now). + uint8_t reserved; - /// Logical blcok length in bytes. - uint8_t block_len[3]; + /// Logical blcok length in bytes. + uint8_t block_len[3]; } iscsi_scsi_mode_sense_lba_parameter_block_desc_data_packet; @@ -4072,14 +2452,14 @@ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_lba_parameter_block * descriptor data. */ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_long_lba_parameter_block_desc_data_packet { - /// Number of blocks in logical blocks. - uint64_t num_blocks; + /// Number of blocks in logical blocks. + uint64_t num_blocks; - /// Reserved for future usage (always MUST be 0 for now). - uint32_t reserved; + /// Reserved for future usage (always MUST be 0 for now). + uint32_t reserved; - /// Logical blcok length in bytes. - uint32_t block_len; + /// Logical blcok length in bytes. + uint32_t block_len; } iscsi_scsi_mode_sense_long_lba_parameter_block_desc_data_packet; @@ -4318,14 +2698,14 @@ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_long_lba_parameter_ * This returns mode page specific data. */ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_mode_page_data_packet { - /// Page code and flags. - int8_t page_code_flags; + /// Page code and flags. + int8_t page_code_flags; - /// Page length in bytes. - uint8_t page_len; + /// Page length in bytes. + uint8_t page_len; - /// Mode parameters. - uint8_t params[0]; + /// Mode parameters. + uint8_t params[0]; } iscsi_scsi_mode_sense_mode_page_data_packet; @@ -4335,17 +2715,17 @@ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_mode_page_data_pack * This returns mode sub page specific data. */ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_mode_sub_page_data_packet { - /// Page code and flags. - int8_t page_code_flags; + /// Page code and flags. + int8_t page_code_flags; - /// Sub page code. - uint8_t sub_page_code; + /// Sub page code. + uint8_t sub_page_code; - /// Page length in bytes. - uint16_t page_len; + /// Page length in bytes. + uint16_t page_len; - /// Mode parameters. - uint8_t params[0]; + /// Mode parameters. + uint8_t params[0]; } iscsi_scsi_mode_sense_mode_sub_page_data_packet; @@ -4355,29 +2735,29 @@ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_mode_sub_page_data_ * This returns mode page specific data. */ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_read_write_err_recovery_mode_page_data_packet { - /// Mode page. - iscsi_scsi_mode_sense_mode_page_data_packet mode_page; + /// Mode page. + iscsi_scsi_mode_sense_mode_page_data_packet mode_page; - /// Flags. - int8_t flags; + /// Flags. + int8_t flags; - /// Read retry count. - uint8_t read_retry_cnt; + /// Read retry count. + uint8_t read_retry_cnt; - /// Obselete. - uint8_t obselete[3]; + /// Obselete. + uint8_t obselete[3]; - /// Restricted for MMC-6. - uint8_t restrict_mmc_6; + /// Restricted for MMC-6. + uint8_t restrict_mmc_6; - /// Write_retry count. - uint8_t write_retry_cnt; + /// Write_retry count. + uint8_t write_retry_cnt; - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved; + /// Reserved for future usage (always MUST be 0 for now). + uint8_t reserved; - /// Recovery time limit. - uint16_t recovery_time_limit; + /// Recovery time limit. + uint16_t recovery_time_limit; } iscsi_scsi_mode_sense_read_write_err_recovery_mode_page_data_packet; @@ -4387,32 +2767,32 @@ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_read_write_err_reco * This returns mode page specific data. */ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_disconnect_reconnect_mode_page_data_packet { - /// Mode page. - iscsi_scsi_mode_sense_mode_page_data_packet mode_page; + /// Mode page. + iscsi_scsi_mode_sense_mode_page_data_packet mode_page; - /// Reserved for future usage (always MUST be 0 for now). - uint16_t reserved; + /// Reserved for future usage (always MUST be 0 for now). + uint16_t reserved; - /// Bus inactivity time limit. - uint16_t bus_inactivity_time_limit; + /// Bus inactivity time limit. + uint16_t bus_inactivity_time_limit; - /// Reserved for future usage (always MUST be 0 for now). - uint16_t reserved2; + /// Reserved for future usage (always MUST be 0 for now). + uint16_t reserved2; - /// Maximum connect time limit. - uint16_t max_connect_time_limit; + /// Maximum connect time limit. + uint16_t max_connect_time_limit; - /// Maximum burst size. - uint16_t max_burst_size; + /// Maximum burst size. + uint16_t max_burst_size; - /// Restricted. - uint8_t restricted; + /// Restricted. + uint8_t restricted; - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved3; + /// Reserved for future usage (always MUST be 0 for now). + uint8_t reserved3; - /// First burst size. - uint16_t first_burst_size; + /// First burst size. + uint16_t first_burst_size; } iscsi_scsi_mode_sense_disconnect_reconnect_mode_page_data_packet; @@ -4422,35 +2802,35 @@ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_disconnect_reconnec * This returns mode page specific data. */ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_verify_err_recovery_mode_page_data_packet { - /// Mode page. - iscsi_scsi_mode_sense_mode_page_data_packet mode_page; + /// Mode page. + iscsi_scsi_mode_sense_mode_page_data_packet mode_page; - /// Flags. - int8_t flags; + /// Flags. + int8_t flags; - /// Verify retry count. - uint8_t verify_retry_cnt; + /// Verify retry count. + uint8_t verify_retry_cnt; - /// Obselete. - uint8_t obselete; + /// Obselete. + uint8_t obselete; - /// Head offset count. - uint8_t head_offset_cnt; + /// Head offset count. + uint8_t head_offset_cnt; - /// Data strobe offset count. - uint8_t data_strobe_offset_cnt; + /// Data strobe offset count. + uint8_t data_strobe_offset_cnt; - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved; + /// Reserved for future usage (always MUST be 0 for now). + uint8_t reserved; - /// Write retry count. - uint8_t write_retry_cnt; + /// Write retry count. + uint8_t write_retry_cnt; - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved2; + /// Reserved for future usage (always MUST be 0 for now). + uint8_t reserved2; - /// Verify_recovery time limit. - uint16_t verify_recovery_time_limit; + /// Verify_recovery time limit. + uint16_t verify_recovery_time_limit; } iscsi_scsi_mode_sense_verify_err_recovery_mode_page_data_packet; @@ -4485,41 +2865,41 @@ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_verify_err_recovery * This returns mode page specific data. */ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_caching_mode_page_data_packet { - /// Mode page. - iscsi_scsi_mode_sense_mode_page_data_packet mode_page; + /// Mode page. + iscsi_scsi_mode_sense_mode_page_data_packet mode_page; - /// Flags. - int8_t flags; + /// Flags. + int8_t flags; - /// Retention priority. - uint8_t retention_pri; + /// Retention priority. + uint8_t retention_pri; - /// Disable prefetch transfer length. - uint16_t disable_prefetch_xfer_len; + /// Disable prefetch transfer length. + uint16_t disable_prefetch_xfer_len; - /// Minimum prefetch. - uint16_t min_prefetch; + /// Minimum prefetch. + uint16_t min_prefetch; - /// Maximum prefetch. - uint16_t max_prefetch; + /// Maximum prefetch. + uint16_t max_prefetch; - /// Maximum prefetch ceiling. - uint16_t max_prefetch_ceil; + /// Maximum prefetch ceiling. + uint16_t max_prefetch_ceil; - /// Cache flags. - int8_t cache_flags; + /// Cache flags. + int8_t cache_flags; - /// Number of cache segments. - uint8_t num_cache_segs; + /// Number of cache segments. + uint8_t num_cache_segs; - /// Cache segment size. - uint16_t cache_seg_size; + /// Cache segment size. + uint16_t cache_seg_size; - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved; + /// Reserved for future usage (always MUST be 0 for now). + uint8_t reserved; - /// Obselete. - uint8_t obselete[3]; + /// Obselete. + uint8_t obselete[3]; } iscsi_scsi_mode_sense_caching_mode_page_data_packet; @@ -4529,29 +2909,29 @@ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_caching_mode_page_d * This returns mode page specific data. */ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_control_mode_page_data_packet { - /// Mode page. - iscsi_scsi_mode_sense_mode_page_data_packet mode_page; + /// Mode page. + iscsi_scsi_mode_sense_mode_page_data_packet mode_page; - /// Flags. - int8_t flags; + /// Flags. + int8_t flags; - /// Queue flags. - int8_t queue_flags; + /// Queue flags. + int8_t queue_flags; - /// Control flags. - int8_t control_flags; + /// Control flags. + int8_t control_flags; - /// Application task flags. - int8_t app_task_flags; + /// Application task flags. + int8_t app_task_flags; - /// Ready AER holdoff period. - uint16_t ready_aer_holdoff_period; + /// Ready AER holdoff period. + uint16_t ready_aer_holdoff_period; - /// Busy timeout period. - uint16_t busy_timeout_period; + /// Busy timeout period. + uint16_t busy_timeout_period; - /// Extended self-test completition time. - uint16_t ext_self_test_complete_time; + /// Extended self-test completition time. + uint16_t ext_self_test_complete_time; } iscsi_scsi_mode_sense_control_mode_page_data_packet; @@ -4561,23 +2941,23 @@ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_control_mode_page_d * This returns mode sub page specific data. */ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_control_ext_mode_page_data_packet { - /// Mode page. - iscsi_scsi_mode_sense_mode_sub_page_data_packet mode_sub_page; + /// Mode page. + iscsi_scsi_mode_sense_mode_sub_page_data_packet mode_sub_page; - /// Flags. - int8_t flags; + /// Flags. + int8_t flags; - /// Initial command priority. - uint8_t init_cmd_pri; + /// Initial command priority. + uint8_t init_cmd_pri; - /// Maximum sense data length in bytes. - uint8_t max_sense_data_len; + /// Maximum sense data length in bytes. + uint8_t max_sense_data_len; - /// Reserved for future usage (always MUST be 0 for now). - uint64_t reserved[3]; + /// Reserved for future usage (always MUST be 0 for now). + uint64_t reserved[3]; - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved2; + /// Reserved for future usage (always MUST be 0 for now). + uint8_t reserved2; } iscsi_scsi_mode_sense_control_ext_mode_page_data_packet; @@ -4587,32 +2967,32 @@ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_control_ext_mode_pa * This returns mode page specific data. */ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_xor_ext_mode_page_data_packet { - /// Mode page. - iscsi_scsi_mode_sense_mode_page_data_packet mode_page; + /// Mode page. + iscsi_scsi_mode_sense_mode_page_data_packet mode_page; - /// Flags. - int8_t flags; + /// Flags. + int8_t flags; - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved; + /// Reserved for future usage (always MUST be 0 for now). + uint8_t reserved; - /// Maximum XOR write size in logical blocks. - uint32_t max_xor_write_size; + /// Maximum XOR write size in logical blocks. + uint32_t max_xor_write_size; - /// Reserved for future usage (always MUST be 0 for now). - uint32_t reserved2; + /// Reserved for future usage (always MUST be 0 for now). + uint32_t reserved2; - /// Maximum regenerate size in logical blocks. - uint32_t max_regenerate_size; + /// Maximum regenerate size in logical blocks. + uint32_t max_regenerate_size; - /// Reserved for future usage (always MUST be 0 for now). - uint32_t reserved3; + /// Reserved for future usage (always MUST be 0 for now). + uint32_t reserved3; - /// Reserved for future usage (always MUST be 0 for now). - uint16_t reserved4; + /// Reserved for future usage (always MUST be 0 for now). + uint16_t reserved4; - /// Rebuild delay. - uint16_t rebuild_delay; + /// Rebuild delay. + uint16_t rebuild_delay; } iscsi_scsi_mode_sense_xor_ext_mode_page_data_packet; @@ -4622,44 +3002,44 @@ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_xor_ext_mode_page_d * This returns mode page specific data. */ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_power_cond_mode_page_data_packet { - /// Mode page. - iscsi_scsi_mode_sense_mode_page_data_packet mode_page; + /// Mode page. + iscsi_scsi_mode_sense_mode_page_data_packet mode_page; - /// Flags. - int8_t flags; + /// Flags. + int8_t flags; - /// Idle and standby flags. - int8_t idle_standby_flags; + /// Idle and standby flags. + int8_t idle_standby_flags; - /// idle_a condition timer. - uint32_t idle_a_cond_timer; + /// idle_a condition timer. + uint32_t idle_a_cond_timer; - /// standby_z condition timer. - uint32_t standby_z_cond_timer; + /// standby_z condition timer. + uint32_t standby_z_cond_timer; - /// idle_b condition timer. - uint32_t idle_b_cond_timer; + /// idle_b condition timer. + uint32_t idle_b_cond_timer; - /// idle_c condition timer. - uint32_t idle_c_cond_timer; + /// idle_c condition timer. + uint32_t idle_c_cond_timer; - /// standby_y condition timer. - uint32_t standby_y_cond_timer; + /// standby_y condition timer. + uint32_t standby_y_cond_timer; - /// Reserved for future usage (always MUST be 0 for now). - uint64_t reserved; + /// Reserved for future usage (always MUST be 0 for now). + uint64_t reserved; - /// Reserved for future usage (always MUST be 0 for now). - uint32_t reserved2; + /// Reserved for future usage (always MUST be 0 for now). + uint32_t reserved2; - /// Reserved for future usage (always MUST be 0 for now). - uint16_t reserved3; + /// Reserved for future usage (always MUST be 0 for now). + uint16_t reserved3; - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved4; + /// Reserved for future usage (always MUST be 0 for now). + uint8_t reserved4; - /// Check Condition From (CCF) flags. - int8_t ccf_flags; + /// Check Condition From (CCF) flags. + int8_t ccf_flags; } iscsi_scsi_mode_sense_power_cond_mode_page_data_packet; @@ -4669,65 +3049,23 @@ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_power_cond_mode_pag * This returns mode page specific data. */ typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_info_exceptions_control_mode_page_data_packet { - /// Mode page. - iscsi_scsi_mode_sense_mode_page_data_packet mode_page; + /// Mode page. + iscsi_scsi_mode_sense_mode_page_data_packet mode_page; - /// Flags. - int8_t flags; + /// Flags. + int8_t flags; - /// Method Of Reporting Informational Exceptions (MRIE) flags. - uint8_t mrie; + /// Method Of Reporting Informational Exceptions (MRIE) flags. + uint8_t mrie; - /// Interval timer. - uint32_t interval_timer; + /// Interval timer. + uint32_t interval_timer; - /// Report count. - uint32_t report_cnt; + /// Report count. + uint32_t report_cnt; } iscsi_scsi_mode_sense_info_exceptions_control_mode_page_data_packet; -/** - * @brief iSCSI SCSI command PERSISTENT RESERVE OUT parameter list packet data. - * - * This returns persistent storage specific data - * like the reservation and service action keys. - */ -typedef struct __attribute__((packed)) iscsi_scsi_pr_reserve_out_parameter_list_packet { - /// Reservation key. - uint64_t r_key; - - /// Service action reservation key. - uint64_t sa_key; - - /// Obselete. - uint32_t obselete; - - /// Flags. - int8_t flags; - - /// Reserved for future usage (always MUST be 0 for now). - uint8_t reserved; - - /// Obselete. - uint16_t obselete2; - -} iscsi_scsi_pr_reserve_out_parameter_list_packet; - - -/** - * @brief iSCSI SCSI command PERSISTENT RESERVE IN parameter data packet data. - * - * This returns persistent storage specific data - * like the reservation and service action keys. - */ -typedef struct __attribute__((packed)) iscsi_scsi_pr_reserve_in_parameter_data_packet { - /// Persistent Reservations (PR) Generation. - uint32_t pr_gen; - - /// Additional length in bytes. - uint32_t add_len; -} iscsi_scsi_pr_reserve_in_parameter_data_packet; - /// SCSI command opcode (embedded in iSCSI protocol): TEST UNIT READY. #define ISCSI_SCSI_OPCODE_TESTUNITREADY 0x00 @@ -4954,86 +3292,80 @@ typedef struct __attribute__((packed)) iscsi_scsi_pr_reserve_in_parameter_data_p * direction is indicated by the R and/or W bit). */ typedef struct __attribute__((packed)) iscsi_scsi_cmd_packet { - /// Always 1 according to the iSCSI specification. - uint8_t opcode; - - /// Flags and Task Attributes. - int8_t flags_task; - - /// Reserved for future usage, MUST always be 0. - uint16_t reserved; - - /// Total length of AHS. - uint8_t total_ahs_len; - - /// Length of DataSegment. - uint8_t ds_len[3]; - - /// SCSI LUN bit mask. - uint64_t lun; - - /// Initiator Task Tag (ITT). - uint32_t init_task_tag; - - /** - * @brief Expected Data Transfer Length. - * - * For unidirectional operations, the Expected Data Transfer Length - * field contains the number of bytes of data involved in this SCSI - * operation. For a unidirectional write operation (W flag set to 1 and - * R flag set to 0), the initiator uses this field to specify the number - * of bytes of data it expects to transfer for this operation. For a - * unidirectional read operation (W flag set to 0 and R flag set to 1), - * the initiator uses this field to specify the number of bytes of data - * it expects the target to transfer to the initiator. It corresponds - * to the SAM-2 byte count.\n - * For bidirectional operations (both R and W flags are set to 1), this - * field contains the number of data bytes involved in the write - * transfer. For bidirectional operations, an additional header segment - * MUST be present in the header sequence that indicates the - * Bidirectional Read Expected Data Transfer Length. The Expected Data - * Transfer Length field and the Bidirectional Read Expected Data - * Transfer Length field correspond to the SAM-2 byte count. - * If the Expected Data Transfer Length for a write and the length of - * the immediate data part that follows the command (if any) are the - * same, then no more data PDUs are expected to follow. In this case, - * the F bit MUST be set to 1.\n - * If the Expected Data Transfer Length is higher than the - * FirstBurstLength (the negotiated maximum amount of unsolicited data - * the target will accept), the initiator MUST send the maximum amount - * of unsolicited data OR ONLY the immediate data, if any. - * Upon completion of a data transfer, the target informs the initiator - * (through residual counts) of how many bytes were actually processed - * (sent and/or received) by the target. - */ - uint32_t exp_xfer_len; - - /// The CmdSN enables ordered delivery across multiple connections in a single session. - uint32_t cmd_sn; - - /// Command responses up to ExpStatSN - 1 (modulo 2**32) have been received (acknowledges status) on the connection. - uint32_t exp_stat_sn; - - /** - * @brief SCSI Command Descriptor Block (CDB). - * - * There are 16 bytes in the CDB field to accommodate the commonly used - * CDBs. Whenever the CDB is larger than 16 bytes, an Extended CDB AHS - * MUST be used to contain the CDB spillover. - */ - iscsi_scsi_cdb scsi_cdb; - - /// Optional AHS packet data. - iscsi_ahs_packet ahs; - - /// Optional header digest. - iscsi_header_digest hdr_digest; - - /// Optional data segment, command data. - iscsi_scsi_ds_cmd_data ds_cmd_data; - - /// Optional data digest. - iscsi_data_digest data_digest; + /// Always 1 according to the iSCSI specification. + uint8_t opcode; + + /// Flags and Task Attributes. + int8_t flags_task; + + /// Reserved for future usage, MUST always be 0. + uint16_t reserved; + + /// Total length of AHS. + uint8_t total_ahs_len; + + /// Length of DataSegment. + uint8_t ds_len[3]; + + /// SCSI LUN bit mask. + uint64_t lun; + + /// Initiator Task Tag (ITT). + uint32_t init_task_tag; + + /** + * @brief Expected Data Transfer Length. + * + * For unidirectional operations, the Expected Data Transfer Length + * field contains the number of bytes of data involved in this SCSI + * operation. For a unidirectional write operation (W flag set to 1 and + * R flag set to 0), the initiator uses this field to specify the number + * of bytes of data it expects to transfer for this operation. For a + * unidirectional read operation (W flag set to 0 and R flag set to 1), + * the initiator uses this field to specify the number of bytes of data + * it expects the target to transfer to the initiator. It corresponds + * to the SAM-2 byte count.\n + * For bidirectional operations (both R and W flags are set to 1), this + * field contains the number of data bytes involved in the write + * transfer. For bidirectional operations, an additional header segment + * MUST be present in the header sequence that indicates the + * Bidirectional Read Expected Data Transfer Length. The Expected Data + * Transfer Length field and the Bidirectional Read Expected Data + * Transfer Length field correspond to the SAM-2 byte count. + * If the Expected Data Transfer Length for a write and the length of + * the immediate data part that follows the command (if any) are the + * same, then no more data PDUs are expected to follow. In this case, + * the F bit MUST be set to 1.\n + * If the Expected Data Transfer Length is higher than the + * FirstBurstLength (the negotiated maximum amount of unsolicited data + * the target will accept), the initiator MUST send the maximum amount + * of unsolicited data OR ONLY the immediate data, if any. + * Upon completion of a data transfer, the target informs the initiator + * (through residual counts) of how many bytes were actually processed + * (sent and/or received) by the target. + */ + uint32_t exp_xfer_len; + + /// The CmdSN enables ordered delivery across multiple connections in a single session. + uint32_t cmd_sn; + + /// Command responses up to ExpStatSN - 1 (modulo 2**32) have been received (acknowledges status) on the connection. + uint32_t exp_stat_sn; + + /** + * @brief SCSI Command Descriptor Block (CDB). + * + * There are 16 bytes in the CDB field to accommodate the commonly used + * CDBs. Whenever the CDB is larger than 16 bytes, an Extended CDB AHS + * MUST be used to contain the CDB spillover. + */ + iscsi_scsi_cdb scsi_cdb; + + /// Optional AHS packet data. + iscsi_ahs_packet ahs; + + /// Optional data segment, command data. + iscsi_scsi_ds_cmd_data ds_cmd_data; } iscsi_scsi_cmd_packet; @@ -5234,496 +3566,132 @@ typedef struct __attribute__((packed)) iscsi_scsi_cmd_packet { * terms, response value 0x00 maps to the SCSI service response (see */ typedef struct __attribute__((packed)) iscsi_scsi_response_packet { - /// Always 0x21 according to specification. - uint8_t opcode; - - /// Flags. - int8_t flags; - - /// This field contains the iSCSI service response. - uint8_t response; - - /// The Status field is used to report the SCSI status of the command (as specified in SAM2) and is only valid if the response code is Command Completed at Target. - uint8_t status; - - /// Total AHS length. - uint8_t total_ahs_len; - - /// Data segment length. - uint8_t ds_len[3]; - - /// Reserved for future usage. Always MUST be 0. - uint64_t reserved; - - /// Initiator Task Tag (ITT). - uint32_t init_task_tag; - - /** - * @brief Copy of the last accepted Selective Negative / Sequence Number Acknowledgment (SNACK) tag. - * - * This field contains a copy of the SNACK Tag of the last SNACK Tag - * accepted by the target on the same connection and for the command for - * which the response is issued. Otherwise, it is reserved and should - * be set to 0.\n - * After issuing a R-Data SNACK, the initiator must discard any SCSI - * status unless contained in a SCSI Response PDU carrying the same - * SNACK Tag as the last issued R-Data SNACK for the SCSI command on the - * current connection. - */ - uint32_t snack_tag; - - /** - * @brief StatSN - Status Sequence Number. - * - * The StatSN is a sequence number that the target iSCSI layer generates - * per connection and that in turn enables the initiator to acknowledge - * status reception. The StatSN is incremented by 1 for every - * response/status sent on a connection, except for responses sent as a - * result of a retry or SNACK. In the case of responses sent due to a - * retransmission request, the StatSN MUST be the same as the first time - * the PDU was sent, unless the connection has since been restarted. - */ - uint32_t stat_sn; - - /** - * @brief ExpCmdSN - Next Expected CmdSN from This Initiator. - * - * The ExpCmdSN is a sequence number that the target iSCSI returns to - * the initiator to acknowledge command reception. It is used to update - * a local variable with the same name. An ExpCmdSN equal to - * MaxCmdSN + 1 indicates that the target cannot accept new commands. - */ - uint32_t exp_cmd_sn; - - /** - * @brief MaxCmdSN - Maximum CmdSN from This Initiator. - * - * The MaxCmdSN is a sequence number that the target iSCSI returns to - * the initiator to indicate the maximum CmdSN the initiator can send. - * It is used to update a local variable with the same name. If the - * MaxCmdSN is equal to ExpCmdSN - 1, this indicates to the initiator - * that the target cannot receive any additional commands. When the - * MaxCmdSN changes at the target while the target has no pending PDUs - * to convey this information to the initiator, it MUST generate a - * NOP-In to carry the new MaxCmdSN. - */ - uint32_t max_cmd_sn; - - /** - * @brief ExpDataSN or Reserved. - * - * This field indicates the number of Data-In (read) PDUs the target has - * sent for the command.\n - * This field MUST be 0 if the response code is not Command Completed at - * Target or the target sent no Data-In PDUs for the command. - */ - uint32_t exp_data_sn; - - /** - * @brief Bidirectional Read Residual Count or Reserved. - * - * The Bidirectional Read Residual Count field MUST be valid in the case - * where either the u bit or the o bit is set. If neither bit is set, - * the Bidirectional Read Residual Count field is reserved. Targets may - * set the Bidirectional Read Residual Count, and initiators may use it - * when the response code is Command Completed at Target. If the o bit - * is set, the Bidirectional Read Residual Count indicates the number of - * bytes that were not transferred to the initiator because the - * initiator's Bidirectional Read Expected Data Transfer Length was not - * sufficient. If the u bit is set, the Bidirectional Read Residual - * Count indicates the number of bytes that were not transferred to the - * initiator out of the number of bytes expected to be transferred. - */ - uint32_t bidi_read_res_cnt; - - /** - * @brief Residual Count or Reserved. - * - * The Residual Count field MUST be valid in the case where either the U - * bit or the O bit is set. If neither bit is set, the Residual Count - * field MUST be ignored on reception and SHOULD be set to 0 when - * sending. Targets may set the residual count, and initiators may use - * it when the response code is Command Completed at Target (even if the - * status returned is not GOOD). If the O bit is set, the Residual - * Count indicates the number of bytes that were not transferred because - * the initiator's Expected Data Transfer Length was not sufficient. If - * the U bit is set, the Residual Count indicates the number of bytes - * that were not transferred out of the number of bytes expected to be - * transferred. - */ - uint32_t res_cnt; - - /// Optional header digest. - iscsi_header_digest hdr_digest; - - /// Optional data segment, command data. - iscsi_scsi_ds_cmd_data ds_cmd_data; - - /// Optional data digest. - iscsi_data_digest data_digest; + /// Always 0x21 according to specification. + uint8_t opcode; + + /// Flags. + int8_t flags; + + /// This field contains the iSCSI service response. + uint8_t response; + + /// The Status field is used to report the SCSI status of the command (as specified in SAM2) and is only valid if the response code is Command Completed at Target. + uint8_t status; + + /// Total AHS length. + uint8_t total_ahs_len; + + /// Data segment length. + uint8_t ds_len[3]; + + /// Reserved for future usage. Always MUST be 0. + uint64_t reserved; + + /// Initiator Task Tag (ITT). + uint32_t init_task_tag; + + /** + * @brief Copy of the last accepted Selective Negative / Sequence Number Acknowledgment (SNACK) tag. + * + * This field contains a copy of the SNACK Tag of the last SNACK Tag + * accepted by the target on the same connection and for the command for + * which the response is issued. Otherwise, it is reserved and should + * be set to 0.\n + * After issuing a R-Data SNACK, the initiator must discard any SCSI + * status unless contained in a SCSI Response PDU carrying the same + * SNACK Tag as the last issued R-Data SNACK for the SCSI command on the + * current connection. + */ + uint32_t snack_tag; + + /** + * @brief StatSN - Status Sequence Number. + * + * The StatSN is a sequence number that the target iSCSI layer generates + * per connection and that in turn enables the initiator to acknowledge + * status reception. The StatSN is incremented by 1 for every + * response/status sent on a connection, except for responses sent as a + * result of a retry or SNACK. In the case of responses sent due to a + * retransmission request, the StatSN MUST be the same as the first time + * the PDU was sent, unless the connection has since been restarted. + */ + uint32_t stat_sn; + + /** + * @brief ExpCmdSN - Next Expected CmdSN from This Initiator. + * + * The ExpCmdSN is a sequence number that the target iSCSI returns to + * the initiator to acknowledge command reception. It is used to update + * a local variable with the same name. An ExpCmdSN equal to + * MaxCmdSN + 1 indicates that the target cannot accept new commands. + */ + uint32_t exp_cmd_sn; + + /** + * @brief MaxCmdSN - Maximum CmdSN from This Initiator. + * + * The MaxCmdSN is a sequence number that the target iSCSI returns to + * the initiator to indicate the maximum CmdSN the initiator can send. + * It is used to update a local variable with the same name. If the + * MaxCmdSN is equal to ExpCmdSN - 1, this indicates to the initiator + * that the target cannot receive any additional commands. When the + * MaxCmdSN changes at the target while the target has no pending PDUs + * to convey this information to the initiator, it MUST generate a + * NOP-In to carry the new MaxCmdSN. + */ + uint32_t max_cmd_sn; + + /** + * @brief ExpDataSN or Reserved. + * + * This field indicates the number of Data-In (read) PDUs the target has + * sent for the command.\n + * This field MUST be 0 if the response code is not Command Completed at + * Target or the target sent no Data-In PDUs for the command. + */ + uint32_t exp_data_sn; + + /** + * @brief Bidirectional Read Residual Count or Reserved. + * + * The Bidirectional Read Residual Count field MUST be valid in the case + * where either the u bit or the o bit is set. If neither bit is set, + * the Bidirectional Read Residual Count field is reserved. Targets may + * set the Bidirectional Read Residual Count, and initiators may use it + * when the response code is Command Completed at Target. If the o bit + * is set, the Bidirectional Read Residual Count indicates the number of + * bytes that were not transferred to the initiator because the + * initiator's Bidirectional Read Expected Data Transfer Length was not + * sufficient. If the u bit is set, the Bidirectional Read Residual + * Count indicates the number of bytes that were not transferred to the + * initiator out of the number of bytes expected to be transferred. + */ + uint32_t bidi_read_res_cnt; + + /** + * @brief Residual Count or Reserved. + * + * The Residual Count field MUST be valid in the case where either the U + * bit or the O bit is set. If neither bit is set, the Residual Count + * field MUST be ignored on reception and SHOULD be set to 0 when + * sending. Targets may set the residual count, and initiators may use + * it when the response code is Command Completed at Target (even if the + * status returned is not GOOD). If the O bit is set, the Residual + * Count indicates the number of bytes that were not transferred because + * the initiator's Expected Data Transfer Length was not sufficient. If + * the U bit is set, the Residual Count indicates the number of bytes + * that were not transferred out of the number of bytes expected to be + * transferred. + */ + uint32_t res_cnt; + + /// Optional data segment, command data. + iscsi_scsi_ds_cmd_data ds_cmd_data; } iscsi_scsi_response_packet; - -/// Task management request function: ABORT TASK: aborts the task identified by the Referenced Task Tag field. -#define ISCSI_TASK_MGMT_FUNC_REQ_FUNC_ABORT_TASK 0x01 - -/// Task management request function: ABORT TASK SET: aborts all tasks issued via this session on the LU. -#define ISCSI_TASK_MGMT_FUNC_REQ_FUNC_ABORT_TASK_SET 0x02 - -/// Task management request function: CLEAR ACA - clears the Auto Contingent Allegiance condition. -#define ISCSI_TASK_MGMT_FUNC_REQ_FUNC_CLEAR_ACA 0x03 - -/// Task management request function: CLEAR TASK SET - aborts all tasks in the appropriate task set as defined by the TST field in the Control mode page (see SPC3). -#define ISCSI_TASK_MGMT_FUNC_REQ_FUNC_CLEAR_TASK_SET 0x04 - -/// Task management request function: LOGICAL UNIT RESET. -#define ISCSI_TASK_MGMT_FUNC_REQ_FUNC_LOGICAL_UNIT_RESET 0x05 - -/// Task management request function: TARGET WARM RESET. -#define ISCSI_TASK_MGMT_FUNC_REQ_FUNC_TARGET_WARM_RESET 0x06 - -/// Task management request function: TARGET COLD RESET. -#define ISCSI_TASK_MGMT_FUNC_REQ_FUNC_TARGET_COLD_RESET 0x07 - -/// Task management request function: TASK REASSIGN - reassigns connection allegiance for the task identified by the Initiator Task Tag field to this connection, thus resuming the iSCSI exchanges for the task. -#define ISCSI_TASK_MGMT_FUNC_REQ_FUNC_TASK_REASSIGN 0x08 - - -/** - * @brief iSCSI Task Management Function Request packet data. - * - * This structure is used to explicity control the execution of one - * or more tasks (iSCSI and SCSI). - */ -typedef struct __attribute__((packed)) iscsi_task_mgmt_func_req_packet { - /// Always 2 according to iSCSI specification. - uint8_t opcode; - - /** - * @brief Function. - * - * The task management functions provide an initiator with a way to - * explicitly control the execution of one or more tasks (SCSI and iSCSI - * tasks). The task management function codes are listed below. For a - * more detailed description of SCSI task management, see SAM2. - */ - int8_t func; - - /// Reserved fot future usage, always MUST be 0. - uint16_t reserved; - - /// TotalAHSLength (MUST be 0 for this PDU). - uint8_t total_ahs_len; - - /// DataSegmentLength (MUST be 0 for this PDU). - uint8_t ds_len[3]; - - /** - * @brief Logical Unit Number (LUN) or Reserved. - * - * This field is required for functions that address a specific LU - * (ABORT TASK, CLEAR TASK SET, ABORT TASK SET, CLEAR ACA, LOGICAL UNIT - * RESET) and is reserved in all others - */ - uint64_t lun; - - /** - * @brief Initiator Task Tag (ITT). - * - * This is the Initiator Task Tag of the task to be aborted for the - * ABORT TASK function or reassigned for the TASK REASSIGN function. - * For all the other functions, this field MUST be set to the reserved - * value 0xFFFFFFFF. - */ - uint32_t init_task_tag; - - /// Referenced task tag or 0xFFFFFFFF. - uint32_t ref_task_tag; - - /// CmdSN. - uint32_t cmd_sn; - - /// ExpStatSN - uint32_t exp_stat_sn; - - /** - * @brief RefCmdSN or Reserved. - * - * If an ABORT TASK is issued for a task created by an immediate - * command, then the RefCmdSN MUST be that of the task management - * request itself (i.e., the CmdSN and RefCmdSN are equal).\n - * For an ABORT TASK of a task created by a non-immediate command, the - * RefCmdSN MUST be set to the CmdSN of the task identified by the - * Referenced Task Tag field. Targets must use this field when the task - * identified by the Referenced Task Tag field is not with the target. - * Otherwise, this field is reserved. - */ - uint32_t ref_cmd_sn; - - /** - * @brief ExpDataSN or Reserved. - * - * For recovery purposes, the iSCSI target and initiator maintain a data - * acknowledgment reference number - the first input DataSN number - * unacknowledged by the initiator. When issuing a new command, this - * number is set to 0. If the function is TASK REASSIGN, which - * establishes a new connection allegiance for a previously issued read - * or bidirectional command, the ExpDataSN will contain an updated data - * acknowledgment reference number or the value 0; the latter indicates - * that the data acknowledgment reference number is unchanged. The - * initiator MUST discard any data PDUs from the previous execution that - * it did not acknowledge, and the target MUST transmit all Data-In PDUs - * (if any) starting with the data acknowledgment reference number. The - * number of retransmitted PDUs may or may not be the same as the - * original transmission, depending on if there was a change in - * MaxRecvDataSegmentLength in the reassignment. The target MAY also - * send no more Data-In PDUs if all data has been acknowledged. - * The value of ExpDataSN MUST be 0 or higher than the DataSN of the - * last acknowledged Data-In PDU, but not larger than DataSN + 1 of the - * last Data-IN PDU sent by the target. Any other value MUST be ignored - * by the target. - * For other functions, this field is reserved - */ - uint32_t exp_data_sn; - - /// Reserved for future usage, always MUST be 0. - uint64_t reserved2; - - /// Optional header digest. - iscsi_header_digest hdr_digest; -} iscsi_task_mgmt_func_req_packet; - - -/// Task management function response: Function complete. -#define ISCSI_TASK_MGMT_FUNC_RESPONSE_FUNC_COMPLETE 0x00 - -/// Task management function response: Task does not exist. -#define ISCSI_TASK_MGMT_FUNC_RESPONSE_TASK_NO_EXIST 0x01 - -/// Task management function response: LUN does not exist. -#define ISCSI_TASK_MGMT_FUNC_RESPONSE_LUN_NO_EXIST 0x02 - -/// Task management function response: Task still allegiant. -#define ISCSI_TASK_MGMT_FUNC_RESPONSE_TASK_ALLEGIANT 0x03 - -/// Task management function response: Task allegiance reassignment not supported. -#define ISCSI_TASK_MGMT_FUNC_RESPONSE_TASK_UNSUPPORTED_ALLEGIANCE 0x04 - -/// Task management function response: Task management function not supported. -#define ISCSI_TASK_MGMT_FUNC_RESPONSE_TASK_UNSUPPORTED_MGMT 0x05 - -/// Task management function response: Function authorization failed. -#define ISCSI_TASK_MGMT_FUNC_RESPONSE_FUNC_AUTH_FAILED 0x06 - -/// Task management function response: Function rejected. -#define ISCSI_TASK_MGMT_FUNC_RESPONSE_FUNC_REJECTED 0xFF - - -/** - * @brief iSCSI Task Management Function Response packet data. - * - * For the functions ABORT TASK, ABORT TASK SET, CLEAR ACA, CLEAR TASK - * SET, LOGICAL UNIT RESET, TARGET COLD RESET, TARGET WARM RESET, and - * TASK REASSIGN, the target performs the requested task management - * function and sends a task management response back to the initiator. - * For TASK REASSIGN, the new connection allegiance MUST ONLY become - * effective at the target after the target issues the task management - * response. - */ -typedef struct __attribute__((packed)) iscsi_task_mgmt_func_response_packet { - /// Always 0x22 according to specification. - uint8_t opcode; - - /// Reserved for future usage (always MUST be 0x80 for now). - int8_t flags; - - /** - * @brief Function response. - * - * For the TARGET COLD RESET and TARGET WARM RESET functions, the target - * cancels all pending operations across all LUs known to the issuing - * initiator. For the TARGET COLD RESET function, the target MUST then - * close all of its TCP connections to all initiators (terminates all - * sessions).\n - * The mapping of the response code into a SCSI service response code - * value, if needed, is outside the scope of this document. However, in - * symbolic terms, Response values 0 and 1 map to the SCSI service - * response of FUNCTION COMPLETE. Response value 2 maps to the SCSI - * service response of INCORRECT LOGICAL UNIT NUMBER. All other - * Response values map to the SCSI service response of FUNCTION - * REJECTED. If a Task Management Function Response PDU does not arrive - * before the session is terminated, the SCSI service response is - * SERVICE DELIVERY OR TARGET FAILURE.\n - * The response to ABORT TASK SET and CLEAR TASK SET MUST only be issued - * by the target after all of the commands affected have been received - * by the target, the corresponding task management functions have been - * executed by the SCSI target, and the delivery of all responses - * delivered until the task management function completion has been - * confirmed (acknowledged through the ExpStatSN) by the initiator on - * all connections of this session.\n - * For the ABORT TASK function,\n - * -# if the Referenced Task Tag identifies a valid task leading to a - * successful termination, then targets must return the "Function - * complete" response. - * -# if the Referenced Task Tag does not identify an existing task - * but the CmdSN indicated by the RefCmdSN field in the Task - * Management Function Request is within the valid CmdSN window - * and less than the CmdSN of the Task Management Function Request - * itself, then targets must consider the CmdSN as received and - * return the "Function complete" response. - * -# if the Referenced Task Tag does not identify an existing task - * and the CmdSN indicated by the RefCmdSN field in the Task - * Management Function Request is outside the valid CmdSN window, - * then targets must return the "Task does not exist" response - */ - uint8_t response; - - /// Reserved for future usage, always MUST be 0. - uint8_t reserved; - - /// TotalAHSLength (MUST be 0 for this PDU). - uint8_t total_ahs_len; - - /// DataSegmentLength (MUST be 0 for this PDU). - uint8_t ds_len[3]; - - /// Reserved for future usage, always MUST be 0. - uint64_t reserved2; - - /// Initiator Task Tag (ITT). - uint32_t init_task_tag; - - /// Reserved for future usage, always MUST be 0. - uint32_t reserved3; - - /// StatSN. - uint32_t stat_sn; - - /// ExpCmdSN. - uint32_t exp_cmd_sn; - - /// MaxCmdSN. - uint32_t max_cmd_sn; - - /// Reserved for future usage, always MUST be 0. - uint32_t reserved4; - - /// Reserved for future usage, always MUST be 0. - uint64_t reserved5; - - /// Optional header digest. - iscsi_header_digest hdr_digest; -} iscsi_task_mgmt_func_response_packet; - /// SCSI data out / in flags: Immediately process transfer. #define ISCSI_SCSI_DATA_OUT_DATA_IN_FLAGS_IMMEDIATE (1 << 7) -/** - * @brief iSCSI SCSI Data Out request packet data. - * - * THis structure is used by iSCSI for SCSI data output - * requests, i.e. write operations. - */ -typedef struct __attribute__((packed)) iscsi_scsi_data_out_req_packet { - /// Always 2 according to iSCSI specification. - uint8_t opcode; - - /// Flags. - int8_t flags; - - /// Reserved for future usage, always MUST be 0. - uint16_t reserved; - - /// TotalAHSLength. - uint8_t total_ahs_len; - - /** - * @brief DataSegmentLength. - * - * This is the data payload length of a SCSI Data-In or SCSI Data-Out - * PDU. The sending of 0-length data segments should be avoided, but - * initiators and targets MUST be able to properly receive 0-length data - * segments.\n - * The data segments of Data-In and Data-Out PDUs SHOULD be filled to - * the integer number of 4-byte words (real payload), unless the F bit - * is set to 1. - */ - uint8_t ds_len[3]; - - /** - * @brief Logical Unit Number (LUN) or Reserved. - * - * If the Target Transfer Tag is provided, then the LUN field MUST hold a - * valid value and be consistent with whatever was specified with the command; - * otherwise, the LUN field is reserved. - */ - uint64_t lun; - - /// Initiator Task Tag (ITT). - uint32_t init_task_tag; - - /** - * @brief Target Transfer Tag or 0xFFFFFFFF. - * - * On outgoing data, the Target Transfer Tag is provided to the target - * if the transfer is honoring an R2T. In this case, the Target - * Transfer Tag field is a replica of the Target Transfer Tag provided - * with the R2T.\n - * The Target Transfer Tag values are not specified by this protocol, - * except that the value 0xFFFFFFFF is reserved and means that the - * Target Transfer Tag is not supplied. - */ - uint32_t target_xfer_tag; - - /// Reserved for future usage, always MUST be 0. - uint32_t reserved2; - - /// ExpStatSN. - uint32_t exp_stat_sn; - - /// Reserved for future usage, always MUST be 0. - uint32_t reserved3; - - /** - * @brief DataSN. - * - * For output (write) data PDUs, the DataSN is the Data-Out PDU number - * within the current output sequence. Either the current output - * sequence is identified by the Initiator Task Tag (for unsolicited - * data) or it is a data sequence generated for one R2T (for data - * solicited through R2T). - */ - uint32_t data_sn; - - /** - * @brief Buffer Offset. - * - * The Buffer Offset field contains the offset of this PDU payload data - * within the complete data transfer. The sum of the buffer offset and - * length should not exceed the expected transfer length for the - * command.\n - * The order of data PDUs within a sequence is determined by - * DataPDUInOrder. When set to Yes, it means that PDUs have to be in - * increasing buffer offset order and overlays are forbidden.\n - * The ordering between sequences is determined by DataSequenceInOrder. - * When set to Yes, it means that sequences have to be in increasing - * buffer offset order and overlays are forbidden. - */ - uint32_t buf_offset; - - /// Reserved for future usage, always MUST be 0. - uint32_t reserved4; - - /// Optional header digest. - iscsi_header_digest hdr_digest; - - /// Data segment. - iscsi_scsi_ds_cmd_data ds_cmd_data; - - /// Optional data digest. - iscsi_data_digest data_digest; -} iscsi_scsi_data_out_req_packet; - /** * @brief SCSI Data In reponse flags: Status. * @@ -5822,436 +3790,114 @@ typedef struct __attribute__((packed)) iscsi_scsi_data_out_req_packet { * responses, i.e. read operations. */ typedef struct __attribute__((packed)) iscsi_scsi_data_in_response_packet { - /// Always 0x25 according to iSCSI specification. - uint8_t opcode; - - /// Incoming data flags. The fields StatSN, Status, and Residual Count only have meaningful content if the S bit is set to 1. - int8_t flags; - - /// Rserved for future usage, always MUST be 0. - uint8_t reserved; - - /** - * @brief Status or Reserved. - * - * Status can accompany the last Data-In PDU if the command did not end - * with an exception (i.e., the status is "good status" - GOOD, - * CONDITION MET, or INTERMEDIATE-CONDITION MET). The presence of - * status (and of a residual count) is signaled via the S flag bit. - * Although targets MAY choose to send even non-exception status in - * separate responses, initiators MUST support non-exception status in - * Data-In PDUs. - */ - uint8_t status; - - /// TotalAHSLength. - uint8_t total_ahs_len; - - /** - * @brief DataSegmentLength. - * - * This is the data payload length of a SCSI Data-In or SCSI Data-Out - * PDU. The sending of 0-length data segments should be avoided, but - * initiators and targets MUST be able to properly receive 0-length data - * segments.\n - * The data segments of Data-In and Data-Out PDUs SHOULD be filled to - * the integer number of 4-byte words (real payload), unless the F bit - * is set to 1. - */ - uint8_t ds_len[3]; - - /** - * @brief Logical Unit Number (LUN) or Reserved. - * - * If the Target Transfer Tag is provided, then the LUN field MUST hold a - * valid value and be consistent with whatever was specified with the command; - * otherwise, the LUN field is reserved. - */ - uint64_t lun; - - /// Initiator Task Tag (ITT). - uint32_t init_task_tag; - - /** - * @brief Target Transfer Tag or 0xFFFFFFFF. - * - * On incoming data, the Target Transfer Tag and LUN MUST be provided by - * the target if the A bit is set to 1; otherwise, they are reserved. - * The Target Transfer Tag and LUN are copied by the initiator into the - * SNACK of type DataACK that it issues as a result of receiving a SCSI - * Data-In PDU with the A bit set to 1.\n - * The Target Transfer Tag values are not specified by this protocol, - * except that the value 0xFFFFFFFF is reserved and means that the - * Target Transfer Tag is not supplied. - */ - uint32_t target_xfer_tag; - - /// StatSN. - uint32_t stat_sn; - - /// ExpCmdSN. - - uint32_t exp_cmd_sn; - - /// MaxCmdSN. - uint32_t max_cmd_sn; - - /** - * @brief DataSN. - * - * For input (read) or bidirectional Data-In PDUs, the DataSN is the - * input PDU number within the data transfer for the command identified - * by the Initiator Task Tag.\n - * R2T and Data-In PDUs, in the context of bidirectional commands, share - * the numbering sequence. - */ - uint32_t data_sn; - - /** - * @brief Buffer Offset. - * - * The Buffer Offset field contains the offset of this PDU payload data - * within the complete data transfer. The sum of the buffer offset and - * length should not exceed the expected transfer length for the - * command.\n - * The order of data PDUs within a sequence is determined by - * DataPDUInOrder. When set to Yes, it means that PDUs have to be in - * increasing buffer offset order and overlays are forbidden.\n - * The ordering between sequences is determined by DataSequenceInOrder. - * When set to Yes, it means that sequences have to be in increasing - * buffer offset order and overlays are forbidden. - */ - uint32_t buf_offset; - - /// Residual Count or Reserved. - uint32_t res_cnt; - - /// Optional header digest. - iscsi_header_digest hdr_digest; - - /// Data segment. - iscsi_scsi_ds_cmd_data ds_cmd_data; - - /// Optional data digest. - iscsi_data_digest data_digest; + /// Always 0x25 according to iSCSI specification. + uint8_t opcode; + + /// Incoming data flags. The fields StatSN, Status, and Residual Count only have meaningful content if the S bit is set to 1. + int8_t flags; + + /// Rserved for future usage, always MUST be 0. + uint8_t reserved; + + /** + * @brief Status or Reserved. + * + * Status can accompany the last Data-In PDU if the command did not end + * with an exception (i.e., the status is "good status" - GOOD, + * CONDITION MET, or INTERMEDIATE-CONDITION MET). The presence of + * status (and of a residual count) is signaled via the S flag bit. + * Although targets MAY choose to send even non-exception status in + * separate responses, initiators MUST support non-exception status in + * Data-In PDUs. + */ + uint8_t status; + + /// TotalAHSLength. + uint8_t total_ahs_len; + + /** + * @brief DataSegmentLength. + * + * This is the data payload length of a SCSI Data-In or SCSI Data-Out + * PDU. The sending of 0-length data segments should be avoided, but + * initiators and targets MUST be able to properly receive 0-length data + * segments.\n + * The data segments of Data-In and Data-Out PDUs SHOULD be filled to + * the integer number of 4-byte words (real payload), unless the F bit + * is set to 1. + */ + uint8_t ds_len[3]; + + /** + * @brief Logical Unit Number (LUN) or Reserved. + * + * If the Target Transfer Tag is provided, then the LUN field MUST hold a + * valid value and be consistent with whatever was specified with the command; + * otherwise, the LUN field is reserved. + */ + uint64_t lun; + + /// Initiator Task Tag (ITT). + uint32_t init_task_tag; + + /** + * @brief Target Transfer Tag or 0xFFFFFFFF. + * + * On incoming data, the Target Transfer Tag and LUN MUST be provided by + * the target if the A bit is set to 1; otherwise, they are reserved. + * The Target Transfer Tag and LUN are copied by the initiator into the + * SNACK of type DataACK that it issues as a result of receiving a SCSI + * Data-In PDU with the A bit set to 1.\n + * The Target Transfer Tag values are not specified by this protocol, + * except that the value 0xFFFFFFFF is reserved and means that the + * Target Transfer Tag is not supplied. + */ + uint32_t target_xfer_tag; + + /// StatSN. + uint32_t stat_sn; + + /// ExpCmdSN. + + uint32_t exp_cmd_sn; + + /// MaxCmdSN. + uint32_t max_cmd_sn; + + /** + * @brief DataSN. + * + * For input (read) or bidirectional Data-In PDUs, the DataSN is the + * input PDU number within the data transfer for the command identified + * by the Initiator Task Tag.\n + * R2T and Data-In PDUs, in the context of bidirectional commands, share + * the numbering sequence. + */ + uint32_t data_sn; + + /** + * @brief Buffer Offset. + * + * The Buffer Offset field contains the offset of this PDU payload data + * within the complete data transfer. The sum of the buffer offset and + * length should not exceed the expected transfer length for the + * command.\n + * The order of data PDUs within a sequence is determined by + * DataPDUInOrder. When set to Yes, it means that PDUs have to be in + * increasing buffer offset order and overlays are forbidden.\n + * The ordering between sequences is determined by DataSequenceInOrder. + * When set to Yes, it means that sequences have to be in increasing + * buffer offset order and overlays are forbidden. + */ + uint32_t buf_offset; + + /// Residual Count or Reserved. + uint32_t res_cnt; + + /// Data segment. + iscsi_scsi_ds_cmd_data ds_cmd_data; } iscsi_scsi_data_in_response_packet; -/** - * @brief iSCSI Ready To Transfer packet data. - * - * When an initiator has submitted a SCSI command with data that passes - * from the initiator to the target (write), the target may specify - * which blocks of data it is ready to receive. The target may request - * that the data blocks be delivered in whichever order is convenient - * for the target at that particular instant. This information is - * passed from the target to the initiator in the Ready To Transfer - * (R2T) PDU. - * - * In order to allow write operations without an explicit initial R2T, - * the initiator and target MUST have negotiated the key InitialR2T to - * No during login. - * - * An R2T MAY be answered with one or more SCSI Data-Out PDUs with a - * matching Target Transfer Tag. If an R2T is answered with a single - * Data-Out PDU, the buffer offset in the data PDU MUST be the same as - * the one specified by the R2T, and the data length of the data PDU - * MUST be the same as the Desired Data Transfer Length specified in the - * R2T. If the R2T is answered with a sequence of data PDUs, the buffer - * offset and length MUST be within the range of those specified by the - * R2T, and the last PDU MUST have the F bit set to 1. If the last PDU - * (marked with the F bit) is received before the Desired Data Transfer - * Length is transferred, a target MAY choose to reject that PDU with - * the "Protocol Error" reason code. DataPDUInOrder governs the - * Data-Out PDU ordering. If DataPDUInOrder is set to Yes, the buffer - * offsets and lengths for consecutive PDUs MUST form a continuous - * non-overlapping range, and the PDUs MUST be sent in increasing offset - * order. - * - * The target may send several R2T PDUs. It therefore can have a number - * of pending data transfers. The number of outstanding R2T PDUs is - * limited by the value of the negotiated key MaxOutstandingR2T. Within - * a task, outstanding R2Ts MUST be fulfilled by the initiator in the - * order in which they were received. - * - * R2T PDUs MAY also be used to recover Data-Out PDUs. Such an R2T - * (Recovery-R2T) is generated by a target upon detecting the loss of - * one or more Data-Out PDUs due to: - * - * - Digest error - * - * - Sequence error - * - * - Sequence reception timeout - * - * A Recovery-R2T carries the next unused R2TSN but requests part of or - * the entire data burst that an earlier R2T (with a lower R2TSN) had - * already requested. - * - * DataSequenceInOrder governs the buffer offset ordering in consecutive - * R2Ts. If DataSequenceInOrder is Yes, then consecutive R2Ts MUST - * refer to continuous non-overlapping ranges, except for Recovery-R2Ts. - */ -typedef struct __attribute__((packed)) iscsi_r2t_packet { - /// Always 0x31 according to iSCSI specification. - uint8_t opcode; - - /// Reserved for future usage (always MUST be 0x80 for now). - int8_t flags; - - /// Reserved for future usage, always MUST be 0 for now. - uint16_t reserved; - - /// TotalAHSLength, MUST be 0 for this PDU. - uint8_t total_ahs_len; - - /// DataSegmentLength, MUST be 0 0 for this PDU. - uint8_t ds_len[3]; - - /// Logical Unit Number (LUN) or Reserved. - uint64_t lun; - - /// Initiator Task Tag (ITT). - uint32_t init_task_tag; - - /// Target Transfer Tag (TTT). - uint32_t target_xfer_tag; - - /// The StatSN field will contain the next StatSN. The StatSN for this connection is not advanced after this PDU is sent. - uint32_t stat_sn; - - /// ExpCmdSN. - uint32_t exp_cmd_sn; - - /// MaxCmdSN. - uint32_t max_cmd_sn; - - /// DataSN. - uint32_t data_sn; - - /// Ready To Transfer Sequence Number (R2TSN) is the R2T PDU input PDU number within the command identified by the Initiator Task Tag. For bidirectional commands, R2T and Data-In PDUs share the input PDU numbering sequence. - uint32_t r2t_sn; - - /** - * @brief Buffer Offset. - * - * The target therefore also specifies a buffer offset that indicates - * the point at which the data transfer should begin, relative to the - * beginning of the total data transfer. - */ - uint32_t buf_offset; - - /** - * @brief Desired Data Transfer Length. - * - * The target specifies how many bytes it wants the initiator to send - * because of this R2T PDU. The target may request the data from the - * initiator in several chunks, not necessarily in the original order of - * the data. The Desired Data Transfer Length MUST NOT be 0 and MUST NOT - * exceed MaxBurstLength. - */ - uint32_t des_data_xfer_len; - - /// Optional header digest. - iscsi_header_digest hdr_digest; -} iscsi_r2t_packet; - - -/** - * @brief SCSI Asynchronous Message Event: SCSI Async Event. - * - * A SCSI asynchronous event is reported in the sense data. - * Sense Data that accompanies the report, in the data - * segment, identifies the condition. The sending of a - * SCSI event ("asynchronous event reporting" in SCSI - * terminology) is dependent on the target support for SCSI - * asynchronous event reporting as indicated in the - * standard INQUIRY data. Its use may be enabled by - * parameters in the SCSI Control mode page. - */ -#define ISCSI_ASYNC_MSG_EVENT_SCSI_ASYNC_EVENT 0x00 - -/** - * @brief SCSI Asynchronous Message Event: Logout Request. - * - * The target requests Logout. This Async Message MUST - * be sent on the same connection as the one requesting - * to be logged out. The initiator MUST honor this request - * by issuing a Logout as early as possible but no later - * than Parameter3 seconds. The initiator MUST send a Logout - * with a reason code of "close the connection" OR "close the - * session" to close all the connections. Once this message is - * received, the initiator SHOULD NOT issue new iSCSI commands on - * the connection to be logged out. The target MAY reject any - * new I/O requests that it receives after this message with the - * reason code "Waiting for Logout". If the initiator does not - * log out in Parameter3 seconds, the target should send an Async - * PDU with iSCSI event code "Dropped the connection" if possible - * or simply terminate the transport connection. Parameter1 and - * Parameter2 are reserved. - */ -#define ISCSI_ASYNC_MSG_EVENT_LOGOUT_REQUEST 0x01 - -/** - * @brief SCSI Asynchronous Message Event: Connection Drop Notification. - * - * The target indicates that it will drop the connection. - * The Parameter1 field indicates the CID of the connection that - * is going to be dropped.\n - * The Parameter2 field (Time2Wait) indicates, in seconds, the - * minimum time to wait before attempting to reconnect or - * reassign.\n - * The Parameter3 field (Time2Retain) indicates the maximum time - * allowed to reassign commands after the initial wait (in - * Parameter2).\n - * If the initiator does not attempt to reconnect and/or reassign - * the outstanding commands within the time specified by - * Parameter3, or if Parameter3 is 0, the target will terminate - * all outstanding commands on this connection. In this case, no - * other responses should be expected from the target for the - * outstanding commands on this connection.\n - * A value of 0 for Parameter2 indicates that reconnect can be - * attempted immediately. - */ -#define ISCSI_ASYNC_MSG_EVENT_CONNECT_DROP_NOTIFY 0x02 - -/** - * @brief SCSI Asynchronous Message Event: Session Drop Notification. - * - * The target indicates that it will drop all the connections - * of this session.\n - * The Parameter1 field is reserved.\n - * The Parameter2 field (Time2Wait) indicates, in seconds, the - * minimum time to wait before attempting to reconnect.\n - * The Parameter3 field (Time2Retain) indicates the maximum time - * allowed to reassign commands after the initial wait (in - * Parameter2).\n - * If the initiator does not attempt to reconnect and/or reassign - * the outstanding commands within the time specified by - * Parameter3, or if Parameter3 is 0, the session is terminated.\n - * In this case, the target will terminate all outstanding - * commands in this session; no other responses should be - * expected from the target for the outstanding commands in this - * session. A value of 0 for Parameter2 indicates that reconnect - * can be attempted immediately. - */ -#define ISCSI_ASYNC_MSG_EVENT_SESSION_DROP_NOTIFY 0x03 - -/** - * @brief SCSI Asynchronous Message Event: Negotiation Request. - * - * The target requests parameter negotiation on this connection. - * The initiator MUST honor this request by issuing a Text - * Request (that can be empty) on the same connection as early - * as possible, but no later than Parameter3 seconds, unless a - * Text Request is already pending on the connection, or by - * issuing a Logout Request. If the initiator does not issue a - * Text Request, the target may reissue the Asynchronous Message - * requesting parameter negotiation. - */ -#define ISCSI_ASYNC_MSG_EVENT_NEGOTIATION_REQUEST 0x04 - -/** - * @brief SCSI Asynchronous Message Event: Task Termination. - * - * All active tasks for a LU with a matching LUN field in the - * Async Message PDU are being terminated. The receiving - * initiator iSCSI layer MUST respond to this message by - * taking the following steps, in order: - * - Stop Data-Out transfers on that connection for all active - * TTTs for the affected LUN quoted in the Async Message PDU. - * - Acknowledge the StatSN of the Async Message PDU via a - * NOP-Out PDU with ITT=0xFFFFFFFF (i.e., non-ping flavor), - * while copying the LUN field from the Async Message to - * NOP-Out. - * This value of AsyncEvent, however, MUST NOT be used on an - * iSCSI session unless the new TaskReporting text key was - * negotiated to FastAbort on the session. - */ -#define ISCSI_ASYNC_MSG_EVENT_TASK_TERMINATION 0x05 - -/// SCSI Asynchronous Message Event: First vendor-specific iSCSI event. The AsyncVCode details the vendor code, and data MAY accompany the report. -#define ISCSI_ASYNC_MSG_EVENT_VENDOR_FIRST 0xF8 - -/// SCSI Asynchronous Message Event: Last vendor-specific iSCSI event. The AsyncVCode details the vendor code, and data MAY accompany the report. -#define ISCSI_ASYNC_MSG_EVENT_VENDOR_LAST 0xFF - -/** - * @brief iSCSI Asynchronous Message packet data. - * - * An Asynchronous Message may be sent from the target to the initiator - * without corresponding to a particular command. The target specifies - * the reason for the event and sense data.\n - * Some Asynchronous Messages are strictly related to iSCSI, while - * others are related to SCSI - */ -typedef struct __attribute__((packed)) iscsi_async_msg_packet { - /// Always 0x32 according to iSCSI specification. - uint8_t opcode; - - /// Reserved for future usage (always MUST be 0x80 for now). - int8_t flags; - - /// Reserved for future usage, always MUST be 0. - uint16_t reserved; - - /// TotalAHSLength, MUST be 0 for this PDU. - uint8_t total_ahs_len; - - /// DataSegmentLength, MUST be 0 0 for this PDU. - uint8_t ds_len[3]; - - /// The LUN field MUST be valid if AsyncEvent is 0. Otherwise, this field is reserved. - uint64_t lun; - - /// Tag (always 0xFFFFFFFF for now). - uint32_t tag; - - /// Reserved for future usage, always MUST be 0. - uint32_t reserved2; - - /** - * @brief StatSN. - * - * The StatSN counts this PDU as an acknowledgeable event (the StatSN is - * advanced), which allows for initiator and target state synchronization. - */ - uint32_t stat_sn; - - /// ExpCmdSN. - uint32_t exp_cmd_sn; - - /// MaxCmdSN. - uint32_t max_cmd_sn; - - /// AsyncEvent. - uint8_t async_event; - - /// AsyncVCode is a vendor-specific detail code that is only valid if the AsyncEvent field indicates a vendor-specific event. Otherwise, it is reserved. - uint8_t async_vcode; - - /// Parameter1 or Reserved. - uint16_t param_1; - - /// Parameter2 or Reserved. - uint16_t param_2; - - /// Parameter3 or Reserved. - uint16_t param_3; - - /// Reserved for future usage, always MUST be 0. - uint32_t reserved3; - - /// Optional header digest. - iscsi_header_digest hdr_digest; - - /// Data segment. - iscsi_scsi_ds_cmd_data ds_cmd_data; - - /// Optional data digest. - iscsi_data_digest data_digest; -} iscsi_async_msg_packet; - - /** * @brief Text Request flags: Continue. * @@ -6287,106 +3933,100 @@ typedef struct __attribute__((packed)) iscsi_async_msg_packet { * implicitly terminated by the target. */ typedef struct __attribute__((packed)) iscsi_text_req_packet { - /// Always 0x04 according to iSCSI specification. - uint8_t opcode; - - /// Text request flags. - int8_t flags; - - /// Reserved for future usage, always MUST be 0. - uint16_t reserved; - - /// TotalAHSLength. - uint8_t total_ahs_len; - - /// DataSegmentLength. - uint8_t ds_len[3]; - - /// Logical Unit Number (LUN) or Reserved. - uint64_t lun; - - /** - * @brief Initiator Task Tag (ITT). - * - * This is the initiator-assigned identifier for this Text Request. If - * the command is sent as part of a sequence of Text Requests and - * responses, the Initiator Task Tag MUST be the same for all the - * requests within the sequence (similar to linked SCSI commands). The - * I bit for all requests in a sequence also MUST be the same. - */ - uint32_t init_task_tag; - - /** - * @brief Target Transfer Tag (TTT). - * - * When the Target Transfer Tag is set to the reserved value 0xFFFFFFFF, - * it tells the target that this is a new request, and the target resets - * any internal state associated with the Initiator Task Tag (resets the - * current negotiation state).\n - * The target sets the Target Transfer Tag in a Text Response to a value - * other than the reserved value 0xFFFFFFFF whenever it indicates that - * it has more data to send or more operations to perform that are - * associated with the specified Initiator Task Tag. It MUST do so - * whenever it sets the F bit to 0 in the response. By copying the - * Target Transfer Tag from the response to the next Text Request, the - * initiator tells the target to continue the operation for the specific - * Initiator Task Tag. The initiator MUST ignore the Target Transfer - * Tag in the Text Response when the F bit is set to 1.\n - * This mechanism allows the initiator and target to transfer a large - * amount of textual data over a sequence of text-command/text-response - * exchanges or to perform extended negotiation sequences.\n - * If the Target Transfer Tag is not 0xFFFFFFFF, the LUN field MUST be - * sent by the target in the Text Response.\n - * A target MAY reset its internal negotiation state if an exchange is - * stalled by the initiator for a long time or if it is running out of - * resources.\n - * Long Text Responses are handled as shown in the following example:\n - * @verbatim - * I->T Text SendTargets=All (F = 1, TTT = 0xFFFFFFFF) - * T->I Text (F = 0, TTT = 0x12345678) - * I->T Text (F = 1, TTT = 0x12345678) - * T->I Text (F = 0, TTT = 0x12345678) - * I->T Text (F = 1, TTT = 0x12345678) - * ... - * T->I Text (F = 1, TTT = 0xFFFFFFFF) - * @endverbatim - */ - uint32_t target_xfer_tag; - - /// CmdSN. - uint32_t cmd_sn; - - /// ExpStatSN. - uint32_t exp_stat_sn; - - /// Reserved for future usage, always MUST be 0. - uint64_t reserved2[2]; - - /// Optional header digest. - iscsi_header_digest hdr_digest; - - /** - * @brief Data segment. - * - * The data lengths of a Text Request MUST NOT exceed the iSCSI target - * MaxRecvDataSegmentLength (a parameter that is negotiated per - * connection and per direction).\n - * A key=value pair can span Text Request or Text Response boundaries. - * A key=value pair can start in one PDU and continue on the next. In - * other words, the end of a PDU does not necessarily signal the end of - * a key=value pair.\n - * The target responds by sending its response back to the initiator. - * The response text format is similar to the request text format. The - * Text Response MAY refer to key=value pairs presented in an earlier - * Text Request, and the text in the request may refer to earlier - * responses.\n - * Text operations are usually meant for parameter setting/negotiations - * but can also be used to perform some long-lasting operations. - */ - iscsi_scsi_ds_cmd_data ds_cmd_data; - - /// Optional data digest. - iscsi_data_digest data_digest; + /// Always 0x04 according to iSCSI specification. + uint8_t opcode; + + /// Text request flags. + int8_t flags; + + /// Reserved for future usage, always MUST be 0. + uint16_t reserved; + + /// TotalAHSLength. + uint8_t total_ahs_len; + + /// DataSegmentLength. + uint8_t ds_len[3]; + + /// Logical Unit Number (LUN) or Reserved. + uint64_t lun; + + /** + * @brief Initiator Task Tag (ITT). + * + * This is the initiator-assigned identifier for this Text Request. If + * the command is sent as part of a sequence of Text Requests and + * responses, the Initiator Task Tag MUST be the same for all the + * requests within the sequence (similar to linked SCSI commands). The + * I bit for all requests in a sequence also MUST be the same. + */ + uint32_t init_task_tag; + + /** + * @brief Target Transfer Tag (TTT). + * + * When the Target Transfer Tag is set to the reserved value 0xFFFFFFFF, + * it tells the target that this is a new request, and the target resets + * any internal state associated with the Initiator Task Tag (resets the + * current negotiation state).\n + * The target sets the Target Transfer Tag in a Text Response to a value + * other than the reserved value 0xFFFFFFFF whenever it indicates that + * it has more data to send or more operations to perform that are + * associated with the specified Initiator Task Tag. It MUST do so + * whenever it sets the F bit to 0 in the response. By copying the + * Target Transfer Tag from the response to the next Text Request, the + * initiator tells the target to continue the operation for the specific + * Initiator Task Tag. The initiator MUST ignore the Target Transfer + * Tag in the Text Response when the F bit is set to 1.\n + * This mechanism allows the initiator and target to transfer a large + * amount of textual data over a sequence of text-command/text-response + * exchanges or to perform extended negotiation sequences.\n + * If the Target Transfer Tag is not 0xFFFFFFFF, the LUN field MUST be + * sent by the target in the Text Response.\n + * A target MAY reset its internal negotiation state if an exchange is + * stalled by the initiator for a long time or if it is running out of + * resources.\n + * Long Text Responses are handled as shown in the following example:\n + * @verbatim + * I->T Text SendTargets=All (F = 1, TTT = 0xFFFFFFFF) + * T->I Text (F = 0, TTT = 0x12345678) + * I->T Text (F = 1, TTT = 0x12345678) + * T->I Text (F = 0, TTT = 0x12345678) + * I->T Text (F = 1, TTT = 0x12345678) + * ... + * T->I Text (F = 1, TTT = 0xFFFFFFFF) + * @endverbatim + */ + uint32_t target_xfer_tag; + + /// CmdSN. + uint32_t cmd_sn; + + /// ExpStatSN. + uint32_t exp_stat_sn; + + /// Reserved for future usage, always MUST be 0. + uint64_t reserved2[2]; + + /** + * @brief Data segment. + * + * The data lengths of a Text Request MUST NOT exceed the iSCSI target + * MaxRecvDataSegmentLength (a parameter that is negotiated per + * connection and per direction).\n + * A key=value pair can span Text Request or Text Response boundaries. + * A key=value pair can start in one PDU and continue on the next. In + * other words, the end of a PDU does not necessarily signal the end of + * a key=value pair.\n + * The target responds by sending its response back to the initiator. + * The response text format is similar to the request text format. The + * Text Response MAY refer to key=value pairs presented in an earlier + * Text Request, and the text in the request may refer to earlier + * responses.\n + * Text operations are usually meant for parameter setting/negotiations + * but can also be used to perform some long-lasting operations. + */ + iscsi_scsi_ds_cmd_data ds_cmd_data; } iscsi_text_req_packet; @@ -6428,87 +4068,81 @@ typedef struct __attribute__((packed)) iscsi_text_req_packet { * of the Text Request. */ typedef struct __attribute__((packed)) iscsi_text_response_packet { - /// Always 0x24 according to iSCSI specification. - uint8_t opcode; - - /// Text response flags. - int8_t flags; - - /// Reserved for future usage, always MUST be 0. - uint16_t reserved; - - /// TotalAHSLength. - uint8_t total_ahs_len; - - /// DataSegmentLength. - uint8_t ds_len[3]; - - /// Logical Unit Number (LUN) or Reserved. - uint64_t lun; - - /// The Initiator Task Tag matches the tag used in the initial Text Request. - uint32_t init_task_tag; - - /** - * @brief Target Transfer Tag (TTT). - * - * When a target has more work to do (e.g., cannot transfer all the - * remaining text data in a single Text Response or has to continue the - * negotiation) and has enough resources to proceed, it MUST set the - * Target Transfer Tag to a value other than the reserved value - * 0xFFFFFFFF. Otherwise, the Target Transfer Tag MUST be set to - * 0xFFFFFFFF.\n - * When the Target Transfer Tag is not 0xFFFFFFFF, the LUN field may be - * significant.\n - * The initiator MUST copy the Target Transfer Tag and LUN in its next - * request to indicate that it wants the rest of the data.\n - * When the target receives a Text Request with the Target Transfer Tag - * set to the reserved value 0xFFFFFFFF, it resets its internal - * information (resets state) associated with the given Initiator Task - * Tag (restarts the negotiation).\n - * When a target cannot finish the operation in a single Text Response - * and does not have enough resources to continue, it rejects the Text - * Request with the appropriate Reject code.\n - * A target may reset its internal state associated with an Initiator - * Task Tag (the current negotiation state) as expressed through the - * Target Transfer Tag if the initiator fails to continue the exchange - * for some time. The target may reject subsequent Text Requests with - * the Target Transfer Tag set to the "stale" value. - */ - uint32_t target_xfer_tag; - - /// StatSN. The target StatSN variable is advanced by each Text Response sent. - uint32_t stat_sn; - - /// ExpCmdSN. - uint32_t exp_cmd_sn; - - /// MaxCmdSN. - uint32_t max_cmd_sn; - - /// Reserved for future usage, always MUST be 0. - uint64_t reserved2[2]; - - /// Optional header digest. - iscsi_header_digest hdr_digest; - - /** - * @brief Data segment. - * - * The data lengths of a Text Response MUST NOT exceed the iSCSI - * initiator MaxRecvDataSegmentLength (a parameter that is negotiated - * per connection and per direction).\n - * The text in the Text Response Data is governed by the same rules as - * the text in the Text Request Data.\n - * Although the initiator is the requesting party and controls the - * request-response initiation and termination, the target can offer - * key=value pairs of its own as part of a sequence and not only in - * response to the initiator. - */ - iscsi_scsi_ds_cmd_data ds_cmd_data; - - /// Optional data digest. - iscsi_data_digest data_digest; + /// Always 0x24 according to iSCSI specification. + uint8_t opcode; + + /// Text response flags. + int8_t flags; + + /// Reserved for future usage, always MUST be 0. + uint16_t reserved; + + /// TotalAHSLength. + uint8_t total_ahs_len; + + /// DataSegmentLength. + uint8_t ds_len[3]; + + /// Logical Unit Number (LUN) or Reserved. + uint64_t lun; + + /// The Initiator Task Tag matches the tag used in the initial Text Request. + uint32_t init_task_tag; + + /** + * @brief Target Transfer Tag (TTT). + * + * When a target has more work to do (e.g., cannot transfer all the + * remaining text data in a single Text Response or has to continue the + * negotiation) and has enough resources to proceed, it MUST set the + * Target Transfer Tag to a value other than the reserved value + * 0xFFFFFFFF. Otherwise, the Target Transfer Tag MUST be set to + * 0xFFFFFFFF.\n + * When the Target Transfer Tag is not 0xFFFFFFFF, the LUN field may be + * significant.\n + * The initiator MUST copy the Target Transfer Tag and LUN in its next + * request to indicate that it wants the rest of the data.\n + * When the target receives a Text Request with the Target Transfer Tag + * set to the reserved value 0xFFFFFFFF, it resets its internal + * information (resets state) associated with the given Initiator Task + * Tag (restarts the negotiation).\n + * When a target cannot finish the operation in a single Text Response + * and does not have enough resources to continue, it rejects the Text + * Request with the appropriate Reject code.\n + * A target may reset its internal state associated with an Initiator + * Task Tag (the current negotiation state) as expressed through the + * Target Transfer Tag if the initiator fails to continue the exchange + * for some time. The target may reject subsequent Text Requests with + * the Target Transfer Tag set to the "stale" value. + */ + uint32_t target_xfer_tag; + + /// StatSN. The target StatSN variable is advanced by each Text Response sent. + uint32_t stat_sn; + + /// ExpCmdSN. + uint32_t exp_cmd_sn; + + /// MaxCmdSN. + uint32_t max_cmd_sn; + + /// Reserved for future usage, always MUST be 0. + uint64_t reserved2[2]; + + /** + * @brief Data segment. + * + * The data lengths of a Text Response MUST NOT exceed the iSCSI + * initiator MaxRecvDataSegmentLength (a parameter that is negotiated + * per connection and per direction).\n + * The text in the Text Response Data is governed by the same rules as + * the text in the Text Request Data.\n + * Although the initiator is the requesting party and controls the + * request-response initiation and termination, the target can offer + * key=value pairs of its own as part of a sequence and not only in + * response to the initiator. + */ + iscsi_scsi_ds_cmd_data ds_cmd_data; } iscsi_text_response_packet; @@ -6585,1735 +4219,20 @@ typedef struct __attribute__((packed)) iscsi_text_response_packet { * MUST also be persistent over power cycles, reboot, card swap, etc. */ typedef struct __attribute__((packed)) iscsi_isid { - /// Meaning depends on T bit, either 22-bit OUI or reserved. - uint8_t a; + /// Meaning depends on T bit, either 22-bit OUI or reserved. + uint8_t a; - /// Meaning depends on T bit, either 22-bit OUI, EN (IANA Enterprise Number) or random. - uint16_t b; + /// Meaning depends on T bit, either 22-bit OUI, EN (IANA Enterprise Number) or random. + uint16_t b; - /// Meaning depends on T bit, either 24-bit Qualifier, EN (IANA Enterprise Number) or random. - uint8_t c; + /// Meaning depends on T bit, either 24-bit Qualifier, EN (IANA Enterprise Number) or random. + uint8_t c; - /// Meaning depends on T bit, either 24-bit Qualifier or Qualifier. - uint16_t d; + /// Meaning depends on T bit, either 24-bit Qualifier or Qualifier. + uint16_t d; } iscsi_isid; -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Session type. - * - * @verbatim - * Use: LO, Declarative, Any-Stage - * Senders: Initiator - * Scope: SW - * SessionType= - * Default is Normal. - * @endverbatim - * The initiator indicates the type of session it wants to create. The - * target can either accept it or reject it.\n - * A Discovery session indicates to the target that the only purpose of - * this session is discovery. The only requests a target accepts in - * this type of session are a Text Request with a SendTargets key and a - * Logout Request with reason "close the session".\n - * The Discovery session implies MaxConnections = 1 and overrides both - * the default and an explicit setting. ErrorRecoveryLevel MUST be 0 - * (zero) for Discovery sessions.\n - * Depending on the type of session, a target may decide on resources to - * allocate, the security to enforce, etc., for the session. If the - * SessionType key is thus going to be offered as "Discovery", it SHOULD - * be offered in the initial Login Request by the initiator. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_SESSION_TYPE ((const uint8_t *) "SessionType\0\0\0\0") - -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Initiator name. - * - * @verbatim - * Use: IO, Declarative, Any-Stage - * Senders: Initiator - * Scope: SW - * InitiatorName= - * Examples: - * InitiatorName=iqn.1992-04.de.uni-freiburg.bwlehrpool:qcow2.5003 - * InitiatorName=iqn.2001-02.de.uni-freiburg.matrix:basty.eduroam - * InitiatorName=naa.52004567BA64678D - * @endverbatim - * The initiator of the TCP connection MUST provide this key to the - * remote endpoint at the first login of the Login Phase for every - * connection. The InitiatorName key enables the initiator to identify - * itself to the remote endpoint.\n - * The InitiatorName MUST NOT be redeclared within the Login Phase. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_INITIATOR_NAME ((const uint8_t *) "InitiatorName\0\0") - -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Target name. - * - * @verbatim - * Use: IO by initiator, FFPO by target - only as response to a - * SendTargets, Declarative, Any-Stage - * Senders: Initiator and target - * Scope: SW - * TargetName= - * Examples: - * TargetName=iqn.1993-11.de.uni-freiburg:diskarrays.sn.5003 - * TargetName=eui.020000023B040506 - * TargetName=naa.62004567BA64678D0123456789ABCDEF - * @endverbatim - * The initiator of the TCP connection MUST provide this key to the - * remote endpoint in the first Login Request if the initiator is not - * establishing a Discovery session. The iSCSI Target Name specifies - * the worldwide unique name of the target.\n - * The TargetName key may also be returned by the SendTargets Text - * Request (which is its only use when issued by a target).\n - * The TargetName MUST NOT be redeclared within the Login Phase. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_TARGET_NAME ((const uint8_t *) "TargetName\0\0\0\0\0") - -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Target address. - * - * @verbatim - * Use: ALL, Declarative, Any-Stage - * Senders: Target - * Scope: SW - * TargetAddress=domainname[:port][,portal-group-tag] - * @endverbatim - * The domainname can be specified as either a DNS host name, a dotted- - * decimal IPv4 address, or a bracketed IPv6 address as specified in - * RFC3986.\n - * If the TCP port is not specified, it is assumed to be the IANA- - * assigned default port for iSCSI.\n - * If the TargetAddress is returned as the result of a redirect status - * in a Login Response, the comma and portal-group-tag MUST be omitted. - * If the TargetAddress is returned within a SendTargets response, the - * portal-group-tag MUST be included.\n - * @verbatim - * Examples: - * TargetAddress=10.0.0.1:5003,1 - * TargetAddress=[1080:0:0:0:8:800:200C:417A],65 - * TargetAddress=[1080::8:800:200C:417A]:5003,1 - * TargetAddress=gitlab.uni-freiburg.de,443 - * @endverbatim - * The formats for the port and portal-group-tag are the same as the one - * specified in TargetPortalGroupTag. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_TARGET_ADDRESS ((const uint8_t *) "TargetAddress\0\0") - -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Initiator alias. - * - * @verbatim - * Use: ALL, Declarative, Any-Stage - * Senders: Initiator - * Scope: SW - * InitiatorAlias= - * Examples: - * InitiatorAlias=Web Server 5 - * InitiatorAlias=matrix.uni-freiburg.de - * InitiatorAlias=Matrix Server - * @endverbatim - * If an initiator has been configured with a human-readable name or - * description, it SHOULD be communicated to the target during a Login - * Request PDU. If not, the host name can be used instead. This string - * is not used as an identifier, nor is it meant to be used for - * authentication or authorization decisions. It can be displayed by - * the target's user interface in a list of initiators to which it is - * connected. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_INITIATOR_ALIAS ((const uint8_t *) "InitiatorAlias\0") - -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Target alias. - * - * @verbatim - * Use: ALL, Declarative, Any-Stage - * Senders: Target - * Scope: SW - * TargetAlias= - * Examples: - * TargetAlias=Bob-s Disk - * TargetAlias=Database Server 1 Log Disk - * TargetAlias=Web Server 3 Disk 20 - * @endverbatim - * If a target has been configured with a human-readable name or - * description, this name SHOULD be communicated to the initiator during - * a Login Response PDU if SessionType=Normal. This string is not used - * as an identifier, nor is it meant to be used for authentication or - * authorization decisions. It can be displayed by the initiator's user - * interface in a list of targets to which it is connected. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_TARGET_ALIAS ((const uint8_t *) "TargetAlias\0\0\0\0") - -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Target portal group tag. - * - * @verbatim - * Use: IO by target, Declarative, Any-Stage - * Senders: Target - * Scope: SW - * TargetPortalGroupTag=<16-bit-binary-value> - * Example: - * TargetPortalGroupTag=1 - * @endverbatim - * The TargetPortalGroupTag key is a 16-bit binary-value that uniquely - * identifies a portal group within an iSCSI target node. This key - * carries the value of the tag of the portal group that is servicing - * the Login Request. The iSCSI target returns this key to the - * initiator in the Login Response PDU to the first Login Request PDU - * that has the C bit set to 0 when TargetName is given by the - * initiator.\n - * SAM2 notes in its informative text that the TPGT value should be - * non-zero; note that this is incorrect. A zero value is allowed as a - * legal value for the TPGT. This discrepancy currently stands - * corrected in SAM4. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_TARGET_PORTAL_GROUP_TAG ((const uint8_t *) "TargetPortalGroupTag\0\0\0") - -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Authentication method. - * - * @verbatim - * Use: During Login - Security Negotiation - * Senders: Initiator and target - * Scope: connection - * AuthMethod = - * @endverbatim - * The main item of security negotiation is the authentication method - * (AuthMethod).\n - * The authentication methods that can be used (appear in the list-of- - * values) are either vendor-unique methods or those listed in the - * following table: - * Name | Description - * :--- | :--------------------------------------------------------------- - * KRB5 | Kerberos V5 - defined in RFC4120 - * SRP | Secure Remote Password - defined in RFC2945 - * CHAP | Challenge Handshake Authentication Protocol - defined in RFC1994 - * None | No authentication - * - * The AuthMethod selection is followed by an "authentication exchange" - * specific to the authentication method selected.\n - * The authentication method proposal may be made by either the - * initiator or the target. However, the initiator MUST make the first - * step specific to the selected authentication method as soon as it is - * selected. It follows that if the target makes the authentication - * method proposal, the initiator sends the first key(s) of the exchange - * together with its authentication method selection.\n - * The authentication exchange authenticates the initiator to the target - * and, optionally, the target to the initiator. Authentication is - * OPTIONAL to use but MUST be supported by the target and initiator. - * The initiator and target MUST implement CHAP. All other - * authentication methods are OPTIONAL.\n - * Private or public extension algorithms MAY also be negotiated for - * authentication methods. Whenever a private or public extension - * algorithm is part of the default offer (the offer made in the absence - * of explicit administrative action), the implementer MUST ensure that - * CHAP is listed as an alternative in the default offer and "None" is - * not part of the default offer.\n - * Extension authentication methods MUST be named using one of the - * following two formats: - * -# Z-reversed.vendor.dns_name.do_something= - * -# New public key with no name prefix constraints - * - * Authentication methods named using the Z- format are used as private - * extensions. New public keys must be registered with IANA using the - * IETF Review process RFC5226. New public extensions for - * authentication methods MUST NOT use the Z# name prefix.\n - * For all of the public or private extension authentication methods, - * the method-specific keys MUST conform to the format specified for - * standard-label.\n - * To identify the vendor for private extension authentication methods, - * we suggest using the reversed DNS-name as a prefix to the proper - * digest names.\n - * The part of digest-name following Z- MUST conform to the format for - * standard-label.\n - * Support for public or private extension authentication methods is - * OPTIONAL. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD ((const uint8_t *) "AuthMethod\0\0\0\0\0") - - -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Kerberos V5 (KRB5): KRB_AP_REQ. - * - * For KRB5 (Kerberos V5) (see RFC4120 and RFC1964), the initiator MUST use: - * @verbatim - * KRB_AP_REQ= - * @endverbatim - * where KRB_AP_REQ is the client message as defined in RFC4120. - * The default principal name assumed by an iSCSI initiator or target - * (prior to any administrative configuration action) MUST be the iSCSI - * Initiator Name or iSCSI Target Name, respectively, prefixed by the - * string "iscsi/".\n - * If the initiator authentication fails, the target MUST respond with a - * Login reject with "Authentication Failure" status. Otherwise, if the - * initiator has selected the mutual authentication option (by setting - * MUTUAL-REQUIRED in the ap-options field of the KRB_AP_REQ), the - * target MUST reply with: - * @verbatim - * KRB_AP_REP= - * @endverbatim - * where KRB_AP_REP is the server's response message as defined in - * RFC4120.\n - * If mutual authentication was selected and target authentication - * fails, the initiator MUST close the connection.\n - * KRB_AP_REQ and KRB_AP_REP are binary-values, and their binary length - * (not the length of the character string that represents them in - * encoded form) MUST NOT exceed 65536 bytes. Hex or Base64 encoding - * may be used for KRB_AP_REQ and KRB_AP_REP. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD_KRB_AP_REQ ((const uint8_t *) "KRB_AP_REQ\0\0\0\0\0") - -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Kerberos V5 (KRB5): KRB_AP_REP. - * - * For KRB5 (Kerberos V5) (see RFC4120 and RFC1964), the initiator MUST use: - * @verbatim - * KRB_AP_REQ= - * @endverbatim - * where KRB_AP_REQ is the client message as defined in RFC4120. - * The default principal name assumed by an iSCSI initiator or target - * (prior to any administrative configuration action) MUST be the iSCSI - * Initiator Name or iSCSI Target Name, respectively, prefixed by the - * string "iscsi/".\n - * If the initiator authentication fails, the target MUST respond with a - * Login reject with "Authentication Failure" status. Otherwise, if the - * initiator has selected the mutual authentication option (by setting - * MUTUAL-REQUIRED in the ap-options field of the KRB_AP_REQ), the - * target MUST reply with: - * @verbatim - * KRB_AP_REP= - * @endverbatim - * where KRB_AP_REP is the server's response message as defined in - * RFC4120.\n - * If mutual authentication was selected and target authentication - * fails, the initiator MUST close the connection.\n - * KRB_AP_REQ and KRB_AP_REP are binary-values, and their binary length - * (not the length of the character string that represents them in - * encoded form) MUST NOT exceed 65536 bytes. Hex or Base64 encoding - * may be used for KRB_AP_REQ and KRB_AP_REP. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD_KRB_AP_REP ((const uint8_t *) "KRB_AP_REP\0\0\0\0\0") - - -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Secure Remote Password (SRP): SRP_U. - * - * For SRP RFC2945, the initiator MUST use: - * @verbatim - * SRP_U= TargetAuth=Yes or TargetAuth=No - * @endverbatim - * The target MUST answer with a Login reject with the "Authorization - * Failure" status or reply with: - * @verbatim - * SRP_GROUP= SRP_s= - * @endverbatim - * where G1,G2... are proposed groups, in order of preference. - * The initiator MUST either close the connection or continue with: - * @verbatim - * SRP_A= - * SRP_GROUP= - * @endverbatim - * where G is one of G1,G2... that were proposed by the target. - * The target MUST answer with a Login reject with the "Authentication - * Failure" status or reply with: - * @verbatim - * SRP_B= - * @endverbatim - * The initiator MUST close the connection or continue with: - * @verbatim - * SRP_M= - * @endverbatim - * If the initiator authentication fails, the target MUST answer with a - * Login reject with "Authentication Failure" status. Otherwise, if the - * initiator sent TargetAuth=Yes in the first message (requiring target - * authentication), the target MUST reply with: - * @verbatim - * SRP_HM= - * @endverbatim - * If the target authentication fails, the initiator MUST close the - * connection:\n - * where U, s, A, B, M, and H(A | M | K) are defined in RFC2945 (using - * the SHA1 hash function, such as SRP-SHA1) and - * G,Gn ("Gn" stands for G1,G2...) are identifiers of SRP groups - * specified in RFC3723.\n - * G, Gn, and U are text strings; s,A,B,M, and H(A | M | K) are - * binary-values. The length of s,A,B,M and H(A | M | K) in binary form - * (not the length of the character string that represents them in - * encoded form) MUST NOT exceed 1024 bytes. Hex or Base64 encoding may - * be used for s,A,B,M and H(A | M | K).\n - * For the SRP_GROUP, all the groups specified in RFC3723 up to - * 1536 bits (i.e. SRP-768, SRP-1024, SRP-1280, SRP-1536) must be - * supported by initiators and targets. To guarantee interoperability, - * targets MUST always offer "SRP-1536" as one of the proposed groups. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD_SRP_SRP_U ((const uint8_t *) "SRP_U\0\0") - -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Secure Remote Password (SRP): SRP_GROUP. - * - * For SRP RFC2945, the initiator MUST use: - * @verbatim - * SRP_U= TargetAuth=Yes or TargetAuth=No - * @endverbatim - * The target MUST answer with a Login reject with the "Authorization - * Failure" status or reply with: - * @verbatim - * SRP_GROUP= SRP_s= - * @endverbatim - * where G1,G2... are proposed groups, in order of preference. - * The initiator MUST either close the connection or continue with: - * @verbatim - * SRP_A= - * SRP_GROUP= - * @endverbatim - * where G is one of G1,G2... that were proposed by the target. - * The target MUST answer with a Login reject with the "Authentication - * Failure" status or reply with: - * @verbatim - * SRP_B= - * @endverbatim - * The initiator MUST close the connection or continue with: - * @verbatim - * SRP_M= - * @endverbatim - * If the initiator authentication fails, the target MUST answer with a - * Login reject with "Authentication Failure" status. Otherwise, if the - * initiator sent TargetAuth=Yes in the first message (requiring target - * authentication), the target MUST reply with: - * @verbatim - * SRP_HM= - * @endverbatim - * If the target authentication fails, the initiator MUST close the - * connection:\n - * where U, s, A, B, M, and H(A | M | K) are defined in RFC2945 (using - * the SHA1 hash function, such as SRP-SHA1) and - * G,Gn ("Gn" stands for G1,G2...) are identifiers of SRP groups - * specified in RFC3723.\n - * G, Gn, and U are text strings; s,A,B,M, and H(A | M | K) are - * binary-values. The length of s,A,B,M and H(A | M | K) in binary form - * (not the length of the character string that represents them in - * encoded form) MUST NOT exceed 1024 bytes. Hex or Base64 encoding may - * be used for s,A,B,M and H(A | M | K).\n - * For the SRP_GROUP, all the groups specified in RFC3723 up to - * 1536 bits (i.e. SRP-768, SRP-1024, SRP-1280, SRP-1536) must be - * supported by initiators and targets. To guarantee interoperability, - * targets MUST always offer "SRP-1536" as one of the proposed groups. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD_SRP_SRP_GROUP ((const uint8_t *) "SRP_GROUP\0\0\0\0\0\0") - -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Secure Remote Password (SRP): SRP_A. - * - * For SRP RFC2945, the initiator MUST use: - * @verbatim - * SRP_U= TargetAuth=Yes or TargetAuth=No - * @endverbatim - * The target MUST answer with a Login reject with the "Authorization - * Failure" status or reply with: - * @verbatim - * SRP_GROUP= SRP_s= - * @endverbatim - * where G1,G2... are proposed groups, in order of preference. - * The initiator MUST either close the connection or continue with: - * @verbatim - * SRP_A= - * SRP_GROUP= - * @endverbatim - * where G is one of G1,G2... that were proposed by the target. - * The target MUST answer with a Login reject with the "Authentication - * Failure" status or reply with: - * @verbatim - * SRP_B= - * @endverbatim - * The initiator MUST close the connection or continue with: - * @verbatim - * SRP_M= - * @endverbatim - * If the initiator authentication fails, the target MUST answer with a - * Login reject with "Authentication Failure" status. Otherwise, if the - * initiator sent TargetAuth=Yes in the first message (requiring target - * authentication), the target MUST reply with: - * @verbatim - * SRP_HM= - * @endverbatim - * If the target authentication fails, the initiator MUST close the - * connection:\n - * where U, s, A, B, M, and H(A | M | K) are defined in RFC2945 (using - * the SHA1 hash function, such as SRP-SHA1) and - * G,Gn ("Gn" stands for G1,G2...) are identifiers of SRP groups - * specified in RFC3723.\n - * G, Gn, and U are text strings; s,A,B,M, and H(A | M | K) are - * binary-values. The length of s,A,B,M and H(A | M | K) in binary form - * (not the length of the character string that represents them in - * encoded form) MUST NOT exceed 1024 bytes. Hex or Base64 encoding may - * be used for s,A,B,M and H(A | M | K).\n - * For the SRP_GROUP, all the groups specified in RFC3723 up to - * 1536 bits (i.e. SRP-768, SRP-1024, SRP-1280, SRP-1536) must be - * supported by initiators and targets. To guarantee interoperability, - * targets MUST always offer "SRP-1536" as one of the proposed groups. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD_SRP_SRP_A ((const uint8_t *) "SRP_A\0\0") - -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Secure Remote Password (SRP): SRP_B. - * - * For SRP RFC2945, the initiator MUST use: - * @verbatim - * SRP_U= TargetAuth=Yes or TargetAuth=No - * @endverbatim - * The target MUST answer with a Login reject with the "Authorization - * Failure" status or reply with: - * @verbatim - * SRP_GROUP= SRP_s= - * @endverbatim - * where G1,G2... are proposed groups, in order of preference. - * The initiator MUST either close the connection or continue with: - * @verbatim - * SRP_A= - * SRP_GROUP= - * @endverbatim - * where G is one of G1,G2... that were proposed by the target. - * The target MUST answer with a Login reject with the "Authentication - * Failure" status or reply with: - * @verbatim - * SRP_B= - * @endverbatim - * The initiator MUST close the connection or continue with: - * @verbatim - * SRP_M= - * @endverbatim - * If the initiator authentication fails, the target MUST answer with a - * Login reject with "Authentication Failure" status. Otherwise, if the - * initiator sent TargetAuth=Yes in the first message (requiring target - * authentication), the target MUST reply with: - * @verbatim - * SRP_HM= - * @endverbatim - * If the target authentication fails, the initiator MUST close the - * connection:\n - * where U, s, A, B, M, and H(A | M | K) are defined in RFC2945 (using - * the SHA1 hash function, such as SRP-SHA1) and - * G,Gn ("Gn" stands for G1,G2...) are identifiers of SRP groups - * specified in RFC3723.\n - * G, Gn, and U are text strings; s,A,B,M, and H(A | M | K) are - * binary-values. The length of s,A,B,M and H(A | M | K) in binary form - * (not the length of the character string that represents them in - * encoded form) MUST NOT exceed 1024 bytes. Hex or Base64 encoding may - * be used for s,A,B,M and H(A | M | K).\n - * For the SRP_GROUP, all the groups specified in RFC3723 up to - * 1536 bits (i.e. SRP-768, SRP-1024, SRP-1280, SRP-1536) must be - * supported by initiators and targets. To guarantee interoperability, - * targets MUST always offer "SRP-1536" as one of the proposed groups. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD_SRP_SRP_B ((const uint8_t *) "SRP_B\0\0") - -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Secure Remote Password (SRP): SRP_M. - * - * For SRP RFC2945, the initiator MUST use: - * @verbatim - * SRP_U= TargetAuth=Yes or TargetAuth=No - * @endverbatim - * The target MUST answer with a Login reject with the "Authorization - * Failure" status or reply with: - * @verbatim - * SRP_GROUP= SRP_s= - * @endverbatim - * where G1,G2... are proposed groups, in order of preference. - * The initiator MUST either close the connection or continue with: - * @verbatim - * SRP_A= - * SRP_GROUP= - * @endverbatim - * where G is one of G1,G2... that were proposed by the target. - * The target MUST answer with a Login reject with the "Authentication - * Failure" status or reply with: - * @verbatim - * SRP_B= - * @endverbatim - * The initiator MUST close the connection or continue with: - * @verbatim - * SRP_M= - * @endverbatim - * If the initiator authentication fails, the target MUST answer with a - * Login reject with "Authentication Failure" status. Otherwise, if the - * initiator sent TargetAuth=Yes in the first message (requiring target - * authentication), the target MUST reply with: - * @verbatim - * SRP_HM= - * @endverbatim - * If the target authentication fails, the initiator MUST close the - * connection:\n - * where U, s, A, B, M, and H(A | M | K) are defined in RFC2945 (using - * the SHA1 hash function, such as SRP-SHA1) and - * G,Gn ("Gn" stands for G1,G2...) are identifiers of SRP groups - * specified in RFC3723.\n - * G, Gn, and U are text strings; s,A,B,M, and H(A | M | K) are - * binary-values. The length of s,A,B,M and H(A | M | K) in binary form - * (not the length of the character string that represents them in - * encoded form) MUST NOT exceed 1024 bytes. Hex or Base64 encoding may - * be used for s,A,B,M and H(A | M | K).\n - * For the SRP_GROUP, all the groups specified in RFC3723 up to - * 1536 bits (i.e. SRP-768, SRP-1024, SRP-1280, SRP-1536) must be - * supported by initiators and targets. To guarantee interoperability, - * targets MUST always offer "SRP-1536" as one of the proposed groups. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD_SRP_SRP_M ((const uint8_t *) "SRP_M\0\0") - -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Secure Remote Password (SRP): SRP_HM. - * - * For SRP RFC2945, the initiator MUST use: - * @verbatim - * SRP_U= TargetAuth=Yes or TargetAuth=No - * @endverbatim - * The target MUST answer with a Login reject with the "Authorization - * Failure" status or reply with: - * @verbatim - * SRP_GROUP= SRP_s= - * @endverbatim - * where G1,G2... are proposed groups, in order of preference. - * The initiator MUST either close the connection or continue with: - * @verbatim - * SRP_A= - * SRP_GROUP= - * @endverbatim - * where G is one of G1,G2... that were proposed by the target. - * The target MUST answer with a Login reject with the "Authentication - * Failure" status or reply with: - * @verbatim - * SRP_B= - * @endverbatim - * The initiator MUST close the connection or continue with: - * @verbatim - * SRP_M= - * @endverbatim - * If the initiator authentication fails, the target MUST answer with a - * Login reject with "Authentication Failure" status. Otherwise, if the - * initiator sent TargetAuth=Yes in the first message (requiring target - * authentication), the target MUST reply with: - * @verbatim - * SRP_HM= - * @endverbatim - * If the target authentication fails, the initiator MUST close the - * connection:\n - * where U, s, A, B, M, and H(A | M | K) are defined in RFC2945 (using - * the SHA1 hash function, such as SRP-SHA1) and - * G,Gn ("Gn" stands for G1,G2...) are identifiers of SRP groups - * specified in RFC3723.\n - * G, Gn, and U are text strings; s,A,B,M, and H(A | M | K) are - * binary-values. The length of s,A,B,M and H(A | M | K) in binary form - * (not the length of the character string that represents them in - * encoded form) MUST NOT exceed 1024 bytes. Hex or Base64 encoding may - * be used for s,A,B,M and H(A | M | K).\n - * For the SRP_GROUP, all the groups specified in RFC3723 up to - * 1536 bits (i.e. SRP-768, SRP-1024, SRP-1280, SRP-1536) must be - * supported by initiators and targets. To guarantee interoperability, - * targets MUST always offer "SRP-1536" as one of the proposed groups. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD_SRP_SRP_HM ((const uint8_t *) "SRP_HM\0") - - -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Challenge Handshake Authentication Protocol (CHAP): CHAP_A. - * - * For CHAP RFC1994, the initiator MUST use: - * @verbatim - * CHAP_A= - * @endverbatim - * where A1,A2... are proposed algorithms, in order of preference. - * The target MUST answer with a Login reject with the "Authentication - * Failure" status or reply with: - * @verbatim - * CHAP_A= - * CHAP_I= - * CHAP_C= - * @endverbatim - * where A is one of A1,A2... that were proposed by the initiator. - * The initiator MUST continue with: - * @verbatim - * CHAP_N= - * CHAP_R= - * @endverbatim - * or, if it requires target authentication, with: - * @verbatim - * CHAP_N= - * CHAP_R= - * CHAP_I= - * CHAP_C= - * @endverbatim - * If the initiator authentication fails, the target MUST answer with a - * Login reject with "Authentication Failure" status. Otherwise, if the - * initiator required target authentication, the target MUST either - * answer with a Login reject with "Authentication Failure" or reply - * with: - * @verbatim - * CHAP_N= - * CHAP_R= - * @endverbatim - * If the target authentication fails, the initiator MUST close the - * connection:\n - * where N, (A,A1,A2), I, C, and R are (correspondingly) the Name, - * Algorithm, Identifier, Challenge, and Response as defined in - * RFC1994.\n - * N is a text string; A,A1,A2, and I are numbers; C and R are - * binary-values. Their binary length (not the length of the character - * string that represents them in encoded form) MUST NOT exceed - * 1024 bytes. Hex or Base64 encoding may be used for C and R.\n - * For the Algorithm, as stated in [RFC1994], one value is required to - * be implemented: - * @verbatim - * 5 (CHAP with MD5) - * @endverbatim - * To guarantee interoperability, initiators MUST always offer it as one - * of the proposed algorithms. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD_CHAP_CHAP_A ((const uint8_t *) "CHAP_A\0") - -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Challenge Handshake Authentication Protocol (CHAP): CHAP_I. - * - * For CHAP RFC1994, the initiator MUST use: - * @verbatim - * CHAP_A= - * @endverbatim - * where A1,A2... are proposed algorithms, in order of preference. - * The target MUST answer with a Login reject with the "Authentication - * Failure" status or reply with: - * @verbatim - * CHAP_A= - * CHAP_I= - * CHAP_C= - * @endverbatim - * where A is one of A1,A2... that were proposed by the initiator. - * The initiator MUST continue with: - * @verbatim - * CHAP_N= - * CHAP_R= - * @endverbatim - * or, if it requires target authentication, with: - * @verbatim - * CHAP_N= - * CHAP_R= - * CHAP_I= - * CHAP_C= - * @endverbatim - * If the initiator authentication fails, the target MUST answer with a - * Login reject with "Authentication Failure" status. Otherwise, if the - * initiator required target authentication, the target MUST either - * answer with a Login reject with "Authentication Failure" or reply - * with: - * @verbatim - * CHAP_N= - * CHAP_R= - * @endverbatim - * If the target authentication fails, the initiator MUST close the - * connection:\n - * where N, (A,A1,A2), I, C, and R are (correspondingly) the Name, - * Algorithm, Identifier, Challenge, and Response as defined in - * RFC1994.\n - * N is a text string; A,A1,A2, and I are numbers; C and R are - * binary-values. Their binary length (not the length of the character - * string that represents them in encoded form) MUST NOT exceed - * 1024 bytes. Hex or Base64 encoding may be used for C and R.\n - * For the Algorithm, as stated in [RFC1994], one value is required to - * be implemented: - * @verbatim - * 5 (CHAP with MD5) - * @endverbatim - * To guarantee interoperability, initiators MUST always offer it as one - * of the proposed algorithms. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD_CHAP_CHAP_I ((const uint8_t *) "CHAP_I\0") - -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Challenge Handshake Authentication Protocol (CHAP): CHAP_C. - * - * For CHAP RFC1994, the initiator MUST use: - * @verbatim - * CHAP_A= - * @endverbatim - * where A1,A2... are proposed algorithms, in order of preference. - * The target MUST answer with a Login reject with the "Authentication - * Failure" status or reply with: - * @verbatim - * CHAP_A= - * CHAP_I= - * CHAP_C= - * @endverbatim - * where A is one of A1,A2... that were proposed by the initiator. - * The initiator MUST continue with: - * @verbatim - * CHAP_N= - * CHAP_R= - * @endverbatim - * or, if it requires target authentication, with: - * @verbatim - * CHAP_N= - * CHAP_R= - * CHAP_I= - * CHAP_C= - * @endverbatim - * If the initiator authentication fails, the target MUST answer with a - * Login reject with "Authentication Failure" status. Otherwise, if the - * initiator required target authentication, the target MUST either - * answer with a Login reject with "Authentication Failure" or reply - * with: - * @verbatim - * CHAP_N= - * CHAP_R= - * @endverbatim - * If the target authentication fails, the initiator MUST close the - * connection:\n - * where N, (A,A1,A2), I, C, and R are (correspondingly) the Name, - * Algorithm, Identifier, Challenge, and Response as defined in - * RFC1994.\n - * N is a text string; A,A1,A2, and I are numbers; C and R are - * binary-values. Their binary length (not the length of the character - * string that represents them in encoded form) MUST NOT exceed - * 1024 bytes. Hex or Base64 encoding may be used for C and R.\n - * For the Algorithm, as stated in [RFC1994], one value is required to - * be implemented: - * @verbatim - * 5 (CHAP with MD5) - * @endverbatim - * To guarantee interoperability, initiators MUST always offer it as one - * of the proposed algorithms. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD_CHAP_CHAP_C ((const uint8_t *) "CHAP_C\0") - -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Challenge Handshake Authentication Protocol (CHAP): CHAP_N. - * - * For CHAP RFC1994, the initiator MUST use: - * @verbatim - * CHAP_A= - * @endverbatim - * where A1,A2... are proposed algorithms, in order of preference. - * The target MUST answer with a Login reject with the "Authentication - * Failure" status or reply with: - * @verbatim - * CHAP_A= - * CHAP_I= - * CHAP_C= - * @endverbatim - * where A is one of A1,A2... that were proposed by the initiator. - * The initiator MUST continue with: - * @verbatim - * CHAP_N= - * CHAP_R= - * @endverbatim - * or, if it requires target authentication, with: - * @verbatim - * CHAP_N= - * CHAP_R= - * CHAP_I= - * CHAP_C= - * @endverbatim - * If the initiator authentication fails, the target MUST answer with a - * Login reject with "Authentication Failure" status. Otherwise, if the - * initiator required target authentication, the target MUST either - * answer with a Login reject with "Authentication Failure" or reply - * with: - * @verbatim - * CHAP_N= - * CHAP_R= - * @endverbatim - * If the target authentication fails, the initiator MUST close the - * connection:\n - * where N, (A,A1,A2), I, C, and R are (correspondingly) the Name, - * Algorithm, Identifier, Challenge, and Response as defined in - * RFC1994.\n - * N is a text string; A,A1,A2, and I are numbers; C and R are - * binary-values. Their binary length (not the length of the character - * string that represents them in encoded form) MUST NOT exceed - * 1024 bytes. Hex or Base64 encoding may be used for C and R.\n - * For the Algorithm, as stated in [RFC1994], one value is required to - * be implemented: - * @verbatim - * 5 (CHAP with MD5) - * @endverbatim - * To guarantee interoperability, initiators MUST always offer it as one - * of the proposed algorithms. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD_CHAP_CHAP_N ((const uint8_t *) "CHAP_N\0") - -/** - * @brief Key used during SecurityNegotiation stage of Login Phase: Challenge Handshake Authentication Protocol (CHAP): CHAP_R. - * - * For CHAP RFC1994, the initiator MUST use: - * @verbatim - * CHAP_A= - * @endverbatim - * where A1,A2... are proposed algorithms, in order of preference. - * The target MUST answer with a Login reject with the "Authentication - * Failure" status or reply with: - * @verbatim - * CHAP_A= - * CHAP_I= - * CHAP_C= - * @endverbatim - * where A is one of A1,A2... that were proposed by the initiator. - * The initiator MUST continue with: - * @verbatim - * CHAP_N= - * CHAP_R= - * @endverbatim - * or, if it requires target authentication, with: - * @verbatim - * CHAP_N= - * CHAP_R= - * CHAP_I= - * CHAP_C= - * @endverbatim - * If the initiator authentication fails, the target MUST answer with a - * Login reject with "Authentication Failure" status. Otherwise, if the - * initiator required target authentication, the target MUST either - * answer with a Login reject with "Authentication Failure" or reply - * with: - * @verbatim - * CHAP_N= - * CHAP_R= - * @endverbatim - * If the target authentication fails, the initiator MUST close the - * connection:\n - * where N, (A,A1,A2), I, C, and R are (correspondingly) the Name, - * Algorithm, Identifier, Challenge, and Response as defined in - * RFC1994.\n - * N is a text string; A,A1,A2, and I are numbers; C and R are - * binary-values. Their binary length (not the length of the character - * string that represents them in encoded form) MUST NOT exceed - * 1024 bytes. Hex or Base64 encoding may be used for C and R.\n - * For the Algorithm, as stated in [RFC1994], one value is required to - * be implemented: - * @verbatim - * 5 (CHAP with MD5) - * @endverbatim - * To guarantee interoperability, initiators MUST always offer it as one - * of the proposed algorithms. - */ -#define ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD_CHAP_CHAP_R ((const uint8_t *) "CHAP_R\0") - -/* Login/Text Operational Text Keys - - Some session-specific parameters MUST only be carried on the leading - connection and cannot be changed after the leading connection login - (e.g., MaxConnections - the maximum number of connections). This - holds for a single connection session with regard to connection - restart. The keys that fall into this category have the "use: LO" - (Leading Only). - - Keys that can only be used during login have the "use: IO" - (Initialize Only), while those that can be used in both the Login - Phase and Full Feature Phase have the "use: ALL". - - Keys that can only be used during the Full Feature Phase use FFPO - (Full Feature Phase Only). - - Keys marked as Any-Stage may also appear in the SecurityNegotiation - stage, while all other keys described in this section are - operational keys. - - Keys that do not require an answer are marked as Declarative. - - Key scope is indicated as session-wide (SW) or connection-only (CO). - - "Result function", wherever mentioned, states the function that can - be applied to check the validity of the responder selection. - "Minimum" means that the selected value cannot exceed the offered - value. "Maximum" means that the selected value cannot be lower than - the offered value. "AND" means that the selected value must be a - possible result of a Boolean "and" function with an arbitrary Boolean - value (e.g., if the offered value is No the selected value must be - No). "OR" means that the selected value must be a possible result of - a Boolean "or" function with an arbitrary Boolean value (e.g., if the - offered value is Yes the selected value must be Yes). -*/ - -/** - * @brief Login/Text Operational Session Text Key: Header digest. - * - * @verbatim - * Use: IO - * Senders: Initiator and target - * Scope: CO - * HeaderDigest = - * Default is None for HeaderDigest. - * @endverbatim - * Digests enable the checking of end-to-end, non-cryptographic data - * integrity beyond the integrity checks provided by the link layers and - * the covering of the whole communication path, including all elements - * that may change the network-level PDUs, such as routers, switches, - * and proxies.\n - * The following table lists cyclic integrity checksums that can be - * negotiated for the digests and MUST be implemented by every iSCSI - * initiator and target. These digest options only have error detection - * significance. - * Name | Description | Generator - * :----- | :---------- | :---------- - * CRC32C | 32-bit CRC | 0x11EDC6F41 - * None | no digest || - * - * The generator polynomial G(x) for this digest is given in hexadecimal - * notation (e.g. "0x3b" stands for 0011 1011, and the polynomial is - * x**5 + x**4 + x**3 + x + 1).\n - * When the initiator and target agree on a digest, this digest MUST be - * used for every PDU in the Full Feature Phase.\n - * Padding bytes, when present in a segment covered by a CRC, SHOULD be - * set to 0 and are included in the CRC.\n - * The CRC MUST be calculated by a method that produces the same results - * as the following process: - * - The PDU bits are considered as the coefficients of a polynomial - * M(x) of degree n - 1; bit 7 of the lowest numbered byte is - * considered the most significant bit (x**n - 1), followed by bit 6 - * of the lowest numbered byte through bit 0 of the highest numbered - * byte (x**0). - * - The most significant 32 bits are complemented. - * - The polynomial is multiplied by x**32, then divided by G(x). The - * generator polynomial produces a remainder R(x) of degree <= 31. - * - The coefficients of R(x) are formed into a 32-bit sequence. - * - The bit sequence is complemented, and the result is the CRC. - * - The CRC bits are mapped into the digest word. The x**31 - * coefficient is mapped to bit 7 of the lowest numbered byte of the - * digest, and the mapping continues with successive coefficients and - * bits so that the x**24 coefficient is mapped to bit 0 of the lowest - * numbered byte. The mapping continues further with the x**23 - * coefficient mapped to bit 7 of the next byte in the digest until - * the x**0 coefficient is mapped to bit 0 of the highest numbered - * byte of the digest. - * - Computing the CRC over any segment (data or header) extended to - * include the CRC built using the generator 0x11edc6f41 will always - * get the value 0x1c2d19ed as its final remainder (R(x)). This value - * is given here in its polynomial form (i.e., not mapped as the - * digest word). - * - * For a discussion about selection criteria for the CRC, see RFC3385.\n - * For a detailed analysis of the iSCSI polynomial, see Castagnoli93.\n - * Private or public extension algorithms MAY also be negotiated for - * digests. Whenever a private or public digest extension algorithm is - * part of the default offer (the offer made in the absence of explicit - * administrative action), the implementer MUST ensure that CRC32C is - * listed as an alternative in the default offer and "None" is not part - * of the default offer.\n - * Extension digest algorithms MUST be named using one of the following - * two formats: - * 1. Y-reversed.vendor.dns_name.do_something= - * 2. New public key with no name prefix constraints - * - * Digests named using the Y- format are used for private purposes - * (unregistered). New public keys must be registered with IANA using - * the IETF Review process (RFC5226). New public extensions for - * digests MUST NOT use the Y# name prefix.\n - * For private extension digests, to identify the vendor we suggest - * using the reversed DNS-name as a prefix to the proper digest names.\n - * The part of digest-name following Y- MUST conform to the format for - * standard-label specified.\n - * Support for public or private extension digests is OPTIONAL. - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_HEADER_DIGEST ((const uint8_t *) "HeaderDigest\0\0\0") - -/** - * @brief Login/Text Operational Session Text Key: Data digest. - * - * @verbatim - * Use: IO - * Senders: Initiator and target - * Scope: CO - * DataDigest = - * Default is None for DataDigest. - * @endverbatim - * Digests enable the checking of end-to-end, non-cryptographic data - * integrity beyond the integrity checks provided by the link layers and - * the covering of the whole communication path, including all elements - * that may change the network-level PDUs, such as routers, switches, - * and proxies.\n - * The following table lists cyclic integrity checksums that can be - * negotiated for the digests and MUST be implemented by every iSCSI - * initiator and target. These digest options only have error detection - * significance. - * Name | Description | Generator - * :----- | :---------- | :---------- - * CRC32C | 32-bit CRC | 0x11EDC6F41 - * None | no digest || - * - * The generator polynomial G(x) for this digest is given in hexadecimal - * notation (e.g. "0x3b" stands for 0011 1011, and the polynomial is - * x**5 + x**4 + x**3 + x + 1).\n - * When the initiator and target agree on a digest, this digest MUST be - * used for every PDU in the Full Feature Phase.\n - * Padding bytes, when present in a segment covered by a CRC, SHOULD be - * set to 0 and are included in the CRC.\n - * The CRC MUST be calculated by a method that produces the same results - * as the following process: - * - The PDU bits are considered as the coefficients of a polynomial - * M(x) of degree n - 1; bit 7 of the lowest numbered byte is - * considered the most significant bit (x**n - 1), followed by bit 6 - * of the lowest numbered byte through bit 0 of the highest numbered - * byte (x**0). - * - The most significant 32 bits are complemented. - * - The polynomial is multiplied by x**32, then divided by G(x). The - * generator polynomial produces a remainder R(x) of degree <= 31. - * - The coefficients of R(x) are formed into a 32-bit sequence. - * - The bit sequence is complemented, and the result is the CRC. - * - The CRC bits are mapped into the digest word. The x**31 - * coefficient is mapped to bit 7 of the lowest numbered byte of the - * digest, and the mapping continues with successive coefficients and - * bits so that the x**24 coefficient is mapped to bit 0 of the lowest - * numbered byte. The mapping continues further with the x**23 - * coefficient mapped to bit 7 of the next byte in the digest until - * the x**0 coefficient is mapped to bit 0 of the highest numbered - * byte of the digest. - * - Computing the CRC over any segment (data or header) extended to - * include the CRC built using the generator 0x11edc6f41 will always - * get the value 0x1c2d19ed as its final remainder (R(x)). This value - * is given here in its polynomial form (i.e., not mapped as the - * digest word). - * - * For a discussion about selection criteria for the CRC, see RFC3385.\n - * For a detailed analysis of the iSCSI polynomial, see Castagnoli93.\n - * Private or public extension algorithms MAY also be negotiated for - * digests. Whenever a private or public digest extension algorithm is - * part of the default offer (the offer made in the absence of explicit - * administrative action), the implementer MUST ensure that CRC32C is - * listed as an alternative in the default offer and "None" is not part - * of the default offer.\n - * Extension digest algorithms MUST be named using one of the following - * two formats: - * 1. Y-reversed.vendor.dns_name.do_something= - * 2. New public key with no name prefix constraints - * - * Digests named using the Y- format are used for private purposes - * (unregistered). New public keys must be registered with IANA using - * the IETF Review process (RFC5226). New public extensions for - * digests MUST NOT use the Y# name prefix.\n - * For private extension digests, to identify the vendor we suggest - * using the reversed DNS-name as a prefix to the proper digest names.\n - * The part of digest-name following Y- MUST conform to the format for - * standard-label specified.\n - * Support for public or private extension digests is OPTIONAL. - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_DATA_DIGEST ((const uint8_t *) "DataDigest\0\0\0\0\0") - -/** - * @brief Login/Text Operational Session Text Key: New connections. - * - * @verbatim - * Use: LO - * Senders: Initiator and target - * Scope: SW - * Irrelevant when: SessionType=Discovery - * MaxConnections= - * Default is 1. - * @endverbatim - * Result function is Minimum.\n - * The initiator and target negotiate the maximum number of connections - * requested/acceptable. - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_MAX_CONNECTIONS ((const uint8_t *) "MaxConnections\0") - -/** - * @brief Login/Text Operational Session Text Key: Send targets. - * - * @verbatim - * Use: FFPO - * Senders: Initiator - * Scope: SW - * @endverbatim - * The text in this appendix is a normative part of this document.\n - * To reduce the amount of configuration required on an initiator, iSCSI - * provides the SendTargets Text Request. The initiator uses the - * SendTargets request to get a list of targets to which it may have - * access, as well as the list of addresses (IP address and TCP port) on - * which these targets may be accessed.\n - * To make use of SendTargets, an initiator must first establish one of - * two types of sessions. If the initiator establishes the session - * using the key "SessionType=Discovery", the session is a Discovery - * session, and a target name does not need to be specified. Otherwise, - * the session is a Normal operational session. The SendTargets command - * MUST only be sent during the Full Feature Phase of a Normal or - * Discovery session.\n - * A system that contains targets MUST support Discovery sessions on - * each of its iSCSI IP address-port pairs and MUST support the - * SendTargets command on the Discovery session. In a Discovery - * session, a target MUST return all path information (IP address-port - * pairs and Target Portal Group Tags) for the targets on the target - * Network Entity that the requesting initiator is authorized to access.\n - * A target MUST support the SendTargets command on operational - * sessions; these will only return path information about the target to - * which the session is connected and do not need to return information - * about other target names that may be defined in the responding - * system.\n - * An initiator MAY make use of the SendTargets command as it sees fit.\n - * A SendTargets command consists of a single Text Request PDU. This - * PDU contains exactly one text key and value. The text key MUST be - * SendTargets. The expected response depends upon the value, as well - * as whether the session is a Discovery session or an operational - * session.\n - * The value must be one of: - * @verbatim - * All - * The initiator is requesting that information on all relevant - * targets known to the implementation be returned. This value - * MUST be supported on a Discovery session and MUST NOT be - * supported on an operational session. - * - * If an iSCSI Target Name is specified, the session should - * respond with addresses for only the named target, if possible. - * This value MUST be supported on Discovery sessions. A - * Discovery session MUST be capable of returning addresses for - * those targets that would have been returned had value=All been - * designated. - * - * The session should only respond with addresses for the target - * to which the session is logged in. This MUST be supported on - * operational sessions and MUST NOT return targets other than the - * one to which the session is logged in. - * @endverbatim - * The response to this command is a Text Response that contains a list - * of zero or more targets and, optionally, their addresses. Each - * target is returned as a target record. A target record begins with - * the TargetName text key, followed by a list of TargetAddress text - * keys, and bounded by the end of the Text Response or the next - * TargetName key, which begins a new record. No text keys other than - * TargetName and TargetAddress are permitted within a SendTargets - * response.\n - * A Discovery session MAY respond to a SendTargets request with its - * complete list of targets, or with a list of targets that is based on - * the name of the initiator logged in to the session.\n - * A SendTargets response MUST NOT contain target names if there are no - * targets for the requesting initiator to access.\n - * Each target record returned includes zero or more TargetAddress - * fields.\n - * Each target record starts with one text key of the form: - * @verbatim - * TargetName= - * @endverbatim - * followed by zero or more address keys of the form: - * @verbatim - * TargetAddress=[:], - * - * @endverbatim - * The hostname-or-ipaddress contains a domain name, IPv4 address, or - * IPv6 address (RFC4291), as specified for the TargetAddress key.\n - * A hostname-or-ipaddress duplicated in TargetAddress responses for a - * given node (the port is absent or equal) would probably indicate that - * multiple address families are in use at once (IPv6 and IPv4).\n - * Each TargetAddress belongs to a portal group, identified by its - * numeric Target Portal Group Tag. The iSCSI Target Name, together with - * this tag, constitutes the SCSI port identifier; the tag only needs to - * be unique within a given target's name list of addresses.\n - * Multiple-connection sessions can span iSCSI addresses that belong to - * the same portal group.\n - * Multiple-connection sessions cannot span iSCSI addresses that belong - * to different portal groups.\n - * If a SendTargets response reports an iSCSI address for a target, it - * SHOULD also report all other addresses in its portal group in the - * same response.\n - * A SendTargets Text Response can be longer than a single Text Response - * PDU and makes use of the long Text Responses as specified.\n - * After obtaining a list of targets from the Discovery session, an - * iSCSI initiator may initiate new sessions to log in to the discovered - * targets for full operation. The initiator MAY keep the Discovery - * session open and MAY send subsequent SendTargets commands to discover - * new targets.\n - * Examples:\n - * This example is the SendTargets response from a single target that - * has no other interface ports.\n - * The initiator sends a Text Request that contains: - * @verbatim - * SendTargets=All - * @endverbatim - * The target sends a Text Response that contains: - * @verbatim - * TargetName=iqn.1993-11.de.uni-freiburg:diskarray.sn.8675309 - * @endverbatim - * All the target had to return in this simple case was the target name.\n - * It is assumed by the initiator that the IP address and TCP port for - * this target are the same as those used on the current connection to - * the default iSCSI target.\n - * The next example has two internal iSCSI targets, each accessible via - * two different ports with different IP addresses. The following is - * the Text Response: - * @verbatim - * TargetName=iqn.1993-11.de.uni-freiburg:diskarray.sn.8675309 - * TargetAddress=10.1.0.45:5300,1 - * TargetAddress=10.1.1.45:5300,2 - * TargetName=iqn.1993-11.de.uni-freiburg:diskarray.sn.1234567 - * TargetAddress=10.1.0.45:5300,1 - * TargetAddress=10.1.1.45:5300,2 - * @endverbatim - * Both targets share both addresses; the multiple addresses are likely - * used to provide multi-path support. The initiator may connect to - * either target name on either address. Each of the addresses has its - * own Target Portal Group Tag; they do not support spanning multiple- - * connection sessions with each other. Keep in mind that the Target - * Portal Group Tags for the two named targets are independent of one - * another; portal group "1" on the first target is not necessarily the - * same as portal group "1" on the second target.\n - * In the above example, a DNS host name or an IPv6 address could have - * been returned instead of an IPv4 address.\n - * The next Text Response shows a target that supports spanning sessions - * across multiple addresses and further illustrates the use of the - * Target Portal Group Tags: - * @verbatim - * TargetName=iqn.1993-11.de.uni-freiburg:diskarray.sn.8675309 - * TargetAddress=10.1.0.45:5300,1 - * TargetAddress=10.1.1.46:5300,1 - * TargetAddress=10.1.0.47:5300,2 - * TargetAddress=10.1.1.48:5300,2 - * TargetAddress=10.1.1.49:5300,3 - * @endverbatim - * In this example, any of the target addresses can be used to reach the - * same target. A single-connection session can be established to any - * of these TCP addresses. A multiple-connection session could span - * addresses .45 and .46 or .47 and .48 but cannot span any other - * combination. A TargetAddress with its own tag (.49) cannot be - * combined with any other address within the same session.\n - * This SendTargets response does not indicate whether .49 supports - * multiple connections per session; it is communicated via the - * MaxConnections text key upon login to the target. - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_SEND_TARGETS ((const uint8_t *) "SendTargets\0\0\0\0") - -/** - * @brief Login/Text Operational Session Text Key: Initial Ready To Transfer. - * - * @verbatim - * Use: LO - * Senders: Initiator and target - * Scope: SW - * Irrelevant when: SessionType=Discovery - * InitialR2T= - * Examples: - * I->InitialR2T=No - * T->InitialR2T=No - * Default is Yes. - * @endverbatim - * Result function is OR.\n - * The InitialR2T key is used to turn off the default use of R2T for - * unidirectional operations and the output part of bidirectional - * commands, thus allowing an initiator to start sending data to a - * target as if it has received an initial R2T with Buffer - * Offset=Immediate Data Length and Desired Data Transfer - * Length=(min(FirstBurstLength, Expected Data Transfer Length) - - * Received Immediate Data Length).\n - * The default action is that R2T is required, unless both the initiator - * and the target send this key-pair attribute specifying InitialR2T=No. - * Only the first outgoing data burst (immediate data and/or separate - * PDUs) can be sent unsolicited (i.e., not requiring an explicit R2T). - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_INITIAL_R2T ((const uint8_t *) "InitialR2T\0\0\0\0\0") - -/** - * @brief Login/Text Operational Session Text Key: Immediate data. - * - * @verbatim - * Use: LO - * Senders: Initiator and target - * Scope: SW - * Irrelevant when: SessionType=Discovery - * ImmediateData= - * Default is Yes. - * @endverbatim - * Result function is AND.\n - * The initiator and target negotiate support for immediate data. To - * turn immediate data off, the initiator or target must state its - * desire to do soImmediateData can be turned on if both the - * initiator and target have ImmediateData=Yes.\n - * If ImmediateData is set to Yes and InitialR2T is set to Yes - * (default), then only immediate data are accepted in the first burst. - * If ImmediateData is set to No and InitialR2T is set to Yes, then the - * initiator MUST NOT send unsolicited data and the target MUST reject - * unsolicited data with the corresponding response code.\n - * If ImmediateData is set to No and InitialR2T is set to No, then the - * initiator MUST NOT send unsolicited immediate data but MAY send one - * unsolicited burst of Data-OUT PDUs.\n - * If ImmediateData is set to Yes and InitialR2T is set to No, then the - * initiator MAY send unsolicited immediate data and/or one unsolicited - * burst of Data-OUT PDUs.\n - * The following table is a summary of unsolicited data options: - * InitialR2T | ImmediateData | Unsolicited Data-Out PDUs | ImmediateData - * :--------- | :------------ | :------------------------ | :------------ - * | No | No | Yes | No | - * | No | Yes | Yes | Yes | - * | Yes | No | No | No | - * | Yes | Yes | No | Yes | - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_IMMEDIATE_DATA ((const uint8_t *) "ImmediateData\0\0") - -/** - * @brief Login/Text Operational Session Text Key: Maximum receive DataSegmentLength. - * - * @verbatim - * Use: ALL, Declarative - * Senders: Initiator and target - * Scope: CO - * MaxRecvDataSegmentLength= - * Default is 8192 bytes. - * @endverbatim - * The initiator or target declares the maximum data segment length in - * bytes it can receive in an iSCSI PDU.\n - * The transmitter (initiator or target) is required to send PDUs with a - * data segment that does not exceed MaxRecvDataSegmentLength of the - * receiver.\n - * A target receiver is additionally limited by MaxBurstLength for - * solicited data and FirstBurstLength for unsolicited dataAn - * initiator MUST NOT send solicited PDUs exceeding MaxBurstLength nor - * unsolicited PDUs exceeding FirstBurstLength (or FirstBurstLength- - * Immediate Data Length if immediate data were sent). - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_MAX_RECV_DS_LEN ((const uint8_t *) "MaxRecvDataSegmentLength\0\0\0\0\0\0\0") - -/** - * @brief Login/Text Operational Session Text Key: Maximum burst length. - * - * @verbatim - * Use: LO - * Senders: Initiator and target - * Scope: SW - * Irrelevant when: SessionType=Discovery - * MaxBurstLength= - * Default is 262144 (256 KB). - * @endverbatim - * Result function is Minimum.\n - * The initiator and target negotiate the maximum SCSI data payload in - * bytes in a Data-In or a solicited Data-Out iSCSI sequence. A - * sequence consists of one or more consecutive Data-In or Data-Out PDUs - * that end with a Data-In or Data-Out PDU with the F bit set to 1. - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_MAX_BURST_LEN ((const uint8_t *) "MaxBurstLength\0") - -/** - * @brief Login/Text Operational Session Text Key: First burst length. - * - * @verbatim - * Use: LO - * Senders: Initiator and target - * Scope: SW - * Irrelevant when: SessionType=Discovery - * Irrelevant when: ( InitialR2T=Yes and ImmediateData=No ) - * FirstBurstLength= - * Default is 65536 (64 KB). - * @endverbatim - * Result function is Minimum.\n - * The initiator and target negotiate the maximum amount in bytes of - * unsolicited data an iSCSI initiator may send to the target during the - * execution of a single SCSI command. This covers the immediate data - * (if any) and the sequence of unsolicited Data-Out PDUs (if any) that - * follow the command.\n - * FirstBurstLength MUST NOT exceed MaxBurstLength. - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_FIRST_BURST_LEN ((const uint8_t *) "FirstBurstLength\0\0\0\0\0\0\0") - -/** - * @brief Login/Text Operational Session Text Key: Default time to wait. - * - * @verbatim - * Use: LO - * Senders: Initiator and target - * Scope: SW - * DefaultTime2Wait= - * Default is 2. - * @endverbatim - * Result function is Maximum.\n - * The initiator and target negotiate the minimum time, in seconds, to - * wait before attempting an explicit/implicit logout or an active task - * reassignment after an unexpected connection termination or a - * connection reset.\n - * A value of 0 indicates that logout or active task reassignment can be - * attempted immediately. - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_DEFAULT_TIME_WAIT ((const uint8_t *) "DefaultTime2Wait\0\0\0\0\0\0\0") - -/** - * @brief Login/Text Operational Session Text Key: Default time to retain. - * - * @verbatim - * Use: LO - * Senders: Initiator and target - * Scope: SW - * DefaultTime2Retain= - * Default is 20. - * @endverbatim - * Result function is Minimum.\n - * The initiator and target negotiate the maximum time, in seconds, - * after an initial wait (Time2Wait), before which an active task - * reassignment is still possible after an unexpected connection - * termination or a connection reset.\n - * This value is also the session state timeout if the connection in - * question is the last LOGGED_IN connection in the session.\n - * A value of 0 indicates that connection/task state is immediately - * discarded by the target. - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_DEFAULT_TIME_RETAIN ((const uint8_t *) "DefaultTime2Retain\0\0\0\0\0") - -/** - * @brief Login/Text Operational Session Text Key: Maximum outstanding Ready To Transfer. - * - * @verbatim - * Use: LO - * Senders: Initiator and target - * Scope: SW - * MaxOutstandingR2T= - * Irrelevant when: SessionType=Discovery - * Default is 1. - * @endverbatim - * Result function is Minimum.\n - * The initiator and target negotiate the maximum number of outstanding - * R2Ts per task, excluding any implied initial R2T that might be part - * of that task. An R2T is considered outstanding until the last data - * PDU (with the F bit set to 1) is transferred or a sequence reception - * timeout is encountered for that data sequence. - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_MAX_OUTSTANDING_R2T ((const uint8_t *) "MaxOutstandingR2T\0\0\0\0\0\0") - -/** - * @brief Login/Text Operational Session Text Key: Data Protocol Data Unit (PDU) in order. - * - * @verbatim - * Use: LO - * Senders: Initiator and target - * Scope: SW - * Irrelevant when: SessionType=Discovery - * DataPDUInOrder= - * Default is Yes. - * @endverbatim - * Result function is OR.\n - * "No" is used by iSCSI to indicate that the data PDUs within sequences - * can be in any order. "Yes" is used to indicate that data PDUs within - * sequences have to be at continuously increasing addresses and - * overlays are forbidden. - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_DATA_PDU_IN_ORDER ((const uint8_t *) "DataPDUInOrder\0") - -/** - * @brief Login/Text Operational Session Text Key: Data sequence in order. - * - * @verbatim - * Use: LO - * Senders: Initiator and target - * Scope: SW - * Irrelevant when: SessionType=Discovery - * DataSequenceInOrder= - * Default is Yes. - * @endverbatim - * Result function is OR.\n - * A data sequence is a sequence of Data-In or Data-Out PDUs that end - * with a Data-In or Data-Out PDU with the F bit set to 1. A Data-Out - * sequence is sent either unsolicited or in response to an R2T.\n - * Sequences cover an offset-range.\n - * If DataSequenceInOrder is set to No, data PDU sequences may be - * transferred in any order.\n - * If DataSequenceInOrder is set to Yes, data sequences MUST be - * transferred using continuously non-decreasing sequence offsets (R2T - * buffer offset for writes, or the smallest SCSI Data-In buffer offset - * within a read data sequence).\n - * If DataSequenceInOrder is set to Yes, a target may retry at most the - * last R2T, and an initiator may at most request retransmission for the - * last read data sequence. For this reason, if ErrorRecoveryLevel is - * not 0 and DataSequenceInOrder is set to Yes, then MaxOutstandingR2T - * MUST be set to 1. - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_DATA_SEQ_IN_ORDER ((const uint8_t *) "DataSequenceInOrder\0\0\0\0") - -/** - * @brief Login/Text Operational Session Text Key: Error recovery level. - * - * @verbatim - * Use: LO - * Senders: Initiator and target - * Scope: SW - * ErrorRecoveryLevel= - * Default is 0. - * @endverbatim - * Result function is Minimum.\n - * The initiator and target negotiate the recovery level supported. - * Recovery levels represent a combination of recovery capabilities. - * Each recovery level includes all the capabilities of the lower - * recovery levels and adds some new ones to them.\n - * In the description of recovery mechanisms, certain recovery classes - * are specified. - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_ERR_RECOVERY_LEVEL ((const uint8_t *) "ErrorRecoveryLevel\0\0\0\0\0") - -/** - * @brief Login/Text Operational Session Text Key: X reversed vendor. - * - * @verbatim - * Use: ALL - * Senders: Initiator and target - * Scope: specific key dependent - * X-reversed.vendor.dns_name.do_something= - * @endverbatim - * Keys with this format are used for private extension purposes. These - * keys always start with X- if unregistered with IANA (private). New - * public keys (if registered with IANA via an IETF Review RFC5226) no - * longer have an X# name prefix requirement; implementers may propose - * any intuitive unique name.\n - * For unregistered keys, to identify the vendor we suggest using the - * reversed DNS-name as a prefix to the key-proper.\n - * The part of key-name following X- MUST conform to the format for - * key-name.\n - * Vendor-specific keys MUST ONLY be used in Normal sessions.\n - * Support for public or private extension keys is OPTIONAL. - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_PRIV_EXT_KEY_FMT ((const uint8_t *) "X-reversed.vendor\0\0\0\0\0\0") - -/** - * @brief Login/Text Operational Session Text Key: Task reporting. - * - * @verbatim - * Use: LO - * Senders: Initiator and target - * Scope: SW - * Irrelevant when: SessionType=Discovery - * TaskReporting= - * Default is RFC3720. - * @endverbatim - * This key is used to negotiate the task completion reporting semantics - * from the SCSI target. The following table describes the semantics - * that an iSCSI target MUST support for respective negotiated key - * values. Whenever this key is negotiated, at least the RFC3720 and - * ResponseFence values MUST be offered as options by the negotiation - * originator. - * Name | Description - * :-------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------ - * | RFC3720 | RFC 3720-compliant semantics. Response fencing is not guaranteed, and fast completion of multi-task aborting is not supported. - * | ResponseFence | Response Fence semantics MUST be supported in reporting task completions. - * | FastAbort | Updated fast multi-task abort semantics defined in MUST be supported. Support for the Response. Fence is implied - i.e., semantics MUST be supported as well. - * - * When TaskReporting is not negotiated to FastAbort, the - * standard multi-task abort semantics MUST be used. - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_TASK_REPORTING ((const uint8_t *) "TaskReporting\0\0") - -/** - * @brief Login/Text Operational Session Text Key: X Node architecture. - * - * @verbatim - * Use: LO, Declarative - * Senders: Initiator and target - * Scope: SW - * X#NodeArchitecture= - * Default is None. - * Examples: - * X#NodeArchitecture=ExampleOS/v1234,ExampleInc_SW_Initiator/1.05a - * X#NodeArchitecture=ExampleInc_HW_Initiator/4010,Firmware/2.0.0.5 - * X#NodeArchitecture=ExampleInc_SW_Initiator/2.1,CPU_Arch/i686 - * @endverbatim - * This document does not define the structure or content of the list of - * values.\n - * The initiator or target declares the details of its iSCSI node - * architecture to the remote endpoint. These details may include, but - * are not limited to, iSCSI vendor software, firmware, or hardware - * versions; the OS version; or hardware architecture. This key may be - * declared on a Discovery session or a Normal session.\n - * The length of the key value (total length of the list-of-values) MUST - * NOT be greater than 255 bytes.\n - * X#NodeArchitecture MUST NOT be redeclared during the Login Phase.\n - * Functional behavior of the iSCSI node (this includes the iSCSI - * protocol logic - the SCSI, iSCSI, and TCP/IP protocols) MUST NOT - * depend on the presence, absence, or content of the X#NodeArchitecture - * key. The key MUST NOT be used by iSCSI nodes for interoperability or - * for exclusion of other nodes. To ensure proper use, key values - * SHOULD be set by the node itself, and there SHOULD NOT be provisions - * for the key values to contain user-defined text.\n - * Nodes implementing this key MUST choose one of the following - * implementation options:\n - * - only transmit the key, - * - only log the key values received from other nodes, or - * - both transmit and log the key values. - * - * Each node choosing to implement transmission of the key values MUST - * be prepared to handle the response of iSCSI nodes that do not - * understand the key.\n - * Nodes that implement transmission and/or logging of the key values - * may also implement administrative mechanisms that disable and/or - * change the logging and key transmission details.\n - * Thus, a valid behavior for this key may be that a node is completely - * silent (the node does not transmit any key value and simply discards - * any key values it receives without issuing a NotUnderstood response). - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_X_NODE_ARCH ((const uint8_t *) "X#NodeArchitecture\0\0\0\0\0") - -/** - * @brief Login/Text Operational Session Text Key: IFMarker (obseleted). - * - * This document obsoletes the following keys defined in RFC3720:\n - * IFMarker, OFMarker, OFMarkInt, and IFMarkInt. However, iSCSI - * mplementations compliant to this document may still receive these - * obsoleted keys - i.e., in a responder role - in a text negotiation.\n - * When an IFMarker or OFMarker key is received, a compliant iSCSI - * implementation SHOULD respond with the constant "Reject" value. The - * implementation MAY alternatively respond with a "No" value.\n - * However, the implementation MUST NOT respond with a "NotUnderstood" - * value for either of these keys.\n - * When an IFMarkInt or OFMarkInt key is received, a compliant iSCSI - * implementation MUST respond with the constant "Reject" value. The - * implementation MUST NOT respond with a "NotUnderstood" value for - * either of these keys. - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_IF_MARKER ((const uint8_t *) "IFMarker\0\0\0\0\0\0\0") - -/** - * @brief Login/Text Operational Session Text Key: OFMarker (obseleted). - * - * This document obsoletes the following keys defined in RFC3720:\n - * IFMarker, OFMarker, OFMarkInt, and IFMarkInt. However, iSCSI - * mplementations compliant to this document may still receive these - * obsoleted keys - i.e., in a responder role - in a text negotiation.\n - * When an IFMarker or OFMarker key is received, a compliant iSCSI - * implementation SHOULD respond with the constant "Reject" value. The - * implementation MAY alternatively respond with a "No" value.\n - * However, the implementation MUST NOT respond with a "NotUnderstood" - * value for either of these keys.\n - * When an IFMarkInt or OFMarkInt key is received, a compliant iSCSI - * implementation MUST respond with the constant "Reject" value. The - * implementation MUST NOT respond with a "NotUnderstood" value for - * either of these keys. - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_OF_MARKER ((const uint8_t *) "OFMarker\0\0\0\0\0\0\0") - -/** - * @brief Login/Text Operational Session Text Key: OFMarkInt (obseleted). - * - * This document obsoletes the following keys defined in RFC3720:\n - * IFMarker, OFMarker, OFMarkInt, and IFMarkInt. However, iSCSI - * mplementations compliant to this document may still receive these - * obsoleted keys - i.e., in a responder role - in a text negotiation.\n - * When an IFMarker or OFMarker key is received, a compliant iSCSI - * implementation SHOULD respond with the constant "Reject" value. The - * implementation MAY alternatively respond with a "No" value.\n - * However, the implementation MUST NOT respond with a "NotUnderstood" - * value for either of these keys.\n - * When an IFMarkInt or OFMarkInt key is received, a compliant iSCSI - * implementation MUST respond with the constant "Reject" value. The - * implementation MUST NOT respond with a "NotUnderstood" value for - * either of these keys. - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_OF_MARK_INT ((const uint8_t *) "OFMarkInt\0\0\0\0\0\0") - -/** - * @brief Login/Text Operational Session Text Key: IFMarkInt (obseleted). - * - * This document obsoletes the following keys defined in RFC3720:\n - * IFMarker, OFMarker, OFMarkInt, and IFMarkInt. However, iSCSI - * mplementations compliant to this document may still receive these - * obsoleted keys - i.e., in a responder role - in a text negotiation.\n - * When an IFMarker or OFMarker key is received, a compliant iSCSI - * implementation SHOULD respond with the constant "Reject" value. The - * implementation MAY alternatively respond with a "No" value.\n - * However, the implementation MUST NOT respond with a "NotUnderstood" - * value for either of these keys.\n - * When an IFMarkInt or OFMarkInt key is received, a compliant iSCSI - * implementation MUST respond with the constant "Reject" value. The - * implementation MUST NOT respond with a "NotUnderstood" value for - * either of these keys. - */ -#define ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_IF_MARK_INT ((const uint8_t *) "IFMarkInt\0\0\0\0\0\0") - - /// Login request Next Stage (NSG) flags: SecurityNegotiation. #define ISCSI_LOGIN_REQ_FLAGS_NEXT_STAGE_SECURITY_NEGOTIATION 0x0 @@ -8436,119 +4355,119 @@ typedef struct __attribute__((packed)) iscsi_isid { * Login Requests are always considered as immediate. */ typedef struct __attribute__((packed)) iscsi_login_req_packet { - /// Always 0x03 according to iSCSI specification. - uint8_t opcode; - - /// Login request flags. - int8_t flags; - - /** - * @brief Version-max indicates the maximum version number supported. - * - * All Login Requests within the Login Phase MUST carry the same - * Version-max. Currently, this is always 0.\n - * The target MUST use the value presented with the first Login Request. - */ - uint8_t version_max; - - /** - * @brief Version-min indicates the minimum version number supported. - * - * All Login Requests within the Login Phase MUST carry the same - * Version-min. The target MUST use the value presented with the first - * Login Request. Always 0 for now. - */ - uint8_t version_min; - - /// TotalAHSLength. - uint8_t total_ahs_len; - - /// DataSegmentLength. - uint8_t ds_len[3]; - - /// Initiator Session ID (ISID). - iscsi_isid isid; - - /** - * @brief Target Session Identifying Handle (TSIH). - * - * The TSIH must be set in the first Login Request. The reserved value - * 0 MUST be used on the first connection for a new session. Otherwise, - * the TSIH sent by the target at the conclusion of the successful login - * of the first connection for this session MUST be used. The TSIH - * identifies to the target the associated existing session for this new - * connection.\n - * All Login Requests within a Login Phase MUST carry the same TSIH. - * The target MUST check the value presented with the first Login - * Request. - */ - uint16_t tsih; - - /// Initiator Task Tag (ITT). - uint32_t init_task_tag; - - /** - * @brief Connection ID (CID). - * - * The CID provides a unique ID for this connection within the session.\n - * All Login Requests within the Login Phase MUST carry the same CID. - * The target MUST use the value presented with the first Login Request.\n - * A Login Request with a non-zero TSIH and a CID equal to that of an - * existing connection implies a logout of the connection followed by a - * login. - */ - uint16_t cid; - - /// Reserved for future usage, always MUST be 0. - uint16_t reserved; - - /** - * @brief CmdSN. - * - * The CmdSN is either the initial command sequence number of a session - * (for the first Login Request of a session - the "leading" login) or - * the command sequence number in the command stream if the login is for - * a new connection in an existing session.\n - * Examples: - * - Login on a leading connection: If the leading login carries the - * CmdSN 123, all other Login Requests in the same Login Phase carry - * the CmdSN 123, and the first non-immediate command in the Full - * Feature Phase also carries the CmdSN 123. - * - Login on other than a leading connection: If the current CmdSN at - * the time the first login on the connection is issued is 500, then - * that PDU carries CmdSN=500. Subsequent Login Requests that are - * needed to complete this Login Phase may carry a CmdSN higher than - * 500 if non-immediate requests that were issued on other connections - * in the same session advance the CmdSN. - * - * If the Login Request is a leading Login Request, the target MUST use - * the value presented in the CmdSN as the target value for the - * ExpCmdSN. - */ - uint32_t cmd_sn; - - /** - * @brief ExpStatSN. - * - * For the first Login Request on a connection, this is the ExpStatSN - * for the old connection, and this field is only valid if the Login - * Request restarts a connection.\n - * For subsequent Login Requests, it is used to acknowledge the Login - * Responses with their increasing StatSN values. - */ - uint32_t exp_stat_sn; - - /// Reserved for future usage, always MUST be 0. - uint64_t reserved2[2]; - - /** - * @brief Data segment - Login Parameters in Text Request Format. - * - * The initiator MUST provide some basic parameters in order - * to enable the target to determine if the initiator may use - * the target's resources and the initial text parameters for the security exchange - */ - iscsi_scsi_ds_cmd_data ds_cmd_data; + /// Always 0x03 according to iSCSI specification. + uint8_t opcode; + + /// Login request flags. + int8_t flags; + + /** + * @brief Version-max indicates the maximum version number supported. + * + * All Login Requests within the Login Phase MUST carry the same + * Version-max. Currently, this is always 0.\n + * The target MUST use the value presented with the first Login Request. + */ + uint8_t version_max; + + /** + * @brief Version-min indicates the minimum version number supported. + * + * All Login Requests within the Login Phase MUST carry the same + * Version-min. The target MUST use the value presented with the first + * Login Request. Always 0 for now. + */ + uint8_t version_min; + + /// TotalAHSLength. + uint8_t total_ahs_len; + + /// DataSegmentLength. + uint8_t ds_len[3]; + + /// Initiator Session ID (ISID). + iscsi_isid isid; + + /** + * @brief Target Session Identifying Handle (TSIH). + * + * The TSIH must be set in the first Login Request. The reserved value + * 0 MUST be used on the first connection for a new session. Otherwise, + * the TSIH sent by the target at the conclusion of the successful login + * of the first connection for this session MUST be used. The TSIH + * identifies to the target the associated existing session for this new + * connection.\n + * All Login Requests within a Login Phase MUST carry the same TSIH. + * The target MUST check the value presented with the first Login + * Request. + */ + uint16_t tsih; + + /// Initiator Task Tag (ITT). + uint32_t init_task_tag; + + /** + * @brief Connection ID (CID). + * + * The CID provides a unique ID for this connection within the session.\n + * All Login Requests within the Login Phase MUST carry the same CID. + * The target MUST use the value presented with the first Login Request.\n + * A Login Request with a non-zero TSIH and a CID equal to that of an + * existing connection implies a logout of the connection followed by a + * login. + */ + uint16_t cid; + + /// Reserved for future usage, always MUST be 0. + uint16_t reserved; + + /** + * @brief CmdSN. + * + * The CmdSN is either the initial command sequence number of a session + * (for the first Login Request of a session - the "leading" login) or + * the command sequence number in the command stream if the login is for + * a new connection in an existing session.\n + * Examples: + * - Login on a leading connection: If the leading login carries the + * CmdSN 123, all other Login Requests in the same Login Phase carry + * the CmdSN 123, and the first non-immediate command in the Full + * Feature Phase also carries the CmdSN 123. + * - Login on other than a leading connection: If the current CmdSN at + * the time the first login on the connection is issued is 500, then + * that PDU carries CmdSN=500. Subsequent Login Requests that are + * needed to complete this Login Phase may carry a CmdSN higher than + * 500 if non-immediate requests that were issued on other connections + * in the same session advance the CmdSN. + * + * If the Login Request is a leading Login Request, the target MUST use + * the value presented in the CmdSN as the target value for the + * ExpCmdSN. + */ + uint32_t cmd_sn; + + /** + * @brief ExpStatSN. + * + * For the first Login Request on a connection, this is the ExpStatSN + * for the old connection, and this field is only valid if the Login + * Request restarts a connection.\n + * For subsequent Login Requests, it is used to acknowledge the Login + * Responses with their increasing StatSN values. + */ + uint32_t exp_stat_sn; + + /// Reserved for future usage, always MUST be 0. + uint64_t reserved2[2]; + + /** + * @brief Data segment - Login Parameters in Text Request Format. + * + * The initiator MUST provide some basic parameters in order + * to enable the target to determine if the initiator may use + * the target's resources and the initial text parameters for the security exchange + */ + iscsi_scsi_ds_cmd_data ds_cmd_data; } iscsi_login_req_packet; @@ -8795,107 +4714,107 @@ typedef struct __attribute__((packed)) iscsi_login_req_packet { * Phase. */ typedef struct __attribute__((packed)) iscsi_login_response_packet { - /// Always 0x23 according to iSCSI specification. - uint8_t opcode; - - /// Login response flags. - int8_t flags; - - /** - * @brief This is the highest version number supported by the target. - * - * All Login Responses within the Login Phase MUST carry the same - * Version-max. - */ - uint8_t version_max; - - /** - * @brief Version-active indicates the highest version supported by the target and initiator. - * - * If the target does not support a version within the - * range specified by the initiator, the target rejects the login and - * this field indicates the lowest version supported by the target. - * All Login Responses within the Login Phase MUST carry the same - * Version-active.\n - * The initiator MUST use the value presented as a response to the first - * Login Request. - */ - uint8_t version_active; - - /// TotalAHSLength. - uint8_t total_ahs_len; - - /// DataSegmentLength. - uint8_t ds_len[3]; - - /// Initiator Session ID (ISID). - iscsi_isid isid; - - /** - * @brief Target Session Identifying Handle (TSIH). - * - * The TSIH is the target-assigned session-identifying handle. Its - * internal format and content are not defined by this protocol, except - * for the value 0, which is reserved. With the exception of the Login - * Final-Response in a new session, this field should be set to the TSIH - * provided by the initiator in the Login Request. For a new session, - * the target MUST generate a non-zero TSIH and ONLY return it in the - * Login Final-Response. - */ - uint16_t tsih; - - /// Initiator Task Tag (ITT). - uint32_t init_task_tag; - - /// Reserved for future usage, always MUST be 0. - uint32_t reserved; - - /** - * @brief StatSN. - * - * For the first Login Response (the response to the first Login - * Request), this is the starting status sequence number for the - * connection. The next response of any kind - including the next - * Login Response, if any, in the same Login Phase - will carry this - * number + 1. This field is only valid if the Status-Class is 0. - */ - uint32_t stat_sn; - - /// ExpCmdSN. - uint32_t exp_cmd_sn; - - /// MaxCmdSN. - uint32_t max_cmd_sn; - - /** - * @brief Status-class. - * - * Status-class (see above for details). If the Status-Class is - * not 0, the initiator and target MUST close the TCP connection - * If the target wishes to reject the Login Request for more than one - * reason, it should return the primary reason for the rejection. - */ - uint8_t status_class; - - /// Status-detail. - uint8_t status_detail; - - /// Reserved for future usage, always MUST be 0. - uint16_t reserved2; - - /// Reserved for future usage, always MUST be 0. - uint64_t reserved3; - - /** - * @brief Data segment - Login Parameters in Text Request Format. - * - * The target MUST provide some basic parameters in order to enable the - * initiator to determine if it is connected to the correct port and the - * initial text parameters for the security exchange.\n - * All the rules specified for Text Responses also hold for Login - * Responses. - */ - iscsi_scsi_ds_cmd_data ds_cmd_data; + /// Always 0x23 according to iSCSI specification. + uint8_t opcode; + + /// Login response flags. + int8_t flags; + + /** + * @brief This is the highest version number supported by the target. + * + * All Login Responses within the Login Phase MUST carry the same + * Version-max. + */ + uint8_t version_max; + + /** + * @brief Version-active indicates the highest version supported by the target and initiator. + * + * If the target does not support a version within the + * range specified by the initiator, the target rejects the login and + * this field indicates the lowest version supported by the target. + * All Login Responses within the Login Phase MUST carry the same + * Version-active.\n + * The initiator MUST use the value presented as a response to the first + * Login Request. + */ + uint8_t version_active; + + /// TotalAHSLength. + uint8_t total_ahs_len; + + /// DataSegmentLength. + uint8_t ds_len[3]; + + /// Initiator Session ID (ISID). + iscsi_isid isid; + + /** + * @brief Target Session Identifying Handle (TSIH). + * + * The TSIH is the target-assigned session-identifying handle. Its + * internal format and content are not defined by this protocol, except + * for the value 0, which is reserved. With the exception of the Login + * Final-Response in a new session, this field should be set to the TSIH + * provided by the initiator in the Login Request. For a new session, + * the target MUST generate a non-zero TSIH and ONLY return it in the + * Login Final-Response. + */ + uint16_t tsih; + + /// Initiator Task Tag (ITT). + uint32_t init_task_tag; + + /// Reserved for future usage, always MUST be 0. + uint32_t reserved; + + /** + * @brief StatSN. + * + * For the first Login Response (the response to the first Login + * Request), this is the starting status sequence number for the + * connection. The next response of any kind - including the next + * Login Response, if any, in the same Login Phase - will carry this + * number + 1. This field is only valid if the Status-Class is 0. + */ + uint32_t stat_sn; + + /// ExpCmdSN. + uint32_t exp_cmd_sn; + + /// MaxCmdSN. + uint32_t max_cmd_sn; + + /** + * @brief Status-class. + * + * Status-class (see above for details). If the Status-Class is + * not 0, the initiator and target MUST close the TCP connection + * If the target wishes to reject the Login Request for more than one + * reason, it should return the primary reason for the rejection. + */ + uint8_t status_class; + + /// Status-detail. + uint8_t status_detail; + + /// Reserved for future usage, always MUST be 0. + uint16_t reserved2; + + /// Reserved for future usage, always MUST be 0. + uint64_t reserved3; + + /** + * @brief Data segment - Login Parameters in Text Request Format. + * + * The target MUST provide some basic parameters in order to enable the + * initiator to determine if it is connected to the correct port and the + * initial text parameters for the security exchange.\n + * All the rules specified for Text Responses also hold for Login + * Responses. + */ + iscsi_scsi_ds_cmd_data ds_cmd_data; } iscsi_login_response_packet; @@ -9003,82 +4922,79 @@ typedef struct __attribute__((packed)) iscsi_login_response_packet { * recovery, unless the session is also closed. */ typedef struct __attribute__((packed)) iscsi_logout_req_packet { - /// Always 6 according to iSCSI specification. - uint8_t opcode; - - /** - * @brief Reason code. - * - * A target implicitly terminates the active tasks due to the iSCSI - * protocol in the following cases: - * -# When a connection is implicitly or explicitly logged out with - * the reason code "close the connection" and there are active - * tasks allegiant to that connection. - * -# When a connection fails and eventually the connection state - * times out and there are active tasks allegiant to that - * connection - * -# When a successful recovery Logout is performed while there are - * active tasks allegiant to that connection and those tasks - * eventually time out after the Time2Wait and Time2Retain periods - * without allegiance reassignment - * -# When a connection is implicitly or explicitly logged out with - * the reason code "close the session" and there are active tasks - * in that session - * - * If the tasks terminated in any of the above cases are SCSI tasks, - * they must be internally terminated as if with CHECK CONDITION status. - * This status is only meaningful for appropriately handling the - * internal SCSI state and SCSI side effects with respect to ordering, - * because this status is never communicated back as a terminating - * status to the initiator. However, additional actions may have to be - * taken at the SCSI level, depending on the SCSI context as defined by - * the SCSI standards (e.g., queued commands and ACA; UA for the next - * command on the I_T nexus in cases a), b), and c) above). After the - * tasks are terminated, the target MUST report a Unit Attention condition - * on the next command processed on any connection for each affected - * I_T_L nexus with the status of CHECK CONDITION, the ASC/ASCQ value - * of 0x47 / 0x7F ("SOME COMMANDS CLEARED BY ISCSI PROTOCOL EVENT"), etc. - */ - int8_t reason_code; - - /// Reserved for future usage, always MUST be 0. - uint16_t reserved; - - /// TotalAHSLength (MUST be 0 for this PDU). - uint8_t total_ahs_len; - - /// DataSegmentLength (MUST be 0 for this PDU). - uint8_t ds_len[3]; - - /// Reserved for future usage, always MUST be 0. - uint64_t reserved2; - - /// Initiator Task Tag (ITT). - uint32_t init_task_tag; - - /** - * @brief Connection ID (CID). - * - * This is the connection ID of the connection to be closed (including - * closing the TCP stream). This field is only valid if the reason code - * is not "close the session". - */ - uint16_t cid; - - /// Reserved for future usage, always MUST be 0. - uint16_t reserved3; - - /// CmdSN. - uint32_t cmd_sn; - - /// This is the last ExpStatSN value for the connection to be closed. - uint32_t exp_stat_sn; - - /// Reserved for future usage, always MUST be 0. - uint64_t reserved4[2]; - - /// Optional header digest. - iscsi_header_digest hdr_digest; + /// Always 6 according to iSCSI specification. + uint8_t opcode; + + /** + * @brief Reason code. + * + * A target implicitly terminates the active tasks due to the iSCSI + * protocol in the following cases: + * -# When a connection is implicitly or explicitly logged out with + * the reason code "close the connection" and there are active + * tasks allegiant to that connection. + * -# When a connection fails and eventually the connection state + * times out and there are active tasks allegiant to that + * connection + * -# When a successful recovery Logout is performed while there are + * active tasks allegiant to that connection and those tasks + * eventually time out after the Time2Wait and Time2Retain periods + * without allegiance reassignment + * -# When a connection is implicitly or explicitly logged out with + * the reason code "close the session" and there are active tasks + * in that session + * + * If the tasks terminated in any of the above cases are SCSI tasks, + * they must be internally terminated as if with CHECK CONDITION status. + * This status is only meaningful for appropriately handling the + * internal SCSI state and SCSI side effects with respect to ordering, + * because this status is never communicated back as a terminating + * status to the initiator. However, additional actions may have to be + * taken at the SCSI level, depending on the SCSI context as defined by + * the SCSI standards (e.g., queued commands and ACA; UA for the next + * command on the I_T nexus in cases a), b), and c) above). After the + * tasks are terminated, the target MUST report a Unit Attention condition + * on the next command processed on any connection for each affected + * I_T_L nexus with the status of CHECK CONDITION, the ASC/ASCQ value + * of 0x47 / 0x7F ("SOME COMMANDS CLEARED BY ISCSI PROTOCOL EVENT"), etc. + */ + int8_t reason_code; + + /// Reserved for future usage, always MUST be 0. + uint16_t reserved; + + /// TotalAHSLength (MUST be 0 for this PDU). + uint8_t total_ahs_len; + + /// DataSegmentLength (MUST be 0 for this PDU). + uint8_t ds_len[3]; + + /// Reserved for future usage, always MUST be 0. + uint64_t reserved2; + + /// Initiator Task Tag (ITT). + uint32_t init_task_tag; + + /** + * @brief Connection ID (CID). + * + * This is the connection ID of the connection to be closed (including + * closing the TCP stream). This field is only valid if the reason code + * is not "close the session". + */ + uint16_t cid; + + /// Reserved for future usage, always MUST be 0. + uint16_t reserved3; + + /// CmdSN. + uint32_t cmd_sn; + + /// This is the last ExpStatSN value for the connection to be closed. + uint32_t exp_stat_sn; + + /// Reserved for future usage, always MUST be 0. + uint64_t reserved4[2]; } iscsi_logout_req_packet; @@ -9105,272 +5021,90 @@ typedef struct __attribute__((packed)) iscsi_logout_req_packet { * was session close). */ typedef struct __attribute__((packed)) iscsi_logout_response_packet { - /// Always 0x26 according to iSCSI specification. - uint8_t opcode; - - /// Reserved for future usage (always MUST be 0x80 for now). - int8_t flags; - - /// Response. - uint8_t response; - - /// Reserved for future usage, always MUST be 0. - uint8_t reserved; - - /// TotalAHSLength (MUST be 0 for this PDU). - uint8_t total_ahs_len; - - /// DataSegmentLength (MUST be 0 for this PDU). - uint8_t ds_len[3]; - - /// Reserved for future usage, always MUST be 0. - uint64_t reserved2; - - /// Initiator Task Tag (ITT). - uint32_t init_task_tag; - - /// Reserved for future usage, always MUST be 0. - uint32_t reserved3; - - /// StatSN. - uint32_t stat_sn; - - /// ExpCmdSN. - uint32_t exp_cmd_sn; - - /// MaxCmdSN. - uint32_t max_cmd_sn; - - /// Reserved for future usage, always MUST be 0. - uint32_t reserved4; - - /** - * @brief Time2Wait. - * - * If the Logout response code is 0 and the operational - * ErrorRecoveryLevel is 2, this is the minimum amount of time, in - * seconds, to wait before attempting task reassignment. If the Logout - * response code is 0 and the operational ErrorRecoveryLevel is less - * than 2, this field is to be ignored.\n - * This field is invalid if the Logout response code is 1.\n - * If the Logout response code is 2 or 3, this field specifies the - * minimum time to wait before attempting a new implicit or explicit - * logout.\n - * If Time2Wait is 0, the reassignment or a new Logout may be attempted - * immediately. - */ - uint16_t time_wait; - - /** - * @brief Time2Retain. - * - * If the Logout response code is 0 and the operational - * ErrorRecoveryLevel is 2, this is the maximum amount of time, in - * seconds, after the initial wait (Time2Wait) that the target waits for - * the allegiance reassignment for any active task, after which the task - * state is discarded. If the Logout response code is 0 and the - * operational ErrorRecoveryLevel is less than 2, this field is to be - * ignored.\n - * This field is invalid if the Logout response code is 1.\n - * If the Logout response code is 2 or 3, this field specifies the - * maximum amount of time, in seconds, after the initial wait - * (Time2Wait) that the target waits for a new implicit or explicit - * logout.\n - * If it is the last connection of a session, the whole session state is - * discarded after Time2Retain.\n - * If Time2Retain is 0, the target has already discarded the connection - * (and possibly the session) state along with the task states. No - * reassignment or Logout is required in this case. - */ - uint16_t time_retain; - - /// Reserved for future usage, always MUST be 0. - uint32_t reserved5; - - /// Optional header digest. - iscsi_header_digest hdr_digest; + /// Always 0x26 according to iSCSI specification. + uint8_t opcode; + + /// Reserved for future usage (must be always 0x80 for now). + int8_t flags; + + /// Response. + uint8_t response; + + /// Reserved for future usage, always MUST be 0. + uint8_t reserved; + + /// TotalAHSLength (MUST be 0 for this PDU). + uint8_t total_ahs_len; + + /// DataSegmentLength (MUST be 0 for this PDU). + uint8_t ds_len[3]; + + /// Reserved for future usage, always MUST be 0. + uint64_t reserved2; + + /// Initiator Task Tag (ITT). + uint32_t init_task_tag; + + /// Reserved for future usage, always MUST be 0. + uint32_t reserved3; + + /// StatSN. + uint32_t stat_sn; + + /// ExpCmdSN. + uint32_t exp_cmd_sn; + + /// MaxCmdSN. + uint32_t max_cmd_sn; + + /// Reserved for future usage, always MUST be 0. + uint32_t reserved4; + + /** + * @brief Time2Wait. + * + * If the Logout response code is 0 and the operational + * ErrorRecoveryLevel is 2, this is the minimum amount of time, in + * seconds, to wait before attempting task reassignment. If the Logout + * response code is 0 and the operational ErrorRecoveryLevel is less + * than 2, this field is to be ignored.\n + * This field is invalid if the Logout response code is 1.\n + * If the Logout response code is 2 or 3, this field specifies the + * minimum time to wait before attempting a new implicit or explicit + * logout.\n + * If Time2Wait is 0, the reassignment or a new Logout may be attempted + * immediately. + */ + uint16_t time_wait; + + /** + * @brief Time2Retain. + * + * If the Logout response code is 0 and the operational + * ErrorRecoveryLevel is 2, this is the maximum amount of time, in + * seconds, after the initial wait (Time2Wait) that the target waits for + * the allegiance reassignment for any active task, after which the task + * state is discarded. If the Logout response code is 0 and the + * operational ErrorRecoveryLevel is less than 2, this field is to be + * ignored.\n + * This field is invalid if the Logout response code is 1.\n + * If the Logout response code is 2 or 3, this field specifies the + * maximum amount of time, in seconds, after the initial wait + * (Time2Wait) that the target waits for a new implicit or explicit + * logout.\n + * If it is the last connection of a session, the whole session state is + * discarded after Time2Retain.\n + * If Time2Retain is 0, the target has already discarded the connection + * (and possibly the session) state along with the task states. No + * reassignment or Logout is required in this case. + */ + uint16_t time_retain; + + /// Reserved for future usage, always MUST be 0. + uint32_t reserved5; } iscsi_logout_response_packet; -/// Selective Negative / Sequence Number Acknowledgment (SNACK) request: Data/R2T SNACK: requesting retransmission of one or more Data-In or R2T PDUs. -#define ISCSI_SNACK_REQ_TYPE_DATA_R2T_SNACK 0x00 - -/// Selective Negative / Sequence Number Acknowledgment (SNACK) request: -#define ISCSI_SNACK_REQ_TYPE_STATUS_SNACK 0x01 // Status SNACK: requesting retransmission of one or more - // numbered responses - -/** - * @brief Selective Negative / Sequence Number Acknowledgment (SNACK) request: DataACK: positively acknowledges Data-In PDUs. - * - * If an initiator operates at ErrorRecoveryLevel 1 or higher, it MUST - * issue a SNACK of type DataACK after receiving a Data-In PDU with the - * A bit set to 1. However, if the initiator has detected holes in the - * input sequence, it MUST postpone issuing the SNACK of type DataACK - * until the holes are filled. An initiator MAY ignore the A bit if it - * deems that the bit is being set aggressively by the target (i.e., - * before the MaxBurstLength limit is reached).\n - * The DataACK is used to free resources at the target and not to - * request or imply data retransmission.\n - * An initiator MUST NOT request retransmission for any data it had - * already acknowledged - */ -#define ISCSI_SNACK_REQ_TYPE_DATA_ACK 0x02 - -/** - * @brief Selective Negative / Sequence Number Acknowledgment (SNACK) request: R-Data SNACK: requesting retransmission of Data-In PDUs with possible resegmentation and status tagging. - * - * If the initiator MaxRecvDataSegmentLength changed between the - * original transmission and the time the initiator requests - * retransmission, the initiator MUST issue a R-Data SNACK.\n - * With R-Data SNACK, the initiator indicates that it discards all the - * unacknowledged data and expects the target to resend it. It also - * expects resegmentation. In this case, the retransmitted Data-In PDUs - * MAY be different from the ones originally sent in order to reflect - * changes in MaxRecvDataSegmentLength. Their DataSN starts with the - * BegRun of the last DataACK received by the target if any was received; - * otherwise, it starts with 0 and is increased by 1 for each resent - * Data-In PDU.\n - * A target that has received a R-Data SNACK MUST return a SCSI Response - * that contains a copy of the SNACK Tag field from the R-Data SNACK in - * the SCSI Response SNACK Tag field as its last or only Response. For - * example, if it has already sent a response containing another value - * in the SNACK Tag field or had the status included in the last Data-In - * PDU, it must send a new SCSI Response PDU. If a target sends more - * than one SCSI Response PDU due to this rule, all SCSI Response PDUs - * must carry the same StatSN. If an initiator attempts to recover a lost - * SCSI Response when more than one response has been sent, the - * target will send the SCSI Response with the latest content known to - * the target, including the last SNACK Tag for the command.\n - * For considerations in allegiance reassignment of a task to a - * connection with a different MaxRecvDataSegmentLength. - */ -#define ISCSI_SNACK_REQ_TYPE_R_DATA_SNACK 0x03 - - -/** - * @brief iSCSI SNACK Request packet data. - * - * If the implementation supports ErrorRecoveryLevel greater than zero, - * it MUST support all SNACK types. - * - * The SNACK is used by the initiator to request the retransmission of - * numbered responses, data, or R2T PDUs from the target. The SNACK - * Request indicates the numbered responses or data "runs" whose - * retransmission is requested, where the run starts with the first - * StatSN, DataSN, or R2TSN whose retransmission is requested and - * indicates the number of Status, Data, or R2T PDUs requested, - * including the first. 0 has special meaning when used as a starting - * number and length: - * - * - When used in RunLength, it means all PDUs starting with the - * initial. - * - * - When used in both BegRun and RunLength, it means all - * unacknowledged PDUs. - * - * The numbered response(s) or R2T(s) requested by a SNACK MUST be - * delivered as exact replicas of the ones that the target transmitted - * originally, except for the fields ExpCmdSN, MaxCmdSN, and ExpDataSN, - * which MUST carry the current values. R2T(s)requested by SNACK MUST - * also carry the current value of the StatSN. - * - * The numbered Data-In PDUs requested by a Data SNACK MUST be delivered - * as exact replicas of the ones that the target transmitted originally, - * except for the fields ExpCmdSN and MaxCmdSN, which MUST carry the - * current values; and except for resegmentation. - * - * Any SNACK that requests a numbered response, data, or R2T that was - * not sent by the target or was already acknowledged by the initiator - * MUST be rejected with a reason code of "Protocol Error". - */ -typedef struct __attribute__((packed)) iscsi_snack_req_packet { - /// Always 0x10 according to iSCSI specification. - uint8_t opcode; - - /** - * @brief Type. - * - * Data/R2T SNACK, Status SNACK, or R-Data SNACK for a command MUST - * precede status acknowledgment for the given command. - */ - int8_t type; - - /// Reserved for future usage, always MUST be 0. - uint16_t reserved; - - /// TotalAHSLength. - uint8_t total_ahs_len; - - /// DataSegmentLength. - uint8_t ds_len[3]; - - /// LUN or Reserved. - uint64_t lun; - - /** - * @brief Initiator Task Tag (ITT). - * - * For a Status SNACK and DataACK, the Initiator Task Tag MUST be set to - * the reserved value 0xFFFFFFFF. In all other cases, the Initiator - * Task Tag field MUST be set to the Initiator Task Tag of the - * referenced command. - */ - uint32_t init_task_tag; - - /** - * @brief Target Transfer Tag (TTT). - * - * For a R-Data SNACK, this field MUST contain a value that is different - * from 0 or 0xFFFFFFFF and is unique for the task (identified by the - * Initiator Task Tag). This value MUST be copied by the iSCSI target - * in the last or only SCSI Response PDU it issues for the command.\n - * For DataACK, the Target Transfer Tag MUST contain a copy of the - * Target Transfer Tag and LUN provided with the SCSI Data-In PDU with - * the A bit set to 1.\n - * In all other cases, the Target Transfer Tag field MUST be set to the - * reserved value 0xFFFFFFFF. - */ - uint32_t target_xfer_snack_tag; - - /// Reserved for future usage, always MUST be 0. - uint32_t reserved2; - - /// ExpStatSN. - uint32_t exp_stat_sn; - - /// Reserved for future usage, always MUST be 0. - uint32_t reserved3; - - /** - * @brief BegRun. - * - * This field indicates the DataSN, R2TSN, or StatSN of the first PDU - * whose retransmission is requested (Data/R2T and Status SNACK), or the - * next expected DataSN (DataACK SNACK).\n - * A BegRun of 0, when used in conjunction with a RunLength of 0, means - * "resend all unacknowledged Data-In, R2T or Response PDUs". - * BegRun MUST be 0 for a R-Data SNACK. - */ - uint32_t beg_run; - - /** - * @brief RunLength. - * - * This field indicates the number of PDUs whose retransmission is - * requested.\n - * A RunLength of 0 signals that all Data-In, R2T, or Response PDUs - * carrying the numbers equal to or greater than BegRun have to be - * resent.\n - * The RunLength MUST also be 0 for a DataACK SNACK in addition to a - * R-Data SNACK. - */ - uint32_t run_len; - - /// Optional header digest. - iscsi_header_digest hdr_digest; -} iscsi_snack_req_packet; - - /// iSCSI Reject packet data: Reserved, original PDU can't be resent. #define ISCSI_REJECT_REASON_RESERVED 0x01 @@ -9437,100 +5171,91 @@ typedef struct __attribute__((packed)) iscsi_snack_req_packet { * packet was rejected or has been rejected for some reason. */ typedef struct __attribute__((packed)) iscsi_reject_packet { - /// Always 0x3F according to iSCSI specification. - uint8_t opcode; - - /// Reserved for future usage (always MUST be 0x80 for now). - int8_t flags; - - /** - * @brief Reject reason. - * - * In all the cases in which a pre-instantiated SCSI task is terminated - * because of the reject, the target MUST issue a proper SCSI command - * response with CHECK CONDITION. In these cases in which a status for - * the SCSI task was already sent before the reject, no additional - * status is required. If the error is detected while data from the - * initiator is still expected (i.e., the command PDU did not contain - * all the data and the target has not received a Data-Out PDU with the - * Final bit set to 1 for the unsolicited data, if any, and all - * outstanding R2Ts, if any), the target MUST wait until it receives - * the last expected Data-Out PDUs with the F bit set to 1 before - * sending the Response PDU. - */ - uint8_t reason; - - /// Reserved for future usage, always MUST be 0. - uint8_t reserved; - - /// TotalAHSLength. - uint8_t total_ahs_len; - - /// DataSegmentLength. - uint8_t ds_len[3]; - - /// Reserved for future usage, always MUST be 0. - uint64_t reserved2; - - /// Always 0xFFFFFFFF for now. - uint32_t tag; - - /// Reserved for future usage, always MUST be 0. - uint32_t reserved3; - - /** - * @brief StatSN. - * - * This field carries its usual value and is not related to the - * rejected command. The StatSN is advanced after a Reject. - */ - uint32_t stat_sn; - - /** - * @brief ExpCmdSN. - * - * This field carries its usual value and is not related to the - * rejected command. - */ - uint32_t exp_cmd_sn; - - /** - * @brief MaxCmdSN. - * - * This field carries its usual value and is not related to the - * rejected command. - */ - uint32_t max_cmd_sn; - - /** - * @brief DataSN / Ready To Transfer Sequence Number (R2TSN) or Reserved. - * - * This field is only valid if the rejected PDU is a Data/R2T SNACK and - * the Reject reason code is "Protocol Error". The DataSN/R2TSN is the - * next Data/R2T sequence number that the target would send for the - * task, if any. - */ - uint32_t data_r2t_sn; - - /// Reserved for future usage, always MUST be 0. - uint64_t reserved4; - - /// Optional header digest. - iscsi_header_digest hdr_digest; - - /** - * @brief Complete Header of Bad PDU. - * - * The target returns the header (not including the digest) of the - * PDU in error as the data of the response. - */ - iscsi_bhs_packet bad_pdu_hdr; - - /// Vendor-specific data (if any). - uint8_t vendor_data[0]; - - /// Optional data digest. - iscsi_data_digest data_digest; + /// Always 0x3F according to iSCSI specification. + uint8_t opcode; + + /// Reserved for future usage (must be always 0x80 for now). + int8_t flags; + + /** + * @brief Reject reason. + * + * In all the cases in which a pre-instantiated SCSI task is terminated + * because of the reject, the target MUST issue a proper SCSI command + * response with CHECK CONDITION. In these cases in which a status for + * the SCSI task was already sent before the reject, no additional + * status is required. If the error is detected while data from the + * initiator is still expected (i.e., the command PDU did not contain + * all the data and the target has not received a Data-Out PDU with the + * Final bit set to 1 for the unsolicited data, if any, and all + * outstanding R2Ts, if any), the target MUST wait until it receives + * the last expected Data-Out PDUs with the F bit set to 1 before + * sending the Response PDU. + */ + uint8_t reason; + + /// Reserved for future usage, always MUST be 0. + uint8_t reserved; + + /// TotalAHSLength. + uint8_t total_ahs_len; + + /// DataSegmentLength. + uint8_t ds_len[3]; + + /// Reserved for future usage, always MUST be 0. + uint64_t reserved2; + + /// Always 0xFFFFFFFF for now. + uint32_t tag; + + /// Reserved for future usage, always MUST be 0. + uint32_t reserved3; + + /** + * @brief StatSN. + * + * This field carries its usual value and is not related to the + * rejected command. The StatSN is advanced after a Reject. + */ + uint32_t stat_sn; + + /** + * @brief ExpCmdSN. + * + * This field carries its usual value and is not related to the + * rejected command. + */ + uint32_t exp_cmd_sn; + + /** + * @brief MaxCmdSN. + * + * This field carries its usual value and is not related to the + * rejected command. + */ + uint32_t max_cmd_sn; + + /** + * @brief DataSN / Ready To Transfer Sequence Number (R2TSN) or Reserved. + * + * This field is only valid if the rejected PDU is a Data/R2T SNACK and + * the Reject reason code is "Protocol Error". The DataSN/R2TSN is the + * next Data/R2T sequence number that the target would send for the + * task, if any. + */ + uint32_t data_r2t_sn; + + /// Reserved for future usage, always MUST be 0. + uint64_t reserved4; + + /** + * @brief Complete Header of Bad PDU. + * + * The target returns the header (not including the digest) of the + * PDU in error as the data of the response. + */ + iscsi_bhs_packet bad_pdu_hdr; } iscsi_reject_packet; /** @@ -9555,76 +5280,76 @@ typedef struct __attribute__((packed)) iscsi_reject_packet { * in response to each other. */ typedef struct __attribute__((packed)) iscsi_nop_out_packet { - /// Always 0x00 according to iSCSI specification. - uint8_t opcode; - - /// Reserved for future usage (always MUST be 0x80 for now). - int8_t flags; - - /// Reserved for future usage, always MUST be 0. - uint16_t reserved; - - /// TotalAHSLength. - uint8_t total_ahs_len; - - /// DataSegmentLength. - uint8_t ds_len[3]; - - /// LUN or Reserved. - uint64_t lun; - - /** - * @brief Initiator Task Tag (ITT). - * - * The NOP-Out MUST have the Initiator Task Tag set to a valid value - * only if a response in the form of a NOP-In is requested (i.e., the - * NOP-Out is used as a ping request). Otherwise, the Initiator Task - * Tag MUST be set to 0xFFFFFFFF.\n - * When a target receives the NOP-Out with a valid Initiator Task Tag, - * it MUST respond with a NOP-In Response.\n - * If the Initiator Task Tag contains 0xFFFFFFFF, the I bit MUST be set - * to 1, and the CmdSN is not advanced after this PDU is sent. - */ - uint32_t init_task_tag; - - /** - * @brief Target Transfer Tag (TTT). - * - * The Target Transfer Tag is a target-assigned identifier for the - * operation.\n - * The NOP-Out MUST only have the Target Transfer Tag set if it is - * issued in response to a NOP-In with a valid Target Transfer Tag. In - * this case, it copies the Target Transfer Tag from the NOP-In PDU.\n - * Otherwise, the Target Transfer Tag MUST be set to 0xFFFFFFFF.\n - * When the Target Transfer Tag is set to a value other than 0xFFFFFFFF, - * the LUN field MUST also be copied from the NOP-In. - */ - uint32_t target_xfer_tag; - - /// CmdSN. - uint32_t cmd_sn; - - /// ExpStatSN. - uint32_t exp_stat_sn; - - /// Reserved for future usage, always MUST be 0. - uint64_t reserved2[2]; - - /// Optional header digest. - iscsi_header_digest hdr_digest; - - /** - * @brief DataSegment - Ping Data (optional). - * - * Ping data is reflected in the NOP-In Response. The length of the - * reflected data is limited to MaxRecvDataSegmentLength. The length of - * ping data is indicated by the DataSegmentLength. 0 is a valid value - * for the DataSegmentLength and indicates the absence of ping data. - */ - iscsi_scsi_ds_cmd_data ds_ping_data; - - /// Optional data digest. - iscsi_data_digest data_digest; + /// Always 0x00 according to iSCSI specification. + uint8_t opcode; + + /// Reserved for future usage (must be always 0x80 for now). + int8_t flags; + + /// Reserved for future usage, always MUST be 0. + uint16_t reserved; + + /// TotalAHSLength. + uint8_t total_ahs_len; + + /// DataSegmentLength. + uint8_t ds_len[3]; + + /// LUN or Reserved. + uint64_t lun; + + /** + * @brief Initiator Task Tag (ITT). + * + * The NOP-Out MUST have the Initiator Task Tag set to a valid value + * only if a response in the form of a NOP-In is requested (i.e., the + * NOP-Out is used as a ping request). Otherwise, the Initiator Task + * Tag MUST be set to 0xFFFFFFFF.\n + * When a target receives the NOP-Out with a valid Initiator Task Tag, + * it MUST respond with a NOP-In Response.\n + * If the Initiator Task Tag contains 0xFFFFFFFF, the I bit MUST be set + * to 1, and the CmdSN is not advanced after this PDU is sent. + */ + uint32_t init_task_tag; + + /** + * @brief Target Transfer Tag (TTT). + * + * The Target Transfer Tag is a target-assigned identifier for the + * operation.\n + * The NOP-Out MUST only have the Target Transfer Tag set if it is + * issued in response to a NOP-In with a valid Target Transfer Tag. In + * this case, it copies the Target Transfer Tag from the NOP-In PDU.\n + * Otherwise, the Target Transfer Tag MUST be set to 0xFFFFFFFF.\n + * When the Target Transfer Tag is set to a value other than 0xFFFFFFFF, + * the LUN field MUST also be copied from the NOP-In. + */ + uint32_t target_xfer_tag; + + /// CmdSN. + uint32_t cmd_sn; + + /// ExpStatSN. + uint32_t exp_stat_sn; + + /// Reserved for future usage, always MUST be 0. + uint64_t reserved2[2]; + + /// Optional header digest. + uint32_t hdr_digest; + + /** + * @brief DataSegment - Ping Data (optional). + * + * Ping data is reflected in the NOP-In Response. The length of the + * reflected data is limited to MaxRecvDataSegmentLength. The length of + * ping data is indicated by the DataSegmentLength. 0 is a valid value + * for the DataSegmentLength and indicates the absence of ping data. + */ + iscsi_scsi_ds_cmd_data ds_ping_data; + + /// Optional data digest. + uint32_t data_digest; } iscsi_nop_out_packet; @@ -9653,70 +5378,70 @@ typedef struct __attribute__((packed)) iscsi_nop_out_packet { * (DataSegmentLength MUST be 0). */ typedef struct __attribute__((packed)) iscsi_nop_in_packet { - /// Always 0x20 according to iSCSI specification. - uint8_t opcode; - - /// Reserved for future usage (always MUST be 0x80 for now). - int8_t flags; - - /// Reserved for future usage, always MUST be 0. - uint16_t reserved; - - /// TotalAHSLength - uint8_t total_ahs_len; - - /// DataSegmentLength. - uint8_t ds_len[3]; - - /// A LUN MUST be set to a correct value when the Target Transfer Tag is valid (not the reserved value 0xFFFFFFFF). - uint64_t lun; - - /// Initiator Task Tag (ITT) or 0xFFFFFFFF. - uint32_t init_task_tag; - - /** - * @brief Target Transfer Tag (TTT). - * - * If the target is responding to a NOP-Out, this field is set to the - * reserved value 0xFFFFFFFF.\n - * If the target is sending a NOP-In as a ping (intending to receive a - * corresponding NOP-Out), this field is set to a valid value (not the - * reserved value 0xFFFFFFFF).\n - * If the target is initiating a NOP-In without wanting to receive a - * corresponding NOP-Out, this field MUST hold the reserved value - * 0xFFFFFFFF. - */ - uint32_t target_xfer_tag; - - /** - * @brief StatSN. - * - * The StatSN field will always contain the next StatSN. However, when - * the Initiator Task Tag is set to 0xFFFFFFFF, the StatSN for the - * connection is not advanced after this PDU is sent. - */ - uint32_t stat_sn; - - /// ExpCmdSN. - uint32_t exp_cmd_sn; - - /// MaxCmdSN. - uint32_t max_cmd_sn; - - /// Reserved for future usage, always MUST be 0. - uint32_t reserved2; - - /// Reserved for future usage, always MUST be 0. - uint64_t reserved3; - - /// Optional header digest. - iscsi_header_digest hdr_digest; - - /// DataSegment - Return Ping Data. - iscsi_scsi_ds_cmd_data ds_ping_data; - - /// Optional data digest. - iscsi_data_digest data_digest; + /// Always 0x20 according to iSCSI specification. + uint8_t opcode; + + /// Reserved for future usage (must be always 0x80 for now). + int8_t flags; + + /// Reserved for future usage, always MUST be 0. + uint16_t reserved; + + /// TotalAHSLength + uint8_t total_ahs_len; + + /// DataSegmentLength. + uint8_t ds_len[3]; + + /// A LUN MUST be set to a correct value when the Target Transfer Tag is valid (not the reserved value 0xFFFFFFFF). + uint64_t lun; + + /// Initiator Task Tag (ITT) or 0xFFFFFFFF. + uint32_t init_task_tag; + + /** + * @brief Target Transfer Tag (TTT). + * + * If the target is responding to a NOP-Out, this field is set to the + * reserved value 0xFFFFFFFF.\n + * If the target is sending a NOP-In as a ping (intending to receive a + * corresponding NOP-Out), this field is set to a valid value (not the + * reserved value 0xFFFFFFFF).\n + * If the target is initiating a NOP-In without wanting to receive a + * corresponding NOP-Out, this field MUST hold the reserved value + * 0xFFFFFFFF. + */ + uint32_t target_xfer_tag; + + /** + * @brief StatSN. + * + * The StatSN field will always contain the next StatSN. However, when + * the Initiator Task Tag is set to 0xFFFFFFFF, the StatSN for the + * connection is not advanced after this PDU is sent. + */ + uint32_t stat_sn; + + /// ExpCmdSN. + uint32_t exp_cmd_sn; // ExpCmdSN + + /// MaxCmdSN. + uint32_t max_cmd_sn; + + /// Reserved for future usage, always MUST be 0. + uint32_t reserved2; + + /// Reserved for future usage, always MUST be 0. + uint64_t reserved3; + + /// Optional header digest. + uint32_t hdr_digest; + + /// DataSegment - Return Ping Data. + iscsi_scsi_ds_cmd_data ds_ping_data; + + /// Optional data digest. + uint32_t data_digest; } iscsi_nop_in_packet; @@ -9764,17 +5489,17 @@ typedef struct __attribute__((packed)) iscsi_nop_in_packet { * identifier data. */ typedef struct __attribute__((packed)) iscsi_transport_id { - /// First 4 bits are protocol ID and last 2 bits are format. - uint8_t id; + /// First 4 bits are protocol ID and last 2 bits are format. + uint8_t id; - /// Reserved for future usage (always MUST be 0). - uint8_t reserved; + /// Reserved for future usage (always MUST be 0). + uint8_t reserved; - /// Additional length of name. - uint16_t add_len; + /// Additional length of name. + uint16_t add_len; - /// Name. - uint8_t name[0]; + /// Name. + uint8_t name[0]; } iscsi_transport_id; @@ -9854,20 +5579,20 @@ typedef struct __attribute__((packed)) iscsi_transport_id { * and the iSCSI connection lookup table. */ typedef struct iscsi_key_value_pair_lut_entry { - /// Name of key. - const uint8_t *key; + /// Name of key. + const uint8_t *key; - /// Default value of the key, always in string representation. - uint8_t *value; + /// Default value of the key, always in string representation. + uint8_t *value; - /// NUL separated list of allowed string values. If key type is numeric: NUL separated minimum and maximum integer range. End is marked with another NUL. - uint8_t *list_range; + /// NUL separated list of allowed string values. If key type is numeric: NUL separated minimum and maximum integer range. End is marked with another NUL. + uint8_t *list_range; - /// Type of key and value pair. - const int type; + /// Type of key and value pair. + const int type; - /// Flags indicating special key attributes. - const int flags; + /// Flags indicating special key attributes. + const int flags; } iscsi_key_value_pair_lut_entry; @@ -9879,555 +5604,62 @@ typedef struct iscsi_key_value_pair_lut_entry { * Text or Login packet data. */ typedef struct iscsi_key_value_pair { - /// Value of the key which is stored in the hash map. + /// Value of the key which is stored in the hash map. uint8_t *value; - /// NUL separated list of allowed string values. If key type is numeric: NUL separated minimum and maximum integer range. End is marked with another NUL. - uint8_t *list_range; + /// NUL separated list of allowed string values. If key type is numeric: NUL separated minimum and maximum integer range. End is marked with another NUL. + uint8_t *list_range; - /// Type of key and value pair. - int type; + /// Type of key and value pair. + int type; - /// Flags indicating special key attributes. - int flags; + /// Flags indicating special key attributes. + int flags; - /// State bit mask. + /// State bit mask. uint state_mask; } iscsi_key_value_pair; -typedef struct iscsi_connection iscsi_connection; - -/** - * @brief iSCSI Text / Login key=value packet data construction helper. - * - * This structure is used to store the key=value plus NUL terminator - * pairs for sending as DataSegment packet data to the client. - */ -typedef struct iscsi_key_value_pair_packet { - /// Associated iSCSI connection. - iscsi_connection *conn; - - /// Current text buffer containing multiple key=value + NUL terminator pairs. - uint8_t *buf; - - /// Position of output buffer for next write. - uint32_t pos; - - /// Current length of buffer including final NUL terminator without iSCSI zero padding. - uint32_t len; - - /// Discovery mode. - int discovery; -} iscsi_key_value_pair_packet; - -int iscsi_parse_key_value_pairs(iscsi_hashmap *key_value_pairs, const uint8_t *packet_data, uint len, int c_bit, uint8_t **partial_pairs); // Extracts all text key / value pairs out of an iSCSI packet into a hash map - - -/// iSCSI main global data: INI configuration filename. -#define ISCSI_GLOBALS_CONFIG_FILENAME "iscsi.conf" - - -/// iSCSI main global data: iSCSI INI configuration iSCSI section identifier string. -#define ISCSI_GLOBALS_SECTION_ISCSI "iscsi" - -/// iSCSI main global data: iSCSI INI configuration iSCSI SCSI section identifier string. -#define ISCSI_GLOBALS_SECTION_SCSI "scsi" - - -/// iSCSI main global data: iSCSI INI configuration iSCSI section target name check key identifier string. -#define ISCSI_GLOBALS_SECTION_ISCSI_KEY_TARGET_NAME_CHECK "TargetNameCheck" - -/// iSCSI main global data: iSCSI INI configuration iSCSI section maximum number of sessions allowed key identifier string. -#define ISCSI_GLOBALS_SECTION_ISCSI_KEY_MAX_SESSIONS "MaxSessions" - -/// iSCSI main global data: iSCSI INI configuration iSCSI section maximum number of connections per session allowed key identifier string. -#define ISCSI_GLOBALS_SECTION_ISCSI_MAX_CONNECTIONS_PER_SESSIONS "MaxConnectionsPerSession" - - -/// iSCSI main global data: iSCSI INI configuration iSCSI SCSI section device type key identifier string. -#define ISCSI_GLOBALS_SECTION_SCSI_KEY_DEVICE_TYPE "DeviceType" - -/// iSCSI main global data: iSCSI INI configuration iSCSI SCSI section physical block size key identifier string. -#define ISCSI_GLOBALS_SECTION_SCSI_KEY_PHYSICAL_BLOCK_SIZE "PhysicalBlockSize" - -/// iSCSI main global data: iSCSI INI configuration iSCSI SCSI section logical block size key identifier string. -#define ISCSI_GLOBALS_SECTION_SCSI_KEY_LOGICAL_BLOCK_SIZE "LogicalBlockSize" - -/// iSCSI main global data: iSCSI INI configuration iSCSI SCSI section removable device key identifier string. -#define ISCSI_GLOBALS_SECTION_SCSI_KEY_REMOVABLE "Removable" - -/// iSCSI main global data: iSCSI INI configuration iSCSI SCSI section UNMAP support device key identifier string. -#define ISCSI_GLOBALS_SECTION_SCSI_KEY_UNMAP "UNMAP" - -/// iSCSI main global data: iSCSI INI configuration iSCSI SCSI section no rotation device key identifier string. -#define ISCSI_GLOBALS_SECTION_SCSI_KEY_NO_ROTATION "NoRotation" - -/// iSCSI main global data: iSCSI INI configuration iSCSI SCSI section physical read only device key identifier string. -#define ISCSI_GLOBALS_SECTION_SCSI_KEY_PHYSICAL_READ_ONLY "PhysicalReadOnly" - -/// iSCSI main global data: iSCSI INI configuration iSCSI SCSI section write protected device key identifier string. -#define ISCSI_GLOBALS_SECTION_SCSI_KEY_WRITE_PROTECT "WriteProtect" - -/// iSCSI main global data: iSCSI INI configuration iSCSI SCSI section write cache supported device key identifier string. -#define ISCSI_GLOBALS_SECTION_SCSI_KEY_WRITE_CACHE "WriteCache" - - -/// iSCSI main global data: iSCSI SCSI device specific INI configuration section prefix identifier string. -#define ISCSI_GLOBALS_SECTION_SCSI_DEVICE_PREFIX "scsi-device-" - - -/// iSCSI main global data config type: iHeader digest (CRC32), always MUST be 0 or 4 for now. -#define ISCSI_GLOBALS_CONFIG_TYPE_HEADER_DIGEST 0 - -/// iSCSI main global data config type: Data digest (CRC32), always MUST be 0 or 4 for now. -#define ISCSI_GLOBALS_CONFIG_TYPE_DATA_DIGEST 1 - -/// iSCSI main global data config type: Maximum receive DataSegment length in bytes. -#define ISCSI_GLOBALS_CONFIG_TYPE_MAX_RECV_DS_LEN 2 - -/// iSCSI main global data config type: Maximum number of connections per session. -#define ISCSI_GLOBALS_CONFIG_TYPE_MAX_SESSION_CONNS 3 - -/// iSCSI main global data config type: Ready to transfer maximum outstanding value. -#define ISCSI_GLOBALS_CONFIG_TYPE_MAX_OUTSTANDING_R2T 4 - -/// iSCSI main global data config type: Default time to wait. -#define ISCSI_GLOBALS_CONFIG_TYPE_DEFAULT_TIME_TO_WAIT 5 - -/// iSCSI main global data config type: Default time to retain. -#define ISCSI_GLOBALS_CONFIG_TYPE_DEFAULT_TIME_TO_RETAIN 6 - -/// iSCSI main global data config type: First burst length. -#define ISCSI_GLOBALS_CONFIG_TYPE_FIRST_BURST_LEN 7 - -/// iSCSI main global data config type: Maximum burst length. -#define ISCSI_GLOBALS_CONFIG_TYPE_MAX_BURST_LEN 8 - -/// iSCSI main global data config type: Error recovery level. -#define ISCSI_GLOBALS_CONFIG_TYPE_ERR_RECOVERY_LEVEL 9 - -/// iSCSI main global data config type: SCSI emulation for device type. -#define ISCSI_GLOBALS_CONFIG_TYPE_SCSI_DEVICE_TYPE 10 - -/// iSCSI main global data config type: SCSI emulation for physical block size. -#define ISCSI_GLOBALS_CONFIG_TYPE_SCSI_PHYSICAL_BLOCK_SIZE 11 - -/// iSCSI main global data config type: SCSI emulation for physical block size shift count. -#define ISCSI_GLOBALS_CONFIG_TYPE_SCSI_PHYSICAL_BLOCK_SIZE_SHIFT 12 - -/// iSCSI main global data config type: SCSI emulation for logical block size. -#define ISCSI_GLOBALS_CONFIG_TYPE_SCSI_LOGICAL_BLOCK_SIZE 13 - -/// iSCSI main global data config type: SCSI emulation for logical block size shift count. -#define ISCSI_GLOBALS_CONFIG_TYPE_SCSI_LOGICAL_BLOCK_SIZE_SHIFT 14 - -/// iSCSI main global data config type: Initial ready to transfer. -#define ISCSI_GLOBALS_CONFIG_TYPE_FLAGS_INIT_R2T 15 - -/// iSCSI main global data config type: Immediate data. -#define ISCSI_GLOBALS_CONFIG_TYPE_FLAGS_IMMEDIATE_DATA 16 - -/// iSCSI main global data config type: Data PDU in order. -#define ISCSI_GLOBALS_CONFIG_TYPE_FLAGS_DATA_PDU_IN_ORDER 17 - -/// iSCSI main global data config type: Data sequence in order. -#define ISCSI_GLOBALS_CONFIG_TYPE_FLAGS_DATA_SEQ_IN_ORDER 18 - -/// iSCSI main global data config type: SCSI emulation for I/O removable device. -#define ISCSI_GLOBALS_CONFIG_TYPE_FLAGS_SCSI_IO_REMOVABLE 19 - -/// iSCSI main global data config type: SCSI emulation for I/O UNMAP supporting device. -#define ISCSI_GLOBALS_CONFIG_TYPE_FLAGS_SCSI_IO_UNMAP 20 - -/// iSCSI main global data config type: SCSI emulation for I/O non-rotating device. -#define ISCSI_GLOBALS_CONFIG_TYPE_FLAGS_SCSI_IO_NO_ROTATION 21 - -/// iSCSI main global data config type: SCSI emulation for I/O physical read only device. -#define ISCSI_GLOBALS_CONFIG_TYPE_FLAGS_SCSI_IO_PHYSICAL_READ_ONLY 22 - -/// iSCSI main global data config type: SCSI emulation for I/O write protected device. -#define ISCSI_GLOBALS_CONFIG_TYPE_FLAGS_SCSI_IO_WRITE_PROTECT 23 - -/// iSCSI main global data config type: SCSI emulation for I/O write cache device. -#define ISCSI_GLOBALS_CONFIG_TYPE_FLAGS_SCSI_IO_WRITE_CACHE 24 - - -/// iSCSI main global data SCSI device configuration flags: Initial ready to transfer. -#define ISCSI_GLOBALS_SCSI_DEVICE_CONFIG_FLAGS_INIT_R2T (1 << 0) - -/// iSCSI main global data SCSI device configuration flags: Immediate data. -#define ISCSI_GLOBALS_SCSI_DEVICE_CONFIG_FLAGS_IMMEDIATE_DATA (1 << 1) - -/// iSCSI main global data SCSI device configuration flags: Data PDU in order. -#define ISCSI_GLOBALS_SCSI_DEVICE_CONFIG_FLAGS_DATA_PDU_IN_ORDER (1 << 2) - -/// iSCSI main global data SCSI device configuration flags: Data sequence in order. -#define ISCSI_GLOBALS_SCSI_DEVICE_CONFIG_FLAGS_DATA_SEQ_IN_ORDER (1 << 3) - -/// iSCSI main global data SCSI device configuration flags: SCSI emulation for I/O removable device. -#define ISCSI_GLOBALS_SCSI_DEVICE_CONFIG_FLAGS_SCSI_IO_REMOVABLE (1 << 4) - -/// iSCSI main global data SCSI device configuration flags: SCSI emulation for I/O UNMAP supporting device. -#define ISCSI_GLOBALS_SCSI_DEVICE_CONFIG_FLAGS_SCSI_IO_UNMAP (1 << 5) - -/// iSCSI main global data SCSI device configuration flags: SCSI emulation for I/O non-rotating device. -#define ISCSI_GLOBALS_SCSI_DEVICE_CONFIG_FLAGS_SCSI_IO_NO_ROTATION (1 << 6) - -/// iSCSI main global data SCSI device configuration flags: SCSI emulation for I/O physical read only device. -#define ISCSI_GLOBALS_SCSI_DEVICE_CONFIG_FLAGS_SCSI_IO_PHYSICAL_READ_ONLY (1 << 7) - -/// iSCSI main global data SCSI device configuration flags: SCSI emulation for I/O write protected device. -#define ISCSI_GLOBALS_SCSI_DEVICE_CONFIG_FLAGS_SCSI_IO_WRITE_PROTECT (1 << 8) - -/// iSCSI main global data SCSI device configuration flags: SCSI emulation for I/O write cache device. -#define ISCSI_GLOBALS_SCSI_DEVICE_CONFIG_FLAGS_SCSI_IO_WRITE_CACHE (1 << 9) - - -/** - * @brief iSCSI main global data SCSI device configuration. - * - * This structure is used for specific SCSI device - * configuration which are matched using wildcard - * patterns which are stored in the hash map key. - */ -typedef struct iscsi_scsi_device_config { - /// SCSI device configuration flags. - int flags; - - /// iHeader digest (CRC32), always MUST be 0 or 4 for now. - int header_digest; - - /// Data digest (CRC32), always MUST be 0 or 4 for now. - int data_digest; - - /// SCSI emulation: Device type. - uint scsi_device_type; - - /// Maximum receive DataSegment length in bytes. - uint32_t max_recv_ds_len; - - /// Maximum number of connections per session. - uint32_t max_session_conns; - - /// Ready to transfer maximum outstanding value. - uint32_t max_outstanding_r2t; - - /// Default time to wait. - uint32_t default_time_to_wait; - - /// Default time to retain. - uint32_t default_time_to_retain; - - /// First burst length. - uint32_t first_burst_len; - - /// Maximum burst length. - uint32_t max_burst_len; - - /// Error recovery level. - uint32_t err_recovery_level; - - /// SCSI emulation: Physical block size. - uint32_t scsi_physical_block_size; - - /// SCSI emulation: Physical block size shift count. - uint32_t scsi_physical_block_size_shift; - - /// SCSI emulation: Logical block size. - uint32_t scsi_logical_block_size; - - /// SCSI emulation: Logical block size shift count. - uint32_t scsi_logical_block_size_shift; -} iscsi_scsi_device_config; - - -/** - * @brief iSCSI SCSI device configuration search by name. - * - * This structure is used by iterating through - * all iSCSI SCSI device configurations and - * uses wildcard matching in order to retrieve - * the correct SCSI configuration for a - * specified device name. - */ -typedef struct iscsi_scsi_device_config_find { - /// Found iSCSI SCSI device configuration is stored here, should be initialized to NULL. - iscsi_scsi_device_config *scsi_device_config; - - /// The name to be searched for is stored here. - uint8_t *name; -} iscsi_scsi_device_config_find; - - -/// iSCSI main global data flags: Allow duplicate ISIDs. -#define ISCSI_GLOBALS_FLAGS_ISID_ALLOW_DUPLICATES (1 << 0) - -/// iSCSI main global data flags: CHAP authentication is disabled. -#define ISCSI_GLOBALS_FLAGS_CHAP_DISABLE (1 << 1) - -/// iSCSI main global data flags: CHAP authentication is required. -#define ISCSI_GLOBALS_FLAGS_CHAP_REQUIRE (1 << 2) - -/// iSCSI main global data flags: CHAP authentication is mutual. -#define ISCSI_GLOBALS_FLAGS_CHAP_MUTUAL (1 << 3) - -/// iSCSI main global data flags: Initial ready to transfer. -#define ISCSI_GLOBALS_FLAGS_INIT_R2T (1 << 4) - -/// iSCSI main global data flags: Immediate data. -#define ISCSI_GLOBALS_FLAGS_IMMEDIATE_DATA (1 << 5) - -/// iSCSI main global data flags: Data PDU in order. -#define ISCSI_GLOBALS_FLAGS_DATA_PDU_IN_ORDER (1 << 6) - -/// iSCSI main global data flags: Data sequence in order. -#define ISCSI_GLOBALS_FLAGS_DATA_SEQ_IN_ORDER (1 << 7) - -/// iSCSI main global data flags: SCSI emulation for I/O removable device. -#define ISCSI_GLOBALS_FLAGS_SCSI_IO_REMOVABLE (1 << 8) - -/// iSCSI main global data flags: SCSI emulation for I/O UNMAP supporting device. -#define ISCSI_GLOBALS_FLAGS_SCSI_IO_UNMAP (1 << 9) - -/// iSCSI main global data flags: SCSI emulation for I/O non-rotating device. -#define ISCSI_GLOBALS_FLAGS_SCSI_IO_NO_ROTATION (1 << 10) - -/// iSCSI main global data flags: SCSI emulation for I/O physical read only device. -#define ISCSI_GLOBALS_FLAGS_SCSI_IO_PHYSICAL_READ_ONLY (1 << 11) - -/// iSCSI main global data flags: SCSI emulation for I/O write protected device. -#define ISCSI_GLOBALS_FLAGS_SCSI_IO_WRITE_PROTECT (1 << 12) - -/// iSCSI main global data flags: SCSI emulation for I/O write cache device. -#define ISCSI_GLOBALS_FLAGS_SCSI_IO_WRITE_CACHE (1 << 13) - - -/// iSCSI main global data target name validation check level: None, allow everything. -#define ISCSI_GLOBALS_TARGET_NAME_CHECK_NONE 0 - -/// iSCSI main global data target name validation check level: Relaxed, check for maximum target name length and if target name starts with 'iqn.', 'naa.' or 'eui.' also check if target name only contains allowed characters. -#define ISCSI_GLOBALS_TARGET_NAME_CHECK_RELAXED 1 - -/// iSCSI main global data target name validation check level: Full, check for maximum target name length and always check target name only contains allowed characters. -#define ISCSI_GLOBALS_TARGET_NAME_CHECK_FULL 2 - - -/// iSCSI main global data: Default maximum number of connections. -#define ISCSI_GLOBALS_DEFAULT_MAX_CONNECTIONS 1UL - -/// iSCSI main global data: Default maximum number of outstanding ready to transfers. -#define ISCSI_GLOBALS_DEFAULT_MAX_OUTSTANDING_R2T 1UL - -/// iSCSI main global data: Default time to wait in seconds. -#define ISCSI_GLOBALS_DEFAULT_TIME_TO_WAIT 2UL - -/// iSCSI main global data: Default time to retain in seconds. -#define ISCSI_GLOBALS_DEFAULT_TIME_TO_RETAIN 20UL - -/// iSCSI main global data: First burst length in bytes. -#define ISCSI_GLOBALS_DEFAULT_FIRST_BURST_LEN ISCSI_DEFAULT_RECV_DS_LEN - -/// iSCSI main global data: Maximum burst length in bytes. -#define ISCSI_GLOBALS_DEFAULT_MAX_BURST_LEN (ISCSI_DEFAULT_MAX_RECV_DS_LEN * ISCSI_DEFAULT_MAX_DATA_OUT_PER_CONNECTION) - -/// iSCSI main global data: Default error recovery level. -#define ISCSI_GLOBALS_DEFAULT_ERR_RECOVERY_LEVEL 0UL - - -/** - * @brief This is the main global iSCSI structure which manages all global data. - * - * All iSCSI portal groups, target nodes, sessions and - * connections are stored here for global access. - */ -typedef struct iscsi_globals { - /// Hash map containing all iSCSI devices. - iscsi_hashmap *devices; - - /// Read/write lock for hash map containing all iSCSI devices. MUST be initialized with iscsi_create before any iSCSI functions are used. - pthread_rwlock_t devices_rwlock; - - /// Hash map containing all registered iSCSI portal groups. - iscsi_hashmap *portal_groups; - - /// Read/write lock for hash map containing all iSCSI portal_groups. MUST be initialized with iscsi_create before any iSCSI functions are used. - pthread_rwlock_t portal_groups_rwlock; - - /// iSCSI target nodes. - iscsi_hashmap *target_nodes; - - /// Read/write lock for hash map containing all iSCSI target nodes. MUST be initialized with iscsi_create before any iSCSI functions are used. - pthread_rwlock_t target_nodes_rwlock; - - /// Hash map containing all iSCSI sessions. - iscsi_hashmap *sessions; - - /// Read/write lock for hash map containing all iSCSI sessions. MUST be initialized with iscsi_create before any iSCSI functions are used. - pthread_rwlock_t sessions_rwlock; - - /// Hash map containing session key and value pair types and allowed values or ranges. - iscsi_hashmap *session_key_value_pairs; - - /// Hash map containing connection key and value pair types and allowed values or ranges. - iscsi_hashmap *connection_key_value_pairs; - - /// Hash map containing iSCSI SCSI device specific configuration. - iscsi_hashmap *scsi_device_config; - - /// Mutex for hash map containing iSCSI SCSI device specific configuration. - pthread_mutex_t scsi_device_config_mutex; - - /// Global flags. - int flags; - - /// Target name validation check level. - int target_name_check; - - /// Maximum number of allowed sessions. - uint max_sessions; - - /// iHeader digest (CRC32), always MUST be 0 or 4 for now. - int header_digest; - - /// Data digest (CRC32), always MUST be 0 or 4 for now. - int data_digest; - - /// SCSI emulation: Device type. - uint scsi_device_type; - - /// Maximum receive DataSegment length in bytes. - uint32_t max_recv_ds_len; - - /// Maximum number of connections per session. - uint32_t max_session_conns; - - /// Ready to transfer maximum outstanding value. - uint32_t max_outstanding_r2t; - - /// Default time to wait. - uint32_t default_time_to_wait; - - /// Default time to retain. - uint32_t default_time_to_retain; - - /// First burst length. - uint32_t first_burst_len; - - /// Maximum burst length. - uint32_t max_burst_len; - - /// Error recovery level. - uint32_t err_recovery_level; - - /// CHAP group id. - int32_t chap_group; - - /// SCSI emulation: Physical block size. - uint32_t scsi_physical_block_size; - - /// SCSI emulation: Physical block size shift count. - uint32_t scsi_physical_block_size_shift; - - /// SCSI emulation: Logical block size. - uint32_t scsi_logical_block_size; - - /// SCSI emulation: Logical block size shift count. - uint32_t scsi_logical_block_size_shift; -} iscsi_globals; - - -/// Reference to iSCSI global vector. MUST be initialized with iscsi_create before any iSCSI functions are used. -extern iscsi_globals *iscsi_globvec; - -/// Read/write lock for iSCSI global vector. MUST be initialized with iscsi_create before any iSCSI functions are used. -extern pthread_rwlock_t iscsi_globvec_rwlock; - - -int iscsi_create(); // Allocates and initializes the iSCSI global vector structure -void iscsi_destroy(); // Deallocates all resources acquired by iscsi_create - -int iscsi_config_load(iscsi_globals *globvec); // Loads iSCSI server configuration from INI file -int iscsi_config_get_callback(uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *user_data); // Finds an iSCSI SCSI device configuration by name using pattern matching -int32_t iscsi_config_get(uint8_t *name, const int type); // Retrieves a configuration value either from the iSCSI global vector or for a specified SCSI device name - - -/** - * @brief iSCSI portal group: Private portal group if set, public otherwise. - * - * When redirecting logins, there are two portal group types: public and - * private.\n - * Public portal groups return their portals during discovery session. - * A redirection private portal may also be specified for non-discovery - * logins.\n - * Private portal groups instead do not return their portals during - * the discovery session. - */ -#define ISCSI_PORTAL_GROUP_PRIVATE (1 << 0) - -/// iSCSI portal group: CHAP authentication is disabled. -#define ISCSI_PORTAL_GROUP_CHAP_DISABLE (1 << 1) - -/// iSCSI portal group: CHAP authentication is required. -#define ISCSI_PORTAL_GROUP_CHAP_REQUIRE (1 << 2) - -/// iSCSI portal group: CHAP authentication is mutual. -#define ISCSI_PORTAL_GROUP_CHAP_MUTUAL (1 << 3) - +typedef struct iscsi_connection iscsi_connection; /** - * @brief iSCSI portal group. + * @brief iSCSI Text / Login key=value packet data construction helper. * - * Portal groups are either public or private and also are used - * by CHAP authentication. + * This structure is used to store the key=value plus NUL terminator + * pairs for sending as DataSegment packet data to the client. */ -typedef struct iscsi_portal_group { - /// Hash map containing all portals associated with this iSCSI group. - iscsi_hashmap *portals; - - /// Tag value for this portal group. - uint64_t tag; - - /// Reference count. - int ref_count; +typedef struct iscsi_key_value_pair_packet { + /// Associated iSCSI connection. + iscsi_connection *conn; - /// Portal group flags. - int flags; + /// Current text buffer containing multiple key=value + NUL terminator pairs. + uint8_t *buf; - /// CHAP group id. - int32_t chap_group; -} iscsi_portal_group; + /// Position of output buffer for next write. + uint32_t pos; + /// Current length of buffer including final NUL terminator without iSCSI zero padding. + uint32_t len; -/** - * @brief iSCSI portal. - * - * iSCSI portals manage the host / IP address and port, as well - * as the associated connections. - */ -typedef struct iscsi_portal { - /// Group this portal belongs to. - iscsi_portal_group *group; + /// Discovery mode. + int discovery; +} iscsi_key_value_pair_packet; - /// Hostname / IP address of the portal. - uint8_t *host; +/// iSCSI main global data flags: Allow duplicate ISIDs. +#define ISCSI_GLOBALS_FLAGS_ISID_ALLOW_DUPLICATES (1 << 0) - /// Port of the portal. - uint8_t *port; +/// iSCSI main global data flags: CHAP authentication is disabled. +#define ISCSI_GLOBALS_FLAGS_CHAP_DISABLE (1 << 1) - /// TCP/IP socket for the portal. - int sock; -} iscsi_portal; +/// iSCSI main global data flags: CHAP authentication is required. +#define ISCSI_GLOBALS_FLAGS_CHAP_REQUIRE (1 << 2) +/// iSCSI main global data flags: CHAP authentication is mutual. +#define ISCSI_GLOBALS_FLAGS_CHAP_MUTUAL (1 << 3) -iscsi_portal_group *iscsi_portal_group_create(const uint64_t tag, const int flags); // Creates and initializes an iSCSI portal group -int iscsi_portal_group_destroy_callback(uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *user_data); // iSCSI portal group destructor callback for hash map -void iscsi_portal_group_destroy(iscsi_portal_group *portal_group); // Deallocates resources acquired by iscsi_portal_group_create -int iscsi_portal_group_add_portal(iscsi_portal_group *portal_group, iscsi_portal *portal); // Adds an iSCSI portal to the iSCSI portal group hash map -void iscsi_portal_group_del_portal(iscsi_portal_group *portal_group, iscsi_portal *portal); // Removes an iSCSI portal from the iSCSI portal group hash map -iscsi_portal *iscsi_portal_create(const uint8_t *host, const uint8_t *port); // Allocates and initializes an iSCSI portal structure -int iscsi_portal_destroy_callback(uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *user_data); // iSCSI portal destructor callback for hash map -void iscsi_portal_destroy(iscsi_portal *portal); +/// Read/write lock for iSCSI global vector. MUST be initialized with iscsi_create before any iSCSI functions are used. +//extern pthread_rwlock_t iscsi_globvec_rwlock; /// iSCSI SCSI status code: Good. @@ -10531,711 +5763,277 @@ void iscsi_portal_destroy(iscsi_portal *portal); /// iSCSI SCSI Additional Sense Code (ASC): Block reference tag check failed. #define ISCSI_SCSI_ASC_LOGICAL_BLOCK_REF_TAG_CHECK_FAIL 0x10 -/// iSCSI SCSI Additional Sense Code (ASC): Unrecovered read error. -#define ISCSI_SCSI_ASC_UNRECOVERED_READ_ERR 0x11 - -/// iSCSI SCSI Additional Sense Code (ASC): Miscompare during verify operation. -#define ISCSI_SCSI_ASC_MISCOMPARE_DURING_VERIFY_OPERATION 0x1D - -/// iSCSI SCSI Additional Sense Code (ASC): Invalid command operation code. -#define ISCSI_SCSI_ASC_INVALID_COMMAND_OPERATION_CODE 0x20 - -/// iSCSI SCSI Additional Sense Code (ASC): Access denied. -#define ISCSI_SCSI_ASC_ACCESS_DENIED 0x20 - -/// iSCSI SCSI Additional Sense Code (ASC): Logical block address out of range. -#define ISCSI_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21 - -/// iSCSI SCSI Additional Sense Code (ASC): Invalid field in CDB. -#define ISCSI_SCSI_ASC_INVALID_FIELD_IN_CDB 0x24 - -/// iSCSI SCSI Additional Sense Code (ASC): Logical unit not supported. -#define ISCSI_SCSI_ASC_LU_NOT_SUPPORTED 0x25 - -/// iSCSI SCSI Additional Sense Code (ASC): Write protected. -#define ISCSI_SCSI_ASC_WRITE_PROTECTED 0x27 - -/// iSCSI SCSI Additional Sense Code (ASC): Data has changed. -#define ISCSI_SCSI_ASC_CAPACITY_DATA_HAS_CHANGED 0x2A - -/// iSCSI SCSI Additional Sense Code (ASC): Format command failed. -#define ISCSI_SCSI_ASC_FORMAT_COMMAND_FAIL 0x31 - -/// iSCSI SCSI Additional Sense Code (ASC): Saving parameters not supported. -#define ISCSI_SCSI_ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39 - -/// iSCSI SCSI Additional Sense Code (ASC): Internal target failure. -#define ISCSI_SCSI_ASC_INTERNAL_TARGET_FAIL 0x44 - - -/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): Cause not reportable. -#define ISCSI_SCSI_ASCQ_CAUSE_NOT_REPORTABLE 0x00 - -/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): Becoming ready. -#define ISCSI_SCSI_ASCQ_BECOMING_READY 0x01 - -/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): Format command failed. -#define ISCSI_SCSI_ASCQ_FORMAT_COMMAND_FAIL 0x01 - -/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): Block guard check failed. -#define ISCSI_SCSI_ASCQ_LOGICAL_BLOCK_GUARD_CHECK_FAIL 0x01 - -/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): Block application tag check failed. -#define ISCSI_SCSI_ASCQ_LOGICAL_BLOCK_APP_TAG_CHECK_FAIL 0x02 - -/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): No access rights. -#define ISCSI_SCSI_ASCQ_NO_ACCESS_RIGHTS 0x02 - -/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): Manual intervention required. -#define ISCSI_SCSI_ASCQ_MANUAL_INTERVENTION_REQUIRED 0x03 - -/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): Block reference tag check failed. -#define ISCSI_SCSI_ASCQ_LOGICAL_BLOCK_REF_TAG_CHECK_FAIL 0x03 - -/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): Power loss expected. -#define ISCSI_SCSI_ASCQ_POWER_LOSS_EXPECTED 0x08 - -/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): Invalid logical unit identifier. -#define ISCSI_SCSI_ASCQ_INVALID_LU_IDENTIFIER 0x09 - -/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): Capacity data has changed. -#define ISCSI_SCSI_ASCQ_CAPACITY_DATA_HAS_CHANGED 0x09 - - -typedef struct iscsi_port iscsi_port; - - -/** - * @brief iSCSI SCSI Persistent Reservation (PR) registrant with I_T nexus. - * - * I_T nexus is a nexus which exists between an initiator and a - * target. - */ -typedef struct iscsi_scsi_pr_registrant { - /// Target iSCSI port. - iscsi_port *target_port; - - /// Target iSCSI port name. - uint8_t *target_name; - - /// Initiator iSCSI port. - iscsi_port *init_port; - - /// Initiator iSCSI port name. - uint8_t *init_name; - - /// Transport ID. - iscsi_transport_id *transport_id; - - /// Reservation key. - uint64_t r_key; - - /// Relative target port identifier. - uint16_t rel_target_port_id; - - /// Transport ID length. - uint16_t transport_id_len; -} iscsi_scsi_pr_registrant; - - -/// iSCSI SCSI Persistent Reservation (PR) reservation type: Write exclusive. -#define ISCSI_SCSI_PR_RESERVATION_TYPE_WRITE_EXCLUSIVE 0x01 - -/// iSCSI SCSI Persistent Reservation (PR) reservation type: Exclusive access. -#define ISCSI_SCSI_PR_RESERVATION_TYPE_EXCLUSIVE_ACCESS 0x03 - -/// iSCSI SCSI Persistent Reservation (PR) reservation type: Write exclusive - registrants only. -#define ISCSI_SCSI_PR_RESERVATION_TYPE_WRITE_EXCLUSIVE_REGS_ONLY 0x05 - -/// iSCSI SCSI Persistent Reservation (PR) reservation type: Exclusive access - registrants only. -#define ISCSI_SCSI_PR_RESERVATION_TYPE_EXCLUSIVE_ACCESS_REGS_ONLY 0x06 - -/// iSCSI SCSI Persistent Reservation (PR) reservation type: Write exclusive - all registrants. -#define ISCSI_SCSI_PR_RESERVATION_TYPE_WRITE_EXCLUSIVE_ALL_REGS 0x07 - -/// iSCSI SCSI Persistent Reservation (PR) reservation type: Exclusive access - all registrants. -#define ISCSI_SCSI_PR_RESERVATION_TYPE_EXCLUSIVE_ACCESS_ALL_REGS 0x08 - - -/// iSCSI SCSI Persistent Reservation (PR) reservation flags: SPC2 reserve. -#define ISCSI_SCSI_PR_RESERVATION_FLAGS_SPC2_RESERVE (1L << 0L) - - -/** - * @brief iSCSI SCSI Persistent Reservation (PR) reservation with LU_SCOPE. - * - * LU_SCOPE means that Persistent Reservation (PR) scope - * applies to the full logical unit. - */ -typedef struct iscsi_scsi_pr_reservation { - /// Registrant for this reservation. - iscsi_scsi_pr_registrant *holder; - - /// Current reservation key. - uint64_t cr_key; - - /// Reservation type. - int type; - - /// Reservation flags. - int32_t flags; -} iscsi_scsi_pr_reservation; - - -/** - * @brief iSCSI SCSI Persistent Reservation (PR) registrant search by target and initiator port. - * - * This structure is used by iterating through - * all iSCSI LUN Persistent Reservation (PR) - * registrant's finding by target and initiator - * port. - */ -typedef struct iscsi_scsi_pr_registrant_get_reg { - /// Found iSCSI SCSI Persistent Reservation (PR) registrant is stored here, should be initialized to NULL. - iscsi_scsi_pr_registrant *reg; - - /// The target port to be searched for is stored here. - iscsi_port *target_port; - - /// The initiator port to be searched for is stored here. - iscsi_port *init_port; -} iscsi_scsi_pr_registrant_get_reg; - - -/// iSCSI SCSI task run: Unknown. -#define ISCSI_SCSI_TASK_RUN_UNKNOWN -1 - -/// iSCSI SCSI task run: Completed. -#define ISCSI_SCSI_TASK_RUN_COMPLETE 0 - -/// iSCSI SCSI task run: Pending. -#define ISCSI_SCSI_TASK_RUN_PENDING 1 - - -typedef struct iscsi_scsi_task iscsi_scsi_task; -typedef struct iscsi_scsi_lun iscsi_scsi_lun; - - -/** - * @brief Callback when iSCSI SCSI transfer task completed. - * - * This function is invoked when an iSCSI task - * finished a transfer. - * - * @param[in] scsi_task Pointer to iSCSI SCSI task which - * completed the transfer and may NOT be NULL, - * so be careful. - */ -typedef void (*iscsi_scsi_task_xfer_complete_callback)(iscsi_scsi_task *scsi_task); - -/** - * @brief Callback when iSCSI SCSI transfer task destruction. - * - * This function is invoked when an iSCSI task - * needs to be destroyed. - * - * @param[in] scsi_task Pointer to iSCSI SCSI task which - * is about to be destroyed and may NOT be - * NULL, so be careful. - */ -typedef void (*iscsi_scsi_task_destroy_callback)(iscsi_scsi_task *scsi_task); - -/** - * @brief Callback for I/O operation completion. - * - * This function is invoked when an I/O operation - * has been completed. - * - * @param[in] image Pointer to DNBD3 image which completed the - * I/O operation. - * @param[in] user_data Pointer to user data. - * @param[in] success true if I/O completed successfully or false - * if it failed instead. - * @return Pointer to passed user data. - */ -typedef uint8_t *(*iscsi_scsi_emu_io_complete_callback)(dnbd3_image_t *image, uint8_t *user_data, const bool success); - -/** - * @brief Callback for I/O wait operation. - * - * This function is invoked when an I/O - * operation needs waiting. - * - * @param[in] user_data Pointer to user data. - * @return Pointer to passed user data. - */ -typedef uint8_t *(*iscsi_scsi_emu_io_wait_callback)(uint8_t *user_data); - - -typedef struct iscsi_scsi_emu_io_wait { - /// I/O task wait callback associated DNBD3 image. - dnbd3_image_t *image; - - /// I/O task wait callback function. - iscsi_scsi_emu_io_wait_callback callback; - - /// I/O task wait callback user data. - uint8_t *user_data; -} iscsi_scsi_emu_io_wait; - - -/// iSCSI SCSI task flags: Read. -#define ISCSI_SCSI_TASK_FLAGS_XFER_READ (1 << 0) - -/// iSCSI SCSI task flags: Write. -#define ISCSI_SCSI_TASK_FLAGS_XFER_WRITE (1 << 1) - - -/** - * @brief iSCSI SCSI Task. - * - * This structure is used for the iSCSI SCSI - * layer task management. - */ -typedef struct iscsi_scsi_task { - /// Doubly linked list node, MUST be first element. - iscsi_node node; - - /// SCSI LUN associated with this task. - iscsi_scsi_lun *lun; - - /// Target iSCSI port. - iscsi_port *target_port; - - /// Initiator iSCSI port. - iscsi_port *init_port; - - /// SCSI Command Descriptor Block (CDB). - iscsi_scsi_cdb *cdb; - - /// SCSI sense data. - iscsi_scsi_sense_data_packet *sense_data; - - /// Transfer complete callback function. - iscsi_scsi_task_xfer_complete_callback xfer_complete_callback; - - /// Task destruction callback function. - iscsi_scsi_task_destroy_callback destroy_callback; - - /// I/O task complete callback function. - iscsi_scsi_emu_io_complete_callback io_complete_callback; - - /// I/O task wait. - iscsi_scsi_emu_io_wait io_wait; - - /// Uplink read mutex for synchronization. - pthread_mutex_t uplink_mutex; - - /// Conditional to signal uplink read complete. - pthread_cond_t uplink_cond; - - /// Output buffer. - uint8_t *buf; - - /// Position of buffer in bytes. - uint32_t pos; - - /// Length of buffer in bytes. - uint32_t len; - - /// Unique identifier for this task. - uint64_t id; - - /// Flags. - int flags; - - /// Reference counter. - uint32_t ref; - - /// Transfer position in bytes. - uint32_t xfer_pos; - - /// Transfer length in bytes. - uint32_t xfer_len; - - /// Sense data length. - uint8_t sense_data_len; - - /// iSCSI SCSI status code. - uint8_t status; - - /// Task management function. - uint8_t task_mgmt_func; - - /// Task management response code. - uint8_t task_mgmt_response; -} iscsi_scsi_task; - - -/// iSCSI SCSI emulation physical block size in bytes. -#define ISCSI_SCSI_EMU_PHYSICAL_BLOCK_SIZE 4096UL - -/// iSCSI SCSI emulation logical block size in bytes. -#define ISCSI_SCSI_EMU_BLOCK_SIZE 512UL - - -/// iSCSI SCSI emulation maximum tansfer length in logical blocks. -#define ISCSI_SCSI_EMU_MAX_XFER_LEN (ISCSI_DEFAULT_MAX_RECV_DS_LEN * ISCSI_DEFAULT_MAX_DATA_OUT_PER_CONNECTION) - -/// iSCSI SCSI emulation maximum UNMAP LBA count in LBAs. -#define ISCSI_SCSI_EMU_MAX_UNMAP_LBA_COUNT (ISCSI_DEFAULT_MAX_RECV_DS_LEN * ISCSI_DEFAULT_MAX_DATA_IN_PER_CONNECTION) - -/// iSCSI SCSI emulation maximum UNMAP block descriptor count in block descriptors. -#define ISCSI_SCSI_EMU_MAX_UNMAP_BLOCK_DESC_COUNT 256UL - - -/// iSCSI SCSI emulation I/O type: Removable. -#define ISCSI_SCSI_EMU_IO_TYPE_REMOVABLE (1 << 0) - -/// iSCSI SCSI emulation I/O type: Unmap. -#define ISCSI_SCSI_EMU_IO_TYPE_UNMAP (1 << 1) - -/// iSCSI SCSI emulation I/O type: Non-rotating medium (e.g., solid state). -#define ISCSI_SCSI_EMU_IO_TYPE_NO_ROTATION (1 << 2) - -/// iSCSI SCSI emulation I/O type: Physical read only device. -#define ISCSI_SCSI_EMU_IO_TYPE_PHYSICAL_READ_ONLY (1 << 3) - -/// iSCSI SCSI emulation I/O type: Device is (temporarily) write protected. -#define ISCSI_SCSI_EMU_IO_TYPE_WRITE_PROTECT (1 << 4) - -/// iSCSI SCSI emulation I/O type: Write cache available. -#define ISCSI_SCSI_EMU_IO_TYPE_WRITE_CACHE (1 << 5) - - -/// iSCSI SCSI emulation block flags: Write operation. -#define ISCSI_SCSI_EMU_BLOCK_FLAGS_WRITE (1 << 0) - -/// iSCSI SCSI emulation block flags: Verify operation. -#define ISCSI_SCSI_EMU_BLOCK_FLAGS_VERIFY (1 << 1) - - -void iscsi_scsi_task_create(iscsi_scsi_task *scsi_task, iscsi_scsi_task_xfer_complete_callback xfer_complete_callback, iscsi_scsi_task_destroy_callback destroy_callback); // Allocates and initializes a SCSI task -void iscsi_scsi_task_destroy(iscsi_scsi_task *scsi_task); // Deallocates all resources acquired iscsi_scsi_task_create - -void iscsi_scsi_task_xfer_complete(iscsi_scsi_task *scsi_task); // Callback function when an iSCSI SCSI task completed the data transfer - -void iscsi_scsi_task_sense_data_check_cond_build(iscsi_scsi_task *scsi_task, const uint8_t sense_key, const uint8_t asc, const uint8_t ascq); // Allocates, if necessary and initializes SCSI sense data for check condition status code -int iscsi_scsi_task_status_copy(iscsi_scsi_task *dst_scsi_task, const iscsi_scsi_task *src_scsi_task); // Copies iSCSI SCSI task sense data and status code -void iscsi_scsi_task_lun_process_none(iscsi_scsi_task *scsi_task); // Processes a iSCSI SCSI task with no LUN identifier -void iscsi_scsi_task_lun_process_abort(iscsi_scsi_task *scsi_task); // Processes a iSCSI SCSI aborted task - -iscsi_scsi_lun *iscsi_scsi_lun_create(const int lun_id); // Allocates and initializes an iSCSI LUN structure for linkage with a DNBD3 image -int iscsi_scsi_lun_destroy_callback(uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *user_data); // iSCSI SCSI LUN destructor callback for hash map -void iscsi_scsi_lun_destroy(iscsi_scsi_lun *lun); // Deallocates all resources acquired by iscsi_scsi_lun_create - -uint64_t iscsi_scsi_lun_get_from_scsi(const int lun_id); // Converts an internal representation of a LUN identifier to an iSCSI LUN required for packet data -int iscsi_scsi_lun_get_from_iscsi(const uint64_t lun); // Converts an iSCSI LUN from packet data to internal SCSI LUN identifier - -void iscsi_scsi_lun_task_append(iscsi_scsi_lun *lun, iscsi_scsi_task *scsi_task); // Appends an iSCSI SCSI task to a iSCSI SCSI LUN pending tasks doubly linked list -void iscsi_scsi_lun_tasks_exec(iscsi_scsi_lun *lun); // Executes all iSCSI SCSI pending tasks assigned to a iSCSI SCSI LUN -void iscsi_scsi_lun_task_run(iscsi_scsi_lun *lun, iscsi_scsi_task *scsi_task); // Runs an iSCSI SCSI task for a specified iSCSI SCSI LUN -void iscsi_scsi_lun_task_complete(iscsi_scsi_lun *lun, iscsi_scsi_task *scsi_task); // Handles iSCSI SCSI task completition -void iscsi_scsi_lun_task_exec(iscsi_scsi_lun *lun, iscsi_scsi_task *scsi_task); // Appends iSCSI SCSI task to pending tasks doubly linked list and / or runs it directly +/// iSCSI SCSI Additional Sense Code (ASC): Unrecovered read error. +#define ISCSI_SCSI_ASC_UNRECOVERED_READ_ERR 0x11 -int iscsi_scsi_pr_check_scsi2(iscsi_scsi_task *scsi_task); // Checks the iSCSI SCSI Persistent Reservation (PR) SCSI-2 reserve of an iSCSI SCSI task -int iscsi_scsi_pr_registrant_get_callback(uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *user_data); // Finds an iSCSI SCSI Persistent Reservation (PR) registrant by target and initiator port -int iscsi_scsi_pr_check(iscsi_scsi_task *scsi_task); // Checks the iSCSI SCSI Persistent Reservation (PR) of an iSCSI SCSI task -int iscsi_scsi_pr_out(iscsi_scsi_task *scsi_task, iscsi_scsi_pr_reserve_out_parameter_list_packet *pr_reserve_out_parameter_list, const iscsi_scsi_cdb_pr_reserve_out *cdb_pr_reserve_out, const uint len); // Constructs an iSCSI SCSI Persistent Reservation (PR) out parameter list of an iSCSI SCSI task -int iscsi_scsi_pr_in(iscsi_scsi_task *scsi_task, iscsi_scsi_pr_reserve_in_parameter_data_packet *pr_reserve_in_parameter_data, const iscsi_scsi_cdb_pr_reserve_in *cdb_pr_reserve_in, const uint len); // Constructs iSCSI SCSI Persistent Reservation (PR) in parameter data of an iSCSI SCSI task -int iscsi_scsi_pr_reserve_scsi2(iscsi_scsi_task *scsi_task, const iscsi_scsi_cdb_pr_reserve_6 *cdb_pr_reserve_6); // Reserves an iSCSI SCSI Persistent Reservation (PR) of an iSCSI SCSI task -int iscsi_scsi_pr_release_scsi2(iscsi_scsi_task *scsi_task); // Releases an iSCSI SCSI Persistent Reservation (PR) of an iSCSI SCSI task +/// iSCSI SCSI Additional Sense Code (ASC): Miscompare during verify operation. +#define ISCSI_SCSI_ASC_MISCOMPARE_DURING_VERIFY_OPERATION 0x1D -int iscsi_scsi_emu_io_block_read(iscsi_scsi_task *scsi_task, dnbd3_image_t *image, const uint64_t offset_blocks, const uint64_t num_blocks, const uint32_t block_size, iscsi_scsi_emu_io_complete_callback callback, uint8_t *user_data); // Reads a number of blocks from a block offset of a DNBD3 image to a specified buffer -uint8_t *iscsi_scsi_emu_block_read_complete_callback(dnbd3_image_t *image, uint8_t *user_data, const bool success); // Completes an iSCSI SCSI task after a finished I/O read operation -int iscsi_scsi_emu_io_block_cmp_write(iscsi_scsi_task *scsi_task, uint8_t *cmp_buf, dnbd3_image_t *image, const uint64_t offset_blocks, const uint64_t num_blocks, const uint32_t block_size, iscsi_scsi_emu_io_complete_callback callback, uint8_t *user_data); // Compares and writes a number of blocks starting from a block offset in a DNBD3 image with specified buffers -uint8_t *iscsi_scsi_emu_block_write_complete_callback(dnbd3_image_t *image, uint8_t *user_data, const bool success); // Completes an iSCSI SCSI task after a finished I/O write operation -int iscsi_scsi_emu_io_block_write(iscsi_scsi_task *scsi_task, dnbd3_image_t *image, const uint64_t offset_blocks, const uint64_t num_blocks, const uint32_t block_size, iscsi_scsi_emu_io_complete_callback callback, uint8_t *user_data); // Writes a number of blocks from a block offset to a DNBD3 image of a specified buffer -int iscsi_scsi_emu_io_queue(iscsi_scsi_emu_io_wait *io_wait); // Enqueues an I/O wait in the thread pool to execute -uint8_t *iscsi_scsi_emu_block_resubmit_process_callback(uint8_t *user_data); // Resubmits an iSCSI SCSI task for execution +/// iSCSI SCSI Additional Sense Code (ASC): Invalid command operation code. +#define ISCSI_SCSI_ASC_INVALID_COMMAND_OPERATION_CODE 0x20 -int iscsi_scsi_emu_primary_inquiry_callback(uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *user_data); // Fills in a single Vital Product Data (VPD) SCSI Port Designation Descriptor entry of an INQUIRY operation -int iscsi_scsi_emu_exec(iscsi_scsi_task *scsi_task); // Executes the iSCSI SCSI emulation for an iSCSI SCSI task +/// iSCSI SCSI Additional Sense Code (ASC): Access denied. +#define ISCSI_SCSI_ASC_ACCESS_DENIED 0x20 +/// iSCSI SCSI Additional Sense Code (ASC): Logical block address out of range. +#define ISCSI_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21 -/// iSCSI port flags: In use. -#define ISCSI_PORT_FLAGS_IN_USE (1 << 0) +/// iSCSI SCSI Additional Sense Code (ASC): Invalid field in CDB. +#define ISCSI_SCSI_ASC_INVALID_FIELD_IN_CDB 0x24 +/// iSCSI SCSI Additional Sense Code (ASC): Logical unit not supported. +#define ISCSI_SCSI_ASC_LU_NOT_SUPPORTED 0x25 -/** - * @brief iSCSI port. - * - * This structure maintains the transport ID, - * name, identifiers and index of an ISCSI - * port. - */ -typedef struct iscsi_port { - /// Transport ID. - iscsi_transport_id *transport_id; +/// iSCSI SCSI Additional Sense Code (ASC): Write protected. +#define ISCSI_SCSI_ASC_WRITE_PROTECTED 0x27 - /// Name. - uint8_t *name; +/// iSCSI SCSI Additional Sense Code (ASC): Data has changed. +#define ISCSI_SCSI_ASC_CAPACITY_DATA_HAS_CHANGED 0x2A - /// Identifier. - uint64_t id; +/// iSCSI SCSI Additional Sense Code (ASC): Format command failed. +#define ISCSI_SCSI_ASC_FORMAT_COMMAND_FAIL 0x31 - /// Flags. - int flags; +/// iSCSI SCSI Additional Sense Code (ASC): Saving parameters not supported. +#define ISCSI_SCSI_ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39 - /// Index. - uint16_t index; +/// iSCSI SCSI Additional Sense Code (ASC): Internal target failure. +#define ISCSI_SCSI_ASC_INTERNAL_TARGET_FAIL 0x44 - /// Transport ID length. - uint16_t transport_id_len; -} iscsi_port; +/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): Cause not reportable. +#define ISCSI_SCSI_ASCQ_CAUSE_NOT_REPORTABLE 0x00 -iscsi_port *iscsi_port_create(const uint8_t *name, const uint64_t id, const uint16_t index); // Allocates and initializes an iSCSI port -int iscsi_port_destroy_callback(uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *user_data); // iSCSI port destructor callback for hash map -void iscsi_port_destroy(iscsi_port *port); // Deallocates all resource acquired iscsi_port_create +/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): Becoming ready. +#define ISCSI_SCSI_ASCQ_BECOMING_READY 0x01 -uint8_t *iscsi_port_get_name(const iscsi_port *port); // Retrieves the name of an iSCSI port +/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): Format command failed. +#define ISCSI_SCSI_ASCQ_FORMAT_COMMAND_FAIL 0x01 -int iscsi_port_transport_id_set(iscsi_port *port, const uint8_t *name, const uint64_t isid); // Sets the SCSI transport ID of the iSCSI port +/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): Block guard check failed. +#define ISCSI_SCSI_ASCQ_LOGICAL_BLOCK_GUARD_CHECK_FAIL 0x01 +/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): Block application tag check failed. +#define ISCSI_SCSI_ASCQ_LOGICAL_BLOCK_APP_TAG_CHECK_FAIL 0x02 -/// iSCSI SCSI LUN flags: Removed. -#define ISCSI_SCSI_LUN_FLAGS_REMOVED (1 << 0) +/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): No access rights. +#define ISCSI_SCSI_ASCQ_NO_ACCESS_RIGHTS 0x02 -/// iSCSI SCSI LUN flags: Resizing. -#define ISCSI_SCSI_LUN_FLAGS_RESIZING (1 << 1) +/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): Manual intervention required. +#define ISCSI_SCSI_ASCQ_MANUAL_INTERVENTION_REQUIRED 0x03 +/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): Block reference tag check failed. +#define ISCSI_SCSI_ASCQ_LOGICAL_BLOCK_REF_TAG_CHECK_FAIL 0x03 -typedef struct iscsi_device iscsi_device; +/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): Power loss expected. +#define ISCSI_SCSI_ASCQ_POWER_LOSS_EXPECTED 0x08 +/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): Invalid logical unit identifier. +#define ISCSI_SCSI_ASCQ_INVALID_LU_IDENTIFIER 0x09 -/** - * @brief iSCSI SCSI LUN. - * - * This structure managesw the SCSI - * LUNs attached to an iSCSI device - * and associates a disk image file. - */ -typedef struct iscsi_scsi_lun { - /// Doubly linked list containing associated tasks with this LUN. - iscsi_list tasks; +/// iSCSI SCSI Additional Sense Code Qualifier (ASCQ): Capacity data has changed. +#define ISCSI_SCSI_ASCQ_CAPACITY_DATA_HAS_CHANGED 0x09 - /// Mutex for accessing the associated tasks through multiple threads. - pthread_mutex_t tasks_mutex; - /// Doubly linked list containing associated pending tasks with this LUN. - iscsi_list tasks_pending; - /// Mutex for accessing the associated pending tasks through multiple threads. - pthread_mutex_t tasks_pending_mutex; +/// iSCSI SCSI Persistent Reservation (PR) reservation type: Write exclusive. +#define ISCSI_SCSI_PR_RESERVATION_TYPE_WRITE_EXCLUSIVE 0x01 - /// Doubly linked list containing associated management tasks with this LUN. - iscsi_list tasks_mgmt; +/// iSCSI SCSI Persistent Reservation (PR) reservation type: Exclusive access. +#define ISCSI_SCSI_PR_RESERVATION_TYPE_EXCLUSIVE_ACCESS 0x03 - /// Mutex for accessing the associated management tasks through multiple threads. - pthread_mutex_t tasks_mgmt_mutex; +/// iSCSI SCSI Persistent Reservation (PR) reservation type: Write exclusive - registrants only. +#define ISCSI_SCSI_PR_RESERVATION_TYPE_WRITE_EXCLUSIVE_REGS_ONLY 0x05 - /// Doubly linked list containing associated management pending tasks with this LUN. - iscsi_list tasks_mgmt_pending; +/// iSCSI SCSI Persistent Reservation (PR) reservation type: Exclusive access - registrants only. +#define ISCSI_SCSI_PR_RESERVATION_TYPE_EXCLUSIVE_ACCESS_REGS_ONLY 0x06 - /// Mutex for accessing the associated management pending tasks through multiple threads. - pthread_mutex_t tasks_mgmt_pending_mutex; +/// iSCSI SCSI Persistent Reservation (PR) reservation type: Write exclusive - all registrants. +#define ISCSI_SCSI_PR_RESERVATION_TYPE_WRITE_EXCLUSIVE_ALL_REGS 0x07 - /// Doubly linked list containg Persistent Reservation (PR) registrant for I_T nexus. - iscsi_hashmap *pr_regs; +/// iSCSI SCSI Persistent Reservation (PR) reservation type: Exclusive access - all registrants. +#define ISCSI_SCSI_PR_RESERVATION_TYPE_EXCLUSIVE_ACCESS_ALL_REGS 0x08 - /// Persistent Reservation (PR) for the LUN. - iscsi_scsi_pr_reservation pr_reservation; - /// Persistent Reservation (PR) holder for SPC2 RESERVE(6) and RESERVE(10). - iscsi_scsi_pr_registrant pr_scsi2_holder; +/// iSCSI SCSI Persistent Reservation (PR) reservation flags: SPC2 reserve. +#define ISCSI_SCSI_PR_RESERVATION_FLAGS_SPC2_RESERVE (1L << 0L) - /// iSCSI device which belongs to this LUN. - iscsi_device *device; - /// Assocated DNBD3 image for this LUN. - dnbd3_image_t *image; +/// iSCSI SCSI task run: Unknown. +#define ISCSI_SCSI_TASK_RUN_UNKNOWN -1 - /// LUN identifier (always MUST be between 0 and 7). - int id; +/// iSCSI SCSI task run: Completed. +#define ISCSI_SCSI_TASK_RUN_COMPLETE 0 - /// Flags. - int flags; +/// iSCSI SCSI task run: Pending. +#define ISCSI_SCSI_TASK_RUN_PENDING 1 - /// Persistent Reservation (PR) generation. - uint32_t pr_gen; -} iscsi_scsi_lun; +typedef struct iscsi_scsi_task iscsi_scsi_task; +typedef struct iscsi_scsi_lun iscsi_scsi_lun; -/// iSCSI device flags: Allocated. -#define ISCSI_DEVICE_FLAGS_ALLOCATED (1 << 0) +/// iSCSI SCSI task flags: Read. +#define ISCSI_SCSI_TASK_FLAGS_XFER_READ (1 << 0) -/// iSCSI device flags: Removed. -#define ISCSI_DEVICE_FLAGS_REMOVED (1 << 1) +/// iSCSI SCSI task flags: Write. +#define ISCSI_SCSI_TASK_FLAGS_XFER_WRITE (1 << 1) /** - * @brief iSCSI device. + * @brief iSCSI SCSI Task. * - * This structure managesw the SCSI - * devices and associates the - * disk image files with them. + * This structure is used for the iSCSI SCSI + * layer task management. */ -typedef struct iscsi_device { - /// Name of device. - uint8_t *name; +typedef struct iscsi_scsi_task { + /// Connection associated with this task. + iscsi_connection *connection; - /// LUNs associated with this device. - iscsi_hashmap *luns; + /// SCSI Command Descriptor Block (CDB). + iscsi_scsi_cdb *cdb; - /// Read/write lock for hash map containing all LUNs associated with this device. MUST be initialized with iscsi_create before any iSCSI functions are used. - pthread_rwlock_t luns_rwlock; + /// SCSI sense data. + iscsi_scsi_sense_data_packet *sense_data; - /// Ports associated with this device. - iscsi_hashmap *ports; + /// Output buffer. + uint8_t *buf; - /// Device identifier. - int id; + /// Position of buffer in bytes. + uint32_t pos; - /// Flags. - int flags; + /// Length of buffer in bytes. + uint32_t len; - /// Number of active connections for this device. - uint32_t active_conns; + /// Unique identifier for this task. + uint64_t id; - /// Protocol identifier. - uint8_t protocol_id; -} iscsi_device; + /// Flags. + int flags; + /// Transfer position in bytes. + uint32_t xfer_pos; -/// iSCSI target node maximum length. -#define ISCSI_TARGET_NODE_MAX_NAME_LEN 223U + /// Transfer length in bytes. + uint32_t xfer_len; + /// Sense data length. + uint8_t sense_data_len; -/// iSCSI target node IQN identifier prefix string. -#define ISCSI_TARGET_NODE_NAME_IQN_PREFIX "iqn." + /// iSCSI SCSI status code. + uint8_t status; -/// iSCSI target node IEEE NAA identifier prefix string. -#define ISCSI_TARGET_NODE_NAME_NAA_PREFIX "naa." + /// Uplink read mutex for sync + pthread_mutex_t uplink_mutex; -/// iSCSI target node EUI identifier prefix string. -#define ISCSI_TARGET_NODE_NAME_EUI_PREFIX "eui." + /// Conditional to signal uplink read complete + pthread_cond_t uplink_cond; +} iscsi_scsi_task; -/// iSCSI target node WWN identifier prefix string. -#define ISCSI_TARGET_NODE_NAME_WWN_PREFIX "wwn-0x" +/// iSCSI SCSI emulation physical block size in bytes. +#define ISCSI_SCSI_EMU_PHYSICAL_BLOCK_SIZE DNBD3_BLOCK_SIZE +/// iSCSI SCSI emulation logical block size in bytes. +#define ISCSI_SCSI_EMU_BLOCK_SIZE (512) -/// iSCSI target node flags: CHAP authentication disabled. -#define ISCSI_TARGET_NODE_FLAGS_CHAP_DISABLE (1 << 0) +/// Block shift difference between dnbd3 (4k) and iSCSI (512b) +#define ISCSI_SCSI_EMU_BLOCK_DIFF_SHIFT (3) -/// iSCSI target node flags: CHAP authentication required. -#define ISCSI_TARGET_NODE_FLAGS_CHAP_REQUIRE (1 << 1) +/// iSCSI SCSI emulation I/O type: Removable. +#define ISCSI_SCSI_EMU_IO_TYPE_REMOVABLE (1 << 0) -/// iSCSI target node flags: CHAP authentication mutual. -#define ISCSI_TARGET_NODE_FLAGS_CHAP_MUTUAL (1 << 2) +/// iSCSI SCSI emulation I/O type: Unmap. +#define ISCSI_SCSI_EMU_IO_TYPE_UNMAP (1 << 1) -/// iSCSI target node flags: Destroyed. -#define ISCSI_TARGET_NODE_FLAGS_DESTROYED (1 << 3) +/// iSCSI SCSI emulation I/O type: Non-rotating medium (e.g., solid state). +#define ISCSI_SCSI_EMU_IO_TYPE_NO_ROTATION (1 << 2) +/// iSCSI SCSI emulation I/O type: Physical read only device. +#define ISCSI_SCSI_EMU_IO_TYPE_PHYSICAL_READ_ONLY (1 << 3) -/** - * @brief iSCSI target node. - * - * This structure maintains the name, alias, - * associated device and connection data - * for a specific iSCSI target node. - */ -typedef struct iscsi_target_node { - /// Name of target node. - uint8_t *name; +/// iSCSI SCSI emulation I/O type: Device is (temporarily) write protected. +#define ISCSI_SCSI_EMU_IO_TYPE_WRITE_PROTECT (1 << 4) - /// Alias name of target node. - uint8_t *alias; - /// Associated iSCSI device. - iscsi_device *device; +/// iSCSI SCSI emulation block flags: Write operation. +#define ISCSI_SCSI_EMU_BLOCK_FLAGS_WRITE (1 << 0) + +/// iSCSI SCSI emulation block flags: Verify operation. +#define ISCSI_SCSI_EMU_BLOCK_FLAGS_VERIFY (1 << 1) - /// Target node number. - uint num; - /// Queue depth. - uint queue_depth; - /// Flags. - int flags; +/// iSCSI target node WWN identifier prefix string. +#define ISCSI_TARGET_NODE_WWN_NAME_PREFIX "wwn-0x" - /// Header digest size (always MUST be 0 or 4 for now). - int header_digest; +/// iSCSI target node maximum length +#define ISCSI_TARGET_NODE_MAX_NAME_LEN 223U - /// Data digest size (always MUST be 0 or 4 for now). - int data_digest; - /// CHAP group ID. - int32_t chap_group; +/// iSCSI session type: Invalid. +#define ISCSI_SESSION_TYPE_INVALID 0 - /// Number of active connections for this target node. - uint32_t active_conns; -} iscsi_target_node; +/// iSCSI session type: Normal. +#define ISCSI_SESSION_TYPE_NORMAL 1 +/// iSCSI session type: Discovery. +#define ISCSI_SESSION_TYPE_DISCOVERY 2 /** - * @brief iSCSI target node search by name. - * - * This structure is used by iterating through - * all iSCSI target nodes finding by name. + * All mandatory fields in login process. + * Set to -1 or NULL if not sent by client. */ -typedef struct iscsi_target_node_find_name { - /// Found iSCSI target node is stored here, should be initialized to NULL. - iscsi_target_node *target; - - /// The name of the target node to search for. - uint8_t *name; -} iscsi_target_node_find_name; - - -/// iSCSI authentication CHAP phase: None. -#define ISCSI_AUTH_CHAP_PHASE_NONE 0 - -/// iSCSI authentication CHAP phase: Wait A. -#define ISCSI_AUTH_CHAP_PHASE_WAIT_A 1 +typedef struct iscsi_login_kvp +{ + /// Largest PDU client can receive. + int MaxRecvDataSegmentLength; -/// iSCSI authentication CHAP phase: Wait NR. -#define ISCSI_AUTH_CHAP_PHASE_WAIT_NR 2 + /// Maximum burst length client can receive. + int MaxBurstLength; -/// iSCSI authentication CHAP phase: End. -#define ISCSI_AUTH_CHAP_PHASE_END 3 + // Maximum unsolicited burst length client can receive. + int FirstBurstLength; + /// Maximum number of connections. + int MaxConnections; -/** - * @brief iSCSI CHAP authentication data structure. - * - * This structure maintains all data required for - * CHAP authentication method. - */ -typedef struct iscsi_auth_chap { - /// CHAP phase. - int phase; -} iscsi_auth_chap; + /// Error recovery level. + int ErrorRecoveryLevel; + /// The session type (Discovery, Normal). + const char *SessionType; -/// iSCSI session flags: Initial ready to transfer. -#define ISCSI_SESSION_FLAGS_INIT_R2T (1 << 0) + /// Desired auth method. + const char *AuthMethod; -/// iSCSI session flags: Immediate data. -#define ISCSI_SESSION_FLAGS_IMMEDIATE_DATA (1 << 1) + /// SendTargets command. + const char *SendTargets; -/// iSCSI session flags: Data PDU in order. -#define ISCSI_SESSION_FLAGS_DATA_PDU_IN_ORDER (1 << 2) + /// HeaderDigest requested by client. + const char *HeaderDigest; -/// iSCSI session flags: Data sequence in order. -#define ISCSI_SESSION_FLAGS_DATA_SEQ_IN_ORDER (1 << 3) + /// DataDigest requested by client. + const char *DataDigest; + const char *InitiatorName; -/// iSCSI session type: Invalid. -#define ISCSI_SESSION_TYPE_INVALID 0 + const char *TargetName; +} iscsi_negotiation_kvp; -/// iSCSI session type: Normal. -#define ISCSI_SESSION_TYPE_NORMAL 1 +/** + * Options/limits the client told us that + * are relevant for proper communication + */ +typedef struct iscsi_session_options +{ + /// Largest PDU client can receive. + int MaxRecvDataSegmentLength; -/// iSCSI session type: Discovery. -#define ISCSI_SESSION_TYPE_DISCOVERY 2 + /// Maximum burst length client can receive. + int MaxBurstLength; + // Maximum unsolicited burst length client can receive. + int FirstBurstLength; +} iscsi_session_options; /** * @brief iSCSI session. @@ -11245,68 +6043,29 @@ typedef struct iscsi_auth_chap { * login phase. */ typedef struct iscsi_session { - /// List of iSCSI connections associated with this session. - iscsi_list conn_list; - - /// Initiator port. - iscsi_port *init_port; - - /// Hash map of login key / value pairs negotiated with this session. - iscsi_hashmap *key_value_pairs; - - /// iSCSI target node. - iscsi_target_node *target; - - /// Portal group tag. - uint64_t tag; - - /// Initiator Session ID (ISID). - uint64_t isid; - - /// Target Session Identifying Handle (TSIH). - uint64_t tsih; - - /// Flags (extracted from key and value pairs). - int flags; - - /// Queue depth. - uint queue_depth; - - /// iSCSI session type. - int type; - - /// Number of active connections linked to this session. - uint32_t conns; - - /// Maximum number of connections. - uint32_t max_conns; - - /// Ready to transfer maximum outstanding value. - uint32_t max_outstanding_r2t; - - /// Default time to wait. - uint32_t default_time_to_wait; + /// Initiator Session ID (ISID). + uint64_t isid; - /// Default time to retain. - uint32_t default_time_to_retain; + /// Target Session Identifying Handle (TSIH). + uint64_t tsih; - /// First burst length. - uint32_t first_burst_len; + /// Flags (extracted from key and value pairs). + int flags; - /// Maximum burst length. - uint32_t max_burst_len; + /// iSCSI session type. + int type; - /// Error recovery level. - uint32_t err_recovery_level; + /// ExpCmdSN. + uint32_t exp_cmd_sn; - /// ExpCmdSN. - uint32_t exp_cmd_sn; + /// MaxCmdSN. + uint32_t max_cmd_sn; - /// MaxCmdSN. - uint32_t max_cmd_sn; + /// Current text Initiator Task Tag (ITT). + uint32_t current_text_init_task_tag; - /// Current text Initiator Task Tag (ITT). - uint32_t current_text_init_task_tag; + /// Session options client sent in login request. + iscsi_session_options opts; } iscsi_session; @@ -11320,16 +6079,16 @@ typedef struct iscsi_pdu iscsi_pdu; #define ISCSI_CONNECT_PDU_READ_PROCESSED 1 /// iSCSI connection read packet data return code from iscsi_connection_pdu_read function: Fatail error during packet parsing. -#define ISCSI_CONNECT_PDU_READ_ERR_FATAL -1 +#define ISCSI_CONNECT_PDU_READ_ERR_FATAL (-1) /// iSCSI connection read packet data return code from iscsi_connection_pdu_read function: Login error response. -#define ISCSI_CONNECT_PDU_READ_ERR_LOGIN_RESPONSE -2 +#define ISCSI_CONNECT_PDU_READ_ERR_LOGIN_RESPONSE (-2) /// iSCSI connection read packet data return code from iscsi_connection_pdu_read function: Login parameter error. -#define ISCSI_CONNECT_PDU_READ_ERR_LOGIN_PARAMETER -3 +#define ISCSI_CONNECT_PDU_READ_ERR_LOGIN_PARAMETER (-3) /// iSCSI connection read packet data return code from iscsi_connection_pdu_read function: Login parameter not exchanged once error. -#define ISCSI_CONNECT_PDU_READ_ERR_LOGIN_PARAMETER_XCHG_NOT_ONCE -4 +#define ISCSI_CONNECT_PDU_READ_ERR_LOGIN_PARAMETER_XCHG_NOT_ONCE (-4) /// iSCSI connection flags: Stopped. @@ -11399,258 +6158,59 @@ typedef struct iscsi_pdu iscsi_pdu; * and iSCSI portals. */ typedef struct iscsi_connection { - /// Doubly linked list node, MUST be first element. - iscsi_node node; - - /// iSCSI session associated with this connection. - iscsi_session *session; - - /// Hash map containing login text key / value pairs associated to this connection. - iscsi_hashmap *key_value_pairs; - - /// Temporarily storage for partially received login parameter. - uint8_t *partial_pairs; - - /// Hash map containing text key / value pairs associated to this connection. - iscsi_hashmap *text_key_value_pairs; - - /// Temporarily storage for partially received text parameter. - uint8_t *text_partial_pairs; - - /// iSCSI device. - iscsi_device *device; - - /// iSCSI initiator port. - iscsi_port *init_port; - - /// Initiator name. - uint8_t *init_name; - - //// Initiator IP address. - uint8_t *init_adr; - - /// iSCSI target node. - iscsi_target_node *target; - - /// iSCSI target port. - iscsi_port *target_port; - - /// iSCSI target short name. - uint8_t *target_name_short; - - /// iSCSI portal host name. - uint8_t *portal_host; - - /// iSCSI portal host port. - uint8_t *portal_port; - - /// Current PDU being processed. - iscsi_pdu *pdu_processing; - - /// Login response PDU. - iscsi_pdu *login_response_pdu; + /// iSCSI session associated with this connection. + iscsi_session *session; - /// Doubly linked list containing enqueued SCSI Data In tasks. - iscsi_list scsi_data_in_queued_tasks; + /// Associated dnbd3 client + dnbd3_client_t *client; - /// Doubly linked list containing writing PDU's associated with this connection. - iscsi_list pdus_write; + /// Current PDU being processed. + iscsi_pdu *pdu_processing; - /// Doubly linked list containing SNACK PDU's associated with this connection. - iscsi_list pdus_snack; + /// Login response PDU. + iscsi_pdu *login_response_pdu; - /// Doubly linked list containing active Ready To Transfer (R2T) tasks. - iscsi_list r2t_tasks_active; + /// Internal connection identifier + int id; - /// Doubly linked list containing queued Ready To Transfer (R2T) tasks. - iscsi_list r2t_tasks_queue; + /// iSCSI connection receiving state. + int pdu_recv_state; - /// iSCSI SendTargets total number of bytes completed. - uint target_send_total_size; + /// iSCSI connection flags. + int flags; - /// iSCSI SCSI Data In count. - uint scsi_data_in_cnt; + /// iSCSI connection state. + int state; - /// iSCSI SCSI Data Out count. - uint scsi_data_out_cnt; + /// iSCSI connection login phase. + int login_phase; - /// iSCSI tasks pending count. - uint task_cnt; + /// Initiator Session ID (ISID). + iscsi_isid isid; - /// Pending Ready To Transfer (R2T) tasks. - uint r2t_pending; + /// Target Session Identifying Handle (TSIH). + uint16_t tsih; - /// iSCSI connection contains a header digest (CRC32), always MUST be 0 or 4 for now. - int header_digest; + /// Connection ID (CID). + uint16_t cid; - /// iSCSI connection contains a data digest (CRC32), always MUST be 0 or 4 for now. - int data_digest; + /// Bit mask for connection state key negotiation. + uint16_t state_negotiated; - /// Internal connection identifier (key of iSCSI global vector hash map). - int id; + /// Bit mask for session state key negotiation. + uint32_t session_state_negotiated; - /// Connected TCP/IP socket. - int sock; + /// Initiator Task Tag (ITT). + uint32_t init_task_tag; - /// iSCSI connection receiving state. - int pdu_recv_state; + /// Targer Transfer Tag (TTT). + uint32_t target_xfer_tag; - /// iSCSI connection flags. - int flags; - - /// iSCSI connection state. - int state; - - /// iSCSI connection login phase. - int login_phase; - - /// Maximum receive DataSegment length in bytes. - uint32_t max_recv_ds_len; - - /// Portal group tag. - uint64_t pg_tag; - - /// Initiator Session ID (ISID). - iscsi_isid isid; - - /// Target Session Identifying Handle (TSIH). - uint16_t tsih; - - /// Connection ID (CID). - uint16_t cid; - - /// Bit mask for connection state key negotiation. - uint16_t state_negotiated; - - /// Bit mask for session state key negotiation. - uint32_t session_state_negotiated; - - /// Initiator Task Tag (ITT). - uint32_t init_task_tag; - - /// Targer Transfer Tag (TTT). - uint32_t target_xfer_tag; - - /// CHAP authentication. - iscsi_auth_chap auth_chap; - - /// CHAP group id. - int32_t chap_group; - - /// StatSN. - uint32_t stat_sn; - - /// ExpStatSN. - uint32_t exp_stat_sn; - - /// Execution queue to run to invoke callback functions after asynchronous I/O has been finished. - iscsi_list exec_queue; - - // TODO: Remove after test finish - iscsi_hashmap *stat_iscsi_opcodes; - - // TODO: Remove after test finish - iscsi_hashmap *stat_scsi_opcodes; + /// StatSN. + uint32_t stat_sn; } iscsi_connection; -/** - * @brief iSCSI transfer completed callback function. - * - * This function is invoked when the response PDU - * write to the TCP/IP socket has been completed. - * - * @param[in] user_data Pointer to user data. - */ -typedef void (*iscsi_connection_xfer_complete_callback)(uint8_t *user_data); - - -/** - * @brief Callback for iSCSI connection write TCP/IP write operation completion. - * - * This function is invoked when the sending - * TCP/IP transfer has been finished. - * - * @param[in] user_data Pointer to user data. - * @param[in] err 0 if I/O completed successfully or an - * error code indicating the problem. - */ -typedef void (*iscsi_connection_write_complete_callback)(uint8_t *user_data, int err); - - -/// iSCSI connection asynchronous execution queue: SCSI emulation I/O. -#define ISCSI_CONNECT_EXEC_QUEUE_TYPE_SCSI_EMU_IO 0U - -/// iSCSI connection asynchronous execution queue: PDU write I/O. -#define ISCSI_CONNECT_EXEC_QUEUE_TYPE_PDU_WRITE 1U - - -/** - * @brief iSCSI connection execution queue. - * - * This structure is used for invoking the - * callback functions after processing has - * been completed.\n - * Currently, PDU writes and SCSI emulation - * invoke I/O callbacks after finishing - * their operations. - */ -typedef struct iscsi_connection_exec_queue { - /// Doubly linked list node, MUST be first element. - iscsi_node node; - - /** - * @union data - * @brief Invokes callback functions with arguments based on the execution queue type. - * - * This union contains the arguments needed - * for their respective callback functions - * of the completion process. - */ - union { - /** - * @brief PDU write completion callback and arguments. - * - * For PDU write completion type, two arguments - * are passed. - */ - struct { - /// Callback function to invoke after PDU write completion process has been completed. - iscsi_connection_write_complete_callback callback; - - /// User data to be passed to the PDU write completion process callback function. - uint8_t *user_data; - - /// Error code to be passed to the PDU write completion process callback function. - int err; - } pdu_write; - - /** - * @brief I/O completion callback and arguments. - * - * For I/O completion type, three arguments - * are passed. - */ - struct { - /// Callback function to invoke after I/O process has been completed. - iscsi_scsi_emu_io_complete_callback callback; - - /// DNBD3 image to be passed to the I/O completion process callback function. - dnbd3_image_t *image; - - /// User data to be passed to the I/O completion process callback function. - uint8_t *user_data; - - /// Successful state passed to the I/O completion process callback function. - bool success; - } io; - } data; - - /// Type of completion callback. - uint type; -} iscsi_connection_exec_queue; - - typedef struct iscsi_task iscsi_task; @@ -11666,77 +6226,38 @@ typedef struct iscsi_task iscsi_task; * and filling the BHS, AHS and DS properly. */ typedef struct iscsi_pdu { - /// Doubly linked list node, MUST be first element. - iscsi_node node; - - /// iSCSI Basic Header Segment (BHS) packet data. - iscsi_bhs_packet *bhs_pkt; - - /// iSCSI Advanced Header Segment (AHS) packet data for fast access and is straight after BHS packet in memory. - iscsi_ahs_packet *ahs_pkt; + /// iSCSI Basic Header Segment (BHS) packet data. + iscsi_bhs_packet *bhs_pkt; - /// Header digest (CRC32C) packet data for fast access and is straight after BHS and AHS packet in memory. - iscsi_header_digest *header_digest; + /// iSCSI Advanced Header Segment (AHS) packet data for fast access and is straight after BHS packet in memory. + iscsi_ahs_packet *ahs_pkt; - /// iSCSI DataSegment (DS) packet data for fast access and is straight after BHS, AHS and header digest packet in memory. - iscsi_scsi_ds_cmd_data *ds_cmd_data; + /// iSCSI DataSegment (DS) packet data for fast access and is straight after BHS, AHS and header digest packet in memory. + iscsi_scsi_ds_cmd_data *ds_cmd_data; - /// Data digest (CRC32C) packet data for fast access and is straight after BHS, AHS, header digest and DataSegment packet in memory. - iscsi_data_digest *data_digest; + /// iSCSI task handling this PDU. + iscsi_task *task; - /// iSCSI task handling this PDU. - iscsi_task *task; + /// Flags. + int flags; - /// Associated iSCSI connection. - iscsi_connection *conn; + /// Bytes of Basic Header Segment (BHS) already read. + uint bhs_pos; - /// Transfer complete callback function. - iscsi_connection_xfer_complete_callback xfer_complete_callback; + /// AHSLength. + uint ahs_len; - /// Transfer complete callback user data (arguments). - uint8_t *xfer_complete_user_data; + /// DataSegmentLength. + uint32_t ds_len; - /// Flags. - int flags; + /// DS Buffer write pos when filling buffer for sending. + uint32_t ds_write_pos; - /// Reference counter. - uint32_t ref; + /// Read position in AHS + DS buffer (recv). + uint32_t recv_pos; - /// Bytes of Basic Header Segment (BHS) already read. - uint bhs_pos; - - /// Bytes of Advanced Header Segment (AHS) already read. - uint ahs_pos; - - /// AHSLength. - uint ahs_len; - - /// Bytes of header digest (CRC32C) already read. - uint header_digest_pos; - - /// Header digest size (always 0 or 4 for now). - int header_digest_size; - - /// DataSegmentLength. - uint32_t ds_len; - - /// Position of DataSegment buffer for next operation. - uint32_t pos; - - /// Allocated DataSegment buffer length. - uint32_t len; - - /// Bytes of data digest (CRC32C) already read. - uint data_digest_pos; - - /// Data digest size (always 0 or 4 for now). - int data_digest_size; - - /// Tasks referenced by this PDU counter. - uint task_ref_cnt; - - /// CmdSN. - uint32_t cmd_sn; + /// CmdSN. + uint32_t cmd_sn; } iscsi_pdu; @@ -11754,163 +6275,43 @@ typedef struct iscsi_pdu { * including the underlying SCSI layer. */ typedef struct iscsi_task { - /// Doubly linked list node, MUST be first element. - iscsi_node node; - - /// Underlying SCSI task structure. - iscsi_scsi_task scsi_task; - - /// Parent iSCSI task. - iscsi_task *parent; - - /// Sub tasks doubly linked list for splitted data transfers. - iscsi_list sub_tasks; - - /// Associated iSCSI connection. - iscsi_connection *conn; - - /// Associated iSCSI PDU. - iscsi_pdu *pdu; + /// Underlying SCSI task structure. + iscsi_scsi_task scsi_task; - /// Buffer position in bytes. - uint32_t pos; + /// Associated iSCSI connection. + iscsi_connection *conn; - /// Buffer length in bytes. - uint32_t len; + /// Buffer position in bytes. + uint32_t pos; - /// Unique identifier for this task. - uint64_t id; + /// Buffer length in bytes. + uint32_t len; - /// Flags. - int flags; + /// Unique identifier for this task. + uint64_t id; - /// LUN identifier associated with this task (always MUST be between 0 and 7), used for hot removal tracking. - int lun_id; + /// Flags. + int flags; - /// Initiator Task Tag (ITT). - uint32_t init_task_tag; + /// LUN identifier associated with this task (always MUST be between 0 and 7), used for hot removal tracking. + int lun_id; - /// Target Transfer Tag (TTT). - uint32_t target_xfer_tag; + /// Initiator Task Tag (ITT). + uint32_t init_task_tag; - /// Desired number of bytes completed. - uint32_t des_data_xfer_pos; + /// Target Transfer Tag (TTT). + uint32_t target_xfer_tag; - /// Desired data transfer length. - uint32_t des_data_xfer_len; + /// Desired number of bytes completed. + uint32_t des_data_xfer_pos; - /// SCSI Data In Data Sequence Number (DataSN). - uint32_t data_sn; + /// Desired data transfer length. + uint32_t des_data_xfer_len; - /// SCSI Data Out count. - uint32_t scsi_data_out_cnt; - - /// Length in bytes of R2T, used for ensuring that R2T burst does not exceed MaxBurstLength. - uint32_t r2t_len; - - /// Ready To Transfer Sequence Number (R2TSN). - uint32_t r2t_sn; - - /// Next expected Ready To Transfer offset is used for receiving the Data-OUT PDU. - uint32_t r2t_next_exp_pos; - - /// Ready To Transfer DataSN, used for next sequence of a R2TSN. - uint32_t r2t_data_sn; - - /// Next R2TSN to be acknowledged. - uint32_t r2t_sn_ack; - - /// Outstanding Ready To Transfer (R2T) count. - uint32_t r2t_outstanding; + /// SCSI Data In Data Sequence Number (DataSN). + uint32_t data_sn; } iscsi_task; - -iscsi_task *iscsi_task_create(iscsi_connection *conn, iscsi_task *parent, iscsi_scsi_task_xfer_complete_callback callback); // Allocates and initializes an iSCSI task structure -void iscsi_task_destroy_callback(iscsi_scsi_task *scsi_task); // Deallocates all resources of the iSCSI task of an iSCSI SCSI task -void iscsi_task_destroy(iscsi_task *task); // Deallocates resources acquired by iscsi_task_create - -void iscsi_task_queue(iscsi_connection *conn, iscsi_task *task); // Enqueues an iSCSI task - -void iscsi_task_xfer_complete_process_read(iscsi_connection *conn, iscsi_task *task, iscsi_task *primary_task); // Processes an iSCSI SCSI task which completed a read data transfer -bool iscsi_task_xfer_del(iscsi_connection *conn, const uint32_t target_xfer_tag); // Deletes an iSCSI task from the active Ready To Transfer (R2T) doubly linked list by Target Transfer Tag (TTT) -void iscsi_task_xfer_complete_process_other(iscsi_connection *conn, iscsi_task *task, iscsi_task *primary_task); // Processes an iSCSI SCSI task which completed a non-read data transfer - -void iscsi_task_response(iscsi_connection *conn, iscsi_task *task); // Creates, initializes and sends an iSCSI task reponse PDU. - -iscsi_device *iscsi_device_create(const uint8_t *name, const int lun_id, const uint8_t protocol_id); // Creates and initializes an iSCSI device with a maximum number of LUNs -int iscsi_device_destroy_callback(uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *user_data); // iSCSI device destructor callback for hash map -void iscsi_device_destroy(iscsi_device *device); // Deallocates all resources acquired by iscsi_device_create - -iscsi_port *iscsi_device_find_port_by_portal_group_tag(const iscsi_device *device, const uint64_t id); // Gets an iSCSI device being in use by portal group identifier -iscsi_scsi_lun *iscsi_device_find_lun(iscsi_device *device, const int lun_id); // Searches an iSCSI LUN by LUN identifier - -int iscsi_device_port_add(iscsi_device *device, const uint8_t *name, const uint64_t id); // Creates, initializes and adds an iSCSI target port to an iSCSI device - -void iscsi_device_scsi_task_queue(iscsi_device *device, iscsi_scsi_task *scsi_task); // Enqueues an iSCSI SCSI task to the first LUN of an iSCSI device - -int iscsi_target_node_create_callback(uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *user_data); // Creates, initializes and adds a portal group to an iSCSI target node -iscsi_target_node *iscsi_target_node_create(uint8_t *name, const uint8_t *alias, const int index, const int lun_id, const uint queue_depth, const int flags, const int32_t chap_group, const int header_digest, const int data_digest); // Creates and initializes an iSCSI target node -int iscsi_target_node_destroy_callback(uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *user_data); // iSCSI target node destructor callback for hash map -void iscsi_target_node_destroy(iscsi_target_node *target); // Deallocates all resources acquired by iscsi_target_node_create - -int32_t iscsi_target_node_send(iscsi_connection *conn, const uint8_t *dst_iqn, const uint8_t *src_iqn, uint8_t *buf, const uint32_t pos, const uint32_t len); // Sends a buffer from a source iSCSI IQN to target iSCSI IQNs -uint64_t iscsi_target_node_wwn_get(const uint8_t *name); // Calculates the WWN using 64-bit IEEE Extended NAA for a name -dnbd3_image_t *iscsi_target_node_image_get(uint8_t *iqn); // Extracts the DNBD3 image out of an iSCSI IQN string and opens the DNBD3 image -int iscsi_target_node_find_callback(uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *user_data); // Finds an iSCSI target node by case insensitive name search -iscsi_target_node *iscsi_target_node_find(uint8_t *target_name); // Searches an iSCSI target node by name using case insensitive search - -uint8_t *iscsi_target_node_get_redirect(iscsi_connection *conn, iscsi_target_node *target); // Retrieves target node redirection address -int iscsi_target_node_access(iscsi_connection *conn, iscsi_target_node *target, const uint8_t *iqn, const uint8_t *adr); // Checks if target node is accessible - -iscsi_session *iscsi_session_create(iscsi_connection *conn, iscsi_target_node *target, const int type); // Creates and initializes an iSCSI session -int iscsi_session_destroy_callback(uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *user_data); // iSCSI session destructor callback for hash map -void iscsi_session_destroy(iscsi_session *session); // Deallocates all resources acquired by iscsi_session_create - -int iscsi_session_init_key_value_pairs(iscsi_hashmap *key_value_pairs); // Initializes a key and value pair hash table with default values - -iscsi_connection *iscsi_connection_create(iscsi_portal *portal, const int sock); // Creates data structure for an iSCSI connection from iSCSI portal and TCP/IP socket -int iscsi_connection_destroy_callback(uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *user_data); // iSCSI connection destructor callback for hash map -void iscsi_connection_destroy(iscsi_connection *conn); // Deallocates all resources acquired by iscsi_connection_create - -int iscsi_connection_drop(iscsi_connection *conn, const uint8_t *conn_match, const int all); // Drops all connections based on matching pattern -void iscsi_connection_schedule(iscsi_connection *conn); // Schedules an iSCSI connection - -int32_t iscsi_connection_read(const iscsi_connection *conn, uint8_t *buf, const uint32_t len); // Reads data for the specified iSCSI connection from its TCP socket -int32_t iscsi_connection_write(const iscsi_connection *conn, uint8_t *buf, const uint32_t len); // Writes data for the specified iSCSI connection to its TCP socket -int iscsi_connection_handle_scsi_data_in_queued_tasks(iscsi_connection *conn); // This function handles all queued iSCSI SCSI Data In tasks - -int iscsi_connection_init_key_value_pairs(iscsi_hashmap *key_value_pairs); // Initializes a key and value pair hash table with default values for an iSCSI connection -int32_t iscsi_negotiate_key_value_pairs(iscsi_connection *conn, iscsi_hashmap *key_value_pairs, uint8_t *buf, const uint32_t pos, const uint32_t len); // Negotiates all key and value pairs required for session authentication -int iscsi_connection_copy_key_value_pairs(iscsi_connection *conn); // Copies retrieved key and value pairs into SCSI connection and session structures -int iscsi_connection_save_incoming_key_value_pairs(iscsi_connection *conn, iscsi_hashmap *key_value_pairs, iscsi_pdu *login_response_pdu, const iscsi_pdu *pdu); // Saves incoming key / value pairs from the client of a login request PDU -void iscsi_connection_login_response_reject(iscsi_pdu *login_response_pdu, const iscsi_pdu *pdu); // Initializes a rejecting login response packet -iscsi_pdu *iscsi_connection_pdu_create(iscsi_connection *conn, const uint ahs_len, const int header_digest_size, const uint32_t ds_len, const int data_sigest_size ); // Creates an iSCSI PDU structure used by connections -void iscsi_connection_pdu_destroy(iscsi_pdu *pdu); // Destroys an iSCSI PDU structure used by connections -void iscsi_connection_pdu_free(iscsi_connection *conn, iscsi_pdu *pdu); // Frees an iSCSI PDU structure used by using connection callback function - -iscsi_bhs_packet *iscsi_connection_pdu_append(iscsi_pdu *pdu, const uint ahs_len, const int header_digest_size, const uint32_t ds_len, const int data_digest_size); // Appends packet data to an iSCSI PDU structure used by connections -iscsi_ahs_packet *iscsi_connection_pdu_ahs_packet_get(const iscsi_pdu *pdu, const int index); // Retrieves the pointer to an specific AHS packet from an iSCSI PDU by index -int iscsi_connection_pdu_ahs_packet_count(const iscsi_pdu *pdu); // Counts number of AHS packets of an iSCSI PDU - -void iscsi_connection_pdu_digest_header_update(iscsi_header_digest *header_digest, const iscsi_bhs_packet *packet_data, const uint ahs_len); // Calculate and store iSCSI header digest (CRC32C) -bool iscsi_connection_pdu_digest_header_verify(const iscsi_header_digest *header_digest, const iscsi_bhs_packet *packet_data, const uint ahs_len); // Validates a stored iSCSI header digest (CRC32C) with actual header data -void iscsi_connection_pdu_digest_data_update(iscsi_data_digest *data_digest, const iscsi_scsi_ds_cmd_data *ds_cmd_data, const uint32_t ds_len); // Calculate iSCSI data digest (CRC32C) -bool iscsi_connection_pdu_digest_data_verify(const iscsi_data_digest *data_digest, const iscsi_scsi_ds_cmd_data *ds_cmd_data, const uint32_t ds_len); // Validates a stored iSCSI data digest (CRC32C) with actual DataSegment - -void iscsi_connection_pdu_ack_remove(iscsi_connection *conn, const uint32_t exp_stat_sn); // Removes an acknowledged PDU from SNACK PDU doubly linked list by ExpStatSN - -iscsi_pdu *iscsi_r2t_find_pdu_bhs(iscsi_connection *conn, iscsi_pdu *pdu); // Searches an iSCSI PDU by Basic Header Segment (BHS) in the Ready To Transfer (R2T) active and queued task doubly linked list -int iscsi_r2t_send(iscsi_connection *conn, iscsi_task *task, uint32_t *r2t_sn, const uint32_t pos, const uint32_t len, const uint32_t target_xfer_tag); // Sends an iSCSI Ready To Transfer Sequence Number (R2TSN) packet to the initiator - -int iscsi_connection_read_data(iscsi_connection *conn, int len, void *buf); -int iscsi_connection_read_iov_data(iscsi_connection *conn, struct iovec *iov, int iov_count); -void iscsi_connection_pdu_write(iscsi_connection *conn, iscsi_pdu *pdu, iscsi_connection_xfer_complete_callback callback, uint8_t *user_data); - -int iscsi_connection_pdu_handle(iscsi_connection *conn); // Handles incoming PDU data, read up to 16 fragments at once void iscsi_connection_handle(dnbd3_client_t *client, const dnbd3_request_t *request, const int len); // Handles an iSCSI connection until connection is closed -#ifdef __cplusplus -} -#endif - #endif /* DNBD3_ISCSI_H_ */ -- cgit v1.2.3-55-g7522