162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * NVM Express target device driver tracepoints
462306a36Sopenharmony_ci * Copyright (c) 2018 Johannes Thumshirn, SUSE Linux GmbH
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <asm/unaligned.h>
862306a36Sopenharmony_ci#include "trace.h"
962306a36Sopenharmony_ci
1062306a36Sopenharmony_cistatic const char *nvmet_trace_admin_identify(struct trace_seq *p, u8 *cdw10)
1162306a36Sopenharmony_ci{
1262306a36Sopenharmony_ci	const char *ret = trace_seq_buffer_ptr(p);
1362306a36Sopenharmony_ci	u8 cns = cdw10[0];
1462306a36Sopenharmony_ci	u16 ctrlid = get_unaligned_le16(cdw10 + 2);
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci	trace_seq_printf(p, "cns=%u, ctrlid=%u", cns, ctrlid);
1762306a36Sopenharmony_ci	trace_seq_putc(p, 0);
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci	return ret;
2062306a36Sopenharmony_ci}
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cistatic const char *nvmet_trace_admin_get_features(struct trace_seq *p,
2362306a36Sopenharmony_ci						 u8 *cdw10)
2462306a36Sopenharmony_ci{
2562306a36Sopenharmony_ci	const char *ret = trace_seq_buffer_ptr(p);
2662306a36Sopenharmony_ci	u8 fid = cdw10[0];
2762306a36Sopenharmony_ci	u8 sel = cdw10[1] & 0x7;
2862306a36Sopenharmony_ci	u32 cdw11 = get_unaligned_le32(cdw10 + 4);
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci	trace_seq_printf(p, "fid=0x%x, sel=0x%x, cdw11=0x%x", fid, sel, cdw11);
3162306a36Sopenharmony_ci	trace_seq_putc(p, 0);
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	return ret;
3462306a36Sopenharmony_ci}
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_cistatic const char *nvmet_trace_get_lba_status(struct trace_seq *p,
3762306a36Sopenharmony_ci					     u8 *cdw10)
3862306a36Sopenharmony_ci{
3962306a36Sopenharmony_ci	const char *ret = trace_seq_buffer_ptr(p);
4062306a36Sopenharmony_ci	u64 slba = get_unaligned_le64(cdw10);
4162306a36Sopenharmony_ci	u32 mndw = get_unaligned_le32(cdw10 + 8);
4262306a36Sopenharmony_ci	u16 rl = get_unaligned_le16(cdw10 + 12);
4362306a36Sopenharmony_ci	u8 atype = cdw10[15];
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci	trace_seq_printf(p, "slba=0x%llx, mndw=0x%x, rl=0x%x, atype=%u",
4662306a36Sopenharmony_ci			slba, mndw, rl, atype);
4762306a36Sopenharmony_ci	trace_seq_putc(p, 0);
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci	return ret;
5062306a36Sopenharmony_ci}
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_cistatic const char *nvmet_trace_admin_set_features(struct trace_seq *p,
5362306a36Sopenharmony_ci						 u8 *cdw10)
5462306a36Sopenharmony_ci{
5562306a36Sopenharmony_ci	const char *ret = trace_seq_buffer_ptr(p);
5662306a36Sopenharmony_ci	u8 fid = cdw10[0];
5762306a36Sopenharmony_ci	u8 sv = cdw10[3] & 0x8;
5862306a36Sopenharmony_ci	u32 cdw11 = get_unaligned_le32(cdw10 + 4);
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	trace_seq_printf(p, "fid=0x%x, sv=0x%x, cdw11=0x%x", fid, sv, cdw11);
6162306a36Sopenharmony_ci	trace_seq_putc(p, 0);
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci	return ret;
6462306a36Sopenharmony_ci}
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_cistatic const char *nvmet_trace_read_write(struct trace_seq *p, u8 *cdw10)
6762306a36Sopenharmony_ci{
6862306a36Sopenharmony_ci	const char *ret = trace_seq_buffer_ptr(p);
6962306a36Sopenharmony_ci	u64 slba = get_unaligned_le64(cdw10);
7062306a36Sopenharmony_ci	u16 length = get_unaligned_le16(cdw10 + 8);
7162306a36Sopenharmony_ci	u16 control = get_unaligned_le16(cdw10 + 10);
7262306a36Sopenharmony_ci	u32 dsmgmt = get_unaligned_le32(cdw10 + 12);
7362306a36Sopenharmony_ci	u32 reftag = get_unaligned_le32(cdw10 +  16);
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	trace_seq_printf(p,
7662306a36Sopenharmony_ci			 "slba=%llu, len=%u, ctrl=0x%x, dsmgmt=%u, reftag=%u",
7762306a36Sopenharmony_ci			 slba, length, control, dsmgmt, reftag);
7862306a36Sopenharmony_ci	trace_seq_putc(p, 0);
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci	return ret;
8162306a36Sopenharmony_ci}
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_cistatic const char *nvmet_trace_dsm(struct trace_seq *p, u8 *cdw10)
8462306a36Sopenharmony_ci{
8562306a36Sopenharmony_ci	const char *ret = trace_seq_buffer_ptr(p);
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	trace_seq_printf(p, "nr=%u, attributes=%u",
8862306a36Sopenharmony_ci			 get_unaligned_le32(cdw10),
8962306a36Sopenharmony_ci			 get_unaligned_le32(cdw10 + 4));
9062306a36Sopenharmony_ci	trace_seq_putc(p, 0);
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci	return ret;
9362306a36Sopenharmony_ci}
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_cistatic const char *nvmet_trace_common(struct trace_seq *p, u8 *cdw10)
9662306a36Sopenharmony_ci{
9762306a36Sopenharmony_ci	const char *ret = trace_seq_buffer_ptr(p);
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	trace_seq_printf(p, "cdw10=%*ph", 24, cdw10);
10062306a36Sopenharmony_ci	trace_seq_putc(p, 0);
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci	return ret;
10362306a36Sopenharmony_ci}
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ciconst char *nvmet_trace_parse_admin_cmd(struct trace_seq *p,
10662306a36Sopenharmony_ci		u8 opcode, u8 *cdw10)
10762306a36Sopenharmony_ci{
10862306a36Sopenharmony_ci	switch (opcode) {
10962306a36Sopenharmony_ci	case nvme_admin_identify:
11062306a36Sopenharmony_ci		return nvmet_trace_admin_identify(p, cdw10);
11162306a36Sopenharmony_ci	case nvme_admin_set_features:
11262306a36Sopenharmony_ci		return nvmet_trace_admin_set_features(p, cdw10);
11362306a36Sopenharmony_ci	case nvme_admin_get_features:
11462306a36Sopenharmony_ci		return nvmet_trace_admin_get_features(p, cdw10);
11562306a36Sopenharmony_ci	case nvme_admin_get_lba_status:
11662306a36Sopenharmony_ci		return nvmet_trace_get_lba_status(p, cdw10);
11762306a36Sopenharmony_ci	default:
11862306a36Sopenharmony_ci		return nvmet_trace_common(p, cdw10);
11962306a36Sopenharmony_ci	}
12062306a36Sopenharmony_ci}
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ciconst char *nvmet_trace_parse_nvm_cmd(struct trace_seq *p,
12362306a36Sopenharmony_ci		u8 opcode, u8 *cdw10)
12462306a36Sopenharmony_ci{
12562306a36Sopenharmony_ci	switch (opcode) {
12662306a36Sopenharmony_ci	case nvme_cmd_read:
12762306a36Sopenharmony_ci	case nvme_cmd_write:
12862306a36Sopenharmony_ci	case nvme_cmd_write_zeroes:
12962306a36Sopenharmony_ci		return nvmet_trace_read_write(p, cdw10);
13062306a36Sopenharmony_ci	case nvme_cmd_dsm:
13162306a36Sopenharmony_ci		return nvmet_trace_dsm(p, cdw10);
13262306a36Sopenharmony_ci	default:
13362306a36Sopenharmony_ci		return nvmet_trace_common(p, cdw10);
13462306a36Sopenharmony_ci	}
13562306a36Sopenharmony_ci}
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_cistatic const char *nvmet_trace_fabrics_property_set(struct trace_seq *p,
13862306a36Sopenharmony_ci		u8 *spc)
13962306a36Sopenharmony_ci{
14062306a36Sopenharmony_ci	const char *ret = trace_seq_buffer_ptr(p);
14162306a36Sopenharmony_ci	u8 attrib = spc[0];
14262306a36Sopenharmony_ci	u32 ofst = get_unaligned_le32(spc + 4);
14362306a36Sopenharmony_ci	u64 value = get_unaligned_le64(spc + 8);
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci	trace_seq_printf(p, "attrib=%u, ofst=0x%x, value=0x%llx",
14662306a36Sopenharmony_ci			 attrib, ofst, value);
14762306a36Sopenharmony_ci	trace_seq_putc(p, 0);
14862306a36Sopenharmony_ci	return ret;
14962306a36Sopenharmony_ci}
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_cistatic const char *nvmet_trace_fabrics_connect(struct trace_seq *p,
15262306a36Sopenharmony_ci		u8 *spc)
15362306a36Sopenharmony_ci{
15462306a36Sopenharmony_ci	const char *ret = trace_seq_buffer_ptr(p);
15562306a36Sopenharmony_ci	u16 recfmt = get_unaligned_le16(spc);
15662306a36Sopenharmony_ci	u16 qid = get_unaligned_le16(spc + 2);
15762306a36Sopenharmony_ci	u16 sqsize = get_unaligned_le16(spc + 4);
15862306a36Sopenharmony_ci	u8 cattr = spc[6];
15962306a36Sopenharmony_ci	u32 kato = get_unaligned_le32(spc + 8);
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci	trace_seq_printf(p, "recfmt=%u, qid=%u, sqsize=%u, cattr=%u, kato=%u",
16262306a36Sopenharmony_ci			 recfmt, qid, sqsize, cattr, kato);
16362306a36Sopenharmony_ci	trace_seq_putc(p, 0);
16462306a36Sopenharmony_ci	return ret;
16562306a36Sopenharmony_ci}
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_cistatic const char *nvmet_trace_fabrics_property_get(struct trace_seq *p,
16862306a36Sopenharmony_ci		u8 *spc)
16962306a36Sopenharmony_ci{
17062306a36Sopenharmony_ci	const char *ret = trace_seq_buffer_ptr(p);
17162306a36Sopenharmony_ci	u8 attrib = spc[0];
17262306a36Sopenharmony_ci	u32 ofst = get_unaligned_le32(spc + 4);
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci	trace_seq_printf(p, "attrib=%u, ofst=0x%x", attrib, ofst);
17562306a36Sopenharmony_ci	trace_seq_putc(p, 0);
17662306a36Sopenharmony_ci	return ret;
17762306a36Sopenharmony_ci}
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_cistatic const char *nvmet_trace_fabrics_common(struct trace_seq *p, u8 *spc)
18062306a36Sopenharmony_ci{
18162306a36Sopenharmony_ci	const char *ret = trace_seq_buffer_ptr(p);
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci	trace_seq_printf(p, "specific=%*ph", 24, spc);
18462306a36Sopenharmony_ci	trace_seq_putc(p, 0);
18562306a36Sopenharmony_ci	return ret;
18662306a36Sopenharmony_ci}
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ciconst char *nvmet_trace_parse_fabrics_cmd(struct trace_seq *p,
18962306a36Sopenharmony_ci		u8 fctype, u8 *spc)
19062306a36Sopenharmony_ci{
19162306a36Sopenharmony_ci	switch (fctype) {
19262306a36Sopenharmony_ci	case nvme_fabrics_type_property_set:
19362306a36Sopenharmony_ci		return nvmet_trace_fabrics_property_set(p, spc);
19462306a36Sopenharmony_ci	case nvme_fabrics_type_connect:
19562306a36Sopenharmony_ci		return nvmet_trace_fabrics_connect(p, spc);
19662306a36Sopenharmony_ci	case nvme_fabrics_type_property_get:
19762306a36Sopenharmony_ci		return nvmet_trace_fabrics_property_get(p, spc);
19862306a36Sopenharmony_ci	default:
19962306a36Sopenharmony_ci		return nvmet_trace_fabrics_common(p, spc);
20062306a36Sopenharmony_ci	}
20162306a36Sopenharmony_ci}
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ciconst char *nvmet_trace_disk_name(struct trace_seq *p, char *name)
20462306a36Sopenharmony_ci{
20562306a36Sopenharmony_ci	const char *ret = trace_seq_buffer_ptr(p);
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci	if (*name)
20862306a36Sopenharmony_ci		trace_seq_printf(p, "disk=%s, ", name);
20962306a36Sopenharmony_ci	trace_seq_putc(p, 0);
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci	return ret;
21262306a36Sopenharmony_ci}
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ciconst char *nvmet_trace_ctrl_name(struct trace_seq *p, struct nvmet_ctrl *ctrl)
21562306a36Sopenharmony_ci{
21662306a36Sopenharmony_ci	const char *ret = trace_seq_buffer_ptr(p);
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	/*
21962306a36Sopenharmony_ci	 * XXX: We don't know the controller instance before executing the
22062306a36Sopenharmony_ci	 * connect command itself because the connect command for the admin
22162306a36Sopenharmony_ci	 * queue will not provide the cntlid which will be allocated in this
22262306a36Sopenharmony_ci	 * command.  In case of io queues, the controller instance will be
22362306a36Sopenharmony_ci	 * mapped by the extra data of the connect command.
22462306a36Sopenharmony_ci	 * If we can know the extra data of the connect command in this stage,
22562306a36Sopenharmony_ci	 * we can update this print statement later.
22662306a36Sopenharmony_ci	 */
22762306a36Sopenharmony_ci	if (ctrl)
22862306a36Sopenharmony_ci		trace_seq_printf(p, "%d", ctrl->cntlid);
22962306a36Sopenharmony_ci	else
23062306a36Sopenharmony_ci		trace_seq_printf(p, "_");
23162306a36Sopenharmony_ci	trace_seq_putc(p, 0);
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci	return ret;
23462306a36Sopenharmony_ci}
23562306a36Sopenharmony_ci
236