aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-10-20 00:07:34 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-20 12:12:32 -0400
commit332d2e7834986a9326ec3fa6a91641daef81746c (patch)
tree06a7bdc9675485577080b5af964fd6480a2670fa /lib
parent88e366217e8f75bd7eab64f4aa4ff9583070b0af (diff)
Implement %pR to print struct resource content
Add a %pR option to the kernel vsnprintf that prints the range of addresses inside a struct resource passed by pointer. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/vsprintf.c49
1 files changed, 43 insertions, 6 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index cceecb6a963d..a013bbc23717 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -24,6 +24,7 @@
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/kallsyms.h> 25#include <linux/kallsyms.h>
26#include <linux/uaccess.h> 26#include <linux/uaccess.h>
27#include <linux/ioport.h>
27 28
28#include <asm/page.h> /* for PAGE_SIZE */ 29#include <asm/page.h> /* for PAGE_SIZE */
29#include <asm/div64.h> 30#include <asm/div64.h>
@@ -550,18 +551,51 @@ static char *symbol_string(char *buf, char *end, void *ptr, int field_width, int
550#endif 551#endif
551} 552}
552 553
554static char *resource_string(char *buf, char *end, struct resource *res, int field_width, int precision, int flags)
555{
556#ifndef IO_RSRC_PRINTK_SIZE
557#define IO_RSRC_PRINTK_SIZE 4
558#endif
559
560#ifndef MEM_RSRC_PRINTK_SIZE
561#define MEM_RSRC_PRINTK_SIZE 8
562#endif
563
564 /* room for the actual numbers, the two "0x", -, [, ] and the final zero */
565 char sym[4*sizeof(resource_size_t) + 8];
566 char *p = sym, *pend = sym + sizeof(sym);
567 int size = -1;
568
569 if (res->flags & IORESOURCE_IO)
570 size = IO_RSRC_PRINTK_SIZE;
571 else if (res->flags & IORESOURCE_MEM)
572 size = MEM_RSRC_PRINTK_SIZE;
573
574 *p++ = '[';
575 p = number(p, pend, res->start, 16, size, -1, SPECIAL | SMALL | ZEROPAD);
576 *p++ = '-';
577 p = number(p, pend, res->end, 16, size, -1, SPECIAL | SMALL | ZEROPAD);
578 *p++ = ']';
579 *p = 0;
580
581 return string(buf, end, sym, field_width, precision, flags);
582}
583
553/* 584/*
554 * Show a '%p' thing. A kernel extension is that the '%p' is followed 585 * Show a '%p' thing. A kernel extension is that the '%p' is followed
555 * by an extra set of alphanumeric characters that are extended format 586 * by an extra set of alphanumeric characters that are extended format
556 * specifiers. 587 * specifiers.
557 * 588 *
558 * Right now we just handle 'F' (for symbolic Function descriptor pointers) 589 * Right now we handle:
559 * and 'S' (for Symbolic direct pointers), but this can easily be 590 *
560 * extended in the future (network address types etc). 591 * - 'F' For symbolic function descriptor pointers
592 * - 'S' For symbolic direct pointers
593 * - 'R' For a struct resource pointer, it prints the range of
594 * addresses (not the name nor the flags)
561 * 595 *
562 * The difference between 'S' and 'F' is that on ia64 and ppc64 function 596 * Note: The difference between 'S' and 'F' is that on ia64 and ppc64
563 * pointers are really function descriptors, which contain a pointer the 597 * function pointers are really function descriptors, which contain a
564 * real address. 598 * pointer to the real address.
565 */ 599 */
566static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field_width, int precision, int flags) 600static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field_width, int precision, int flags)
567{ 601{
@@ -571,6 +605,8 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field
571 /* Fallthrough */ 605 /* Fallthrough */
572 case 'S': 606 case 'S':
573 return symbol_string(buf, end, ptr, field_width, precision, flags); 607 return symbol_string(buf, end, ptr, field_width, precision, flags);
608 case 'R':
609 return resource_string(buf, end, ptr, field_width, precision, flags);
574 } 610 }
575 flags |= SMALL; 611 flags |= SMALL;
576 if (field_width == -1) { 612 if (field_width == -1) {
@@ -590,6 +626,7 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field
590 * This function follows C99 vsnprintf, but has some extensions: 626 * This function follows C99 vsnprintf, but has some extensions:
591 * %pS output the name of a text symbol 627 * %pS output the name of a text symbol
592 * %pF output the name of a function pointer 628 * %pF output the name of a function pointer
629 * %pR output the address range in a struct resource
593 * 630 *
594 * The return value is the number of characters which would 631 * The return value is the number of characters which would
595 * be generated for the given input, excluding the trailing 632 * be generated for the given input, excluding the trailing