diff options
| -rw-r--r-- | src/server/iscsi.c | 1420 | ||||
| -rw-r--r-- | src/server/iscsi.h | 1298 | ||||
| -rw-r--r-- | src/server/server.c | 3 |
3 files changed, 2099 insertions, 622 deletions
diff --git a/src/server/iscsi.c b/src/server/iscsi.c index cc1c7a5..8ba0c42 100644 --- a/src/server/iscsi.c +++ b/src/server/iscsi.c @@ -32,6 +32,7 @@ #include <dnbd3/shared/log.h> #include <dnbd3/shared/sockhelper.h> #include <dnbd3/types.h> +#include <pthread.h> #include <time.h> #include "globals.h" @@ -54,22 +55,26 @@ /// iSCSI global vector. MUST be initialized with iscsi_create before any iSCSI functions are used. iscsi_globals *iscsi_globvec = NULL; +/// Read/write lock for iSCSI global vector. MUST be initialized with iscsi_create before any iSCSI functions are used. +pthread_rwlock_t iscsi_globvec_rwlock; + + /// iSCSI connection negotation key and value pair lookup table. static const iscsi_key_value_pair_lut_entry iscsi_connection_key_value_pair_lut[] = { - { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_HEADER_DIGEST, (uint8_t *) "None", (uint8_t *) "CRC32C\0None\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_LIST, 0L }, - { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_DATA_DIGEST, (uint8_t *) "None", (uint8_t *) "CRC32C\0None\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_LIST, 0L }, + { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_HEADER_DIGEST, (uint8_t *) "None", (uint8_t *) "CRC32C\0None\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_LIST, 0 }, + { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_DATA_DIGEST, (uint8_t *) "None", (uint8_t *) "CRC32C\0None\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_LIST, 0 }, { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_MAX_RECV_DS_LEN, (uint8_t *) "8192", (uint8_t *) "512\016777215\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_DECLARATIVE, ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_MULTI_NEGOTIATION | ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_OVERRIDE_DEFAULT }, - { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_OF_MARKER, (uint8_t *) "No", (uint8_t *) "Yes\0No\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_BOOL_AND, 0L }, - { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_IF_MARKER, (uint8_t *) "No", (uint8_t *) "Yes\0No\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_BOOL_AND, 0L }, - { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_OF_MARK_INT, (uint8_t *) "1", (uint8_t *) "1\0""65535\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_MIN, 0L }, - { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_IF_MARK_INT, (uint8_t *) "1", (uint8_t *) "1\0""65535\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_MIN, 0L }, - { ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD, (uint8_t *) "None", (uint8_t *) "CHAP\0None\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_LIST, 0L }, + { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_OF_MARKER, (uint8_t *) "No", (uint8_t *) "Yes\0No\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_BOOL_AND, 0 }, + { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_IF_MARKER, (uint8_t *) "No", (uint8_t *) "Yes\0No\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_BOOL_AND, 0 }, + { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_OF_MARK_INT, (uint8_t *) "1", (uint8_t *) "1\0""65535\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_MIN, 0 }, + { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_IF_MARK_INT, (uint8_t *) "1", (uint8_t *) "1\0""65535\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_MIN, 0 }, + { ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD, (uint8_t *) "None", (uint8_t *) "CHAP\0None\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_LIST, 0 }, { ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD_CHAP_CHAP_A, (uint8_t *) "5", (uint8_t *) "5\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_LIST, ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_CHAP_TYPE }, { ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD_CHAP_CHAP_N, (uint8_t *) "", (uint8_t *) "\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_DECLARATIVE, ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_CHAP_TYPE }, { ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD_CHAP_CHAP_R, (uint8_t *) "", (uint8_t *) "\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_DECLARATIVE, ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_CHAP_TYPE }, { ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD_CHAP_CHAP_I, (uint8_t *) "", (uint8_t *) "\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_DECLARATIVE, ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_CHAP_TYPE }, { ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD_CHAP_CHAP_C, (uint8_t *) "", (uint8_t *) "\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_DECLARATIVE, ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_CHAP_TYPE }, - { NULL, NULL, NULL, ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_INVALID, 0L } + { NULL, NULL, NULL, ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_INVALID, 0 } }; /// iSCSI session negotation key and value pair lookup table. @@ -77,23 +82,23 @@ static const iscsi_key_value_pair_lut_entry iscsi_session_key_value_pair_lut[] = { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_MAX_CONNECTIONS, (uint8_t *) "1", (uint8_t *) "1\0""65535\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_MIN, ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_DISCOVERY_IGNORE }, { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_SEND_TARGETS, (uint8_t *) "", (uint8_t *) "\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_DECLARATIVE, ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_SPECIAL_HANDLING }, { ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_TARGET_NAME, (uint8_t *) "", (uint8_t *) "\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_DECLARATIVE, ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_TARGET_DECLARATIVE }, - { ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_INITIATOR_NAME, (uint8_t *) "", (uint8_t *) "\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_DECLARATIVE, 0L }, - { ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_TARGET_ALIAS, (uint8_t *) "", (uint8_t *) "\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_DECLARATIVE, 0L }, - { ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_INITIATOR_ALIAS, (uint8_t *) "", (uint8_t *) "\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_DECLARATIVE, 0L }, + { ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_INITIATOR_NAME, (uint8_t *) "", (uint8_t *) "\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_DECLARATIVE, 0 }, + { ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_TARGET_ALIAS, (uint8_t *) "", (uint8_t *) "\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_DECLARATIVE, 0 }, + { ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_INITIATOR_ALIAS, (uint8_t *) "", (uint8_t *) "\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_DECLARATIVE, 0 }, { ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_TARGET_ADDRESS, (uint8_t *) "", (uint8_t *) "\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_DECLARATIVE, ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_TARGET_DECLARATIVE }, { ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_TARGET_PORTAL_GROUP_TAG, (uint8_t *) "1", (uint8_t *) "1\0""65535\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_DECLARATIVE, ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_TARGET_DECLARATIVE }, { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_INITIAL_R2T, (uint8_t *) "Yes", (uint8_t *) "Yes\0No\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_BOOL_OR, ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_DISCOVERY_IGNORE }, { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_IMMEDIATE_DATA, (uint8_t *) "Yes", (uint8_t *) "Yes\0No\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_BOOL_AND, ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_DISCOVERY_IGNORE }, { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_MAX_BURST_LEN, (uint8_t *) "262144", (uint8_t *) "512\0""16777215\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_MIN, ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_DISCOVERY_IGNORE | ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_USE_OTHER_MAX_VALUE }, { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_FIRST_BURST_LEN, (uint8_t *) "65536", (uint8_t *) "512\0""16777215\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_MIN, ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_DISCOVERY_IGNORE | ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_USE_PREVIOUS_VALUE }, - { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_DEFAULT_TIME_WAIT, (uint8_t *) "2", (uint8_t *) "0\0""3600\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_MAX, 0L }, - { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_DEFAULT_TIME_RETAIN, (uint8_t *) "20", (uint8_t *) "0\0""3600\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_MIN, 0L }, + { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_DEFAULT_TIME_WAIT, (uint8_t *) "2", (uint8_t *) "0\0""3600\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_MAX, 0 }, + { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_DEFAULT_TIME_RETAIN, (uint8_t *) "20", (uint8_t *) "0\0""3600\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_MIN, 0 }, { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_MAX_OUTSTANDING_R2T, (uint8_t *) "1", (uint8_t *) "1\0""65536\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_MIN, ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_DISCOVERY_IGNORE }, { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_DATA_PDU_IN_ORDER, (uint8_t *) "Yes", (uint8_t *) "Yes\0No\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_BOOL_OR, ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_DISCOVERY_IGNORE }, { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_DATA_SEQ_IN_ORDER, (uint8_t *) "Yes", (uint8_t *) "Yes\0No\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_BOOL_OR, ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_DISCOVERY_IGNORE }, - { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_ERR_RECOVERY_LEVEL, (uint8_t *) "0", (uint8_t *) "0\0""2\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_MIN, 0L }, - { ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_SESSION_TYPE, (uint8_t *) "Normal", (uint8_t *) "Normal\0Discovery\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_DECLARATIVE, 0L }, - { NULL, NULL, NULL, ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_INVALID, 0L } + { ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_ERR_RECOVERY_LEVEL, (uint8_t *) "0", (uint8_t *) "0\0""2\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_MIN, 0 }, + { ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_SESSION_TYPE, (uint8_t *) "Normal", (uint8_t *) "Normal\0Discovery\0", ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_DECLARATIVE, 0 }, + { NULL, NULL, NULL, ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_INVALID, 0 } }; /** @@ -112,22 +117,22 @@ static const iscsi_key_value_pair_lut_entry iscsi_session_key_value_pair_lut[] = */ static int iscsi_global_key_value_pair_init(iscsi_hashmap *key_value_pairs, const iscsi_key_value_pair_lut_entry *lut) { - for ( uint i = 0; lut[i].key != NULL; i++ ) { + for ( uint i = 0U, j = 1U; lut[i].key != NULL; i++, j += j ) { iscsi_key_value_pair *key_value_pair = (iscsi_key_value_pair *) malloc( sizeof(struct iscsi_key_value_pair) ); if ( key_value_pair == NULL ) { logadd( LOG_ERROR, "iscsi_global_key_value_pair_init: Out of memory allocating key value pair" ); - return -1L; + return -1; } - const uint key_len = (uint) strlen( (char *) lut[i].key ) + 1UL; + const uint key_len = (uint) strlen( (char *) lut[i].key ) + 1U; key_value_pair->value = lut[i].value; key_value_pair->list_range = lut[i].list_range; key_value_pair->type = lut[i].type; key_value_pair->flags = lut[i].flags; - key_value_pair->state_mask = (1UL << i); + key_value_pair->state_mask = j; const int rc = iscsi_hashmap_put( key_value_pairs, (uint8_t *) lut[i].key, key_len, (uint8_t *) key_value_pair ); @@ -138,7 +143,7 @@ static int iscsi_global_key_value_pair_init(iscsi_hashmap *key_value_pairs, cons } } - return 0L; + return 0; } /** @@ -156,37 +161,43 @@ static int iscsi_global_key_value_pair_init(iscsi_hashmap *key_value_pairs, cons */ int iscsi_create() { + pthread_rwlock_wrlock( &iscsi_globvec_rwlock ); + if ( iscsi_globvec == NULL ) { iscsi_globals *globvec = (iscsi_globals *) malloc( sizeof(struct iscsi_globals) ); if ( globvec == NULL ) { logadd( LOG_ERROR, "iscsi_create: Out of memory while allocating iSCSI global vector" ); - return -1L; + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); + + return -1; } - globvec->devices = iscsi_hashmap_create( 0UL ); + globvec->devices = iscsi_hashmap_create( 0U ); if ( globvec->devices == NULL ) { logadd( LOG_ERROR, "iscsi_create: Out of memory while allocating iSCSI global vector devices hash map" ); free( globvec ); + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); - return -1L; + return -1; } - globvec->portal_groups = iscsi_hashmap_create( 0UL ); + globvec->portal_groups = iscsi_hashmap_create( 0U ); if ( globvec->portal_groups == NULL ) { logadd( LOG_ERROR, "iscsi_create: Out of memory while allocating iSCSI global vector portal groups hash map" ); iscsi_hashmap_destroy( globvec->devices ); free( globvec ); + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); - return -1L; + return -1; } - globvec->target_nodes = iscsi_hashmap_create( 0UL ); + globvec->target_nodes = iscsi_hashmap_create( 0U ); if ( globvec->target_nodes == NULL ) { logadd( LOG_ERROR, "iscsi_create: Out of memory while allocating iSCSI global vector target nodes hash map" ); @@ -194,11 +205,12 @@ int iscsi_create() iscsi_hashmap_destroy( globvec->portal_groups ); iscsi_hashmap_destroy( globvec->devices ); free( globvec ); + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); - return -1L; + return -1; } - globvec->sessions = iscsi_hashmap_create( 0UL ); + globvec->sessions = iscsi_hashmap_create( 0U ); if ( globvec->sessions == NULL ) { logadd( LOG_ERROR, "iscsi_create: Out of memory while allocating iSCSI global vector sessions hash map" ); @@ -207,11 +219,12 @@ int iscsi_create() iscsi_hashmap_destroy( globvec->portal_groups ); iscsi_hashmap_destroy( globvec->devices ); free( globvec ); + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); - return -1L; + return -1; } - globvec->session_key_value_pairs = iscsi_hashmap_create( 32UL ); + globvec->session_key_value_pairs = iscsi_hashmap_create( 32U ); if ( globvec->session_key_value_pairs == NULL ) { logadd( LOG_ERROR, "iscsi_create: Out of memory while allocating iSCSI global vector session key and value pairs hash map" ); @@ -221,8 +234,9 @@ int iscsi_create() iscsi_hashmap_destroy( globvec->portal_groups ); iscsi_hashmap_destroy( globvec->devices ); free( globvec ); + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); - return -1L; + return -1; } int rc = iscsi_global_key_value_pair_init( globvec->session_key_value_pairs, &iscsi_session_key_value_pair_lut[0] ); @@ -237,11 +251,12 @@ int iscsi_create() iscsi_hashmap_destroy( globvec->portal_groups ); iscsi_hashmap_destroy( globvec->devices ); free( globvec ); + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); - return -1L; + return -1; } - globvec->connections = iscsi_hashmap_create( 0UL ); + globvec->connections = iscsi_hashmap_create( 0U ); if ( globvec->connections == NULL ) { logadd( LOG_ERROR, "iscsi_create: Out of memory while allocating iSCSI global vector connections hash map" ); @@ -253,11 +268,12 @@ int iscsi_create() iscsi_hashmap_destroy( globvec->portal_groups ); iscsi_hashmap_destroy( globvec->devices ); free( globvec ); + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); - return -1L; + return -1; } - globvec->connection_key_value_pairs = iscsi_hashmap_create( 32UL ); + globvec->connection_key_value_pairs = iscsi_hashmap_create( 32U ); if ( globvec->connection_key_value_pairs == NULL ) { logadd( LOG_ERROR, "iscsi_create: Out of memory while allocating iSCSI global vector connection key and value pairs hash map" ); @@ -270,8 +286,9 @@ int iscsi_create() iscsi_hashmap_destroy( globvec->portal_groups ); iscsi_hashmap_destroy( globvec->devices ); free( globvec ); + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); - return -1L; + return -1; } rc = iscsi_global_key_value_pair_init( globvec->connection_key_value_pairs, &iscsi_connection_key_value_pair_lut[0] ); @@ -289,18 +306,21 @@ int iscsi_create() iscsi_hashmap_destroy( globvec->portal_groups ); iscsi_hashmap_destroy( globvec->devices ); free( globvec ); + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); - return -1L; + return -1; } - globvec->flags = 0L; - globvec->max_sessions = 0UL; + globvec->flags = 0; + globvec->max_sessions = 0U; globvec->chap_group = 0L; iscsi_globvec = globvec; } - return 0L; + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); + + return 0; } /** @@ -316,6 +336,8 @@ int iscsi_create() */ void iscsi_destroy() { + pthread_rwlock_wrlock( &iscsi_globvec_rwlock ); + iscsi_globals *globvec = iscsi_globvec; if ( globvec != NULL ) { @@ -346,6 +368,8 @@ void iscsi_destroy() free( globvec ); } + + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); } /** @@ -362,7 +386,7 @@ void iscsi_destroy() uint8_t *iscsi_vsprintf_append_realloc(char *buf, const char *format, va_list args) { va_list args_copy; - uint orig_size = 0UL; + uint orig_size = 0U; if ( buf != NULL ) orig_size = (uint) strlen( (char *) buf ); @@ -371,7 +395,7 @@ uint8_t *iscsi_vsprintf_append_realloc(char *buf, const char *format, va_list ar uint new_size = vsnprintf( NULL, 0, format, args_copy ); va_end( args_copy ); - new_size += (uint) (orig_size + 1UL); + new_size += (uint) (orig_size + 1U); uint8_t *new_buf = realloc( buf, new_size ); @@ -474,14 +498,14 @@ iscsi_hashmap *iscsi_hashmap_create(const uint capacity) return map; } - if ( capacity > 0UL ) { - uint new_capacity = (capacity - 1); // 1UL << (lg(capacity - 1) + 1) + if ( capacity > 0U ) { + uint new_capacity = (capacity - 1U); // 1U << (lg(capacity - 1U) + 1U) - new_capacity |= (new_capacity >> 1UL); - new_capacity |= (new_capacity >> 2UL); - new_capacity |= (new_capacity >> 4UL); - new_capacity |= (new_capacity >> 8UL); - new_capacity |= (new_capacity >> 16UL); + new_capacity |= (new_capacity >> 1U); + new_capacity |= (new_capacity >> 2U); + new_capacity |= (new_capacity >> 4U); + new_capacity |= (new_capacity >> 8U); + new_capacity |= (new_capacity >> 16U); map->capacity = ++new_capacity; // Round up actual new capacity to nearest power of two } else { @@ -498,9 +522,9 @@ iscsi_hashmap *iscsi_hashmap_create(const uint capacity) return NULL; } - map->cap_load = (uint) ((map->capacity * 3UL) >> 2UL); // 75% of capacity - map->count = 0UL; - map->removed_count = 0UL; + map->cap_load = (uint) ((map->capacity * 3U) >> 2U); // 75% of capacity + map->count = 0U; + map->removed_count = 0U; map->first = NULL; map->last = (iscsi_hashmap_bucket *) &map->first; @@ -542,7 +566,7 @@ void iscsi_hashmap_destroy(iscsi_hashmap *map) */ static iscsi_hashmap_bucket *iscsi_hashmap_resize_entry(iscsi_hashmap *map, const iscsi_hashmap_bucket *old_entry) { - uint32_t index = old_entry->hash & (map->capacity - 1); + uint32_t index = old_entry->hash & (map->capacity - 1U); for ( ;; ) { iscsi_hashmap_bucket *entry = &map->buckets[index]; @@ -553,7 +577,7 @@ static iscsi_hashmap_bucket *iscsi_hashmap_resize_entry(iscsi_hashmap *map, cons return entry; } - index = (index + 1) & (map->capacity - 1); + index = (index + 1) & (map->capacity - 1U); } } @@ -583,13 +607,13 @@ static int iscsi_hashmap_resize(iscsi_hashmap *map) map->capacity = old_capacity; map->buckets = old_buckets; - return -1L; + return -1; } - map->cap_load = (uint) ((map->capacity * 3UL) >> 2UL); // 75% of capacity + map->cap_load = (uint) ((map->capacity * 3U) >> 2U); // 75% of capacity map->last = (iscsi_hashmap_bucket *) &map->first; map->count -= map->removed_count; - map->removed_count = 0UL; + map->removed_count = 0U; do { iscsi_hashmap_bucket *current = map->last->next; @@ -606,7 +630,7 @@ static int iscsi_hashmap_resize(iscsi_hashmap *map) free( old_buckets ); - return 0L; + return 0; } /** @@ -656,7 +680,7 @@ static inline uint32_t iscsi_hashmap_hash_data(const uint8_t *data, const size_t */ static iscsi_hashmap_bucket *iscsi_hashmap_find_entry(iscsi_hashmap *map, const uint8_t *key, size_t key_size, uint32_t hash) { - uint32_t index = hash & (map->capacity - 1); + uint32_t index = hash & (map->capacity - 1U); for ( ;; ) { iscsi_hashmap_bucket *entry = &map->buckets[index]; @@ -664,7 +688,7 @@ static iscsi_hashmap_bucket *iscsi_hashmap_find_entry(iscsi_hashmap *map, const if ( ((entry->key == NULL) && (entry->value == NULL)) || ((entry->key != NULL) && (entry->key_size == key_size) && (entry->hash == hash) && (memcmp( entry->key, key, key_size ) == 0)) ) return entry; - index = (index + 1) & (map->capacity - 1); + index = (index + 1UL) & (map->capacity - 1U); } } @@ -761,7 +785,7 @@ int iscsi_hashmap_key_destroy_callback(uint8_t *key, const size_t key_size, uint { iscsi_hashmap_key_destroy( key ); - return 0L; + return 0; } /** @@ -785,7 +809,7 @@ int iscsi_hashmap_destroy_value_callback(uint8_t *key, const size_t key_size, ui if ( value != NULL ) free( value ); - return 0L; + return 0; } /** @@ -811,7 +835,7 @@ int iscsi_hashmap_key_destroy_value_callback(uint8_t *key, const size_t key_size iscsi_hashmap_key_destroy( key ); - return 0L; + return 0; } /** @@ -843,8 +867,8 @@ int iscsi_hashmap_key_destroy_value_callback(uint8_t *key, const size_t key_size */ int iscsi_hashmap_put(iscsi_hashmap *map, uint8_t *key, const size_t key_size, uint8_t *value) { - if ( ((map->count + 1) > map->cap_load) && (iscsi_hashmap_resize( map ) < 0) ) - return -1L; + if ( ((map->count + 1U) > map->cap_load) && (iscsi_hashmap_resize( map ) < 0) ) + return -1; const uint32_t hash = iscsi_hashmap_hash_data( key, key_size ); iscsi_hashmap_bucket *entry = iscsi_hashmap_find_entry( map, key, key_size, hash ); @@ -863,7 +887,7 @@ int iscsi_hashmap_put(iscsi_hashmap *map, uint8_t *key, const size_t key_size, u entry->value = value; - return 0L; + return 0; } /** @@ -895,8 +919,8 @@ int iscsi_hashmap_put(iscsi_hashmap *map, uint8_t *key, const size_t key_size, u */ int iscsi_hashmap_push(iscsi_hashmap *map, uint8_t *key, const size_t key_size, uint8_t *value) { - if ( ((map->count + 1) > map->cap_load) && (iscsi_hashmap_resize( map ) < 0) ) - return -1L; + if ( ((map->count + 1U) > map->cap_load) && (iscsi_hashmap_resize( map ) < 0) ) + return -1; const uint32_t hash = iscsi_hashmap_hash_data( key, key_size ); iscsi_hashmap_bucket *entry = iscsi_hashmap_find_entry( map, key, key_size, hash ); @@ -917,7 +941,7 @@ int iscsi_hashmap_push(iscsi_hashmap *map, uint8_t *key, const size_t key_size, entry->value = value; - return 0L; + return 0; } /** @@ -955,8 +979,8 @@ int iscsi_hashmap_push(iscsi_hashmap *map, uint8_t *key, const size_t key_size, */ int iscsi_hashmap_insert_before(iscsi_hashmap *map, uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *insert_key, const size_t insert_key_size) { - if ( ((map->count + 1) > map->cap_load) && (iscsi_hashmap_resize( map ) < 0) ) - return -1L; + if ( ((map->count + 1U) > map->cap_load) && (iscsi_hashmap_resize( map ) < 0) ) + return -1; const uint32_t hash = iscsi_hashmap_hash_data( key, key_size ); iscsi_hashmap_bucket *entry = iscsi_hashmap_find_entry( map, key, key_size, hash ); @@ -986,7 +1010,7 @@ int iscsi_hashmap_insert_before(iscsi_hashmap *map, uint8_t *key, const size_t k entry->value = value; - return 0L; + return 0; } /** @@ -1021,8 +1045,8 @@ int iscsi_hashmap_insert_before(iscsi_hashmap *map, uint8_t *key, const size_t k */ int iscsi_hashmap_get_put(iscsi_hashmap *map, uint8_t *key, const size_t key_size, uint8_t **out_in_value) { - if ( ((map->count + 1) > map->cap_load) && (iscsi_hashmap_resize( map ) < 0) ) - return -1L; + if ( ((map->count + 1U) > map->cap_load) && (iscsi_hashmap_resize( map ) < 0) ) + return -1; const uint32_t hash = iscsi_hashmap_hash_data( key, key_size ); iscsi_hashmap_bucket *entry = iscsi_hashmap_find_entry( map, key, key_size, hash ); @@ -1039,12 +1063,12 @@ int iscsi_hashmap_get_put(iscsi_hashmap *map, uint8_t *key, const size_t key_siz entry->key_size = key_size; entry->hash = hash; - return 0L; + return 0; } *out_in_value = entry->value; - return 1L; + return 1; } /** @@ -1087,8 +1111,8 @@ int iscsi_hashmap_get_put(iscsi_hashmap *map, uint8_t *key, const size_t key_siz */ 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) { - if ( ((map->count + 1) > map->cap_load) && (iscsi_hashmap_resize( map ) < 0) ) - return -1L; + if ( ((map->count + 1U) > map->cap_load) && (iscsi_hashmap_resize( map ) < 0) ) + return -1; const uint32_t hash = iscsi_hashmap_hash_data( key, key_size ); iscsi_hashmap_bucket *entry = iscsi_hashmap_find_entry( map, key, key_size, hash ); @@ -1105,7 +1129,7 @@ int iscsi_hashmap_put_free(iscsi_hashmap *map, uint8_t *key, const size_t key_si entry->hash = hash; entry->value = value; - return 0L; + return 0; } int err = callback( entry->key, key_size, entry->value, user_data ); @@ -1169,7 +1193,7 @@ int iscsi_hashmap_get(iscsi_hashmap *map, const uint8_t *key, const size_t key_s *out_value = entry->value; - return (entry->key != NULL) ? 0L : -1L; + return (entry->key != NULL) ? 0 : -1; } /** @@ -1316,7 +1340,7 @@ uint iscsi_hashmap_size(const iscsi_hashmap *map) int iscsi_hashmap_iterate(iscsi_hashmap *map, iscsi_hashmap_callback callback, uint8_t *user_data) { iscsi_hashmap_bucket *current = map->first; - int err = 0L; + int err = 0; while ( current != NULL ) { if ( current->key != NULL ) { @@ -1351,14 +1375,14 @@ iscsi_bhs_packet *iscsi_create_packet() return bhs_pkt; } - bhs_pkt->opcode = 0; // Initialize everything to zero - bhs_pkt->opcode_fields[0] = 0; - bhs_pkt->opcode_fields[1] = 0; - bhs_pkt->opcode_fields[2] = 0; - bhs_pkt->total_ahs_len = 0; - bhs_pkt->ds_len[0] = 0; - bhs_pkt->ds_len[1] = 0; - bhs_pkt->ds_len[2] = 0; + bhs_pkt->opcode = 0U; // Initialize everything to zero + bhs_pkt->opcode_fields[0] = 0U; + bhs_pkt->opcode_fields[1] = 0U; + bhs_pkt->opcode_fields[2] = 0U; + bhs_pkt->total_ahs_len = 0U; + bhs_pkt->ds_len[0] = 0U; + bhs_pkt->ds_len[1] = 0U; + bhs_pkt->ds_len[2] = 0U; bhs_pkt->lun_opcode.lun = 0ULL; bhs_pkt->init_task_tag = 0UL; @@ -1450,8 +1474,8 @@ int iscsi_get_ahs_packets(const iscsi_bhs_packet *packet_data) return 0; iscsi_ahs_packet *ahs_pkt = (iscsi_ahs_packet *) ((iscsi_bhs_packet *) packet_data + 1); // First AHS packet - int count = 0L; - uint32_t ahs_len = (uint32_t) packet_data->total_ahs_len << 2UL; + int count = 0; + uint32_t ahs_len = ((uint32_t) packet_data->total_ahs_len << 2UL); while ( (int32_t) ahs_len > 0L ) { uint32_t len = iscsi_get_be16(ahs_pkt->len) + offsetof(struct iscsi_ahs_packet, data); // Total length of current AHS packet @@ -1485,10 +1509,10 @@ iscsi_ahs_packet *iscsi_get_ahs_packet(const iscsi_bhs_packet *packet_data, cons iscsi_ahs_packet *ahs_pkt = (iscsi_ahs_packet *) ((iscsi_bhs_packet *) packet_data + 1); // First AHS packet int count = index; - uint32_t ahs_len = (uint32_t) packet_data->total_ahs_len << 2UL; + uint32_t ahs_len = ((uint32_t) packet_data->total_ahs_len << 2UL); while ( (int32_t) ahs_len > 0L ) { - if ( count-- < 0L ) + if ( count-- < 0 ) return ahs_pkt; uint32_t len = iscsi_get_be16(ahs_pkt->len) + offsetof(struct iscsi_ahs_packet, data); // Total length of current AHS packet @@ -1775,13 +1799,13 @@ static int iscsi_validate_text_key_value_pair(const uint8_t *packet_data, const if ( key_len > ISCSI_TEXT_KEY_MAX_LEN ) return ISCSI_VALIDATE_PACKET_RESULT_ERROR_PROTOCOL_SPECS; - const uint val_len = (uint) strnlen( (char *) (key_end + 1UL), key_val_len - key_len - 1UL ); - const uint max_len = (memcmp( packet_data, "CHAP_C=", (key_len + 1UL) ) == 0) || (memcmp( packet_data, "CHAP_R=", (key_len + 1UL) ) == 0) ? ISCSI_TEXT_VALUE_MAX_LEN : ISCSI_TEXT_VALUE_MAX_SIMPLE_LEN; + const uint val_len = (uint) strnlen( (char *) (key_end + 1UL), (key_val_len - key_len - 1U) ); + const uint max_len = (memcmp( packet_data, "CHAP_C=", (key_len + 1U) ) == 0) || (memcmp( packet_data, "CHAP_R=", (key_len + 1U) ) == 0) ? ISCSI_TEXT_VALUE_MAX_LEN : ISCSI_TEXT_VALUE_MAX_SIMPLE_LEN; if ( val_len > max_len ) return ISCSI_VALIDATE_PACKET_RESULT_ERROR_PROTOCOL_SPECS; // Value exceeds maximum length -> invalid iSCSI packet data - return (int) (key_len + 1UL + val_len + 1UL); // Number of bytes for processed key / value pair (+1 for '=' and NUL terminator) + return (int) (key_len + 1U + val_len + 1U); // Number of bytes for processed key / value pair (+1 for '=' and NUL terminator) } /** @@ -1802,7 +1826,7 @@ static int iscsi_validate_key_value_pairs(const uint8_t *packet_data, uint len) if ( len == 0 ) return ISCSI_VALIDATE_PACKET_RESULT_ERROR_PROTOCOL_SPECS; // Zero length is not allowed -> invalid iSCSI packet data - int offset = 0L; + int offset = 0; while ( ((uint) offset < len) && (packet_data[offset] != '\0') ) { const int rc = iscsi_validate_text_key_value_pair( (packet_data + offset), (len - offset) ); @@ -2123,7 +2147,7 @@ static int iscsi_parse_text_key_value_pair(iscsi_hashmap *key_value_pairs, const if ( key_end == NULL ) { logadd( LOG_ERROR, "iscsi_parse_text_key_value_pair: Key / value separator '=' not found" ); - return -1L; + return -1; } const uint key_len = (uint) (key_end - packet_data); @@ -2131,20 +2155,20 @@ static int iscsi_parse_text_key_value_pair(iscsi_hashmap *key_value_pairs, const if ( key_len == 0 ) { logadd( LOG_ERROR, "iscsi_parse_text_key_value_pair: Empty key found which is NOT allowed according to iSCSI specs" ); - return -1L; + return -1; } if ( key_len > ISCSI_TEXT_KEY_MAX_LEN ) { logadd( LOG_ERROR, "iscsi_parse_text_key_value_pair: Key value is too large (max 63 bytes)" ); - return -1L; + return -1; } - const uint hash_key_len = (key_len + 1UL); + const uint hash_key_len = (key_len + 1U); uint8_t *hash_key = iscsi_hashmap_key_create( packet_data, hash_key_len ); if ( hash_key == NULL ) - return -1L; + return -1; hash_key[key_len] = '\0'; @@ -2153,10 +2177,10 @@ static int iscsi_parse_text_key_value_pair(iscsi_hashmap *key_value_pairs, const iscsi_hashmap_key_destroy( hash_key ); - return -1L; + return -1; } - const uint val_len = (uint) strnlen( (char *) (key_end + 1UL), key_val_len - key_len - 1UL ); + const uint val_len = (uint) strnlen( (char *) (key_end + 1U), (key_val_len - key_len - 1U) ); const uint max_len = (strcmp( (char *) hash_key, "CHAP_C" ) == 0) || (strcmp( (char *) hash_key, "CHAP_R" ) == 0) ? ISCSI_TEXT_VALUE_MAX_LEN : ISCSI_TEXT_VALUE_MAX_SIMPLE_LEN; if ( val_len > max_len ) { @@ -2164,17 +2188,17 @@ static int iscsi_parse_text_key_value_pair(iscsi_hashmap *key_value_pairs, const iscsi_hashmap_key_destroy( hash_key ); - return -1L; + return -1; } - uint8_t *hash_val = (uint8_t *) malloc( iscsi_align(val_len + 1UL, ISCSI_HASHMAP_VALUE_ALIGN) ); + uint8_t *hash_val = (uint8_t *) malloc( iscsi_align(val_len + 1U, ISCSI_HASHMAP_VALUE_ALIGN) ); if ( hash_val == NULL ) { logadd( LOG_ERROR, "iscsi_parse_text_key_value_pair: Out of memory allocating memory for value string" ); iscsi_hashmap_key_destroy( hash_key ); - return -1L; + return -1; } memcpy( hash_val, key_end + 1, val_len ); @@ -2182,9 +2206,9 @@ static int iscsi_parse_text_key_value_pair(iscsi_hashmap *key_value_pairs, const const int rc = iscsi_hashmap_put( key_value_pairs, hash_key, hash_key_len, hash_val ); if ( rc < 0 ) - return -1L; + return -1; - return (int) (hash_key_len + val_len + 1UL); // Number of bytes for processed key / value pair (+1 for '=' and NUL terminator) + return (int) (hash_key_len + val_len + 1U); // Number of bytes for processed key / value pair (+1 for '=' and NUL terminator) } /** @@ -2209,7 +2233,7 @@ static int iscsi_parse_text_key_value_pair(iscsi_hashmap *key_value_pairs, const 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) { if ( len == 0 ) - return 0L; // iSCSI specs don't allow zero length + return 0; // iSCSI specs don't allow zero length if ( (partial_pairs != NULL) && (*partial_pairs != NULL) ) { // Strip partial text parameters in case C bit was enabled previously uint key_val_pair_len; @@ -2220,13 +2244,13 @@ int iscsi_parse_key_value_pairs(iscsi_hashmap *key_value_pairs, const uint8_t *p uint8_t *tmp_partial_buf = iscsi_sprintf_alloc( "%s%s", *partial_pairs, (const char *) packet_data ); if ( tmp_partial_buf == NULL ) - return -1L; + return -1; const int rc = iscsi_parse_text_key_value_pair( key_value_pairs, tmp_partial_buf, (uint32_t) (key_val_pair_len + strlen( (char *) *partial_pairs )) ); free( tmp_partial_buf ); if ( rc < 0 ) - return -1L; + return -1; free( *partial_pairs ); *partial_pairs = NULL; @@ -2239,45 +2263,45 @@ int iscsi_parse_key_value_pairs(iscsi_hashmap *key_value_pairs, const uint8_t *p if ( partial_pairs == NULL ) { logadd( LOG_ERROR, "iscsi_parse_key_value_pairs: C bit set but missing partial parameter" ); - return -1L; + return -1; } uint key_val_pair_len; - for (key_val_pair_len = len - 1; (packet_data[key_val_pair_len] != '\0') && (key_val_pair_len > 0); key_val_pair_len--) { + for (key_val_pair_len = (len - 1U); (packet_data[key_val_pair_len] != '\0') && (key_val_pair_len > 0U); key_val_pair_len--) { } if ( key_val_pair_len != 0 ) key_val_pair_len++; // NUL char found, don't copy to target buffer' - *partial_pairs = (uint8_t *) malloc ( (len - key_val_pair_len) + 1 ); + *partial_pairs = (uint8_t *) malloc( (len - key_val_pair_len) + 1 ); if ( *partial_pairs == NULL ) { logadd( LOG_ERROR, "iscsi_parse_key_value_pairs: Out of memory allocating partial parameter" ); - return -1L; + return -1; } memcpy( *partial_pairs, &packet_data[key_val_pair_len], (len - key_val_pair_len) ); if ( key_val_pair_len != 0 ) - len = key_val_pair_len - 1; + len = key_val_pair_len - 1U; else - return 0L; + return 0; } - int offset = 0L; + int offset = 0; while ( ((uint) offset < len) && (packet_data[offset] != '\0') ) { const int rc = iscsi_parse_text_key_value_pair( key_value_pairs, (packet_data + offset), (len - offset) ); if ( rc < 0 ) - return -1L; + return -1; offset += rc; } - return 0L; + return 0; } /** @@ -2297,7 +2321,7 @@ int iscsi_parse_key_value_pairs(iscsi_hashmap *key_value_pairs, const uint8_t *p */ static int iscsi_get_key_value_pair(iscsi_hashmap *key_value_pairs, const uint8_t *key, uint8_t **out_value) { - const uint key_len = (uint) strlen( (char *) key ) + 1UL; + const uint key_len = (uint) strlen( (char *) key ) + 1U; return iscsi_hashmap_get( key_value_pairs, key, key_len, out_value ); } @@ -2319,16 +2343,16 @@ static int iscsi_get_key_value_pair(iscsi_hashmap *key_value_pairs, const uint8_ */ static int iscsi_add_key_value_pair(iscsi_hashmap *key_value_pairs, const uint8_t *key, const uint8_t *value) { - const uint key_len = (uint) strlen( (char *) key ) + 1UL; + const uint key_len = (uint) strlen( (char *) key ) + 1U; uint8_t *hash_key = iscsi_hashmap_key_create( key, key_len ); if ( hash_key == NULL ) { logadd( LOG_ERROR, "iscsi_add_key_value_pair: Out of memory allocating key" ); - return -1L; + return -1; } - const uint val_len = (uint) strlen( (char *) value ) + 1UL; + const uint val_len = (uint) strlen( (char *) value ) + 1U; uint8_t *hash_val = (uint8_t *) malloc( iscsi_align(val_len, ISCSI_HASHMAP_VALUE_ALIGN) ); if ( hash_val == NULL ) { @@ -2336,7 +2360,7 @@ static int iscsi_add_key_value_pair(iscsi_hashmap *key_value_pairs, const uint8_ iscsi_hashmap_key_destroy( hash_key ); - return -1L; + return -1; } memcpy( hash_val, value, val_len ); @@ -2363,16 +2387,16 @@ static int iscsi_add_key_value_pair(iscsi_hashmap *key_value_pairs, const uint8_ */ static int iscsi_update_key_value_pair(iscsi_hashmap *key_value_pairs, const uint8_t *key, const uint8_t *value) { - const uint key_len = (uint) strlen( (char *) key ) + 1UL; + const uint key_len = (uint) strlen( (char *) key ) + 1U; uint8_t *hash_key = iscsi_hashmap_key_create( key, key_len ); if ( hash_key == NULL ) { logadd( LOG_ERROR, "iscsi_update_key_value_pair: Out of memory allocating key" ); - return -1L; + return -1; } - const uint val_len = (uint) strlen( (char *) value ) + 1UL; + const uint val_len = (uint) strlen( (char *) value ) + 1U; uint8_t *hash_val = (uint8_t *) malloc( iscsi_align(val_len, ISCSI_HASHMAP_VALUE_ALIGN) ); if ( hash_val == NULL ) { @@ -2380,7 +2404,7 @@ static int iscsi_update_key_value_pair(iscsi_hashmap *key_value_pairs, const uin iscsi_hashmap_key_destroy( hash_key ); - return -1L; + return -1; } memcpy( hash_val, value, val_len ); @@ -2436,7 +2460,7 @@ static int iscsi_add_int_key_value_pair(iscsi_hashmap *key_value_pairs, const ui if ( hash_val == NULL ) { logadd( LOG_ERROR, "iscsi_add_int_key_value_pair: Out of memory allocating integer value." ); - return -1L; + return -1; } return iscsi_add_key_value_pair( key_value_pairs, key, hash_val ); @@ -2466,7 +2490,7 @@ static int iscsi_update_int_key_value_pair(iscsi_hashmap *key_value_pairs, const if ( hash_val == NULL ) { logadd( LOG_ERROR, "iscsi_update_int_key_value_pair: Out of memory allocating integer value." ); - return -1L; + return -1; } return iscsi_update_key_value_pair( key_value_pairs, key, hash_val ); @@ -2493,7 +2517,7 @@ static int iscsi_get_bool_key_value_pair(iscsi_hashmap *key_value_pairs, const u int rc = iscsi_get_key_value_pair( key_value_pairs, key, &value ); if ( rc == 0 ) - *out_value = (strcasecmp( (char *) value, "Yes" ) == 0) ? true : false; + *out_value = (strcasecmp( (char *) value, "Yes" ) == 0); return rc; } @@ -2586,11 +2610,11 @@ iscsi_task *iscsi_task_create(iscsi_connection *conn, iscsi_task *parent, iscsi_ task->conn = conn; task->pdu = NULL; task->buf = NULL; - task->pos = 0UL; - task->len = 0UL; + task->pos = 0U; + task->len = 0U; task->id = 0ULL; - task->flags = 0L; - task->lun_id = 0L; + task->flags = 0; + task->lun_id = 0; task->init_task_tag = 0UL; task->target_xfer_tag = 0UL; task->des_data_xfer_len = 0UL; @@ -2697,11 +2721,11 @@ int iscsi_task_find_callback(uint8_t *key, const size_t key_size, uint8_t *value iscsi_task *task = (iscsi_task *) value; if ( task->target_xfer_tag != task_find->tag ) - return 0L; + return 0; task_find->task = task; - return -1L; + return -1; } /** @@ -2786,12 +2810,12 @@ int iscsi_task_xfer_complete_process_read_insert_before_callback(uint8_t *key, c iscsi_task *task = (iscsi_task *) value; if ( insert_before_task->task->scsi_task.pos >= task->scsi_task.pos ) - return 0L; + return 0; iscsi_hashmap_key_create_id( insert_before_task->sub_tasks, &task->id ); iscsi_hashmap_insert_before( insert_before_task->sub_tasks, (uint8_t *) &task->id, sizeof(task->id), (uint8_t *) task, key, key_size ); - return -1L; + return -1; } /** @@ -2824,7 +2848,7 @@ int iscsi_task_xfer_complete_process_read_sub_tasks_callback(uint8_t *key, const iscsi_task *sub_task = (iscsi_task *) value; if ( sub_task->scsi_task.pos != primary_task->pos ) - return -1L; + return -1; iscsi_hashmap_remove( primary_task->sub_tasks, key, key_size ); @@ -2836,7 +2860,7 @@ int iscsi_task_xfer_complete_process_read_sub_tasks_callback(uint8_t *key, const iscsi_task_response( proc_tasks_ordered->conn, sub_task ); iscsi_task_destroy( sub_task ); - return 0L; + return 0; } /** @@ -3023,7 +3047,7 @@ int iscsi_task_xfer_queued_tasks_start_callback(uint8_t *key, const size_t key_s iscsi_task *task = (iscsi_task *) value; if ( conn->r2t_pending >= ISCSI_DEFAULT_MAX_R2T_PER_CONNECTION ) - return -1L; + return -1; iscsi_hashmap_remove( conn->r2t_tasks_queue, key, key_size ); @@ -3077,7 +3101,7 @@ int iscsi_task_xfer_del_callback(uint8_t *key, const size_t key_size, uint8_t *v iscsi_task *task = (iscsi_task *) value; if ( task->target_xfer_tag != task_xfer_del->tag ) - return 0L; + return 0; iscsi_connection *conn = task_xfer_del->conn; @@ -3091,7 +3115,7 @@ int iscsi_task_xfer_del_callback(uint8_t *key, const size_t key_size, uint8_t *v iscsi_task_destroy( task ); iscsi_task_xfer_queued_tasks_start( conn ); - return -1L; + return -1; } /** @@ -3314,7 +3338,7 @@ static uint32_t iscsi_scsi_data_in_send(iscsi_connection *conn, iscsi_task *task static int iscsi_task_xfer_scsi_data_in(iscsi_connection *conn, iscsi_task *task) { if ( task->scsi_task.status != ISCSI_SCSI_STATUS_GOOD ) - return 0L; + return 0; const uint pos = task->scsi_task.pos; uint xfer_len = task->scsi_task.len; @@ -3333,9 +3357,9 @@ static int iscsi_task_xfer_scsi_data_in(iscsi_connection *conn, iscsi_task *task iscsi_task *primary_task = (task->parent != NULL) ? task->parent : task; uint32_t data_sn = primary_task->data_sn; - uint offset = 0UL; + uint offset = 0U; const uint max_burst_len = conn->session->max_burst_len; - uint data_in_seq_count = (uint) (((xfer_len - 1UL) / max_burst_len) + 1UL); + uint data_in_seq_count = (uint) (((xfer_len - 1U) / max_burst_len) + 1U); for (uint i = 0; i < data_in_seq_count; i++) { uint seq_end = (offset + max_burst_len); @@ -3520,7 +3544,7 @@ iscsi_portal_group *iscsi_portal_group_create(const int tag, const int flags) return NULL; } - portal_group->portals = iscsi_hashmap_create( 0UL ); + portal_group->portals = iscsi_hashmap_create( 0U ); if ( portal_group->portals == NULL ) { logadd( LOG_ERROR, "iscsi_portal_group_create: Out of memory allocating iSCSI portal hash map" ); @@ -3530,7 +3554,7 @@ iscsi_portal_group *iscsi_portal_group_create(const int tag, const int flags) return NULL; } - portal_group->ref_count = 0L; + portal_group->ref_count = 0; portal_group->tag = tag; portal_group->flags = flags; portal_group->chap_group = 0L; @@ -3558,7 +3582,7 @@ int iscsi_portal_destroy_callback(uint8_t *key, const size_t key_size, uint8_t * iscsi_portal_destroy( (iscsi_portal *) value ); iscsi_hashmap_key_destroy( key ); - return 0L; + return 0; } /** @@ -3604,9 +3628,9 @@ int iscsi_portal_group_add_portal(iscsi_portal_group *portal_group, iscsi_portal uint8_t *tmp_buf = iscsi_sprintf_alloc( "%s:%s", portal->host, portal->port ); if ( tmp_buf == NULL ) - return -1L; + return -1; - const uint key_len = (uint) strlen( (char *) tmp_buf ) + 1UL; + const uint key_len = (uint) strlen( (char *) tmp_buf ) + 1U; uint8_t *key = iscsi_hashmap_key_create( tmp_buf, key_len ); free( tmp_buf ); @@ -3614,7 +3638,7 @@ int iscsi_portal_group_add_portal(iscsi_portal_group *portal_group, iscsi_portal if ( key == NULL ) { logadd( LOG_ERROR, "iscsi_portal_group_add_portal: Out of memory allocating key for iSCSI portal" ); - return -1L; + return -1; } int rc = iscsi_hashmap_put( portal_group->portals, key, key_len, (uint8_t *) portal ); @@ -3629,7 +3653,7 @@ int iscsi_portal_group_add_portal(iscsi_portal_group *portal_group, iscsi_portal portal->group = portal_group; - return 0L; + return 0; } /** @@ -3655,7 +3679,7 @@ iscsi_portal *iscsi_portal_create(const uint8_t *host, const uint8_t *port) portal->group = NULL; - const uint host_len = (uint) strlen( (char *) host ) + 1UL; + const uint host_len = (uint) strlen( (char *) host ) + 1U; portal->host = (uint8_t *) malloc( host_len ); @@ -3667,7 +3691,7 @@ iscsi_portal *iscsi_portal_create(const uint8_t *host, const uint8_t *port) memcpy( portal->host, host, host_len ); - const uint port_len = (uint) strlen( (char *) port ) + 1UL; + const uint port_len = (uint) strlen( (char *) port ) + 1U; portal->port = (uint8_t *) malloc( port_len ); @@ -3679,7 +3703,7 @@ iscsi_portal *iscsi_portal_create(const uint8_t *host, const uint8_t *port) memcpy( portal->port, port, port_len ); - portal->sock = -1L; + portal->sock = -1; return portal; } @@ -3736,10 +3760,10 @@ void iscsi_scsi_task_create(iscsi_scsi_task *scsi_task, iscsi_scsi_task_xfer_com scsi_task->destroy_callback = destroy_callback; scsi_task->sense_data = NULL; scsi_task->buf = NULL; - scsi_task->pos = 0UL; - scsi_task->len = 0UL; + scsi_task->pos = 0U; + scsi_task->len = 0U; scsi_task->id = 0ULL; - scsi_task->flags = 0L; + scsi_task->flags = 0; scsi_task->ref = 1UL; scsi_task->xfer_len = 0UL; scsi_task->sense_data_len = 0U; @@ -3761,7 +3785,7 @@ void iscsi_scsi_task_create(iscsi_scsi_task *scsi_task, iscsi_scsi_task_xfer_com void iscsi_scsi_task_destroy(iscsi_scsi_task *scsi_task) { if ( scsi_task != NULL ) { - if ( --scsi_task->ref == 0 ) + if ( --scsi_task->ref == 0UL ) scsi_task->destroy_callback( scsi_task ); } } @@ -3807,7 +3831,7 @@ void iscsi_scsi_task_xfer_complete(iscsi_scsi_task *scsi_task) * @param[in] asc Additional Sense Code (ASC). * @param[in] ascq Additional Sense Code Qualifier (ASCQ). */ -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) +void iscsi_scsi_task_sense_data_build(iscsi_scsi_task *scsi_task, const uint8_t sense_key, const uint8_t asc, const uint8_t ascq) { iscsi_scsi_sense_data_check_cond_packet *sense_data = (iscsi_scsi_sense_data_check_cond_packet *) scsi_task->sense_data; @@ -3823,16 +3847,16 @@ void iscsi_scsi_task_sense_data_check_cond_build(iscsi_scsi_task *scsi_task, con scsi_task->sense_data = (iscsi_scsi_sense_data_packet *) sense_data; } - sense_data->sense_data.response_code = (int8_t) (ISCSI_SCSI_SENSE_DATA_RESPONSE_CODE_CURRENT_FMT | ISCSI_SCSI_SENSE_DATA_RESPONSE_CODE_VALID); + sense_data->sense_data.response_code = (int8_t) (ISCSI_SCSI_SENSE_DATA_PUT_RESPONSE_CODE(ISCSI_SCSI_SENSE_DATA_RESPONSE_CODE_CURRENT_FMT) | ISCSI_SCSI_SENSE_DATA_RESPONSE_CODE_VALID); sense_data->sense_data.reserved = 0U; - sense_data->sense_data.sense_key_flags = (sense_key & ISCSI_SCSI_SENSE_DATA_SENSE_KEY_MASK); + sense_data->sense_data.sense_key_flags = ISCSI_SCSI_SENSE_DATA_PUT_SENSE_KEY(sense_key); sense_data->sense_data.info = 0UL; // Zero does not require endianess conversion sense_data->sense_data.add_len = (sizeof(struct iscsi_scsi_sense_data_check_cond_packet) - sizeof(struct iscsi_scsi_sense_data_packet)); sense_data->cmd_spec_info = 0UL; // Zero does not require endianess conversion sense_data->asc = asc; sense_data->ascq = ascq; - sense_data->field_rep_unit_code = 0U; + sense_data->field_rep_unit_code = 0UL; sense_data->sense_key_spec_flags = 0U; sense_data->sense_key_spec = 0U; // Zero does not require endianess conversion @@ -3858,7 +3882,7 @@ void iscsi_scsi_task_sense_data_check_cond_build(iscsi_scsi_task *scsi_task, con static void iscsi_scsi_task_status_set(iscsi_scsi_task *scsi_task, const uint8_t status, const uint8_t sense_key, const uint8_t asc, const uint8_t ascq) { if ( status == ISCSI_SCSI_STATUS_CHECK_COND ) - iscsi_scsi_task_sense_data_check_cond_build( scsi_task, sense_key, asc, ascq ); + iscsi_scsi_task_sense_data_build( scsi_task, sense_key, asc, ascq ); scsi_task->status = status; } @@ -3888,7 +3912,7 @@ int iscsi_scsi_task_status_copy(iscsi_scsi_task *dst_scsi_task, const iscsi_scsi dst_scsi_task->sense_data = malloc( src_scsi_task->sense_data_len ); if ( dst_scsi_task == NULL ) - return -1L; + return -1; memcpy( dst_scsi_task->sense_data, src_scsi_task->sense_data, src_scsi_task->sense_data_len ); } else { @@ -3898,7 +3922,7 @@ int iscsi_scsi_task_status_copy(iscsi_scsi_task *dst_scsi_task, const iscsi_scsi dst_scsi_task->sense_data_len = src_scsi_task->sense_data_len; dst_scsi_task->status = src_scsi_task->status; - return 0L; + return 0; } /** @@ -3925,7 +3949,7 @@ void iscsi_scsi_task_lun_process_none(iscsi_scsi_task *scsi_task) memset( &std_inquiry_data_pkt, 0, len ); - std_inquiry_data_pkt.peripheral_type_id = ((ISCSI_SCSI_DATA_PERIPHERAL_TYPE_UNKNOWN << ISCSI_SCSI_DATA_PERIPHERAL_TYPE_FIRST_BIT) | (ISCSI_SCSI_DATA_PERIPHERAL_ID_NEVER << ISCSI_SCSI_DATA_PERIPHERAL_ID_FIRST_BIT)); + std_inquiry_data_pkt.peripheral_type_id = (ISCSI_SCSI_DATA_PUT_PERIPHERAL_TYPE(ISCSI_SCSI_DATA_PERIPHERAL_TYPE_UNKNOWN) | ISCSI_SCSI_DATA_PUT_PERIPHERAL_ID(ISCSI_SCSI_DATA_PERIPHERAL_ID_NEVER)); std_inquiry_data_pkt.add_len = (uint8_t) (len - sizeof(struct iscsi_scsi_data_packet)); const uint alloc_len = iscsi_get_be16(cdb->alloc_len); @@ -3940,7 +3964,7 @@ void iscsi_scsi_task_lun_process_none(iscsi_scsi_task *scsi_task) } else { iscsi_scsi_task_status_set( scsi_task, ISCSI_SCSI_STATUS_CHECK_COND, ISCSI_SCSI_SENSE_KEY_ILLEGAL_REQ, ISCSI_SCSI_ASC_LU_NOT_SUPPORTED, ISCSI_SCSI_ASCQ_CAUSE_NOT_REPORTABLE ); - scsi_task->pos = 0UL; + scsi_task->pos = 0U; } } @@ -3979,7 +4003,7 @@ iscsi_scsi_lun *iscsi_scsi_lun_create(const uint id) return NULL; } - lun->tasks = iscsi_hashmap_create( 0UL ); + lun->tasks = iscsi_hashmap_create( 0U ); if ( lun->tasks == NULL ) { logadd( LOG_ERROR, "iscsi_device_create: Out of memory allocating iSCSI device LUN tasks hash map" ); @@ -3989,7 +4013,7 @@ iscsi_scsi_lun *iscsi_scsi_lun_create(const uint id) return NULL; } - lun->tasks_pending = iscsi_hashmap_create( 0UL ); + lun->tasks_pending = iscsi_hashmap_create( 0U ); if ( lun->tasks_pending == NULL ) { logadd( LOG_ERROR, "iscsi_device_create: Out of memory allocating iSCSI device LUN pending tasks hash map" ); @@ -4000,7 +4024,7 @@ iscsi_scsi_lun *iscsi_scsi_lun_create(const uint id) return NULL; } - lun->tasks_mgmt = iscsi_hashmap_create( 0UL ); + lun->tasks_mgmt = iscsi_hashmap_create( 0U ); if ( lun->tasks_mgmt == NULL ) { logadd( LOG_ERROR, "iscsi_device_create: Out of memory allocating iSCSI device LUN management tasks hash map" ); @@ -4012,7 +4036,7 @@ iscsi_scsi_lun *iscsi_scsi_lun_create(const uint id) return NULL; } - lun->tasks_mgmt_pending = iscsi_hashmap_create( 0UL ); + lun->tasks_mgmt_pending = iscsi_hashmap_create( 0U ); if ( lun->tasks_mgmt_pending == NULL ) { logadd( LOG_ERROR, "iscsi_device_create: Out of memory allocating iSCSI device LUN pending management tasks hash map" ); @@ -4025,7 +4049,7 @@ iscsi_scsi_lun *iscsi_scsi_lun_create(const uint id) return NULL; } - lun->pr_regs = iscsi_hashmap_create( 0UL ); + lun->pr_regs = iscsi_hashmap_create( 0U ); if ( lun->pr_regs == NULL ) { logadd( LOG_ERROR, "iscsi_device_create: Out of memory allocating iSCSI device LUN Persistent Reservation (PR) registrant for I_T nexus hash map" ); @@ -4041,7 +4065,7 @@ iscsi_scsi_lun *iscsi_scsi_lun_create(const uint id) lun->pr_reservation.holder = NULL; lun->pr_reservation.cr_key = 0ULL; - lun->pr_reservation.type = 0L; + lun->pr_reservation.type = 0; lun->pr_reservation.flags = 0L; lun->pr_scsi2_holder.target_port = NULL; @@ -4053,9 +4077,10 @@ iscsi_scsi_lun *iscsi_scsi_lun_create(const uint id) lun->pr_scsi2_holder.rel_target_port_id = 0U; lun->pr_scsi2_holder.transport_id_len = 0U; + lun->device = NULL; lun->image = NULL; lun->id = id; - lun->flags = 0U; + lun->flags = 0; lun->pr_gen = 0UL; return lun; @@ -4212,7 +4237,7 @@ int iscsi_scsi_lun_tasks_exec_callback(uint8_t *key, const size_t key_size, uint iscsi_hashmap_remove( lun->tasks_pending, key, key_size ); iscsi_scsi_lun_task_run( lun, scsi_task ); - return 0L; + return 0; } /** @@ -4454,11 +4479,11 @@ int iscsi_scsi_pr_registrant_get_callback(uint8_t *key, const size_t key_size, u iscsi_scsi_pr_registrant *reg = (iscsi_scsi_pr_registrant *) value; if ( (reg_find->target_port != reg->target_port) || (reg_find->init_port != reg->init_port) ) - return 0L; + return 0; reg_find->reg = reg; - return -1L; + return -1; } /** @@ -4553,10 +4578,10 @@ int iscsi_scsi_pr_check(iscsi_scsi_task *scsi_task) if ( (reg == NULL) || ((reg->target_port == scsi_task->target_port) && (reg->init_port == scsi_task->init_port)) ) return ISCSI_SCSI_TASK_RUN_COMPLETE; - const iscsi_scsi_cdb_pr_reserve_out *cdb = (iscsi_scsi_cdb_pr_reserve_out *) scsi_task->cdb; + const iscsi_scsi_cdb *cdb = (iscsi_scsi_cdb *) scsi_task->cdb; bool dma_to_device = false; - switch ( cdb->cdb.opcode ) { + switch ( cdb->opcode ) { case ISCSI_SCSI_OPCODE_INQUIRY : case ISCSI_SCSI_OPCODE_REPORTLUNS : case ISCSI_SCSI_OPCODE_REQUESTSENSE : @@ -4590,7 +4615,8 @@ int iscsi_scsi_pr_check(iscsi_scsi_task *scsi_task) break; } case ISCSI_SCSI_OPCODE_PERSISTENT_RESERVE_OUT : { - const uint8_t action = ISCSI_SCSI_CDB_PR_RESERVE_OUT_GET_ACTION(cdb->lun_action); + const iscsi_scsi_cdb_pr_reserve_out *cdb_pr_reserve_out = (iscsi_scsi_cdb_pr_reserve_out *) cdb; + const uint8_t action = ISCSI_SCSI_CDB_PR_RESERVE_OUT_GET_ACTION(cdb_pr_reserve_out->action); switch ( action ) { case ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_REGISTER : @@ -4697,6 +4723,106 @@ int iscsi_scsi_pr_check(iscsi_scsi_task *scsi_task) } /** + * @brief Constructs an iSCSI SCSI Persistent Reservation (PR) out parameter list of an iSCSI SCSI task. + * + * This function also sets the SCSI + * status result code accordingly. + * + * @param[in] scsi_task Pointer to iSCSI SCSI task to + * construct Persistent Reservation (PR) + * out parameter list for. May NOT be NULL, + * so be careful. + * @param[in] pr_reserve_out_parameter_list Pointer to iSCSI SCSI Persistent + * Reservation (PR) out parameter list. NULL + * is NOT allowed here, take caution. + * @param[in] cdb_pr_reserve_out Pointer to iSCSI SCSI Command + * Descriptor Block (CDB) to construct the + * out data from and may NOT be NULL, so be + * careful. + * @param[in] len Length of parameter list in bytes. + * @return 0 on successful operation, a negative + * error code otherwise. + */ +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) +{ + // TODO: Implement function. + + return 0; +} + +/** + * @brief Constructs iSCSI SCSI Persistent Reservation (PR) in parameter data of an iSCSI SCSI task. + * + * This function also sets the SCSI + * status result code accordingly. + * + * @param[in] scsi_task Pointer to iSCSI SCSI task to + * construct Persistent Reservation (PR) + * in parameter data for. May NOT be NULL, + * so be careful. + * @param[in] pr_reserve_in_parameter_data Pointer to iSCSI SCSI Persistent + * Reservation (PR) in parameter data. NULL + * is NOT allowed here, take caution. + * @param[in] cdb_pr_reserve_in Pointer to iSCSI SCSI Command + * Descriptor Block (CDB) to construct the + * in data from and may NOT be NULL, so be + * careful. + * @param[in] len Length of parameter data in bytes. + * @return 0 on successful operation, a negative + * error code otherwise. + */ +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) +{ + // TODO: Implement function. + + return 0; +} + +/** + * @brief Reserves an iSCSI SCSI Persistent Reservation (PR) of an iSCSI SCSI task. + * + * This function also sets the SCSI + * status result code accordingly. + * + * @param[in] scsi_task Pointer to iSCSI SCSI task to + * reserve the Persistent Reservation + * (PR) for. May NOT be NULL, so be + * careful. + * @param[in] cdb_pr_reserve_6 Pointer to iSCSI SCSI Command + * Descriptor Block (CDB) to reserve the + * data from. NULL is NOT allowed here, + * take caution. + * @return 0 on successful operation, a negative + * error code otherwise. + */ +int iscsi_scsi_pr_reserve_scsi2(iscsi_scsi_task *scsi_task, const iscsi_scsi_cdb_pr_reserve_6 *cdb_pr_reserve_6) +{ + // TODO: Implement function. + + return 0; +} + +/** + * @brief Releases an iSCSI SCSI Persistent Reservation (PR) of an iSCSI SCSI task. + * + * This function also sets the SCSI + * status result code accordingly. + * + * @param[in] scsi_task Pointer to iSCSI SCSI task to + * release the Persistent Reservation + * (PR) for. May NOT be NULL, so be + * careful. + * @return 0 on successful operation, a negative + * error code otherwise. + */ +int iscsi_scsi_pr_release_scsi2(iscsi_scsi_task *scsi_task) +{ + // TODO: Implement function. + + return 0; +} + +/** * @brief Checks whether an I/O feature is supported by a DNBD3 image. * * This function depends on DNBB3 image @@ -4797,7 +4923,7 @@ static inline uint32_t iscsi_scsi_emu_block_get_size(const dnbd3_image_t *image) */ static inline uint32_t iscsi_scsi_emu_block_get_ratio_shift(const dnbd3_image_t *image) { - return (ISCSI_SCSI_EMU_PHYSICAL_BLOCK_SIZE_BITS - ISCSI_SCSI_EMU_BLOCK_SIZE_BITS); + return (ISCSI_SCSI_EMU_BLOCK_SIZE_BITS - ISCSI_SCSI_EMU_PHYSICAL_BLOCK_SIZE_BITS); } /** @@ -4845,7 +4971,7 @@ static int iscsi_scsi_emu_block_read_write(dnbd3_image_t *image, iscsi_scsi_task { // TODO: Implement SCSI emulation for DNBD3 image. - return 0L; + return 0; } /** @@ -4871,7 +4997,7 @@ static int iscsi_scsi_emu_block_sync(dnbd3_image_t *image, iscsi_scsi_task *scsi { // TODO: Implement SCSI emulation for DNBD3 image. - return 0L; + return 0; } /** @@ -4894,7 +5020,7 @@ static int iscsi_scsi_emu_block_unmap(dnbd3_image_t *image, iscsi_scsi_task *scs { // TODO: Implement SCSI emulation for DNBD3 image. - return 0L; + return 0; } /** @@ -4921,7 +5047,7 @@ static int iscsi_scsi_emu_block_write_same(dnbd3_image_t *image, iscsi_scsi_task { // TODO: Implement SCSI emulation for DNBD3 image. - return 0L; + return 0; } /** @@ -4938,7 +5064,7 @@ static int iscsi_scsi_emu_block_write_same(dnbd3_image_t *image, iscsi_scsi_task */ static int iscsi_scsi_emu_block_process(iscsi_scsi_task *scsi_task) { - iscsi_scsi_lun *lun = scsi_task->lun; + iscsi_scsi_lun *lun = scsi_task->lun; uint64_t lba; uint32_t xfer_len; @@ -4950,10 +5076,10 @@ static int iscsi_scsi_emu_block_process(iscsi_scsi_task *scsi_task) lba = iscsi_get_be24(cdb_read_write_6->lba); xfer_len = cdb_read_write_6->xfer_len; - if ( xfer_len == 0 ) + if ( xfer_len == 0UL ) xfer_len = 256UL; - return iscsi_scsi_emu_block_read_write( lun->image, scsi_task, lba, xfer_len, ((scsi_task->cdb->opcode == ISCSI_SCSI_OPCODE_WRITE6) ? ISCSI_SCSI_EMU_BLOCK_FLAGS_WRITE : 0L) ); + return iscsi_scsi_emu_block_read_write( lun->image, scsi_task, lba, xfer_len, ((scsi_task->cdb->opcode == ISCSI_SCSI_OPCODE_WRITE6) ? ISCSI_SCSI_EMU_BLOCK_FLAGS_WRITE : 0) ); break; } @@ -4964,7 +5090,7 @@ static int iscsi_scsi_emu_block_process(iscsi_scsi_task *scsi_task) lba = iscsi_get_be32(cdb_read_write_10->lba); xfer_len = iscsi_get_be16(cdb_read_write_10->xfer_len); - return iscsi_scsi_emu_block_read_write( lun->image, scsi_task, lba, xfer_len, ((scsi_task->cdb->opcode == ISCSI_SCSI_OPCODE_WRITE10) ? ISCSI_SCSI_EMU_BLOCK_FLAGS_WRITE : 0L) ); + return iscsi_scsi_emu_block_read_write( lun->image, scsi_task, lba, xfer_len, ((scsi_task->cdb->opcode == ISCSI_SCSI_OPCODE_WRITE10) ? ISCSI_SCSI_EMU_BLOCK_FLAGS_WRITE : 0) ); break; } @@ -4975,7 +5101,7 @@ static int iscsi_scsi_emu_block_process(iscsi_scsi_task *scsi_task) lba = iscsi_get_be32(cdb_read_write_12->lba); xfer_len = iscsi_get_be32(cdb_read_write_12->xfer_len); - return iscsi_scsi_emu_block_read_write( lun->image, scsi_task, lba, xfer_len, ((scsi_task->cdb->opcode == ISCSI_SCSI_OPCODE_WRITE12) ? ISCSI_SCSI_EMU_BLOCK_FLAGS_WRITE : 0L) ); + return iscsi_scsi_emu_block_read_write( lun->image, scsi_task, lba, xfer_len, ((scsi_task->cdb->opcode == ISCSI_SCSI_OPCODE_WRITE12) ? ISCSI_SCSI_EMU_BLOCK_FLAGS_WRITE : 0) ); break; } @@ -4986,7 +5112,7 @@ static int iscsi_scsi_emu_block_process(iscsi_scsi_task *scsi_task) lba = iscsi_get_be64(cdb_read_write_16->lba); xfer_len = iscsi_get_be32(cdb_read_write_16->xfer_len); - return iscsi_scsi_emu_block_read_write( lun->image, scsi_task, lba, xfer_len, ((scsi_task->cdb->opcode == ISCSI_SCSI_OPCODE_WRITE16) ? ISCSI_SCSI_EMU_BLOCK_FLAGS_WRITE : 0L) ); + return iscsi_scsi_emu_block_read_write( lun->image, scsi_task, lba, xfer_len, ((scsi_task->cdb->opcode == ISCSI_SCSI_OPCODE_WRITE16) ? ISCSI_SCSI_EMU_BLOCK_FLAGS_WRITE : 0) ); break; } @@ -4996,7 +5122,7 @@ static int iscsi_scsi_emu_block_process(iscsi_scsi_task *scsi_task) lba = iscsi_get_be64(cdb_cmp_write->lba); xfer_len = cdb_cmp_write->num_blocks; - if ( ((cdb_cmp_write->flags & ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_FUA) != 0) || ((cdb_cmp_write->flags & ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_DPO) != 0) || ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_GET_WRPROTECT(cdb_cmp_write->flags) ) { + if ( ((cdb_cmp_write->flags & (ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_FUA | ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_DPO)) != 0) || ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_GET_WRPROTECT(cdb_cmp_write->flags) ) { iscsi_scsi_task_status_set( scsi_task, ISCSI_SCSI_STATUS_CHECK_COND, ISCSI_SCSI_SENSE_KEY_ILLEGAL_REQ, ISCSI_SCSI_ASC_INVALID_FIELD_IN_CDB, ISCSI_SCSI_ASCQ_CAUSE_NOT_REPORTABLE ); return ISCSI_SCSI_TASK_RUN_COMPLETE; @@ -5066,7 +5192,7 @@ static int iscsi_scsi_emu_block_process(iscsi_scsi_task *scsi_task) const uint8_t exponent = (uint8_t) iscsi_scsi_emu_block_get_ratio_shift( lun->image ); - buf->expontents = ((exponent <= ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_MASK) ? exponent : 0U); + buf->exponents = ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_PUT_LBPPB_EXPONENT((exponent <= ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_MASK) ? exponent : 0U); if ( iscsi_scsi_emu_io_type_is_supported( lun->image, ISCSI_SCSI_EMU_IO_TYPE_UNMAP ) ) iscsi_put_be16( (uint8_t *) &buf->lbp_lalba, ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPME ); @@ -5158,6 +5284,203 @@ static int iscsi_scsi_emu_block_process(iscsi_scsi_task *scsi_task) } /** + * @brief Checks whether provided SCSI CDB allocation length is large enough. + * + * This function also sets the SCSI + * status result code if the allocation + * size is insufficent. + * + * @param[in] scsi_task Pointer to iSCSI SCSI task to set + * the iSCSI status result code for and + * may NOT be NULL, so be careful. + * @param[in] len Actual length in bytes passed to check. + * @param[in] min_len Minimum length in bytes required. + * @retval 0 Allocation length is sufficent. + * @retval -1 Allocation length is insufficent, SCSI status + * code set. + */ +static int iscsi_scsi_emu_check_len(iscsi_scsi_task *scsi_task, const uint len, const uint min_len) +{ + if ( len >= min_len ) + return 0; + + iscsi_scsi_task_status_set( scsi_task, ISCSI_SCSI_STATUS_CHECK_COND, ISCSI_SCSI_SENSE_KEY_ILLEGAL_REQ, ISCSI_SCSI_ASC_INVALID_FIELD_IN_CDB, ISCSI_SCSI_ASCQ_CAUSE_NOT_REPORTABLE ); + + return -1; +} + +/** + * @brief Executes an inquiry operation on a DNBD3 image. + * + * This function also sets the SCSI + * status result code accordingly. + * + * @param[in] image Pointer to DNBD3 image to get + * the inquiry data from. May NOT be + * NULL, so be careful. + * @param[in] scsi_task Pointer to iSCSI SCSI task + * responsible for this inqueiry + * request. NULL is NOT allowed here, + * take caution. + * @param[in] cdb_inquiry Pointer to Command Descriptor + * Block (CDB) and may NOT be NULL, be + * careful. + * @param[in] std_inquiry_data_pkt Pointer to standard inquiry + * data packet to fill the inquiry + * data with. + * @param[in] len Length of inquiry result buffer + * in bytes. + * @return 0 on successful operation, a negative + * error code otherwise. + */ +static int iscsi_scsi_emu_primary_inquiry(dnbd3_image_t *image, iscsi_scsi_task *scsi_task, const iscsi_scsi_cdb_inquiry *cdb_inquiry, iscsi_scsi_std_inquiry_data_packet *std_inquiry_data_pkt, const uint len) +{ + // TODO: Implement SCSI emulation for DNBD3 image. + + return 0; +} + +/** + * @brief Fills in a single LUN entry of a report LUNs operation on a DNBD3 image. + * + * Callback function for each element while iterating + * through the iSCSI SCSI LUNs hash map.\n + * The iteration process is aborted when the + * remaining allocation length is not enough + * to hold the current LUN. + * + * @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. + * @param[in] value Value of the key, NULL creates an + * empty key assignment. + * @param[in,out] user_data Pointer to a data structure + * containing the report LUN list, the + * current report LUN entry, the total + * length of all LUN entries in bytes, the + * remaining allocation length in bytes and + * the selected report. May NOT be NULL, so + * be careful. + * @retval -1 Operation failure, ran out of + * allocation space during traversal. + * @retval 0 Successful operation, there is enough + * allocation space to store this + * reported LUN entry. + */ +int iscsi_scsi_emu_primary_report_luns_callback(uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *user_data) +{ + iscsi_scsi_emu_primary_report_luns_fill *lun_report_fill = (iscsi_scsi_emu_primary_report_luns_fill *) user_data; + iscsi_scsi_lun *scsi_lun = (iscsi_scsi_lun *) value; + + lun_report_fill->alloc_len -= (uint) sizeof(struct iscsi_scsi_report_luns_parameter_data_lun_entry_packet); + + if ( (int) lun_report_fill->alloc_len < 0 ) + return -1; + + lun_report_fill->len += (uint) sizeof(struct iscsi_scsi_report_luns_parameter_data_lun_entry_packet); + + const uint64_t lun = iscsi_scsi_lun_get_from_scsi( scsi_lun->id ); + iscsi_put_be64( (uint8_t *) &lun_report_fill->lun_entry->lun, lun ); + + lun_report_fill->lun_entry++; + + return 0; +} + +/** + * @brief Executes a report LUNs operation on a DNBD3 image. + * + * This function also sets the SCSI + * status result code accordingly. + * + * @param[in] lun Pointer to iSCSI SCSI LUN to + * report the LUNs for. May NOT be + * NULL, so be careful. + * @param[in] report_luns_parameter_data_pkt Pointer to report LUNS + * parameter data packet to fill the + * LUN data data with. + * @param[in] len Length of LUN reporting result buffer + * in bytes. + * @param[in] select_report Selected report. + * @return Total length of LUN data on successful + * operation, a negative error code + * otherwise. + */ +static int iscsi_scsi_emu_primary_report_luns(iscsi_scsi_lun *lun, iscsi_scsi_report_luns_parameter_data_lun_list_packet *report_luns_parameter_data_pkt, const uint len, const uint select_report) +{ + if ( len < sizeof(struct iscsi_scsi_report_luns_parameter_data_lun_list_packet) ) + return -1; + + switch ( select_report ) { + case ISCSI_SCSI_CDB_REPORT_LUNS_SELECT_REPORT_LU_ADDR_METHOD : { + break; + } + case ISCSI_SCSI_CDB_REPORT_LUNS_SELECT_REPORT_LU_KNOWN : { + break; + } + case ISCSI_SCSI_CDB_REPORT_LUNS_SELECT_REPORT_LU_ALL : { + break; + } + default : { + return -1; + + break; + } + } + + report_luns_parameter_data_pkt->lun_list_len = 0UL; + report_luns_parameter_data_pkt->reserved = 0UL; + + iscsi_scsi_emu_primary_report_luns_fill lun_report_fill = {report_luns_parameter_data_pkt, (iscsi_scsi_report_luns_parameter_data_lun_entry_packet *) (report_luns_parameter_data_pkt + 1), 0U, (uint) (len - sizeof(struct iscsi_scsi_report_luns_parameter_data_lun_list_packet)), select_report }; + + const int rc = iscsi_hashmap_iterate( lun->device->luns, iscsi_scsi_emu_primary_report_luns_callback, (uint8_t *) &lun_report_fill ); + + if ( rc < 0 ) + return -1; + + iscsi_put_be32( (uint8_t *) &report_luns_parameter_data_pkt->lun_list_len, lun_report_fill.len ); + + return (int) (lun_report_fill.len + sizeof(struct iscsi_scsi_report_luns_parameter_data_lun_list_packet)); +} + +/** + * @brief Executes a mode sense operation on a DNBD3 image. + * + * This function also sets the SCSI + * status result code accordingly. + * + * @param[in] image Pointer to DNBD3 image to sense. + * May NOT be NULL, so be careful. + * @param[in] scsi_task Pointer to iSCSI SCSI task + * responsible for this sense task. + * NULL is NOT allowed here, take + * caution. + * @param[in] cdb_mode_sense Pointer to Command Descriptor + * Block (CDB) and may NOT be NULL, be + * careful. + * @param[in] mode_sense_parameter_data_pkt Pointer to mode sense parameter + * data packet to fill the mode sense + * data with. If this is NULL, only the + * length of sense data is calculated. + * @param[in] len Length of sense result buffer + * in bytes. + * @param[in] dbd Disable Block Descriptors (DBD). + * @param[in] llba Long LBA Accepted (LLBAA). + * @param[in] pc Page control (PC). + * @param[in] page_code Page code. + * @param[in] sub_page_code Sub page code. + * @return Total length of sense data on successful + * operation, a negative error code + * otherwise. + */ +static int iscsi_scsi_emu_primary_mode_sense(dnbd3_image_t *image, iscsi_scsi_task *scsi_task, const iscsi_scsi_cdb_mode_sense_6 *cdb_mode_sense, iscsi_scsi_mode_sense_parameter_data_packet *mode_sense_parameter_data_pkt, const uint len, const int dbd, const int llba, const uint pc, const uint page_code, const uint sub_page_code) +{ + // TODO: Implement SCSI emulation for DNBD3 image. + + return 0; +} + +/** * @brief Executes SCSI non-block emulation on a DNBD3 image. * * This function determines the @@ -5173,9 +5496,419 @@ static int iscsi_scsi_emu_block_process(iscsi_scsi_task *scsi_task) */ static int iscsi_scsi_emu_primary_process(iscsi_scsi_task *scsi_task) { - // TODO: Implement SCSI emulation for DNBD3 image. + iscsi_scsi_lun *lun = scsi_task->lun; + uint alloc_len; + uint len; + int rc; + + switch ( scsi_task->cdb->opcode ) { + case ISCSI_SCSI_OPCODE_INQUIRY : { + const iscsi_scsi_cdb_inquiry *cdb_inquiry = (iscsi_scsi_cdb_inquiry *) scsi_task->cdb; + + alloc_len = iscsi_get_be16(cdb_inquiry->alloc_len); + len = alloc_len; + + if ( len > 4096U ) + len = 4096U; + + iscsi_scsi_std_inquiry_data_packet *std_inquiry_data_pkt = NULL; + + if ( len > 0U ) { + std_inquiry_data_pkt = (iscsi_scsi_std_inquiry_data_packet *) malloc( len ); + + if ( std_inquiry_data_pkt == NULL ) { + iscsi_scsi_task_status_set( scsi_task, ISCSI_SCSI_STATUS_CHECK_COND, ISCSI_SCSI_SENSE_KEY_HARDWARE_ERR, ISCSI_SCSI_ASC_WARNING, ISCSI_SCSI_ASCQ_POWER_LOSS_EXPECTED ); + + break; + } + } + + rc = iscsi_scsi_emu_primary_inquiry( lun->image, scsi_task, cdb_inquiry, std_inquiry_data_pkt, len ); + + if ( (rc >= 0) && (len > 0U) ) { + if ( len > alloc_len ) + len = alloc_len; + + scsi_task->buf = (uint8_t *) std_inquiry_data_pkt; + rc = len; + } + + if ( rc >= 0 ) { + scsi_task->pos = rc; + scsi_task->status = ISCSI_SCSI_STATUS_GOOD; + } + + break; + } + case ISCSI_SCSI_OPCODE_REPORTLUNS : { + const iscsi_scsi_cdb_report_luns *cdb_report_luns = (iscsi_scsi_cdb_report_luns *) scsi_task->cdb; + + alloc_len = iscsi_get_be32(cdb_report_luns->alloc_len); + rc = iscsi_scsi_emu_check_len( scsi_task, alloc_len, (sizeof(struct iscsi_scsi_report_luns_parameter_data_lun_list_packet) + sizeof(struct iscsi_scsi_report_luns_parameter_data_lun_entry_packet)) ); + + if ( rc < 0 ) + break; + + len = alloc_len; + + if ( len > 4096U ) + len = 4096U; + + iscsi_scsi_report_luns_parameter_data_lun_list_packet *report_luns_parameter_data_pkt = NULL; + + if ( len > 0U ) { + report_luns_parameter_data_pkt = (iscsi_scsi_report_luns_parameter_data_lun_list_packet *) malloc( len ); + + if ( report_luns_parameter_data_pkt == NULL ) { + iscsi_scsi_task_status_set( scsi_task, ISCSI_SCSI_STATUS_CHECK_COND, ISCSI_SCSI_SENSE_KEY_HARDWARE_ERR, ISCSI_SCSI_ASC_WARNING, ISCSI_SCSI_ASCQ_POWER_LOSS_EXPECTED ); - return 0L; + break; + } + } + + rc = iscsi_scsi_emu_primary_report_luns( lun, report_luns_parameter_data_pkt, len, cdb_report_luns->select_report ); + + if ( rc < 0 ) { + free( report_luns_parameter_data_pkt ); + iscsi_scsi_task_status_set( scsi_task, ISCSI_SCSI_STATUS_CHECK_COND, ISCSI_SCSI_SENSE_KEY_NO_SENSE, ISCSI_SCSI_ASC_NO_ADDITIONAL_SENSE, ISCSI_SCSI_ASCQ_CAUSE_NOT_REPORTABLE ); + + break; + } + + len = rc; + + if ( len > 0U ) { + if ( len > alloc_len ) + len = alloc_len; + + scsi_task->buf = (uint8_t *) report_luns_parameter_data_pkt; + } + + scsi_task->pos = len; + scsi_task->status = ISCSI_SCSI_STATUS_GOOD; + + break; + } + case ISCSI_SCSI_OPCODE_MODESELECT6 : { + const iscsi_scsi_cdb_mode_select_6 *cdb_mode_select_6 = (iscsi_scsi_cdb_mode_select_6 *) scsi_task->cdb; + + alloc_len = cdb_mode_select_6->param_list_len; + + if ( alloc_len == 0 ) + break; + + rc = iscsi_scsi_emu_check_len( scsi_task, alloc_len, sizeof(struct iscsi_scsi_mode_select_6_parameter_list_packet) ); + + if ( rc < 0 ) + break; + + len = scsi_task->len; + + if ( alloc_len < sizeof(struct iscsi_scsi_mode_select_6_parameter_list_packet) ) + alloc_len = sizeof(struct iscsi_scsi_mode_select_6_parameter_list_packet); + + rc = iscsi_scsi_emu_check_len( scsi_task, len, alloc_len ); + + if ( rc < 0 ) + break; + + scsi_task->pos = alloc_len; + scsi_task->status = ISCSI_SCSI_STATUS_GOOD; + + break; + } + case ISCSI_SCSI_OPCODE_MODESELECT10 : { + const iscsi_scsi_cdb_mode_select_10 *cdb_mode_select_10 = (iscsi_scsi_cdb_mode_select_10 *) scsi_task->cdb; + + alloc_len = iscsi_get_be16(cdb_mode_select_10->param_list_len); + + if ( alloc_len == 0 ) + break; + + rc = iscsi_scsi_emu_check_len( scsi_task, alloc_len, sizeof(struct iscsi_scsi_mode_select_10_parameter_list_packet) ); + + if ( rc < 0 ) + break; + + len = scsi_task->len; + + if ( alloc_len < sizeof(struct iscsi_scsi_mode_select_10_parameter_list_packet) ) + alloc_len = sizeof(struct iscsi_scsi_mode_select_10_parameter_list_packet); + + rc = iscsi_scsi_emu_check_len( scsi_task, len, alloc_len ); + + if ( rc < 0 ) + break; + + scsi_task->pos = alloc_len; + scsi_task->status = ISCSI_SCSI_STATUS_GOOD; + + break; + } + case ISCSI_SCSI_OPCODE_MODESENSE6 : { + const iscsi_scsi_cdb_mode_sense_6 *cdb_mode_sense_6 = (iscsi_scsi_cdb_mode_sense_6 *) scsi_task->cdb; + + alloc_len = cdb_mode_sense_6->alloc_len; + + const int dbd = (cdb_mode_sense_6->flags & ISCSI_SCSI_CDB_MODE_SENSE_6_FLAGS_DBD); + const uint pc = ISCSI_SCSI_CDB_MODE_SENSE_6_GET_PAGE_CONTROL(cdb_mode_sense_6->page_code_control); + const uint page = ISCSI_SCSI_CDB_MODE_SENSE_6_GET_PAGE_CODE(cdb_mode_sense_6->page_code_control); + const uint sub_page = cdb_mode_sense_6->sub_page_code; + + rc = iscsi_scsi_emu_primary_mode_sense( lun->image, scsi_task, cdb_mode_sense_6, NULL, sizeof(struct iscsi_scsi_cdb_mode_sense_6), dbd, 0U, pc, page, sub_page ); + + if ( rc < 0 ) + break; + + len = rc; + + iscsi_scsi_mode_sense_parameter_data_packet *mode_sense_parameter_data_pkt = (iscsi_scsi_mode_sense_parameter_data_packet *) malloc( len ); + + if ( mode_sense_parameter_data_pkt == NULL ) { + iscsi_scsi_task_status_set( scsi_task, ISCSI_SCSI_STATUS_CHECK_COND, ISCSI_SCSI_SENSE_KEY_HARDWARE_ERR, ISCSI_SCSI_ASC_WARNING, ISCSI_SCSI_ASCQ_POWER_LOSS_EXPECTED ); + + break; + } + + rc = iscsi_scsi_emu_primary_mode_sense( lun->image, scsi_task, cdb_mode_sense_6, mode_sense_parameter_data_pkt, sizeof(struct iscsi_scsi_cdb_mode_sense_6), dbd, 0U, pc, page, sub_page ); + + if ( rc < 0 ) { + free( mode_sense_parameter_data_pkt ); + iscsi_scsi_task_status_set( scsi_task, ISCSI_SCSI_STATUS_CHECK_COND, ISCSI_SCSI_SENSE_KEY_ILLEGAL_REQ, ISCSI_SCSI_ASC_INVALID_FIELD_IN_CDB, ISCSI_SCSI_ASCQ_CAUSE_NOT_REPORTABLE ); + + break; + } + + if ( (rc >= 0) && (len > 0U) ) { + if ( len > alloc_len ) + len = alloc_len; + + scsi_task->buf = (uint8_t *) mode_sense_parameter_data_pkt; + rc = len; + } + + if ( rc >= 0 ) { + scsi_task->pos = rc; + scsi_task->status = ISCSI_SCSI_STATUS_GOOD; + } + + break; + } + case ISCSI_SCSI_OPCODE_MODESENSE10 : { + const iscsi_scsi_cdb_mode_sense_10 *cdb_mode_sense_10 = (iscsi_scsi_cdb_mode_sense_10 *) scsi_task->cdb; + + alloc_len = iscsi_get_be16(cdb_mode_sense_10->alloc_len); + + const int dbd10 = (cdb_mode_sense_10->flags & ISCSI_SCSI_CDB_MODE_SENSE_10_FLAGS_DBD); + const int llba = (cdb_mode_sense_10->flags & ISCSI_SCSI_CDB_MODE_SENSE_10_FLAGS_LLBAA); + const uint pc10 = ISCSI_SCSI_CDB_MODE_SENSE_10_GET_PAGE_CONTROL(cdb_mode_sense_10->page_code_control); + const uint page10 = ISCSI_SCSI_CDB_MODE_SENSE_10_GET_PAGE_CODE(cdb_mode_sense_10->page_code_control); + const uint sub_page10 = cdb_mode_sense_10->sub_page_code; + + rc = iscsi_scsi_emu_primary_mode_sense( lun->image, scsi_task, (iscsi_scsi_cdb_mode_sense_6 *) cdb_mode_sense_10, NULL, sizeof(struct iscsi_scsi_cdb_mode_sense_10), dbd10, llba, pc10, page10, sub_page10 ); + + if ( rc < 0 ) + break; + + len = rc; + + iscsi_scsi_mode_sense_parameter_data_packet *mode_sense_parameter_data_pkt = (iscsi_scsi_mode_sense_parameter_data_packet *) malloc( len ); + + if ( mode_sense_parameter_data_pkt == NULL ) { + iscsi_scsi_task_status_set( scsi_task, ISCSI_SCSI_STATUS_CHECK_COND, ISCSI_SCSI_SENSE_KEY_HARDWARE_ERR, ISCSI_SCSI_ASC_WARNING, ISCSI_SCSI_ASCQ_POWER_LOSS_EXPECTED ); + + break; + } + + rc = iscsi_scsi_emu_primary_mode_sense( lun->image, scsi_task, (iscsi_scsi_cdb_mode_sense_6 *) cdb_mode_sense_10, mode_sense_parameter_data_pkt, sizeof(struct iscsi_scsi_cdb_mode_sense_10), dbd10, llba, pc10, page10, sub_page10 ); + + if ( rc < 0 ) { + free( mode_sense_parameter_data_pkt ); + iscsi_scsi_task_status_set( scsi_task, ISCSI_SCSI_STATUS_CHECK_COND, ISCSI_SCSI_SENSE_KEY_ILLEGAL_REQ, ISCSI_SCSI_ASC_INVALID_FIELD_IN_CDB, ISCSI_SCSI_ASCQ_CAUSE_NOT_REPORTABLE ); + + break; + } + + if ( (rc >= 0) && (len > 0U) ) { + if ( len > alloc_len ) + len = alloc_len; + + scsi_task->buf = (uint8_t *) mode_sense_parameter_data_pkt; + rc = len; + } + + if ( rc >= 0 ) { + scsi_task->pos = rc; + scsi_task->status = ISCSI_SCSI_STATUS_GOOD; + } + + break; + } + case ISCSI_SCSI_OPCODE_REQUESTSENSE : { + const iscsi_scsi_cdb_req_sense *cdb_req_sense = (iscsi_scsi_cdb_req_sense *) scsi_task->cdb; + + if ( (cdb_req_sense->flags & ISCSI_SCSI_CDB_REQ_SENSE_FLAGS_DESC) != 0 ) { + iscsi_scsi_task_status_set( scsi_task, ISCSI_SCSI_STATUS_CHECK_COND, ISCSI_SCSI_SENSE_KEY_ILLEGAL_REQ, ISCSI_SCSI_ASC_INVALID_FIELD_IN_CDB, ISCSI_SCSI_ASCQ_CAUSE_NOT_REPORTABLE ); + + break; + } + + alloc_len = cdb_req_sense->alloc_len; + + iscsi_scsi_task_sense_data_build( scsi_task, ISCSI_SCSI_SENSE_KEY_NO_SENSE, ISCSI_SCSI_ASC_NO_ADDITIONAL_SENSE, ISCSI_SCSI_ASCQ_CAUSE_NOT_REPORTABLE ); + + len = scsi_task->sense_data_len; + + if ( len > 0U ) { + iscsi_scsi_sense_data_check_cond_packet *sense_data = (iscsi_scsi_sense_data_check_cond_packet *) malloc( len ); + + if ( sense_data == NULL ) { + iscsi_scsi_task_status_set( scsi_task, ISCSI_SCSI_STATUS_CHECK_COND, ISCSI_SCSI_SENSE_KEY_HARDWARE_ERR, ISCSI_SCSI_ASC_WARNING, ISCSI_SCSI_ASCQ_POWER_LOSS_EXPECTED ); + + break; + } + + memcpy( sense_data, scsi_task->sense_data, len ); + + if ( len > alloc_len ) + len = alloc_len; + + scsi_task->buf = (uint8_t *) sense_data; + } + + scsi_task->pos = len; + scsi_task->status = ISCSI_SCSI_STATUS_GOOD; + + break; + } + case ISCSI_SCSI_OPCODE_LOGSELECT : + case ISCSI_SCSI_OPCODE_LOGSENSE : { + iscsi_scsi_task_status_set( scsi_task, ISCSI_SCSI_STATUS_CHECK_COND, ISCSI_SCSI_SENSE_KEY_ILLEGAL_REQ, ISCSI_SCSI_ASC_INVALID_COMMAND_OPERATION_CODE, ISCSI_SCSI_ASCQ_CAUSE_NOT_REPORTABLE ); + + break; + } + case ISCSI_SCSI_OPCODE_TESTUNITREADY : + case ISCSI_SCSI_OPCODE_STARTSTOPUNIT : { + scsi_task->pos = 0U; + scsi_task->status = ISCSI_SCSI_STATUS_GOOD; + + break; + } + case ISCSI_SCSI_OPCODE_PERSISTENT_RESERVE_OUT : { + const iscsi_scsi_cdb_pr_reserve_out *cdb_pr_reserve_out = (iscsi_scsi_cdb_pr_reserve_out *) scsi_task->cdb; + + alloc_len = iscsi_get_be32(cdb_pr_reserve_out->param_list_len); + rc = iscsi_scsi_emu_check_len( scsi_task, alloc_len, sizeof(struct iscsi_scsi_pr_reserve_out_parameter_list_packet) ); + + if ( rc < 0 ) + break; + + len = scsi_task->len; + + iscsi_scsi_pr_reserve_out_parameter_list_packet *pr_reserve_out_parameter_list = (iscsi_scsi_pr_reserve_out_parameter_list_packet *) malloc( len ); + + if ( pr_reserve_out_parameter_list == NULL ) { + iscsi_scsi_task_status_set( scsi_task, ISCSI_SCSI_STATUS_CHECK_COND, ISCSI_SCSI_SENSE_KEY_HARDWARE_ERR, ISCSI_SCSI_ASC_WARNING, ISCSI_SCSI_ASCQ_POWER_LOSS_EXPECTED ); + + break; + } + + if ( len < sizeof(struct iscsi_scsi_pr_reserve_out_parameter_list_packet) ) { + free( pr_reserve_out_parameter_list ); + + break; + } + + rc = iscsi_scsi_pr_out( scsi_task, pr_reserve_out_parameter_list, cdb_pr_reserve_out, len ); + + if ( rc < 0 ) { + free( pr_reserve_out_parameter_list ); + + break; + } + + scsi_task->pos = alloc_len; + scsi_task->status = ISCSI_SCSI_STATUS_GOOD; + + free( pr_reserve_out_parameter_list ); + + break; + } + case ISCSI_SCSI_OPCODE_PERSISTENT_RESERVE_IN : { + const iscsi_scsi_cdb_pr_reserve_in *cdb_pr_reserve_in = (iscsi_scsi_cdb_pr_reserve_in *) scsi_task->cdb; + + alloc_len = iscsi_get_be16(cdb_pr_reserve_in->param_list_len); + len = alloc_len; + + iscsi_scsi_pr_reserve_in_parameter_data_packet *pr_reserve_in_parameter_data = (iscsi_scsi_pr_reserve_in_parameter_data_packet *) malloc( len ); + + if ( pr_reserve_in_parameter_data == NULL ) { + iscsi_scsi_task_status_set( scsi_task, ISCSI_SCSI_STATUS_CHECK_COND, ISCSI_SCSI_SENSE_KEY_HARDWARE_ERR, ISCSI_SCSI_ASC_WARNING, ISCSI_SCSI_ASCQ_POWER_LOSS_EXPECTED ); + + break; + } + + rc = iscsi_scsi_pr_in( scsi_task, pr_reserve_in_parameter_data, cdb_pr_reserve_in, len ); + + if ( (rc >= 0) && (len > 0U) ) { + if ( len > alloc_len ) + len = alloc_len; + + scsi_task->buf = (uint8_t *) pr_reserve_in_parameter_data; + rc = len; + } + + if ( rc >= 0 ) { + scsi_task->pos = rc; + scsi_task->status = ISCSI_SCSI_STATUS_GOOD; + } + + break; + } + case ISCSI_SCSI_OPCODE_RESERVE6 : { + const iscsi_scsi_cdb_pr_reserve_6 *cdb_pr_reserve_6 = (iscsi_scsi_cdb_pr_reserve_6 *) scsi_task->cdb; + + rc = iscsi_scsi_pr_reserve_scsi2( scsi_task, cdb_pr_reserve_6 ); + + if ( rc >= 0 ) { + scsi_task->pos = rc; + scsi_task->status = ISCSI_SCSI_STATUS_GOOD; + } + + break; + } + case ISCSI_SCSI_OPCODE_RESERVE10 : { + const iscsi_scsi_cdb_pr_reserve_10 *cdb_pr_reserve_10 = (iscsi_scsi_cdb_pr_reserve_10 *) scsi_task->cdb; + + rc = iscsi_scsi_pr_reserve_scsi2( scsi_task, (iscsi_scsi_cdb_pr_reserve_6 *) cdb_pr_reserve_10 ); + rc = iscsi_get_be16(cdb_pr_reserve_10->param_list_len); + + if ( rc >= 0 ) { + scsi_task->pos = rc; + scsi_task->status = ISCSI_SCSI_STATUS_GOOD; + } + + break; + } + case ISCSI_SCSI_OPCODE_RELEASE6 : + case ISCSI_SCSI_OPCODE_RELEASE10 : { + rc = iscsi_scsi_pr_release_scsi2( scsi_task ); + + if ( rc >= 0 ) { + scsi_task->pos = rc; + scsi_task->status = ISCSI_SCSI_STATUS_GOOD; + } + + break; + } + default : { + return ISCSI_SCSI_TASK_RUN_UNKNOWN; + + break; + } + } + + return ISCSI_SCSI_TASK_RUN_COMPLETE; } /** @@ -5327,10 +6060,10 @@ int iscsi_port_transport_id_set(iscsi_port *port, const uint8_t *name, const uin return ISCSI_CONNECT_PDU_READ_ERR_FATAL; } - const uint name_len = (uint) strlen( (char *) tmp_buf ) + 1UL; + const uint name_len = (uint) strlen( (char *) tmp_buf ) + 1U; const uint len = iscsi_align(name_len, ISCSI_ALIGN_SIZE); - if ( (len < 20UL) || ((len + offsetof(struct iscsi_transport_id, name)) >= 65536UL) ) { + if ( (len < 20U) || ((len + offsetof(struct iscsi_transport_id, name)) >= 65536U) ) { logadd( LOG_ERROR, "iscsi_port_transport_id_set: Out of memory allocating SCSI transport ID for iSCSI port" ); free( tmp_buf ); @@ -5348,7 +6081,7 @@ int iscsi_port_transport_id_set(iscsi_port *port, const uint8_t *name, const uin return ISCSI_CONNECT_PDU_READ_ERR_FATAL; } - port->transport_id->id = (ISCSI_TRANSPORT_ID_FORMAT << 6U) | ISCSI_TRANSPORT_ID_PROTOCOL_ID_ISCSI; + port->transport_id->id = (ISCSI_TRANSPORT_ID_PUT_PROTOCOL_ID(ISCSI_TRANSPORT_ID_PROTOCOL_ID_ISCSI) | ISCSI_TRANSPORT_ID_PUT_FORMAT(ISCSI_TRANSPORT_ID_PROTOCOL_ID_ISCSI)); port->transport_id->reserved = 0U; iscsi_put_be16( (uint8_t *) &port->transport_id->add_len, (uint16_t) len ); @@ -5386,7 +6119,7 @@ iscsi_device *iscsi_device_create(const uint8_t *name, const uint luns) return NULL; } - const uint len = (uint) strlen( (char *) name ) + 1UL; + const uint len = (uint) strlen( (char *) name ) + 1U; device->name = malloc( len ); @@ -5400,7 +6133,7 @@ iscsi_device *iscsi_device_create(const uint8_t *name, const uint luns) memcpy( device->name, name, len ); - device->luns = iscsi_hashmap_create( (luns << 1UL) ); + device->luns = iscsi_hashmap_create( (luns << 1U) ); if ( device->luns == NULL ) { logadd( LOG_ERROR, "iscsi_device_create: Out of memory allocating iSCSI device LUN hash map" ); @@ -5436,9 +6169,11 @@ iscsi_device *iscsi_device_create(const uint8_t *name, const uint luns) return NULL; } + + lun->device = device; } - device->ports = iscsi_hashmap_create( 0UL ); + device->ports = iscsi_hashmap_create( 0U ); if ( device->ports == NULL ) { logadd( LOG_ERROR, "iscsi_device_create: Out of memory allocating iSCSI device ports hash map" ); @@ -5451,9 +6186,9 @@ iscsi_device *iscsi_device_create(const uint8_t *name, const uint luns) return NULL; } - device->id = 0L; - device->flags = 0L; - device->num_ports = 0UL; + device->id = 0; + device->flags = 0; + device->num_ports = 0U; return device; } @@ -5548,11 +6283,11 @@ int iscsi_device_find_lun_callback(uint8_t *key, const size_t key_size, uint8_t iscsi_scsi_lun *lun = (iscsi_scsi_lun *) value; if ( (lun->id != lun_find->id) || ((lun->flags & ISCSI_SCSI_LUN_FLAGS_REMOVED) != 0) ) - return 0L; + return 0; lun_find->lun = lun; - return -1L; + return -1; } /** @@ -5617,19 +6352,19 @@ static int iscsi_target_node_check_name(const uint8_t *name) const size_t len = strlen( (char *) name ); if ( len > ISCSI_TARGET_NODE_MAX_NAME_LEN ) - return -1L; + return -1; for ( size_t i = 0; i < len; i++ ) { const uint8_t c = name[i]; if ( (c <= 0x2CU) || (c == 0x2FU) || ((c >= 0x3BU && c <= 0x40U)) || ((c >= 0x5BU) && (c <= 0x60U)) || ((c >= 0x7BU) && (c <= 0x7FU)) ) - return -1L; + return -1; } if ( (strncasecmp( (char *) name, "iqn.", 4 ) == 0) && (!isdigit(name[4]) || !isdigit(name[5]) || !isdigit(name[6]) || !isdigit(name[7]) || (name[8] != '-') || (name[9] < '0') || (name[9] > '1') || ((name[9] == '0') && ((name[10] < '1') && (name[10] > '9'))) || ((name[9] == '1') && ((name[10] < '0') || (name[10] > '2'))) || (name[11] != '.')) ) - return -1L; + return -1; - return 0L; + return 0; } /** @@ -5646,16 +6381,16 @@ static int iscsi_target_node_check_name(const uint8_t *name) */ static int iscsi_target_node_check_flags(const int flags, const int32_t chap_group) { - if ( chap_group < 0 ) - return -1L; + if ( chap_group < 0L ) + return -1; if ( (((flags & ISCSI_TARGET_NODE_FLAGS_CHAP_DISABLE) == 0) && ((flags & ISCSI_TARGET_NODE_FLAGS_CHAP_REQUIRE) == 0) && ((flags & ISCSI_TARGET_NODE_FLAGS_CHAP_MUTUAL) == 0)) || // Auto (((flags & ISCSI_TARGET_NODE_FLAGS_CHAP_DISABLE) != 0) && ((flags & ISCSI_TARGET_NODE_FLAGS_CHAP_REQUIRE) == 0) && ((flags & ISCSI_TARGET_NODE_FLAGS_CHAP_MUTUAL) == 0)) || // None (((flags & ISCSI_TARGET_NODE_FLAGS_CHAP_DISABLE) == 0) && ((flags & ISCSI_TARGET_NODE_FLAGS_CHAP_REQUIRE) != 0) && ((flags & ISCSI_TARGET_NODE_FLAGS_CHAP_MUTUAL) == 0)) || // CHAP (((flags & ISCSI_TARGET_NODE_FLAGS_CHAP_DISABLE) == 0) && ((flags & ISCSI_TARGET_NODE_FLAGS_CHAP_REQUIRE) != 0) && ((flags & ISCSI_TARGET_NODE_FLAGS_CHAP_MUTUAL) != 0)) ) // CHAP Mutual - return 0L; + return 0; - return -1L; + return -1; } /** @@ -5690,7 +6425,7 @@ iscsi_target_node *iscsi_target_node_create(const uint8_t *name, const uint8_t * return NULL; } - const uint name_len = (uint) strlen( (char *) name ) + 1UL; + const uint name_len = (uint) strlen( (char *) name ) + 1U; target->name = malloc( name_len ); @@ -5705,7 +6440,7 @@ iscsi_target_node *iscsi_target_node_create(const uint8_t *name, const uint8_t * memcpy( target->name, name, name_len ); if ( alias != NULL ) { - const uint alias_len = (uint) strlen( (char *) alias ) + 1UL; + const uint alias_len = (uint) strlen( (char *) alias ) + 1U; target->alias = malloc( alias_len ); @@ -5803,7 +6538,7 @@ int iscsi_target_node_send(iscsi_connection *conn, const uint8_t *dst_iqn, const { // TODO: Implement function. - return -1L; + return -1; } /** @@ -5831,11 +6566,11 @@ int iscsi_target_node_find_callback(uint8_t *key, const size_t key_size, uint8_t iscsi_target_node *target = (iscsi_target_node *) value; if ( strcasecmp( (char *) target->name, (char *) target_find->name ) != 0 ) - return 0L; + return 0; target_find->target = target; - return -1L; + return -1; } /** @@ -5904,7 +6639,7 @@ int iscsi_target_node_access(iscsi_connection *conn, iscsi_target_node *target, { // TODO: Implement access check function - return 0L; + return 0; } /** @@ -5942,7 +6677,7 @@ iscsi_session *iscsi_session_create(iscsi_connection *conn, iscsi_target_node *t session->max_burst_len = ISCSI_SESSION_DEFAULT_MAX_BURST_LEN; session->err_recovery_level = ISCSI_SESSION_DEFAULT_ERR_RECOVERY_LEVEL; - session->connections = iscsi_hashmap_create( session->max_conns ); + session->connections = iscsi_hashmap_create( (session->max_conns << 1U) ); if ( session->connections == NULL ) { logadd( LOG_ERROR, "iscsi_session_create: Out of memory allocating iSCSI session connection hash map" ); @@ -5966,11 +6701,11 @@ iscsi_session *iscsi_session_create(iscsi_connection *conn, iscsi_target_node *t iscsi_hashmap_put( session->connections, conn_key, sizeof(conn->cid), (uint8_t *) conn ); session->target = target; - session->isid = 0LL; + session->isid = 0ULL; session->type = type; session->current_text_init_task_tag = 0xFFFFFFFFUL; - session->key_value_pairs = iscsi_hashmap_create( 32UL ); + session->key_value_pairs = iscsi_hashmap_create( 32U ); if ( session->key_value_pairs == NULL ) { logadd( LOG_ERROR, "iscsi_session_create: Out of memory allocating iSCSI session key and value pairs hash map" ); @@ -6024,7 +6759,7 @@ iscsi_session *iscsi_session_create(iscsi_connection *conn, iscsi_target_node *t void iscsi_session_destroy(iscsi_session *session) { if ( session != NULL ) { - session->tag = 0L; + session->tag = 0; session->target = NULL; session->type = ISCSI_SESSION_TYPE_INVALID; @@ -6077,7 +6812,7 @@ static int iscsi_init_key_value_pairs(iscsi_hashmap *key_value_pairs, const iscs return rc; } - return 0L; + return 0; } /** @@ -6119,7 +6854,7 @@ iscsi_connection *iscsi_connection_create(iscsi_portal *portal, const int sock) } conn->session = NULL; - conn->key_value_pairs = iscsi_hashmap_create( 32UL ); + conn->key_value_pairs = iscsi_hashmap_create( 32U ); if ( conn->key_value_pairs == NULL ) { logadd( LOG_ERROR, "iscsi_create_connection: Out of memory while allocating iSCSI login text key / value pair hash map" ); @@ -6140,7 +6875,7 @@ iscsi_connection *iscsi_connection_create(iscsi_portal *portal, const int sock) } conn->partial_pairs = NULL; - conn->text_key_value_pairs = iscsi_hashmap_create( 32UL ); + conn->text_key_value_pairs = iscsi_hashmap_create( 32U ); if ( conn->text_key_value_pairs == NULL ) { logadd( LOG_ERROR, "iscsi_create_connection: Out of memory while allocating iSCSI text key / value pair hash map" ); @@ -6164,7 +6899,7 @@ iscsi_connection *iscsi_connection_create(iscsi_portal *portal, const int sock) conn->portal_port = NULL; conn->pdu_processing = NULL; - conn->scsi_data_in_queued_tasks = iscsi_hashmap_create( (ISCSI_DEFAULT_MAX_DATA_IN_PER_CONNECTION << 1UL) ); + conn->scsi_data_in_queued_tasks = iscsi_hashmap_create( (ISCSI_DEFAULT_MAX_DATA_IN_PER_CONNECTION << 1U) ); if ( conn->scsi_data_in_queued_tasks == NULL ) { logadd( LOG_ERROR, "iscsi_create_connection: Out of memory while allocating iSCSI SCSI Data In queued tasks hash map" ); @@ -6178,7 +6913,7 @@ iscsi_connection *iscsi_connection_create(iscsi_portal *portal, const int sock) conn->login_response_pdu = NULL; - conn->pdu_snack = iscsi_hashmap_create( 0UL ); + conn->pdu_snack = iscsi_hashmap_create( 0U ); if ( conn->pdu_snack == NULL ) { logadd( LOG_ERROR, "iscsi_create_connection: Out of memory while allocating iSCSI SNACK PDU hash map" ); @@ -6191,7 +6926,7 @@ iscsi_connection *iscsi_connection_create(iscsi_portal *portal, const int sock) return NULL; } - conn->r2t_tasks_active = iscsi_hashmap_create( 0UL ); + conn->r2t_tasks_active = iscsi_hashmap_create( 0U ); if ( conn->r2t_tasks_active == NULL ) { logadd( LOG_ERROR, "iscsi_create_connection: Out of memory while allocating iSCSI active Ready To Transfer (R2T) task hash map" ); @@ -6205,7 +6940,7 @@ iscsi_connection *iscsi_connection_create(iscsi_portal *portal, const int sock) return NULL; } - conn->r2t_tasks_queue = iscsi_hashmap_create( 0UL ); + conn->r2t_tasks_queue = iscsi_hashmap_create( 0U ); if ( conn->r2t_tasks_queue == NULL ) { logadd( LOG_ERROR, "iscsi_create_connection: Out of memory while allocating iSCSI enqueued Ready To Transfer (R2T) task hash map" ); @@ -6220,17 +6955,17 @@ iscsi_connection *iscsi_connection_create(iscsi_portal *portal, const int sock) return NULL; } - conn->target_send_total_size = 0UL; - conn->scsi_data_in_cnt = 0UL; - conn->scsi_data_out_cnt = 0UL; - conn->task_cnt = 0UL; - conn->r2t_pending = 0UL; - conn->header_digest = 0L; - conn->data_digest = 0L; - conn->id = 0L; + conn->target_send_total_size = 0U; + conn->scsi_data_in_cnt = 0U; + conn->scsi_data_out_cnt = 0U; + conn->task_cnt = 0U; + conn->r2t_pending = 0U; + conn->header_digest = 0; + conn->data_digest = 0; + conn->id = 0; conn->sock = sock; conn->pdu_recv_state = ISCSI_CONNECT_PDU_RECV_STATE_WAIT_PDU_READY; - conn->flags = 0L; + conn->flags = 0; conn->state = ISCSI_CONNECT_STATE_INVALID; conn->login_phase = ISCSI_LOGIN_RESPONSE_FLAGS_NEXT_STAGE_SECURITY_NEGOTIATION; conn->max_recv_ds_len = ISCSI_DEFAULT_RECV_DS_LEN; @@ -6272,7 +7007,7 @@ int iscsi_connection_destroy_callback(uint8_t *key, const size_t key_size, uint8 iscsi_connection_destroy( (iscsi_connection *) value ); iscsi_hashmap_key_destroy( key ); - return 0L; + return 0; } /** @@ -6447,7 +7182,7 @@ int iscsi_connection_write(const iscsi_connection *conn, uint8_t *buf, const uin if ( len == 0 ) return 0; - const int rc = (int) send( conn->sock, buf, len, 0L ); + const int rc = (int) send( conn->sock, buf, len, 0 ); return (rc > 0) ? rc : ISCSI_CONNECT_PDU_READ_ERR_FATAL; } @@ -6481,7 +7216,7 @@ int iscsi_connection_handle_scsi_data_in_queued_tasks(iscsi_connection *conn) sub_task->scsi_task.buf = NULL; sub_task->scsi_task.pos = task->pos; - sub_task->scsi_task.len = 0UL; + sub_task->scsi_task.len = 0U; if ( iscsi_device_find_lun( conn->device, task->lun_id ) == NULL ) { iscsi_hashmap_remove( conn->scsi_data_in_queued_tasks, entry->key, entry->key_size ); @@ -6559,15 +7294,15 @@ static int iscsi_append_special_key_value_pair_packet(iscsi_connection *conn, is return pos; if ( (key_value_pair->flags & ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_OVERRIDE_DEFAULT) != 0 ) { - if ( (int) (len - pos) < 1L ) - return -1L; + if ( (int) (len - pos) < 1 ) + return -1; - pos += (uint) (snprintf( (char *) (buf + pos), (len - pos), "%s=%ld", key, ISCSI_DEFAULT_MAX_RECV_DS_LEN ) + 1L); + pos += (uint) (snprintf( (char *) (buf + pos), (len - pos), "%s=%ld", key, ISCSI_DEFAULT_MAX_RECV_DS_LEN ) + 1); } if ( (key_value_pair->flags & ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_USE_OTHER_MAX_VALUE) != 0 ) { - if ( (int) (len - pos) < 1L ) - return -1L; + if ( (int) (len - pos) < 1 ) + return -1; uint8_t *first_burst_len_val = NULL; int rc = iscsi_get_key_value_pair( conn->session->key_value_pairs, ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_FIRST_BURST_LEN, &first_burst_len_val ); @@ -6585,7 +7320,7 @@ static int iscsi_append_special_key_value_pair_packet(iscsi_connection *conn, is } } - pos += (uint) (snprintf( (char *) (buf + pos), (len - pos), "%s=%d", key, first_burst_len ) + 1L); + pos += (uint) (snprintf( (char *) (buf + pos), (len - pos), "%s=%d", key, first_burst_len ) + 1); } return pos; @@ -6618,10 +7353,10 @@ static int iscsi_append_special_key_value_pair_packet(iscsi_connection *conn, is static int iscsi_append_key_value_pair_packet(const iscsi_key_value_pair *key_value_pair, const uint8_t *key, const uint8_t *value, uint8_t *buf, uint pos, const uint len) { if ( (key_value_pair == NULL) || ((key_value_pair->type != ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_DECLARATIVE) && (key_value_pair->type != ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_DECLARATIVE)) ) { - if ( (int) (len - pos) < 1L ) - return -1L; + if ( (int) (len - pos) < 1 ) + return -1; - pos += (uint) (snprintf( (char *) (buf + pos), (len - pos), "%s=%s", key, value ) + 1L); + pos += (uint) (snprintf( (char *) (buf + pos), (len - pos), "%s=%s", key, value ) + 1); } return pos; @@ -6757,7 +7492,7 @@ static uint8_t *iscsi_negotiate_key_value_pair_bool(const iscsi_key_value_pair * const uint8_t *list_bool_false = list_bool_true + strlen( (char *) list_bool_true ) + 1UL; if ( (strcasecmp( (char *) old_value, (char *) list_bool_true ) != 0) && (strcasecmp( (char *) old_value, (char *) list_bool_false ) != 0) ) { - *update_key_value_pair = 0L; + *update_key_value_pair = 0; return (uint8_t *) "Reject"; } @@ -6883,30 +7618,30 @@ int iscsi_negotiate_key_value_pair_callback(uint8_t *key, const size_t key_size, iscsi_connection *conn = key_value_pair_packet->conn; iscsi_hashmap *key_value_pairs = conn->key_value_pairs; iscsi_key_value_pair *key_value_pair = NULL; - int type = 0L; + int type = 0; int rc = iscsi_hashmap_get( iscsi_globvec->connection_key_value_pairs, key, key_size, (uint8_t **) &key_value_pair); if ( rc < 0 ) { key_value_pairs = conn->session->key_value_pairs; - type = 1L; + type = 1; rc = iscsi_hashmap_get( iscsi_globvec->session_key_value_pairs, key, key_size, (uint8_t **) &key_value_pair); } if ( (rc == 0) && (key_value_pair->flags & (ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_CHAP_TYPE | ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_SPECIAL_HANDLING)) != 0 ) - return 0L; + return 0; - int update_key_value_pair = 1L; + int update_key_value_pair = 1; uint8_t *conn_sess_val; if ( rc < 0 ) { conn_sess_val = (uint8_t *) "NotUnderstood"; - update_key_value_pair = 0L; + update_key_value_pair = 0; } else if ( (key_value_pair_packet->discovery != 0) && ((key_value_pair->flags & ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_DISCOVERY_IGNORE) != 0) ) { conn_sess_val = (uint8_t *) "Irrelevant"; - update_key_value_pair = 0L; + update_key_value_pair = 0; } else { rc = iscsi_negotiate_key_value_pairs_state( conn, key_value_pair, type ); @@ -6931,7 +7666,7 @@ int iscsi_negotiate_key_value_pair_callback(uint8_t *key, const size_t key_size, } if ( (key_value_pair->flags & ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_TARGET_DECLARATIVE) != 0 ) - update_key_value_pair = 0L; + update_key_value_pair = 0; conn_sess_val = iscsi_negotiate_key_value_pair_all( key_value_pair, value, conn_sess_val, &update_key_value_pair ); } @@ -6951,7 +7686,7 @@ int iscsi_negotiate_key_value_pair_callback(uint8_t *key, const size_t key_size, return key_value_pair_packet->pos; } - return 0L; + return 0; } /** @@ -6984,7 +7719,7 @@ int iscsi_negotiate_key_value_pairs(iscsi_connection *conn, iscsi_hashmap *key_v if ( rc < 0 ) rc = iscsi_get_key_value_pair( conn->session->key_value_pairs, ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_SESSION_TYPE, &type ); - const int discovery = ((rc == 0) && (strcasecmp( (char *) type, "Discovery" ) == 0)) ? 1L : 0L; + const int discovery = ((rc == 0) && (strcasecmp( (char *) type, "Discovery" ) == 0)) ? 1 : 0; iscsi_key_value_pair_packet key_value_pair_packet = {conn, buf, pos, len, discovery}; iscsi_hashmap_iterate( key_value_pairs, iscsi_negotiate_key_value_pair_callback, (uint8_t *) &key_value_pair_packet ); @@ -7025,14 +7760,14 @@ int iscsi_connection_copy_key_value_pairs(iscsi_connection *conn) if ( rc != 0 ) return rc; - conn->header_digest = (strcasecmp( (char *) value, "CRC32C" ) == 0) ? ISCSI_DIGEST_SIZE : 0L; + conn->header_digest = (strcasecmp( (char *) value, "CRC32C" ) == 0) ? ISCSI_DIGEST_SIZE : 0; rc = iscsi_get_key_value_pair( conn->key_value_pairs, ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_DATA_DIGEST, &value); if ( rc != 0 ) return rc; - conn->data_digest = (strcasecmp( (char *) value, "CRC32C" ) == 0) ? ISCSI_DIGEST_SIZE : 0L; + conn->data_digest = (strcasecmp( (char *) value, "CRC32C" ) == 0) ? ISCSI_DIGEST_SIZE : 0; rc = iscsi_get_int_key_value_pair( conn->key_value_pairs, ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_MAX_CONNECTIONS, &int_val); @@ -7080,7 +7815,7 @@ int iscsi_connection_copy_key_value_pairs(iscsi_connection *conn) if ( int_val != 0 ) conn->session->flags |= ISCSI_SESSION_FLAGS_IMMEDIATE_DATA; - return 0L; + return 0; } /** @@ -7110,7 +7845,7 @@ static int iscsi_connection_auth_key_value_pairs(iscsi_connection *conn, iscsi_h { // TODO: Implement CHAP and other authentication methods. - return 0L; + return 0; } /** @@ -7130,9 +7865,9 @@ static int iscsi_connection_auth_key_value_pairs(iscsi_connection *conn, iscsi_h static int iscsi_connection_check_key_value_pairs(iscsi_connection *conn) { if ( (conn->session->first_burst_len > conn->session->max_burst_len) || (conn->session->first_burst_len < 512) || (conn->session->max_burst_len < 512) || (conn->session->max_burst_len > ISCSI_SESSION_DEFAULT_MAX_BURST_LEN) || (conn->max_recv_ds_len < 512) || (conn->max_recv_ds_len > ISCSI_SESSION_DEFAULT_MAX_BURST_LEN) ) - return -1L; + return -1; - return 0L; + return 0; } /** @@ -7169,17 +7904,17 @@ static int iscsi_connection_update_key_value_pairs(iscsi_connection *conn) conn->state = ISCSI_CONNECT_STATE_EXITING; if ( conn->sock < 0 ) - return -1L; + return -1; uint recv_buf_len = conn->session->first_burst_len; - if ( recv_buf_len < 4096 ) - recv_buf_len = 4096UL; - else if ( recv_buf_len > 8192 ) - recv_buf_len = 8192UL; + if ( recv_buf_len < 4096U ) + recv_buf_len = 4096U; + else if ( recv_buf_len > 8192U ) + recv_buf_len = 8192U; recv_buf_len += (uint) (sizeof(struct iscsi_bhs_packet) + ISCSI_MAX_AHS_SIZE + conn->header_digest + conn->data_digest); // BHS + maximum AHS size + header and data digest overhead - recv_buf_len <<= 2UL; // Receive up to four streams at once. + recv_buf_len <<= 2U; // Receive up to four streams at once. setsockopt( conn->sock, SOL_SOCKET, SO_RCVBUF, &recv_buf_len, sizeof(recv_buf_len)); // Not being able to set the buffer is NOT fatal, so ignore error. @@ -7669,7 +8404,7 @@ static uint16_t iscsi_session_append(iscsi_connection *conn, const uint8_t *init static int iscsi_connection_login_check_session(iscsi_connection *conn, iscsi_pdu *login_response_pdu, uint8_t *init_port_name, uint cid) { iscsi_login_response_packet *login_response_pkt = (iscsi_login_response_packet *) login_response_pdu->bhs_pkt; - int rc = 0L; + int rc = 0; if ( login_response_pkt->tsih != 0 ) { rc = iscsi_session_append( conn, init_port_name, iscsi_get_be16(login_response_pkt->tsih), (uint16_t) cid ); @@ -7748,18 +8483,18 @@ iscsi_pdu *iscsi_connection_pdu_create(iscsi_connection *conn) pdu->conn = conn; pdu->xfer_complete_callback = NULL; pdu->xfer_complete_user_data = NULL; - pdu->flags = 0L; - pdu->bhs_pos = 0UL; - pdu->ahs_pos = 0UL; - pdu->ahs_len = 0UL; - pdu->header_digest_pos = 0UL; - pdu->header_digest_size = 0L; - pdu->ds_len = 0UL; - pdu->pos = 0UL; - pdu->len = 0UL; - pdu->data_digest_pos = 0UL; - pdu->data_digest_size = 0L; - pdu->task_ref_cnt = 0UL; + pdu->flags = 0; + pdu->bhs_pos = 0U; + pdu->ahs_pos = 0U; + pdu->ahs_len = 0U; + pdu->header_digest_pos = 0U; + pdu->header_digest_size = 0; + pdu->ds_len = 0U; + pdu->pos = 0U; + pdu->len = 0U; + pdu->data_digest_pos = 0U; + pdu->data_digest_size = 0; + pdu->task_ref_cnt = 0U; pdu->cmd_sn = 0UL; return pdu; @@ -7836,7 +8571,7 @@ void iscsi_connection_pdu_write(iscsi_connection *conn, iscsi_pdu *pdu, iscsi_co if ( conn->header_digest != 0 ) iscsi_calc_header_digest( pdu->bhs_pkt ); - if ( (conn->data_digest != 0) && (pdu->ds_len != 0) ) + if ( (conn->data_digest != 0) && (pdu->ds_len != 0U) ) iscsi_calc_data_digest( pdu->bhs_pkt, conn->header_digest ); } @@ -7914,7 +8649,7 @@ int iscsi_connection_pdu_ack_remove_callback(uint8_t *key, const size_t key_size iscsi_connection_pdu_free( conn, pdu ); } - return 0L; + return 0; } /** @@ -8330,11 +9065,11 @@ int iscsi_r2t_find_pdu_bhs_callback(uint8_t *key, const size_t key_size, uint8_t iscsi_task *task = (iscsi_task *) value; if ( memcmp( task->pdu->bhs_pkt, pdu_find_bhs->bhs_pkt, sizeof(struct iscsi_bhs_packet) ) != 0 ) - return 0L; + return 0; pdu_find_bhs->pdu = task->pdu; - return -1L; + return -1; } /** @@ -8476,12 +9211,12 @@ int iscsi_r2t_remove_pdu_from_snack_list_callback(uint8_t *key, const size_t key iscsi_r2t_packet *r2t_pkt = (iscsi_r2t_packet *) pdu->bhs_pkt; if ( (pdu->task != pdu_remove->task) || (iscsi_get_be32(r2t_pkt->r2t_sn) != pdu_remove->r2t_sn) ) - return 0L; + return 0; pdu_remove->pdu = pdu; iscsi_hashmap_remove_free( pdu_remove->pdu_snack, key, key_size, iscsi_hashmap_key_destroy_callback, NULL ); - return -1L; + return -1; } /** @@ -8614,7 +9349,7 @@ static int iscsi_connection_pdu_header_handle_scsi_data_out(iscsi_connection *co if ( data_sn != task->r2t_data_sn ) { if ( conn->session->err_recovery_level > 0 ) { - const int rc = iscsi_r2t_recovery_send( conn, task, task->r2t_sn_ack, 1L ); + const int rc = iscsi_r2t_recovery_send( conn, task, task->r2t_sn_ack, 1 ); if ( rc == 0 ) return ISCSI_CONNECT_PDU_READ_OK; @@ -8972,7 +9707,7 @@ static int iscsi_connection_pdu_data_handle_scsi_cmd_read(iscsi_connection *conn if ( task->scsi_task.xfer_len <= ISCSI_DEFAULT_MAX_RECV_DS_LEN ) { task->parent = NULL; task->scsi_task.buf = NULL; - task->scsi_task.pos = 0UL; + task->scsi_task.pos = 0U; task->scsi_task.len = task->scsi_task.xfer_len; iscsi_task_queue( conn, task ); @@ -8981,7 +9716,7 @@ static int iscsi_connection_pdu_data_handle_scsi_cmd_read(iscsi_connection *conn } if ( task->sub_tasks == NULL ) { - task->sub_tasks = iscsi_hashmap_create( 0UL ); + task->sub_tasks = iscsi_hashmap_create( 0U ); if ( task->sub_tasks == NULL ) { logadd( LOG_ERROR, "iscsi_connection_pdu_data_handle_scsi_cmd_read: Out of memory while allocating iSCSI task sub task hash map" ); @@ -8990,7 +9725,7 @@ static int iscsi_connection_pdu_data_handle_scsi_cmd_read(iscsi_connection *conn } } - task->pos = 0UL; + task->pos = 0U; iscsi_hashmap_key_create_id( task->sub_tasks, &task->id ); const int rc = iscsi_hashmap_put( task->sub_tasks, (uint8_t *) &task->id, sizeof(task->id), (uint8_t *) task ); @@ -9020,7 +9755,7 @@ static int iscsi_connection_pdu_data_handle_scsi_cmd_write(iscsi_connection *con { // TODO: Implement SCSI command write (COW). - return 0L; + return 0; } /** @@ -9056,7 +9791,7 @@ static int iscsi_connection_pdu_data_handle_scsi_cmd(iscsi_connection *conn, isc return iscsi_connection_pdu_data_handle_scsi_cmd_read( conn, task ); } else if ( (task->flags & ISCSI_SCSI_TASK_FLAGS_XFER_WRITE) != 0 ) { return iscsi_connection_pdu_data_handle_scsi_cmd_write( conn, task ); - } else if ( ((task->flags & ISCSI_SCSI_TASK_FLAGS_XFER_READ) == 0) && ((task->flags & ISCSI_SCSI_TASK_FLAGS_XFER_WRITE) == 0) ) { + } else if ( (task->flags & (ISCSI_SCSI_TASK_FLAGS_XFER_READ | ISCSI_SCSI_TASK_FLAGS_XFER_WRITE)) == 0 ) { iscsi_task_queue( conn, task ); return ISCSI_CONNECT_PDU_READ_OK; @@ -9080,7 +9815,7 @@ static int iscsi_connection_pdu_data_handle_scsi_cmd(iscsi_connection *conn, isc */ static int iscsi_connection_chap_negotiate(iscsi_connection *conn) { - int rc = 0L; + int rc = 0; if ( (conn->flags & ISCSI_CONNECT_FLAGS_CHAP_DISABLE) != 0 ) rc = iscsi_update_key_value_pair( conn->key_value_pairs, ISCSI_LOGIN_AUTH_SECURITY_TEXT_KEY_AUTH_METHOD, (uint8_t *) "None" ); @@ -9167,7 +9902,7 @@ static int iscsi_connection_login_chap_negotiate(iscsi_connection *conn, const i */ static int iscsi_connection_login_digest_negotiate(iscsi_connection *conn, const iscsi_target_node *target) { - int rc = 0L; + int rc = 0; if ( target->header_digest != 0 ) rc = iscsi_update_key_value_pair( conn->key_value_pairs, ISCSI_LOGIN_AUTH_SESSION_TEXT_KEY_HEADER_DIGEST, (uint8_t *) "CRC32C" ); @@ -9691,7 +10426,7 @@ static int iscsi_connecction_handle_login_response(iscsi_connection *conn, iscsi if ( rc < 0 ) return rc; - if ( (login_response_pkt->flags & ISCSI_LOGIN_RESPONSE_FLAGS_TRANSIT) != 0) + if ( (login_response_pkt->flags & ISCSI_LOGIN_RESPONSE_FLAGS_TRANSIT) != 0 ) rc = iscsi_connecction_handle_login_response_t_bit( conn, login_response_pdu ); return rc; @@ -9719,7 +10454,7 @@ static int iscsi_connection_pdu_data_handle_login_req(iscsi_connection *conn, is if ( login_response_pdu == NULL ) return ISCSI_CONNECT_PDU_READ_OK; - iscsi_hashmap *key_value_pairs = iscsi_hashmap_create( 32UL ); + iscsi_hashmap *key_value_pairs = iscsi_hashmap_create( 32U ); if ( key_value_pairs == NULL ) return ISCSI_CONNECT_PDU_READ_ERR_FATAL; @@ -9793,7 +10528,7 @@ static void iscsi_connection_pdu_text_complete(uint8_t *user_data) */ static int iscsi_connection_pdu_data_handle_text_req(iscsi_connection *conn, iscsi_pdu *pdu) { - iscsi_hashmap *key_value_pairs = iscsi_hashmap_create( 32UL ); + iscsi_hashmap *key_value_pairs = iscsi_hashmap_create( 32U ); if ( key_value_pairs == NULL ) return ISCSI_CONNECT_PDU_READ_ERR_FATAL; @@ -9808,7 +10543,7 @@ static int iscsi_connection_pdu_data_handle_text_req(iscsi_connection *conn, isc return ISCSI_CONNECT_PDU_READ_ERR_FATAL; } - if ( (pdu->ds_len == 0) && (iscsi_hashmap_size( key_value_pairs ) == 0) ) { + if ( (pdu->ds_len == 0U) && (iscsi_hashmap_size( key_value_pairs ) == 0U) ) { iscsi_hashmap *tmp_hashmap = key_value_pairs; key_value_pairs = conn->text_key_value_pairs; conn->text_key_value_pairs = tmp_hashmap; @@ -9981,7 +10716,7 @@ static int iscsi_connection_pdu_data_handle_scsi_data_out(iscsi_connection *conn { // TODO: Implement opcode. - return 0L; + return 0; } /** @@ -10177,10 +10912,10 @@ static int iscsi_connection_pdu_read(iscsi_connection *conn) pdu->ds_len = iscsi_get_be24(pdu->bhs_pkt->ds_len); pdu->ds_len = iscsi_align(pdu->ds_len, ISCSI_ALIGN_SIZE); - pdu->pos = 0UL; + pdu->pos = 0U; pdu->len = pdu->ds_len; - const uint ahs_len = (uint) pdu->bhs_pkt->total_ahs_len << 2UL; + const uint ahs_len = ((uint) pdu->bhs_pkt->total_ahs_len << 2U); if ( pdu->ahs_pos < ahs_len ) { if ( pdu->ahs_pkt == NULL ) { @@ -10241,12 +10976,12 @@ static int iscsi_connection_pdu_read(iscsi_connection *conn) } } - conn->pdu_recv_state = (iscsi_connection_pdu_header_handle( conn, pdu ) < 0L) ? ISCSI_CONNECT_PDU_RECV_STATE_ERR : ISCSI_CONNECT_PDU_RECV_STATE_WAIT_PDU_DATA; + conn->pdu_recv_state = (iscsi_connection_pdu_header_handle( conn, pdu ) < 0) ? ISCSI_CONNECT_PDU_RECV_STATE_ERR : ISCSI_CONNECT_PDU_RECV_STATE_WAIT_PDU_DATA; break; } case ISCSI_CONNECT_PDU_RECV_STATE_WAIT_PDU_DATA : { - if ( pdu->ds_len != 0 ) { + if ( pdu->ds_len != 0U ) { const int len = iscsi_connection_pdu_data_read( conn, pdu ); if ( len < 0 ) { @@ -10311,10 +11046,17 @@ static int iscsi_connection_pdu_read(iscsi_connection *conn) */ int iscsi_connection_pdu_handle(iscsi_connection *conn) { - uint i; + int i; for ( i = 0; i < ISCSI_PDU_HANDLE_COUNT; i++ ) { - int rc = iscsi_connection_pdu_read( conn ); + pthread_rwlock_wrlock( &iscsi_globvec_rwlock ); + + if ( iscsi_globvec == NULL ) + return ISCSI_CONNECT_PDU_READ_ERR_FATAL; + + const int rc = iscsi_connection_pdu_read( conn ); + + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); if ( rc == 0 ) break; @@ -10353,30 +11095,42 @@ void iscsi_connection_handle(dnbd3_client_t *client, const dnbd3_request_t *requ if ( port != NULL ) port++; - iscsi_portal_group *portal_group = iscsi_portal_group_create( 1L, 1L ); + pthread_rwlock_wrlock( &iscsi_globvec_rwlock ); - if ( portal_group == NULL ) { + if ( iscsi_globvec == NULL ) + return; + + uint64_t *hash_key = (uint64_t *) malloc( sizeof(uint64_t) ); + + if ( hash_key == NULL ) { logadd( LOG_ERROR, "iscsi_connection_handle: Out of memory while allocating iSCSI portal group" ); + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); + return; } - uint64_t *hash_key = (uint64_t *) malloc( sizeof(uint64_t) ); + iscsi_hashmap_key_create_id( iscsi_globvec->portal_groups, hash_key ); - if ( hash_key == NULL ) { + iscsi_portal_group *portal_group = iscsi_portal_group_create( (int) *hash_key, 0 ); + + if ( portal_group == NULL ) { logadd( LOG_ERROR, "iscsi_connection_handle: Out of memory while allocating iSCSI portal group" ); + iscsi_hashmap_key_destroy( (uint8_t *) hash_key ); + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); + return; } - portal_group->tag = (int) (*(uint64_t *) hash_key); + portal_group->tag = (int) *hash_key; - iscsi_hashmap_key_create_id( iscsi_globvec->portal_groups, hash_key ); int rc = iscsi_hashmap_put( iscsi_globvec->portal_groups, (uint8_t *) hash_key, sizeof(uint64_t), (uint8_t *) portal_group ); if ( rc < 0 ) { iscsi_hashmap_key_destroy( (uint8_t *) hash_key ); iscsi_portal_group_destroy( portal_group ); + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); return; } @@ -10387,17 +11141,20 @@ void iscsi_connection_handle(dnbd3_client_t *client, const dnbd3_request_t *requ logadd( LOG_ERROR, "iscsi_connection_handle: Out of memory while allocating iSCSI portal" ); iscsi_portal_group_destroy( portal_group ); + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); return; } portal->group = portal_group; - iscsi_target_node *target = iscsi_target_node_create( (uint8_t *) "iqn.2023-01.com.example:target", NULL, 0L, 8UL, 1UL, 0L, 0L, 0L, 0L ); + iscsi_target_node *target = iscsi_target_node_create( (uint8_t *) "iqn.2023-01.com.example:target", NULL, 0, 8U, 1U, 0, 0L, 0, 0 ); if ( target == NULL ) { logadd( LOG_ERROR, "iscsi_connection_handle: Out of memory while allocating iSCSI target node" ); + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); + return; } @@ -10407,6 +11164,7 @@ void iscsi_connection_handle(dnbd3_client_t *client, const dnbd3_request_t *requ logadd( LOG_ERROR, "iscsi_connection_handle: Out of memory while allocating iSCSI target node" ); iscsi_target_node_destroy( target ); + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); return; } @@ -10417,6 +11175,7 @@ void iscsi_connection_handle(dnbd3_client_t *client, const dnbd3_request_t *requ if ( rc < 0 ) { iscsi_hashmap_key_destroy( (uint8_t *) hash_key ); iscsi_target_node_destroy( target ); + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); return; } @@ -10427,6 +11186,7 @@ void iscsi_connection_handle(dnbd3_client_t *client, const dnbd3_request_t *requ logadd( LOG_ERROR, "iscsi_connection_handle: Out of memory while allocating iSCSI connection" ); iscsi_portal_destroy( portal ); + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); return; } @@ -10438,6 +11198,7 @@ void iscsi_connection_handle(dnbd3_client_t *client, const dnbd3_request_t *requ iscsi_connection_destroy( conn ); iscsi_portal_destroy( portal ); + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); return; } @@ -10448,6 +11209,7 @@ void iscsi_connection_handle(dnbd3_client_t *client, const dnbd3_request_t *requ iscsi_hashmap_key_destroy( (uint8_t *) hash_key ); iscsi_connection_destroy( conn ); iscsi_portal_destroy( portal ); + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); return; } @@ -10457,9 +11219,10 @@ void iscsi_connection_handle(dnbd3_client_t *client, const dnbd3_request_t *requ conn->pdu_processing->bhs_pos = len; conn->pdu_recv_state = ISCSI_CONNECT_PDU_RECV_STATE_WAIT_PDU_HDR; - conn->id = (int) (*(uint64_t *) hash_key); - iscsi_hashmap_key_create_id( iscsi_globvec->connections, hash_key ); + + conn->id = (int) *hash_key; + rc = iscsi_hashmap_put( iscsi_globvec->connections, (uint8_t *) hash_key, sizeof(uint64_t), (uint8_t *) conn ); if ( rc < 0 ) { @@ -10467,10 +11230,13 @@ void iscsi_connection_handle(dnbd3_client_t *client, const dnbd3_request_t *requ iscsi_hashmap_key_destroy( (uint8_t *) hash_key ); iscsi_connection_destroy( conn ); iscsi_portal_destroy( portal ); + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); return; } + pthread_rwlock_unlock( &iscsi_globvec_rwlock ); + while ( iscsi_connection_pdu_handle( conn ) >= ISCSI_CONNECT_PDU_READ_OK ) { } } diff --git a/src/server/iscsi.h b/src/server/iscsi.h index 15b925c..315ad2c 100644 --- a/src/server/iscsi.h +++ b/src/server/iscsi.h @@ -37,6 +37,7 @@ #include <stdio.h> #include <sys/types.h> #include <dnbd3/types.h> +#include <pthread.h> #include "globals.h" #include "image.h" @@ -149,6 +150,51 @@ static inline void iscsi_put_be64(uint8_t *data, const uint64_t val) #error "Unknown CPU endianness" #endif + +/// Bit sequence manipulation double word (32 bits) mask bits: Gets mask for filtering out a bit range between a and b, b may NOT exceed 30 bits range. +#define ISCSI_BITS_GET_MASK(a, b) (((1U << (a)) - 1U) ^ ((1U << ((b) + 1U)) - 1U)) + +/// Bit sequence manipulation double word (32 bits) test bits: Tests value x in of a bit range between a and b, b may NOT exceed 30 bits range. +#define ISCSI_BITS_TST(x, a, b) ((x) & ISCSI_BITS_GET_MASK(a, b)) + +/// Bit sequence manipulation double word (32 bits) clear bits: Clears all bits in range between a and b out of x, b may NOT exceed 30 bits range. +#define ISCSI_BITS_CLR(x, a, b) ((x) & ~ISCSI_BITS_GET_MASK(a, b)) + +/// Bit sequence manipulation double word (32 bits) set bits: Sets all bits in range between a and b of x, b may NOT exceed 30 bits range. +#define ISCSI_BITS_SET(x, a, b) ((x) | ISCSI_BITS_GET_MASK(a, b)) + +/// Bit sequence manipulation double word (32 bits) change bits: Flips all bits in range between a and b of x, b may NOT exceed 30 bits range. +#define ISCSI_BITS_CHG(x, a, b) ((x) ^ ISCSI_BITS_GET_MASK(a, b)) + +/// Bit sequence manipulation double word (32 bits) get bits: Extracts a value x out of a bit range between a and b, b may NOT exceed 30 bits range. +#define ISCSI_BITS_GET(x, a, b) (ISCSI_BITS_TST(x, a, b) >> (a)) + +/// Bit sequence manipulation double word (32 bits) get bits: Puts a value x into a bit range between a and b, b may NOT exceed 30 bits range. +#define ISCSI_BITS_PUT(x, a, b) (((x) << (a)) & ISCSI_BITS_GET_MASK(a, b)) + + +/// Bit sequence manipulation quad word (64 bits) mask bits: Gets mask for filtering out a bit range between a and b, b may NOT exceed 62 bits range. +#define ISCSI_QBITS_GET_MASK(a, b) (((1ULL << (a)) - 1ULL) ^ ((1ULL << ((b) + 1ULL)) - 1ULL)) + +/// Bit sequence manipulation quad word (64 bits) test bits: Tests value x in of a bit range between a and b, b may NOT exceed 62 bits range. +#define ISCSI_QBITS_TST(x, a, b) ((x) & ISCSI_QBITS_GET_MASK(a, b)) + +/// Bit sequence manipulation quad word (64 bits) clear bits: Clears bits in range between a and b out of x, b may NOT exceed 62 bits range. +#define ISCSI_QBITS_CLR(x, a, b) ((x) & ~ISCSI_QBITS_GET_MASK(a, b)) + +/// Bit sequence manipulation quad word (64 bits) set bits: Sets all bits in range between a and b of x, b may NOT exceed 62 bits range. +#define ISCSI_QBITS_SET(x, a, b) ((x) | ISCSI_QBITS_GET_MASK(a, b)) + +/// Bit sequence manipulation quad word (64 bits) change bits: Flips all bits in range between a and b of x, b may NOT exceed 62 bits range. +#define ISCSI_QBITS_CHG(x, a, b) ((x) ^ ISCSI_QBITS_GET_MASK(a, b)) + +/// Bit sequence manipulation quad word (64 bits) get bits: Extracts a value x out of a bit range between a and b, b may NOT exceed 62 bits range. +#define ISCSI_QBITS_GET(x, a, b) (ISCSI_QBITS_TST(x, a, b) >> (a)) + +/// Bit sequence manipulation quad word (64 bits) get bits: Puts a value x into a bit range between a and b, b may NOT exceed 62 bits range. +#define ISCSI_QBITS_PUT(x, a, b) (((x) << (a)) & ISCSI_QBITS_GET_MASK(a, b)) + + /// Aligns value x by rounding up, so it's evenly divisable by n. #define iscsi_align(x, n) (((x) + (n) - 1) & ~((n) - 1)) @@ -805,6 +851,48 @@ typedef struct __attribute__((packed)) iscsi_scsi_cdb_read_write_16 { } iscsi_scsi_cdb_read_write_16; +/// iSCSI SCSI Command Descriptor Block (CDB) for REPORT LUNS command select report: Logical unit with addressing method. +#define ISCSI_SCSI_CDB_REPORT_LUNS_SELECT_REPORT_LU_ADDR_METHOD 0x00 + +/// iSCSI SCSI Command Descriptor Block (CDB) for REPORT LUNS command select report: Well known logical unit. +#define ISCSI_SCSI_CDB_REPORT_LUNS_SELECT_REPORT_LU_KNOWN 0x01 + +/// iSCSI SCSI Command Descriptor Block (CDB) for REPORT LUNS command select report: Logical unit. +#define ISCSI_SCSI_CDB_REPORT_LUNS_SELECT_REPORT_LU_ALL 0x02 + + +/** + * @brief iSCSI SCSI CDB packet data structure for REPORT LUNS command. + * + * 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; + + /// Reserved for future usage (always MUST be 0 for now). + uint8_t reserved; + + /// 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). + uint8_t reserved3; + + /// Allocation length in bytes. + uint32_t alloc_len; + + /// Reserved for future usage (always MUST be 0 for now). + uint8_t reserved4; + + /// 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) @@ -814,17 +902,17 @@ typedef struct __attribute__((packed)) iscsi_scsi_cdb_read_write_16 { /// 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 COMPARE AND WRITE command write protect flags: Second bit of the three bits. -#define ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_WRPROTECT_SECOND_BIT ((ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_WRPROTECT_FIRST_BIT) + 1) - -/// iSCSI SCSI Command Descriptor Block (CDB) for COMPARE AND WRITE command write protect flags: Third bit of the three bits. -#define ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_WRPROTECT_THIRD_BIT ((ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_WRPROTECT_SECOND_BIT) + 1) +/// 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 COMPARE AND WRITE command write protect flags: Bit mask. -#define ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_WRPROTECT_MASK ((1 << (ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_WRPROTECT_FIRST_BIT)) | (1 << (ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_WRPROTECT_SECOND_BIT)) | (1 << (ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_WRPROTECT_THIRD_BIT))) +#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 COMPARE AND WRITE command write protect flags: Extracts the write protect bits. -#define ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_GET_WRPROTECT(x) (((x) & ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_WRPROTECT_MASK) >> ISCSI_SCSI_CDB_CMP_WRITE_FLAGS_WRPROTECT_FIRST_BIT) +#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)) /** @@ -868,23 +956,17 @@ typedef struct __attribute__((packed)) iscsi_scsi_cdb_cmp_write { /// 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: Second bit of the five bits. -#define ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_SECOND_BIT ((ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_FIRST_BIT) + 1) - -/// iSCSI SCSI Command Descriptor Block (CDB) for SERVICE ACTION IN(16) command service action: Third bit of the five bits. -#define ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_THIRD_BIT ((ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_SECOND_BIT) + 1) - -/// iSCSI SCSI Command Descriptor Block (CDB) for SERVICE ACTION IN(16) command service action: Fourth bit of the five bits. -#define ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_FOURTH_BIT ((ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_THIRD_BIT) + 1) - -/// iSCSI SCSI Command Descriptor Block (CDB) for SERVICE ACTION IN(16) command service action: Fifth bit of the five bits. -#define ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_FIFTH_BIT ((ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_FOURTH_BIT) + 1) +/// 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 ((1 << (ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_FIRST_BIT)) | (1 << (ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_SECOND_BIT)) | (1 << (ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_THIRD_BIT)) | (1 << (ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_FOURTH_BIT)) | (1 << (ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_FIFTH_BIT))) +#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) (((x) & ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_MASK) >> ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_FIRST_BIT) +#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)) + +/// iSCSI SCSI Command Descriptor Block (CDB) for SERVICE ACTION IN(16) command service action: Stores into the service action bits. +#define ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_PUT_ACTION(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_FIRST_BIT, ISCSI_SCSI_CDB_SERVICE_ACTION_IN_16_ACTION_LAST_BIT)) /** @@ -1017,6 +1099,230 @@ typedef struct __attribute__((packed)) iscsi_scsi_cdb_write_same_16 { } 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) + + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(6) command page code: First bit of the six bits. +#define ISCSI_SCSI_CDB_MODE_SENSE_6_PAGE_CODE_FIRST_BIT 0 + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(6) command page code: Last bit of the six bits. +#define ISCSI_SCSI_CDB_MODE_SENSE_6_PAGE_CODE_LAST_BIT ((ISCSI_SCSI_CDB_MODE_SENSE_6_PAGE_CODE_FIRST_BIT) + 6 - 1) + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(6) command page code: Bit mask. +#define ISCSI_SCSI_CDB_MODE_SENSE_6_PAGE_CODE_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_CDB_MODE_SENSE_6_PAGE_CODE_FIRST_BIT, ISCSI_SCSI_CDB_MODE_SENSE_6_PAGE_CODE_LAST_BIT)) + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(6) command page code: Extracts the page code bits. +#define ISCSI_SCSI_CDB_MODE_SENSE_6_GET_PAGE_CODE(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_CDB_MODE_SENSE_6_PAGE_CODE_FIRST_BIT, ISCSI_SCSI_CDB_MODE_SENSE_6_PAGE_CODE_LAST_BIT)) + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(6) command page code: Stores into the page code bits. +#define ISCSI_SCSI_CDB_MODE_SENSE_6_PUT_PAGE_CODE(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_CDB_MODE_SENSE_6_PAGE_CODE_FIRST_BIT, ISCSI_SCSI_CDB_MODE_SENSE_6_PAGE_CODE_LAST_BIT)) + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(6) command page control: First bit of the two bits. +#define ISCSI_SCSI_CDB_MODE_SENSE_6_PAGE_CONTROL_FIRST_BIT 6 + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(6) command page control: Last bit of the two bits. +#define ISCSI_SCSI_CDB_MODE_SENSE_6_PAGE_CONTROL_LAST_BIT ((ISCSI_SCSI_CDB_MODE_SENSE_6_PAGE_CONTROL_FIRST_BIT) + 2 - 1) + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(6) command page control: Bit mask. +#define ISCSI_SCSI_CDB_MODE_SENSE_6_PAGE_CONTROL_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_CDB_MODE_SENSE_6_PAGE_CONTROL_FIRST_BIT, ISCSI_SCSI_CDB_MODE_SENSE_6_PAGE_CONTROL_LAST_BIT)) + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(6) command page control: Extracts the page control bits. +#define ISCSI_SCSI_CDB_MODE_SENSE_6_GET_PAGE_CONTROL(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_CDB_MODE_SENSE_6_PAGE_CONTROL_FIRST_BIT, ISCSI_SCSI_CDB_MODE_SENSE_6_PAGE_CONTROL_LAST_BIT)) + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(6) command page control: Stores into the page control bits. +#define ISCSI_SCSI_CDB_MODE_SENSE_6_PUT_PAGE_CONTROL(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_CDB_MODE_SENSE_6_PAGE_CONTROL_FIRST_BIT, ISCSI_SCSI_CDB_MODE_SENSE_6_PAGE_CONTROL_LAST_BIT)) + + +/** + * @brief iSCSI SCSI CDB packet data structure for SCSI MODE SENSE(6) command. + * + * 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; + + /// Flags. + int8_t flags; + + /// Page code and page control. + uint8_t page_code_control; + + /// Sub page code. + uint8_t sub_page_code; + + /// Allocation length in bytes. + uint8_t alloc_len; + + /// Control. + uint8_t control; +} iscsi_scsi_cdb_mode_sense_6; + + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(10) command flags: Disable Block Descriptors (DBD). +#define ISCSI_SCSI_CDB_MODE_SENSE_10_FLAGS_DBD (1 << 3) + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(10) command flags: Long LBA Accepted (LLBAA). +#define ISCSI_SCSI_CDB_MODE_SENSE_10_FLAGS_LLBAA (1 << 4) + + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(10) command page code: First bit of the six bits. +#define ISCSI_SCSI_CDB_MODE_SENSE_10_PAGE_CODE_FIRST_BIT 0 + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(10) command page code: Last bit of the six bits. +#define ISCSI_SCSI_CDB_MODE_SENSE_10_PAGE_CODE_LAST_BIT ((ISCSI_SCSI_CDB_MODE_SENSE_10_PAGE_CODE_FIRST_BIT) + 6 - 1) + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(10) command page code: Bit mask. +#define ISCSI_SCSI_CDB_MODE_SENSE_10_PAGE_CODE_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_CDB_MODE_SENSE_10_PAGE_CODE_FIRST_BIT, ISCSI_SCSI_CDB_MODE_SENSE_10_PAGE_CODE_LAST_BIT)) + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(10) command page code: Extracts the page code bits. +#define ISCSI_SCSI_CDB_MODE_SENSE_10_GET_PAGE_CODE(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_CDB_MODE_SENSE_10_PAGE_CODE_FIRST_BIT, ISCSI_SCSI_CDB_MODE_SENSE_10_PAGE_CODE_LAST_BIT)) + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(10) command page code: Stores into the page code bits. +#define ISCSI_SCSI_CDB_MODE_SENSE_10_PUT_PAGE_CODE(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_CDB_MODE_SENSE_10_PAGE_CODE_FIRST_BIT, ISCSI_SCSI_CDB_MODE_SENSE_10_PAGE_CODE_LAST_BIT)) + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(10) command page control: First bit of the two bits. +#define ISCSI_SCSI_CDB_MODE_SENSE_10_PAGE_CONTROL_FIRST_BIT 6 + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(10) command page control: Last bit of the two bits. +#define ISCSI_SCSI_CDB_MODE_SENSE_10_PAGE_CONTROL_LAST_BIT ((ISCSI_SCSI_CDB_MODE_SENSE_10_PAGE_CONTROL_FIRST_BIT) + 2 - 1) + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(10) command page control: Bit mask. +#define ISCSI_SCSI_CDB_MODE_SENSE_10_PAGE_CONTROL_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_CDB_MODE_SENSE_10_PAGE_CONTROL_FIRST_BIT, ISCSI_SCSI_CDB_MODE_SENSE_10_PAGE_CONTROL_LAST_BIT)) + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(10) command page control: Extracts the page control bits. +#define ISCSI_SCSI_CDB_MODE_SENSE_10_GET_PAGE_CONTROL(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_CDB_MODE_SENSE_10_PAGE_CONTROL_FIRST_BIT, ISCSI_SCSI_CDB_MODE_SENSE_10_PAGE_CONTROL_LAST_BIT)) + +/// iSCSI SCSI Command Descriptor Block (CDB) for MODE SENSE(10) command page control: Stores into the page control bits. +#define ISCSI_SCSI_CDB_MODE_SENSE_10_PUT_PAGE_CONTROL(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_CDB_MODE_SENSE_10_PAGE_CONTROL_FIRST_BIT, ISCSI_SCSI_CDB_MODE_SENSE_10_PAGE_CONTROL_LAST_BIT)) + + +/** + * @brief iSCSI SCSI CDB packet data structure for SCSI MODE SENSE(10) command. + * + * 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; + + /// Flags. + int8_t flags; + + /// Page code and page control. + uint8_t page_code_control; + + /// 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). + uint8_t reserved2; + + /// Allocation length in bytes. + uint16_t alloc_len; + + /// 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. + * + * There are 6 bytes in the CDB field for this command. + */ +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; + + /// 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 @@ -1044,23 +1350,17 @@ typedef struct __attribute__((packed)) iscsi_scsi_cdb_write_same_16 { /// 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 Command Descriptor Block (CDB) for PERSISTENT RESERVE OUT command service action: Second bit of the five bits. -#define ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_SECOND_BIT ((ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_FIRST_BIT) + 1) - -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE OUT command service action: Third bit of the five bits. -#define ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_THIRD_BIT ((ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_SECOND_BIT) + 1) - -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE OUT command service action: Fourth bit of the five bits. -#define ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_FOURTH_BIT ((ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_THIRD_BIT) + 1) - -/// iSCSI SCSI Command Descriptor Block (CDB) for PERSISTENT RESERVE OUT command service action: Fifth bit of the five bits. -#define ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_FIFTH_BIT ((ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_FOURTH_BIT) + 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 Command Descriptor Block (CDB) for PERSISTENT RESERVE OUT command service action: Bit mask. -#define ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_MASK ((1 << (ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_FIRST_BIT)) | (1 << (ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_SECOND_BIT)) | (1 << (ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_THIRD_BIT)) | (1 << (ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_FOURTH_BIT)) | (1 << (ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_FIFTH_BIT))) +#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 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) (((x) & ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_MASK) >> ISCSI_SCSI_CDB_PR_RESERVE_OUT_ACTION_FIRST_BIT) +#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 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)) /** @@ -1072,21 +1372,199 @@ typedef struct __attribute__((packed)) iscsi_scsi_cdb_pr_reserve_out { /// SCSI opcode. iscsi_scsi_cdb cdb; - /// Logical Unit Number (LUN) and service action. - uint8_t lun_action; + /// Service action. + uint8_t action; /// Scope and reservation type. uint8_t scope_type; /// Reserved for future usage (always MUST be 0 for now). + uint16_t reserved; + + /// Parameter list length in bytes. + uint32_t param_list_len; + + /// Control. + uint8_t control; +} iscsi_scsi_cdb_pr_reserve_out; + + +/// 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 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 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 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_out; +} 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; /** @@ -1146,25 +1624,19 @@ typedef struct __attribute__((packed)) iscsi_scsi_ds_cmd_data { #define ISCSI_SCSI_DATA_PERIPHERAL_TYPE_UNKNOWN 0x1F /// iSCSI SCSI Data peripheral type: First bit of the five bits. -#define ISCSI_SCSI_DATA_PERIPHERAL_TYPE_FIRST_BIT 0 - -/// iSCSI SCSI Data peripheral type: Second bit of the five bits. -#define ISCSI_SCSI_DATA_PERIPHERAL_TYPE_SECOND_BIT ((ISCSI_SCSI_DATA_PERIPHERAL_TYPE_FIRST_BIT) + 1) - -/// iSCSI SCSI Data peripheral type: Third bit of the five bits. -#define ISCSI_SCSI_DATA_PERIPHERAL_TYPE_THIRD_BIT ((ISCSI_SCSI_DATA_PERIPHERAL_TYPE_SECOND_BIT) + 1) - -/// iSCSI SCSI Data peripheral type: Fourth bit of the five bits. -#define ISCSI_SCSI_DATA_PERIPHERAL_TYPE_FOURTH_BIT ((ISCSI_SCSI_DATA_PERIPHERAL_TYPE_THIRD_BIT) + 1) +#define ISCSI_SCSI_DATA_PERIPHERAL_TYPE_FIRST_BIT 0 -/// iSCSI SCSI Data peripheral type: Fifth bit of the five bits. -#define ISCSI_SCSI_DATA_PERIPHERAL_TYPE_FIFTH_BIT ((ISCSI_SCSI_DATA_PERIPHERAL_TYPE_FOURTH_BIT) + 1) +/// iSCSI SCSI Data peripheral type: Last bit of the five bits. +#define ISCSI_SCSI_DATA_PERIPHERAL_TYPE_LAST_BIT ((ISCSI_SCSI_DATA_PERIPHERAL_TYPE_FIRST_BIT) + 5 - 1) /// iSCSI SCSI Data peripheral type: Bit mask. -#define ISCSI_SCSI_DATA_PERIPHERAL_TYPE_MASK ((1 << (ISCSI_SCSI_DATA_PERIPHERAL_TYPE_FIRST_BIT)) | (1 << (ISCSI_SCSI_DATA_PERIPHERAL_TYPE_SECOND_BIT)) | (1 << (ISCSI_SCSI_DATA_PERIPHERAL_TYPE_THIRD_BIT)) | (1 << (ISCSI_SCSI_DATA_PERIPHERAL_TYPE_FOURTH_BIT)) | (1 << (ISCSI_SCSI_DATA_PERIPHERAL_TYPE_FIFTH_BIT))) +#define ISCSI_SCSI_DATA_PERIPHERAL_TYPE_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_DATA_PERIPHERAL_TYPE_FIRST_BIT, ISCSI_SCSI_DATA_PERIPHERAL_TYPE_LAST_BIT)) -/// iSCSI SCSI Data peripheral type: Extracts the Peripheral device type bits. -#define ISCSI_SCSI_DATA_GET_PERIPHERAL_TYPE(x) (((x) & ISCSI_SCSI_DATA_PERIPHERAL_TYPE_MASK) >> ISCSI_SCSI_DATA_PERIPHERAL_TYPE_FIRST_BIT) +/// iSCSI SCSI Data peripheral type: Extracts the peripheral device type bits. +#define ISCSI_SCSI_DATA_GET_PERIPHERAL_TYPE(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_DATA_PERIPHERAL_TYPE_FIRST_BIT, ISCSI_SCSI_DATA_PERIPHERAL_TYPE_LAST_BIT)) + +/// iSCSI SCSI Data peripheral type: Stores into the peripheral device type bits. +#define ISCSI_SCSI_DATA_PUT_PERIPHERAL_TYPE(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_DATA_PERIPHERAL_TYPE_FIRST_BIT, ISCSI_SCSI_DATA_PERIPHERAL_TYPE_LAST_BIT)) /// iSCSI SCSI 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_DATA_PERIPHERAL_ID_POSSIBLE 0x0 @@ -1181,67 +1653,82 @@ typedef struct __attribute__((packed)) iscsi_scsi_ds_cmd_data { /// iSCSI SCSI Data peripheral identifier: First bit of the three bits. #define ISCSI_SCSI_DATA_PERIPHERAL_ID_FIRST_BIT 5 -/// iSCSI SCSI Data peripheral identifier: Second bit of the fhree bits. -#define ISCSI_SCSI_DATA_PERIPHERAL_ID_SECOND_BIT ((ISCSI_SCSI_DATA_PERIPHERAL_ID_FIRST_BIT) + 1) - -/// iSCSI SCSI Data peripheral identifier: Third bit of the three bits. -#define ISCSI_SCSI_DATA_PERIPHERAL_ID_THIRD_BIT ((ISCSI_SCSI_DATA_PERIPHERAL_ID_SECOND_BIT) + 1) +/// iSCSI SCSI Data peripheral identifier: Last bit of the three bits. +#define ISCSI_SCSI_DATA_PERIPHERAL_ID_LAST_BIT ((ISCSI_SCSI_DATA_PERIPHERAL_ID_FIRST_BIT) + 3 - 1) /// iSCSI SCSI Data peripheral identifier: Bit mask. -#define ISCSI_SCSI_DATA_PERIPHERAL_ID_MASK ((1 << (ISCSI_SCSI_DATA_PERIPHERAL_ID_FIRST_BIT)) | (1 << (ISCSI_SCSI_DATA_PERIPHERAL_ID_SECOND_BIT)) | (1 << (ISCSI_SCSI_DATA_PERIPHERAL_ID_THIRD_BIT))) +#define ISCSI_SCSI_DATA_PERIPHERAL_ID_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_DATA_PERIPHERAL_ID_FIRST_BIT, ISCSI_SCSI_DATA_PERIPHERAL_ID_LAST_BIT)) + +/// iSCSI SCSI Data peripheral identifier: Extracts the peripheral device identifier bits. +#define ISCSI_SCSI_DATA_GET_PERIPHERAL_ID(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_DATA_PERIPHERAL_ID_FIRST_BIT, ISCSI_SCSI_DATA_PERIPHERAL_ID_LAST_BIT)) -/// iSCSI SCSI Data peripheral identifier: Extracts the Peripheral device identifier bits. -#define ISCSI_SCSI_DATA_GET_PERIPHERAL_ID(x) (((x) & ISCSI_SCSI_DATA_PERIPHERAL_ID_MASK) >> ISCSI_SCSI_DATA_PERIPHERAL_ID_FIRST_BIT) +/// iSCSI SCSI Data peripheral identifier: Stores into the peripheral device identifier bits. +#define ISCSI_SCSI_DATA_PUT_PERIPHERAL_ID(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_DATA_PERIPHERAL_ID_FIRST_BIT, ISCSI_SCSI_DATA_PERIPHERAL_ID_LAST_BIT)) +/// iSCSI SCSI Data peripheral type modifier: First bit of the seven bits. +#define ISCSI_SCSI_DATA_PERIPHERAL_TYPE_MOD_FIRST_BIT 0 + +/// iSCSI SCSI Data peripheral type modifier: Last bit of the seven bits. +#define ISCSI_SCSI_DATA_PERIPHERAL_TYPE_MOD_LAST_BIT ((ISCSI_SCSI_DATA_PERIPHERAL_TYPE_MOD_FIRST_BIT) + 7 - 1) + /// iSCSI SCSI Data peripheral type modifier: Bit mask. -#define ISCSI_SCSI_DATA_PERIPHERAL_TYPE_MOD_MASK 0x7F +#define ISCSI_SCSI_DATA_PERIPHERAL_TYPE_MOD_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_DATA_PERIPHERAL_TYPE_MOD_FIRST_BIT, ISCSI_SCSI_DATA_PERIPHERAL_TYPE_MOD_LAST_BIT)) + +/// iSCSI SCSI Data peripheral identifier: Extracts the peripheral type modifier bits. +#define ISCSI_SCSI_DATA_GET_PERIPHERAL_TYPE_MOD(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_DATA_PERIPHERAL_TYPE_MOD_FIRST_BIT, ISCSI_SCSI_DATA_PERIPHERAL_TYPE_MOD_LAST_BIT)) + +/// iSCSI SCSI Data peripheral identifier: Stores into the peripheral type modifier bits. +#define ISCSI_SCSI_DATA_PUT_PERIPHERAL_TYPE_MOD(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_DATA_PERIPHERAL_TYPE_MOD_FIRST_BIT, ISCSI_SCSI_DATA_PERIPHERAL_TYPE_MOD_LAST_BIT)) /// iSCSI SCSI Data peripheral type modifier: Removable media. -#define ISCSI_SCSI_DATA_PERIPHERAL_TYPE_MOD_FLAGS_REMOVABLE_MEDIA (1 << 7L) +#define ISCSI_SCSI_DATA_PERIPHERAL_TYPE_MOD_FLAGS_REMOVABLE_MEDIA (1 << 7) /// iSCSI SCSI Data ANSI version: First bit of the three bits. #define ISCSI_SCSI_DATA_VERSION_ANSI_FIRST_BIT 0 -/// iSCSI SCSI Data ANSI version: Second bit of the fhree bits. -#define ISCSI_SCSI_DATA_VERSION_ANSI_SECOND_BIT ((ISCSI_SCSI_DATA_VERSION_ANSI_FIRST_BIT) + 1) - -/// iSCSI SCSI Data ANSI version: Third bit of the three bits. -#define ISCSI_SCSI_DATA_VERSION_ANSI_THIRD_BIT ((ISCSI_SCSI_DATA_VERSION_ANSI_SECOND_BIT) + 1) +/// iSCSI SCSI Data ANSI version: Last bit of the three bits. +#define ISCSI_SCSI_DATA_VERSION_ANSI_LAST_BIT ((ISCSI_SCSI_DATA_VERSION_ANSI_FIRST_BIT) + 3 - 1) /// iSCSI SCSI Data ANSI version: Bit mask. -#define ISCSI_SCSI_DATA_VERSION_ANSI_MASK ((1 << (ISCSI_SCSI_DATA_VERSION_ANSI_FIRST_BIT)) | (1 << (ISCSI_SCSI_DATA_VERSION_ANSI_SECOND_BIT)) | (1 << (ISCSI_SCSI_DATA_VERSION_ANSI_THIRD_BIT))) +#define ISCSI_SCSI_DATA_VERSION_ANSI_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_DATA_VERSION_ANSI_FIRST_BIT, ISCSI_SCSI_DATA_VERSION_ANSI_LAST_BIT)) + +/// iSCSI SCSI Data ANSI version: Extracts the ANSI version bits. +#define ISCSI_SCSI_DATA_GET_VERSION_ANSI(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_DATA_VERSION_ANSI_FIRST_BIT, ISCSI_SCSI_DATA_VERSION_ANSI_LAST_BIT)) -/// iSCSI SCSI Data ANSI version: Extracts the Peripheral device identifier bits. -#define ISCSI_SCSI_DATA_GET_VERSION_ANSI(x) (((x) & ISCSI_SCSI_DATA_VERSION_ANSI_MASK) >> ISCSI_SCSI_DATA_VERSION_ANSI_FIRST_BIT) +/// iSCSI SCSI Data ANSI version: Stores into the ANSI version bits. +#define ISCSI_SCSI_DATA_PUT_VERSION_ANSI(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_DATA_VERSION_ANSI_FIRST_BIT, ISCSI_SCSI_DATA_VERSION_ANSI_LAST_BIT)) /// iSCSI SCSI Data ECMA version: First bit of the three bits. #define ISCSI_SCSI_DATA_VERSION_ECMA_FIRST_BIT 3 -/// iSCSI SCSI Data ECMA version: Second bit of the fhree bits. -#define ISCSI_SCSI_DATA_VERSION_ECMA_SECOND_BIT ((ISCSI_SCSI_DATA_VERSION_ECMA_FIRST_BIT) + 1) - -/// iSCSI SCSI Data ECMA version: Third bit of the three bits. -#define ISCSI_SCSI_DATA_VERSION_ECMA_THIRD_BIT ((ISCSI_SCSI_DATA_VERSION_ECMA_SECOND_BIT) + 1) +/// iSCSI SCSI Data ECMA version: Last bit of the three bits. +#define ISCSI_SCSI_DATA_VERSION_ECMA_LAST_BIT ((ISCSI_SCSI_DATA_VERSION_ECMA_FIRST_BIT) + 3 - 1) /// iSCSI SCSI Data ECMA version: Bit mask. -#define ISCSI_SCSI_DATA_VERSION_ECMA_MASK ((1 << (ISCSI_SCSI_DATA_VERSION_ECMA_FIRST_BIT)) | (1 << (ISCSI_SCSI_DATA_VERSION_ECMA_SECOND_BIT)) | (1 << (ISCSI_SCSI_DATA_VERSION_ECMA_THIRD_BIT))) +#define ISCSI_SCSI_DATA_VERSION_ECMA_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_DATA_VERSION_ECMA_FIRST_BIT, ISCSI_SCSI_DATA_VERSION_ECMA_LAST_BIT)) -/// iSCSI SCSI Data ECMA version: Extracts the Peripheral device identifier bits. -#define ISCSI_SCSI_DATA_GET_VERSION_ECMA(x) (((x) & ISCSI_SCSI_DATA_VERSION_ECMA_MASK) >> ISCSI_SCSI_DATA_VERSION_ECMA_FIRST_BIT) +/// iSCSI SCSI Data ECMA version: Extracts the ECMA version bits. +#define ISCSI_SCSI_DATA_GET_VERSION_ECMA(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_DATA_VERSION_ECMA_FIRST_BIT, ISCSI_SCSI_DATA_VERSION_ECMA_LAST_BIT)) + +/// iSCSI SCSI Data ECMA version: Stores into the ECMA version bits. +#define ISCSI_SCSI_DATA_PUT_VERSION_ECMA(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_DATA_VERSION_ECMA_FIRST_BIT, ISCSI_SCSI_DATA_VERSION_ECMA_LAST_BIT)) /// iSCSI SCSI Data ISO version: First bit of the two bits. #define ISCSI_SCSI_DATA_VERSION_ISO_FIRST_BIT 6 -/// iSCSI SCSI Data ISO version: Second bit of the two bits. -#define ISCSI_SCSI_DATA_VERSION_ISO_SECOND_BIT ((ISCSI_SCSI_DATA_VERSION_ISO_FIRST_BIT) + 1) +/// iSCSI SCSI Data ISO version: Last bit of the two bits. +#define ISCSI_SCSI_DATA_VERSION_ISO_LAST_BIT ((ISCSI_SCSI_DATA_VERSION_ISO_FIRST_BIT) + 2 - 1) /// iSCSI SCSI Data ISO version: Bit mask. -#define ISCSI_SCSI_DATA_VERSION_ISO_MASK ((1 << (ISCSI_SCSI_DATA_VERSION_ISO_FIRST_BIT)) | (1 << (ISCSI_SCSI_DATA_VERSION_ISO_SECOND_BIT))) +#define ISCSI_SCSI_DATA_VERSION_ISO_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_DATA_VERSION_ISO_FIRST_BIT, ISCSI_SCSI_DATA_VERSION_ISO_LAST_BIT)) + +/// iSCSI SCSI Data ISO version: Extracts the ISO version bits. +#define ISCSI_SCSI_DATA_GET_VERSION_ISO(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_DATA_VERSION_ISO_FIRST_BIT, ISCSI_SCSI_DATA_VERSION_ISO_LAST_BIT)) -/// iSCSI SCSI Data ISO version: Extracts the Peripheral device identifier bits. -#define ISCSI_SCSI_DATA_GET_VERSION_ISO(x) (((x) & ISCSI_SCSI_DATA_VERSION_ISO_MASK) >> ISCSI_SCSI_DATA_VERSION_ISO_FIRST_BIT) +/// iSCSI SCSI Data ISO version: Stores into the ISO version bits. +#define ISCSI_SCSI_DATA_PUT_VERSION_ISO(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_DATA_VERSION_ISO_FIRST_BIT, ISCSI_SCSI_DATA_VERSION_ISO_LAST_BIT)) /// iSCSI SCSI Data response data format flags: This structure complies with SCSI-1 specifications. @@ -1256,26 +1743,23 @@ typedef struct __attribute__((packed)) iscsi_scsi_ds_cmd_data { /// iSCSI SCSI Data response data format flags: First bit of the four bits. #define ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_FIRST_BIT 0 -/// iSCSI SCSI Data response data format flags: Second bit of the four bits. -#define ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_SECOND_BIT ((ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_FIRST_BIT) + 1) - -/// iSCSI SCSI Data response data format flags: Third bit of the four bits. -#define ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_THIRD_BIT ((ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_SECOND_BIT) + 1) - -/// iSCSI SCSI Data response data format flags: Fourth bit of the four bits. -#define ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_FOURTH_BIT ((ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_THIRD_BIT) + 1) +/// iSCSI SCSI Data response data format flags: Last bit of the four bits. +#define ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_LAST_BIT ((ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_FIRST_BIT) + 4 - 1) /// iSCSI SCSI Data response data format flags: Bit mask. -#define ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_MASK ((1 << (ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_FIRST_BIT)) | (1 << (ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_SECOND_BIT)) | (1 << (ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_THIRD_BIT)) | (1 << (ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_FOURTH_BIT))) +#define ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_FIRST_BIT, ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_LAST_BIT)) -/// iSCSI SCSI Data response data format flags: Extracts the Peripheral device type bits. -#define ISCSI_SCSI_DATA_GET_RESPONSE_DATA_FMT_FLAGS(x) (((x) & ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_MASK) >> ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_FIRST_BIT) +/// iSCSI SCSI Data response data format flags: Extracts the response data format flags bits. +#define ISCSI_SCSI_DATA_GET_RESPONSE_DATA_FMT_FLAGS(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_FIRST_BIT, ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_LAST_BIT)) + +/// iSCSI SCSI Data response data format flags: Stores into the response data format flags bits. +#define ISCSI_SCSI_DATA_PUT_RESPONSE_DATA_FMT_FLAGS(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_FIRST_BIT, ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_LAST_BIT)) /// iSCSI SCSI Data response data format flags: TERMINATE I/O PROCESS message device support. -#define ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_TERMINATE_IO_PROC_MSG (1 << 6L) +#define ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_TERMINATE_IO_PROC_MSG (1 << 6) /// iSCSI SCSI Data response data format flags: Asynchronous Event Notification device support. -#define ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_ASYNC_EVENT_NOTIFY (1 << 7L) +#define ISCSI_SCSI_DATA_RESPONSE_DATA_FMT_FLAGS_ASYNC_EVENT_NOTIFY (1 << 7) typedef struct __attribute__((packed)) iscsi_scsi_data_packet { @@ -1297,28 +1781,28 @@ typedef struct __attribute__((packed)) iscsi_scsi_data_packet { /// iSCSI SCSI Standard Inquiry Data flags: Device responds with soft reset instead of hard reset to reset condition. -#define ISCSI_SCSI_STD_INQUIRY_DATA_FLAGS_SOFT_RESET (1 << 0L) +#define ISCSI_SCSI_STD_INQUIRY_DATA_FLAGS_SOFT_RESET (1 << 0) /// iSCSI SCSI Standard Inquiry Data flags: Device supports tagged command queueing. -#define ISCSI_SCSI_STD_INQUIRY_DATA_FLAGS_COMMAND_QUEUE (1 << 1L) +#define ISCSI_SCSI_STD_INQUIRY_DATA_FLAGS_COMMAND_QUEUE (1 << 1) /// iSCSI SCSI Standard Inquiry Data flags: Reserved for future usage. -#define ISCSI_SCSI_STD_INQUIRY_DATA_FLAGS_RESERVED (1 << 2L) +#define ISCSI_SCSI_STD_INQUIRY_DATA_FLAGS_RESERVED (1 << 2) /// iSCSI SCSI Standard Inquiry Data flags: Device supports linked commands for this logical unit. -#define ISCSI_SCSI_STD_INQUIRY_DATA_FLAGS_LINKED_CMDS (1 << 3L) +#define ISCSI_SCSI_STD_INQUIRY_DATA_FLAGS_LINKED_CMDS (1 << 3) /// iSCSI SCSI Standard Inquiry Data flags: Device supports synchronous data transfers. -#define ISCSI_SCSI_STD_INQUIRY_DATA_FLAGS_SYNC (1 << 4L) +#define ISCSI_SCSI_STD_INQUIRY_DATA_FLAGS_SYNC (1 << 4) /// iSCSI SCSI Standard Inquiry Data flags: Device supports 16-bit wide data transfers. -#define ISCSI_SCSI_STD_INQUIRY_DATA_FLAGS_WIDE_16_BIT (1 << 5L) +#define ISCSI_SCSI_STD_INQUIRY_DATA_FLAGS_WIDE_16_BIT (1 << 5) /// iSCSI SCSI Standard Inquiry Data flags: Device supports 32-bit wide data transfers. -#define ISCSI_SCSI_STD_INQUIRY_DATA_FLAGS_WIDE_32_BIT (1 << 6L) +#define ISCSI_SCSI_STD_INQUIRY_DATA_FLAGS_WIDE_32_BIT (1 << 6) /// iSCSI SCSI Standard Inquiry Data flags: Device supports relative addressing mode of this logical unit. -#define ISCSI_SCSI_STD_INQUIRY_DATA_FLAGS_REL_ADDR (1 << 7L) +#define ISCSI_SCSI_STD_INQUIRY_DATA_FLAGS_REL_ADDR (1 << 7) typedef struct __attribute__((packed)) iscsi_scsi_std_inquiry_data_packet { @@ -1389,39 +1873,51 @@ typedef struct __attribute__((packed)) iscsi_scsi_sense_event_data_packet { /// iSCSI SCSI sense data response code: Current format. #define ISCSI_SCSI_SENSE_DATA_RESPONSE_CODE_CURRENT_FMT 0x70 -/// iSCSI SCSI sense data response code: Current format. +/// iSCSI SCSI sense data response code: Deferred format. #define ISCSI_SCSI_SENSE_DATA_RESPONSE_CODE_DEFERRED_FMT 0x71 +/// iSCSI SCSI sense data response code: First bit of the seven bits. +#define ISCSI_SCSI_SENSE_DATA_RESPONSE_CODE_FIRST_BIT 0 + +/// iSCSI SCSI sense data response code: Last bit of the seven bits. +#define ISCSI_SCSI_SENSE_DATA_RESPONSE_CODE_LAST_BIT ((ISCSI_SCSI_SENSE_DATA_RESPONSE_CODE_FIRST_BIT) + 7 - 1) + +/// iSCSI SCSI sense data response code: Bit mask. +#define ISCSI_SCSI_SENSE_DATA_RESPONSE_CODE_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_SENSE_DATA_RESPONSE_CODE_FIRST_BIT, ISCSI_SCSI_SENSE_DATA_RESPONSE_CODE_LAST_BIT)) + +/// iSCSI SCSI sense data response code: Extracts the response code bits. +#define ISCSI_SCSI_SENSE_DATA_GET_RESPONSE_CODE(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_SENSE_DATA_RESPONSE_CODE_FIRST_BIT, ISCSI_SCSI_SENSE_DATA_RESPONSE_CODE_LAST_BIT)) + +/// iSCSI SCSI sense data response code: Stores into the response code bits. +#define ISCSI_SCSI_SENSE_DATA_PUT_RESPONSE_CODE(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_SENSE_DATA_RESPONSE_CODE_FIRST_BIT, ISCSI_SCSI_SENSE_DATA_RESPONSE_CODE_LAST_BIT)) + /// iSCSI SCSI sense data response code: Valid. -#define ISCSI_SCSI_SENSE_DATA_RESPONSE_CODE_VALID (1 << 7L) +#define ISCSI_SCSI_SENSE_DATA_RESPONSE_CODE_VALID (1 << 7) /// iSCSI SCSI sense data sense key: First bit of the four bits. #define ISCSI_SCSI_SENSE_DATA_SENSE_KEY_FIRST_BIT 0 -/// iSCSI SCSI sense data sense key: Second bit of the four bits. -#define ISCSI_SCSI_SENSE_DATA_SENSE_KEY_SECOND_BIT ((ISCSI_SCSI_SENSE_DATA_SENSE_KEY_FIRST_BIT) + 1) - -/// iSCSI SCSI sense data sense key: Third bit of the four bits. -#define ISCSI_SCSI_SENSE_DATA_SENSE_KEY_THIRD_BIT ((ISCSI_SCSI_SENSE_DATA_SENSE_KEY_SECOND_BIT) + 1) - -/// iSCSI SCSI sense data sense key: Fourth bit of the four bits. -#define ISCSI_SCSI_SENSE_DATA_SENSE_KEY_FOURTH_BIT ((ISCSI_SCSI_SENSE_DATA_SENSE_KEY_THIRD_BIT) + 1) +/// iSCSI SCSI sense data sense key: Last bit of the four bits. +#define ISCSI_SCSI_SENSE_DATA_SENSE_KEY_LAST_BIT ((ISCSI_SCSI_SENSE_DATA_SENSE_KEY_FIRST_BIT) + 4 - 1) /// iSCSI SCSI sense data sense key: Bit mask. -#define ISCSI_SCSI_SENSE_DATA_SENSE_KEY_MASK ((1 << (ISCSI_SCSI_SENSE_DATA_SENSE_KEY_FIRST_BIT)) | (1 << (ISCSI_SCSI_SENSE_DATA_SENSE_KEY_SECOND_BIT)) | (1 << (ISCSI_SCSI_SENSE_DATA_SENSE_KEY_THIRD_BIT)) | (1 << (ISCSI_SCSI_SENSE_DATA_SENSE_KEY_FOURTH_BIT))) +#define ISCSI_SCSI_SENSE_DATA_SENSE_KEY_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_SENSE_DATA_SENSE_KEY_FIRST_BIT, ISCSI_SCSI_SENSE_DATA_SENSE_KEY_LAST_BIT)) /// iSCSI SCSI sense data sense key: Extracts the Sense Key (SK) bits. -#define ISCSI_SCSI_SENSE_DATA_GET_SENSE_KEY(x) (((x) & ISCSI_SCSI_SENSE_DATA_SENSE_KEY_MASK) >> ISCSI_SCSI_SENSE_DATA_SENSE_KEY_FIRST_BIT) +#define ISCSI_SCSI_SENSE_DATA_GET_SENSE_KEY(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_SENSE_DATA_SENSE_KEY_FIRST_BIT, ISCSI_SCSI_SENSE_DATA_SENSE_KEY_LAST_BIT)) + +/// iSCSI SCSI sense data sense key: Stores into the Sense Key (SK) bits. +#define ISCSI_SCSI_SENSE_DATA_PUT_SENSE_KEY(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_SENSE_DATA_SENSE_KEY_FIRST_BIT, ISCSI_SCSI_SENSE_DATA_SENSE_KEY_LAST_BIT)) // iSCSI SCSI sense data sense key flags: ILI. -#define ISCSI_SCSI_SENSE_DATA_SENSE_KEY_FLAGS_ILI (1 << 5L) +#define ISCSI_SCSI_SENSE_DATA_SENSE_KEY_FLAGS_ILI (1 << 5) // iSCSI SCSI sense data sense key flags: EOM. -#define ISCSI_SCSI_SENSE_DATA_SENSE_KEY_FLAGS_EOM (1 << 6L) +#define ISCSI_SCSI_SENSE_DATA_SENSE_KEY_FLAGS_EOM (1 << 6) // iSCSI SCSI sense data sense key flags: FILEMARK. -#define ISCSI_SCSI_SENSE_DATA_SENSE_KEY_FLAGS_FILEMARK (1 << 7L) +#define ISCSI_SCSI_SENSE_DATA_SENSE_KEY_FLAGS_FILEMARK (1 << 7) /** @@ -1448,14 +1944,26 @@ typedef struct __attribute__((packed)) iscsi_scsi_sense_data_packet { } iscsi_scsi_sense_data_packet; /// iSCSI SCSI maximum sense data length. -#define ISCSI_SCSI_MAX_SENSE_DATA_LEN (sizeof(struct iscsi_scsi_sense_data_packet) + 255UL) +#define ISCSI_SCSI_MAX_SENSE_DATA_LEN (sizeof(struct iscsi_scsi_sense_data_packet) + 255U) -// iSCSI SCSI sense data check condition sense key specific bit mask. -#define ISCSI_SCSI_SENSE_DATA_CHECK_COND_SENSE_KEY_SPEC_MASK 0x3F +/// iSCSI SCSI sense data check condition sense key specific: First bit of the six bits. +#define ISCSI_SCSI_SENSE_DATA_CHECK_COND_SENSE_KEY_SPEC_FIRST_BIT 0 + +/// iSCSI SCSI sense data check condition sense key specific: Last bit of the six bits. +#define ISCSI_SCSI_SENSE_DATA_CHECK_COND_SENSE_KEY_SPEC_LAST_BIT ((ISCSI_SCSI_SENSE_DATA_CHECK_COND_SENSE_KEY_SPEC_FIRST_BIT) + 6 - 1) + +/// iSCSI SCSI sense data check condition sense key specific: Bit mask. +#define ISCSI_SCSI_SENSE_DATA_CHECK_COND_SENSE_KEY_SPEC_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_SENSE_DATA_CHECK_COND_SENSE_KEY_SPEC_FIRST_BIT, ISCSI_SCSI_SENSE_DATA_CHECK_COND_SENSE_KEY_SPEC_LAST_BIT)) + +/// iSCSI SCSI sense data check condition sense key specific: Extracts the sense key specific bits. +#define ISCSI_SCSI_SENSE_DATA_CHECK_COND_GET_SENSE_KEY_SPEC(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_SENSE_DATA_SENSE_KEY_FIRST_BIT, ISCSI_SCSI_SENSE_DATA_SENSE_KEY_LAST_BIT)) + +/// iSCSI SCSI sense data check condition sense key specific: Stores into the sense key specific bits. +#define ISCSI_SCSI_SENSE_DATA_CHECK_COND_PUT_SENSE_KEY_SPEC(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_SENSE_DATA_SENSE_KEY_FIRST_BIT, ISCSI_SCSI_SENSE_DATA_SENSE_KEY_LAST_BIT)) // iSCSI SCSI sense data check condition sense key specific flags: SKSV. -#define ISCSI_SCSI_SENSE_DATA_CHECK_COND_SENSE_KEY_SPEC_FLAGS_SKSV (1 << 7L) +#define ISCSI_SCSI_SENSE_DATA_CHECK_COND_SENSE_KEY_SPEC_FLAGS_SKSV (1 << 7) /** @@ -1504,84 +2012,90 @@ typedef struct __attribute__((packed)) iscsi_scsi_read_capacity_10_parameter_dat /// iSCSI SCSI command SERVICE ACTION IN(16) parameter data flags: Protection enabled (PROT_EN). -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROT_EN (1 << 0L) +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROT_EN (1 << 0) /// iSCSI SCSI command SERVICE ACTION IN(16) parameter data protection type flags: First bit of the three bits. #define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROTECT_TYPE_FIRST_BIT 1 -/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data protection type flags: Second bit of the three bits. -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROTECT_TYPE_SECOND_BIT ((ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROTECT_TYPE_FIRST_BIT) + 1) - -/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data protection type flags: Third bit of the three bits. -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROTECT_TYPE_THIRD_BIT ((ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROTECT_TYPE_SECOND_BIT) + 1) +/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data protection type flags: Last bit of the three bits. +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROTECT_TYPE_LAST_BIT ((ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROTECT_TYPE_FIRST_BIT) + 3 - 1) /// iSCSI SCSI command SERVICE ACTION IN(16) parameter data protection type flags: Bit mask. -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROTECT_TYPE_MASK ((1 << (ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROTECT_TYPE_FIRST_BIT)) | (1 << (ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROTECT_TYPE_SECOND_BIT)) | (1 << (ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROTECT_TYPE_THIRD_BIT))) +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROTECT_TYPE_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROTECT_TYPE_FIRST_BIT, ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROTECT_TYPE_LAST_BIT)) /// iSCSI SCSI command SERVICE ACTION IN(16) parameter data protection type flags: Extracts the protection type bits. -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_GET_PROTECT_TYPE(x) (((x) & ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROTECT_TYPE_MASK) >> ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROTECT_TYPE_FIRST_BIT) +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_GET_PROTECT_TYPE(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROTECT_TYPE_FIRST_BIT, ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROTECT_TYPE_LAST_BIT)) + +/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data protection type flags: Stores into the protection type bits. +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PUT_PROTECT_TYPE(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROTECT_TYPE_FIRST_BIT, ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PROTECT_TYPE_LAST_BIT)) /// iSCSI SCSI command SERVICE ACTION IN(16) parameter data RC basis flags: First bit of the two bits. #define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_RC_BASIS_FIRST_BIT 4 -/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data RC basis flags: Second bit of the two bits. -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_RC_BASIS_SECOND_BIT ((ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_RC_BASIS_FIRST_BIT) + 1) +/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data RC basis flags: Last bit of the two bits. +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_RC_BASIS_LAST_BIT ((ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_RC_BASIS_FIRST_BIT) + 2 - 1) /// iSCSI SCSI command SERVICE ACTION IN(16) parameter data RC basis flags: Bit mask. -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_RC_BASIS_MASK ((1 << (ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_RC_BASIS_FIRST_BIT)) | (1 << (ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_RC_BASIS_SECOND_BIT))) +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_RC_BASIS_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_RC_BASIS_FIRST_BIT, ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_RC_BASIS_LAST_BIT)) /// iSCSI SCSI command SERVICE ACTION IN(16) parameter data RC basis flags: Extracts the RC basis bits. -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_GET_RC_BASIS(x) (((x) & ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_RC_BASIS_MASK) >> ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_RC_BASIS_FIRST_BIT) +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_GET_RC_BASIS(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_RC_BASIS_FIRST_BIT, ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_RC_BASIS_LAST_BIT)) +/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data RC basis flags: Stores into the RC basis bits. +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_PUT_RC_BASIS(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_RC_BASIS_FIRST_BIT, ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_FLAGS_RC_BASIS_LAST_BIT)) -/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data logical blocks per physical block exponent: First bit of the four bits. -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_FIRST_BIT 0 - -/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data logical blocks per physical block exponent: Second bit of the four bits. -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_SECOND_BIT ((ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_FIRST_BIT) + 1) -/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data logical blocks per physical block exponent: Third bit of the four bits. -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_THIRD_BIT ((ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_SECOND_BIT) + 1) +/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data logical blocks per physical block exponent: First bit of the four bits. +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_FIRST_BIT 0 -/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data logical blocks per physical block exponent: Fourth bit of the four bits. -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_FOURTH_BIT ((ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_THIRD_BIT) + 1) +/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data logical blocks per physical block exponent: Last bit of the four bits. +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_LAST_BIT ((ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_FIRST_BIT) + 4 - 1) /// iSCSI SCSI command SERVICE ACTION IN(16) parameter data logical blocks per physical block exponent: Bit mask. -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_MASK ((1 << (ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_FIRST_BIT)) | (1 << (ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_SECOND_BIT)) | (1 << (ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_THIRD_BIT)) | (1 << (ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_FOURTH_BIT))) +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_FIRST_BIT, ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_LAST_BIT)) /// iSCSI SCSI command SERVICE ACTION IN(16) parameter data logical blocks per physical block exponent: Extracts the logical blocks per physical block bits. -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_GET_LBPPB_EXPONENT(x) (((x) & ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_MASK) >> ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_FIRST_BIT) +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_GET_LBPPB_EXPONENT(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_FIRST_BIT, ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_LAST_BIT)) + +/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data logical blocks per physical block exponent: Stores into the logical blocks per physical block bits. +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_PUT_LBPPB_EXPONENT(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_FIRST_BIT, ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPPB_EXPONENT_LAST_BIT)) /// iSCSI SCSI command SERVICE ACTION IN(16) parameter data protection information intervals exponent: First bit of the four bits. -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_FIRST_BIT 4 +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_FIRST_BIT 4 -/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data protection information intervals exponent: Second bit of the four bits. -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_SECOND_BIT ((ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_FIRST_BIT) + 1) +/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data protection information intervals exponent: Last bit of the four bits. +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_LAST_BIT ((ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_FIRST_BIT) + 4 - 1) -/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data protection information intervals exponent: Third bit of the four bits. -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_THIRD_BIT ((ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_SECOND_BIT) + 1) +/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data protection information intervals exponent: Bit mask. +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_FIRST_BIT, ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_LAST_BIT)) -/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data protection information intervals exponent: Fourth bit of the four bits. -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_FOURTH_BIT ((ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_THIRD_BIT) + 1) +/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data protection information intervals exponent: Extracts the protection information intervals bits. +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_GET_P_I_EXPONENT(x) (ISCSI_BITS_GET((x), ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_FIRST_BIT, ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_LAST_BIT)) -/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data protection information intervals exponent: Bit mask. -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_MASK ((1 << (ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_FIRST_BIT)) | (1 << (ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_SECOND_BIT)) | (1 << (ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_THIRD_BIT)) | (1 << (ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_FOURTH_BIT))) +/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data protection information intervals exponent: Stores into the protection information intervals bits. +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_PUT_P_I_EXPONENT(x) (ISCSI_BITS_PUT((x), ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_FIRST_BIT, ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_LAST_BIT)) -/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data protection information intervals exponent: Extracts the Peripheral device type bits. -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_GET_P_I_EXPONENT(x) (((x) & ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_MASK) >> ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_P_I_EXPONENT_FIRST_BIT) +/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data protection information intervals exponent: First bit of the four bits. +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LALBA_FIRST_BIT 0 + +/// iSCSI SCSI command SERVICE ACTION IN(16) parameter data protection information intervals exponent: Last bit of the four bits. +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LALBA_LAST_BIT ((ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LALBA_FIRST_BIT) + 14 - 1) /// iSCSI SCSI command SERVICE ACTION IN(16) parameter logical block provisioning: Lowest Aligned Logical Block Address mask (LALBA). -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LALBA_MASK 0x3FFF +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LALBA_MASK (ISCSI_BITS_GET_MASK(ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LALBA_FIRST_BIT, ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LALBA_LAST_BIT)) /// iSCSI SCSI command SERVICE ACTION IN(16) parameter logical block provisioning: Extracts the Lowest Aligned Logical Block Address (LALBA) bits. -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_GET_LABLA ((x) & ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LALBA_MASK) +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_GET_LABLA (ISCSI_BITS_GET((x), ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LALBA_FIRST_BIT, ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LALBA_LAST_BIT)) + +/// iSCSI SCSI command SERVICE ACTION IN(16) parameter logical block provisioning: Stores into the Lowest Aligned Logical Block Address (LALBA) bits. +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_PUT_LABLA (ISCSI_BITS_PUT((x), ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LALBA_FIRST_BIT, ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LALBA_LAST_BIT)) /// iSCSI SCSI command SERVICE ACTION IN(16) parameter logical block provisioning: Logical Block Provisioning Read Zeros (LBPRZ). -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPRZ (1 << 14L) +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPRZ (1 << 14) /// iSCSI SCSI command SERVICE ACTION IN(16) parameter logical block provisioning: Logical Block Provisioning Management Enabled (LBPME). -#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPME (1 << 15L) +#define ISCSI_SCSI_SERVICE_ACTION_IN_16_PARAM_DATA_LBPME (1 << 15) /** @@ -1601,7 +2115,7 @@ typedef struct __attribute__((packed)) iscsi_scsi_service_action_in_16_parameter int8_t flags; /// P_I_EXPONENT and logical blocks per physical block exponent. - uint8_t expontents; + 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; @@ -1611,6 +2125,134 @@ typedef struct __attribute__((packed)) iscsi_scsi_service_action_in_16_parameter } iscsi_scsi_service_action_in_16_parameter_data_packet; +/** + * @brief iSCSI SCSI command REPORT LUNS parameter data LUN list packet data. + * + * This returns the number of entries in the + * 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; + + /// 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 MODE SELECT(6) parameter list packet data. + * + * 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; +} iscsi_scsi_mode_select_6_parameter_list_packet; + + +/** + * @brief iSCSI SCSI command MODE SELECT(10) parameter list packet data. + * + * 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; +} iscsi_scsi_mode_select_10_parameter_list_packet; + + +/** + * @brief iSCSI SCSI command MODE SENSE(6) parameter list packet data. + * + * This returns 32-bit vendor specific data. + */ +typedef struct __attribute__((packed)) iscsi_scsi_mode_sense_parameter_data_packet { + /// Vendor specific data. + uint32_t vendor_data; +} iscsi_scsi_mode_sense_parameter_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 @@ -3392,35 +4034,49 @@ typedef struct __attribute__((packed)) iscsi_text_response_packet { iscsi_data_digest data_digest; } iscsi_text_response_packet; -/// Initiator Session ID (ISID) type: Two bits - The T field identifies the format and usage of A, B, C, and D. -#define ISCSI_ISID_TYPE_BITS (1 << 6) /** - * @brief Initiator Session ID (ISID) type: OUI-Format. + * @brief iSCSI Initiator Session ID (ISID) type: OUI-Format. * * A and B: 22-bit OUI * (the I/G and U/L bits are omitted) * C and D: 24-bit Qualifier. */ -#define ISCSI_ISID_TYPE_FORMAT_OUI 0x0 +#define ISCSI_ISID_TYPE_FORMAT_OUI 0x0 /** - * @brief Initiator Session ID (ISID) type: EN: Format (IANA Enterprise Number). + * @brief iSCSI Initiator Session ID (ISID) type: EN: Format (IANA Enterprise Number). * * A: Reserved * B and C: EN (IANA Enterprise Number) * D: Qualifier */ -#define ISCSI_ISID_TYPE_FORMAT_EN 0x1 +#define ISCSI_ISID_TYPE_FORMAT_EN 0x1 /** - * @brief Initiator Session ID (ISID) type: Random. + * @brief iSCSI Initiator Session ID (ISID) type: Random. * * A: Reserved * B and C: Random * D: Qualifier */ -#define ISCSI_ISID_TYPE_FORMAT_RANDOM 0x2 +#define ISCSI_ISID_TYPE_FORMAT_RANDOM 0x2 + +/// iSCSI Initiator Session ID (ISID) type format: First bit of the two bits. +#define ISCSI_ISID_TYPE_FORMAT_FIRST_BIT 6 + +/// iSCSI Initiator Session ID (ISID) type format: Last bit of the two bits. +#define ISCSI_ISID_TYPE_FORMAT_LAST_BIT ((ISCSI_ISID_TYPE_FORMAT_FIRST_BIT) + 2 - 1) + +/// iSCSI Initiator Session ID (ISID) type format: Bit mask. +#define ISCSI_ISID_TYPE_FORMAT_MASK (ISCSI_BITS_GET_MASK(ISCSI_ISID_TYPE_FORMAT_FIRST_BIT, ISCSI_ISID_TYPE_FORMAT_LAST_BIT)) + +/// iSCSI Initiator Session ID (ISID) type format: Extracts the type format. +#define ISCSI_ISID_GET_TYPE_FORMAT(x) (ISCSI_BITS_GET((x), ISCSI_ISID_TYPE_FORMAT_FIRST_BIT, ISCSI_ISID_TYPE_FORMAT_LAST_BIT)) + +/// iSCSI Initiator Session ID (ISID) type format: Stores into the type format. +#define ISCSI_ISID_PUT_TYPE_FORMAT(x) (ISCSI_BITS_PUT((x), ISCSI_ISID_TYPE_FORMAT_FIRST_BIT, ISCSI_ISID_TYPE_FORMAT_LAST_BIT)) + /** * @brief iSCSI Initiator Session ID (ISID) packet data. @@ -5202,10 +5858,10 @@ typedef struct __attribute__((packed)) iscsi_isid { * next stage to which they want to move. The Next Stage value is only * valid when the T bit is 1; otherwise, it is reserved. */ -#define ISCSI_LOGIN_REQ_FLAGS_NEXT_STAGE_FIRST_BIT 0 +#define ISCSI_LOGIN_REQ_FLAGS_NEXT_STAGE_FIRST_BIT 0 /** - * @brief Login request flags: Next Stage (NSG): Second bit of the two bits. + * @brief Login request flags: Next Stage (NSG): Last bit of the two bits. * * The Login negotiation requests and responses are associated * with a specific stage in the session (SecurityNegotiation,\n @@ -5213,13 +5869,16 @@ typedef struct __attribute__((packed)) iscsi_isid { * next stage to which they want to move. The Next Stage value is only * valid when the T bit is 1; otherwise, it is reserved. */ -#define ISCSI_LOGIN_REQ_FLAGS_NEXT_STAGE_SECOND_BIT ((ISCSI_LOGIN_REQ_FLAGS_NEXT_STAGE_FIRST_BIT) + 1) +#define ISCSI_LOGIN_REQ_FLAGS_NEXT_STAGE_LAST_BIT ((ISCSI_LOGIN_REQ_FLAGS_NEXT_STAGE_FIRST_BIT) + 2 - 1) /// Login request flags: Next Stage (NSG): Bit mask. -#define ISCSI_LOGIN_REQ_FLAGS_NEXT_STAGE_MASK ((1 << (ISCSI_LOGIN_REQ_FLAGS_NEXT_STAGE_FIRST_BIT)) | (1 << (ISCSI_LOGIN_REQ_FLAGS_NEXT_STAGE_SECOND_BIT))) +#define ISCSI_LOGIN_REQ_FLAGS_NEXT_STAGE_MASK (ISCSI_BITS_GET_MASK(ISCSI_LOGIN_REQ_FLAGS_NEXT_STAGE_FIRST_BIT, ISCSI_LOGIN_REQ_FLAGS_NEXT_STAGE_LAST_BIT)) /// Login request flags: Extracts the Next Stage (NSG) bits. -#define ISCSI_LOGIN_REQ_FLAGS_GET_NEXT_STAGE(x) (((x) & ISCSI_LOGIN_REQ_FLAGS_NEXT_STAGE_MASK) >> ISCSI_LOGIN_REQ_FLAGS_NEXT_STAGE_FIRST_BIT) +#define ISCSI_LOGIN_REQ_FLAGS_GET_NEXT_STAGE(x) (ISCSI_BITS_GET((x), ISCSI_LOGIN_REQ_FLAGS_NEXT_STAGE_FIRST_BIT, ISCSI_LOGIN_REQ_FLAGS_NEXT_STAGE_LAST_BIT)) + +/// Login request flags: Stores into the Next Stage (NSG) bits. +#define ISCSI_LOGIN_REQ_FLAGS_PUT_NEXT_STAGE(x) (ISCSI_BITS_PUT((x), ISCSI_LOGIN_REQ_FLAGS_NEXT_STAGE_FIRST_BIT, ISCSI_LOGIN_REQ_FLAGS_NEXT_STAGE_LAST_BIT)) /// Login request Current Stage (CSG) flags: SecurityNegotiation. @@ -5242,23 +5901,26 @@ typedef struct __attribute__((packed)) iscsi_isid { * LoginOperationalNegotiation, FullFeaturePhase) and may indicate the * next stage to which they want to move. */ -#define ISCSI_LOGIN_REQ_FLAGS_CURRENT_STAGE_FIRST_BIT 2 +#define ISCSI_LOGIN_REQ_FLAGS_CURRENT_STAGE_FIRST_BIT 2 /** - * @brief Login request flags: Current Stage (CSG): Second bit of the two bits. + * @brief Login request flags: Current Stage (CSG): Last bit of the two bits. * * The Login negotiation requests and responses are associated * with aspecific stage in the session (SecurityNegotiation, * LoginOperationalNegotiation, FullFeaturePhase) and may indicate the * next stage to which they want to move. */ -#define ISCSI_LOGIN_REQ_FLAGS_CURRENT_STAGE_SECOND_BIT ((ISCSI_LOGIN_REQ_FLAGS_CURRENT_STAGE_FIRST_BIT) + 1) +#define ISCSI_LOGIN_REQ_FLAGS_CURRENT_STAGE_LAST_BIT ((ISCSI_LOGIN_REQ_FLAGS_CURRENT_STAGE_FIRST_BIT) + 2 - 1) /// Login request flags: Current Stage (CSG): Bit mask. -#define ISCSI_LOGIN_REQ_FLAGS_CURRENT_STAGE_MASK ((1 << (ISCSI_LOGIN_REQ_FLAGS_CURRENT_STAGE_FIRST_BIT)) | (1 << (ISCSI_LOGIN_REQ_FLAGS_CURRENT_STAGE_SECOND_BIT))) +#define ISCSI_LOGIN_REQ_FLAGS_CURRENT_STAGE_MASK (ISCSI_BITS_GET_MASK(ISCSI_LOGIN_REQ_FLAGS_CURRENT_STAGE_FIRST_BIT, ISCSI_LOGIN_REQ_FLAGS_CURRENT_STAGE_LAST_BIT)) /// Login request flags: Extracts the Current Stage (CSG) bits. -#define ISCSI_LOGIN_REQ_FLAGS_GET_CURRENT_STAGE(x) (((x) & ISCSI_LOGIN_REQ_FLAGS_CURRENT_STAGE_MASK) >> ISCSI_LOGIN_REQ_FLAGS_CURRENT_STAGE_FIRST_BIT) +#define ISCSI_LOGIN_REQ_FLAGS_GET_CURRENT_STAGE(x) (ISCSI_BITS_GET((x), ISCSI_LOGIN_REQ_FLAGS_CURRENT_STAGE_FIRST_BIT, ISCSI_LOGIN_REQ_FLAGS_CURRENT_STAGE_LAST_BIT)) + +/// Login request flags: Stores into the Current Stage (CSG) bits. +#define ISCSI_LOGIN_REQ_FLAGS_PUT_CURRENT_STAGE(x) (ISCSI_BITS_PUT((x), ISCSI_LOGIN_REQ_FLAGS_CURRENT_STAGE_FIRST_BIT, ISCSI_LOGIN_REQ_FLAGS_CURRENT_STAGE_LAST_BIT)) /** @@ -5434,10 +6096,10 @@ typedef struct __attribute__((packed)) iscsi_login_req_packet { * next stage to which they want to move The Next Stage value is only * valid when the T bit is 1; otherwise, it is reserved. */ -#define ISCSI_LOGIN_RESPONSE_FLAGS_NEXT_STAGE_FIRST_BIT 0 +#define ISCSI_LOGIN_RESPONSE_FLAGS_NEXT_STAGE_FIRST_BIT 0 /** - * @brief Login response flags: Next Stage (NSG): First bit of the two bits. + * @brief Login response flags: Next Stage (NSG): Last bit of the two bits. * * The Login negotiation requests and responses are associated * with a specific stage in the session (SecurityNegotiation, @@ -5445,14 +6107,16 @@ typedef struct __attribute__((packed)) iscsi_login_req_packet { * next stage to which they want to move The Next Stage value is only * valid when the T bit is 1; otherwise, it is reserved. */ -#define ISCSI_LOGIN_RESPONSE_FLAGS_NEXT_STAGE_SECOND_BIT ((ISCSI_LOGIN_RESPONSE_FLAGS_NEXT_STAGE_FIRST_BIT) + 1) +#define ISCSI_LOGIN_RESPONSE_FLAGS_NEXT_STAGE_LAST_BIT ((ISCSI_LOGIN_RESPONSE_FLAGS_NEXT_STAGE_FIRST_BIT) + 2 - 1) /// Login response flags: Next Stage (NSG): Bit mask. -#define ISCSI_LOGIN_RESPONSE_FLAGS_NEXT_STAGE_MASK ((1 << (ISCSI_LOGIN_RESPONSE_FLAGS_NEXT_STAGE_FIRST_BIT)) | (1 << (ISCSI_LOGIN_RESPONSE_FLAGS_NEXT_STAGE_SECOND_BIT))) +#define ISCSI_LOGIN_RESPONSE_FLAGS_NEXT_STAGE_MASK (ISCSI_BITS_GET_MASK(ISCSI_LOGIN_RESPONSE_FLAGS_NEXT_STAGE_FIRST_BIT, ISCSI_LOGIN_RESPONSE_FLAGS_NEXT_STAGE_LAST_BIT)) /// Login response flags: Extracts the Next Stage (NSG) bits. -#define ISCSI_LOGIN_RESPONSE_FLAGS_GET_NEXT_STAGE(x) (((x) & ISCSI_LOGIN_RESPONSE_FLAGS_NEXT_STAGE_MASK) >> ISCSI_LOGIN_RESPONSE_FLAGS_NEXT_STAGE_FIRST_BIT) +#define ISCSI_LOGIN_RESPONSE_FLAGS_GET_NEXT_STAGE(x) (ISCSI_BITS_GET((x), ISCSI_LOGIN_RESPONSE_FLAGS_NEXT_STAGE_FIRST_BIT, ISCSI_LOGIN_RESPONSE_FLAGS_NEXT_STAGE_LAST_BIT)) +/// Login response flags: Stores into the Next Stage (NSG) bits. +#define ISCSI_LOGIN_RESPONSE_FLAGS_PUT_NEXT_STAGE(x) (ISCSI_BITS_PUT((x), ISCSI_LOGIN_RESPONSE_FLAGS_NEXT_STAGE_FIRST_BIT, ISCSI_LOGIN_RESPONSE_FLAGS_NEXT_STAGE_LAST_BIT)) /// Login response Current Stage (CSG) flags: SecurityNegotiation. @@ -5475,7 +6139,7 @@ typedef struct __attribute__((packed)) iscsi_login_req_packet { * LoginOperationalNegotiation, FullFeaturePhase) and may indicate the * next stage to which they want to move. */ -#define ISCSI_LOGIN_RESPONSE_FLAGS_CURRENT_STAGE_FIRST_BIT 2 +#define ISCSI_LOGIN_RESPONSE_FLAGS_CURRENT_STAGE_FIRST_BIT 2 /** * @brief Login response flags: Current Stage (CSG): First bit of the two bits. @@ -5485,13 +6149,16 @@ typedef struct __attribute__((packed)) iscsi_login_req_packet { * LoginOperationalNegotiation, FullFeaturePhase) and may indicate the * next stage to which they want to move. */ -#define ISCSI_LOGIN_RESPONSE_FLAGS_CURRENT_STAGE_SECOND_BIT ((ISCSI_LOGIN_RESPONSE_FLAGS_CURRENT_STAGE_FIRST_BIT) + 1) +#define ISCSI_LOGIN_RESPONSE_FLAGS_CURRENT_STAGE_LAST_BIT ((ISCSI_LOGIN_RESPONSE_FLAGS_CURRENT_STAGE_FIRST_BIT) + 2 - 1) /// Login request flags: Current Stage (CSG): Bit mask. -#define ISCSI_LOGIN_RESPONSE_FLAGS_CURRENT_STAGE_MASK ((1 << (ISCSI_LOGIN_RESPONSE_FLAGS_CURRENT_STAGE_FIRST_BIT)) | (1 << (ISCSI_LOGIN_RESPONSE_FLAGS_CURRENT_STAGE_SECOND_BIT))) +#define ISCSI_LOGIN_RESPONSE_FLAGS_CURRENT_STAGE_MASK (ISCSI_BITS_GET_MASK(ISCSI_LOGIN_RESPONSE_FLAGS_CURRENT_STAGE_FIRST_BIT, ISCSI_LOGIN_RESPONSE_FLAGS_CURRENT_STAGE_LAST_BIT)) /// Login request flags: Extracts the Current Stage (CSG) bits. -#define ISCSI_LOGIN_RESPONSE_FLAGS_GET_CURRENT_STAGE(x) (((x) & ISCSI_LOGIN_RESPONSE_FLAGS_CURRENT_STAGE_MASK) >> ISCSI_LOGIN_RESPONSE_FLAGS_CURRENT_STAGE_FIRST_BIT) +#define ISCSI_LOGIN_RESPONSE_FLAGS_GET_CURRENT_STAGE(x) (ISCSI_BITS_GET((x), ISCSI_LOGIN_RESPONSE_FLAGS_CURRENT_STAGE_FIRST_BIT, ISCSI_LOGIN_RESPONSE_FLAGS_CURRENT_STAGE_LAST_BIT)) + +/// Login request flags: Stores into the Current Stage (CSG) bits. +#define ISCSI_LOGIN_RESPONSE_FLAGS_PUT_CURRENT_STAGE(x) (ISCSI_BITS_PUT((x), ISCSI_LOGIN_RESPONSE_FLAGS_CURRENT_STAGE_FIRST_BIT, ISCSI_LOGIN_RESPONSE_FLAGS_CURRENT_STAGE_LAST_BIT)) /** @@ -6573,11 +7240,41 @@ typedef struct __attribute__((packed)) iscsi_nop_in_packet { } iscsi_nop_in_packet; -/// iSCSI SCSI transport ID protocol identifier. -#define ISCSI_TRANSPORT_ID_PROTOCOL_ID_ISCSI 0x05 +/// iSCSI SCSI transport ID protocol identifier: iSCSI. +#define ISCSI_TRANSPORT_ID_PROTOCOL_ID_ISCSI 0x05 + +/// iSCSI SCSI transport ID protocol identifier: First bit of the four bits. +#define ISCSI_TRANSPORT_ID_PROTOCOL_ID_FIRST_BIT 0 + +/// iSCSI SCSI transport ID protocol identifier: Last bit of the four bits. +#define ISCSI_TRANSPORT_ID_PROTOCOL_ID_LAST_BIT ((ISCSI_TRANSPORT_ID_PROTOCOL_ID_FIRST_BIT) + 4 - 1) + +/// iSCSI SCSI transport ID protocol identifier: Bit mask. +#define ISCSI_TRANSPORT_ID_PROTOCOL_ID_MASK (ISCSI_BITS_GET_MASK(ISCSI_TRANSPORT_ID_PROTOCOL_ID_FIRST_BIT, ISCSI_TRANSPORT_ID_PROTOCOL_ID_LAST_BIT)) + +/// iSCSI SCSI transport ID protocol identifier: Extracts the protocol identifier bits. +#define ISCSI_TRANSPORT_ID_GET_PROTOCOL_ID(x) (ISCSI_BITS_GET((x), ISCSI_TRANSPORT_ID_PROTOCOL_ID_FIRST_BIT, ISCSI_TRANSPORT_ID_PROTOCOL_ID_LAST_BIT)) + +/// iSCSI SCSI transport ID protocol identifier: Stores into the protocol identifier bits. +#define ISCSI_TRANSPORT_ID_PUT_PROTOCOL_ID(x) (ISCSI_BITS_PUT((x), ISCSI_TRANSPORT_ID_PROTOCOL_ID_FIRST_BIT, ISCSI_TRANSPORT_ID_PROTOCOL_ID_LAST_BIT)) /// iSCSI SCSI transport ID format. -#define ISCSI_TRANSPORT_ID_FORMAT 0x01 +#define ISCSI_TRANSPORT_ID_FORMAT 0x01 + +/// iSCSI SCSI transport ID format: First bit of the two bits. +#define ISCSI_TRANSPORT_ID_FORMAT_FIRST_BIT 6 + +/// iSCSI SCSI transport ID format: Last bit of the two bits. +#define ISCSI_TRANSPORT_ID_FORMAT_LAST_BIT ((ISCSI_TRANSPORT_ID_FORMAT_FIRST_BIT) + 2 - 1) + +/// iSCSI SCSI transport ID format: Bit mask. +#define ISCSI_TRANSPORT_ID_FORMAT_MASK (ISCSI_BITS_GET_MASK(ISCSI_TRANSPORT_ID_FORMAT_FIRST_BIT, ISCSI_TRANSPORT_ID_FORMAT_LAST_BIT)) + +/// iSCSI SCSI transport ID format: Extracts the format bits. +#define ISCSI_TRANSPORT_ID_GET_FORMAT(x) (ISCSI_BITS_GET((x), ISCSI_TRANSPORT_ID_FORMAT_FIRST_BIT, ISCSI_TRANSPORT_ID_FORMAT_LAST_BIT)) + +/// iSCSI SCSI transport ID format: Stores into the format bits. +#define ISCSI_TRANSPORT_ID_PUT_FORMAT(x) (ISCSI_BITS_PUT((x), ISCSI_TRANSPORT_ID_FORMAT_FIRST_BIT, ISCSI_TRANSPORT_ID_FORMAT_LAST_BIT)) typedef struct __attribute__((packed)) iscsi_transport_id { @@ -6596,31 +7293,31 @@ typedef struct __attribute__((packed)) iscsi_transport_id { /// iSCSI packet validation return code from iscsi_validate_packet function: Validation successful -> iSCSI packet recognized and compliance to protocol specification. -#define ISCSI_VALIDATE_PACKET_RESULT_OK 0L +#define ISCSI_VALIDATE_PACKET_RESULT_OK 0 /// iSCSI packet validation return code from iscsi_validate_packet function: Validation failed -> No packet data specified. -#define ISCSI_VALIDATE_PACKET_RESULT_ERROR_NO_DATA -1L +#define ISCSI_VALIDATE_PACKET_RESULT_ERROR_NO_DATA -1 /// iSCSI packet validation return code from iscsi_validate_packet function: Validation failed -> Packet size smaller than smallest possible iSCSI packet. -#define ISCSI_VALIDATE_PACKET_RESULT_ERROR_SIZE_TOO_SMALL -2L +#define ISCSI_VALIDATE_PACKET_RESULT_ERROR_SIZE_TOO_SMALL -2 /// iSCSI packet validation return code from iscsi_validate_packet function: Validation failed -> Packet size doesn't match calculated lengths from BHS. -#define ISCSI_VALIDATE_PACKET_RESULT_ERROR_SIZE_MISMATCH -3L +#define ISCSI_VALIDATE_PACKET_RESULT_ERROR_SIZE_MISMATCH -3 /// iSCSI packet validation return code from iscsi_validate_packet function: Validation failed -> iSCSI protocol version not supported yet. -#define ISCSI_VALIDATE_PACKET_RESULT_ERROR_UNSUPPORTED_VERSION -4L +#define ISCSI_VALIDATE_PACKET_RESULT_ERROR_UNSUPPORTED_VERSION -4 /// iSCSI packet validation return code from iscsi_validate_packet function: Validation failed -> Valid opcode but violates iSCSI protocol specification. -#define ISCSI_VALIDATE_PACKET_RESULT_ERROR_PROTOCOL_SPECS -5L +#define ISCSI_VALIDATE_PACKET_RESULT_ERROR_PROTOCOL_SPECS -5 /// iSCSI packet validation return code from iscsi_validate_packet function: Validation failed -> Invalid opcode according to iSCSI protocol specification. -#define ISCSI_VALIDATE_PACKET_RESULT_ERROR_INVALID_OPCODE -6L +#define ISCSI_VALIDATE_PACKET_RESULT_ERROR_INVALID_OPCODE -6 /// iSCSI packet validation return code from iscsi_validate_packet function: Validation failed -> CRC32C check failed for header (BHS and/or AHS). -#define ISCSI_VALIDATE_PACKET_RESULT_ERROR_CRC32C_HDR_DIGEST -7L +#define ISCSI_VALIDATE_PACKET_RESULT_ERROR_CRC32C_HDR_DIGEST -7 /// iSCSI packet validation return code from iscsi_validate_packet function: Validation failed -> CRC32C check failed for data segment. -#define ISCSI_VALIDATE_PACKET_RESULT_ERROR_CRC32C_DATA_DIGEST -8L +#define ISCSI_VALIDATE_PACKET_RESULT_ERROR_CRC32C_DATA_DIGEST -8 iscsi_bhs_packet *iscsi_create_packet(); // Allocate and initialize an iSCSI BHS packet @@ -6644,66 +7341,66 @@ int iscsi_validate_packet(const struct iscsi_bhs_packet *packet_data, const uint /// Maximum length of a key according to iSCSI specifications. -#define ISCSI_TEXT_KEY_MAX_LEN 63UL +#define ISCSI_TEXT_KEY_MAX_LEN 63U /// Maximum length of value for a simple key type. -#define ISCSI_TEXT_VALUE_MAX_SIMPLE_LEN 255UL +#define ISCSI_TEXT_VALUE_MAX_SIMPLE_LEN 255U /// Maximum length of value for a normal key. -#define ISCSI_TEXT_VALUE_MAX_LEN 8192UL +#define ISCSI_TEXT_VALUE_MAX_LEN 8192U /// iSCSI text key=value pair type: Invalid. -#define ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_INVALID -1L +#define ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_INVALID -1 /// iSCSI text key=value pair type: Unspecified type. -#define ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_UNSPECIFIED 0L +#define ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_UNSPECIFIED 0 /// iSCSI text key=value pair type: List. -#define ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_LIST 1L +#define ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_LIST 1 /// iSCSI text key=value pair type: Numerical minimum. -#define ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_MIN 2L +#define ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_MIN 2 /// iSCSI text key=value pair type: Numerical maximum. -#define ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_MAX 3L +#define ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_MAX 3 /// iSCSI text key=value pair type: Numerical declarative. -#define ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_DECLARATIVE 4L +#define ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_NUM_DECLARATIVE 4 /// iSCSI text key=value pair type: Declarative. -#define ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_DECLARATIVE 5L +#define ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_DECLARATIVE 5 /// iSCSI text key=value pair type: Boolean OR. -#define ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_BOOL_OR 6L +#define ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_BOOL_OR 6 /// iSCSI text key=value pair type: Boolean AND. -#define ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_BOOL_AND 7L +#define ISCSI_TEXT_KEY_VALUE_PAIR_TYPE_BOOL_AND 7 /// iSCSI key value pair flags: Discovery ignored. -#define ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_DISCOVERY_IGNORE (1 << 0L) +#define ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_DISCOVERY_IGNORE (1 << 0) /// iSCSI key value pair flags: Multi negotiation. -#define ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_MULTI_NEGOTIATION (1 << 1L) +#define ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_MULTI_NEGOTIATION (1 << 1) /// iSCSI key value pair flags: Target declarative. -#define ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_TARGET_DECLARATIVE (1 << 2L) +#define ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_TARGET_DECLARATIVE (1 << 2) /// iSCSI key value pair flags: CHAP type. -#define ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_CHAP_TYPE (1 << 3L) +#define ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_CHAP_TYPE (1 << 3) /// iSCSI key value pair flags: Requires special handling. -#define ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_SPECIAL_HANDLING (1 << 4L) +#define ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_SPECIAL_HANDLING (1 << 4) /// iSCSI key value pair flags: Use previous default value. -#define ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_USE_PREVIOUS_VALUE (1 << 5L) +#define ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_USE_PREVIOUS_VALUE (1 << 5) /// iSCSI key value pair flags: Override with default value. -#define ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_OVERRIDE_DEFAULT (1 << 6L) +#define ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_OVERRIDE_DEFAULT (1 << 6) /// iSCSI key value pair flags: Uses maximum value depending on secondary key. -#define ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_USE_OTHER_MAX_VALUE (1 << 7L) +#define ISCSI_TEXT_KEY_VALUE_PAIR_FLAGS_USE_OTHER_MAX_VALUE (1 << 7) /** @@ -6783,16 +7480,16 @@ int iscsi_parse_key_value_pairs(iscsi_hashmap *pairs, const uint8_t *packet_data /// iSCSI main global data flags: Allow duplicate ISIDs. -#define ISCSI_GLOBALS_FLAGS_ISID_ALLOW_DUPLICATES (1 << 0L) +#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 << 1L) +#define ISCSI_GLOBALS_FLAGS_CHAP_DISABLE (1 << 1) /// iSCSI main global data flags: CHAP authentication is required. -#define ISCSI_GLOBALS_FLAGS_CHAP_REQUIRE (1 << 2L) +#define ISCSI_GLOBALS_FLAGS_CHAP_REQUIRE (1 << 2) /// iSCSI main global data flags: CHAP authentication is mutual. -#define ISCSI_GLOBALS_FLAGS_CHAP_MUTUAL (1 << 3L) +#define ISCSI_GLOBALS_FLAGS_CHAP_MUTUAL (1 << 3) /** @@ -6837,6 +7534,9 @@ typedef struct 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 int iscsi_global_key_value_pair_destroy_callback(uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *user_data); // iSCSI global key and value pair destructor callback for hash map @@ -6853,16 +7553,16 @@ void iscsi_destroy(); // Deallocates all resources acquired by iscsi_create * Private portal groups instead do not return their portals during * the discovery session. */ -#define ISCSI_PORTAL_GROUP_PRIVATE (1 << 0L) +#define ISCSI_PORTAL_GROUP_PRIVATE (1 << 0) /// iSCSI portal group: CHAP authentication is disabled. -#define ISCSI_PORTAL_GROUP_CHAP_DISABLE (1 << 1L) +#define ISCSI_PORTAL_GROUP_CHAP_DISABLE (1 << 1) /// iSCSI portal group: CHAP authentication is required. -#define ISCSI_PORTAL_GROUP_CHAP_REQUIRE (1 << 2L) +#define ISCSI_PORTAL_GROUP_CHAP_REQUIRE (1 << 2) /// iSCSI portal group: CHAP authentication is mutual. -#define ISCSI_PORTAL_GROUP_CHAP_MUTUAL (1 << 3L) +#define ISCSI_PORTAL_GROUP_CHAP_MUTUAL (1 << 3) /** @@ -6918,13 +7618,6 @@ iscsi_portal *iscsi_portal_create(const uint8_t *host, const uint8_t *port); // void iscsi_portal_destroy(iscsi_portal *portal); -/// iSCSI SCSI task flags: Read. -#define ISCSI_SCSI_TASK_FLAGS_XFER_READ (1 << 0L) - -/// iSCSI SCSI task flags: Write. -#define ISCSI_SCSI_TASK_FLAGS_XFER_WRITE (1 << 1L) - - /// iSCSI SCSI status code: Good. #define ISCSI_SCSI_STATUS_GOOD 0x00 @@ -7147,7 +7840,7 @@ typedef struct iscsi_scsi_pr_registrant { /// iSCSI SCSI Persistent Reservation (PR) reservation flags: SPC2 reserve. -#define ISCSI_SCSI_PR_RESERVATION_FLAGS_SPC2_RESERVE (1 << 0L) +#define ISCSI_SCSI_PR_RESERVATION_FLAGS_SPC2_RESERVE (1L << 0L) /** @@ -7192,13 +7885,13 @@ typedef struct iscsi_scsi_pr_registrant_get_reg { /// iSCSI SCSI task run: Unknown. -#define ISCSI_SCSI_TASK_RUN_UNKNOWN -1L +#define ISCSI_SCSI_TASK_RUN_UNKNOWN -1 /// iSCSI SCSI task run: Completed. -#define ISCSI_SCSI_TASK_RUN_COMPLETE 0L +#define ISCSI_SCSI_TASK_RUN_COMPLETE 0 /// iSCSI SCSI task run: Pending. -#define ISCSI_SCSI_TASK_RUN_PENDING 1L +#define ISCSI_SCSI_TASK_RUN_PENDING 1 typedef struct iscsi_scsi_task iscsi_scsi_task; @@ -7212,6 +7905,13 @@ typedef void (*iscsi_scsi_task_xfer_complete_callback)(iscsi_scsi_task *scsi_tas typedef void (*iscsi_scsi_task_destroy_callback)(iscsi_scsi_task *scsi_task); +/// 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. * @@ -7290,14 +7990,14 @@ typedef struct iscsi_scsi_task { /// iSCSI SCSI emulation I/O type: Unmap. -#define ISCSI_SCSI_EMU_IO_TYPE_UNMAP (1 << 0L) +#define ISCSI_SCSI_EMU_IO_TYPE_UNMAP (1 << 0) /// iSCSI SCSI emulation block flags: Write operation. -#define ISCSI_SCSI_EMU_BLOCK_FLAGS_WRITE (1 << 0L) +#define ISCSI_SCSI_EMU_BLOCK_FLAGS_WRITE (1 << 0) /// iSCSI SCSI emulation block flags: Verify operation. -#define ISCSI_SCSI_EMU_BLOCK_FLAGS_VERIFY (1 << 1L) +#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 @@ -7326,12 +8026,16 @@ void iscsi_scsi_lun_task_exec(iscsi_scsi_lun *lun, iscsi_scsi_task *scsi_task); 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 int iscsi_scsi_emu_exec(iscsi_scsi_task *scsi_task); // Executes the iSCSI SCSI emulation for an iSCSI SCSI task /// iSCSI port flags: In use. -#define ISCSI_PORT_FLAGS_IN_USE (1 << 0L) +#define ISCSI_PORT_FLAGS_IN_USE (1 << 0) /** @@ -7371,10 +8075,13 @@ int iscsi_port_transport_id_set(iscsi_port *port, const uint8_t *name, const uin /// iSCSI SCSI LUN flags: Removed. -#define ISCSI_SCSI_LUN_FLAGS_REMOVED (1 << 0L) +#define ISCSI_SCSI_LUN_FLAGS_REMOVED (1 << 0) /// iSCSI SCSI LUN flags: Resizing. -#define ISCSI_SCSI_LUN_FLAGS_RESIZING (1 << 1L) +#define ISCSI_SCSI_LUN_FLAGS_RESIZING (1 << 1) + + +typedef struct iscsi_device iscsi_device; /** @@ -7406,6 +8113,9 @@ typedef struct iscsi_scsi_lun { /// Persistent Reservation (PR) holder for SPC2 RESERVE(6) and RESERVE(10). iscsi_scsi_pr_registrant pr_scsi2_holder; + /// iSCSI device which belongs to this LUN. + iscsi_device *device; + /// Assocated DNBD3 image for this LUN. dnbd3_image_t *image; @@ -7466,10 +8176,10 @@ typedef struct iscsi_r2t_remove_pdu { /// iSCSI device flags: Allocated. -#define ISCSI_DEVICE_FLAGS_ALLOCATED (1 << 0L) +#define ISCSI_DEVICE_FLAGS_ALLOCATED (1 << 0) /// iSCSI device flags: Removed. -#define ISCSI_DEVICE_FLAGS_REMOVED (1 << 1L) +#define ISCSI_DEVICE_FLAGS_REMOVED (1 << 1) /** @@ -7516,20 +8226,20 @@ typedef struct iscsi_device_find_lun_id { /// iSCSI target node maximum length -#define ISCSI_TARGET_NODE_MAX_NAME_LEN 223UL +#define ISCSI_TARGET_NODE_MAX_NAME_LEN 223U /// iSCSI target node flags: CHAP authentication disabled. -#define ISCSI_TARGET_NODE_FLAGS_CHAP_DISABLE (1 << 0L) +#define ISCSI_TARGET_NODE_FLAGS_CHAP_DISABLE (1 << 0) /// iSCSI target node flags: CHAP authentication required. -#define ISCSI_TARGET_NODE_FLAGS_CHAP_REQUIRE (1 << 1L) +#define ISCSI_TARGET_NODE_FLAGS_CHAP_REQUIRE (1 << 1) /// iSCSI target node flags: CHAP authentication mutual. -#define ISCSI_TARGET_NODE_FLAGS_CHAP_MUTUAL (1 << 2L) +#define ISCSI_TARGET_NODE_FLAGS_CHAP_MUTUAL (1 << 2) /// iSCSI target node flags: Destroyed. -#define ISCSI_TARGET_NODE_FLAGS_DESTROYED (1 << 3L) +#define ISCSI_TARGET_NODE_FLAGS_DESTROYED (1 << 3) /** @@ -7588,16 +8298,16 @@ typedef struct iscsi_target_node_find_name { /// iSCSI authentication CHAP phase: None. -#define ISCSI_AUTH_CHAP_PHASE_NONE 0L +#define ISCSI_AUTH_CHAP_PHASE_NONE 0 /// iSCSI authentication CHAP phase: Wait A. -#define ISCSI_AUTH_CHAP_PHASE_WAIT_A 1L +#define ISCSI_AUTH_CHAP_PHASE_WAIT_A 1 /// iSCSI authentication CHAP phase: Wait NR. -#define ISCSI_AUTH_CHAP_PHASE_WAIT_NR 2L +#define ISCSI_AUTH_CHAP_PHASE_WAIT_NR 2 /// iSCSI authentication CHAP phase: End. -#define ISCSI_AUTH_CHAP_PHASE_END 3L +#define ISCSI_AUTH_CHAP_PHASE_END 3 /** @@ -7613,29 +8323,29 @@ typedef struct iscsi_auth_chap { /// iSCSI session flags: Initial ready to transfer. -#define ISCSI_SESSION_FLAGS_INIT_R2T (1 << 0L) +#define ISCSI_SESSION_FLAGS_INIT_R2T (1 << 0) /// iSCSI session flags: Immediate data. -#define ISCSI_SESSION_FLAGS_IMMEDIATE_DATA (1 << 1L) +#define ISCSI_SESSION_FLAGS_IMMEDIATE_DATA (1 << 1) /// iSCSI session flags: Data PDU in order. -#define ISCSI_SESSION_FLAGS_DATA_PDU_IN_ORDER (1 << 2L) +#define ISCSI_SESSION_FLAGS_DATA_PDU_IN_ORDER (1 << 2) /// iSCSI session flags: Data sequence in order. -#define ISCSI_SESSION_FLAGS_DATA_SEQ_IN_ORDER (1 << 3L) +#define ISCSI_SESSION_FLAGS_DATA_SEQ_IN_ORDER (1 << 3) /// iSCSI session: Default maximum number of connections. -#define ISCSI_SESSION_DEFAULT_MAX_CONNECTIONS 2UL +#define ISCSI_SESSION_DEFAULT_MAX_CONNECTIONS 2U /// iSCSI session: Default maximum number of outstanding ready to transfers. -#define ISCSI_SESSION_DEFAULT_MAX_OUTSTANDING_R2T 1UL +#define ISCSI_SESSION_DEFAULT_MAX_OUTSTANDING_R2T 1U /// iSCSI session: Default time to wait in seconds. -#define ISCSI_SESSION_DEFAULT_TIME_TO_WAIT 2UL +#define ISCSI_SESSION_DEFAULT_TIME_TO_WAIT 2U /// iSCSI session: Default time to retain in seconds. -#define ISCSI_SESSION_DEFAULT_TIME_TO_RETAIN 20UL +#define ISCSI_SESSION_DEFAULT_TIME_TO_RETAIN 20U /// iSCSI session: First burst length in bytes. #define ISCSI_SESSION_DEFAULT_FIRST_BURST_LEN ISCSI_DEFAULT_RECV_DS_LEN @@ -7644,17 +8354,17 @@ typedef struct iscsi_auth_chap { #define ISCSI_SESSION_DEFAULT_MAX_BURST_LEN (ISCSI_DEFAULT_MAX_RECV_DS_LEN * ISCSI_DEFAULT_MAX_DATA_OUT_PER_CONNECTION) /// iSCSI session: Default error recovery level. -#define ISCSI_SESSION_DEFAULT_ERR_RECOVERY_LEVEL 0L +#define ISCSI_SESSION_DEFAULT_ERR_RECOVERY_LEVEL 0U /// iSCSI session type: Invalid. -#define ISCSI_SESSION_TYPE_INVALID 0L +#define ISCSI_SESSION_TYPE_INVALID 0 /// iSCSI session type: Normal. -#define ISCSI_SESSION_TYPE_NORMAL 1L +#define ISCSI_SESSION_TYPE_NORMAL 1 /// iSCSI session type: Discovery. -#define ISCSI_SESSION_TYPE_DISCOVERY 2L +#define ISCSI_SESSION_TYPE_DISCOVERY 2 /** @@ -7728,76 +8438,76 @@ typedef struct iscsi_session { /// iSCSI connection read packet data return code from iscsi_connection_pdu_read function: Packet parsed successfully. -#define ISCSI_CONNECT_PDU_READ_OK 0L +#define ISCSI_CONNECT_PDU_READ_OK 0 /// iSCSI connection read packet data return code from iscsi_connection_pdu_read function: Packet processed successfully. -#define ISCSI_CONNECT_PDU_READ_PROCESSED 1L +#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 -1L +#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 -2L +#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 -3L +#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 -4L +#define ISCSI_CONNECT_PDU_READ_ERR_LOGIN_PARAMETER_XCHG_NOT_ONCE -4 /// iSCSI connection flags: Stopped. -#define ISCSI_CONNECT_FLAGS_STOPPED (1 << 0L) +#define ISCSI_CONNECT_FLAGS_STOPPED (1 << 0) /// iSCSI connection flags: Rejected. -#define ISCSI_CONNECT_FLAGS_REJECTED (1 << 1L) +#define ISCSI_CONNECT_FLAGS_REJECTED (1 << 1) /// iSCSI connection flags: Logged out. -#define ISCSI_CONNECT_FLAGS_LOGGED_OUT (1 << 2L) +#define ISCSI_CONNECT_FLAGS_LOGGED_OUT (1 << 2) /// iSCSI connection flags: Full feature. -#define ISCSI_CONNECT_FLAGS_FULL_FEATURE (1 << 3L) +#define ISCSI_CONNECT_FLAGS_FULL_FEATURE (1 << 3) /// iSCSI connection flags: CHAP authentication is disabled. -#define ISCSI_CONNECT_FLAGS_CHAP_DISABLE (1 << 4L) +#define ISCSI_CONNECT_FLAGS_CHAP_DISABLE (1 << 4) /// iSCSI connection flags: CHAP authentication is required. -#define ISCSI_CONNECT_FLAGS_CHAP_REQUIRE (1 << 5L) +#define ISCSI_CONNECT_FLAGS_CHAP_REQUIRE (1 << 5) /// iSCSI connection flags: CHAP authentication is mutual. -#define ISCSI_CONNECT_FLAGS_CHAP_MUTUAL (1 << 6L) +#define ISCSI_CONNECT_FLAGS_CHAP_MUTUAL (1 << 6) /// iSCSI connection flags: Authenticated. -#define ISCSI_CONNECT_FLAGS_AUTH (1 << 7L) +#define ISCSI_CONNECT_FLAGS_AUTH (1 << 7) /// iSCSI connection flags: Oustanding NOP. -#define ISCSI_CONNECT_FLAGS_NOP_OUTSTANDING (1 << 8L) +#define ISCSI_CONNECT_FLAGS_NOP_OUTSTANDING (1 << 8) /// Ready to wait for PDU. -#define ISCSI_CONNECT_PDU_RECV_STATE_WAIT_PDU_READY 0L +#define ISCSI_CONNECT_PDU_RECV_STATE_WAIT_PDU_READY 0 /// Active connection waiting for any PDU header. -#define ISCSI_CONNECT_PDU_RECV_STATE_WAIT_PDU_HDR 1L +#define ISCSI_CONNECT_PDU_RECV_STATE_WAIT_PDU_HDR 1 /// Active connection waiting for data. -#define ISCSI_CONNECT_PDU_RECV_STATE_WAIT_PDU_DATA 2L +#define ISCSI_CONNECT_PDU_RECV_STATE_WAIT_PDU_DATA 2 /// Active connection does not wait for data. -#define ISCSI_CONNECT_PDU_RECV_STATE_ERR 3L +#define ISCSI_CONNECT_PDU_RECV_STATE_ERR 3 /// iSCSI connection state: Invalid. -#define ISCSI_CONNECT_STATE_INVALID 0L +#define ISCSI_CONNECT_STATE_INVALID 0 /// iSCSI connection state: Running. -#define ISCSI_CONNECT_STATE_RUNNING 1L +#define ISCSI_CONNECT_STATE_RUNNING 1 /// iSCSI connection state: Exiting. -#define ISCSI_CONNECT_STATE_EXITING 2L +#define ISCSI_CONNECT_STATE_EXITING 2 /// iSCSI connection state: Invalid. -#define ISCSI_CONNECT_STATE_EXITED 3L +#define ISCSI_CONNECT_STATE_EXITED 3 /** @@ -7953,7 +8663,7 @@ typedef void (*iscsi_connection_xfer_complete_callback)(uint8_t *user_data); // /// iSCSI PDU flags: Rejected. -#define ISCSI_PDU_FLAGS_REJECTED (1 << 0L) +#define ISCSI_PDU_FLAGS_REJECTED (1 << 0) /** @@ -8033,10 +8743,10 @@ typedef struct iscsi_pdu { /// iSCSI task flags: Ready To Transfer is active. -#define ISCSI_TASK_FLAGS_R2T_ACTIVE (1 << 0L) +#define ISCSI_TASK_FLAGS_R2T_ACTIVE (1 << 0) /// iSCSI task flags: Task is enqueued in SCSI layer. -#define ISCSI_TASK_FLAGS_QUEUED (1 << 1L) +#define ISCSI_TASK_FLAGS_QUEUED (1 << 1) /** diff --git a/src/server/server.c b/src/server/server.c index bfda12d..d6b849c 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -179,6 +179,7 @@ _Noreturn static void dnbd3_cleanup() // Destroy iSCSI global vector iscsi_destroy(); + pthread_rwlock_destroy( &iscsi_globvec_rwlock ); // Clean up images retries = 5; @@ -370,7 +371,7 @@ int main(int argc, char *argv[]) integrity_init(); net_init(); - if ( iscsi_create() < 0 ) + if ( (pthread_rwlock_init( &iscsi_globvec_rwlock, NULL ) != 0) || (iscsi_create() < 0) ) return EXIT_FAILURE; uplink_globalsInit(); |
