![]() |
|
|||
0001 /* 0002 * linux/drivers/scsi/esas2r/esas2r_log.c 0003 * For use with ATTO ExpressSAS R6xx SAS/SATA RAID controllers 0004 * 0005 * Copyright (c) 2001-2013 ATTO Technology, Inc. 0006 * (mailto:linuxdrivers@attotech.com) 0007 * 0008 * This program is free software; you can redistribute it and/or 0009 * modify it under the terms of the GNU General Public License 0010 * as published by the Free Software Foundation; either version 2 0011 * of the License, or (at your option) any later version. 0012 * 0013 * This program is distributed in the hope that it will be useful, 0014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0016 * GNU General Public License for more details. 0017 * 0018 * NO WARRANTY 0019 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR 0020 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT 0021 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 0022 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is 0023 * solely responsible for determining the appropriateness of using and 0024 * distributing the Program and assumes all risks associated with its 0025 * exercise of rights under this Agreement, including but not limited to 0026 * the risks and costs of program errors, damage to or loss of data, 0027 * programs or equipment, and unavailability or interruption of operations. 0028 * 0029 * DISCLAIMER OF LIABILITY 0030 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY 0031 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 0032 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND 0033 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 0034 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 0035 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED 0036 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES 0037 * 0038 * You should have received a copy of the GNU General Public License 0039 * along with this program; if not, write to the Free Software 0040 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 0041 * USA. 0042 */ 0043 0044 #include "esas2r.h" 0045 0046 /* 0047 * this module within the driver is tasked with providing logging functionality. 0048 * the event_log_level module parameter controls the level of messages that are 0049 * written to the system log. the default level of messages that are written 0050 * are critical and warning messages. if other types of messages are desired, 0051 * one simply needs to load the module with the correct value for the 0052 * event_log_level module parameter. for example: 0053 * 0054 * insmod <module> event_log_level=1 0055 * 0056 * will load the module and only critical events will be written by this module 0057 * to the system log. if critical, warning, and information-level messages are 0058 * desired, the correct value for the event_log_level module parameter 0059 * would be as follows: 0060 * 0061 * insmod <module> event_log_level=3 0062 */ 0063 0064 #define EVENT_LOG_BUFF_SIZE 1024 0065 0066 static long event_log_level = ESAS2R_LOG_DFLT; 0067 0068 module_param(event_log_level, long, S_IRUGO | S_IRUSR); 0069 MODULE_PARM_DESC(event_log_level, 0070 "Specifies the level of events to report to the system log. Critical and warning level events are logged by default."); 0071 0072 /* A shared buffer to use for formatting messages. */ 0073 static char event_buffer[EVENT_LOG_BUFF_SIZE]; 0074 0075 /* A lock to protect the shared buffer used for formatting messages. */ 0076 static DEFINE_SPINLOCK(event_buffer_lock); 0077 0078 /* 0079 * translates an esas2r-defined logging event level to a kernel logging level. 0080 * 0081 * @param [in] level the esas2r-defined logging event level to translate 0082 * 0083 * @return the corresponding kernel logging level. 0084 */ 0085 static const char *translate_esas2r_event_level_to_kernel(const long level) 0086 { 0087 switch (level) { 0088 case ESAS2R_LOG_CRIT: 0089 return KERN_CRIT; 0090 0091 case ESAS2R_LOG_WARN: 0092 return KERN_WARNING; 0093 0094 case ESAS2R_LOG_INFO: 0095 return KERN_INFO; 0096 0097 case ESAS2R_LOG_DEBG: 0098 case ESAS2R_LOG_TRCE: 0099 default: 0100 return KERN_DEBUG; 0101 } 0102 } 0103 0104 #pragma GCC diagnostic push 0105 #ifndef __clang__ 0106 #pragma GCC diagnostic ignored "-Wsuggest-attribute=format" 0107 #endif 0108 0109 /* 0110 * the master logging function. this function will format the message as 0111 * outlined by the formatting string, the input device information and the 0112 * substitution arguments and output the resulting string to the system log. 0113 * 0114 * @param [in] level the event log level of the message 0115 * @param [in] dev the device information 0116 * @param [in] format the formatting string for the message 0117 * @param [in] args the substition arguments to the formatting string 0118 * 0119 * @return 0 on success, or -1 if an error occurred. 0120 */ 0121 static int esas2r_log_master(const long level, 0122 const struct device *dev, 0123 const char *format, 0124 va_list args) 0125 { 0126 if (level <= event_log_level) { 0127 unsigned long flags = 0; 0128 int retval = 0; 0129 char *buffer = event_buffer; 0130 size_t buflen = EVENT_LOG_BUFF_SIZE; 0131 const char *fmt_nodev = "%s%s: "; 0132 const char *fmt_dev = "%s%s [%s, %s, %s]"; 0133 const char *slevel = 0134 translate_esas2r_event_level_to_kernel(level); 0135 0136 spin_lock_irqsave(&event_buffer_lock, flags); 0137 0138 memset(buffer, 0, buflen); 0139 0140 /* 0141 * format the level onto the beginning of the string and do 0142 * some pointer arithmetic to move the pointer to the point 0143 * where the actual message can be inserted. 0144 */ 0145 0146 if (dev == NULL) { 0147 snprintf(buffer, buflen, fmt_nodev, slevel, 0148 ESAS2R_DRVR_NAME); 0149 } else { 0150 snprintf(buffer, buflen, fmt_dev, slevel, 0151 ESAS2R_DRVR_NAME, 0152 (dev->driver ? dev->driver->name : "unknown"), 0153 (dev->bus ? dev->bus->name : "unknown"), 0154 dev_name(dev)); 0155 } 0156 0157 buffer += strlen(event_buffer); 0158 buflen -= strlen(event_buffer); 0159 0160 retval = vsnprintf(buffer, buflen, format, args); 0161 if (retval < 0) { 0162 spin_unlock_irqrestore(&event_buffer_lock, flags); 0163 return -1; 0164 } 0165 0166 /* 0167 * Put a line break at the end of the formatted string so that 0168 * we don't wind up with run-on messages. 0169 */ 0170 printk("%s\n", event_buffer); 0171 0172 spin_unlock_irqrestore(&event_buffer_lock, flags); 0173 } 0174 0175 return 0; 0176 } 0177 0178 #pragma GCC diagnostic pop 0179 0180 /* 0181 * formats and logs a message to the system log. 0182 * 0183 * @param [in] level the event level of the message 0184 * @param [in] format the formating string for the message 0185 * @param [in] ... the substitution arguments to the formatting string 0186 * 0187 * @return 0 on success, or -1 if an error occurred. 0188 */ 0189 int esas2r_log(const long level, const char *format, ...) 0190 { 0191 int retval = 0; 0192 va_list args; 0193 0194 va_start(args, format); 0195 0196 retval = esas2r_log_master(level, NULL, format, args); 0197 0198 va_end(args); 0199 0200 return retval; 0201 } 0202 0203 /* 0204 * formats and logs a message to the system log. this message will include 0205 * device information. 0206 * 0207 * @param [in] level the event level of the message 0208 * @param [in] dev the device information 0209 * @param [in] format the formatting string for the message 0210 * @param [in] ... the substitution arguments to the formatting string 0211 * 0212 * @return 0 on success, or -1 if an error occurred. 0213 */ 0214 int esas2r_log_dev(const long level, 0215 const struct device *dev, 0216 const char *format, 0217 ...) 0218 { 0219 int retval = 0; 0220 va_list args; 0221 0222 va_start(args, format); 0223 0224 retval = esas2r_log_master(level, dev, format, args); 0225 0226 va_end(args); 0227 0228 return retval; 0229 } 0230 0231 /* 0232 * formats and logs a message to the system log. this message will include 0233 * device information. 0234 * 0235 * @param [in] level the event level of the message 0236 * @param [in] buf 0237 * @param [in] len 0238 * 0239 * @return 0 on success, or -1 if an error occurred. 0240 */ 0241 int esas2r_log_hexdump(const long level, 0242 const void *buf, 0243 size_t len) 0244 { 0245 if (level <= event_log_level) { 0246 print_hex_dump(translate_esas2r_event_level_to_kernel(level), 0247 "", DUMP_PREFIX_OFFSET, 16, 1, buf, 0248 len, true); 0249 } 0250 0251 return 1; 0252 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |