diff options
-rw-r--r-- | lib/vsprintf.c | 49 |
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 | ||
554 | static 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 | */ |
566 | static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field_width, int precision, int flags) | 600 | static 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 |