From 2840537228fba95e05cab1a6b5719c61982db279 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 6 Oct 2009 15:33:29 -0600 Subject: vsprintf: fix io/mem resource width The leading "0x" consumes field width, so leave space for it in addition to the 4 or 8 hex digits. This means we'll print "0x0000-0x01df" rather than "0x00-0x1df", for example. Signed-off-by: Bjorn Helgaas Signed-off-by: Jesse Barnes --- lib/vsprintf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/vsprintf.c') diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 33bed5e67a21..7830576018c0 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -598,11 +598,11 @@ static char *resource_string(char *buf, char *end, struct resource *res, struct printf_spec spec) { #ifndef IO_RSRC_PRINTK_SIZE -#define IO_RSRC_PRINTK_SIZE 4 +#define IO_RSRC_PRINTK_SIZE 6 #endif #ifndef MEM_RSRC_PRINTK_SIZE -#define MEM_RSRC_PRINTK_SIZE 8 +#define MEM_RSRC_PRINTK_SIZE 10 #endif struct printf_spec num_spec = { .base = 16, -- cgit v1.2.2 From c91d3376e5f4277173a22f0ef9989125c318bacb Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 6 Oct 2009 15:33:34 -0600 Subject: vsprintf: add %pR support for IRQ and DMA resources Print addresses (IO port numbers and memory addresses) in hex, but print others (IRQs and DMA channels) in decimal. Only print the end if it's different from the start. Signed-off-by: Bjorn Helgaas Signed-off-by: Jesse Barnes --- lib/vsprintf.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'lib/vsprintf.c') diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 7830576018c0..1b60aedab44d 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -604,26 +604,37 @@ static char *resource_string(char *buf, char *end, struct resource *res, #ifndef MEM_RSRC_PRINTK_SIZE #define MEM_RSRC_PRINTK_SIZE 10 #endif - struct printf_spec num_spec = { + struct printf_spec hex_spec = { .base = 16, .precision = -1, .flags = SPECIAL | SMALL | ZEROPAD, }; - /* room for the actual numbers, the two "0x", -, [, ] and the final zero */ - char sym[4*sizeof(resource_size_t) + 8]; + struct printf_spec dec_spec = { + .base = 10, + .precision = -1, + .flags = 0, + }; + /* room for two actual numbers (decimal or hex), the two "0x", -, [, ] + * and the final zero */ + char sym[2*3*sizeof(resource_size_t) + 8]; char *p = sym, *pend = sym + sizeof(sym); - int size = -1; + int size = -1, addr = 0; - if (res->flags & IORESOURCE_IO) + if (res->flags & IORESOURCE_IO) { size = IO_RSRC_PRINTK_SIZE; - else if (res->flags & IORESOURCE_MEM) + addr = 1; + } else if (res->flags & IORESOURCE_MEM) { size = MEM_RSRC_PRINTK_SIZE; + addr = 1; + } *p++ = '['; - num_spec.field_width = size; - p = number(p, pend, res->start, num_spec); - *p++ = '-'; - p = number(p, pend, res->end, num_spec); + hex_spec.field_width = size; + p = number(p, pend, res->start, addr ? hex_spec : dec_spec); + if (res->start != res->end) { + *p++ = '-'; + p = number(p, pend, res->end, addr ? hex_spec : dec_spec); + } *p++ = ']'; *p = 0; -- cgit v1.2.2 From fd95541e23e2c9acb1e38cd41fc0c7cc37fceb53 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 6 Oct 2009 15:33:39 -0600 Subject: vsprintf: add %pRt, %pRf to print struct resource details This adds support for printing struct resource type and flag information. For example, "%pRt" looks like "[mem 0x80080000000-0x8008001ffff 64bit pref]", and "%pRf" looks like "[mem 0xff5e2000-0xff5e2007 pref flags 0x1]". Signed-off-by: Bjorn Helgaas Signed-off-by: Jesse Barnes --- lib/vsprintf.c | 51 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) (limited to 'lib/vsprintf.c') diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 1b60aedab44d..a6e195163eb3 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -595,7 +595,7 @@ static char *symbol_string(char *buf, char *end, void *ptr, } static char *resource_string(char *buf, char *end, struct resource *res, - struct printf_spec spec) + struct printf_spec spec, const char *fmt) { #ifndef IO_RSRC_PRINTK_SIZE #define IO_RSRC_PRINTK_SIZE 6 @@ -614,9 +614,21 @@ static char *resource_string(char *buf, char *end, struct resource *res, .precision = -1, .flags = 0, }; - /* room for two actual numbers (decimal or hex), the two "0x", -, [, ] - * and the final zero */ - char sym[2*3*sizeof(resource_size_t) + 8]; + struct printf_spec str_spec = { + .field_width = -1, + .precision = 10, + .flags = LEFT, + }; + struct printf_spec flag_spec = { + .base = 16, + .precision = -1, + .flags = SPECIAL | SMALL, + }; + /* + * room for three actual numbers (decimal or hex), plus + * "[mem 0x-0x 64bit pref disabled flags 0x]\0" + */ + char sym[3*3*sizeof(resource_size_t) + 41]; char *p = sym, *pend = sym + sizeof(sym); int size = -1, addr = 0; @@ -629,12 +641,35 @@ static char *resource_string(char *buf, char *end, struct resource *res, } *p++ = '['; + if (fmt[1] == 't' || fmt[1] == 'f') { + if (res->flags & IORESOURCE_IO) + p = string(p, pend, "io ", str_spec); + else if (res->flags & IORESOURCE_MEM) + p = string(p, pend, "mem ", str_spec); + else if (res->flags & IORESOURCE_IRQ) + p = string(p, pend, "irq ", str_spec); + else if (res->flags & IORESOURCE_DMA) + p = string(p, pend, "dma ", str_spec); + } hex_spec.field_width = size; p = number(p, pend, res->start, addr ? hex_spec : dec_spec); if (res->start != res->end) { *p++ = '-'; p = number(p, pend, res->end, addr ? hex_spec : dec_spec); } + if (fmt[1] == 't' || fmt[1] == 'f') { + if (res->flags & IORESOURCE_MEM_64) + p = string(p, pend, " 64bit", str_spec); + if (res->flags & IORESOURCE_PREFETCH) + p = string(p, pend, " pref", str_spec); + if (res->flags & IORESOURCE_DISABLED) + p = string(p, pend, " disabled", str_spec); + if (fmt[1] == 'f') { + p = string(p, pend, " flags ", str_spec); + p = number(p, pend, res->flags & ~IORESOURCE_TYPE_BITS, + flag_spec); + } + } *p++ = ']'; *p = 0; @@ -812,8 +847,10 @@ static char *ip4_addr_string(char *buf, char *end, const u8 *addr, * - 'f' For simple symbolic function names without offset * - 'S' For symbolic direct pointers with offset * - 's' For symbolic direct pointers without offset - * - 'R' For a struct resource pointer, it prints the range of - * addresses (not the name nor the flags) + * - 'R' For a struct resource pointer, print: + * R address range only ([0x0-0x1f]) + * Rt type and range ([mem 0x0-0x1f 64bit pref]) + * Rf type, range, and flags ([mem 0x0-0x1f 64bit pref flags 0x1]) * - 'M' For a 6-byte MAC address, it prints the address in the * usual colon-separated hex notation * - 'm' For a 6-byte MAC address, it prints the hex address without colons @@ -844,7 +881,7 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, case 'S': return symbol_string(buf, end, ptr, spec, *fmt); case 'R': - return resource_string(buf, end, ptr, spec); + return resource_string(buf, end, ptr, spec, fmt); case 'M': /* Colon separated: 00:01:02:03:04:05 */ case 'm': /* Contiguous: 000102030405 */ return mac_address_string(buf, end, ptr, spec, fmt); -- cgit v1.2.2 From c7dabef8a2c59e6a3de9d66fc35fb6a43ef7172d Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 27 Oct 2009 13:26:47 -0600 Subject: vsprintf: use %pR, %pr instead of %pRt, %pRf Jesse accidentally applied v1 [1] of the patchset instead of v2 [2]. This is the diff between v1 and v2. The changes in this patch are: - tidied vsprintf stack buffer to shrink and compute size more accurately - use %pR for decoding and %pr for "raw" (with type and flags) instead of adding %pRt and %pRf [1] http://lkml.org/lkml/2009/10/6/491 [2] http://lkml.org/lkml/2009/10/13/441 Signed-off-by: Bjorn Helgaas Signed-off-by: Jesse Barnes --- lib/vsprintf.c | 55 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 25 deletions(-) (limited to 'lib/vsprintf.c') diff --git a/lib/vsprintf.c b/lib/vsprintf.c index a6e195163eb3..6438cd5599ee 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -624,13 +624,19 @@ static char *resource_string(char *buf, char *end, struct resource *res, .precision = -1, .flags = SPECIAL | SMALL, }; - /* - * room for three actual numbers (decimal or hex), plus - * "[mem 0x-0x 64bit pref disabled flags 0x]\0" - */ - char sym[3*3*sizeof(resource_size_t) + 41]; + + /* 32-bit res (sizeof==4): 10 chars in dec, 10 in hex ("0x" + 8) + * 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */ +#define RSRC_BUF_SIZE ((2 * sizeof(resource_size_t)) + 4) +#define FLAG_BUF_SIZE (2 * sizeof(res->flags)) +#define DECODED_BUF_SIZE sizeof("[mem - 64bit pref disabled]") +#define RAW_BUF_SIZE sizeof("[mem - flags 0x]") + char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE, + 2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)]; + char *p = sym, *pend = sym + sizeof(sym); int size = -1, addr = 0; + int decode = (fmt[0] == 'R') ? 1 : 0; if (res->flags & IORESOURCE_IO) { size = IO_RSRC_PRINTK_SIZE; @@ -641,15 +647,17 @@ static char *resource_string(char *buf, char *end, struct resource *res, } *p++ = '['; - if (fmt[1] == 't' || fmt[1] == 'f') { - if (res->flags & IORESOURCE_IO) - p = string(p, pend, "io ", str_spec); - else if (res->flags & IORESOURCE_MEM) - p = string(p, pend, "mem ", str_spec); - else if (res->flags & IORESOURCE_IRQ) - p = string(p, pend, "irq ", str_spec); - else if (res->flags & IORESOURCE_DMA) - p = string(p, pend, "dma ", str_spec); + if (res->flags & IORESOURCE_IO) + p = string(p, pend, "io ", str_spec); + else if (res->flags & IORESOURCE_MEM) + p = string(p, pend, "mem ", str_spec); + else if (res->flags & IORESOURCE_IRQ) + p = string(p, pend, "irq ", str_spec); + else if (res->flags & IORESOURCE_DMA) + p = string(p, pend, "dma ", str_spec); + else { + p = string(p, pend, "??? ", str_spec); + decode = 0; } hex_spec.field_width = size; p = number(p, pend, res->start, addr ? hex_spec : dec_spec); @@ -657,21 +665,19 @@ static char *resource_string(char *buf, char *end, struct resource *res, *p++ = '-'; p = number(p, pend, res->end, addr ? hex_spec : dec_spec); } - if (fmt[1] == 't' || fmt[1] == 'f') { + if (decode) { if (res->flags & IORESOURCE_MEM_64) p = string(p, pend, " 64bit", str_spec); if (res->flags & IORESOURCE_PREFETCH) p = string(p, pend, " pref", str_spec); if (res->flags & IORESOURCE_DISABLED) p = string(p, pend, " disabled", str_spec); - if (fmt[1] == 'f') { - p = string(p, pend, " flags ", str_spec); - p = number(p, pend, res->flags & ~IORESOURCE_TYPE_BITS, - flag_spec); - } + } else { + p = string(p, pend, " flags ", str_spec); + p = number(p, pend, res->flags, flag_spec); } *p++ = ']'; - *p = 0; + *p = '\0'; return string(buf, end, sym, spec); } @@ -847,10 +853,8 @@ static char *ip4_addr_string(char *buf, char *end, const u8 *addr, * - 'f' For simple symbolic function names without offset * - 'S' For symbolic direct pointers with offset * - 's' For symbolic direct pointers without offset - * - 'R' For a struct resource pointer, print: - * R address range only ([0x0-0x1f]) - * Rt type and range ([mem 0x0-0x1f 64bit pref]) - * Rf type, range, and flags ([mem 0x0-0x1f 64bit pref flags 0x1]) + * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref] + * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201] * - 'M' For a 6-byte MAC address, it prints the address in the * usual colon-separated hex notation * - 'm' For a 6-byte MAC address, it prints the hex address without colons @@ -881,6 +885,7 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, case 'S': return symbol_string(buf, end, ptr, spec, *fmt); case 'R': + case 'r': return resource_string(buf, end, ptr, spec, fmt); case 'M': /* Colon separated: 00:01:02:03:04:05 */ case 'm': /* Contiguous: 000102030405 */ -- cgit v1.2.2