Merge git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
[linux/fpc-iii.git] / drivers / scsi / snic / snic_trc.c
blob28a40a7ade3896323cbb62c372a0b1d96a85428c
1 /*
2 * Copyright 2014 Cisco Systems, Inc. All rights reserved.
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
18 #include <linux/module.h>
19 #include <linux/mempool.h>
20 #include <linux/errno.h>
21 #include <linux/vmalloc.h>
23 #include "snic_io.h"
24 #include "snic.h"
27 * snic_get_trc_buf : Allocates a trace record and returns.
29 struct snic_trc_data *
30 snic_get_trc_buf(void)
32 struct snic_trc *trc = &snic_glob->trc;
33 struct snic_trc_data *td = NULL;
34 unsigned long flags;
36 spin_lock_irqsave(&trc->lock, flags);
37 td = &trc->buf[trc->wr_idx];
38 trc->wr_idx++;
40 if (trc->wr_idx == trc->max_idx)
41 trc->wr_idx = 0;
43 if (trc->wr_idx != trc->rd_idx) {
44 spin_unlock_irqrestore(&trc->lock, flags);
46 goto end;
49 trc->rd_idx++;
50 if (trc->rd_idx == trc->max_idx)
51 trc->rd_idx = 0;
53 td->ts = 0; /* Marker for checking the record, for complete data*/
54 spin_unlock_irqrestore(&trc->lock, flags);
56 end:
58 return td;
59 } /* end of snic_get_trc_buf */
62 * snic_fmt_trc_data : Formats trace data for printing.
64 static int
65 snic_fmt_trc_data(struct snic_trc_data *td, char *buf, int buf_sz)
67 int len = 0;
68 struct timespec tmspec;
70 jiffies_to_timespec(td->ts, &tmspec);
72 len += snprintf(buf, buf_sz,
73 "%lu.%10lu %-25s %3d %4x %16llx %16llx %16llx %16llx %16llx\n",
74 tmspec.tv_sec,
75 tmspec.tv_nsec,
76 td->fn,
77 td->hno,
78 td->tag,
79 td->data[0], td->data[1], td->data[2], td->data[3],
80 td->data[4]);
82 return len;
83 } /* end of snic_fmt_trc_data */
86 * snic_get_trc_data : Returns a formatted trace buffer.
88 int
89 snic_get_trc_data(char *buf, int buf_sz)
91 struct snic_trc_data *td = NULL;
92 struct snic_trc *trc = &snic_glob->trc;
93 unsigned long flags;
95 spin_lock_irqsave(&trc->lock, flags);
96 if (trc->rd_idx == trc->wr_idx) {
97 spin_unlock_irqrestore(&trc->lock, flags);
99 return -1;
101 td = &trc->buf[trc->rd_idx];
103 if (td->ts == 0) {
104 /* write in progress. */
105 spin_unlock_irqrestore(&trc->lock, flags);
107 return -1;
110 trc->rd_idx++;
111 if (trc->rd_idx == trc->max_idx)
112 trc->rd_idx = 0;
113 spin_unlock_irqrestore(&trc->lock, flags);
115 return snic_fmt_trc_data(td, buf, buf_sz);
116 } /* end of snic_get_trc_data */
119 * snic_trc_init() : Configures Trace Functionality for snic.
122 snic_trc_init(void)
124 struct snic_trc *trc = &snic_glob->trc;
125 void *tbuf = NULL;
126 int tbuf_sz = 0, ret;
128 tbuf_sz = (snic_trace_max_pages * PAGE_SIZE);
129 tbuf = vmalloc(tbuf_sz);
130 if (!tbuf) {
131 SNIC_ERR("Failed to Allocate Trace Buffer Size. %d\n", tbuf_sz);
132 SNIC_ERR("Trace Facility not enabled.\n");
133 ret = -ENOMEM;
135 return ret;
138 memset(tbuf, 0, tbuf_sz);
139 trc->buf = (struct snic_trc_data *) tbuf;
140 spin_lock_init(&trc->lock);
142 ret = snic_trc_debugfs_init();
143 if (ret) {
144 SNIC_ERR("Failed to create Debugfs Files.\n");
146 goto error;
149 trc->max_idx = (tbuf_sz / SNIC_TRC_ENTRY_SZ);
150 trc->rd_idx = trc->wr_idx = 0;
151 trc->enable = 1;
152 SNIC_INFO("Trace Facility Enabled.\n Trace Buffer SZ %lu Pages.\n",
153 tbuf_sz / PAGE_SIZE);
154 ret = 0;
156 return ret;
158 error:
159 snic_trc_free();
161 return ret;
162 } /* end of snic_trc_init */
165 * snic_trc_free : Releases the trace buffer and disables the tracing.
167 void
168 snic_trc_free(void)
170 struct snic_trc *trc = &snic_glob->trc;
172 trc->enable = 0;
173 snic_trc_debugfs_term();
175 if (trc->buf) {
176 vfree(trc->buf);
177 trc->buf = NULL;
180 SNIC_INFO("Trace Facility Disabled.\n");
181 } /* end of snic_trc_free */