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 |
