A few sysfs output uses of hex arrays are uppercase and are nominally ABI. Add a mechanism to the existing vsprintf %*ph hex output extension to support upper case hex output. Signed-off-by: Joe Perches <joe@xxxxxxxxxxx> --- Documentation/core-api/printk-formats.rst | 6 ++++ lib/vsprintf.c | 42 ++++++++++++++--------- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst index e08bbe9b0cbf3..ca750274992e6 100644 --- a/Documentation/core-api/printk-formats.rst +++ b/Documentation/core-api/printk-formats.rst @@ -284,10 +284,16 @@ Raw buffer as a hex string :: + The preferred output is lowercase %*ph 00 01 02 ... 3f %*phC 00:01:02: ... :3f %*phD 00-01-02- ... -3f %*phN 000102 ... 3f + Formats with X are uppercase, used for backwards compatibility + %*phX 00 01 02 ... 3F + %*phCX 00:01:02: ... :3F + %*phDX 00-01-02- ... -3F + %*phNX 000102 ... 3F For printing small buffers (up to 64 bytes long) as a hex string with a certain separator. For larger buffers consider using diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 134216c45980e..5c22a07bbe3a7 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1147,7 +1147,10 @@ char *hex_string(char *buf, char *end, u8 *addr, struct printf_spec spec, { int i, len = 1; /* if we pass '%ph[CDN]', field width remains negative value, fallback to the default */ - char separator; + char separator = ' '; + int count = 1; + bool found = true; + char locase = 0x20; /* ASCII OR'd for lower case see: number() */ if (spec.field_width == 0) /* nothing to print */ @@ -1156,30 +1159,35 @@ char *hex_string(char *buf, char *end, u8 *addr, struct printf_spec spec, if (check_pointer(&buf, end, addr, spec)) return buf; - switch (fmt[1]) { - case 'C': - separator = ':'; - break; - case 'D': - separator = '-'; - break; - case 'N': - separator = 0; - break; - default: - separator = ' '; - break; - } + do { + switch (fmt[count++]) { + case 'C': + separator = ':'; + break; + case 'D': + separator = '-'; + break; + case 'N': + separator = 0; + break; + case 'X': + locase = 0; + break; + default: + found = false; + break; + } + } while (found); if (spec.field_width > 0) len = min_t(int, spec.field_width, 64); for (i = 0; i < len; ++i) { if (buf < end) - *buf = hex_asc_hi(addr[i]); + *buf = hex_asc_upper_hi(addr[i]) | locase; ++buf; if (buf < end) - *buf = hex_asc_lo(addr[i]); + *buf = hex_asc_upper_lo(addr[i]) | locase; ++buf; if (separator && i != len - 1) { -- 2.30.0