root/drivers/gpu/drm/drm_print.c

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

DEFINITIONS

This source file includes following definitions.
  1. __drm_puts_coredump
  2. __drm_printfn_coredump
  3. __drm_puts_seq_file
  4. __drm_printfn_seq_file
  5. __drm_printfn_info
  6. __drm_printfn_debug
  7. drm_puts
  8. drm_printf
  9. drm_dev_printk
  10. drm_dev_dbg
  11. drm_dbg
  12. drm_err
  13. drm_print_regset32

   1 /*
   2  * Copyright (C) 2016 Red Hat
   3  *
   4  * Permission is hereby granted, free of charge, to any person obtaining a
   5  * copy of this software and associated documentation files (the "Software"),
   6  * to deal in the Software without restriction, including without limitation
   7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8  * and/or sell copies of the Software, and to permit persons to whom the
   9  * Software is furnished to do so, subject to the following conditions:
  10  *
  11  * The above copyright notice and this permission notice shall be included in
  12  * all copies or substantial portions of the Software.
  13  *
  14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20  * OTHER DEALINGS IN THE SOFTWARE.
  21  *
  22  * Authors:
  23  * Rob Clark <robdclark@gmail.com>
  24  */
  25 
  26 #define DEBUG /* for pr_debug() */
  27 
  28 #include <stdarg.h>
  29 
  30 #include <linux/io.h>
  31 #include <linux/seq_file.h>
  32 #include <linux/slab.h>
  33 
  34 #include <drm/drm.h>
  35 #include <drm/drm_drv.h>
  36 #include <drm/drm_print.h>
  37 
  38 void __drm_puts_coredump(struct drm_printer *p, const char *str)
  39 {
  40         struct drm_print_iterator *iterator = p->arg;
  41         ssize_t len;
  42 
  43         if (!iterator->remain)
  44                 return;
  45 
  46         if (iterator->offset < iterator->start) {
  47                 ssize_t copy;
  48 
  49                 len = strlen(str);
  50 
  51                 if (iterator->offset + len <= iterator->start) {
  52                         iterator->offset += len;
  53                         return;
  54                 }
  55 
  56                 copy = len - (iterator->start - iterator->offset);
  57 
  58                 if (copy > iterator->remain)
  59                         copy = iterator->remain;
  60 
  61                 /* Copy out the bit of the string that we need */
  62                 memcpy(iterator->data,
  63                         str + (iterator->start - iterator->offset), copy);
  64 
  65                 iterator->offset = iterator->start + copy;
  66                 iterator->remain -= copy;
  67         } else {
  68                 ssize_t pos = iterator->offset - iterator->start;
  69 
  70                 len = min_t(ssize_t, strlen(str), iterator->remain);
  71 
  72                 memcpy(iterator->data + pos, str, len);
  73 
  74                 iterator->offset += len;
  75                 iterator->remain -= len;
  76         }
  77 }
  78 EXPORT_SYMBOL(__drm_puts_coredump);
  79 
  80 void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf)
  81 {
  82         struct drm_print_iterator *iterator = p->arg;
  83         size_t len;
  84         char *buf;
  85 
  86         if (!iterator->remain)
  87                 return;
  88 
  89         /* Figure out how big the string will be */
  90         len = snprintf(NULL, 0, "%pV", vaf);
  91 
  92         /* This is the easiest path, we've already advanced beyond the offset */
  93         if (iterator->offset + len <= iterator->start) {
  94                 iterator->offset += len;
  95                 return;
  96         }
  97 
  98         /* Then check if we can directly copy into the target buffer */
  99         if ((iterator->offset >= iterator->start) && (len < iterator->remain)) {
 100                 ssize_t pos = iterator->offset - iterator->start;
 101 
 102                 snprintf(((char *) iterator->data) + pos,
 103                         iterator->remain, "%pV", vaf);
 104 
 105                 iterator->offset += len;
 106                 iterator->remain -= len;
 107 
 108                 return;
 109         }
 110 
 111         /*
 112          * Finally, hit the slow path and make a temporary string to copy over
 113          * using _drm_puts_coredump
 114          */
 115         buf = kmalloc(len + 1, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
 116         if (!buf)
 117                 return;
 118 
 119         snprintf(buf, len + 1, "%pV", vaf);
 120         __drm_puts_coredump(p, (const char *) buf);
 121 
 122         kfree(buf);
 123 }
 124 EXPORT_SYMBOL(__drm_printfn_coredump);
 125 
 126 void __drm_puts_seq_file(struct drm_printer *p, const char *str)
 127 {
 128         seq_puts(p->arg, str);
 129 }
 130 EXPORT_SYMBOL(__drm_puts_seq_file);
 131 
 132 void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf)
 133 {
 134         seq_printf(p->arg, "%pV", vaf);
 135 }
 136 EXPORT_SYMBOL(__drm_printfn_seq_file);
 137 
 138 void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf)
 139 {
 140         dev_info(p->arg, "[" DRM_NAME "] %pV", vaf);
 141 }
 142 EXPORT_SYMBOL(__drm_printfn_info);
 143 
 144 void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf)
 145 {
 146         pr_debug("%s %pV", p->prefix, vaf);
 147 }
 148 EXPORT_SYMBOL(__drm_printfn_debug);
 149 
 150 /**
 151  * drm_puts - print a const string to a &drm_printer stream
 152  * @p: the &drm printer
 153  * @str: const string
 154  *
 155  * Allow &drm_printer types that have a constant string
 156  * option to use it.
 157  */
 158 void drm_puts(struct drm_printer *p, const char *str)
 159 {
 160         if (p->puts)
 161                 p->puts(p, str);
 162         else
 163                 drm_printf(p, "%s", str);
 164 }
 165 EXPORT_SYMBOL(drm_puts);
 166 
 167 /**
 168  * drm_printf - print to a &drm_printer stream
 169  * @p: the &drm_printer
 170  * @f: format string
 171  */
 172 void drm_printf(struct drm_printer *p, const char *f, ...)
 173 {
 174         va_list args;
 175 
 176         va_start(args, f);
 177         drm_vprintf(p, f, &args);
 178         va_end(args);
 179 }
 180 EXPORT_SYMBOL(drm_printf);
 181 
 182 void drm_dev_printk(const struct device *dev, const char *level,
 183                     const char *format, ...)
 184 {
 185         struct va_format vaf;
 186         va_list args;
 187 
 188         va_start(args, format);
 189         vaf.fmt = format;
 190         vaf.va = &args;
 191 
 192         if (dev)
 193                 dev_printk(level, dev, "[" DRM_NAME ":%ps] %pV",
 194                            __builtin_return_address(0), &vaf);
 195         else
 196                 printk("%s" "[" DRM_NAME ":%ps] %pV",
 197                        level, __builtin_return_address(0), &vaf);
 198 
 199         va_end(args);
 200 }
 201 EXPORT_SYMBOL(drm_dev_printk);
 202 
 203 void drm_dev_dbg(const struct device *dev, unsigned int category,
 204                  const char *format, ...)
 205 {
 206         struct va_format vaf;
 207         va_list args;
 208 
 209         if (!(drm_debug & category))
 210                 return;
 211 
 212         va_start(args, format);
 213         vaf.fmt = format;
 214         vaf.va = &args;
 215 
 216         if (dev)
 217                 dev_printk(KERN_DEBUG, dev, "[" DRM_NAME ":%ps] %pV",
 218                            __builtin_return_address(0), &vaf);
 219         else
 220                 printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
 221                        __builtin_return_address(0), &vaf);
 222 
 223         va_end(args);
 224 }
 225 EXPORT_SYMBOL(drm_dev_dbg);
 226 
 227 void drm_dbg(unsigned int category, const char *format, ...)
 228 {
 229         struct va_format vaf;
 230         va_list args;
 231 
 232         if (!(drm_debug & category))
 233                 return;
 234 
 235         va_start(args, format);
 236         vaf.fmt = format;
 237         vaf.va = &args;
 238 
 239         printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
 240                __builtin_return_address(0), &vaf);
 241 
 242         va_end(args);
 243 }
 244 EXPORT_SYMBOL(drm_dbg);
 245 
 246 void drm_err(const char *format, ...)
 247 {
 248         struct va_format vaf;
 249         va_list args;
 250 
 251         va_start(args, format);
 252         vaf.fmt = format;
 253         vaf.va = &args;
 254 
 255         printk(KERN_ERR "[" DRM_NAME ":%ps] *ERROR* %pV",
 256                __builtin_return_address(0), &vaf);
 257 
 258         va_end(args);
 259 }
 260 EXPORT_SYMBOL(drm_err);
 261 
 262 /**
 263  * drm_print_regset32 - print the contents of registers to a
 264  * &drm_printer stream.
 265  *
 266  * @p: the &drm printer
 267  * @regset: the list of registers to print.
 268  *
 269  * Often in driver debug, it's useful to be able to either capture the
 270  * contents of registers in the steady state using debugfs or at
 271  * specific points during operation.  This lets the driver have a
 272  * single list of registers for both.
 273  */
 274 void drm_print_regset32(struct drm_printer *p, struct debugfs_regset32 *regset)
 275 {
 276         int namelen = 0;
 277         int i;
 278 
 279         for (i = 0; i < regset->nregs; i++)
 280                 namelen = max(namelen, (int)strlen(regset->regs[i].name));
 281 
 282         for (i = 0; i < regset->nregs; i++) {
 283                 drm_printf(p, "%*s = 0x%08x\n",
 284                            namelen, regset->regs[i].name,
 285                            readl(regset->base + regset->regs[i].offset));
 286         }
 287 }
 288 EXPORT_SYMBOL(drm_print_regset32);

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