diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/vsprintf.c | 87 |
1 files changed, 70 insertions, 17 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 33bed5e67a21..6438cd5599ee 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
| @@ -595,37 +595,89 @@ static char *symbol_string(char *buf, char *end, void *ptr, | |||
| 595 | } | 595 | } |
| 596 | 596 | ||
| 597 | static char *resource_string(char *buf, char *end, struct resource *res, | 597 | static char *resource_string(char *buf, char *end, struct resource *res, |
| 598 | struct printf_spec spec) | 598 | struct printf_spec spec, const char *fmt) |
| 599 | { | 599 | { |
| 600 | #ifndef IO_RSRC_PRINTK_SIZE | 600 | #ifndef IO_RSRC_PRINTK_SIZE |
| 601 | #define IO_RSRC_PRINTK_SIZE 4 | 601 | #define IO_RSRC_PRINTK_SIZE 6 |
| 602 | #endif | 602 | #endif |
| 603 | 603 | ||
| 604 | #ifndef MEM_RSRC_PRINTK_SIZE | 604 | #ifndef MEM_RSRC_PRINTK_SIZE |
| 605 | #define MEM_RSRC_PRINTK_SIZE 8 | 605 | #define MEM_RSRC_PRINTK_SIZE 10 |
| 606 | #endif | 606 | #endif |
| 607 | struct printf_spec num_spec = { | 607 | struct printf_spec hex_spec = { |
| 608 | .base = 16, | 608 | .base = 16, |
| 609 | .precision = -1, | 609 | .precision = -1, |
| 610 | .flags = SPECIAL | SMALL | ZEROPAD, | 610 | .flags = SPECIAL | SMALL | ZEROPAD, |
| 611 | }; | 611 | }; |
| 612 | /* room for the actual numbers, the two "0x", -, [, ] and the final zero */ | 612 | struct printf_spec dec_spec = { |
| 613 | char sym[4*sizeof(resource_size_t) + 8]; | 613 | .base = 10, |
| 614 | .precision = -1, | ||
| 615 | .flags = 0, | ||
| 616 | }; | ||
| 617 | struct printf_spec str_spec = { | ||
| 618 | .field_width = -1, | ||
| 619 | .precision = 10, | ||
| 620 | .flags = LEFT, | ||
| 621 | }; | ||
| 622 | struct printf_spec flag_spec = { | ||
| 623 | .base = 16, | ||
| 624 | .precision = -1, | ||
| 625 | .flags = SPECIAL | SMALL, | ||
| 626 | }; | ||
| 627 | |||
| 628 | /* 32-bit res (sizeof==4): 10 chars in dec, 10 in hex ("0x" + 8) | ||
| 629 | * 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */ | ||
| 630 | #define RSRC_BUF_SIZE ((2 * sizeof(resource_size_t)) + 4) | ||
| 631 | #define FLAG_BUF_SIZE (2 * sizeof(res->flags)) | ||
| 632 | #define DECODED_BUF_SIZE sizeof("[mem - 64bit pref disabled]") | ||
| 633 | #define RAW_BUF_SIZE sizeof("[mem - flags 0x]") | ||
| 634 | char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE, | ||
| 635 | 2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)]; | ||
| 636 | |||
| 614 | char *p = sym, *pend = sym + sizeof(sym); | 637 | char *p = sym, *pend = sym + sizeof(sym); |
| 615 | int size = -1; | 638 | int size = -1, addr = 0; |
| 639 | int decode = (fmt[0] == 'R') ? 1 : 0; | ||
| 616 | 640 | ||
| 617 | if (res->flags & IORESOURCE_IO) | 641 | if (res->flags & IORESOURCE_IO) { |
| 618 | size = IO_RSRC_PRINTK_SIZE; | 642 | size = IO_RSRC_PRINTK_SIZE; |
| 619 | else if (res->flags & IORESOURCE_MEM) | 643 | addr = 1; |
| 644 | } else if (res->flags & IORESOURCE_MEM) { | ||
| 620 | size = MEM_RSRC_PRINTK_SIZE; | 645 | size = MEM_RSRC_PRINTK_SIZE; |
| 646 | addr = 1; | ||
| 647 | } | ||
| 621 | 648 | ||
| 622 | *p++ = '['; | 649 | *p++ = '['; |
| 623 | num_spec.field_width = size; | 650 | if (res->flags & IORESOURCE_IO) |
| 624 | p = number(p, pend, res->start, num_spec); | 651 | p = string(p, pend, "io ", str_spec); |
| 625 | *p++ = '-'; | 652 | else if (res->flags & IORESOURCE_MEM) |
| 626 | p = number(p, pend, res->end, num_spec); | 653 | p = string(p, pend, "mem ", str_spec); |
| 654 | else if (res->flags & IORESOURCE_IRQ) | ||
| 655 | p = string(p, pend, "irq ", str_spec); | ||
| 656 | else if (res->flags & IORESOURCE_DMA) | ||
| 657 | p = string(p, pend, "dma ", str_spec); | ||
| 658 | else { | ||
| 659 | p = string(p, pend, "??? ", str_spec); | ||
| 660 | decode = 0; | ||
| 661 | } | ||
| 662 | hex_spec.field_width = size; | ||
| 663 | p = number(p, pend, res->start, addr ? hex_spec : dec_spec); | ||
| 664 | if (res->start != res->end) { | ||
| 665 | *p++ = '-'; | ||
| 666 | p = number(p, pend, res->end, addr ? hex_spec : dec_spec); | ||
| 667 | } | ||
| 668 | if (decode) { | ||
| 669 | if (res->flags & IORESOURCE_MEM_64) | ||
| 670 | p = string(p, pend, " 64bit", str_spec); | ||
| 671 | if (res->flags & IORESOURCE_PREFETCH) | ||
| 672 | p = string(p, pend, " pref", str_spec); | ||
| 673 | if (res->flags & IORESOURCE_DISABLED) | ||
| 674 | p = string(p, pend, " disabled", str_spec); | ||
| 675 | } else { | ||
| 676 | p = string(p, pend, " flags ", str_spec); | ||
| 677 | p = number(p, pend, res->flags, flag_spec); | ||
| 678 | } | ||
| 627 | *p++ = ']'; | 679 | *p++ = ']'; |
| 628 | *p = 0; | 680 | *p = '\0'; |
| 629 | 681 | ||
| 630 | return string(buf, end, sym, spec); | 682 | return string(buf, end, sym, spec); |
| 631 | } | 683 | } |
| @@ -801,8 +853,8 @@ static char *ip4_addr_string(char *buf, char *end, const u8 *addr, | |||
| 801 | * - 'f' For simple symbolic function names without offset | 853 | * - 'f' For simple symbolic function names without offset |
| 802 | * - 'S' For symbolic direct pointers with offset | 854 | * - 'S' For symbolic direct pointers with offset |
| 803 | * - 's' For symbolic direct pointers without offset | 855 | * - 's' For symbolic direct pointers without offset |
| 804 | * - 'R' For a struct resource pointer, it prints the range of | 856 | * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref] |
| 805 | * addresses (not the name nor the flags) | 857 | * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201] |
| 806 | * - 'M' For a 6-byte MAC address, it prints the address in the | 858 | * - 'M' For a 6-byte MAC address, it prints the address in the |
| 807 | * usual colon-separated hex notation | 859 | * usual colon-separated hex notation |
| 808 | * - 'm' For a 6-byte MAC address, it prints the hex address without colons | 860 | * - 'm' For a 6-byte MAC address, it prints the hex address without colons |
| @@ -833,7 +885,8 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
| 833 | case 'S': | 885 | case 'S': |
| 834 | return symbol_string(buf, end, ptr, spec, *fmt); | 886 | return symbol_string(buf, end, ptr, spec, *fmt); |
| 835 | case 'R': | 887 | case 'R': |
| 836 | return resource_string(buf, end, ptr, spec); | 888 | case 'r': |
| 889 | return resource_string(buf, end, ptr, spec, fmt); | ||
| 837 | case 'M': /* Colon separated: 00:01:02:03:04:05 */ | 890 | case 'M': /* Colon separated: 00:01:02:03:04:05 */ |
| 838 | case 'm': /* Contiguous: 000102030405 */ | 891 | case 'm': /* Contiguous: 000102030405 */ |
| 839 | return mac_address_string(buf, end, ptr, spec, fmt); | 892 | return mac_address_string(buf, end, ptr, spec, fmt); |
