Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/boot: Add decimal conversion specifiers to boot_printk()

Enable the boot_printk() function to print decimal values. Add the 'd',
'i', and 'u' conversion specifiers support.

Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>

authored by

Vasily Gorbik and committed by
Alexander Gordeev
92b712fa 3d846daa

+40 -4
+40 -4
arch/s390/boot/printk.c
··· 13 13 14 14 const char hex_asc[] = "0123456789abcdef"; 15 15 16 - #define MAX_NUMLEN 17 17 16 static char *as_hex(char *dst, unsigned long val, int pad) 18 17 { 19 18 char *p = dst + max(pad, (int)__fls(val | 1) / 4 + 1); ··· 22 23 return dst; 23 24 } 24 25 26 + #define MAX_NUMLEN 21 27 + static char *as_dec(char *buf, unsigned long val, bool is_signed) 28 + { 29 + bool negative = false; 30 + char *p = buf + MAX_NUMLEN; 31 + 32 + if (is_signed && (long)val < 0) { 33 + val = (val == LONG_MIN ? LONG_MIN : -(long)val); 34 + negative = true; 35 + } 36 + 37 + *--p = '\0'; 38 + do { 39 + *--p = '0' + (val % 10); 40 + val /= 10; 41 + } while (val); 42 + 43 + if (negative) 44 + *--p = '-'; 45 + return p; 46 + } 47 + 25 48 static ssize_t strpad(char *dst, size_t dst_size, const char *src, 26 - int _pad, bool zero_pad) 49 + int _pad, bool zero_pad, bool decimal) 27 50 { 28 51 ssize_t len = strlen(src), pad = _pad; 29 52 char *p = dst; ··· 54 33 return -E2BIG; 55 34 56 35 if (pad > len) { 36 + if (decimal && zero_pad && *src == '-') { 37 + *p++ = '-'; 38 + src++; 39 + len--; 40 + pad--; 41 + } 57 42 memset(p, zero_pad ? '0' : ' ', pad - len); 58 43 p += pad - len; 59 44 } ··· 142 115 { 143 116 char buf[1024] = { 0 }; 144 117 char *end = buf + sizeof(buf) - 1; /* make sure buf is 0 terminated */ 145 - bool zero_pad; 118 + bool zero_pad, decimal; 146 119 char *strval, *p = buf; 147 120 char valbuf[MAX(MAX_SYMLEN, MAX_NUMLEN)]; 148 121 va_list args; ··· 167 140 lenmod = 'H'; 168 141 fmt++; 169 142 } 143 + decimal = false; 170 144 switch (*fmt) { 171 145 case 's': 172 146 if (lenmod) ··· 181 153 strval = strsym(valbuf, va_arg(args, void *)); 182 154 zero_pad = false; 183 155 break; 156 + case 'd': 157 + case 'i': 158 + strval = as_dec(valbuf, va_arg_len_type(args, lenmod, signed), 1); 159 + decimal = true; 160 + break; 161 + case 'u': 162 + strval = as_dec(valbuf, va_arg_len_type(args, lenmod, unsigned), 0); 163 + break; 184 164 case 'x': 185 165 strval = as_hex(valbuf, va_arg_len_type(args, lenmod, unsigned), 0); 186 166 break; 187 167 default: 188 168 goto out; 189 169 } 190 - len = strpad(p, end - p, strval, pad, zero_pad); 170 + len = strpad(p, end - p, strval, pad, zero_pad, decimal); 191 171 if (len == -E2BIG) 192 172 break; 193 173 p += len;