cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

esas2r_log.c (7786B)


      1/*
      2 *  linux/drivers/scsi/esas2r/esas2r_log.c
      3 *      For use with ATTO ExpressSAS R6xx SAS/SATA RAID controllers
      4 *
      5 *  Copyright (c) 2001-2013 ATTO Technology, Inc.
      6 *  (mailto:linuxdrivers@attotech.com)
      7 *
      8 * This program is free software; you can redistribute it and/or
      9 * modify it under the terms of the GNU General Public License
     10 * as published by the Free Software Foundation; either version 2
     11 * of the License, or (at your option) any later version.
     12 *
     13 * This program is distributed in the hope that it will be useful,
     14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 * GNU General Public License for more details.
     17 *
     18 * NO WARRANTY
     19 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
     20 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
     21 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
     22 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
     23 * solely responsible for determining the appropriateness of using and
     24 * distributing the Program and assumes all risks associated with its
     25 * exercise of rights under this Agreement, including but not limited to
     26 * the risks and costs of program errors, damage to or loss of data,
     27 * programs or equipment, and unavailability or interruption of operations.
     28 *
     29 * DISCLAIMER OF LIABILITY
     30 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
     31 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     32 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
     33 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
     34 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
     35 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
     36 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
     37 *
     38 * You should have received a copy of the GNU General Public License
     39 * along with this program; if not, write to the Free Software
     40 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
     41 * USA.
     42 */
     43
     44#include "esas2r.h"
     45
     46/*
     47 * this module within the driver is tasked with providing logging functionality.
     48 * the event_log_level module parameter controls the level of messages that are
     49 * written to the system log.  the default level of messages that are written
     50 * are critical and warning messages.  if other types of messages are desired,
     51 * one simply needs to load the module with the correct value for the
     52 * event_log_level module parameter.  for example:
     53 *
     54 * insmod <module> event_log_level=1
     55 *
     56 * will load the module and only critical events will be written by this module
     57 * to the system log.  if critical, warning, and information-level messages are
     58 * desired, the correct value for the event_log_level module parameter
     59 * would be as follows:
     60 *
     61 * insmod <module> event_log_level=3
     62 */
     63
     64#define EVENT_LOG_BUFF_SIZE 1024
     65
     66static long event_log_level = ESAS2R_LOG_DFLT;
     67
     68module_param(event_log_level, long, S_IRUGO | S_IRUSR);
     69MODULE_PARM_DESC(event_log_level,
     70		 "Specifies the level of events to report to the system log.  Critical and warning level events are logged by default.");
     71
     72/* A shared buffer to use for formatting messages. */
     73static char event_buffer[EVENT_LOG_BUFF_SIZE];
     74
     75/* A lock to protect the shared buffer used for formatting messages. */
     76static DEFINE_SPINLOCK(event_buffer_lock);
     77
     78/*
     79 * translates an esas2r-defined logging event level to a kernel logging level.
     80 *
     81 * @param [in] level the esas2r-defined logging event level to translate
     82 *
     83 * @return the corresponding kernel logging level.
     84 */
     85static const char *translate_esas2r_event_level_to_kernel(const long level)
     86{
     87	switch (level) {
     88	case ESAS2R_LOG_CRIT:
     89		return KERN_CRIT;
     90
     91	case ESAS2R_LOG_WARN:
     92		return KERN_WARNING;
     93
     94	case ESAS2R_LOG_INFO:
     95		return KERN_INFO;
     96
     97	case ESAS2R_LOG_DEBG:
     98	case ESAS2R_LOG_TRCE:
     99	default:
    100		return KERN_DEBUG;
    101	}
    102}
    103
    104#pragma GCC diagnostic push
    105#ifndef __clang__
    106#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
    107#endif
    108
    109/*
    110 * the master logging function.  this function will format the message as
    111 * outlined by the formatting string, the input device information and the
    112 * substitution arguments and output the resulting string to the system log.
    113 *
    114 * @param [in] level  the event log level of the message
    115 * @param [in] dev    the device information
    116 * @param [in] format the formatting string for the message
    117 * @param [in] args   the substition arguments to the formatting string
    118 *
    119 * @return 0 on success, or -1 if an error occurred.
    120 */
    121static int esas2r_log_master(const long level,
    122			     const struct device *dev,
    123			     const char *format,
    124			     va_list args)
    125{
    126	if (level <= event_log_level) {
    127		unsigned long flags = 0;
    128		int retval = 0;
    129		char *buffer = event_buffer;
    130		size_t buflen = EVENT_LOG_BUFF_SIZE;
    131		const char *fmt_nodev = "%s%s: ";
    132		const char *fmt_dev = "%s%s [%s, %s, %s]";
    133		const char *slevel =
    134			translate_esas2r_event_level_to_kernel(level);
    135
    136		spin_lock_irqsave(&event_buffer_lock, flags);
    137
    138		memset(buffer, 0, buflen);
    139
    140		/*
    141		 * format the level onto the beginning of the string and do
    142		 * some pointer arithmetic to move the pointer to the point
    143		 * where the actual message can be inserted.
    144		 */
    145
    146		if (dev == NULL) {
    147			snprintf(buffer, buflen, fmt_nodev, slevel,
    148				 ESAS2R_DRVR_NAME);
    149		} else {
    150			snprintf(buffer, buflen, fmt_dev, slevel,
    151				 ESAS2R_DRVR_NAME,
    152				 (dev->driver ? dev->driver->name : "unknown"),
    153				 (dev->bus ? dev->bus->name : "unknown"),
    154				 dev_name(dev));
    155		}
    156
    157		buffer += strlen(event_buffer);
    158		buflen -= strlen(event_buffer);
    159
    160		retval = vsnprintf(buffer, buflen, format, args);
    161		if (retval < 0) {
    162			spin_unlock_irqrestore(&event_buffer_lock, flags);
    163			return -1;
    164		}
    165
    166		/*
    167		 * Put a line break at the end of the formatted string so that
    168		 * we don't wind up with run-on messages.
    169		 */
    170		printk("%s\n", event_buffer);
    171
    172		spin_unlock_irqrestore(&event_buffer_lock, flags);
    173	}
    174
    175	return 0;
    176}
    177
    178#pragma GCC diagnostic pop
    179
    180/*
    181 * formats and logs a message to the system log.
    182 *
    183 * @param [in] level  the event level of the message
    184 * @param [in] format the formating string for the message
    185 * @param [in] ...    the substitution arguments to the formatting string
    186 *
    187 * @return 0 on success, or -1 if an error occurred.
    188 */
    189int esas2r_log(const long level, const char *format, ...)
    190{
    191	int retval = 0;
    192	va_list args;
    193
    194	va_start(args, format);
    195
    196	retval = esas2r_log_master(level, NULL, format, args);
    197
    198	va_end(args);
    199
    200	return retval;
    201}
    202
    203/*
    204 * formats and logs a message to the system log.  this message will include
    205 * device information.
    206 *
    207 * @param [in] level   the event level of the message
    208 * @param [in] dev     the device information
    209 * @param [in] format  the formatting string for the message
    210 * @param [in] ...     the substitution arguments to the formatting string
    211 *
    212 * @return 0 on success, or -1 if an error occurred.
    213 */
    214int esas2r_log_dev(const long level,
    215		   const struct device *dev,
    216		   const char *format,
    217		   ...)
    218{
    219	int retval = 0;
    220	va_list args;
    221
    222	va_start(args, format);
    223
    224	retval = esas2r_log_master(level, dev, format, args);
    225
    226	va_end(args);
    227
    228	return retval;
    229}
    230
    231/*
    232 * formats and logs a message to the system log.  this message will include
    233 * device information.
    234 *
    235 * @param [in] level   the event level of the message
    236 * @param [in] buf
    237 * @param [in] len
    238 *
    239 * @return 0 on success, or -1 if an error occurred.
    240 */
    241int esas2r_log_hexdump(const long level,
    242		       const void *buf,
    243		       size_t len)
    244{
    245	if (level <= event_log_level) {
    246		print_hex_dump(translate_esas2r_event_level_to_kernel(level),
    247			       "", DUMP_PREFIX_OFFSET, 16, 1, buf,
    248			       len, true);
    249	}
    250
    251	return 1;
    252}