forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
3.8 KiB
170 lines
3.8 KiB
/* |
|
* Copyright 2014 Cisco Systems, Inc. All rights reserved. |
|
* |
|
* This program is free software; you may redistribute it and/or modify |
|
* it under the terms of the GNU General Public License as published by |
|
* the Free Software Foundation; version 2 of the License. |
|
* |
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|
* SOFTWARE. |
|
*/ |
|
|
|
#include <linux/module.h> |
|
#include <linux/mempool.h> |
|
#include <linux/errno.h> |
|
#include <linux/vmalloc.h> |
|
|
|
#include "snic_io.h" |
|
#include "snic.h" |
|
|
|
/* |
|
* snic_get_trc_buf : Allocates a trace record and returns. |
|
*/ |
|
struct snic_trc_data * |
|
snic_get_trc_buf(void) |
|
{ |
|
struct snic_trc *trc = &snic_glob->trc; |
|
struct snic_trc_data *td = NULL; |
|
unsigned long flags; |
|
|
|
spin_lock_irqsave(&trc->lock, flags); |
|
td = &trc->buf[trc->wr_idx]; |
|
trc->wr_idx++; |
|
|
|
if (trc->wr_idx == trc->max_idx) |
|
trc->wr_idx = 0; |
|
|
|
if (trc->wr_idx != trc->rd_idx) { |
|
spin_unlock_irqrestore(&trc->lock, flags); |
|
|
|
goto end; |
|
} |
|
|
|
trc->rd_idx++; |
|
if (trc->rd_idx == trc->max_idx) |
|
trc->rd_idx = 0; |
|
|
|
td->ts = 0; /* Marker for checking the record, for complete data*/ |
|
spin_unlock_irqrestore(&trc->lock, flags); |
|
|
|
end: |
|
|
|
return td; |
|
} /* end of snic_get_trc_buf */ |
|
|
|
/* |
|
* snic_fmt_trc_data : Formats trace data for printing. |
|
*/ |
|
static int |
|
snic_fmt_trc_data(struct snic_trc_data *td, char *buf, int buf_sz) |
|
{ |
|
int len = 0; |
|
struct timespec64 tmspec; |
|
|
|
jiffies_to_timespec64(td->ts, &tmspec); |
|
|
|
len += snprintf(buf, buf_sz, |
|
"%llu.%09lu %-25s %3d %4x %16llx %16llx %16llx %16llx %16llx\n", |
|
tmspec.tv_sec, |
|
tmspec.tv_nsec, |
|
td->fn, |
|
td->hno, |
|
td->tag, |
|
td->data[0], td->data[1], td->data[2], td->data[3], |
|
td->data[4]); |
|
|
|
return len; |
|
} /* end of snic_fmt_trc_data */ |
|
|
|
/* |
|
* snic_get_trc_data : Returns a formatted trace buffer. |
|
*/ |
|
int |
|
snic_get_trc_data(char *buf, int buf_sz) |
|
{ |
|
struct snic_trc_data *td = NULL; |
|
struct snic_trc *trc = &snic_glob->trc; |
|
unsigned long flags; |
|
|
|
spin_lock_irqsave(&trc->lock, flags); |
|
if (trc->rd_idx == trc->wr_idx) { |
|
spin_unlock_irqrestore(&trc->lock, flags); |
|
|
|
return -1; |
|
} |
|
td = &trc->buf[trc->rd_idx]; |
|
|
|
if (td->ts == 0) { |
|
/* write in progress. */ |
|
spin_unlock_irqrestore(&trc->lock, flags); |
|
|
|
return -1; |
|
} |
|
|
|
trc->rd_idx++; |
|
if (trc->rd_idx == trc->max_idx) |
|
trc->rd_idx = 0; |
|
spin_unlock_irqrestore(&trc->lock, flags); |
|
|
|
return snic_fmt_trc_data(td, buf, buf_sz); |
|
} /* end of snic_get_trc_data */ |
|
|
|
/* |
|
* snic_trc_init() : Configures Trace Functionality for snic. |
|
*/ |
|
int |
|
snic_trc_init(void) |
|
{ |
|
struct snic_trc *trc = &snic_glob->trc; |
|
void *tbuf = NULL; |
|
int tbuf_sz = 0, ret; |
|
|
|
tbuf_sz = (snic_trace_max_pages * PAGE_SIZE); |
|
tbuf = vzalloc(tbuf_sz); |
|
if (!tbuf) { |
|
SNIC_ERR("Failed to Allocate Trace Buffer Size. %d\n", tbuf_sz); |
|
SNIC_ERR("Trace Facility not enabled.\n"); |
|
ret = -ENOMEM; |
|
|
|
return ret; |
|
} |
|
|
|
trc->buf = (struct snic_trc_data *) tbuf; |
|
spin_lock_init(&trc->lock); |
|
|
|
snic_trc_debugfs_init(); |
|
|
|
trc->max_idx = (tbuf_sz / SNIC_TRC_ENTRY_SZ); |
|
trc->rd_idx = trc->wr_idx = 0; |
|
trc->enable = true; |
|
SNIC_INFO("Trace Facility Enabled.\n Trace Buffer SZ %lu Pages.\n", |
|
tbuf_sz / PAGE_SIZE); |
|
ret = 0; |
|
|
|
return ret; |
|
} /* end of snic_trc_init */ |
|
|
|
/* |
|
* snic_trc_free : Releases the trace buffer and disables the tracing. |
|
*/ |
|
void |
|
snic_trc_free(void) |
|
{ |
|
struct snic_trc *trc = &snic_glob->trc; |
|
|
|
trc->enable = false; |
|
snic_trc_debugfs_term(); |
|
|
|
if (trc->buf) { |
|
vfree(trc->buf); |
|
trc->buf = NULL; |
|
} |
|
|
|
SNIC_INFO("Trace Facility Disabled.\n"); |
|
} /* end of snic_trc_free */
|
|
|