root/drivers/scsi/snic/snic_trc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. snic_get_trc_buf
  2. snic_fmt_trc_data
  3. snic_get_trc_data
  4. snic_trc_init
  5. snic_trc_free

   1 /*
   2  * Copyright 2014 Cisco Systems, Inc.  All rights reserved.
   3  *
   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.
   7  *
   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.
  16  */
  17 
  18 #include <linux/module.h>
  19 #include <linux/mempool.h>
  20 #include <linux/errno.h>
  21 #include <linux/vmalloc.h>
  22 
  23 #include "snic_io.h"
  24 #include "snic.h"
  25 
  26 /*
  27  * snic_get_trc_buf : Allocates a trace record and returns.
  28  */
  29 struct snic_trc_data *
  30 snic_get_trc_buf(void)
  31 {
  32         struct snic_trc *trc = &snic_glob->trc;
  33         struct snic_trc_data *td = NULL;
  34         unsigned long flags;
  35 
  36         spin_lock_irqsave(&trc->lock, flags);
  37         td = &trc->buf[trc->wr_idx];
  38         trc->wr_idx++;
  39 
  40         if (trc->wr_idx == trc->max_idx)
  41                 trc->wr_idx = 0;
  42 
  43         if (trc->wr_idx != trc->rd_idx) {
  44                 spin_unlock_irqrestore(&trc->lock, flags);
  45 
  46                 goto end;
  47         }
  48 
  49         trc->rd_idx++;
  50         if (trc->rd_idx == trc->max_idx)
  51                 trc->rd_idx = 0;
  52 
  53         td->ts = 0;     /* Marker for checking the record, for complete data*/
  54         spin_unlock_irqrestore(&trc->lock, flags);
  55 
  56 end:
  57 
  58         return td;
  59 } /* end of snic_get_trc_buf */
  60 
  61 /*
  62  * snic_fmt_trc_data : Formats trace data for printing.
  63  */
  64 static int
  65 snic_fmt_trc_data(struct snic_trc_data *td, char *buf, int buf_sz)
  66 {
  67         int len = 0;
  68         struct timespec64 tmspec;
  69 
  70         jiffies_to_timespec64(td->ts, &tmspec);
  71 
  72         len += snprintf(buf, buf_sz,
  73                         "%llu.%09lu %-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]);
  81 
  82         return len;
  83 } /* end of snic_fmt_trc_data */
  84 
  85 /*
  86  * snic_get_trc_data : Returns a formatted trace buffer.
  87  */
  88 int
  89 snic_get_trc_data(char *buf, int buf_sz)
  90 {
  91         struct snic_trc_data *td = NULL;
  92         struct snic_trc *trc = &snic_glob->trc;
  93         unsigned long flags;
  94 
  95         spin_lock_irqsave(&trc->lock, flags);
  96         if (trc->rd_idx == trc->wr_idx) {
  97                 spin_unlock_irqrestore(&trc->lock, flags);
  98 
  99                 return -1;
 100         }
 101         td = &trc->buf[trc->rd_idx];
 102 
 103         if (td->ts == 0) {
 104                 /* write in progress. */
 105                 spin_unlock_irqrestore(&trc->lock, flags);
 106 
 107                 return -1;
 108         }
 109 
 110         trc->rd_idx++;
 111         if (trc->rd_idx == trc->max_idx)
 112                 trc->rd_idx = 0;
 113         spin_unlock_irqrestore(&trc->lock, flags);
 114 
 115         return snic_fmt_trc_data(td, buf, buf_sz);
 116 } /* end of snic_get_trc_data */
 117 
 118 /*
 119  * snic_trc_init() : Configures Trace Functionality for snic.
 120  */
 121 int
 122 snic_trc_init(void)
 123 {
 124         struct snic_trc *trc = &snic_glob->trc;
 125         void *tbuf = NULL;
 126         int tbuf_sz = 0, ret;
 127 
 128         tbuf_sz = (snic_trace_max_pages * PAGE_SIZE);
 129         tbuf = vzalloc(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;
 134 
 135                 return ret;
 136         }
 137 
 138         trc->buf = (struct snic_trc_data *) tbuf;
 139         spin_lock_init(&trc->lock);
 140 
 141         snic_trc_debugfs_init();
 142 
 143         trc->max_idx = (tbuf_sz / SNIC_TRC_ENTRY_SZ);
 144         trc->rd_idx = trc->wr_idx = 0;
 145         trc->enable = true;
 146         SNIC_INFO("Trace Facility Enabled.\n Trace Buffer SZ %lu Pages.\n",
 147                   tbuf_sz / PAGE_SIZE);
 148         ret = 0;
 149 
 150         return ret;
 151 } /* end of snic_trc_init */
 152 
 153 /*
 154  * snic_trc_free : Releases the trace buffer and disables the tracing.
 155  */
 156 void
 157 snic_trc_free(void)
 158 {
 159         struct snic_trc *trc = &snic_glob->trc;
 160 
 161         trc->enable = false;
 162         snic_trc_debugfs_term();
 163 
 164         if (trc->buf) {
 165                 vfree(trc->buf);
 166                 trc->buf = NULL;
 167         }
 168 
 169         SNIC_INFO("Trace Facility Disabled.\n");
 170 } /* end of snic_trc_free */

/* [<][>][^][v][top][bottom][index][help] */