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); |