NVME Identify Controller: decode TNVMCAP, UNVMCAP, RPMBS fields.

Also, undo a3000150a6 changes, per review comments.
This commit is contained in:
Constantine Gavrilov 2021-03-13 00:24:03 +02:00 committed by Wireshark GitLab Utility
parent d509e7e872
commit 272ff625f5
1 changed files with 195 additions and 175 deletions

View File

@ -156,6 +156,9 @@ static int hf_nvme_identify_ctrl_cctemp = -1;
static int hf_nvme_identify_ctrl_mtfa = -1;
static int hf_nvme_identify_ctrl_hmpre = -1;
static int hf_nvme_identify_ctrl_hmmin = -1;
static int hf_nvme_identify_ctrl_tnvmcap = -1;
static int hf_nvme_identify_ctrl_unvmcap = -1;
static int hf_nvme_identify_ctrl_rpmbs[6] = { NEG_LST_5 };
static int hf_nvme_identify_ctrl_kas = -1;
static int hf_nvme_identify_ctrl_sqes = -1;
static int hf_nvme_identify_ctrl_cqes = -1;
@ -752,85 +755,19 @@ static void dissect_nvme_identify_nslist_resp(tvbuff_t *cmd_tvb,
}
}
typedef enum {
TREE_ENT_REGULAR,
TREE_ENT_GROUP,
TREE_ENT_GROUP_MASK,
} tree_ent_type_t;
typedef struct tree_ent {
tree_ent_type_t type;
guint field;
guint array_len;
guint dec_type;
guint16 offset;
guint16 bytes;
union {
struct tree_ent *ent_array;
int *field_array;
void (*post_add)(proto_item *ti, guint val);
} u;
} tree_ent_t;
static void add_regular_entry(tvbuff_t *tvb, proto_tree *tree, tree_ent_t *entry)
{
if (entry->u.post_add) {
guint val;
proto_item *ti = proto_tree_add_item_ret_uint(tree, entry->field, tvb, entry->offset, entry->bytes, entry->dec_type, &val);
entry->u.post_add(ti, val);
} else {
proto_tree_add_item(tree, entry->field, tvb, entry->offset, entry->bytes, entry->dec_type);
}
}
static void add_group_mask_entry(tvbuff_t *tvb, proto_tree *tree, tree_ent_t *entry)
static void add_group_mask_entry(tvbuff_t *tvb, proto_tree *tree, guint offset, guint bytes, int *array, guint array_len)
{
proto_item *ti, *grp;
guint i;
ti = proto_tree_add_item(tree, entry->u.field_array[0], tvb, entry->offset, entry->bytes, entry->dec_type);
ti = proto_tree_add_item(tree, array[0], tvb, offset, bytes, ENC_LITTLE_ENDIAN);
grp = proto_item_add_subtree(ti, ett_data);
for (i = 1; i < entry->array_len; i++)
proto_tree_add_item(grp, entry->u.field_array[i], tvb, entry->offset, entry->bytes, entry->dec_type);
for (i = 1; i < array_len; i++)
proto_tree_add_item(grp, array[i], tvb, offset, bytes, ENC_LITTLE_ENDIAN);
}
static void add_tree_entries(tvbuff_t *tvb, proto_tree *tree, tree_ent_t *entries, guint entries_n);
static void add_group_entry(tvbuff_t *tvb, proto_tree *tree, tree_ent_t *entry)
{
proto_item *ti, *grp;
guint i;
ti = proto_tree_add_item(tree, entry->u.ent_array[0].field, tvb, entry->u.ent_array[0].offset, entry->u.ent_array[0].bytes, entry->u.ent_array[0].dec_type);
grp = proto_item_add_subtree(ti, ett_data);
for (i = 1; i < entry->array_len; i++)
add_tree_entries(tvb, grp, &entry->u.ent_array[i], 1);
}
static void add_tree_entries(tvbuff_t *tvb, proto_tree *tree, tree_ent_t *entries, guint entries_n)
{
guint i;
for (i = 0; i < entries_n; i++) {
switch(entries[i].type) {
case TREE_ENT_REGULAR:
add_regular_entry(tvb, tree, entries + i);
break;
case TREE_ENT_GROUP:
add_group_entry(tvb, tree, entries + i);
break;
case TREE_ENT_GROUP_MASK:
add_group_mask_entry(tvb, tree, entries + i);
break;
}
}
}
static void post_add_rab(proto_item *ti, guint val)
{
proto_item_append_text(ti, " (%lu command%s)", 1UL << val, val ? "s" : "");
}
static void post_add_mdts(proto_item *ti, guint val)
{
@ -860,123 +797,174 @@ static void post_add_cntrltype(proto_item *ti, guint val)
proto_item_append_text(ti, " (%s)", val_to_str(val, ctrl_type_tbl, "Reserved"));
}
static void post_add_crdt(proto_item *ti, guint val)
static void post_add_ms(proto_item *ti, guint val)
{
proto_item_append_text(ti, " (%u ms)", val * 100);
}
static void post_add_acl(proto_item *ti, guint val)
{
proto_item_append_text(ti, " (%u command%s)", val+1, val ? "s" : "");
}
static void post_add_aerl(proto_item *ti, guint val)
{
proto_item_append_text(ti, " (%u event%s)", val+1, val ? "s" : "");
}
static void post_add_elpe(proto_item *ti, guint val)
{
proto_item_append_text(ti, " (%u entr%s)", val+1, val ? "ies" : "y");
}
static void post_add_npss(proto_item *ti, guint val)
{
proto_item_append_text(ti, " (%u state%s)", val+1, val ? "s" : "");
}
static void post_add_hmpre(proto_item *ti, guint val)
{
proto_item_append_text(ti, " (%lu bytes)", ((unsigned long)(val)) * 4096);
}
#define ALEN(_x_) array_length(_x_)
static void post_add_cap(proto_item *ti, tvbuff_t *tvb, guint off)
{
guint64 lo = tvb_get_guint64(tvb, off, 0);
guint64 hi = tvb_get_guint64(tvb, off, 8);
if (hi) {
if (!(hi >> 10))
proto_item_append_text(ti, " (%lu KiB)", (hi << 54) | (lo >> 10));
else if (!(hi >> 20))
proto_item_append_text(ti, " (%lu MiB)", (hi << 44) | (lo >> 20));
else if (!(hi >> 30))
proto_item_append_text(ti, " (%lu GiB)", (hi << 34) | (lo >> 30));
else if (!(hi >> 40))
proto_item_append_text(ti, " (%lu TiB)", (hi << 24) | (lo >> 40));
else if (!(hi >> 50))
proto_item_append_text(ti, " (%lu PiB)", (hi << 14) | (lo >> 50));
else if (!(hi >> 60))
proto_item_append_text(ti, " (%lu EiB)", (hi << 4) | (lo >> 60));
else
proto_item_append_text(ti, " (%lu ZiB)", hi >> 6);
} else {
proto_item_append_text(ti, " (%lu bytes)", lo);
}
}
static void dissect_nvme_identify_ctrl_resp_ver(tvbuff_t *cmd_tvb, proto_tree *cmd_tree)
{
proto_item *ti;
proto_tree *grp;
ti = proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_ver, cmd_tvb, 80, 4, ENC_LITTLE_ENDIAN);
grp = proto_item_add_subtree(ti, ett_data);
proto_tree_add_item(grp, hf_nvme_identify_ctrl_ver_mjr, cmd_tvb, 82, 2, ENC_LITTLE_ENDIAN);
proto_tree_add_item(grp, hf_nvme_identify_ctrl_ver_min, cmd_tvb, 81, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item(grp, hf_nvme_identify_ctrl_ver_ter, cmd_tvb, 80, 1, ENC_LITTLE_ENDIAN);
}
static void dissect_nvme_identify_ctrl_resp_fguid(tvbuff_t *cmd_tvb, proto_tree *cmd_tree)
{
proto_item *ti;
proto_tree *grp;
ti = proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_fguid, cmd_tvb, 112, 16, ENC_NA);
grp = proto_item_add_subtree(ti, ett_data);
proto_tree_add_item(grp, hf_nvme_identify_ctrl_fguid_vse, cmd_tvb, 112, 8, ENC_LITTLE_ENDIAN);
proto_tree_add_item(grp, hf_nvme_identify_ctrl_fguid_oui, cmd_tvb, 120, 3, ENC_LITTLE_ENDIAN);
proto_tree_add_item(grp, hf_nvme_identify_ctrl_fguid_ei, cmd_tvb, 123, 5, ENC_LITTLE_ENDIAN);
}
#define ASPEC(_x_) _x_, array_length(_x_)
static void dissect_nvme_identify_ctrl_resp_mi(tvbuff_t *cmd_tvb, proto_tree *cmd_tree)
{
proto_item *ti;
proto_tree *grp;
ti = proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_mi, cmd_tvb, 240, 16, ENC_NA);
grp = proto_item_add_subtree(ti, ett_data);
proto_tree_add_item(grp, hf_nvme_identify_ctrl_mi_rsvd, cmd_tvb, 240, 13, ENC_NA);
add_group_mask_entry(cmd_tvb, grp, 253, 1, ASPEC(hf_nvme_identify_ctrl_mi_nvmsr));
add_group_mask_entry(cmd_tvb, grp, 254, 1, ASPEC(hf_nvme_identify_ctrl_mi_vwci));
add_group_mask_entry(cmd_tvb, grp, 255, 1, ASPEC(hf_nvme_identify_ctrl_mi_mec));
}
static void dissect_nvme_identify_ctrl_resp(tvbuff_t *cmd_tvb,
proto_tree *cmd_tree)
{
tree_ent_t ver_array[] = {
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_ver, .dec_type = ENC_LITTLE_ENDIAN, .offset = 80, .bytes = 4 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_ver_mjr, .dec_type = ENC_LITTLE_ENDIAN, .offset = 82, .bytes = 2 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_ver_min, .dec_type = ENC_LITTLE_ENDIAN, .offset = 81, .bytes = 1 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_ver_ter, .dec_type = ENC_LITTLE_ENDIAN, .offset = 80, .bytes = 1 },
};
tree_ent_t fguid_array[] = {
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_fguid, .dec_type = ENC_NA, .offset = 112, .bytes = 16 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_fguid_vse, .dec_type = ENC_LITTLE_ENDIAN, .offset = 112, .bytes = 8 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_fguid_oui, .dec_type = ENC_LITTLE_ENDIAN, .offset = 120, .bytes = 3 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_fguid_ei, .dec_type = ENC_LITTLE_ENDIAN, .offset = 123, .bytes = 5 },
};
tree_ent_t mi_array[] = {
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_mi, .dec_type = ENC_NA, .offset = 240, .bytes = 16 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_mi_rsvd, .dec_type = ENC_NA, .offset = 240, .bytes = 13 },
{ .type = TREE_ENT_GROUP_MASK, .array_len = ALEN(hf_nvme_identify_ctrl_mi_nvmsr), .dec_type = ENC_LITTLE_ENDIAN, .offset = 253, .bytes = 1,
.u.field_array = hf_nvme_identify_ctrl_mi_nvmsr},
{ .type = TREE_ENT_GROUP_MASK, .array_len = ALEN(hf_nvme_identify_ctrl_mi_vwci), .dec_type = ENC_LITTLE_ENDIAN, .offset = 254, .bytes = 1,
.u.field_array = hf_nvme_identify_ctrl_mi_vwci},
{ .type = TREE_ENT_GROUP_MASK, .array_len = ALEN(hf_nvme_identify_ctrl_mi_mec), .dec_type = ENC_LITTLE_ENDIAN, .offset = 255, .bytes = 1,
.u.field_array = hf_nvme_identify_ctrl_mi_mec},
};
tree_ent_t ent_array[] = {
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_vid, .dec_type = ENC_LITTLE_ENDIAN, .offset = 0, .bytes = 2 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_ssvid, .dec_type = ENC_LITTLE_ENDIAN, .offset = 2, .bytes = 2 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_sn, .dec_type = ENC_ASCII|ENC_NA, .offset = 4, .bytes = 20 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_mn, .dec_type = ENC_ASCII|ENC_NA, .offset = 24, .bytes = 40 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_fr, .dec_type = ENC_NA, .offset = 64, .bytes = 8 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_rab, .dec_type = ENC_LITTLE_ENDIAN, .offset = 72, .bytes = 1, .u.post_add = post_add_rab },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_ieee, .dec_type = ENC_LITTLE_ENDIAN, .offset = 73, .bytes = 3 },
{ .type = TREE_ENT_GROUP_MASK, .array_len = ALEN(hf_nvme_identify_ctrl_cmic), .dec_type = ENC_LITTLE_ENDIAN, .offset = 76, .bytes = 1,
.u.field_array = hf_nvme_identify_ctrl_cmic},
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_mdts, .dec_type = ENC_LITTLE_ENDIAN, .offset = 77, .bytes = 1, .u.post_add = post_add_mdts },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_cntlid, .dec_type = ENC_LITTLE_ENDIAN, .offset = 78, .bytes = 2 },
{ .type = TREE_ENT_GROUP, .array_len = ALEN(ver_array), .u.ent_array = ver_array },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_rtd3r, .dec_type = ENC_LITTLE_ENDIAN, .offset = 84, .bytes = 4, .u.post_add = post_add_rtd3 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_rtd3e, .dec_type = ENC_LITTLE_ENDIAN, .offset = 88, .bytes = 4, .u.post_add = post_add_rtd3 },
{ .type = TREE_ENT_GROUP_MASK, .array_len = ALEN(hf_nvme_identify_ctrl_oaes), .dec_type = ENC_LITTLE_ENDIAN, .offset = 92, .bytes = 4,
.u.field_array = hf_nvme_identify_ctrl_oaes},
{ .type = TREE_ENT_GROUP_MASK, .array_len = ALEN(hf_nvme_identify_ctrl_ctratt), .dec_type = ENC_LITTLE_ENDIAN, .offset = 96, .bytes = 4,
.u.field_array = hf_nvme_identify_ctrl_ctratt},
{ .type = TREE_ENT_GROUP_MASK, .array_len = ALEN(hf_nvme_identify_ctrl_rrls), .dec_type = ENC_LITTLE_ENDIAN, .offset = 100, .bytes = 2,
.u.field_array = hf_nvme_identify_ctrl_rrls},
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_rsvd0, .dec_type = ENC_NA, .offset = 102, .bytes = 9 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_cntrltype, .dec_type = ENC_LITTLE_ENDIAN, .offset = 111, .bytes = 1, .u.post_add = post_add_cntrltype },
{ .type = TREE_ENT_GROUP, .array_len = ALEN(fguid_array), .u.ent_array = fguid_array },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_crdt1, .dec_type = ENC_LITTLE_ENDIAN, .offset = 128, .bytes = 2, .u.post_add = post_add_crdt },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_crdt2, .dec_type = ENC_LITTLE_ENDIAN, .offset = 130, .bytes = 2, .u.post_add = post_add_crdt },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_crdt3, .dec_type = ENC_LITTLE_ENDIAN, .offset = 132, .bytes = 2, .u.post_add = post_add_crdt },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_rsvd1, .dec_type = ENC_NA, .offset = 134, .bytes = 106 },
{ .type = TREE_ENT_GROUP, .array_len = ALEN(mi_array), .u.ent_array = mi_array },
{ .type = TREE_ENT_GROUP_MASK, .array_len = ALEN(hf_nvme_identify_ctrl_oacs), .dec_type = ENC_LITTLE_ENDIAN, .offset = 256, .bytes = 2,
.u.field_array = hf_nvme_identify_ctrl_oacs},
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_acl, .dec_type = ENC_LITTLE_ENDIAN, .offset = 258, .bytes = 1, .u.post_add = post_add_acl },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_aerl, .dec_type = ENC_LITTLE_ENDIAN, .offset = 259, .bytes = 1, .u.post_add = post_add_aerl },
{ .type = TREE_ENT_GROUP_MASK, .array_len = ALEN(hf_nvme_identify_ctrl_frmw), .dec_type = ENC_LITTLE_ENDIAN, .offset = 260, .bytes = 1,
.u.field_array = hf_nvme_identify_ctrl_frmw},
{ .type = TREE_ENT_GROUP_MASK, .array_len = ALEN(hf_nvme_identify_ctrl_lpa), .dec_type = ENC_LITTLE_ENDIAN, .offset = 261, .bytes = 1,
.u.field_array = hf_nvme_identify_ctrl_lpa},
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_elpe, .dec_type = ENC_LITTLE_ENDIAN, .offset = 262, .bytes = 1, .u.post_add = post_add_elpe },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_npss, .dec_type = ENC_LITTLE_ENDIAN, .offset = 263, .bytes = 1, .u.post_add = post_add_npss },
{ .type = TREE_ENT_GROUP_MASK, .array_len = ALEN(hf_nvme_identify_ctrl_avscc), .dec_type = ENC_LITTLE_ENDIAN, .offset = 264, .bytes = 1,
.u.field_array = hf_nvme_identify_ctrl_avscc},
{ .type = TREE_ENT_GROUP_MASK, .array_len = ALEN(hf_nvme_identify_ctrl_apsta), .dec_type = ENC_LITTLE_ENDIAN, .offset = 265, .bytes = 1,
.u.field_array = hf_nvme_identify_ctrl_apsta},
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_wctemp, .dec_type = ENC_LITTLE_ENDIAN, .offset = 266, .bytes = 2, },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_cctemp, .dec_type = ENC_LITTLE_ENDIAN, .offset = 268, .bytes = 2, },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_mtfa, .dec_type = ENC_LITTLE_ENDIAN, .offset = 270, .bytes = 2, .u.post_add = post_add_crdt },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_hmpre, .dec_type = ENC_LITTLE_ENDIAN, .offset = 272, .bytes = 4, .u.post_add = post_add_hmpre },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_hmmin, .dec_type = ENC_LITTLE_ENDIAN, .offset = 276, .bytes = 4, .u.post_add = post_add_hmpre },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_kas, .dec_type = ENC_LITTLE_ENDIAN, .offset = 320, .bytes = 2 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_sqes, .dec_type = ENC_LITTLE_ENDIAN, .offset = 512, .bytes = 1 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_cqes, .dec_type = ENC_LITTLE_ENDIAN, .offset = 513, .bytes = 1 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_maxcmd, .dec_type = ENC_LITTLE_ENDIAN, .offset = 514, .bytes = 2 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_nn, .dec_type = ENC_LITTLE_ENDIAN, .offset = 516, .bytes = 4 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_oncs, .dec_type = ENC_LITTLE_ENDIAN, .offset = 520, .bytes = 2 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_sgls, .dec_type = ENC_LITTLE_ENDIAN, .offset = 536, .bytes = 4 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_subnqn, .dec_type = ENC_LITTLE_ENDIAN, .offset = 768, .bytes = 256 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_ioccsz, .dec_type = ENC_LITTLE_ENDIAN, .offset = 1792, .bytes = 4 },
{ .type = TREE_ENT_REGULAR, .field = hf_nvme_identify_ctrl_iorcsz, .dec_type = ENC_LITTLE_ENDIAN, .offset = 1796, .bytes = 4 },
proto_item *ti;
guint val;
};
add_tree_entries(cmd_tvb, cmd_tree, ent_array, ALEN(ent_array));
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_vid, cmd_tvb, 0, 2, ENC_LITTLE_ENDIAN);
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_ssvid, cmd_tvb, 2, 2, ENC_LITTLE_ENDIAN);
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_sn, cmd_tvb, 4, 20, ENC_ASCII|ENC_NA);
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_mn, cmd_tvb, 24, 40, ENC_ASCII|ENC_NA);
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_fr, cmd_tvb, 64, 8, ENC_NA);
ti = proto_tree_add_item_ret_uint(cmd_tree, hf_nvme_identify_ctrl_rab, cmd_tvb, 72, 1, ENC_LITTLE_ENDIAN, &val);
proto_item_append_text(ti, " (%lu command%s)", 1UL << val, val ? "s" : "");
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_ieee, cmd_tvb, 73, 3, ENC_LITTLE_ENDIAN);
add_group_mask_entry(cmd_tvb, cmd_tree, 76, 1, ASPEC(hf_nvme_identify_ctrl_cmic));
ti = proto_tree_add_item_ret_uint(cmd_tree, hf_nvme_identify_ctrl_mdts, cmd_tvb, 77, 1, ENC_LITTLE_ENDIAN, &val);
post_add_mdts(ti, val);
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_cntlid, cmd_tvb, 78, 2, ENC_LITTLE_ENDIAN);
dissect_nvme_identify_ctrl_resp_ver(cmd_tvb, cmd_tree);
ti = proto_tree_add_item_ret_uint(cmd_tree, hf_nvme_identify_ctrl_rtd3r, cmd_tvb, 84, 4, ENC_LITTLE_ENDIAN, &val);
post_add_rtd3(ti, val);
ti = proto_tree_add_item_ret_uint(cmd_tree, hf_nvme_identify_ctrl_rtd3e, cmd_tvb, 88, 4, ENC_LITTLE_ENDIAN, &val);
post_add_rtd3(ti, val);
add_group_mask_entry(cmd_tvb, cmd_tree, 92, 4, ASPEC(hf_nvme_identify_ctrl_oaes));
add_group_mask_entry(cmd_tvb, cmd_tree, 96, 4, ASPEC(hf_nvme_identify_ctrl_ctratt));
add_group_mask_entry(cmd_tvb, cmd_tree, 100, 2, ASPEC(hf_nvme_identify_ctrl_rrls));
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_rsvd0, cmd_tvb, 102, 9, ENC_NA);
ti = proto_tree_add_item_ret_uint(cmd_tree, hf_nvme_identify_ctrl_cntrltype, cmd_tvb, 111, 1, ENC_LITTLE_ENDIAN, &val);
post_add_cntrltype(ti, val);
dissect_nvme_identify_ctrl_resp_fguid(cmd_tvb, cmd_tree);
ti = proto_tree_add_item_ret_uint(cmd_tree, hf_nvme_identify_ctrl_crdt1, cmd_tvb, 128, 2, ENC_LITTLE_ENDIAN, &val);
post_add_ms(ti, val);
ti = proto_tree_add_item_ret_uint(cmd_tree, hf_nvme_identify_ctrl_crdt2, cmd_tvb, 130, 2, ENC_LITTLE_ENDIAN, &val);
post_add_ms(ti, val);
ti = proto_tree_add_item_ret_uint(cmd_tree, hf_nvme_identify_ctrl_crdt3, cmd_tvb, 132, 2, ENC_LITTLE_ENDIAN, &val);
post_add_ms(ti, val);
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_rsvd1, cmd_tvb, 134, 106, ENC_NA);
dissect_nvme_identify_ctrl_resp_mi(cmd_tvb, cmd_tree);
add_group_mask_entry(cmd_tvb, cmd_tree, 256, 2, ASPEC(hf_nvme_identify_ctrl_oacs));
ti = proto_tree_add_item_ret_uint(cmd_tree, hf_nvme_identify_ctrl_acl, cmd_tvb, 258, 1, ENC_LITTLE_ENDIAN, &val);
proto_item_append_text(ti, " (%u command%s)", val+1, val ? "s" : "");
ti = proto_tree_add_item_ret_uint(cmd_tree, hf_nvme_identify_ctrl_aerl, cmd_tvb, 259, 1, ENC_LITTLE_ENDIAN, &val);
proto_item_append_text(ti, " (%u event%s)", val+1, val ? "s" : "");
add_group_mask_entry(cmd_tvb, cmd_tree, 260, 1, ASPEC(hf_nvme_identify_ctrl_frmw));
add_group_mask_entry(cmd_tvb, cmd_tree, 261, 1, ASPEC(hf_nvme_identify_ctrl_lpa));
ti = proto_tree_add_item_ret_uint(cmd_tree, hf_nvme_identify_ctrl_elpe, cmd_tvb, 262, 1, ENC_LITTLE_ENDIAN, &val);
proto_item_append_text(ti, " (%u entr%s)", val+1, val ? "ies" : "y");
ti = proto_tree_add_item_ret_uint(cmd_tree, hf_nvme_identify_ctrl_npss, cmd_tvb, 263, 1, ENC_LITTLE_ENDIAN, &val);
proto_item_append_text(ti, " (%u state%s)", val+1, val ? "s" : "");
add_group_mask_entry(cmd_tvb, cmd_tree, 264, 1, ASPEC(hf_nvme_identify_ctrl_avscc));
add_group_mask_entry(cmd_tvb, cmd_tree, 265, 1, ASPEC(hf_nvme_identify_ctrl_apsta));
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_wctemp, cmd_tvb, 266, 2, ENC_LITTLE_ENDIAN);
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_cctemp, cmd_tvb, 268, 2, ENC_LITTLE_ENDIAN);
ti = proto_tree_add_item_ret_uint(cmd_tree, hf_nvme_identify_ctrl_mtfa, cmd_tvb, 270, 2, ENC_LITTLE_ENDIAN, &val);
post_add_ms(ti, val);
ti = proto_tree_add_item_ret_uint(cmd_tree, hf_nvme_identify_ctrl_hmpre, cmd_tvb, 272, 4, ENC_LITTLE_ENDIAN, &val);
post_add_hmpre(ti, val);
ti = proto_tree_add_item_ret_uint(cmd_tree, hf_nvme_identify_ctrl_hmmin, cmd_tvb, 276, 4, ENC_LITTLE_ENDIAN, &val);
post_add_hmpre(ti, val);
ti = proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_tnvmcap, cmd_tvb, 280, 16, ENC_NA);
post_add_cap(ti, cmd_tvb, 280);
ti = proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_unvmcap, cmd_tvb, 296, 16, ENC_NA);
post_add_cap(ti, cmd_tvb, 296);
add_group_mask_entry(cmd_tvb, cmd_tree, 312, 4, ASPEC(hf_nvme_identify_ctrl_rpmbs));
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_kas, cmd_tvb, 320, 2, ENC_LITTLE_ENDIAN);
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_sqes, cmd_tvb, 512, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_cqes, cmd_tvb, 513, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_maxcmd, cmd_tvb, 514, 2, ENC_LITTLE_ENDIAN);
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_nn, cmd_tvb, 516, 4, ENC_LITTLE_ENDIAN);
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_oncs, cmd_tvb, 520, 2, ENC_LITTLE_ENDIAN);
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_sgls, cmd_tvb, 536, 4, ENC_LITTLE_ENDIAN);
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_subnqn, cmd_tvb, 768, 256, ENC_ASCII|ENC_NA);
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_ioccsz, cmd_tvb, 1792, 4, ENC_LITTLE_ENDIAN);
proto_tree_add_item(cmd_tree, hf_nvme_identify_ctrl_iorcsz, cmd_tvb, 1796, 4, ENC_LITTLE_ENDIAN);
}
static void dissect_nvme_identify_resp(tvbuff_t *cmd_tvb, proto_tree *cmd_tree,
@ -1836,7 +1824,7 @@ proto_register_nvme(void)
FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
},
{ &hf_nvme_identify_ctrl_frmw[1],
{ "First Firmware Slot Read-ONly", "nvme.cmd.identify.ctrl.frmw.fro",
{ "First Firmware Slot Read-Only", "nvme.cmd.identify.ctrl.frmw.fro",
FT_UINT8, BASE_HEX, NULL, 0x1, NULL, HFILL}
},
{ &hf_nvme_identify_ctrl_frmw[2],
@ -1931,6 +1919,38 @@ proto_register_nvme(void)
{ "Host Memory Buffer Minimum Size (HMMIN)", "nvme.cmd.identify.ctrl.hmmin",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
},
{ &hf_nvme_identify_ctrl_tnvmcap,
{ "Total NVM Capacity (TNVMCAP)", "nvme.cmd.identify.ctrl.tnvmcap",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}
},
{ &hf_nvme_identify_ctrl_unvmcap,
{ "Unallocated NVM Capacity (UNVMCAP)", "nvme.cmd.identify.ctrl.unvmcap",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}
},
{ &hf_nvme_identify_ctrl_rpmbs[0],
{ "Replay Protected Memory Block Support (RPMBS)", "nvme.cmd.identify.ctrl.rpmbs",
FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}
},
{ &hf_nvme_identify_ctrl_rpmbs[1],
{ "Number of RPMB Units", "nvme.cmd.identify.ctrl.rpmbs.nu",
FT_UINT32, BASE_HEX, NULL, 0x7, NULL, HFILL}
},
{ &hf_nvme_identify_ctrl_rpmbs[2],
{ "Authentication Method", "nvme.cmd.identify.ctrl.rpmbs.au",
FT_UINT32, BASE_HEX, NULL, 0x38, NULL, HFILL}
},
{ &hf_nvme_identify_ctrl_rpmbs[3],
{ "Resered", "nvme.cmd.identify.ctrl.rpmbs.rsvd",
FT_UINT32, BASE_HEX, NULL, 0xffc0, NULL, HFILL}
},
{ &hf_nvme_identify_ctrl_rpmbs[4],
{ "Total RPMB Unit Size (128 KiB blocks, zero based)", "nvme.cmd.identify.ctrl.rpmbs.ts",
FT_UINT32, BASE_HEX, NULL, 0xff0000, NULL, HFILL}
},
{ &hf_nvme_identify_ctrl_rpmbs[5],
{ "Access Size (512-byte blocks, zero based)", "nvme.cmd.identify.ctrl.rpmbs.as",
FT_UINT32, BASE_HEX, NULL, 0xff000000, NULL, HFILL}
},
{ &hf_nvme_identify_ctrl_kas,
{ "Keep Alive Support (KAS)", "nvme.cmd.identify.ctrl.kas",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}