1/* SPDX-License-Identifier: GPL-2.0-only */
2/* Copyright 2014 Cisco Systems, Inc.  All rights reserved. */
3
4#ifndef __SNIC_TRC_H
5#define __SNIC_TRC_H
6
7#ifdef CONFIG_SCSI_SNIC_DEBUG_FS
8
9extern ssize_t simple_read_from_buffer(void __user *to,
10					size_t count,
11					loff_t *ppos,
12					const void *from,
13					size_t available);
14
15extern unsigned int snic_trace_max_pages;
16
17/* Global Data structure for trace to manage trace functionality */
18struct snic_trc_data {
19	u64	ts;		/* Time Stamp */
20	char	*fn;		/* Ptr to Function Name */
21	u32	hno;		/* SCSI Host ID */
22	u32	tag;		/* Command Tag */
23	u64 data[5];
24} __attribute__((__packed__));
25
26#define SNIC_TRC_ENTRY_SZ  64	/* in Bytes */
27
28struct snic_trc {
29	spinlock_t lock;
30	struct snic_trc_data *buf;	/* Trace Buffer */
31	u32	max_idx;		/* Max Index into trace buffer */
32	u32	rd_idx;
33	u32	wr_idx;
34	bool	enable;			/* Control Variable for Tracing */
35};
36
37int snic_trc_init(void);
38void snic_trc_free(void);
39void snic_trc_debugfs_init(void);
40void snic_trc_debugfs_term(void);
41struct snic_trc_data *snic_get_trc_buf(void);
42int snic_get_trc_data(char *buf, int buf_sz);
43
44void snic_debugfs_init(void);
45void snic_debugfs_term(void);
46
47static inline void
48snic_trace(char *fn, u16 hno, u32 tag, u64 d1, u64 d2, u64 d3, u64 d4, u64 d5)
49{
50	struct snic_trc_data *tr_rec = snic_get_trc_buf();
51
52	if (!tr_rec)
53		return;
54
55	tr_rec->fn = (char *)fn;
56	tr_rec->hno = hno;
57	tr_rec->tag = tag;
58	tr_rec->data[0] = d1;
59	tr_rec->data[1] = d2;
60	tr_rec->data[2] = d3;
61	tr_rec->data[3] = d4;
62	tr_rec->data[4] = d5;
63	tr_rec->ts = jiffies; /* Update time stamp at last */
64}
65
66#define SNIC_TRC(_hno, _tag, d1, d2, d3, d4, d5)			\
67	do {								\
68		if (unlikely(snic_glob->trc.enable))			\
69			snic_trace((char *)__func__,			\
70				   (u16)(_hno),				\
71				   (u32)(_tag),				\
72				   (u64)(d1),				\
73				   (u64)(d2),				\
74				   (u64)(d3),				\
75				   (u64)(d4),				\
76				   (u64)(d5));				\
77	} while (0)
78#else
79
80#define SNIC_TRC(_hno, _tag, d1, d2, d3, d4, d5)	\
81	do {						\
82		if (unlikely(snic_log_level & 0x2))	\
83			SNIC_DBG("SnicTrace: %s %2u %2u %llx %llx %llx %llx %llx", \
84				 (char *)__func__,	\
85				 (u16)(_hno),		\
86				 (u32)(_tag),		\
87				 (u64)(d1),		\
88				 (u64)(d2),		\
89				 (u64)(d3),		\
90				 (u64)(d4),		\
91				 (u64)(d5));		\
92	} while (0)
93#endif /* end of CONFIG_SCSI_SNIC_DEBUG_FS */
94
95#define SNIC_TRC_CMD(sc)	\
96	((u64)sc->cmnd[0] << 56 | (u64)sc->cmnd[7] << 40 |	\
97	 (u64)sc->cmnd[8] << 32 | (u64)sc->cmnd[2] << 24 |	\
98	 (u64)sc->cmnd[3] << 16 | (u64)sc->cmnd[4] << 8 |	\
99	 (u64)sc->cmnd[5])
100
101#define SNIC_TRC_CMD_STATE_FLAGS(sc)	\
102	((u64) CMD_FLAGS(sc) << 32 | CMD_STATE(sc))
103
104#endif /* end of __SNIC_TRC_H */
105