Re: [PATCH v4 5/7] lib/hexdump.c: Allow multiple groups to be separated by lines '|'

2019-06-25 Thread Alastair D'Silva
On Mon, 2019-06-24 at 22:37 -0700, Joe Perches wrote:
> On Tue, 2019-06-25 at 13:17 +1000, Alastair D'Silva wrote:
> > From: Alastair D'Silva 
> > 
> > With the wider display format, it can become hard to identify how
> > many
> > bytes into the line you are looking at.
> > 
> > The patch adds new flags to hex_dump_to_buffer() and
> > print_hex_dump() to
> > print vertical lines to separate every N groups of bytes.
> > 
> > eg.
> > buf:: 454d414e 43415053|4e495f45
> > 00584544  NAMESPAC|E_INDEX.
> > buf:0010: 0000 0002|
> >   |
> > 
> > Signed-off-by: Alastair D'Silva 
> > ---
> >  include/linux/printk.h |  3 +++
> >  lib/hexdump.c  | 59 
> > --
> >  2 files changed, 54 insertions(+), 8 deletions(-)
> > 
> > diff --git a/include/linux/printk.h b/include/linux/printk.h
> []
> > @@ -485,6 +485,9 @@ enum {
> >  
> >  #define HEXDUMP_ASCII  BIT(0)
> >  #define HEXDUMP_SUPPRESS_REPEATED  BIT(1)
> > +#define HEXDUMP_2_GRP_LINESBIT(2)
> > +#define HEXDUMP_4_GRP_LINESBIT(3)
> > +#define HEXDUMP_8_GRP_LINESBIT(4)
> 
> These aren't really bits as only one value should be set
> as 8 overrides 4 and 4 overrides 2.

This should be the other way around, as we should be emitting alternate
seperators based on the smallest grouping (2 implies 4 and 8, and 4
implies 8). I'll fix the logic.

I can't come up with a better way to represent these without making the
API more complex, if you have a suggestion, I'm happy to hear it.

> 
> I would also expect this to be a value of 2 in your above
> example, rather than 8.  It's described as groups not bytes.
> 
> The example is showing a what would normally be a space ' '
> separator as a vertical bar '|' every 2nd grouping.
> 

The above example shows a group size of 4 bytes, and
HEXDUMP_2_GRP_LINES set, with 2 groups being 8 bytes.

I'll make that clearer in the commit message.

-- 
Alastair D'Silva   mob: 0423 762 819
skype: alastair_dsilva
Twitter: @EvilDeece
blog: http://alastair.d-silva.org


___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v4 4/7] lib/hexdump.c: Replace ascii bool in hex_dump_to_buffer with flags

2019-06-25 Thread Alastair D'Silva
On Mon, 2019-06-24 at 22:19 -0700, Joe Perches wrote:
> On Tue, 2019-06-25 at 15:06 +1000, Alastair D'Silva wrote:
> > The change actions Jani's suggestion:
> > https://lkml.org/lkml/2019/6/20/343
> 
> I suggest not changing any of the existing uses of
> hex_dump_to_buffer and only use hex_dump_to_buffer_ext
> when necessary for your extended use cases.
> 
> 

I disagree, adding a wrapper for the benefit of avoiding touching a
handful of call sites that are easily amended would be adding technical
debt.

-- 
Alastair D'Silva   mob: 0423 762 819
skype: alastair_dsilva
Twitter: @EvilDeece
blog: http://alastair.d-silva.org


___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v4 4/7] lib/hexdump.c: Replace ascii bool in hex_dump_to_buffer with flags

2019-06-25 Thread Alastair D'Silva
On Mon, 2019-06-24 at 22:01 -0700, Joe Perches wrote:
> On Tue, 2019-06-25 at 13:17 +1000, Alastair D'Silva wrote:
> > From: Alastair D'Silva 
> > 
> > In order to support additional features, rename hex_dump_to_buffer
> > to
> > hex_dump_to_buffer_ext, and replace the ascii bool parameter with
> > flags.
> []
> > diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c
> > b/drivers/gpu/drm/i915/intel_engine_cs.c
> []
> > @@ -1338,9 +1338,8 @@ static void hexdump(struct drm_printer *m,
> > const void *buf, size_t len)
> > }
> >  
> > WARN_ON_ONCE(hex_dump_to_buffer(buf + pos, len - pos,
> > -   rowsize, sizeof(u32),
> > -   line, sizeof(line),
> > -   false) >=
> > sizeof(line));
> > +   rowsize, sizeof(u32),
> > line,
> > +   sizeof(line)) >=
> > sizeof(line));
> 
> Huh?  Why do this?

The ascii parameter was removed from the simple API as per Jani's
suggestion. The remainder was reformatted to avoid exceeding the line
length limits.

> 
> > diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c
> > b/drivers/isdn/hardware/mISDN/mISDNisar.c
> []
> > @@ -70,8 +70,9 @@ send_mbox(struct isar_hw *isar, u8 his, u8 creg,
> > u8 len, u8 *msg)
> > int l = 0;
> >  
> > while (l < (int)len) {
> > -   hex_dump_to_buffer(msg + l, len - l,
> > 32, 1,
> > -  isar->log, 256, 1);
> > +   hex_dump_to_buffer_ext(msg + l, len -
> > l, 32, 1,
> > +  isar->log, 256,
> > +  HEXDUMP_ASCII);
> 
> Again, why do any of these?
> 
> The point of the wrapper is to avoid changing these.

Jani made a pretty good point that about half the callers didn't want
an ASCII dump, and presenting a simplified API makes sense.

I would actually put forward that we consider dropping rowsize from the
simplified API too, as most callers use 32, and those that use 16 would
probably be OK with 32.

Your proposal, on the other hand, only makes sense if there were many
callers, and even so, not in the form that you presented, since that
result in a mix of booleans & bitfields that you were critical of.

-- 
Alastair D'Silva   mob: 0423 762 819
skype: alastair_dsilva
Twitter: @EvilDeece
blog: http://alastair.d-silva.org


___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v4 0/7] Hexdump Enhancements

2019-06-25 Thread Alastair D'Silva
On Mon, 2019-06-24 at 22:01 -0700, Joe Perches wrote:
> On Tue, 2019-06-25 at 13:17 +1000, Alastair D'Silva wrote:
> > From: Alastair D'Silva 
> > 
> > Apologies for the large CC list, it's a heads up for those
> > responsible
> > for subsystems where a prototype change in generic code causes a
> > change
> > in those subsystems.
> []
> > The default behaviour of hexdump is unchanged, however, the
> > prototype
> > for hex_dump_to_buffer() has changed, and print_hex_dump() has been
> > renamed to print_hex_dump_ext(), with a wrapper replacing it for
> > compatibility with existing code, which would have been too
> > invasive to
> > change.
> 
> I believe this cover letter is misleading.
> 
> The point of the wrapper is to avoid unnecessary changes
> in existing
> code.
> 
> 

The wrapper is for print_hex_dump(), which has many callers.

The changes to existing code are for hex_dump_to_buffer(), which is
called in relatively few places.

-- 
Alastair D'Silva   mob: 0423 762 819
skype: alastair_dsilva
Twitter: @EvilDeece
blog: http://alastair.d-silva.org


___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v4 4/7] lib/hexdump.c: Replace ascii bool in hex_dump_to_buffer with flags

2019-06-24 Thread Alastair D'Silva
On Mon, 2019-06-24 at 22:01 -0700, Joe Perches wrote:
> On Tue, 2019-06-25 at 13:17 +1000, Alastair D'Silva wrote:
> > From: Alastair D'Silva 
> > 
> > In order to support additional features, rename hex_dump_to_buffer
> > to
> > hex_dump_to_buffer_ext, and replace the ascii bool parameter with
> > flags.
> []
> > diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c
> > b/drivers/gpu/drm/i915/intel_engine_cs.c
> []
> > @@ -1338,9 +1338,8 @@ static void hexdump(struct drm_printer *m,
> > const void *buf, size_t len)
> > }
> >  
> > WARN_ON_ONCE(hex_dump_to_buffer(buf + pos, len - pos,
> > -   rowsize, sizeof(u32),
> > -   line, sizeof(line),
> > -   false) >=
> > sizeof(line));
> > +   rowsize, sizeof(u32),
> > line,
> > +   sizeof(line)) >=
> > sizeof(line));
> 
> Huh?  Why do this?
> 
> > diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c
> > b/drivers/isdn/hardware/mISDN/mISDNisar.c
> []
> > @@ -70,8 +70,9 @@ send_mbox(struct isar_hw *isar, u8 his, u8 creg,
> > u8 len, u8 *msg)
> > int l = 0;
> >  
> > while (l < (int)len) {
> > -   hex_dump_to_buffer(msg + l, len - l,
> > 32, 1,
> > -  isar->log, 256, 1);
> > +   hex_dump_to_buffer_ext(msg + l, len -
> > l, 32, 1,
> > +  isar->log, 256,
> > +      HEXDUMP_ASCII);
> 
> Again, why do any of these?
> 
> The point of the wrapper is to avoid changing these.
> 
> 

The change actions Jani's suggestion:
https://lkml.org/lkml/2019/6/20/343


-- 
Alastair D'Silva   mob: 0423 762 819
skype: alastair_dsilva
Twitter: @EvilDeece
blog: http://alastair.d-silva.org


___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v4 6/7] lib/hexdump.c: Allow multiple groups to be separated by spaces

2019-06-24 Thread Alastair D'Silva
From: Alastair D'Silva 

Similar to the previous patch, this patch separates groups by 2 spaces for
the hex fields, and 1 space for the ASCII field.

eg.
buf:: 454d414e 43415053  4e495f45 00584544  NAMESPAC E_INDEX.
buf:0010:  0002      

Signed-off-by: Alastair D'Silva 
---
 include/linux/printk.h |  3 ++
 lib/hexdump.c  | 65 +++---
 2 files changed, 52 insertions(+), 16 deletions(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index ae80d7af82ab..1d082291facf 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -488,6 +488,9 @@ enum {
 #define HEXDUMP_2_GRP_LINESBIT(2)
 #define HEXDUMP_4_GRP_LINESBIT(3)
 #define HEXDUMP_8_GRP_LINESBIT(4)
+#define HEXDUMP_2_GRP_SPACES   BIT(5)
+#define HEXDUMP_4_GRP_SPACES   BIT(6)
+#define HEXDUMP_8_GRP_SPACES   BIT(7)
 
 extern int hex_dump_to_buffer_ext(const void *buf, size_t len, int rowsize,
  int groupsize, char *linebuf, size_t linebuflen,
diff --git a/lib/hexdump.c b/lib/hexdump.c
index 4dcf759fe048..e09e3cf8e595 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -91,9 +91,37 @@ static const char *group_separator(int group, u64 flags)
if ((flags & HEXDUMP_2_GRP_LINES) && !((group) % 2))
return "|";
 
+   if ((flags & HEXDUMP_8_GRP_SPACES) && !((group) % 8))
+   return "  ";
+
+   if ((flags & HEXDUMP_4_GRP_SPACES) && !((group) % 4))
+   return "  ";
+
+   if ((flags & HEXDUMP_2_GRP_SPACES) && !((group) % 2))
+   return "  ";
+
return " ";
 }
 
+static void separator_parameters(u64 flags, int groupsize, int *sep_chars,
+char *sep)
+{
+   if (flags & (HEXDUMP_2_GRP_LINES | HEXDUMP_2_GRP_SPACES))
+   *sep_chars = groupsize * 2;
+   if (flags & (HEXDUMP_4_GRP_LINES | HEXDUMP_4_GRP_SPACES))
+   *sep_chars = groupsize * 4;
+   if (flags & (HEXDUMP_8_GRP_LINES | HEXDUMP_8_GRP_SPACES))
+   *sep_chars = groupsize * 8;
+
+   if (flags & (HEXDUMP_2_GRP_LINES | HEXDUMP_4_GRP_LINES |
+  HEXDUMP_8_GRP_LINES))
+   *sep = '|';
+
+   if (flags & (HEXDUMP_2_GRP_SPACES | HEXDUMP_4_GRP_SPACES |
+  HEXDUMP_8_GRP_SPACES))
+   *sep = ' ';
+}
+
 /**
  * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
  * @buf: data blob to dump
@@ -107,6 +135,9 @@ static const char *group_separator(int group, u64 flags)
  * HEXDUMP_2_GRP_LINES:insert a '|' after every 2 groups
  * HEXDUMP_4_GRP_LINES:insert a '|' after every 4 groups
  * HEXDUMP_8_GRP_LINES:insert a '|' after every 8 groups
+ * HEXDUMP_2_GRP_SPACES:   insert a ' ' after every 2 groups
+ * HEXDUMP_4_GRP_SPACES:   insert a ' ' after every 4 groups
+ * HEXDUMP_8_GRP_SPACES:   insert a ' ' after every 8 groups
  *
  * hex_dump_to_buffer() works on one "line" of output at a time, converting
  *  bytes of input to hexadecimal (and optionally printable ASCII)
@@ -139,7 +170,8 @@ int hex_dump_to_buffer_ext(const void *buf, size_t len, int 
rowsize,
int j, lx = 0;
int ascii_column;
int ret;
-   int line_chars = 0;
+   int sep_chars = 0;
+   char sep = 0;
 
if (!is_power_of_2(groupsize) || groupsize > 8)
groupsize = 1;
@@ -153,8 +185,14 @@ int hex_dump_to_buffer_ext(const void *buf, size_t len, 
int rowsize,
len = rowsize;
 
ngroups = len / groupsize;
+
ascii_column = rowsize * 2 + rowsize / groupsize + 1;
 
+   // space separators use 2 spaces in the hex output
+   separator_parameters(flags, groupsize, _chars, );
+   if (sep == ' ')
+   ascii_column += rowsize / sep_chars;
+
if (!linebuflen)
goto overflow1;
 
@@ -222,24 +260,17 @@ int hex_dump_to_buffer_ext(const void *buf, size_t len, 
int rowsize,
linebuf[lx++] = ' ';
}
 
-   if (flags & HEXDUMP_2_GRP_LINES)
-   line_chars = groupsize * 2;
-   if (flags & HEXDUMP_4_GRP_LINES)
-   line_chars = groupsize * 4;
-   if (flags & HEXDUMP_8_GRP_LINES)
-   line_chars = groupsize * 8;
-
for (j = 0; j < len; j++) {
if (linebuflen < lx + 2)
goto overflow2;
ch = ptr[j];
linebuf[lx++] = (isascii(ch) && isprint(ch)) ? ch : '.';
 
-   if (line_chars && ((j + 1) < len) &&
-   ((j + 

[PATCH v4 4/7] lib/hexdump.c: Replace ascii bool in hex_dump_to_buffer with flags

2019-06-24 Thread Alastair D'Silva
From: Alastair D'Silva 

In order to support additional features, rename hex_dump_to_buffer to
hex_dump_to_buffer_ext, and replace the ascii bool parameter with flags.

A wrapper is provided for callers that do not need anything but a basic
dump.

Signed-off-by: Alastair D'Silva 
---
 drivers/gpu/drm/i915/intel_engine_cs.c|  5 +-
 drivers/isdn/hardware/mISDN/mISDNisar.c   | 10 ++--
 drivers/mailbox/mailbox-test.c|  8 ++--
 drivers/net/ethernet/amd/xgbe/xgbe-drv.c  |  2 +-
 .../net/ethernet/synopsys/dwc-xlgmac-common.c |  2 +-
 drivers/net/wireless/ath/ath10k/debug.c   |  7 +--
 .../net/wireless/intel/iwlegacy/3945-mac.c|  4 +-
 drivers/platform/chrome/wilco_ec/debugfs.c| 10 ++--
 drivers/scsi/scsi_logging.c   |  8 ++--
 drivers/staging/fbtft/fbtft-core.c|  2 +-
 fs/seq_file.c |  6 ++-
 include/linux/printk.h| 46 +--
 lib/hexdump.c | 24 +-
 lib/test_hexdump.c| 10 ++--
 14 files changed, 94 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c 
b/drivers/gpu/drm/i915/intel_engine_cs.c
index eea9bec04f1b..64189a0e5ec9 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -1338,9 +1338,8 @@ static void hexdump(struct drm_printer *m, const void 
*buf, size_t len)
}
 
WARN_ON_ONCE(hex_dump_to_buffer(buf + pos, len - pos,
-   rowsize, sizeof(u32),
-   line, sizeof(line),
-   false) >= sizeof(line));
+   rowsize, sizeof(u32), line,
+   sizeof(line)) >= sizeof(line));
drm_printf(m, "[%04zx] %s\n", pos, line);
 
prev = buf + pos;
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c 
b/drivers/isdn/hardware/mISDN/mISDNisar.c
index fd5c52f37802..84455b521246 100644
--- a/drivers/isdn/hardware/mISDN/mISDNisar.c
+++ b/drivers/isdn/hardware/mISDN/mISDNisar.c
@@ -70,8 +70,9 @@ send_mbox(struct isar_hw *isar, u8 his, u8 creg, u8 len, u8 
*msg)
int l = 0;
 
while (l < (int)len) {
-   hex_dump_to_buffer(msg + l, len - l, 32, 1,
-  isar->log, 256, 1);
+   hex_dump_to_buffer_ext(msg + l, len - l, 32, 1,
+  isar->log, 256,
+  HEXDUMP_ASCII);
pr_debug("%s: %s %02x: %s\n", isar->name,
 __func__, l, isar->log);
l += 32;
@@ -99,8 +100,9 @@ rcv_mbox(struct isar_hw *isar, u8 *msg)
int l = 0;
 
while (l < (int)isar->clsb) {
-   hex_dump_to_buffer(msg + l, isar->clsb - l, 32,
-  1, isar->log, 256, 1);
+   hex_dump_to_buffer_ext(msg + l, isar->clsb - l,
+  32, 1, isar->log, 256,
+  HEXDUMP_ASCII);
pr_debug("%s: %s %02x: %s\n", isar->name,
 __func__, l, isar->log);
l += 32;
diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c
index 4555d678fadd..ce334f88a3ee 100644
--- a/drivers/mailbox/mailbox-test.c
+++ b/drivers/mailbox/mailbox-test.c
@@ -206,10 +206,10 @@ static ssize_t mbox_test_message_read(struct file *filp, 
char __user *userbuf,
 
ptr = tdev->rx_buffer;
while (l < MBOX_HEXDUMP_MAX_LEN) {
-   hex_dump_to_buffer(ptr,
-  MBOX_BYTES_PER_LINE,
-  MBOX_BYTES_PER_LINE, 1, touser + l,
-  MBOX_HEXDUMP_LINE_LEN, true);
+   hex_dump_to_buffer_ext(ptr,
+  MBOX_BYTES_PER_LINE,
+  MBOX_BYTES_PER_LINE, 1, touser + l,
+  MBOX_HEXDUMP_LINE_LEN, HEXDUMP_ASCII);
 
ptr += MBOX_BYTES_PER_LINE;
l += MBOX_HEXDUMP_LINE_LEN;
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c 
b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index 3dd0cecddba8..f0118fe35c41 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -2992,7 +2992,7 @@ void xgbe_print_pkt(struct net_device 

[PATCH v4 5/7] lib/hexdump.c: Allow multiple groups to be separated by lines '|'

2019-06-24 Thread Alastair D'Silva
From: Alastair D'Silva 

With the wider display format, it can become hard to identify how many
bytes into the line you are looking at.

The patch adds new flags to hex_dump_to_buffer() and print_hex_dump() to
print vertical lines to separate every N groups of bytes.

eg.
buf:: 454d414e 43415053|4e495f45 00584544  NAMESPAC|E_INDEX.
buf:0010:  0002|   |

Signed-off-by: Alastair D'Silva 
---
 include/linux/printk.h |  3 +++
 lib/hexdump.c  | 59 --
 2 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index f0761b3a2d5d..ae80d7af82ab 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -485,6 +485,9 @@ enum {
 
 #define HEXDUMP_ASCII  BIT(0)
 #define HEXDUMP_SUPPRESS_REPEATED  BIT(1)
+#define HEXDUMP_2_GRP_LINESBIT(2)
+#define HEXDUMP_4_GRP_LINESBIT(3)
+#define HEXDUMP_8_GRP_LINESBIT(4)
 
 extern int hex_dump_to_buffer_ext(const void *buf, size_t len, int rowsize,
  int groupsize, char *linebuf, size_t linebuflen,
diff --git a/lib/hexdump.c b/lib/hexdump.c
index 1bf838c1a568..4dcf759fe048 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -77,6 +77,23 @@ char *bin2hex(char *dst, const void *src, size_t count)
 }
 EXPORT_SYMBOL(bin2hex);
 
+static const char *group_separator(int group, u64 flags)
+{
+   if (group == 0)
+   return " ";
+
+   if ((flags & HEXDUMP_8_GRP_LINES) && !((group) % 8))
+   return "|";
+
+   if ((flags & HEXDUMP_4_GRP_LINES) && !((group) % 4))
+   return "|";
+
+   if ((flags & HEXDUMP_2_GRP_LINES) && !((group) % 2))
+   return "|";
+
+   return " ";
+}
+
 /**
  * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
  * @buf: data blob to dump
@@ -87,6 +104,9 @@ EXPORT_SYMBOL(bin2hex);
  * @linebuflen: total size of @linebuf, including space for terminating NUL
  * @flags: A bitwise OR of the following flags:
  * HEXDUMP_ASCII:  include ASCII after the hex output
+ * HEXDUMP_2_GRP_LINES:insert a '|' after every 2 groups
+ * HEXDUMP_4_GRP_LINES:insert a '|' after every 4 groups
+ * HEXDUMP_8_GRP_LINES:insert a '|' after every 8 groups
  *
  * hex_dump_to_buffer() works on one "line" of output at a time, converting
  *  bytes of input to hexadecimal (and optionally printable ASCII)
@@ -119,6 +139,7 @@ int hex_dump_to_buffer_ext(const void *buf, size_t len, int 
rowsize,
int j, lx = 0;
int ascii_column;
int ret;
+   int line_chars = 0;
 
if (!is_power_of_2(groupsize) || groupsize > 8)
groupsize = 1;
@@ -145,7 +166,8 @@ int hex_dump_to_buffer_ext(const void *buf, size_t len, int 
rowsize,
 
for (j = 0; j < ngroups; j++) {
ret = snprintf(linebuf + lx, linebuflen - lx,
-  "%s%16.16llx", j ? " " : "",
+  "%s%16.16llx",
+  j ? group_separator(j, flags) : "",
   get_unaligned(ptr8 + j));
if (ret >= linebuflen - lx)
goto overflow1;
@@ -156,7 +178,8 @@ int hex_dump_to_buffer_ext(const void *buf, size_t len, int 
rowsize,
 
for (j = 0; j < ngroups; j++) {
ret = snprintf(linebuf + lx, linebuflen - lx,
-  "%s%8.8x", j ? " " : "",
+  "%s%8.8x",
+  j ? group_separator(j, flags) : "",
   get_unaligned(ptr4 + j));
if (ret >= linebuflen - lx)
goto overflow1;
@@ -167,7 +190,8 @@ int hex_dump_to_buffer_ext(const void *buf, size_t len, int 
rowsize,
 
for (j = 0; j < ngroups; j++) {
ret = snprintf(linebuf + lx, linebuflen - lx,
-  "%s%4.4x", j ? " " : "",
+  "%s%4.4x",
+  j ? group_separator(j, flags) : "",
   get_unaligned(ptr2 + j));
if (ret >= linebuflen - lx)
goto overflow1;
@@ -197,11 +221,26 @@ int hex_dump_to_buffer_ext(const void *buf, size_t len, 
int rowsize,
goto overflow2;
linebuf[lx++] = ' ';
}
+
+   if

[PATCH v4 7/7] lib/hexdump.c: Optionally retain byte ordering

2019-06-24 Thread Alastair D'Silva
From: Alastair D'Silva 

The behaviour of hexdump groups is to print the data out as if
it was a native-endian number.

This patch tweaks the documentation to make this clear, and also
adds the HEXDUMP_RETAIN_BYTE_ORDER flag to allow groups of
multiple bytes to be printed without affecting the ordering
of the printed bytes.

Signed-off-by: Alastair D'Silva 
---
 include/linux/printk.h |  1 +
 lib/hexdump.c  | 30 
 lib/test_hexdump.c | 62 --
 3 files changed, 68 insertions(+), 25 deletions(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index 1d082291facf..ed1a79aa9695 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -491,6 +491,7 @@ enum {
 #define HEXDUMP_2_GRP_SPACES   BIT(5)
 #define HEXDUMP_4_GRP_SPACES   BIT(6)
 #define HEXDUMP_8_GRP_SPACES   BIT(7)
+#define HEXDUMP_RETAIN_BYTE_ORDER  BIT(8)
 
 extern int hex_dump_to_buffer_ext(const void *buf, size_t len, int rowsize,
  int groupsize, char *linebuf, size_t linebuflen,
diff --git a/lib/hexdump.c b/lib/hexdump.c
index e09e3cf8e595..29024eccf5da 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -127,7 +127,8 @@ static void separator_parameters(u64 flags, int groupsize, 
int *sep_chars,
  * @buf: data blob to dump
  * @len: number of bytes in the @buf
  * @rowsize: number of bytes to print per line; must be a multiple of groupsize
- * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
+ * @groupsize: number of bytes to convert to a native endian number and print:
+ *1, 2, 4, 8; default = 1
  * @linebuf: where to put the converted data
  * @linebuflen: total size of @linebuf, including space for terminating NUL
  * @flags: A bitwise OR of the following flags:
@@ -138,6 +139,9 @@ static void separator_parameters(u64 flags, int groupsize, 
int *sep_chars,
  * HEXDUMP_2_GRP_SPACES:   insert a ' ' after every 2 groups
  * HEXDUMP_4_GRP_SPACES:   insert a ' ' after every 4 groups
  * HEXDUMP_8_GRP_SPACES:   insert a ' ' after every 8 groups
+ * HEXDUMP_RETAIN_BYTE_ORDER:  Retain the byte ordering of groups
+ * instead of treating each group as a
+ * native-endian number
  *
  * hex_dump_to_buffer() works on one "line" of output at a time, converting
  *  bytes of input to hexadecimal (and optionally printable ASCII)
@@ -172,6 +176,7 @@ int hex_dump_to_buffer_ext(const void *buf, size_t len, int 
rowsize,
int ret;
int sep_chars = 0;
char sep = 0;
+   bool big_endian = (flags & HEXDUMP_RETAIN_BYTE_ORDER) ? 1 : 0;
 
if (!is_power_of_2(groupsize) || groupsize > 8)
groupsize = 1;
@@ -203,10 +208,13 @@ int hex_dump_to_buffer_ext(const void *buf, size_t len, 
int rowsize,
const u64 *ptr8 = buf;
 
for (j = 0; j < ngroups; j++) {
+   u64 val = big_endian ?
+   be64_to_cpu(get_unaligned(ptr8 + j)) :
+   get_unaligned(ptr8 + j);
ret = snprintf(linebuf + lx, linebuflen - lx,
   "%s%16.16llx",
   j ? group_separator(j, flags) : "",
-  get_unaligned(ptr8 + j));
+  val);
if (ret >= linebuflen - lx)
goto overflow1;
lx += ret;
@@ -215,10 +223,14 @@ int hex_dump_to_buffer_ext(const void *buf, size_t len, 
int rowsize,
const u32 *ptr4 = buf;
 
for (j = 0; j < ngroups; j++) {
+   u32 val = big_endian ?
+   be32_to_cpu(get_unaligned(ptr4 + j)) :
+   get_unaligned(ptr4 + j);
+
ret = snprintf(linebuf + lx, linebuflen - lx,
   "%s%8.8x",
   j ? group_separator(j, flags) : "",
-  get_unaligned(ptr4 + j));
+  val);
if (ret >= linebuflen - lx)
goto overflow1;
lx += ret;
@@ -227,10 +239,14 @@ int hex_dump_to_buffer_ext(const void *buf, size_t len, 
int rowsize,
const u16 *ptr2 = buf;
 
for (j = 0; j < ngroups; j++) {
+   u16 val = big_endian ?
+   be16_to_cpu(get_unaligned(ptr2 + j)) :
+   get_unaligned(ptr2 + j);
+
ret = snprintf(linebuf + lx, linebuflen - lx,
  

[PATCH v4 0/7] Hexdump Enhancements

2019-06-24 Thread Alastair D'Silva
From: Alastair D'Silva 

Apologies for the large CC list, it's a heads up for those responsible
for subsystems where a prototype change in generic code causes a change
in those subsystems.

This series enhances hexdump.

These improve the readability of the dumped data in certain situations
(eg. wide terminals are available, many lines of empty bytes exist, etc).

The default behaviour of hexdump is unchanged, however, the prototype
for hex_dump_to_buffer() has changed, and print_hex_dump() has been
renamed to print_hex_dump_ext(), with a wrapper replacing it for
compatibility with existing code, which would have been too invasive to
change.

Hexdump selftests have be run & confirmed passed.

Changelog:
V4:
 - Add missing header (linux/bits.h)
 - Fix comment formatting
 - Create hex_dump_to_buffer_ext & make hex_dump_to_buffer a wrapper
V3:
 - Fix inline documention
 - use BIT macros
 - use u32 rather than u64 for flags
V2:
 - Fix failing selftests
 - Fix precedence bug in 'Replace ascii bool in hex_dump_to_buffer...'
 - Remove hardcoded new lengths & instead relax the checks in
   hex_dump_to_buffer, allocating the buffer from the heap instead of the
   stack.
 - Replace the skipping of lines of 0x00/0xff with skipping lines of
   repeated characters, announcing what has been skipped.
 - Add spaces as an optional N-group separator
 - Allow byte ordering to be maintained when HEXDUMP_RETAIN_BYTE_ORDERING
   is set.
 - Updated selftests to cover 'Relax rowsize checks' &
   'Optionally retain byte ordering'

Alastair D'Silva (7):
  lib/hexdump.c: Fix selftests
  lib/hexdump.c: Relax rowsize checks in hex_dump_to_buffer
  lib/hexdump.c: Optionally suppress lines of repeated bytes
  lib/hexdump.c: Replace ascii bool in hex_dump_to_buffer with flags
  lib/hexdump.c: Allow multiple groups to be separated by lines '|'
  lib/hexdump.c: Allow multiple groups to be separated by spaces
  lib/hexdump.c: Optionally retain byte ordering

 drivers/gpu/drm/i915/intel_engine_cs.c|   5 +-
 drivers/isdn/hardware/mISDN/mISDNisar.c   |  10 +-
 drivers/mailbox/mailbox-test.c|   8 +-
 drivers/net/ethernet/amd/xgbe/xgbe-drv.c  |   2 +-
 .../net/ethernet/synopsys/dwc-xlgmac-common.c |   2 +-
 drivers/net/wireless/ath/ath10k/debug.c   |   7 +-
 .../net/wireless/intel/iwlegacy/3945-mac.c|   4 +-
 drivers/platform/chrome/wilco_ec/debugfs.c|  10 +-
 drivers/scsi/scsi_logging.c   |   8 +-
 drivers/staging/fbtft/fbtft-core.c|   2 +-
 fs/seq_file.c |   6 +-
 include/linux/printk.h|  75 -
 lib/hexdump.c | 267 +++---
 lib/test_hexdump.c| 154 +++---
 14 files changed, 438 insertions(+), 122 deletions(-)

-- 
2.21.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v4 3/7] lib/hexdump.c: Optionally suppress lines of repeated bytes

2019-06-24 Thread Alastair D'Silva
From: Alastair D'Silva 

Some buffers may only be partially filled with useful data, while the rest
is padded (typically with 0x00 or 0xff).

This patch introduces a flag to allow the supression of lines of repeated
bytes, which are replaced with '** Skipped %u bytes of value 0x%x **'

An inline wrapper function is provided for backwards compatibility with
existing code, which maintains the original behaviour.

Signed-off-by: Alastair D'Silva 
---
 include/linux/printk.h | 26 +---
 lib/hexdump.c  | 91 --
 2 files changed, 100 insertions(+), 17 deletions(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index cefd374c47b1..c0416d0eb9e2 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -7,6 +7,7 @@
 #include 
 #include 
 #include 
+#include 
 
 extern const char linux_banner[];
 extern const char linux_proc_banner[];
@@ -481,13 +482,18 @@ enum {
DUMP_PREFIX_ADDRESS,
DUMP_PREFIX_OFFSET
 };
+
 extern int hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
  int groupsize, char *linebuf, size_t linebuflen,
  bool ascii);
+
+#define HEXDUMP_ASCII  BIT(0)
+#define HEXDUMP_SUPPRESS_REPEATED  BIT(1)
+
 #ifdef CONFIG_PRINTK
-extern void print_hex_dump(const char *level, const char *prefix_str,
+extern void print_hex_dump_ext(const char *level, const char *prefix_str,
   int prefix_type, int rowsize, int groupsize,
-  const void *buf, size_t len, bool ascii);
+  const void *buf, size_t len, u32 flags);
 #if defined(CONFIG_DYNAMIC_DEBUG)
 #define print_hex_dump_bytes(prefix_str, prefix_type, buf, len)\
dynamic_hex_dump(prefix_str, prefix_type, 16, 1, buf, len, true)
@@ -496,18 +502,28 @@ extern void print_hex_dump_bytes(const char *prefix_str, 
int prefix_type,
 const void *buf, size_t len);
 #endif /* defined(CONFIG_DYNAMIC_DEBUG) */
 #else
-static inline void print_hex_dump(const char *level, const char *prefix_str,
+static inline void print_hex_dump_ext(const char *level, const char 
*prefix_str,
  int prefix_type, int rowsize, int groupsize,
- const void *buf, size_t len, bool ascii)
+ const void *buf, size_t len, u32 flags)
 {
 }
 static inline void print_hex_dump_bytes(const char *prefix_str, int 
prefix_type,
const void *buf, size_t len)
 {
 }
-
 #endif
 
+static __always_inline void print_hex_dump(const char *level,
+  const char *prefix_str,
+  int prefix_type, int rowsize,
+  int groupsize, const void *buf,
+  size_t len, bool ascii)
+{
+   print_hex_dump_ext(level, prefix_str, prefix_type, rowsize, groupsize,
+   buf, len, ascii ? HEXDUMP_ASCII : 0);
+}
+
+
 #if defined(CONFIG_DYNAMIC_DEBUG)
 #define print_hex_dump_debug(prefix_str, prefix_type, rowsize, \
 groupsize, buf, len, ascii)\
diff --git a/lib/hexdump.c b/lib/hexdump.c
index 870c8cbff1e1..61dc625c32f5 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -212,8 +212,44 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
 EXPORT_SYMBOL(hex_dump_to_buffer);
 
 #ifdef CONFIG_PRINTK
+
+/**
+ * buf_is_all - Check if a buffer contains only a single byte value
+ * @buf: pointer to the buffer
+ * @len: the size of the buffer in bytes
+ * @val: outputs the value if if the bytes are identical
+ */
+static bool buf_is_all(const u8 *buf, size_t len, u8 *val_out)
+{
+   size_t i;
+   u8 val;
+
+   if (len <= 1)
+   return false;
+
+   val = buf[0];
+
+   for (i = 1; i < len; i++) {
+   if (buf[i] != val)
+   return false;
+   }
+
+   *val_out = val;
+   return true;
+}
+
+static void announce_skipped(const char *level, const char *prefix_str,
+  u8 val, size_t count)
+{
+   if (count == 0)
+   return;
+
+   printk("%s%s ** Skipped %lu bytes of value 0x%x **\n",
+  level, prefix_str, count, val);
+}
+
 /**
- * print_hex_dump - print a text hex dump to syslog for a binary blob of data
+ * print_hex_dump_ext - dump a binary blob of data to syslog in hexadecimal
  * @level: kernel log level (e.g. KERN_DEBUG)
  * @prefix_str: string to prefix each line with;
  *  caller supplies trailing spaces for alignment if desired
@@ -224,6 +260,10 @@ EXPORT_SYMBOL(hex_dump_to_buffer);
  * @buf: data blob to dump
  * @len: number of bytes in the @buf
  * @ascii: include ASCII after the hex output
+ * @flags: A bitwise OR of the

[PATCH v4 2/7] lib/hexdump.c: Relax rowsize checks in hex_dump_to_buffer

2019-06-24 Thread Alastair D'Silva
From: Alastair D'Silva 

This patch removes the hardcoded row limits and allows for
other lengths. These lengths must still be a multiple of
groupsize.

This allows structs that are not 16/32 bytes to display on
a single line.

This patch also expands the self-tests to test row sizes
up to 64 bytes (though they can now be arbitrarily long).

Signed-off-by: Alastair D'Silva 
---
 lib/hexdump.c  | 49 +--
 lib/test_hexdump.c | 52 ++
 2 files changed, 76 insertions(+), 25 deletions(-)

diff --git a/lib/hexdump.c b/lib/hexdump.c
index 81b70ed37209..870c8cbff1e1 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 const char hex_asc[] = "0123456789abcdef";
@@ -80,14 +81,15 @@ EXPORT_SYMBOL(bin2hex);
  * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
  * @buf: data blob to dump
  * @len: number of bytes in the @buf
- * @rowsize: number of bytes to print per line; must be 16 or 32
+ * @rowsize: number of bytes to print per line; must be a multiple of groupsize
  * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
  * @linebuf: where to put the converted data
  * @linebuflen: total size of @linebuf, including space for terminating NUL
  * @ascii: include ASCII after the hex output
  *
- * hex_dump_to_buffer() works on one "line" of output at a time, i.e.,
- * 16 or 32 bytes of input data converted to hex + ASCII output.
+ * hex_dump_to_buffer() works on one "line" of output at a time, converting
+ *  bytes of input to hexadecimal (and optionally printable ASCII)
+ * until  bytes have been emitted.
  *
  * Given a buffer of u8 data, hex_dump_to_buffer() converts the input data
  * to a hex + ASCII dump at the supplied memory location.
@@ -116,16 +118,17 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
int ascii_column;
int ret;
 
-   if (rowsize != 16 && rowsize != 32)
-   rowsize = 16;
-
-   if (len > rowsize)  /* limit to one line at a time */
-   len = rowsize;
if (!is_power_of_2(groupsize) || groupsize > 8)
groupsize = 1;
if ((len % groupsize) != 0) /* no mixed size output */
groupsize = 1;
 
+   if (rowsize % groupsize)
+   rowsize -= rowsize % groupsize;
+
+   if (len > rowsize)  /* limit to one line at a time */
+   len = rowsize;
+
ngroups = len / groupsize;
ascii_column = rowsize * 2 + rowsize / groupsize + 1;
 
@@ -216,7 +219,7 @@ EXPORT_SYMBOL(hex_dump_to_buffer);
  *  caller supplies trailing spaces for alignment if desired
  * @prefix_type: controls whether prefix of an offset, address, or none
  *  is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE)
- * @rowsize: number of bytes to print per line; must be 16 or 32
+ * @rowsize: number of bytes to print per line; must be a multiple of groupsize
  * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
  * @buf: data blob to dump
  * @len: number of bytes in the @buf
@@ -226,10 +229,9 @@ EXPORT_SYMBOL(hex_dump_to_buffer);
  * to the kernel log at the specified kernel log level, with an optional
  * leading prefix.
  *
- * print_hex_dump() works on one "line" of output at a time, i.e.,
- * 16 or 32 bytes of input data converted to hex + ASCII output.
  * print_hex_dump() iterates over the entire input @buf, breaking it into
- * "line size" chunks to format and print.
+ * lines of rowsize/groupsize groups of input data converted to hex +
+ * (optionally) ASCII output.
  *
  * E.g.:
  *   print_hex_dump(KERN_DEBUG, "raw data: ", DUMP_PREFIX_ADDRESS,
@@ -246,17 +248,30 @@ void print_hex_dump(const char *level, const char 
*prefix_str, int prefix_type,
 {
const u8 *ptr = buf;
int i, linelen, remaining = len;
-   unsigned char linebuf[32 * 3 + 2 + 32 + 1];
+   unsigned char *linebuf;
+   unsigned int linebuf_len;
 
-   if (rowsize != 16 && rowsize != 32)
-   rowsize = 16;
+   if (rowsize % groupsize)
+   rowsize -= rowsize % groupsize;
+
+   /*
+* Worst case line length:
+* 2 hex chars + space per byte in, 2 spaces, 1 char per byte in, NULL
+*/
+   linebuf_len = rowsize * 3 + 2 + rowsize + 1;
+   linebuf = kzalloc(linebuf_len, GFP_KERNEL);
+   if (!linebuf) {
+   printk("%s%shexdump: Could not alloc %u bytes for buffer\n",
+   level, prefix_str, linebuf_len);
+   return;
+   }
 
for (i = 0; i < len; i += rowsize) {
linelen = min(remaining, rowsize);
remaining -= rowsize;
 
hex_dump_to_buf

[PATCH v4 1/7] lib/hexdump.c: Fix selftests

2019-06-24 Thread Alastair D'Silva
From: Alastair D'Silva 

The overflow tests did not account for the situation where no
overflow occurs and len < rowsize.

This patch renames the cryptic variables and accounts for the
above case.

The selftests now pass.

Signed-off-by: Alastair D'Silva 
---
 lib/test_hexdump.c | 48 +++---
 1 file changed, 28 insertions(+), 20 deletions(-)

diff --git a/lib/test_hexdump.c b/lib/test_hexdump.c
index 5144899d3c6b..bef97a964582 100644
--- a/lib/test_hexdump.c
+++ b/lib/test_hexdump.c
@@ -163,45 +163,53 @@ static void __init test_hexdump_overflow(size_t buflen, 
size_t len,
 {
char test[TEST_HEXDUMP_BUF_SIZE];
char buf[TEST_HEXDUMP_BUF_SIZE];
-   int rs = rowsize, gs = groupsize;
-   int ae, he, e, f, r;
-   bool a;
+   int ascii_len, hex_len, expected_len, fill_point, ngroups, rc;
+   bool match;
 
total_tests++;
 
memset(buf, FILL_CHAR, sizeof(buf));
 
-   r = hex_dump_to_buffer(data_b, len, rs, gs, buf, buflen, ascii);
+   rc = hex_dump_to_buffer(data_b, len, rowsize, groupsize, buf, buflen,
+   ascii);
 
/*
 * Caller must provide the data length multiple of groupsize. The
 * calculations below are made with that assumption in mind.
 */
-   ae = rs * 2 /* hex */ + rs / gs /* spaces */ + 1 /* space */ + len /* 
ascii */;
-   he = (gs * 2 /* hex */ + 1 /* space */) * len / gs - 1 /* no trailing 
space */;
+   ngroups = rowsize / groupsize;
+   hex_len = (groupsize * 2 /* hex */ + 1 /* spaces */) * ngroups
+ - 1 /* no trailing space */;
+   ascii_len = hex_len + 2 /* space */ + len /* ascii */;
+
+   if (len < rowsize) {
+   ngroups = len / groupsize;
+   hex_len = (groupsize * 2 /* hex */ + 1 /* spaces */) * ngroups
+ - 1 /* no trailing space */;
+   }
 
-   if (ascii)
-   e = ae;
-   else
-   e = he;
+   expected_len = (ascii) ? ascii_len : hex_len;
 
-   f = min_t(int, e + 1, buflen);
+   fill_point = min_t(int, expected_len + 1, buflen);
if (buflen) {
-   test_hexdump_prepare_test(len, rs, gs, test, sizeof(test), 
ascii);
-   test[f - 1] = '\0';
+   test_hexdump_prepare_test(len, rowsize, groupsize, test,
+ sizeof(test), ascii);
+   test[fill_point - 1] = '\0';
}
-   memset(test + f, FILL_CHAR, sizeof(test) - f);
+   memset(test + fill_point, FILL_CHAR, sizeof(test) - fill_point);
 
-   a = r == e && !memcmp(test, buf, TEST_HEXDUMP_BUF_SIZE);
+   match = rc == expected_len && !memcmp(test, buf, TEST_HEXDUMP_BUF_SIZE);
 
buf[sizeof(buf) - 1] = '\0';
 
-   if (!a) {
-   pr_err("Len: %zu buflen: %zu strlen: %zu\n",
-   len, buflen, strnlen(buf, sizeof(buf)));
-   pr_err("Result: %d '%s'\n", r, buf);
-   pr_err("Expect: %d '%s'\n", e, test);
+   if (!match) {
+   pr_err("rowsize: %u groupsize: %u ascii: %d Len: %zu buflen: 
%zu strlen: %zu\n",
+   rowsize, groupsize, ascii, len, buflen,
+   strnlen(buf, sizeof(buf)));
+   pr_err("Result: %d '%-.*s'\n", rc, (int)buflen, buf);
+   pr_err("Expect: %d '%-.*s'\n", expected_len, (int)buflen, test);
failed_tests++;
+
}
 }
 
-- 
2.21.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v3 0/7] Hexdump Enhancements

2019-06-19 Thread Alastair D'Silva
On Wed, 2019-06-19 at 17:35 -0700, Joe Perches wrote:
> On Thu, 2019-06-20 at 09:15 +1000, Alastair D'Silva wrote:
> > On Wed, 2019-06-19 at 09:31 -0700, Joe Perches wrote:
> > > On Mon, 2019-06-17 at 12:04 +1000, Alastair D'Silva wrote:
> > > > From: Alastair D'Silva 
> > > > 
> > > > Apologies for the large CC list, it's a heads up for those
> > > > responsible
> > > > for subsystems where a prototype change in generic code causes
> > > > a
> > > > change
> > > > in those subsystems.
> > > > 
> > > > This series enhances hexdump.
> > > 
> > > Still not a fan of these patches.
> > 
> > I'm afraid there's not too much action I can take on that, I'm
> > happy to
> > address specific issues though.
> > 
> > > > These improve the readability of the dumped data in certain
> > > > situations
> > > > (eg. wide terminals are available, many lines of empty bytes
> > > > exist,
> > > > etc).
> 
> I think it's generally overkill for the desired uses.

I understand where you're coming from, however, these patches make it a
lot easier to work with large chucks of binary data. I think it makes
more sense to have these patches upstream, even though committed code
may not necessarily have all the features enabled, as it means that
devs won't have to apply out-of-tree patches during development to make
larger dumps manageable.

> 
> > > Changing hexdump's last argument from bool to int is odd.
> > > 
> > 
> > Think of it as replacing a single boolean with many booleans.
> 
> I understand it.  It's odd.
> 
> I would rather not have a mixture of true, false, and apparently
> random collections of bitfields like 0xd or 0b1011 or their
> equivalent or'd defines.
> 

Where's the mixture? What would you propose instead?

-- 
Alastair D'Silva   mob: 0423 762 819
skype: alastair_dsilva
Twitter: @EvilDeece
blog: http://alastair.d-silva.org


___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v3 0/7] Hexdump Enhancements

2019-06-19 Thread Alastair D'Silva
On Wed, 2019-06-19 at 09:31 -0700, Joe Perches wrote:
> On Mon, 2019-06-17 at 12:04 +1000, Alastair D'Silva wrote:
> > From: Alastair D'Silva 
> > 
> > Apologies for the large CC list, it's a heads up for those
> > responsible
> > for subsystems where a prototype change in generic code causes a
> > change
> > in those subsystems.
> > 
> > This series enhances hexdump.
> 
> Still not a fan of these patches.

I'm afraid there's not too much action I can take on that, I'm happy to
address specific issues though.

> 
> > These improve the readability of the dumped data in certain
> > situations
> > (eg. wide terminals are available, many lines of empty bytes exist,
> > etc).
> 
> Changing hexdump's last argument from bool to int is odd.
> 

Think of it as replacing a single boolean with many booleans.

> Perhaps a new function should be added instead of changing
> the existing hexdump.
> 

There's only a handful of consumers, I don't think there is a value-add 
in creating more wrappers vs updating the existing callers.

-- 
Alastair D'Silva   mob: 0423 762 819
skype: alastair_dsilva
Twitter: @EvilDeece
blog: http://alastair.d-silva.org


___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v3 2/7] lib/hexdump.c: Relax rowsize checks in hex_dump_to_buffer

2019-06-17 Thread Alastair D'Silva
On Mon, 2019-06-17 at 15:47 -0700, Randy Dunlap wrote:
> Hi,
> Just a comment style nit below...
> 
> On 6/16/19 7:04 PM, Alastair D'Silva wrote:
> > From: Alastair D'Silva 
> > 
> > This patch removes the hardcoded row limits and allows for
> > other lengths. These lengths must still be a multiple of
> > groupsize.
> > 
> > This allows structs that are not 16/32 bytes to display on
> > a single line.
> > 
> > This patch also expands the self-tests to test row sizes
> > up to 64 bytes (though they can now be arbitrarily long).
> > 
> > Signed-off-by: Alastair D'Silva 
> > ---
> >  lib/hexdump.c  | 48 --
> >  lib/test_hexdump.c | 52 ++--
> > --
> >  2 files changed, 75 insertions(+), 25 deletions(-)
> > 
> > diff --git a/lib/hexdump.c b/lib/hexdump.c
> > index 81b70ed37209..3943507bc0e9 100644
> > --- a/lib/hexdump.c
> > +++ b/lib/hexdump.c
> > @@ -246,17 +248,29 @@ void print_hex_dump(const char *level, const
> > char *prefix_str, int prefix_type,
> >  {
> > const u8 *ptr = buf;
> > int i, linelen, remaining = len;
> > -   unsigned char linebuf[32 * 3 + 2 + 32 + 1];
> > +   unsigned char *linebuf;
> > +   unsigned int linebuf_len;
> >  
> > -   if (rowsize != 16 && rowsize != 32)
> > -   rowsize = 16;
> > +   if (rowsize % groupsize)
> > +   rowsize -= rowsize % groupsize;
> > +
> > +   /* Worst case line length:
> > +* 2 hex chars + space per byte in, 2 spaces, 1 char per byte
> > in, NULL
> > +*/
> 
> According to Documentation/process/coding-style.rst:
> 
> The preferred style for long (multi-line) comments is:
> 
> .. code-block:: c
> 
>   /*
>* This is the preferred style for multi-line
>* comments in the Linux kernel source code.
>* Please use it consistently.
>*
>* Description:  A column of asterisks on the left side,
>* with beginning and ending almost-blank lines.
>*/
> 

Thanks Randy, I'll address this.


-- 
Alastair D'Silva   mob: 0423 762 819
skype: alastair_dsilva
Twitter: @EvilDeece
blog: http://alastair.d-silva.org


___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v3 3/7] lib/hexdump.c: Optionally suppress lines of repeated bytes

2019-06-16 Thread Alastair D'Silva
On Mon, 2019-06-17 at 12:04 +1000, Alastair D'Silva wrote:
> From: Alastair D'Silva 
> 
> Some buffers may only be partially filled with useful data, while the
> rest
> is padded (typically with 0x00 or 0xff).
> 
> This patch introduces a flag to allow the supression of lines of
> repeated
> bytes, which are replaced with '** Skipped %u bytes of value 0x%x **'
> 
> An inline wrapper function is provided for backwards compatibility
> with
> existing code, which maintains the original behaviour.
> 
> Signed-off-by: Alastair D'Silva 
> ---
>  include/linux/printk.h | 25 +---
>  lib/hexdump.c  | 91 --
> 
>  2 files changed, 99 insertions(+), 17 deletions(-)
> 
> diff --git a/include/linux/printk.h b/include/linux/printk.h
> index cefd374c47b1..d7754799cfe0 100644
> --- a/include/linux/printk.h
> +++ b/include/linux/printk.h
> @@ -481,13 +481,18 @@ enum {
>   DUMP_PREFIX_ADDRESS,
>   DUMP_PREFIX_OFFSET
>  };
> +
>  extern int hex_dump_to_buffer(const void *buf, size_t len, int
> rowsize,
> int groupsize, char *linebuf, size_t
> linebuflen,
> bool ascii);
> +
> +#define HEXDUMP_ASCIIBIT(0)
> +#define HEXDUMP_SUPPRESS_REPEATED    BIT(1)
> +

This is missing the include of linux/bits.h, I'll fix this in the next
version.

-- 
Alastair D'Silva   mob: 0423 762 819
skype: alastair_dsilva
Twitter: @EvilDeece
blog: http://alastair.d-silva.org


___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 6/7] lib/hexdump.c: Allow multiple groups to be separated by spaces

2019-06-16 Thread Alastair D'Silva
From: Alastair D'Silva 

Similar to the previous patch, this patch separates groups by 2 spaces for
the hex fields, and 1 space for the ASCII field.

eg.
buf:: 454d414e 43415053  4e495f45 00584544  NAMESPAC E_INDEX.
buf:0010:  0002      

Signed-off-by: Alastair D'Silva 
---
 include/linux/printk.h |  3 ++
 lib/hexdump.c  | 65 +++---
 2 files changed, 52 insertions(+), 16 deletions(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index c6b748f66a82..04416e788802 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -487,6 +487,9 @@ enum {
 #define HEXDUMP_2_GRP_LINESBIT(2)
 #define HEXDUMP_4_GRP_LINESBIT(3)
 #define HEXDUMP_8_GRP_LINESBIT(4)
+#define HEXDUMP_2_GRP_SPACES   BIT(5)
+#define HEXDUMP_4_GRP_SPACES   BIT(6)
+#define HEXDUMP_8_GRP_SPACES   BIT(7)
 
 extern int hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
  int groupsize, char *linebuf, size_t linebuflen,
diff --git a/lib/hexdump.c b/lib/hexdump.c
index 4da7d24826fb..dc85ef0dbb0a 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -91,9 +91,37 @@ static const char *group_separator(int group, u64 flags)
if ((flags & HEXDUMP_2_GRP_LINES) && !((group) % 2))
return "|";
 
+   if ((flags & HEXDUMP_8_GRP_SPACES) && !((group) % 8))
+   return "  ";
+
+   if ((flags & HEXDUMP_4_GRP_SPACES) && !((group) % 4))
+   return "  ";
+
+   if ((flags & HEXDUMP_2_GRP_SPACES) && !((group) % 2))
+   return "  ";
+
return " ";
 }
 
+static void separator_parameters(u64 flags, int groupsize, int *sep_chars,
+char *sep)
+{
+   if (flags & (HEXDUMP_2_GRP_LINES | HEXDUMP_2_GRP_SPACES))
+   *sep_chars = groupsize * 2;
+   if (flags & (HEXDUMP_4_GRP_LINES | HEXDUMP_4_GRP_SPACES))
+   *sep_chars = groupsize * 4;
+   if (flags & (HEXDUMP_8_GRP_LINES | HEXDUMP_8_GRP_SPACES))
+   *sep_chars = groupsize * 8;
+
+   if (flags & (HEXDUMP_2_GRP_LINES | HEXDUMP_4_GRP_LINES |
+  HEXDUMP_8_GRP_LINES))
+   *sep = '|';
+
+   if (flags & (HEXDUMP_2_GRP_SPACES | HEXDUMP_4_GRP_SPACES |
+  HEXDUMP_8_GRP_SPACES))
+   *sep = ' ';
+}
+
 /**
  * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
  * @buf: data blob to dump
@@ -107,6 +135,9 @@ static const char *group_separator(int group, u64 flags)
  * HEXDUMP_2_GRP_LINES:insert a '|' after every 2 groups
  * HEXDUMP_4_GRP_LINES:insert a '|' after every 4 groups
  * HEXDUMP_8_GRP_LINES:insert a '|' after every 8 groups
+ * HEXDUMP_2_GRP_SPACES:   insert a ' ' after every 2 groups
+ * HEXDUMP_4_GRP_SPACES:   insert a ' ' after every 4 groups
+ * HEXDUMP_8_GRP_SPACES:   insert a ' ' after every 8 groups
  *
  * hex_dump_to_buffer() works on one "line" of output at a time, converting
  *  bytes of input to hexadecimal (and optionally printable ASCII)
@@ -138,7 +169,8 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
int j, lx = 0;
int ascii_column;
int ret;
-   int line_chars = 0;
+   int sep_chars = 0;
+   char sep = 0;
 
if (!is_power_of_2(groupsize) || groupsize > 8)
groupsize = 1;
@@ -152,8 +184,14 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
len = rowsize;
 
ngroups = len / groupsize;
+
ascii_column = rowsize * 2 + rowsize / groupsize + 1;
 
+   // space separators use 2 spaces in the hex output
+   separator_parameters(flags, groupsize, _chars, );
+   if (sep == ' ')
+   ascii_column += rowsize / sep_chars;
+
if (!linebuflen)
goto overflow1;
 
@@ -221,24 +259,17 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
linebuf[lx++] = ' ';
}
 
-   if (flags & HEXDUMP_2_GRP_LINES)
-   line_chars = groupsize * 2;
-   if (flags & HEXDUMP_4_GRP_LINES)
-   line_chars = groupsize * 4;
-   if (flags & HEXDUMP_8_GRP_LINES)
-   line_chars = groupsize * 8;
-
for (j = 0; j < len; j++) {
if (linebuflen < lx + 2)
goto overflow2;
ch = ptr[j];
linebuf[lx++] = (isascii(ch) && isprint(ch)) ? ch : '.';
 
-   if (line_chars && ((j + 1) < len) &&
-   ((j + 

[PATCH v3 5/7] lib/hexdump.c: Allow multiple groups to be separated by lines '|'

2019-06-16 Thread Alastair D'Silva
From: Alastair D'Silva 

With the wider display format, it can become hard to identify how many
bytes into the line you are looking at.

The patch adds new flags to hex_dump_to_buffer() and print_hex_dump() to
print vertical lines to separate every N groups of bytes.

eg.
buf:: 454d414e 43415053|4e495f45 00584544  NAMESPAC|E_INDEX.
buf:0010:  0002|   |

Signed-off-by: Alastair D'Silva 
---
 include/linux/printk.h |  3 +++
 lib/hexdump.c  | 59 --
 2 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index 97dd29a2bd77..c6b748f66a82 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -484,6 +484,9 @@ enum {
 
 #define HEXDUMP_ASCII  BIT(0)
 #define HEXDUMP_SUPPRESS_REPEATED  BIT(1)
+#define HEXDUMP_2_GRP_LINESBIT(2)
+#define HEXDUMP_4_GRP_LINESBIT(3)
+#define HEXDUMP_8_GRP_LINESBIT(4)
 
 extern int hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
  int groupsize, char *linebuf, size_t linebuflen,
diff --git a/lib/hexdump.c b/lib/hexdump.c
index 08c6084d7daa..4da7d24826fb 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -77,6 +77,23 @@ char *bin2hex(char *dst, const void *src, size_t count)
 }
 EXPORT_SYMBOL(bin2hex);
 
+static const char *group_separator(int group, u64 flags)
+{
+   if (group == 0)
+   return " ";
+
+   if ((flags & HEXDUMP_8_GRP_LINES) && !((group) % 8))
+   return "|";
+
+   if ((flags & HEXDUMP_4_GRP_LINES) && !((group) % 4))
+   return "|";
+
+   if ((flags & HEXDUMP_2_GRP_LINES) && !((group) % 2))
+   return "|";
+
+   return " ";
+}
+
 /**
  * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
  * @buf: data blob to dump
@@ -87,6 +104,9 @@ EXPORT_SYMBOL(bin2hex);
  * @linebuflen: total size of @linebuf, including space for terminating NUL
  * @flags: A bitwise OR of the following flags:
  * HEXDUMP_ASCII:  include ASCII after the hex output
+ * HEXDUMP_2_GRP_LINES:insert a '|' after every 2 groups
+ * HEXDUMP_4_GRP_LINES:insert a '|' after every 4 groups
+ * HEXDUMP_8_GRP_LINES:insert a '|' after every 8 groups
  *
  * hex_dump_to_buffer() works on one "line" of output at a time, converting
  *  bytes of input to hexadecimal (and optionally printable ASCII)
@@ -118,6 +138,7 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
int j, lx = 0;
int ascii_column;
int ret;
+   int line_chars = 0;
 
if (!is_power_of_2(groupsize) || groupsize > 8)
groupsize = 1;
@@ -144,7 +165,8 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
 
for (j = 0; j < ngroups; j++) {
ret = snprintf(linebuf + lx, linebuflen - lx,
-  "%s%16.16llx", j ? " " : "",
+  "%s%16.16llx",
+  j ? group_separator(j, flags) : "",
   get_unaligned(ptr8 + j));
if (ret >= linebuflen - lx)
goto overflow1;
@@ -155,7 +177,8 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
 
for (j = 0; j < ngroups; j++) {
ret = snprintf(linebuf + lx, linebuflen - lx,
-  "%s%8.8x", j ? " " : "",
+  "%s%8.8x",
+  j ? group_separator(j, flags) : "",
   get_unaligned(ptr4 + j));
if (ret >= linebuflen - lx)
goto overflow1;
@@ -166,7 +189,8 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
 
for (j = 0; j < ngroups; j++) {
ret = snprintf(linebuf + lx, linebuflen - lx,
-  "%s%4.4x", j ? " " : "",
+  "%s%4.4x",
+  j ? group_separator(j, flags) : "",
   get_unaligned(ptr2 + j));
if (ret >= linebuflen - lx)
goto overflow1;
@@ -196,11 +220,26 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
goto overflow2;
 

[PATCH v3 7/7] lib/hexdump.c: Optionally retain byte ordering

2019-06-16 Thread Alastair D'Silva
From: Alastair D'Silva 

The behaviour of hexdump groups is to print the data out as if
it was a native-endian number.

This patch tweaks the documentation to make this clear, and also
adds the HEXDUMP_RETAIN_BYTE_ORDER flag to allow groups of
multiple bytes to be printed without affecting the ordering
of the printed bytes.

Signed-off-by: Alastair D'Silva 
---
 include/linux/printk.h |  1 +
 lib/hexdump.c  | 30 +
 lib/test_hexdump.c | 60 +-
 3 files changed, 68 insertions(+), 23 deletions(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index 04416e788802..ffc94bedd737 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -490,6 +490,7 @@ enum {
 #define HEXDUMP_2_GRP_SPACES   BIT(5)
 #define HEXDUMP_4_GRP_SPACES   BIT(6)
 #define HEXDUMP_8_GRP_SPACES   BIT(7)
+#define HEXDUMP_RETAIN_BYTE_ORDER  BIT(8)
 
 extern int hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
  int groupsize, char *linebuf, size_t linebuflen,
diff --git a/lib/hexdump.c b/lib/hexdump.c
index dc85ef0dbb0a..ce14abc7701f 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -127,7 +127,8 @@ static void separator_parameters(u64 flags, int groupsize, 
int *sep_chars,
  * @buf: data blob to dump
  * @len: number of bytes in the @buf
  * @rowsize: number of bytes to print per line; must be a multiple of groupsize
- * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
+ * @groupsize: number of bytes to convert to a native endian number and print:
+ *1, 2, 4, 8; default = 1
  * @linebuf: where to put the converted data
  * @linebuflen: total size of @linebuf, including space for terminating NUL
  * @flags: A bitwise OR of the following flags:
@@ -138,6 +139,9 @@ static void separator_parameters(u64 flags, int groupsize, 
int *sep_chars,
  * HEXDUMP_2_GRP_SPACES:   insert a ' ' after every 2 groups
  * HEXDUMP_4_GRP_SPACES:   insert a ' ' after every 4 groups
  * HEXDUMP_8_GRP_SPACES:   insert a ' ' after every 8 groups
+ * HEXDUMP_RETAIN_BYTE_ORDER:  Retain the byte ordering of groups
+ * instead of treating each group as a
+ * native-endian number
  *
  * hex_dump_to_buffer() works on one "line" of output at a time, converting
  *  bytes of input to hexadecimal (and optionally printable ASCII)
@@ -171,6 +175,7 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
int ret;
int sep_chars = 0;
char sep = 0;
+   bool big_endian = (flags & HEXDUMP_RETAIN_BYTE_ORDER) ? 1 : 0;
 
if (!is_power_of_2(groupsize) || groupsize > 8)
groupsize = 1;
@@ -202,10 +207,13 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
const u64 *ptr8 = buf;
 
for (j = 0; j < ngroups; j++) {
+   u64 val = big_endian ?
+   be64_to_cpu(get_unaligned(ptr8 + j)) :
+   get_unaligned(ptr8 + j);
ret = snprintf(linebuf + lx, linebuflen - lx,
   "%s%16.16llx",
   j ? group_separator(j, flags) : "",
-  get_unaligned(ptr8 + j));
+  val);
if (ret >= linebuflen - lx)
goto overflow1;
lx += ret;
@@ -214,10 +222,14 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
const u32 *ptr4 = buf;
 
for (j = 0; j < ngroups; j++) {
+   u32 val = big_endian ?
+   be32_to_cpu(get_unaligned(ptr4 + j)) :
+   get_unaligned(ptr4 + j);
+
ret = snprintf(linebuf + lx, linebuflen - lx,
   "%s%8.8x",
   j ? group_separator(j, flags) : "",
-  get_unaligned(ptr4 + j));
+  val);
if (ret >= linebuflen - lx)
goto overflow1;
lx += ret;
@@ -226,10 +238,14 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
const u16 *ptr2 = buf;
 
for (j = 0; j < ngroups; j++) {
+   u16 val = big_endian ?
+   be16_to_cpu(get_unaligned(ptr2 + j)) :
+   get_unaligned(ptr2 + j);
+
ret = snprintf(linebu

[PATCH v3 2/7] lib/hexdump.c: Relax rowsize checks in hex_dump_to_buffer

2019-06-16 Thread Alastair D'Silva
From: Alastair D'Silva 

This patch removes the hardcoded row limits and allows for
other lengths. These lengths must still be a multiple of
groupsize.

This allows structs that are not 16/32 bytes to display on
a single line.

This patch also expands the self-tests to test row sizes
up to 64 bytes (though they can now be arbitrarily long).

Signed-off-by: Alastair D'Silva 
---
 lib/hexdump.c  | 48 --
 lib/test_hexdump.c | 52 ++
 2 files changed, 75 insertions(+), 25 deletions(-)

diff --git a/lib/hexdump.c b/lib/hexdump.c
index 81b70ed37209..3943507bc0e9 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 const char hex_asc[] = "0123456789abcdef";
@@ -80,14 +81,15 @@ EXPORT_SYMBOL(bin2hex);
  * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
  * @buf: data blob to dump
  * @len: number of bytes in the @buf
- * @rowsize: number of bytes to print per line; must be 16 or 32
+ * @rowsize: number of bytes to print per line; must be a multiple of groupsize
  * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
  * @linebuf: where to put the converted data
  * @linebuflen: total size of @linebuf, including space for terminating NUL
  * @ascii: include ASCII after the hex output
  *
- * hex_dump_to_buffer() works on one "line" of output at a time, i.e.,
- * 16 or 32 bytes of input data converted to hex + ASCII output.
+ * hex_dump_to_buffer() works on one "line" of output at a time, converting
+ *  bytes of input to hexadecimal (and optionally printable ASCII)
+ * until  bytes have been emitted.
  *
  * Given a buffer of u8 data, hex_dump_to_buffer() converts the input data
  * to a hex + ASCII dump at the supplied memory location.
@@ -116,16 +118,17 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
int ascii_column;
int ret;
 
-   if (rowsize != 16 && rowsize != 32)
-   rowsize = 16;
-
-   if (len > rowsize)  /* limit to one line at a time */
-   len = rowsize;
if (!is_power_of_2(groupsize) || groupsize > 8)
groupsize = 1;
if ((len % groupsize) != 0) /* no mixed size output */
groupsize = 1;
 
+   if (rowsize % groupsize)
+   rowsize -= rowsize % groupsize;
+
+   if (len > rowsize)  /* limit to one line at a time */
+   len = rowsize;
+
ngroups = len / groupsize;
ascii_column = rowsize * 2 + rowsize / groupsize + 1;
 
@@ -216,7 +219,7 @@ EXPORT_SYMBOL(hex_dump_to_buffer);
  *  caller supplies trailing spaces for alignment if desired
  * @prefix_type: controls whether prefix of an offset, address, or none
  *  is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE)
- * @rowsize: number of bytes to print per line; must be 16 or 32
+ * @rowsize: number of bytes to print per line; must be a multiple of groupsize
  * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
  * @buf: data blob to dump
  * @len: number of bytes in the @buf
@@ -226,10 +229,9 @@ EXPORT_SYMBOL(hex_dump_to_buffer);
  * to the kernel log at the specified kernel log level, with an optional
  * leading prefix.
  *
- * print_hex_dump() works on one "line" of output at a time, i.e.,
- * 16 or 32 bytes of input data converted to hex + ASCII output.
  * print_hex_dump() iterates over the entire input @buf, breaking it into
- * "line size" chunks to format and print.
+ * lines of rowsize/groupsize groups of input data converted to hex +
+ * (optionally) ASCII output.
  *
  * E.g.:
  *   print_hex_dump(KERN_DEBUG, "raw data: ", DUMP_PREFIX_ADDRESS,
@@ -246,17 +248,29 @@ void print_hex_dump(const char *level, const char 
*prefix_str, int prefix_type,
 {
const u8 *ptr = buf;
int i, linelen, remaining = len;
-   unsigned char linebuf[32 * 3 + 2 + 32 + 1];
+   unsigned char *linebuf;
+   unsigned int linebuf_len;
 
-   if (rowsize != 16 && rowsize != 32)
-   rowsize = 16;
+   if (rowsize % groupsize)
+   rowsize -= rowsize % groupsize;
+
+   /* Worst case line length:
+* 2 hex chars + space per byte in, 2 spaces, 1 char per byte in, NULL
+*/
+   linebuf_len = rowsize * 3 + 2 + rowsize + 1;
+   linebuf = kzalloc(linebuf_len, GFP_KERNEL);
+   if (!linebuf) {
+   printk("%s%shexdump: Could not alloc %u bytes for buffer\n",
+   level, prefix_str, linebuf_len);
+   return;
+   }
 
for (i = 0; i < len; i += rowsize) {
linelen = min(remaining, rowsize);
remaining -= rowsize;
 
hex_dump_to_buf

[PATCH v3 4/7] lib/hexdump.c: Replace ascii bool in hex_dump_to_buffer with flags

2019-06-16 Thread Alastair D'Silva
From: Alastair D'Silva 

In order to support additional features in hex_dump_to_buffer, replace
the ascii bool parameter with flags.

Signed-off-by: Alastair D'Silva 
---
 drivers/gpu/drm/i915/intel_engine_cs.c|  2 +-
 drivers/isdn/hardware/mISDN/mISDNisar.c   |  6 --
 drivers/mailbox/mailbox-test.c|  2 +-
 drivers/net/ethernet/amd/xgbe/xgbe-drv.c  |  2 +-
 drivers/net/ethernet/synopsys/dwc-xlgmac-common.c |  2 +-
 drivers/net/wireless/ath/ath10k/debug.c   |  3 ++-
 drivers/net/wireless/intel/iwlegacy/3945-mac.c|  2 +-
 drivers/platform/chrome/wilco_ec/debugfs.c|  2 +-
 drivers/scsi/scsi_logging.c   |  8 +++-
 drivers/staging/fbtft/fbtft-core.c|  2 +-
 fs/seq_file.c |  3 ++-
 include/linux/printk.h|  8 
 lib/hexdump.c | 15 ---
 lib/test_hexdump.c|  5 +++--
 14 files changed, 33 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c 
b/drivers/gpu/drm/i915/intel_engine_cs.c
index eea9bec04f1b..5df5fffdb848 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -1340,7 +1340,7 @@ static void hexdump(struct drm_printer *m, const void 
*buf, size_t len)
WARN_ON_ONCE(hex_dump_to_buffer(buf + pos, len - pos,
rowsize, sizeof(u32),
line, sizeof(line),
-   false) >= sizeof(line));
+   0) >= sizeof(line));
drm_printf(m, "[%04zx] %s\n", pos, line);
 
prev = buf + pos;
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c 
b/drivers/isdn/hardware/mISDN/mISDNisar.c
index fd5c52f37802..ccc0ee9d894f 100644
--- a/drivers/isdn/hardware/mISDN/mISDNisar.c
+++ b/drivers/isdn/hardware/mISDN/mISDNisar.c
@@ -71,7 +71,8 @@ send_mbox(struct isar_hw *isar, u8 his, u8 creg, u8 len, u8 
*msg)
 
while (l < (int)len) {
hex_dump_to_buffer(msg + l, len - l, 32, 1,
-  isar->log, 256, 1);
+  isar->log, 256,
+  HEXDUMP_ASCII);
pr_debug("%s: %s %02x: %s\n", isar->name,
 __func__, l, isar->log);
l += 32;
@@ -100,7 +101,8 @@ rcv_mbox(struct isar_hw *isar, u8 *msg)
 
while (l < (int)isar->clsb) {
hex_dump_to_buffer(msg + l, isar->clsb - l, 32,
-  1, isar->log, 256, 1);
+  1, isar->log, 256,
+  HEXDUMP_ASCII);
pr_debug("%s: %s %02x: %s\n", isar->name,
 __func__, l, isar->log);
l += 32;
diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c
index 4555d678fadd..23c3fbafdcb2 100644
--- a/drivers/mailbox/mailbox-test.c
+++ b/drivers/mailbox/mailbox-test.c
@@ -209,7 +209,7 @@ static ssize_t mbox_test_message_read(struct file *filp, 
char __user *userbuf,
hex_dump_to_buffer(ptr,
   MBOX_BYTES_PER_LINE,
   MBOX_BYTES_PER_LINE, 1, touser + l,
-  MBOX_HEXDUMP_LINE_LEN, true);
+  MBOX_HEXDUMP_LINE_LEN, HEXDUMP_ASCII);
 
ptr += MBOX_BYTES_PER_LINE;
l += MBOX_HEXDUMP_LINE_LEN;
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c 
b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index 3dd0cecddba8..1e26410cf6c2 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -2992,7 +2992,7 @@ void xgbe_print_pkt(struct net_device *netdev, struct 
sk_buff *skb, bool tx_rx)
unsigned int len = min(skb->len - i, 32U);
 
hex_dump_to_buffer(>data[i], len, 32, 1,
-  buffer, sizeof(buffer), false);
+  buffer, sizeof(buffer), 0);
netdev_dbg(netdev, "  %#06x: %s\n", i, buffer);
}
 
diff --git a/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c 
b/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c
index eb1c6b03c329..b80adfa1f890 100644
--- a/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c
+++ b/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c
@@ -349,7 +349,7 @@ void xlgmac_

[PATCH v3 1/7] lib/hexdump.c: Fix selftests

2019-06-16 Thread Alastair D'Silva
From: Alastair D'Silva 

The overflow tests did not account for the situation where no
overflow occurs and len < rowsize.

This patch renames the cryptic variables and accounts for the
above case.

The selftests now pass.

Signed-off-by: Alastair D'Silva 
---
 lib/test_hexdump.c | 47 ++
 1 file changed, 27 insertions(+), 20 deletions(-)

diff --git a/lib/test_hexdump.c b/lib/test_hexdump.c
index 5144899d3c6b..d78ddd62ffd0 100644
--- a/lib/test_hexdump.c
+++ b/lib/test_hexdump.c
@@ -163,45 +163,52 @@ static void __init test_hexdump_overflow(size_t buflen, 
size_t len,
 {
char test[TEST_HEXDUMP_BUF_SIZE];
char buf[TEST_HEXDUMP_BUF_SIZE];
-   int rs = rowsize, gs = groupsize;
-   int ae, he, e, f, r;
-   bool a;
+   int ascii_len, hex_len, expected_len, fill_point, ngroups, rc;
+   bool match;
 
total_tests++;
 
memset(buf, FILL_CHAR, sizeof(buf));
 
-   r = hex_dump_to_buffer(data_b, len, rs, gs, buf, buflen, ascii);
+   rc = hex_dump_to_buffer(data_b, len, rowsize, groupsize, buf, buflen, 
ascii);
 
/*
 * Caller must provide the data length multiple of groupsize. The
 * calculations below are made with that assumption in mind.
 */
-   ae = rs * 2 /* hex */ + rs / gs /* spaces */ + 1 /* space */ + len /* 
ascii */;
-   he = (gs * 2 /* hex */ + 1 /* space */) * len / gs - 1 /* no trailing 
space */;
+   ngroups = rowsize / groupsize;
+   hex_len = (groupsize * 2 /* hex */ + 1 /* spaces */) * ngroups
+ - 1 /* no trailing space */;
+   ascii_len = hex_len + 2 /* space */ + len /* ascii */;
+
+   if (len < rowsize) {
+   ngroups = len / groupsize;
+   hex_len = (groupsize * 2 /* hex */ + 1 /* spaces */) * ngroups
+ - 1 /* no trailing space */;
+   }
 
-   if (ascii)
-   e = ae;
-   else
-   e = he;
+   expected_len = (ascii) ? ascii_len : hex_len;
 
-   f = min_t(int, e + 1, buflen);
+   fill_point = min_t(int, expected_len + 1, buflen);
if (buflen) {
-   test_hexdump_prepare_test(len, rs, gs, test, sizeof(test), 
ascii);
-   test[f - 1] = '\0';
+   test_hexdump_prepare_test(len, rowsize, groupsize, test,
+ sizeof(test), ascii);
+   test[fill_point - 1] = '\0';
}
-   memset(test + f, FILL_CHAR, sizeof(test) - f);
+   memset(test + fill_point, FILL_CHAR, sizeof(test) - fill_point);
 
-   a = r == e && !memcmp(test, buf, TEST_HEXDUMP_BUF_SIZE);
+   match = rc == expected_len && !memcmp(test, buf, TEST_HEXDUMP_BUF_SIZE);
 
buf[sizeof(buf) - 1] = '\0';
 
-   if (!a) {
-   pr_err("Len: %zu buflen: %zu strlen: %zu\n",
-   len, buflen, strnlen(buf, sizeof(buf)));
-   pr_err("Result: %d '%s'\n", r, buf);
-   pr_err("Expect: %d '%s'\n", e, test);
+   if (!match) {
+   pr_err("rowsize: %u groupsize: %u ascii: %d Len: %zu buflen: 
%zu strlen: %zu\n",
+   rowsize, groupsize, ascii, len, buflen,
+   strnlen(buf, sizeof(buf)));
+   pr_err("Result: %d '%-.*s'\n", rc, (int)buflen, buf);
+   pr_err("Expect: %d '%-.*s'\n", expected_len, (int)buflen, test);
failed_tests++;
+
}
 }
 
-- 
2.21.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 3/7] lib/hexdump.c: Optionally suppress lines of repeated bytes

2019-06-16 Thread Alastair D'Silva
From: Alastair D'Silva 

Some buffers may only be partially filled with useful data, while the rest
is padded (typically with 0x00 or 0xff).

This patch introduces a flag to allow the supression of lines of repeated
bytes, which are replaced with '** Skipped %u bytes of value 0x%x **'

An inline wrapper function is provided for backwards compatibility with
existing code, which maintains the original behaviour.

Signed-off-by: Alastair D'Silva 
---
 include/linux/printk.h | 25 +---
 lib/hexdump.c  | 91 --
 2 files changed, 99 insertions(+), 17 deletions(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index cefd374c47b1..d7754799cfe0 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -481,13 +481,18 @@ enum {
DUMP_PREFIX_ADDRESS,
DUMP_PREFIX_OFFSET
 };
+
 extern int hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
  int groupsize, char *linebuf, size_t linebuflen,
  bool ascii);
+
+#define HEXDUMP_ASCII  BIT(0)
+#define HEXDUMP_SUPPRESS_REPEATED  BIT(1)
+
 #ifdef CONFIG_PRINTK
-extern void print_hex_dump(const char *level, const char *prefix_str,
+extern void print_hex_dump_ext(const char *level, const char *prefix_str,
   int prefix_type, int rowsize, int groupsize,
-  const void *buf, size_t len, bool ascii);
+  const void *buf, size_t len, u32 flags);
 #if defined(CONFIG_DYNAMIC_DEBUG)
 #define print_hex_dump_bytes(prefix_str, prefix_type, buf, len)\
dynamic_hex_dump(prefix_str, prefix_type, 16, 1, buf, len, true)
@@ -496,18 +501,28 @@ extern void print_hex_dump_bytes(const char *prefix_str, 
int prefix_type,
 const void *buf, size_t len);
 #endif /* defined(CONFIG_DYNAMIC_DEBUG) */
 #else
-static inline void print_hex_dump(const char *level, const char *prefix_str,
+static inline void print_hex_dump_ext(const char *level, const char 
*prefix_str,
  int prefix_type, int rowsize, int groupsize,
- const void *buf, size_t len, bool ascii)
+ const void *buf, size_t len, u32 flags)
 {
 }
 static inline void print_hex_dump_bytes(const char *prefix_str, int 
prefix_type,
const void *buf, size_t len)
 {
 }
-
 #endif
 
+static __always_inline void print_hex_dump(const char *level,
+  const char *prefix_str,
+  int prefix_type, int rowsize,
+  int groupsize, const void *buf,
+  size_t len, bool ascii)
+{
+   print_hex_dump_ext(level, prefix_str, prefix_type, rowsize, groupsize,
+   buf, len, ascii ? HEXDUMP_ASCII : 0);
+}
+
+
 #if defined(CONFIG_DYNAMIC_DEBUG)
 #define print_hex_dump_debug(prefix_str, prefix_type, rowsize, \
 groupsize, buf, len, ascii)\
diff --git a/lib/hexdump.c b/lib/hexdump.c
index 3943507bc0e9..b781f84e 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -212,8 +212,44 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
 EXPORT_SYMBOL(hex_dump_to_buffer);
 
 #ifdef CONFIG_PRINTK
+
+/**
+ * buf_is_all - Check if a buffer contains only a single byte value
+ * @buf: pointer to the buffer
+ * @len: the size of the buffer in bytes
+ * @val: outputs the value if if the bytes are identical
+ */
+static bool buf_is_all(const u8 *buf, size_t len, u8 *val_out)
+{
+   size_t i;
+   u8 val;
+
+   if (len <= 1)
+   return false;
+
+   val = buf[0];
+
+   for (i = 1; i < len; i++) {
+   if (buf[i] != val)
+   return false;
+   }
+
+   *val_out = val;
+   return true;
+}
+
+static void announce_skipped(const char *level, const char *prefix_str,
+  u8 val, size_t count)
+{
+   if (count == 0)
+   return;
+
+   printk("%s%s ** Skipped %lu bytes of value 0x%x **\n",
+  level, prefix_str, count, val);
+}
+
 /**
- * print_hex_dump - print a text hex dump to syslog for a binary blob of data
+ * print_hex_dump_ext - dump a binary blob of data to syslog in hexadecimal
  * @level: kernel log level (e.g. KERN_DEBUG)
  * @prefix_str: string to prefix each line with;
  *  caller supplies trailing spaces for alignment if desired
@@ -224,6 +260,10 @@ EXPORT_SYMBOL(hex_dump_to_buffer);
  * @buf: data blob to dump
  * @len: number of bytes in the @buf
  * @ascii: include ASCII after the hex output
+ * @flags: A bitwise OR of the following flags:
+ * HEXDUMP_ASCII:  include ASCII after the hex output
+ * HEXDUMP_SUPPRESS_REPEATED:  suppress repeated li

[PATCH v3 0/7] Hexdump Enhancements

2019-06-16 Thread Alastair D'Silva
From: Alastair D'Silva 

Apologies for the large CC list, it's a heads up for those responsible
for subsystems where a prototype change in generic code causes a change
in those subsystems.

This series enhances hexdump.

These improve the readability of the dumped data in certain situations
(eg. wide terminals are available, many lines of empty bytes exist, etc).

The default behaviour of hexdump is unchanged, however, the prototype
for hex_dump_to_buffer() has changed, and print_hex_dump() has been
renamed to print_hex_dump_ext(), with a wrapper replacing it for
compatibility with existing code, which would have been too invasive to
change.

Hexdump selftests have be run & confirmed passed.

Changelog:
V3:
 - Fix inline documention
 - use BIT macros
 - use u32 rather than u64 for flags
V2:
 - Fix failing selftests
 - Fix precedence bug in 'Replace ascii bool in hex_dump_to_buffer...'
 - Remove hardcoded new lengths & instead relax the checks in
   hex_dump_to_buffer, allocating the buffer from the heap instead of the
   stack.
 - Replace the skipping of lines of 0x00/0xff with skipping lines of
   repeated characters, announcing what has been skipped.
 - Add spaces as an optional N-group separator
 - Allow byte ordering to be maintained when HEXDUMP_RETAIN_BYTE_ORDERING
   is set.
 - Updated selftests to cover 'Relax rowsize checks' &
   'Optionally retain byte ordering'

Alastair D'Silva (7):
  lib/hexdump.c: Fix selftests
  lib/hexdump.c: Relax rowsize checks in hex_dump_to_buffer
  lib/hexdump.c: Optionally suppress lines of repeated bytes
  lib/hexdump.c: Replace ascii bool in hex_dump_to_buffer with flags
  lib/hexdump.c: Allow multiple groups to be separated by lines '|'
  lib/hexdump.c: Allow multiple groups to be separated by spaces
  lib/hexdump.c: Optionally retain byte ordering

 drivers/gpu/drm/i915/intel_engine_cs.c|   2 +-
 drivers/isdn/hardware/mISDN/mISDNisar.c   |   6 +-
 drivers/mailbox/mailbox-test.c|   2 +-
 drivers/net/ethernet/amd/xgbe/xgbe-drv.c  |   2 +-
 .../net/ethernet/synopsys/dwc-xlgmac-common.c |   2 +-
 drivers/net/wireless/ath/ath10k/debug.c   |   3 +-
 .../net/wireless/intel/iwlegacy/3945-mac.c|   2 +-
 drivers/platform/chrome/wilco_ec/debugfs.c|   2 +-
 drivers/scsi/scsi_logging.c   |   8 +-
 drivers/staging/fbtft/fbtft-core.c|   2 +-
 fs/seq_file.c |   3 +-
 include/linux/printk.h|  34 ++-
 lib/hexdump.c | 260 +++---
 lib/test_hexdump.c| 146 +++---
 14 files changed, 372 insertions(+), 102 deletions(-)

-- 
2.21.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


RE: [PATCH v2 3/7] lib/hexdump.c: Optionally suppress lines of repeated bytes

2019-05-13 Thread Alastair D'Silva
> -Original Message-
> From: Geert Uytterhoeven 
> Sent: Monday, 13 May 2019 5:01 PM
> To: Alastair D'Silva 
> Cc: alast...@d-silva.org; Jani Nikula ; Joonas
> Lahtinen ; Rodrigo Vivi
> ; David Airlie ; Daniel Vetter
> ; Dan Carpenter ; Karsten
> Keil ; Jassi Brar ; Tom
> Lendacky ; David S. Miller
> ; Jose Abreu ; Kalle
> Valo ; Stanislaw Gruszka ;
> Benson Leung ; Enric Balletbo i Serra
> ; James E.J. Bottomley
> ; Martin K. Petersen ;
> Greg Kroah-Hartman ; Alexander Viro
> ; Petr Mladek ; Sergey
> Senozhatsky ; Steven Rostedt
> ; David Laight ; Andrew
> Morton ; Intel Graphics Development  g...@lists.freedesktop.org>; DRI Development  de...@lists.freedesktop.org>; Linux Kernel Mailing List  ker...@vger.kernel.org>; netdev ;
> ath...@lists.infradead.org; linux-wireless ;
> scsi ; Linux Fbdev development list  fb...@vger.kernel.org>; driverdevel ; Linux
> FS Devel 
> Subject: Re: [PATCH v2 3/7] lib/hexdump.c: Optionally suppress lines of
> repeated bytes
> 
> Hi Alastair,
> 
> Thanks for your patch!

And thanks for your politeness :)

> 
> On Wed, May 8, 2019 at 9:04 AM Alastair D'Silva 
> wrote:
> > From: Alastair D'Silva 
> >
> > Some buffers may only be partially filled with useful data, while the
> > rest is padded (typically with 0x00 or 0xff).
> >
> > This patch introduces a flag to allow the supression of lines of
> > repeated bytes,
> 
> Given print_hex_dump() operates on entities of groupsize (1, 2, 4, or 8)
> bytes, wouldn't it make more sense to consider repeated groups instead of
> repeated bytes?

Maybe, it would mean that subsequent addresses may not be a multiple of rowsize 
though, which is useful.

> > which are replaced with '** Skipped %u bytes of value 0x%x **'
> 
> Using a custom message instead of just "*", like "hexdump" uses, will require
> preprocessing the output when recovering the original binary data by
> feeding it to e.g. "xxd".
> This may sound worse than it is, though, as I never got "xxd" to work without
> preprocessing anyway ;-)

I think showing the details of the skipped values is useful when reading the 
output directly. In situations where binary extracts are desired, the feature 
can always be disabled.

-- 
Alastair D'Silva   mob: 0423 762 819
skype: alastair_dsilva msn: alast...@d-silva.org
blog: http://alastair.d-silva.orgTwitter: @EvilDeece



___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2 3/7] lib/hexdump.c: Optionally suppress lines of repeated bytes

2019-05-09 Thread Alastair D'Silva
On Wed, 2019-05-08 at 17:58 -0700, Randy Dunlap wrote:
> On 5/8/19 12:01 AM, Alastair D'Silva wrote:
> > From: Alastair D'Silva 
> > 
> > Some buffers may only be partially filled with useful data, while
> > the rest
> > is padded (typically with 0x00 or 0xff).
> > 
> > This patch introduces a flag to allow the supression of lines of
> > repeated
> > bytes, which are replaced with '** Skipped %u bytes of value 0x%x
> > **'
> > 
> > An inline wrapper function is provided for backwards compatibility
> > with
> > existing code, which maintains the original behaviour.
> > 
> > Signed-off-by: Alastair D'Silva 
> > ---
> >  include/linux/printk.h | 25 +---
> >  lib/hexdump.c  | 91 
> > --
> >  2 files changed, 99 insertions(+), 17 deletions(-)
> > 
> 
> Hi,
> Did you do "make htmldocs" or something similar on this?
> 
> > diff --git a/lib/hexdump.c b/lib/hexdump.c
> > index 3943507bc0e9..d61a1e4f19fa 100644
> > --- a/lib/hexdump.c
> > +++ b/lib/hexdump.c
> > @@ -212,8 +212,44 @@ int hex_dump_to_buffer(const void *buf, size_t
> > len, int rowsize, int groupsize,
> >  EXPORT_SYMBOL(hex_dump_to_buffer);
> >  
> >  #ifdef CONFIG_PRINTK
> > +
> > +/**
> > + * Check if a buffer contains only a single byte value
> > + * @buf: pointer to the buffer
> > + * @len: the size of the buffer in bytes
> > + * @val: outputs the value if if the bytes are identical
> 
> Does this work without a function name?
> Documentation/doc-guide/kernel-doc.rst says the general format is:
> 
>   /**
>* function_name() - Brief description of function.
>* @arg1: Describe the first argument.
>* @arg2: Describe the second argument.
>*One can provide multiple line descriptions
>*for arguments.
>*
> 
> > + */
> >  /**
> > - * print_hex_dump - print a text hex dump to syslog for a binary
> > blob of data
> > + * print_hex_dump_ext: dump a binary blob of data to syslog in
> > hexadecimal
> 
> Also not in the general documented format.
> 

Thanks Randy, I'll address these.

-- 
Alastair D'Silva   mob: 0423 762 819
skype: alastair_dsilva
Twitter: @EvilDeece
blog: http://alastair.d-silva.org


___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


RE: [PATCH v2 4/7] lib/hexdump.c: Replace ascii bool in hex_dump_to_buffer with flags

2019-05-08 Thread Alastair D'Silva
> -Original Message-
> From: David Laight 
> Sent: Wednesday, 8 May 2019 7:20 PM
> To: 'Alastair D'Silva' ; alast...@d-silva.org
> Cc: Jani Nikula ; Joonas Lahtinen
> ; Rodrigo Vivi ;
> David Airlie ; Daniel Vetter ; Dan
> Carpenter ; Karsten Keil  pingi.de>; Jassi Brar ; Tom Lendacky
> ; David S. Miller ;
> Jose Abreu ; Kalle Valo
> ; Stanislaw Gruszka ;
> Benson Leung ; Enric Balletbo i Serra
> ; James E.J. Bottomley
> ; Martin K. Petersen ;
> Greg Kroah-Hartman ; Alexander Viro
> ; Petr Mladek ; Sergey
> Senozhatsky ; Steven Rostedt
> ; Andrew Morton ;
> intel-...@lists.freedesktop.org; dri-de...@lists.freedesktop.org; linux-
> ker...@vger.kernel.org; net...@vger.kernel.org;
> ath...@lists.infradead.org; linux-wirel...@vger.kernel.org; linux-
> s...@vger.kernel.org; linux-fb...@vger.kernel.org;
> de...@driverdev.osuosl.org; linux-fsde...@vger.kernel.org
> Subject: RE: [PATCH v2 4/7] lib/hexdump.c: Replace ascii bool in
> hex_dump_to_buffer with flags
> 
> From: Alastair D'Silva
> > Sent: 08 May 2019 08:02
> > To: alast...@d-silva.org
> ...
> > --- a/include/linux/printk.h
> > +++ b/include/linux/printk.h
> > @@ -480,13 +480,13 @@ enum {
> > DUMP_PREFIX_OFFSET
> >  };
> >
> > -extern int hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
> > - int groupsize, char *linebuf, size_t linebuflen,
> > - bool ascii);
> > -
> >  #define HEXDUMP_ASCII  (1 << 0)
> >  #define HEXDUMP_SUPPRESS_REPEATED  (1 << 1)
> 
> These ought to be BIT(0) and BIT(1)

Thanks, I'll address that.

> 
> > +extern int hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
> > + int groupsize, char *linebuf, size_t linebuflen,
> > + u64 flags);
> 
> Why 'u64 flags' ?
> How many flags do you envisage ??
> Your HEXDUMP_ASCII (etc) flags are currently signed values and might get
> sign extended causing grief.
> 'unsigned int flags' is probably sufficient.

I was trying to avoid having to change the prototype again in the future, but 
it's not a big deal, if enough work goes in to require more than 32 bits, it 
can be updated at that point.

> 
> I've not really looked at the code, it seems OTT in places though.

I'll wait for more concrete criticisms here, this it a bit too vague to take 
any action on.

> If someone copies it somewhere where the performance matters (I've user
> space code which is dominated by its tracing!) then you don't want all the
> function calls and conditionals even if you want some of the functionality.

Calling hexdump (even in it's unaltered form) in performance critical code is 
always going to suck. As you mentioned before, it's all based around printf. A 
performance conscious user would be better off building their code around 
hex_asc_hi/lo instead (see lib/vsprintf.c:hex_string).

-- 
Alastair D'Silva   mob: 0423 762 819
skype: alastair_dsilva msn: alast...@d-silva.org
blog: http://alastair.d-silva.orgTwitter: @EvilDeece



___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 7/7] lib/hexdump.c: Optionally retain byte ordering

2019-05-08 Thread Alastair D'Silva
From: Alastair D'Silva 

The behaviour of hexdump groups is to print the data out as if
it was a native-endian number.

This patch tweaks the documentation to make this clear, and also
adds the HEXDUMP_RETAIN_BYTE_ORDER flag to allow groups of
multiple bytes to be printed without affecting the ordering
of the printed bytes.

Signed-off-by: Alastair D'Silva 
---
 include/linux/printk.h |  1 +
 lib/hexdump.c  | 30 +
 lib/test_hexdump.c | 60 +-
 3 files changed, 68 insertions(+), 23 deletions(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index 5231a14e4593..15277d50159c 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -488,6 +488,7 @@ enum {
 #define HEXDUMP_2_GRP_SPACES   (1 << 5)
 #define HEXDUMP_4_GRP_SPACES   (1 << 6)
 #define HEXDUMP_8_GRP_SPACES   (1 << 7)
+#define HEXDUMP_RETAIN_BYTE_ORDER  (1 << 8)
 
 extern int hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
  int groupsize, char *linebuf, size_t linebuflen,
diff --git a/lib/hexdump.c b/lib/hexdump.c
index febd614406d1..bfc9800630ae 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -127,7 +127,8 @@ static void separator_parameters(u64 flags, int groupsize, 
int *sep_chars,
  * @buf: data blob to dump
  * @len: number of bytes in the @buf
  * @rowsize: number of bytes to print per line; must be a multiple of groupsize
- * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
+ * @groupsize: number of bytes to convert to a native endian number and print:
+ *1, 2, 4, 8; default = 1
  * @linebuf: where to put the converted data
  * @linebuflen: total size of @linebuf, including space for terminating NUL
  * @flags: A bitwise OR of the following flags:
@@ -138,6 +139,9 @@ static void separator_parameters(u64 flags, int groupsize, 
int *sep_chars,
  * HEXDUMP_2_GRP_SPACES:   insert a ' ' after every 2 groups
  * HEXDUMP_4_GRP_SPACES:   insert a ' ' after every 4 groups
  * HEXDUMP_8_GRP_SPACES:   insert a ' ' after every 8 groups
+ * HEXDUMP_RETAIN_BYTE_ORDER:  Retain the byte ordering of groups
+ * instead of treating each group as a
+ * native-endian number
  *
  * hex_dump_to_buffer() works on one "line" of output at a time, converting
  *  bytes of input to hexadecimal (and optionally printable ASCII)
@@ -171,6 +175,7 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
int ret;
int sep_chars = 0;
char sep = 0;
+   bool big_endian = (flags & HEXDUMP_RETAIN_BYTE_ORDER) ? 1 : 0;
 
if (!is_power_of_2(groupsize) || groupsize > 8)
groupsize = 1;
@@ -202,10 +207,13 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
const u64 *ptr8 = buf;
 
for (j = 0; j < ngroups; j++) {
+   u64 val = big_endian ?
+   be64_to_cpu(get_unaligned(ptr8 + j)) :
+   get_unaligned(ptr8 + j);
ret = snprintf(linebuf + lx, linebuflen - lx,
   "%s%16.16llx",
   j ? group_separator(j, flags) : "",
-  get_unaligned(ptr8 + j));
+  val);
if (ret >= linebuflen - lx)
goto overflow1;
lx += ret;
@@ -214,10 +222,14 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
const u32 *ptr4 = buf;
 
for (j = 0; j < ngroups; j++) {
+   u32 val = big_endian ?
+   be32_to_cpu(get_unaligned(ptr4 + j)) :
+   get_unaligned(ptr4 + j);
+
ret = snprintf(linebuf + lx, linebuflen - lx,
   "%s%8.8x",
   j ? group_separator(j, flags) : "",
-  get_unaligned(ptr4 + j));
+  val);
if (ret >= linebuflen - lx)
goto overflow1;
lx += ret;
@@ -226,10 +238,14 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
const u16 *ptr2 = buf;
 
for (j = 0; j < ngroups; j++) {
+   u16 val = big_endian ?
+   be16_to_cpu(get_unaligned(ptr2 + j)) :
+   get_unaligned(ptr2 + j);
+

[PATCH v2 6/7] lib/hexdump.c: Allow multiple groups to be separated by spaces

2019-05-08 Thread Alastair D'Silva
From: Alastair D'Silva 

Similar to the previous patch, this patch separates groups by 2 spaces for
the hex fields, and 1 space for the ASCII field.

eg.
buf:: 454d414e 43415053  4e495f45 00584544  NAMESPAC E_INDEX.
buf:0010:  0002      

Signed-off-by: Alastair D'Silva 
---
 include/linux/printk.h |  3 ++
 lib/hexdump.c  | 65 +++---
 2 files changed, 52 insertions(+), 16 deletions(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index dc693aec394c..5231a14e4593 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -485,6 +485,9 @@ enum {
 #define HEXDUMP_2_GRP_LINES(1 << 2)
 #define HEXDUMP_4_GRP_LINES(1 << 3)
 #define HEXDUMP_8_GRP_LINES(1 << 4)
+#define HEXDUMP_2_GRP_SPACES   (1 << 5)
+#define HEXDUMP_4_GRP_SPACES   (1 << 6)
+#define HEXDUMP_8_GRP_SPACES   (1 << 7)
 
 extern int hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
  int groupsize, char *linebuf, size_t linebuflen,
diff --git a/lib/hexdump.c b/lib/hexdump.c
index 6f4d1176c332..febd614406d1 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -91,9 +91,37 @@ static const char *group_separator(int group, u64 flags)
if ((flags & HEXDUMP_2_GRP_LINES) && !((group) % 2))
return "|";
 
+   if ((flags & HEXDUMP_8_GRP_SPACES) && !((group) % 8))
+   return "  ";
+
+   if ((flags & HEXDUMP_4_GRP_SPACES) && !((group) % 4))
+   return "  ";
+
+   if ((flags & HEXDUMP_2_GRP_SPACES) && !((group) % 2))
+   return "  ";
+
return " ";
 }
 
+static void separator_parameters(u64 flags, int groupsize, int *sep_chars,
+char *sep)
+{
+   if (flags & (HEXDUMP_2_GRP_LINES | HEXDUMP_2_GRP_SPACES))
+   *sep_chars = groupsize * 2;
+   if (flags & (HEXDUMP_4_GRP_LINES | HEXDUMP_4_GRP_SPACES))
+   *sep_chars = groupsize * 4;
+   if (flags & (HEXDUMP_8_GRP_LINES | HEXDUMP_8_GRP_SPACES))
+   *sep_chars = groupsize * 8;
+
+   if (flags & (HEXDUMP_2_GRP_LINES | HEXDUMP_4_GRP_LINES |
+  HEXDUMP_8_GRP_LINES))
+   *sep = '|';
+
+   if (flags & (HEXDUMP_2_GRP_SPACES | HEXDUMP_4_GRP_SPACES |
+  HEXDUMP_8_GRP_SPACES))
+   *sep = ' ';
+}
+
 /**
  * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
  * @buf: data blob to dump
@@ -107,6 +135,9 @@ static const char *group_separator(int group, u64 flags)
  * HEXDUMP_2_GRP_LINES:insert a '|' after every 2 groups
  * HEXDUMP_4_GRP_LINES:insert a '|' after every 4 groups
  * HEXDUMP_8_GRP_LINES:insert a '|' after every 8 groups
+ * HEXDUMP_2_GRP_SPACES:   insert a ' ' after every 2 groups
+ * HEXDUMP_4_GRP_SPACES:   insert a ' ' after every 4 groups
+ * HEXDUMP_8_GRP_SPACES:   insert a ' ' after every 8 groups
  *
  * hex_dump_to_buffer() works on one "line" of output at a time, converting
  *  bytes of input to hexadecimal (and optionally printable ASCII)
@@ -138,7 +169,8 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
int j, lx = 0;
int ascii_column;
int ret;
-   int line_chars = 0;
+   int sep_chars = 0;
+   char sep = 0;
 
if (!is_power_of_2(groupsize) || groupsize > 8)
groupsize = 1;
@@ -152,8 +184,14 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
len = rowsize;
 
ngroups = len / groupsize;
+
ascii_column = rowsize * 2 + rowsize / groupsize + 1;
 
+   // space separators use 2 spaces in the hex output
+   separator_parameters(flags, groupsize, _chars, );
+   if (sep == ' ')
+   ascii_column += rowsize / sep_chars;
+
if (!linebuflen)
goto overflow1;
 
@@ -221,24 +259,17 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
linebuf[lx++] = ' ';
}
 
-   if (flags & HEXDUMP_2_GRP_LINES)
-   line_chars = groupsize * 2;
-   if (flags & HEXDUMP_4_GRP_LINES)
-   line_chars = groupsize * 4;
-   if (flags & HEXDUMP_8_GRP_LINES)
-   line_chars = groupsize * 8;
-
for (j = 0; j < len; j++) {
if (linebuflen < lx + 2)
goto overflow2;
ch = ptr[j];
linebuf[lx++] = (isascii(ch) && isprint(ch)) ? ch : '.';
 
-   if (line_chars && ((j + 1) < len) &

[PATCH v2 4/7] lib/hexdump.c: Replace ascii bool in hex_dump_to_buffer with flags

2019-05-08 Thread Alastair D'Silva
From: Alastair D'Silva 

In order to support additional features in hex_dump_to_buffer, replace
the ascii bool parameter with flags.

Signed-off-by: Alastair D'Silva 
---
 drivers/gpu/drm/i915/intel_engine_cs.c|  2 +-
 drivers/isdn/hardware/mISDN/mISDNisar.c   |  6 --
 drivers/mailbox/mailbox-test.c|  2 +-
 drivers/net/ethernet/amd/xgbe/xgbe-drv.c  |  2 +-
 drivers/net/ethernet/synopsys/dwc-xlgmac-common.c |  2 +-
 drivers/net/wireless/ath/ath10k/debug.c   |  3 ++-
 drivers/net/wireless/intel/iwlegacy/3945-mac.c|  2 +-
 drivers/platform/chrome/wilco_ec/debugfs.c|  2 +-
 drivers/scsi/scsi_logging.c   |  8 +++-
 drivers/staging/fbtft/fbtft-core.c|  2 +-
 fs/seq_file.c |  3 ++-
 include/linux/printk.h|  8 
 lib/hexdump.c | 15 ---
 lib/test_hexdump.c|  5 +++--
 14 files changed, 33 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c 
b/drivers/gpu/drm/i915/intel_engine_cs.c
index 49fa43ff02ba..fb133e729f9a 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -1318,7 +1318,7 @@ static void hexdump(struct drm_printer *m, const void 
*buf, size_t len)
WARN_ON_ONCE(hex_dump_to_buffer(buf + pos, len - pos,
rowsize, sizeof(u32),
line, sizeof(line),
-   false) >= sizeof(line));
+   0) >= sizeof(line));
drm_printf(m, "[%04zx] %s\n", pos, line);
 
prev = buf + pos;
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c 
b/drivers/isdn/hardware/mISDN/mISDNisar.c
index 386731ec2489..f13f34db6c17 100644
--- a/drivers/isdn/hardware/mISDN/mISDNisar.c
+++ b/drivers/isdn/hardware/mISDN/mISDNisar.c
@@ -84,7 +84,8 @@ send_mbox(struct isar_hw *isar, u8 his, u8 creg, u8 len, u8 
*msg)
 
while (l < (int)len) {
hex_dump_to_buffer(msg + l, len - l, 32, 1,
-  isar->log, 256, 1);
+  isar->log, 256,
+  HEXDUMP_ASCII);
pr_debug("%s: %s %02x: %s\n", isar->name,
 __func__, l, isar->log);
l += 32;
@@ -113,7 +114,8 @@ rcv_mbox(struct isar_hw *isar, u8 *msg)
 
while (l < (int)isar->clsb) {
hex_dump_to_buffer(msg + l, isar->clsb - l, 32,
-  1, isar->log, 256, 1);
+  1, isar->log, 256,
+  HEXDUMP_ASCII);
pr_debug("%s: %s %02x: %s\n", isar->name,
 __func__, l, isar->log);
l += 32;
diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c
index 4e4ac4be6423..2f9a094d0259 100644
--- a/drivers/mailbox/mailbox-test.c
+++ b/drivers/mailbox/mailbox-test.c
@@ -213,7 +213,7 @@ static ssize_t mbox_test_message_read(struct file *filp, 
char __user *userbuf,
hex_dump_to_buffer(ptr,
   MBOX_BYTES_PER_LINE,
   MBOX_BYTES_PER_LINE, 1, touser + l,
-  MBOX_HEXDUMP_LINE_LEN, true);
+  MBOX_HEXDUMP_LINE_LEN, HEXDUMP_ASCII);
 
ptr += MBOX_BYTES_PER_LINE;
l += MBOX_HEXDUMP_LINE_LEN;
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c 
b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index 0cc911f928b1..e954a31cee0c 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -2992,7 +2992,7 @@ void xgbe_print_pkt(struct net_device *netdev, struct 
sk_buff *skb, bool tx_rx)
unsigned int len = min(skb->len - i, 32U);
 
hex_dump_to_buffer(>data[i], len, 32, 1,
-  buffer, sizeof(buffer), false);
+  buffer, sizeof(buffer), 0);
netdev_dbg(netdev, "  %#06x: %s\n", i, buffer);
}
 
diff --git a/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c 
b/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c
index eb1c6b03c329..b80adfa1f890 100644
--- a/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c
+++ b/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c
@@ -349,7 +349,7 @@ void xlgmac_

[PATCH v2 2/7] lib/hexdump.c: Relax rowsize checks in hex_dump_to_buffer

2019-05-08 Thread Alastair D'Silva
From: Alastair D'Silva 

This patch removes the hardcoded row limits and allows for
other lengths. These lengths must still be a multiple of
groupsize.

This allows structs that are not 16/32 bytes to display on
a single line.

This patch also expands the self-tests to test row sizes
up to 64 bytes (though they can now be arbitrarily long).

Signed-off-by: Alastair D'Silva 
---
 lib/hexdump.c  | 48 --
 lib/test_hexdump.c | 52 ++
 2 files changed, 75 insertions(+), 25 deletions(-)

diff --git a/lib/hexdump.c b/lib/hexdump.c
index 81b70ed37209..3943507bc0e9 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 const char hex_asc[] = "0123456789abcdef";
@@ -80,14 +81,15 @@ EXPORT_SYMBOL(bin2hex);
  * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
  * @buf: data blob to dump
  * @len: number of bytes in the @buf
- * @rowsize: number of bytes to print per line; must be 16 or 32
+ * @rowsize: number of bytes to print per line; must be a multiple of groupsize
  * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
  * @linebuf: where to put the converted data
  * @linebuflen: total size of @linebuf, including space for terminating NUL
  * @ascii: include ASCII after the hex output
  *
- * hex_dump_to_buffer() works on one "line" of output at a time, i.e.,
- * 16 or 32 bytes of input data converted to hex + ASCII output.
+ * hex_dump_to_buffer() works on one "line" of output at a time, converting
+ *  bytes of input to hexadecimal (and optionally printable ASCII)
+ * until  bytes have been emitted.
  *
  * Given a buffer of u8 data, hex_dump_to_buffer() converts the input data
  * to a hex + ASCII dump at the supplied memory location.
@@ -116,16 +118,17 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
int ascii_column;
int ret;
 
-   if (rowsize != 16 && rowsize != 32)
-   rowsize = 16;
-
-   if (len > rowsize)  /* limit to one line at a time */
-   len = rowsize;
if (!is_power_of_2(groupsize) || groupsize > 8)
groupsize = 1;
if ((len % groupsize) != 0) /* no mixed size output */
groupsize = 1;
 
+   if (rowsize % groupsize)
+   rowsize -= rowsize % groupsize;
+
+   if (len > rowsize)  /* limit to one line at a time */
+   len = rowsize;
+
ngroups = len / groupsize;
ascii_column = rowsize * 2 + rowsize / groupsize + 1;
 
@@ -216,7 +219,7 @@ EXPORT_SYMBOL(hex_dump_to_buffer);
  *  caller supplies trailing spaces for alignment if desired
  * @prefix_type: controls whether prefix of an offset, address, or none
  *  is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE)
- * @rowsize: number of bytes to print per line; must be 16 or 32
+ * @rowsize: number of bytes to print per line; must be a multiple of groupsize
  * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
  * @buf: data blob to dump
  * @len: number of bytes in the @buf
@@ -226,10 +229,9 @@ EXPORT_SYMBOL(hex_dump_to_buffer);
  * to the kernel log at the specified kernel log level, with an optional
  * leading prefix.
  *
- * print_hex_dump() works on one "line" of output at a time, i.e.,
- * 16 or 32 bytes of input data converted to hex + ASCII output.
  * print_hex_dump() iterates over the entire input @buf, breaking it into
- * "line size" chunks to format and print.
+ * lines of rowsize/groupsize groups of input data converted to hex +
+ * (optionally) ASCII output.
  *
  * E.g.:
  *   print_hex_dump(KERN_DEBUG, "raw data: ", DUMP_PREFIX_ADDRESS,
@@ -246,17 +248,29 @@ void print_hex_dump(const char *level, const char 
*prefix_str, int prefix_type,
 {
const u8 *ptr = buf;
int i, linelen, remaining = len;
-   unsigned char linebuf[32 * 3 + 2 + 32 + 1];
+   unsigned char *linebuf;
+   unsigned int linebuf_len;
 
-   if (rowsize != 16 && rowsize != 32)
-   rowsize = 16;
+   if (rowsize % groupsize)
+   rowsize -= rowsize % groupsize;
+
+   /* Worst case line length:
+* 2 hex chars + space per byte in, 2 spaces, 1 char per byte in, NULL
+*/
+   linebuf_len = rowsize * 3 + 2 + rowsize + 1;
+   linebuf = kzalloc(linebuf_len, GFP_KERNEL);
+   if (!linebuf) {
+   printk("%s%shexdump: Could not alloc %u bytes for buffer\n",
+   level, prefix_str, linebuf_len);
+   return;
+   }
 
for (i = 0; i < len; i += rowsize) {
linelen = min(remaining, rowsize);
remaining -= rowsize;
 
hex_dump_to_buf

[PATCH v2 3/7] lib/hexdump.c: Optionally suppress lines of repeated bytes

2019-05-08 Thread Alastair D'Silva
From: Alastair D'Silva 

Some buffers may only be partially filled with useful data, while the rest
is padded (typically with 0x00 or 0xff).

This patch introduces a flag to allow the supression of lines of repeated
bytes, which are replaced with '** Skipped %u bytes of value 0x%x **'

An inline wrapper function is provided for backwards compatibility with
existing code, which maintains the original behaviour.

Signed-off-by: Alastair D'Silva 
---
 include/linux/printk.h | 25 +---
 lib/hexdump.c  | 91 --
 2 files changed, 99 insertions(+), 17 deletions(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index d7c77ed1a4cb..938a67580d78 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -479,13 +479,18 @@ enum {
DUMP_PREFIX_ADDRESS,
DUMP_PREFIX_OFFSET
 };
+
 extern int hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
  int groupsize, char *linebuf, size_t linebuflen,
  bool ascii);
+
+#define HEXDUMP_ASCII  (1 << 0)
+#define HEXDUMP_SUPPRESS_REPEATED  (1 << 1)
+
 #ifdef CONFIG_PRINTK
-extern void print_hex_dump(const char *level, const char *prefix_str,
+extern void print_hex_dump_ext(const char *level, const char *prefix_str,
   int prefix_type, int rowsize, int groupsize,
-  const void *buf, size_t len, bool ascii);
+  const void *buf, size_t len, u64 flags);
 #if defined(CONFIG_DYNAMIC_DEBUG)
 #define print_hex_dump_bytes(prefix_str, prefix_type, buf, len)\
dynamic_hex_dump(prefix_str, prefix_type, 16, 1, buf, len, true)
@@ -494,18 +499,28 @@ extern void print_hex_dump_bytes(const char *prefix_str, 
int prefix_type,
 const void *buf, size_t len);
 #endif /* defined(CONFIG_DYNAMIC_DEBUG) */
 #else
-static inline void print_hex_dump(const char *level, const char *prefix_str,
+static inline void print_hex_dump_ext(const char *level, const char 
*prefix_str,
  int prefix_type, int rowsize, int groupsize,
- const void *buf, size_t len, bool ascii)
+ const void *buf, size_t len, u64 flags)
 {
 }
 static inline void print_hex_dump_bytes(const char *prefix_str, int 
prefix_type,
const void *buf, size_t len)
 {
 }
-
 #endif
 
+static __always_inline void print_hex_dump(const char *level,
+  const char *prefix_str,
+  int prefix_type, int rowsize,
+  int groupsize, const void *buf,
+  size_t len, bool ascii)
+{
+   print_hex_dump_ext(level, prefix_str, prefix_type, rowsize, groupsize,
+   buf, len, ascii ? HEXDUMP_ASCII : 0);
+}
+
+
 #if defined(CONFIG_DYNAMIC_DEBUG)
 #define print_hex_dump_debug(prefix_str, prefix_type, rowsize, \
 groupsize, buf, len, ascii)\
diff --git a/lib/hexdump.c b/lib/hexdump.c
index 3943507bc0e9..d61a1e4f19fa 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -212,8 +212,44 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
 EXPORT_SYMBOL(hex_dump_to_buffer);
 
 #ifdef CONFIG_PRINTK
+
+/**
+ * Check if a buffer contains only a single byte value
+ * @buf: pointer to the buffer
+ * @len: the size of the buffer in bytes
+ * @val: outputs the value if if the bytes are identical
+ */
+static bool buf_is_all(const u8 *buf, size_t len, u8 *val_out)
+{
+   size_t i;
+   u8 val;
+
+   if (len <= 1)
+   return false;
+
+   val = buf[0];
+
+   for (i = 1; i < len; i++) {
+   if (buf[i] != val)
+   return false;
+   }
+
+   *val_out = val;
+   return true;
+}
+
+static void announce_skipped(const char *level, const char *prefix_str,
+  u8 val, size_t count)
+{
+   if (count == 0)
+   return;
+
+   printk("%s%s ** Skipped %lu bytes of value 0x%x **\n",
+  level, prefix_str, count, val);
+}
+
 /**
- * print_hex_dump - print a text hex dump to syslog for a binary blob of data
+ * print_hex_dump_ext: dump a binary blob of data to syslog in hexadecimal
  * @level: kernel log level (e.g. KERN_DEBUG)
  * @prefix_str: string to prefix each line with;
  *  caller supplies trailing spaces for alignment if desired
@@ -224,6 +260,10 @@ EXPORT_SYMBOL(hex_dump_to_buffer);
  * @buf: data blob to dump
  * @len: number of bytes in the @buf
  * @ascii: include ASCII after the hex output
+ * @flags: A bitwise OR of the following flags:
+ * HEXDUMP_ASCII:  include ASCII after the hex output
+ * HEXDUMP_SUPPRESS_REPEATED:  suppress

[PATCH v2 5/7] lib/hexdump.c: Allow multiple groups to be separated by lines '|'

2019-05-08 Thread Alastair D'Silva
From: Alastair D'Silva 

With the wider display format, it can become hard to identify how many
bytes into the line you are looking at.

The patch adds new flags to hex_dump_to_buffer() and print_hex_dump() to
print vertical lines to separate every N groups of bytes.

eg.
buf:: 454d414e 43415053|4e495f45 00584544  NAMESPAC|E_INDEX.
buf:0010:  0002|   |

Signed-off-by: Alastair D'Silva 
---
 include/linux/printk.h |  3 +++
 lib/hexdump.c  | 59 --
 2 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index 00a82e468643..dc693aec394c 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -482,6 +482,9 @@ enum {
 
 #define HEXDUMP_ASCII  (1 << 0)
 #define HEXDUMP_SUPPRESS_REPEATED  (1 << 1)
+#define HEXDUMP_2_GRP_LINES(1 << 2)
+#define HEXDUMP_4_GRP_LINES(1 << 3)
+#define HEXDUMP_8_GRP_LINES(1 << 4)
 
 extern int hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
  int groupsize, char *linebuf, size_t linebuflen,
diff --git a/lib/hexdump.c b/lib/hexdump.c
index ddd1697e5f9b..6f4d1176c332 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -77,6 +77,23 @@ char *bin2hex(char *dst, const void *src, size_t count)
 }
 EXPORT_SYMBOL(bin2hex);
 
+static const char *group_separator(int group, u64 flags)
+{
+   if (group == 0)
+   return " ";
+
+   if ((flags & HEXDUMP_8_GRP_LINES) && !((group) % 8))
+   return "|";
+
+   if ((flags & HEXDUMP_4_GRP_LINES) && !((group) % 4))
+   return "|";
+
+   if ((flags & HEXDUMP_2_GRP_LINES) && !((group) % 2))
+   return "|";
+
+   return " ";
+}
+
 /**
  * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
  * @buf: data blob to dump
@@ -87,6 +104,9 @@ EXPORT_SYMBOL(bin2hex);
  * @linebuflen: total size of @linebuf, including space for terminating NUL
  * @flags: A bitwise OR of the following flags:
  * HEXDUMP_ASCII:  include ASCII after the hex output
+ * HEXDUMP_2_GRP_LINES:insert a '|' after every 2 groups
+ * HEXDUMP_4_GRP_LINES:insert a '|' after every 4 groups
+ * HEXDUMP_8_GRP_LINES:insert a '|' after every 8 groups
  *
  * hex_dump_to_buffer() works on one "line" of output at a time, converting
  *  bytes of input to hexadecimal (and optionally printable ASCII)
@@ -118,6 +138,7 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
int j, lx = 0;
int ascii_column;
int ret;
+   int line_chars = 0;
 
if (!is_power_of_2(groupsize) || groupsize > 8)
groupsize = 1;
@@ -144,7 +165,8 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
 
for (j = 0; j < ngroups; j++) {
ret = snprintf(linebuf + lx, linebuflen - lx,
-  "%s%16.16llx", j ? " " : "",
+  "%s%16.16llx",
+  j ? group_separator(j, flags) : "",
   get_unaligned(ptr8 + j));
if (ret >= linebuflen - lx)
goto overflow1;
@@ -155,7 +177,8 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
 
for (j = 0; j < ngroups; j++) {
ret = snprintf(linebuf + lx, linebuflen - lx,
-  "%s%8.8x", j ? " " : "",
+  "%s%8.8x",
+  j ? group_separator(j, flags) : "",
   get_unaligned(ptr4 + j));
if (ret >= linebuflen - lx)
goto overflow1;
@@ -166,7 +189,8 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
 
for (j = 0; j < ngroups; j++) {
ret = snprintf(linebuf + lx, linebuflen - lx,
-  "%s%4.4x", j ? " " : "",
+  "%s%4.4x",
+  j ? group_separator(j, flags) : "",
   get_unaligned(ptr2 + j));
if (ret >= linebuflen - lx)
goto overflow1;
@@ -196,11 +220,26 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int gr

[PATCH v2 0/7] Hexdump Enhancements

2019-05-08 Thread Alastair D'Silva
From: Alastair D'Silva 

Apologies for the large CC list, it's a heads up for those responsible
for subsystems where a prototype change in generic code causes a change
in those subsystems.

This series enhances hexdump.

These improve the readability of the dumped data in certain situations
(eg. wide terminals are available, many lines of empty bytes exist, etc).

The default behaviour of hexdump is unchanged, however, the prototype
for hex_dump_to_buffer() has changed, and print_hex_dump() has been
renamed to print_hex_dump_ext(), with a wrapper replacing it for
compatibility with existing code, which would have been too invasive to
change.

Hexdump selftests have be run & confirmed passed.

Changelog:
 - Fix failing selftests
 - Fix precedence bug in 'Replace ascii bool in hex_dump_to_buffer...'
 - Remove hardcoded new lengths & instead relax the checks in
   hex_dump_to_buffer, allocating the buffer from the heap instead of the
   stack.
 - Replace the skipping of lines of 0x00/0xff with skipping lines of
   repeated characters, announcing what has been skipped.
 - Add spaces as an optional N-group separator
 - Allow byte ordering to be maintained when HEXDUMP_RETAIN_BYTE_ORDERING
   is set.
 - Updated selftests to cover 'Relax rowsize checks' &
   'Optionally retain byte ordering'

Alastair D'Silva (7):
  lib/hexdump.c: Fix selftests
  lib/hexdump.c: Relax rowsize checks in hex_dump_to_buffer
  lib/hexdump.c: Optionally suppress lines of repeated bytes
  lib/hexdump.c: Replace ascii bool in hex_dump_to_buffer with flags
  lib/hexdump.c: Allow multiple groups to be separated by lines '|'
  lib/hexdump.c: Allow multiple groups to be separated by spaces
  lib/hexdump.c: Optionally retain byte ordering

 drivers/gpu/drm/i915/intel_engine_cs.c|   2 +-
 drivers/isdn/hardware/mISDN/mISDNisar.c   |   6 +-
 drivers/mailbox/mailbox-test.c|   2 +-
 drivers/net/ethernet/amd/xgbe/xgbe-drv.c  |   2 +-
 .../net/ethernet/synopsys/dwc-xlgmac-common.c |   2 +-
 drivers/net/wireless/ath/ath10k/debug.c   |   3 +-
 .../net/wireless/intel/iwlegacy/3945-mac.c|   2 +-
 drivers/platform/chrome/wilco_ec/debugfs.c|   2 +-
 drivers/scsi/scsi_logging.c   |   8 +-
 drivers/staging/fbtft/fbtft-core.c|   2 +-
 fs/seq_file.c |   3 +-
 include/linux/printk.h|  34 ++-
 lib/hexdump.c | 260 +++---
 lib/test_hexdump.c| 146 +++---
 14 files changed, 372 insertions(+), 102 deletions(-)

-- 
2.21.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 1/7] lib/hexdump.c: Fix selftests

2019-05-08 Thread Alastair D'Silva
From: Alastair D'Silva 

The overflow tests did not account for the situation where no
overflow occurs and len < rowsize.

This patch renames the cryptic variables and accounts for the
above case.

The selftests now pass.

Signed-off-by: Alastair D'Silva 
---
 lib/test_hexdump.c | 47 ++
 1 file changed, 27 insertions(+), 20 deletions(-)

diff --git a/lib/test_hexdump.c b/lib/test_hexdump.c
index 5144899d3c6b..d78ddd62ffd0 100644
--- a/lib/test_hexdump.c
+++ b/lib/test_hexdump.c
@@ -163,45 +163,52 @@ static void __init test_hexdump_overflow(size_t buflen, 
size_t len,
 {
char test[TEST_HEXDUMP_BUF_SIZE];
char buf[TEST_HEXDUMP_BUF_SIZE];
-   int rs = rowsize, gs = groupsize;
-   int ae, he, e, f, r;
-   bool a;
+   int ascii_len, hex_len, expected_len, fill_point, ngroups, rc;
+   bool match;
 
total_tests++;
 
memset(buf, FILL_CHAR, sizeof(buf));
 
-   r = hex_dump_to_buffer(data_b, len, rs, gs, buf, buflen, ascii);
+   rc = hex_dump_to_buffer(data_b, len, rowsize, groupsize, buf, buflen, 
ascii);
 
/*
 * Caller must provide the data length multiple of groupsize. The
 * calculations below are made with that assumption in mind.
 */
-   ae = rs * 2 /* hex */ + rs / gs /* spaces */ + 1 /* space */ + len /* 
ascii */;
-   he = (gs * 2 /* hex */ + 1 /* space */) * len / gs - 1 /* no trailing 
space */;
+   ngroups = rowsize / groupsize;
+   hex_len = (groupsize * 2 /* hex */ + 1 /* spaces */) * ngroups
+ - 1 /* no trailing space */;
+   ascii_len = hex_len + 2 /* space */ + len /* ascii */;
+
+   if (len < rowsize) {
+   ngroups = len / groupsize;
+   hex_len = (groupsize * 2 /* hex */ + 1 /* spaces */) * ngroups
+ - 1 /* no trailing space */;
+   }
 
-   if (ascii)
-   e = ae;
-   else
-   e = he;
+   expected_len = (ascii) ? ascii_len : hex_len;
 
-   f = min_t(int, e + 1, buflen);
+   fill_point = min_t(int, expected_len + 1, buflen);
if (buflen) {
-   test_hexdump_prepare_test(len, rs, gs, test, sizeof(test), 
ascii);
-   test[f - 1] = '\0';
+   test_hexdump_prepare_test(len, rowsize, groupsize, test,
+ sizeof(test), ascii);
+   test[fill_point - 1] = '\0';
}
-   memset(test + f, FILL_CHAR, sizeof(test) - f);
+   memset(test + fill_point, FILL_CHAR, sizeof(test) - fill_point);
 
-   a = r == e && !memcmp(test, buf, TEST_HEXDUMP_BUF_SIZE);
+   match = rc == expected_len && !memcmp(test, buf, TEST_HEXDUMP_BUF_SIZE);
 
buf[sizeof(buf) - 1] = '\0';
 
-   if (!a) {
-   pr_err("Len: %zu buflen: %zu strlen: %zu\n",
-   len, buflen, strnlen(buf, sizeof(buf)));
-   pr_err("Result: %d '%s'\n", r, buf);
-   pr_err("Expect: %d '%s'\n", e, test);
+   if (!match) {
+   pr_err("rowsize: %u groupsize: %u ascii: %d Len: %zu buflen: 
%zu strlen: %zu\n",
+   rowsize, groupsize, ascii, len, buflen,
+   strnlen(buf, sizeof(buf)));
+   pr_err("Result: %d '%-.*s'\n", rc, (int)buflen, buf);
+   pr_err("Expect: %d '%-.*s'\n", expected_len, (int)buflen, test);
failed_tests++;
+
}
 }
 
-- 
2.21.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


RE: [PATCH 3/4] lib/hexdump.c: Replace ascii bool in hex_dump_to_buffer with flags

2019-04-15 Thread Alastair D'Silva
> -Original Message-
> From: David Laight 
> Sent: Monday, 15 April 2019 9:04 PM
> To: 'Alastair D'Silva' ; 'Petr Mladek'
> 
> Cc: 'Alastair D'Silva' ; 'Jani Nikula'
> ; 'Joonas Lahtinen'
> ; 'Rodrigo Vivi' ;
> 'David Airlie' ; 'Daniel Vetter' ; 'Karsten
> Keil' ; 'Jassi Brar' ; 'Tom
> Lendacky' ; 'David S. Miller'
> ; 'Jose Abreu' ; 'Kalle
> Valo' ; 'Stanislaw Gruszka' ;
> 'Benson Leung' ; 'Enric Balletbo i Serra'
> ; 'James E.J. Bottomley'
> ; 'Martin K. Petersen' ;
> 'Greg Kroah-Hartman' ; 'Alexander Viro'
> ; 'Sergey Senozhatsky'
> ; 'Steven Rostedt'
> ; 'Andrew Morton' ;
> intel-...@lists.freedesktop.org; dri-de...@lists.freedesktop.org; linux-
> ker...@vger.kernel.org; net...@vger.kernel.org;
> ath...@lists.infradead.org; linux-wirel...@vger.kernel.org; linux-
> s...@vger.kernel.org; linux-fb...@vger.kernel.org;
> de...@driverdev.osuosl.org; linux-fsde...@vger.kernel.org
> Subject: RE: [PATCH 3/4] lib/hexdump.c: Replace ascii bool in
> hex_dump_to_buffer with flags
> 
> From: Alastair D'Silva
> > Sent: 15 April 2019 11:45
> ...
> > > Although I think you'd want a 'no hex' flag to suppress the hex.
> > >
> > > Probably more useful flags are ones to suppress the address column.
> >
> > This is already supported by the prefix_type parameter - are you
> > proposing that we eliminate the parameter & combine it with flags?
> 
> I was looking at the flags on one of my hexdump() functions...
> 
> > > I've also used flags to enable (or disable) suppression of multiple
> > > lines of zeros of constant bytes.
> > > In that case you may want hexdump to return the flags for the next
> > > call when a large buffer is being dumped in fragments.
> >
> > I'm afraid I don't quite follow here, hex_dump_to_buffer doesn't alter
> > the flags, so the caller already knows it.
> 
> If you are suppressing lines of zeros and dumping a buffer in several blocks
> then subsequent calls need to know that the last line of the previous call was
> suppressed zeros - and carry on with the same suppressed block.

Why wouldn't you do this with a single call to print_hex_dump? (that is where 
the repeated lines are suppressed)

That will already take chunks of the buffer until the whole thing is output, in 
what situation do you see a caller chunking the access themselves?

-- 
Alastair D'Silva   mob: 0423 762 819
skype: alastair_dsilva msn: alast...@d-silva.org
blog: http://alastair.d-silva.orgTwitter: @EvilDeece



___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


RE: [PATCH 1/4] lib/hexdump.c: Allow 64 bytes per line

2019-04-15 Thread Alastair D'Silva
> From: Alastair D'Silva
> > Sent: 15 April 2019 11:29
> ...
> > I do, and I believe the choice of the output length should be in the
> > hands of the caller.
> >
> > On further thought, it would make more sense to remove the hardcoded
> > list of sizes and just enforce a power of 2. The function shouldn't
> > dictate what the caller can and can't do beyond the technical limits of it's
> implementation.
> 
> Why powers of two?
> You may want the length to match sizeof (struct foo).
> You might even want the address increment to be larger that the number of
> lines dumped.

Good point, the base requirement is that it should be a multiple of groupsize.

-- 
Alastair D'Silva   mob: 0423 762 819
skype: alastair_dsilva msn: alast...@d-silva.org
blog: http://alastair.d-silva.orgTwitter: @EvilDeece



___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


RE: [PATCH 3/4] lib/hexdump.c: Replace ascii bool in hex_dump_to_buffer with flags

2019-04-15 Thread Alastair D'Silva
> -Original Message-
> From: David Laight 
> Sent: Monday, 15 April 2019 8:21 PM
> To: 'Alastair D'Silva' ; 'Petr Mladek'
> 
> Cc: 'Alastair D'Silva' ; 'Jani Nikula'
> ; 'Joonas Lahtinen'
> ; 'Rodrigo Vivi' ;
> 'David Airlie' ; 'Daniel Vetter' ; 'Karsten
> Keil' ; 'Jassi Brar' ; 'Tom
> Lendacky' ; 'David S. Miller'
> ; 'Jose Abreu' ; 'Kalle
> Valo' ; 'Stanislaw Gruszka' ;
> 'Benson Leung' ; 'Enric Balletbo i Serra'
> ; 'James E.J. Bottomley'
> ; 'Martin K. Petersen' ;
> 'Greg Kroah-Hartman' ; 'Alexander Viro'
> ; 'Sergey Senozhatsky'
> ; 'Steven Rostedt'
> ; 'Andrew Morton' ;
> intel-...@lists.freedesktop.org; dri-de...@lists.freedesktop.org; linux-
> ker...@vger.kernel.org; net...@vger.kernel.org;
> ath...@lists.infradead.org; linux-wirel...@vger.kernel.org; linux-
> s...@vger.kernel.org; linux-fb...@vger.kernel.org;
> de...@driverdev.osuosl.org; linux-fsde...@vger.kernel.org
> Subject: RE: [PATCH 3/4] lib/hexdump.c: Replace ascii bool in
> hex_dump_to_buffer with flags
> 
> From: Alastair D'Silva
> > Sent: 15 April 2019 11:07
> ...
> > In the above example the author only wants the hex output, while in
> > other situations, both hex & ASCII output is desirable. If you just
> > want ASCII output, the caller should just use a printk or one of it's
> wrappers.
> 
> Hexdump will 'sanitise' the ASCII.
> 

This is functionality that doesn't exist in the current hexdump implementation 
(you always get the hex version).

I think a better option would be to factor out the sanitisation and expose that 
as a separate function.

> Although I think you'd want a 'no hex' flag to suppress the hex.
> 
> Probably more useful flags are ones to suppress the address column.

This is already supported by the prefix_type parameter - are you proposing that 
we eliminate the parameter & combine it with flags?

> I've also used flags to enable (or disable) suppression of multiple lines of
> zeros of constant bytes.
> In that case you may want hexdump to return the flags for the next call when
> a large buffer is being dumped in fragments.
 
I'm afraid I don't quite follow here, hex_dump_to_buffer doesn't alter the 
flags, so the caller already knows it. 

-- 
Alastair D'Silva   mob: 0423 762 819
skype: alastair_dsilva msn: alast...@d-silva.org
blog: http://alastair.d-silva.orgTwitter: @EvilDeece




___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


RE: [PATCH 2/4] lib/hexdump.c: Optionally suppress lines of filler bytes

2019-04-15 Thread Alastair D'Silva
> > > On Wed 2019-04-10 13:17:18, Alastair D'Silva wrote:
> > > > From: Alastair D'Silva 
> > > >
> > > > Some buffers may only be partially filled with useful data, while
> > > > the rest is padded (typically with 0x00 or 0xff).
> > > >
> > > > This patch introduces flags which allow lines of padding bytes to
> > > > be suppressed, making the output easier to interpret:
> > > > HEXDUMP_SUPPRESS_0X00, HEXDUMP_SUPPRESS_0XFF
> > > >
> > > > The first and last lines are not suppressed by default, so the
> > > > function always outputs something. This behaviour can be further
> > > > controlled with the HEXDUMP_SUPPRESS_FIRST &
> > > HEXDUMP_SUPPRESS_LAST flags.
> > > >
> > > > An inline wrapper function is provided for backwards compatibility
> > > > with existing code, which maintains the original behaviour.
> > > >
> > >
> > > > diff --git a/lib/hexdump.c b/lib/hexdump.c index
> > > > b8a164814744..2f3bafb55a44 100644
> > > > --- a/lib/hexdump.c
> > > > +++ b/lib/hexdump.c
> > > > +void print_hex_dump_ext(const char *level, const char *prefix_str,
> > > > +   int prefix_type, int rowsize, int groupsize,
> > > > +   const void *buf, size_t len, u64 flags)
> > > >  {
> > > > const u8 *ptr = buf;
> > > > -   int i, linelen, remaining = len;
> > > > +   int i, remaining = len;
> > > > unsigned char linebuf[64 * 3 + 2 + 64 + 1];
> > > > +   bool first_line = true;
> > > >
> > > > if (rowsize != 16 && rowsize != 32 && rowsize != 64)
> > > > rowsize = 16;
> > > >
> > > > for (i = 0; i < len; i += rowsize) {
> > > > -   linelen = min(remaining, rowsize);
> > > > +   bool skip = false;
> > > > +   int linelen = min(remaining, rowsize);
> > > > +
> > > > remaining -= rowsize;
> > > >
> > > > +   if (flags & HEXDUMP_SUPPRESS_0X00)
> > > > +   skip = buf_is_all(ptr + i, linelen, 0x00);
> > > > +
> > > > +   if (!skip && (flags & HEXDUMP_SUPPRESS_0XFF))
> > > > +   skip = buf_is_all(ptr + i, linelen, 0xff);
> > > > +
> > > > +   if (first_line && !(flags & HEXDUMP_SUPPRESS_FIRST))
> > > > +   skip = false;
> > > > +
> > > > +   if (remaining <= 0 && !(flags &
HEXDUMP_SUPPRESS_LAST))
> > > > +   skip = false;
> > > > +
> > > > +   if (skip)
> > > > +   continue;
> > >
> > > IMHO, quietly skipping lines could cause a lot of confusion,
> > > espcially
> > when the address is not printed.
> > >
> > It's up to the caller to decide how they want it displayed.
> 
> I wonder who would want to quietly skip some data values.
> Are you using it yourself? Could you please provide an example?

Yes, but I don't have the content with me at the moment, so I can't share
it. I'm dumping persistent memory labels, which are 64kB long, but only the
first few hundred bytes are populated.
 
> I do not see why we would need to complicate the API and code by this.
> 
> The behavior proposed by Tvrtko Ursulin makes much more sense. I mean
> https://lkml.kernel.org/r/929244ed-cc7f-b0f3-b5ac-
> 50e798e83...@linux.intel.com

I agree that is better, I'll add that to V2.

-- 
Alastair D'Silva   mob: 0423 762 819
skype: alastair_dsilva msn: alast...@d-silva.org
blog: http://alastair.d-silva.orgTwitter: @EvilDeece



___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


RE: [PATCH 1/4] lib/hexdump.c: Allow 64 bytes per line

2019-04-15 Thread Alastair D'Silva

> > > On Wed 2019-04-10 13:17:17, Alastair D'Silva wrote:
> > > > From: Alastair D'Silva 
> > > >
> > > > With modern high resolution screens, we can display more data,
> > > > which makes life a bit easier when debugging.
> > >
> > > I have quite some doubts about this feature.
> > >
> > > We are talking about more than 256 characters per-line. I wonder if
> > > such a long line is really easier to read for a human.
> >
> > It's basically 2 separate panes of information side by side, the
> > hexdump and the ASCII version.
> >
> > I'm using this myself when dealing with the pmem labels, and it works
> > quite nicely.
> 
> I am sure that it works for you. But I do not believe that it would be
useful in
> general.

I do, and I believe the choice of the output length should be in the hands
of the caller.

On further thought, it would make more sense to remove the hardcoded list of
sizes and just enforce a power of 2. The function shouldn't dictate what the
caller can and can't do beyond the technical limits of it's implementation.

Other print/debug functions don't restrict the output size, and I can't see
a good justification why hexdump should either.

> > > I am not expert but there is a reason why the standard is 80
> > > characters
> > per-
> > > line. I guess that anything above 100 characters is questionable.
> > > https://en.wikipedia.org/wiki/Line_length
> > > somehow confirms that.
> > >
> > > Second, if we take 8 pixels per-character. Then we need
> > > 2048 to show the 256 characters. It is more than HD.
> > > IMHO, there is still huge number of people that even do not have HD
> > display,
> > > especially on a notebook.
> >
> > The intent is to make debugging easier when dealing with large chunks
> > of binary data. I don't expect end users to see this output.
> 
> How is it supposed to be used then? Only by your temporary patches?

Let me rephrase that, I don't expect end users to *use* this data.

Current usage of the hexdump functions are predominantly centred around
logging and debugging, and clearly targeted at someone intimately familiar
with the relevant subsystem. I expect future use would be similar.

Debugging may be as part of active development, or from a log supplied from
an end user. In either case, it should be up to the author (as a
representative for the consumers of the data) to decide how it should be
formatted.

-- 
Alastair D'Silva   mob: 0423 762 819
skype: alastair_dsilva msn: alast...@d-silva.org
blog: http://alastair.d-silva.orgTwitter: @EvilDeece





___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


RE: [PATCH 3/4] lib/hexdump.c: Replace ascii bool in hex_dump_to_buffer with flags

2019-04-15 Thread Alastair D'Silva
> -Original Message-
> From: Petr Mladek 
> Sent: Monday, 15 April 2019 7:24 PM
> To: Alastair D'Silva 
> Cc: 'Alastair D'Silva' ; 'Jani Nikula'
> ; 'Joonas Lahtinen'
> ; 'Rodrigo Vivi'
;
> 'David Airlie' ; 'Daniel Vetter' ;
'Karsten
> Keil' ; 'Jassi Brar' ; 'Tom
> Lendacky' ; 'David S. Miller'
> ; 'Jose Abreu' ; 'Kalle
> Valo' ; 'Stanislaw Gruszka' ;
> 'Benson Leung' ; 'Enric Balletbo i Serra'
> ; 'James E.J. Bottomley'
> ; 'Martin K. Petersen' ;
> 'Greg Kroah-Hartman' ; 'Alexander Viro'
> ; 'Sergey Senozhatsky'
> ; 'Steven Rostedt'
> ; 'Andrew Morton' ;
> intel-...@lists.freedesktop.org; dri-de...@lists.freedesktop.org; linux-
> ker...@vger.kernel.org; net...@vger.kernel.org;
> ath...@lists.infradead.org; linux-wirel...@vger.kernel.org; linux-
> s...@vger.kernel.org; linux-fb...@vger.kernel.org;
> de...@driverdev.osuosl.org; linux-fsde...@vger.kernel.org
> Subject: Re: [PATCH 3/4] lib/hexdump.c: Replace ascii bool in
> hex_dump_to_buffer with flags
> 
> On Sat 2019-04-13 09:31:27, Alastair D'Silva wrote:
> > > -Original Message-----
> > > From: Petr Mladek 
> > > Sent: Saturday, 13 April 2019 12:12 AM
> > > To: Alastair D'Silva 
> > > Cc: alast...@d-silva.org; Jani Nikula ;
> > Joonas
> > > Lahtinen ; Rodrigo Vivi
> > > ; David Airlie ; Daniel
> > > Vetter ; Karsten Keil ; Jassi
> > > Brar ; Tom Lendacky
> > > ; David S. Miller
> ;
> > > Jose Abreu ; Kalle Valo
> > > ; Stanislaw Gruszka ;
> > > Benson Leung ; Enric Balletbo i Serra
> > > ; James E.J. Bottomley
> > > ; Martin K. Petersen
> > > ; Greg Kroah-Hartman
> > > ; Alexander Viro
> > > ; Sergey Senozhatsky
> > > ; Steven Rostedt
> > > ; Andrew Morton  foundation.org>;
> > > intel- g...@lists.freedesktop.org; dri-de...@lists.freedesktop.org;
> > > linux- ker...@vger.kernel.org; net...@vger.kernel.org;
> > > ath...@lists.infradead.org; linux-wirel...@vger.kernel.org; linux-
> > > s...@vger.kernel.org; linux-fb...@vger.kernel.org;
> > > de...@driverdev.osuosl.org; linux-fsde...@vger.kernel.org
> > > Subject: Re: [PATCH 3/4] lib/hexdump.c: Replace ascii bool in
> > > hex_dump_to_buffer with flags
> > >
> > > On Wed 2019-04-10 13:17:19, Alastair D'Silva wrote:
> > > > From: Alastair D'Silva 
> > > >
> > > > In order to support additional features in hex_dump_to_buffer,
> > > > replace the ascii bool parameter with flags.
> > > >
> > > > Signed-off-by: Alastair D'Silva 
> > > > ---
> > > >  drivers/gpu/drm/i915/intel_engine_cs.c|  2 +-
> > > >  drivers/isdn/hardware/mISDN/mISDNisar.c   |  6 --
> > > >  drivers/mailbox/mailbox-test.c|  2 +-
> > > >  drivers/net/ethernet/amd/xgbe/xgbe-drv.c  |  2 +-
> > > >  drivers/net/ethernet/synopsys/dwc-xlgmac-common.c |  2 +-
> > > >  drivers/net/wireless/ath/ath10k/debug.c   |  3 ++-
> > > >  drivers/net/wireless/intel/iwlegacy/3945-mac.c|  2 +-
> > > >  drivers/platform/chrome/wilco_ec/debugfs.c|  3 ++-
> > > >  drivers/scsi/scsi_logging.c   |  8 +++-
> > > >  drivers/staging/fbtft/fbtft-core.c|  2 +-
> > > >  fs/seq_file.c |  3 ++-
> > > >  include/linux/printk.h|  2 +-
> > > >  lib/hexdump.c | 15
---
> > > >  lib/test_hexdump.c|  5 +++--
> > > >  14 files changed, 31 insertions(+), 26 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c
> > > > b/drivers/gpu/drm/i915/intel_engine_cs.c
> > > > index 49fa43ff02ba..fb133e729f9a 100644
> > > > --- a/drivers/gpu/drm/i915/intel_engine_cs.c
> > > > +++ b/drivers/gpu/drm/i915/intel_engine_cs.c
> > > > @@ -1318,7 +1318,7 @@ static void hexdump(struct drm_printer *m,
> > > > const
> > > void *buf, size_t len)
> > > > WARN_ON_ONCE(hex_dump_to_buffer(buf + pos, len -
> > > pos,
> > > > rowsize,
sizeof(u32),
> > > > line, sizeof(line),
> > > > -   false) >=
sizeof(line));
> > > > +   0) >= sizeof(line))

RE: [PATCH 3/4] lib/hexdump.c: Replace ascii bool in hex_dump_to_buffer with flags

2019-04-12 Thread Alastair D'Silva
> -Original Message-
> From: Petr Mladek 
> Sent: Saturday, 13 April 2019 12:12 AM
> To: Alastair D'Silva 
> Cc: alast...@d-silva.org; Jani Nikula ;
Joonas
> Lahtinen ; Rodrigo Vivi
> ; David Airlie ; Daniel Vetter
> ; Karsten Keil ; Jassi Brar
> ; Tom Lendacky ;
> David S. Miller ; Jose Abreu
> ; Kalle Valo ;
> Stanislaw Gruszka ; Benson Leung
> ; Enric Balletbo i Serra
> ; James E.J. Bottomley
> ; Martin K. Petersen ;
> Greg Kroah-Hartman ; Alexander Viro
> ; Sergey Senozhatsky
> ; Steven Rostedt ;
> Andrew Morton ; intel-
> g...@lists.freedesktop.org; dri-de...@lists.freedesktop.org; linux-
> ker...@vger.kernel.org; net...@vger.kernel.org;
> ath...@lists.infradead.org; linux-wirel...@vger.kernel.org; linux-
> s...@vger.kernel.org; linux-fb...@vger.kernel.org;
> de...@driverdev.osuosl.org; linux-fsde...@vger.kernel.org
> Subject: Re: [PATCH 3/4] lib/hexdump.c: Replace ascii bool in
> hex_dump_to_buffer with flags
> 
> On Wed 2019-04-10 13:17:19, Alastair D'Silva wrote:
> > From: Alastair D'Silva 
> >
> > In order to support additional features in hex_dump_to_buffer, replace
> > the ascii bool parameter with flags.
> >
> > Signed-off-by: Alastair D'Silva 
> > ---
> >  drivers/gpu/drm/i915/intel_engine_cs.c|  2 +-
> >  drivers/isdn/hardware/mISDN/mISDNisar.c   |  6 --
> >  drivers/mailbox/mailbox-test.c|  2 +-
> >  drivers/net/ethernet/amd/xgbe/xgbe-drv.c  |  2 +-
> >  drivers/net/ethernet/synopsys/dwc-xlgmac-common.c |  2 +-
> >  drivers/net/wireless/ath/ath10k/debug.c   |  3 ++-
> >  drivers/net/wireless/intel/iwlegacy/3945-mac.c|  2 +-
> >  drivers/platform/chrome/wilco_ec/debugfs.c|  3 ++-
> >  drivers/scsi/scsi_logging.c   |  8 +++-
> >  drivers/staging/fbtft/fbtft-core.c|  2 +-
> >  fs/seq_file.c |  3 ++-
> >  include/linux/printk.h|  2 +-
> >  lib/hexdump.c | 15 ---
> >  lib/test_hexdump.c|  5 +++--
> >  14 files changed, 31 insertions(+), 26 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c
> > b/drivers/gpu/drm/i915/intel_engine_cs.c
> > index 49fa43ff02ba..fb133e729f9a 100644
> > --- a/drivers/gpu/drm/i915/intel_engine_cs.c
> > +++ b/drivers/gpu/drm/i915/intel_engine_cs.c
> > @@ -1318,7 +1318,7 @@ static void hexdump(struct drm_printer *m, const
> void *buf, size_t len)
> > WARN_ON_ONCE(hex_dump_to_buffer(buf + pos, len -
> pos,
> > rowsize, sizeof(u32),
> > line, sizeof(line),
> > -   false) >= sizeof(line));
> > +   0) >= sizeof(line));
> 
> It might be more clear when we define:
> 
> #define HEXDUMP_BINARY 0

This feels unnecessary, and weird. Omitting the flag won't disable the hex
output (as expected), and if you don't want hex output, why call hexdump in
the first place?

> > drm_printf(m, "[%04zx] %s\n", pos, line);
> >
> > prev = buf + pos;
> > diff --git a/include/linux/printk.h b/include/linux/printk.h index
> > c014e5573665..82975853c400 100644
> > --- a/include/linux/printk.h
> > +++ b/include/linux/printk.h
> > @@ -493,7 +493,7 @@ enum {
> >
> >  extern int hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
> >   int groupsize, char *linebuf, size_t
linebuflen,
> > - bool ascii);
> > + u64 flags);
> 
> I wonder how fancy hex_dump could be. IMHO, u32 should be enough.
> The last famous words ;-)
> 
> Best Regards,
> Petr
> 
> 
> ---
> This email has been checked for viruses by AVG.
> https://www.avg.com


___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


RE: [PATCH 2/4] lib/hexdump.c: Optionally suppress lines of filler bytes

2019-04-12 Thread Alastair D'Silva
> -Original Message-
> From: Petr Mladek 
> Sent: Saturday, 13 April 2019 12:04 AM
> To: Alastair D'Silva 
> Cc: alast...@d-silva.org; Jani Nikula ;
Joonas
> Lahtinen ; Rodrigo Vivi
> ; David Airlie ; Daniel Vetter
> ; Karsten Keil ; Jassi Brar
> ; Tom Lendacky ;
> David S. Miller ; Jose Abreu
> ; Kalle Valo ;
> Stanislaw Gruszka ; Benson Leung
> ; Enric Balletbo i Serra
> ; James E.J. Bottomley
> ; Martin K. Petersen ;
> Greg Kroah-Hartman ; Alexander Viro
> ; Sergey Senozhatsky
> ; Steven Rostedt ;
> Andrew Morton ; intel-
> g...@lists.freedesktop.org; dri-de...@lists.freedesktop.org; linux-
> ker...@vger.kernel.org; net...@vger.kernel.org;
> ath...@lists.infradead.org; linux-wirel...@vger.kernel.org; linux-
> s...@vger.kernel.org; linux-fb...@vger.kernel.org;
> de...@driverdev.osuosl.org; linux-fsde...@vger.kernel.org
> Subject: Re: [PATCH 2/4] lib/hexdump.c: Optionally suppress lines of
filler
> bytes
> 
> On Wed 2019-04-10 13:17:18, Alastair D'Silva wrote:
> > From: Alastair D'Silva 
> >
> > Some buffers may only be partially filled with useful data, while the
> > rest is padded (typically with 0x00 or 0xff).
> >
> > This patch introduces flags which allow lines of padding bytes to be
> > suppressed, making the output easier to interpret:
> > HEXDUMP_SUPPRESS_0X00, HEXDUMP_SUPPRESS_0XFF
> >
> > The first and last lines are not suppressed by default, so the
> > function always outputs something. This behaviour can be further
> > controlled with the HEXDUMP_SUPPRESS_FIRST &
> HEXDUMP_SUPPRESS_LAST flags.
> >
> > An inline wrapper function is provided for backwards compatibility
> > with existing code, which maintains the original behaviour.
> >
> 
> > diff --git a/lib/hexdump.c b/lib/hexdump.c index
> > b8a164814744..2f3bafb55a44 100644
> > --- a/lib/hexdump.c
> > +++ b/lib/hexdump.c
> > +void print_hex_dump_ext(const char *level, const char *prefix_str,
> > +   int prefix_type, int rowsize, int groupsize,
> > +   const void *buf, size_t len, u64 flags)
> >  {
> > const u8 *ptr = buf;
> > -   int i, linelen, remaining = len;
> > +   int i, remaining = len;
> > unsigned char linebuf[64 * 3 + 2 + 64 + 1];
> > +   bool first_line = true;
> >
> > if (rowsize != 16 && rowsize != 32 && rowsize != 64)
> > rowsize = 16;
> >
> > for (i = 0; i < len; i += rowsize) {
> > -   linelen = min(remaining, rowsize);
> > +   bool skip = false;
> > +   int linelen = min(remaining, rowsize);
> > +
> > remaining -= rowsize;
> >
> > +   if (flags & HEXDUMP_SUPPRESS_0X00)
> > +   skip = buf_is_all(ptr + i, linelen, 0x00);
> > +
> > +   if (!skip && (flags & HEXDUMP_SUPPRESS_0XFF))
> > +   skip = buf_is_all(ptr + i, linelen, 0xff);
> > +
> > +   if (first_line && !(flags & HEXDUMP_SUPPRESS_FIRST))
> > +   skip = false;
> > +
> > +   if (remaining <= 0 && !(flags & HEXDUMP_SUPPRESS_LAST))
> > +   skip = false;
> > +
> > +   if (skip)
> > +   continue;
> 
> IMHO, quietly skipping lines could cause a lot of confusion, espcially
when
> the address is not printed.
>
It's up to the caller to decide how they want it displayed.

> I wonder how it would look like when we print something like:
> 
> --- skipped XX lines full of 0x00 ---

This could be added as a later enhancement, with a new flag (eg.
HEXDUMP_SUPPRESS_VERBOSE).

> 
> Then we might even remove the SUPPRESS_FIRST, SUPPRESS_LAST and the
> ambiguous QUIET flags.
> 
> > +
> > +   first_line = false;
> 
> This should be above the if (skip).
> 
> > +
> > hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize,
> > -  linebuf, sizeof(linebuf), ascii);
> > +  linebuf, sizeof(linebuf),
> > +  flags & HEXDUMP_ASCII);
> >
> > switch (prefix_type) {
> > case DUMP_PREFIX_ADDRESS:
> > @@ -272,7 +316,7 @@ void print_hex_dump(const char *level, const char
> *prefix_str, int prefix_type,
> > }
> > }
> >  }
> > -EXPORT_SYMBOL(print_hex_dump);
> > +EXPORT_SYMBOL(print_hex_dump_ext);
> 
> We should still export even the original function that is still used
everywhere.

It's replaced with an inline wrapper function, there's no need to export it.

-- 
Alastair D'Silva   mob: 0423 762 819
skype: alastair_dsilva msn: alast...@d-silva.org
blog: http://alastair.d-silva.orgTwitter: @EvilDeece



___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


RE: [PATCH 1/4] lib/hexdump.c: Allow 64 bytes per line

2019-04-12 Thread Alastair D'Silva
> -Original Message-
> From: Petr Mladek 
> Sent: Friday, 12 April 2019 11:48 PM
> To: Alastair D'Silva 
> Cc: alast...@d-silva.org; Jani Nikula ;
Joonas
> Lahtinen ; Rodrigo Vivi
> ; David Airlie ; Daniel Vetter
> ; Karsten Keil ; Jassi Brar
> ; Tom Lendacky ;
> David S. Miller ; Jose Abreu
> ; Kalle Valo ;
> Stanislaw Gruszka ; Benson Leung
> ; Enric Balletbo i Serra
> ; James E.J. Bottomley
> ; Martin K. Petersen ;
> Greg Kroah-Hartman ; Alexander Viro
> ; Sergey Senozhatsky
> ; Steven Rostedt ;
> Andrew Morton ; intel-
> g...@lists.freedesktop.org; dri-de...@lists.freedesktop.org; linux-
> ker...@vger.kernel.org; net...@vger.kernel.org;
> ath...@lists.infradead.org; linux-wirel...@vger.kernel.org; linux-
> s...@vger.kernel.org; linux-fb...@vger.kernel.org;
> de...@driverdev.osuosl.org; linux-fsde...@vger.kernel.org
> Subject: Re: [PATCH 1/4] lib/hexdump.c: Allow 64 bytes per line
> 
> On Wed 2019-04-10 13:17:17, Alastair D'Silva wrote:
> > From: Alastair D'Silva 
> >
> > With modern high resolution screens, we can display more data, which
> > makes life a bit easier when debugging.
> 
> I have quite some doubts about this feature.
> 
> We are talking about more than 256 characters per-line. I wonder if such a
> long line is really easier to read for a human.

It's basically 2 separate panes of information side by side, the hexdump and
the ASCII version.

I'm using this myself when dealing with the pmem labels, and it works quite
nicely.

> 
> I am not expert but there is a reason why the standard is 80 characters
per-
> line. I guess that anything above 100 characters is questionable.
> https://en.wikipedia.org/wiki/Line_length
> somehow confirms that.
> 
> Second, if we take 8 pixels per-character. Then we need
> 2048 to show the 256 characters. It is more than HD.
> IMHO, there is still huge number of people that even do not have HD
display,
> especially on a notebook.

The intent is to make debugging easier when dealing with large chunks of
binary data. I don't expect end users to see this output.

-- 
Alastair D'Silva   mob: 0423 762 819
skype: alastair_dsilva msn: alast...@d-silva.org
blog: http://alastair.d-silva.orgTwitter: @EvilDeece



___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


RE: [PATCH 4/4] lib/hexdump.c: Allow multiple groups to be separated by lines '|'

2019-04-10 Thread Alastair D'Silva
> -Original Message-
> From: David Laight 
> Sent: Wednesday, 10 April 2019 6:45 PM
> To: 'Alastair D'Silva' ; alast...@d-silva.org
> Cc: Jani Nikula ; Joonas Lahtinen
> ; Rodrigo Vivi ;
> David Airlie ; Daniel Vetter ; Karsten Keil
> ; Jassi Brar ; Tom Lendacky
> ; David S. Miller ;
> Jose Abreu ; Kalle Valo
> ; Stanislaw Gruszka ;
> Benson Leung ; Enric Balletbo i Serra
> ; James E.J. Bottomley
> ; Martin K. Petersen ;
> Greg Kroah-Hartman ; Alexander Viro
> ; Petr Mladek ; Sergey
> Senozhatsky ; Steven Rostedt
> ; Andrew Morton ;
> intel-...@lists.freedesktop.org; dri-de...@lists.freedesktop.org; linux-
> ker...@vger.kernel.org; net...@vger.kernel.org;
> ath...@lists.infradead.org; linux-wirel...@vger.kernel.org; linux-
> s...@vger.kernel.org; linux-fb...@vger.kernel.org;
> de...@driverdev.osuosl.org; linux-fsde...@vger.kernel.org
> Subject: RE: [PATCH 4/4] lib/hexdump.c: Allow multiple groups to be
> separated by lines '|'
> 
> From: Alastair D'Silva
> > Sent: 10 April 2019 04:17
> > With the wider display format, it can become hard to identify how many
> > bytes into the line you are looking at.
> >
> > The patch adds new flags to hex_dump_to_buffer() and
> print_hex_dump()
> > to print vertical lines to separate every N groups of bytes.
> >
> > eg.
> > buf:: 454d414e 43415053|4e495f45 00584544
> NAMESPAC|E_INDEX.
> > buf:0010:  0002|   |
> 
> Ugg, that is just horrid.
> It is enough to add an extra space if you really need the columns to be more
> easily counted.
>

I did consider that, but it would be a more invasive change, as the buffer 
length required would differ based on the flags.
 
> I'm not even sure that is needed if you are printing 32bit words.
> OTOH 32bit words makes 64bit values really stupid on LE systems.
> Bytes with extra spaces every 4 bytes is the format I prefer even for long
> lines.
> 
> Oh, and if you are using hexdump() a lot you want a version that never uses
> snprintf().
> 
>   David
> 
> -
> Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes,
> MK1 1PT, UK Registration No: 1397386 (Wales)
> 
> 
> ---
> This email has been checked for viruses by AVG.
> https://www.avg.com


___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/4] lib/hexdump.c: Optionally suppress lines of filler bytes

2019-04-09 Thread Alastair D'Silva
From: Alastair D'Silva 

Some buffers may only be partially filled with useful data, while the rest
is padded (typically with 0x00 or 0xff).

This patch introduces flags which allow lines of padding bytes to be
suppressed, making the output easier to interpret: HEXDUMP_SUPPRESS_0X00,
HEXDUMP_SUPPRESS_0XFF

The first and last lines are not suppressed by default, so the function
always outputs something. This behaviour can be further controlled with
the HEXDUMP_SUPPRESS_FIRST & HEXDUMP_SUPPRESS_LAST flags.

An inline wrapper function is provided for backwards compatibility with
existing code, which maintains the original behaviour.

Signed-off-by: Alastair D'Silva 
---
 include/linux/printk.h | 38 ++
 lib/hexdump.c  | 72 ++
 2 files changed, 89 insertions(+), 21 deletions(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index d7c77ed1a4cb..c014e5573665 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -479,13 +479,26 @@ enum {
DUMP_PREFIX_ADDRESS,
DUMP_PREFIX_OFFSET
 };
+
+#define HEXDUMP_ASCII  (1 << 0)
+#define HEXDUMP_SUPPRESS_0X00  (1 << 1)
+#define HEXDUMP_SUPPRESS_0XFF  (1 << 2)
+#define HEXDUMP_SUPPRESS_FIRST (1 << 3)
+#define HEXDUMP_SUPPRESS_LAST  (1 << 4)
+
+#define HEXDUMP_QUIET  (HEXDUMP_SUPPRESS_0X00 | \
+   HEXDUMP_SUPPRESS_0XFF | \
+   HEXDUMP_SUPPRESS_FIRST | \
+   HEXDUMP_SUPPRESS_LAST)
+
 extern int hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
  int groupsize, char *linebuf, size_t linebuflen,
  bool ascii);
+
 #ifdef CONFIG_PRINTK
-extern void print_hex_dump(const char *level, const char *prefix_str,
-  int prefix_type, int rowsize, int groupsize,
-  const void *buf, size_t len, bool ascii);
+extern void print_hex_dump_ext(const char *level, const char *prefix_str,
+  int prefix_type, int rowsize, int groupsize,
+  const void *buf, size_t len, u64 flags);
 #if defined(CONFIG_DYNAMIC_DEBUG)
 #define print_hex_dump_bytes(prefix_str, prefix_type, buf, len)\
dynamic_hex_dump(prefix_str, prefix_type, 16, 1, buf, len, true)
@@ -494,18 +507,29 @@ extern void print_hex_dump_bytes(const char *prefix_str, 
int prefix_type,
 const void *buf, size_t len);
 #endif /* defined(CONFIG_DYNAMIC_DEBUG) */
 #else
-static inline void print_hex_dump(const char *level, const char *prefix_str,
- int prefix_type, int rowsize, int groupsize,
- const void *buf, size_t len, bool ascii)
+static inline void print_hex_dump_ext(const char *level, const char 
*prefix_str,
+ int prefix_type, int rowsize,
+ int groupsize, const void *buf,
+ size_t len, u64 flags)
 {
 }
 static inline void print_hex_dump_bytes(const char *prefix_str, int 
prefix_type,
const void *buf, size_t len)
 {
 }
-
 #endif
 
+static __always_inline void print_hex_dump(const char *level,
+  const char *prefix_str,
+  int prefix_type, int rowsize,
+  int groupsize, const void *buf,
+  size_t len, bool ascii)
+{
+   print_hex_dump_ext(level, prefix_str, prefix_type, rowsize, groupsize,
+   buf, len, ascii ? HEXDUMP_ASCII : 0);
+}
+
+
 #if defined(CONFIG_DYNAMIC_DEBUG)
 #define print_hex_dump_debug(prefix_str, prefix_type, rowsize, \
 groupsize, buf, len, ascii)\
diff --git a/lib/hexdump.c b/lib/hexdump.c
index b8a164814744..2f3bafb55a44 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -209,8 +209,21 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
 EXPORT_SYMBOL(hex_dump_to_buffer);
 
 #ifdef CONFIG_PRINTK
+
+static bool buf_is_all(const u8 *buf, size_t len, u8 val)
+{
+   size_t i;
+
+   for (i = 0; i < len; i++) {
+   if (buf[i] != val)
+   return false;
+   }
+
+   return true;
+}
+
 /**
- * print_hex_dump - print a text hex dump to syslog for a binary blob of data
+ * print_hex_dump_ext: dump a binary blob of data to syslog in hexadecimal
  * @level: kernel log level (e.g. KERN_DEBUG)
  * @prefix_str: string to prefix each line with;
  *  caller supplies trailing spaces for alignment if desired
@@ -221,42 +234,73 @@ EXPORT_SYMBOL(hex_dump_to_buffer);
  * @buf: data blob to dump
  * @len: number of bytes in the @buf
  * @ascii: include ASCII after the hex output
+ * @flags

[PATCH 4/4] lib/hexdump.c: Allow multiple groups to be separated by lines '|'

2019-04-09 Thread Alastair D'Silva
From: Alastair D'Silva 

With the wider display format, it can become hard to identify how many
bytes into the line you are looking at.

The patch adds new flags to hex_dump_to_buffer() and print_hex_dump() to
print vertical lines to separate every N groups of bytes.

eg.
buf:: 454d414e 43415053|4e495f45 00584544  NAMESPAC|E_INDEX.
buf:0010:  0002|   |

Signed-off-by: Alastair D'Silva 
---
 include/linux/printk.h |  3 +++
 lib/hexdump.c  | 50 +-
 2 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index 82975853c400..d9e407e59059 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -485,6 +485,9 @@ enum {
 #define HEXDUMP_SUPPRESS_0XFF  (1 << 2)
 #define HEXDUMP_SUPPRESS_FIRST (1 << 3)
 #define HEXDUMP_SUPPRESS_LAST  (1 << 4)
+#define HEXDUMP_2_GRP_LINES(1 << 5)
+#define HEXDUMP_4_GRP_LINES(1 << 6)
+#define HEXDUMP_8_GRP_LINES(1 << 7)
 
 #define HEXDUMP_QUIET  (HEXDUMP_SUPPRESS_0X00 | \
HEXDUMP_SUPPRESS_0XFF | \
diff --git a/lib/hexdump.c b/lib/hexdump.c
index 79db784577e7..d42f34b93b2c 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -76,6 +76,20 @@ char *bin2hex(char *dst, const void *src, size_t count)
 }
 EXPORT_SYMBOL(bin2hex);
 
+static const char *group_separator(int group, u64 flags)
+{
+   if ((flags & HEXDUMP_8_GRP_LINES) && ((group - 1) % 8))
+   return "|";
+
+   if ((flags & HEXDUMP_4_GRP_LINES) && ((group - 1) % 4))
+   return "|";
+
+   if ((flags & HEXDUMP_2_GRP_LINES) && ((group - 1) % 2))
+   return "|";
+
+   return " ";
+}
+
 /**
  * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
  * @buf: data blob to dump
@@ -86,6 +100,9 @@ EXPORT_SYMBOL(bin2hex);
  * @linebuflen: total size of @linebuf, including space for terminating NUL
  * @flags: A bitwise OR of the following flags:
  * HEXDUMP_ASCII:  include ASCII after the hex output
+ * HEXDUMP_2_GRP_LINES:insert a '|' after every 2 groups
+ * HEXDUMP_4_GRP_LINES:insert a '|' after every 4 groups
+ * HEXDUMP_8_GRP_LINES:insert a '|' after every 8 groups
  *
  * hex_dump_to_buffer() works on one "line" of output at a time, i.e.,
  * 16, 32 or 64 bytes of input data converted to hex + ASCII output.
@@ -116,6 +133,7 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
int j, lx = 0;
int ascii_column;
int ret;
+   int line_chars = 0;
 
if (rowsize != 16 && rowsize != 32 && rowsize != 64)
rowsize = 16;
@@ -141,7 +159,8 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
 
for (j = 0; j < ngroups; j++) {
ret = snprintf(linebuf + lx, linebuflen - lx,
-  "%s%16.16llx", j ? " " : "",
+  "%s%16.16llx",
+  j ? group_separator(j, flags) : "",
   get_unaligned(ptr8 + j));
if (ret >= linebuflen - lx)
goto overflow1;
@@ -152,7 +171,8 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
 
for (j = 0; j < ngroups; j++) {
ret = snprintf(linebuf + lx, linebuflen - lx,
-  "%s%8.8x", j ? " " : "",
+  "%s%8.8x",
+  j ? group_separator(j, flags) : "",
   get_unaligned(ptr4 + j));
if (ret >= linebuflen - lx)
goto overflow1;
@@ -163,7 +183,8 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
 
for (j = 0; j < ngroups; j++) {
ret = snprintf(linebuf + lx, linebuflen - lx,
-  "%s%4.4x", j ? " " : "",
+  "%s%4.4x",
+  j ? group_separator(j, flags) : "",
   get_unaligned(ptr2 + j));
if (ret >= linebuflen - lx)
goto overflow1;
@@ -193,11 +214,26 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
goto overflow2;
linebuf[lx++] = ' ';
}
+
+   if (flag

[PATCH 0/4] Hexdump enhancements

2019-04-09 Thread Alastair D'Silva
From: Alastair D'Silva 

Apologies for the large CC list, it's a heads up for those responsible
for subsystems where a prototype change in generic code causes a change
in those subsystems.

This series enhances hexdump.

These improve the readability of the dumped data in certain situations
(eg. wide terminals are available, many lines of empty bytes exist, etc).

The default behaviour of hexdump is unchanged, however, the prototype
for hex_dump_to_buffer() has changed, and print_hex_dump() has been
renamed to print_hex_dump_ext(), with a wrapper replacing it for
compatibility with existing code, which would have been too invasive to
change.

Alastair D'Silva (4):
  lib/hexdump.c: Allow 64 bytes per line
  lib/hexdump.c: Optionally suppress lines of filler bytes
  lib/hexdump.c: Replace ascii bool in hex_dump_to_buffer with flags
  lib/hexdump.c: Allow multiple groups to be separated by lines '|'

 drivers/gpu/drm/i915/intel_engine_cs.c|   2 +-
 drivers/isdn/hardware/mISDN/mISDNisar.c   |   6 +-
 drivers/mailbox/mailbox-test.c|   2 +-
 drivers/net/ethernet/amd/xgbe/xgbe-drv.c  |   2 +-
 .../net/ethernet/synopsys/dwc-xlgmac-common.c |   2 +-
 drivers/net/wireless/ath/ath10k/debug.c   |   3 +-
 .../net/wireless/intel/iwlegacy/3945-mac.c|   2 +-
 drivers/platform/chrome/wilco_ec/debugfs.c|   3 +-
 drivers/scsi/scsi_logging.c   |   8 +-
 drivers/staging/fbtft/fbtft-core.c|   2 +-
 fs/seq_file.c |   3 +-
 include/linux/printk.h|  38 -
 lib/hexdump.c | 143 ++
 lib/test_hexdump.c|   5 +-
 14 files changed, 168 insertions(+), 53 deletions(-)

-- 
2.20.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 2/4] lib/hexdump.c: Optionally suppress lines of filler bytes

2019-04-09 Thread Alastair D'Silva
On Wed, 2019-04-10 at 13:17 +1000, Alastair D'Silva wrote:
> From: Alastair D'Silva 
> 
> Some buffers may only be partially filled with useful data, while the
> rest
> is padded (typically with 0x00 or 0xff).
> 
This patch introduces flags which allow lines of padding bytes to be
> suppressed, making the output easier to interpret:
> HEXDUMP_SUPPRESS_0X00,
> HEXDUMP_SUPPRESS_0XFF
> 
> The first and last lines are not suppressed by default, so the
> function
> always outputs something. This behaviour can be further controlled
> with
> the HEXDUMP_SUPPRESS_FIRST & HEXDUMP_SUPPRESS_LAST flags.
> 
> An inline wrapper function is provided for backwards compatibility
> with
> existing code, which maintains the original behaviour.
> 
> Signed-off-by: Alastair D'Silva 
> ---
> 


> diff --git a/lib/hexdump.c b/lib/hexdump.c
> index b8a164814744..2f3bafb55a44 100644
> --- a/lib/hexdump.c
> +++ b/lib/hexdump.c
> @@ -209,8 +209,21 @@ int hex_dump_to_buffer(const void *buf, size_t
> len, int rowsize, int groupsize,
>  EXPORT_SYMBOL(hex_dump_to_buffer);
>  
>  #ifdef CONFIG_PRINTK
> +
> +static bool buf_is_all(const u8 *buf, size_t len, u8 val)
> +{
> + size_t i;
> +
> + for (i = 0; i < len; i++) {
> + if (buf[i] != val)
> + return false;
> + }
> +
> + return true;
> +}
> +
>  /**
> - * print_hex_dump - print a text hex dump to syslog for a binary
> blob of data
> + * print_hex_dump_ext: dump a binary blob of data to syslog in
> hexadecimal
>   * @level: kernel log level (e.g. KERN_DEBUG)
>   * @prefix_str: string to prefix each line with;
>   *  caller supplies trailing spaces for alignment if desired
> @@ -221,42 +234,73 @@ EXPORT_SYMBOL(hex_dump_to_buffer);
>   * @buf: data blob to dump
>   * @len: number of bytes in the @buf
>   * @ascii: include ASCII after the hex output
This line should have been removed. I'll address it in V2.

> + * @flags: A bitwise OR of the following flags:
> + *   HEXDUMP_ASCII:  include ASCII after the hex output
> + *   HEXDUMP_SUPPRESS_0X00:  suppress lines that are all 0x00
> + *   (other than first or last)
> + *   HEXDUMP_SUPPRESS_0XFF:  suppress lines that are all 0xff
> + *   (other than first or last)
> + *   HEXDUMP_SUPPRESS_FIRST: allows the first line to be
> suppressed
> + *   HEXDUMP_SUPPRESS_LAST:  allows the last line to be suppressed
> + *   If the first and last line may be
> suppressed,
> + *   an empty buffer will not produce any
> output
>   *
>   * Given a buffer of u8 data, print_hex_dump() prints a hex + ASCII
> dump
>   * to the kernel log at the specified kernel log level, with an
> optional
>   * leading prefix.
>   *
> - * print_hex_dump() works on one "line" of output at a time, i.e.,
> + * print_hex_dump_ext() works on one "line" of output at a time,
> i.e.,
>   * 16, 32 or 64 bytes of input data converted to hex + ASCII output.
> - * print_hex_dump() iterates over the entire input @buf, breaking it
> into
> + * print_hex_dump_ext() iterates over the entire input @buf,
> breaking it into
>   * "line size" chunks to format and print.
>   *
>   * E.g.:
> - *   print_hex_dump(KERN_DEBUG, "raw data: ", DUMP_PREFIX_ADDRESS,
> - *   16, 1, frame->data, frame->len, true);
> + *   print_hex_dump_ext(KERN_DEBUG, "raw data: ",
> DUMP_PREFIX_ADDRESS,
> + *   16, 1, frame->data, frame->len, HEXDUMP_ASCII);
>   *
>   * Example output using %DUMP_PREFIX_OFFSET and 1-byte mode:
>   * 0009ab42: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e
> 4f  @ABCDEFGHIJKLMNO
>   * Example output using %DUMP_PREFIX_ADDRESS and 4-byte mode:
>   * 88089af0: 73727170 77767574 7b7a7978
> 7f7e7d7c  pqrstuvwxyz{|}~.
>   */

-- 
Alastair D'Silva   mob: 0423 762 819
skype: alastair_dsilva
Twitter: @EvilDeece
blog: http://alastair.d-silva.org


___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/4] lib/hexdump.c: Allow 64 bytes per line

2019-04-09 Thread Alastair D'Silva
From: Alastair D'Silva 

With modern high resolution screens, we can display more data, which makes
life a bit easier when debugging.

Allow 64 bytes to be dumped per line.

Signed-off-by: Alastair D'Silva 
---
 lib/hexdump.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/lib/hexdump.c b/lib/hexdump.c
index 81b70ed37209..b8a164814744 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -80,14 +80,14 @@ EXPORT_SYMBOL(bin2hex);
  * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
  * @buf: data blob to dump
  * @len: number of bytes in the @buf
- * @rowsize: number of bytes to print per line; must be 16 or 32
+ * @rowsize: number of bytes to print per line; must be 16, 32 or 64
  * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
  * @linebuf: where to put the converted data
  * @linebuflen: total size of @linebuf, including space for terminating NUL
  * @ascii: include ASCII after the hex output
  *
  * hex_dump_to_buffer() works on one "line" of output at a time, i.e.,
- * 16 or 32 bytes of input data converted to hex + ASCII output.
+ * 16, 32 or 64 bytes of input data converted to hex + ASCII output.
  *
  * Given a buffer of u8 data, hex_dump_to_buffer() converts the input data
  * to a hex + ASCII dump at the supplied memory location.
@@ -116,7 +116,7 @@ int hex_dump_to_buffer(const void *buf, size_t len, int 
rowsize, int groupsize,
int ascii_column;
int ret;
 
-   if (rowsize != 16 && rowsize != 32)
+   if (rowsize != 16 && rowsize != 32 && rowsize != 64)
rowsize = 16;
 
if (len > rowsize)  /* limit to one line at a time */
@@ -216,7 +216,7 @@ EXPORT_SYMBOL(hex_dump_to_buffer);
  *  caller supplies trailing spaces for alignment if desired
  * @prefix_type: controls whether prefix of an offset, address, or none
  *  is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE)
- * @rowsize: number of bytes to print per line; must be 16 or 32
+ * @rowsize: number of bytes to print per line; must be 16, 32 or 64
  * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
  * @buf: data blob to dump
  * @len: number of bytes in the @buf
@@ -227,7 +227,7 @@ EXPORT_SYMBOL(hex_dump_to_buffer);
  * leading prefix.
  *
  * print_hex_dump() works on one "line" of output at a time, i.e.,
- * 16 or 32 bytes of input data converted to hex + ASCII output.
+ * 16, 32 or 64 bytes of input data converted to hex + ASCII output.
  * print_hex_dump() iterates over the entire input @buf, breaking it into
  * "line size" chunks to format and print.
  *
@@ -246,9 +246,9 @@ void print_hex_dump(const char *level, const char 
*prefix_str, int prefix_type,
 {
const u8 *ptr = buf;
int i, linelen, remaining = len;
-   unsigned char linebuf[32 * 3 + 2 + 32 + 1];
+   unsigned char linebuf[64 * 3 + 2 + 64 + 1];
 
-   if (rowsize != 16 && rowsize != 32)
+   if (rowsize != 16 && rowsize != 32 && rowsize != 64)
rowsize = 16;
 
for (i = 0; i < len; i += rowsize) {
-- 
2.20.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 3/4] lib/hexdump.c: Replace ascii bool in hex_dump_to_buffer with flags

2019-04-09 Thread Alastair D'Silva
From: Alastair D'Silva 

In order to support additional features in hex_dump_to_buffer, replace
the ascii bool parameter with flags.

Signed-off-by: Alastair D'Silva 
---
 drivers/gpu/drm/i915/intel_engine_cs.c|  2 +-
 drivers/isdn/hardware/mISDN/mISDNisar.c   |  6 --
 drivers/mailbox/mailbox-test.c|  2 +-
 drivers/net/ethernet/amd/xgbe/xgbe-drv.c  |  2 +-
 drivers/net/ethernet/synopsys/dwc-xlgmac-common.c |  2 +-
 drivers/net/wireless/ath/ath10k/debug.c   |  3 ++-
 drivers/net/wireless/intel/iwlegacy/3945-mac.c|  2 +-
 drivers/platform/chrome/wilco_ec/debugfs.c|  3 ++-
 drivers/scsi/scsi_logging.c   |  8 +++-
 drivers/staging/fbtft/fbtft-core.c|  2 +-
 fs/seq_file.c |  3 ++-
 include/linux/printk.h|  2 +-
 lib/hexdump.c | 15 ---
 lib/test_hexdump.c|  5 +++--
 14 files changed, 31 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c 
b/drivers/gpu/drm/i915/intel_engine_cs.c
index 49fa43ff02ba..fb133e729f9a 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -1318,7 +1318,7 @@ static void hexdump(struct drm_printer *m, const void 
*buf, size_t len)
WARN_ON_ONCE(hex_dump_to_buffer(buf + pos, len - pos,
rowsize, sizeof(u32),
line, sizeof(line),
-   false) >= sizeof(line));
+   0) >= sizeof(line));
drm_printf(m, "[%04zx] %s\n", pos, line);
 
prev = buf + pos;
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c 
b/drivers/isdn/hardware/mISDN/mISDNisar.c
index 386731ec2489..f13f34db6c17 100644
--- a/drivers/isdn/hardware/mISDN/mISDNisar.c
+++ b/drivers/isdn/hardware/mISDN/mISDNisar.c
@@ -84,7 +84,8 @@ send_mbox(struct isar_hw *isar, u8 his, u8 creg, u8 len, u8 
*msg)
 
while (l < (int)len) {
hex_dump_to_buffer(msg + l, len - l, 32, 1,
-  isar->log, 256, 1);
+  isar->log, 256,
+  HEXDUMP_ASCII);
pr_debug("%s: %s %02x: %s\n", isar->name,
 __func__, l, isar->log);
l += 32;
@@ -113,7 +114,8 @@ rcv_mbox(struct isar_hw *isar, u8 *msg)
 
while (l < (int)isar->clsb) {
hex_dump_to_buffer(msg + l, isar->clsb - l, 32,
-  1, isar->log, 256, 1);
+  1, isar->log, 256,
+  HEXDUMP_ASCII);
pr_debug("%s: %s %02x: %s\n", isar->name,
 __func__, l, isar->log);
l += 32;
diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c
index 4e4ac4be6423..2f9a094d0259 100644
--- a/drivers/mailbox/mailbox-test.c
+++ b/drivers/mailbox/mailbox-test.c
@@ -213,7 +213,7 @@ static ssize_t mbox_test_message_read(struct file *filp, 
char __user *userbuf,
hex_dump_to_buffer(ptr,
   MBOX_BYTES_PER_LINE,
   MBOX_BYTES_PER_LINE, 1, touser + l,
-  MBOX_HEXDUMP_LINE_LEN, true);
+  MBOX_HEXDUMP_LINE_LEN, HEXDUMP_ASCII);
 
ptr += MBOX_BYTES_PER_LINE;
l += MBOX_HEXDUMP_LINE_LEN;
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c 
b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index 0cc911f928b1..e954a31cee0c 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -2992,7 +2992,7 @@ void xgbe_print_pkt(struct net_device *netdev, struct 
sk_buff *skb, bool tx_rx)
unsigned int len = min(skb->len - i, 32U);
 
hex_dump_to_buffer(>data[i], len, 32, 1,
-  buffer, sizeof(buffer), false);
+  buffer, sizeof(buffer), 0);
netdev_dbg(netdev, "  %#06x: %s\n", i, buffer);
}
 
diff --git a/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c 
b/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c
index eb1c6b03c329..b80adfa1f890 100644
--- a/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c
+++ b/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c
@@ -349,7 +349,7 @@ void xlgmac_print