Index: sys/compat/linuxkpi/common/include/linux/printk.h =================================================================== --- sys/compat/linuxkpi/common/include/linux/printk.h +++ sys/compat/linuxkpi/common/include/linux/printk.h @@ -50,6 +50,12 @@ const char *, const char *, const int, const int, const int, const void *, size_t, const bool); +#define hex_dump_to_buffer(buf, len, rowsize, groupsize, linebuf, linebuflen, ascii) \ + lkpi_hex_dump_to_buffer((buf), (len), (rowsize), (groupsize), (linebuf), (linebuflen), (ascii)) + +int lkpi_hex_dump_to_buffer(const void *buf, size_t len, int rowsize, + int groupsize, char *linebuf, size_t linebuflen, bool ascii); + static inline void print_hex_dump(const char *level, const char *prefix_str, const int prefix_type, const int rowsize, const int groupsize, Index: sys/compat/linuxkpi/common/src/linux_compat.c =================================================================== --- sys/compat/linuxkpi/common/src/linux_compat.c +++ sys/compat/linuxkpi/common/src/linux_compat.c @@ -2061,6 +2061,86 @@ } } +struct hdtb_context { + char *linebuf; + size_t linebuflen; + int written; +}; + +static int +hdtb_cb(void *arg, const char *format, ...) +{ + struct hdtb_context *context; + int written; + va_list args; + + context = arg; + + if (context->linebuflen == 0) + return (0); + + va_start(args, format); + written = vsnprintf( + context->linebuf, context->linebuflen, format, args); + va_end(args); + + if (written < 0) + return (written); + + context->written += written; + + if (written < context->linebuflen) { + context->linebuf += written; + context->linebuflen -= written; + } else { + context->linebuf += context->linebuflen; + context->linebuflen = 0; + } + + return (written); +} + +int +lkpi_hex_dump_to_buffer(const void *buf, size_t len, int rowsize, + int groupsize, char *linebuf, size_t linebuflen, bool ascii) +{ + int written; + struct hdtb_context context; + + context.linebuf = linebuf; + context.linebuflen = linebuflen; + context.written = 0; + + if (rowsize != 16 && rowsize != 32) + rowsize = 16; + + len = min(len, rowsize); + + switch (groupsize) { + case 1: + case 2: + case 4: + case 8: + break; + default: + groupsize = 1; + break; + } + + lkpi_hex_dump( + hdtb_cb, &context, NULL, NULL, DUMP_PREFIX_NONE, + rowsize, groupsize, buf, len, ascii); + + written = context.written; + if (written > 0 && linebuf[written - 1] == '\n') { + /* Trim trailing newline from lkpi_hex_dump(). */ + linebuf[written - 1] = '\0'; + written--; + } + + return (written); +} + static void linux_timer_callback_wrapper(void *context) {