Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / acpi / acpica / utprint.c
1 /******************************************************************************
2  *
3  * Module Name: utprint - Formatted printing routines
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2015, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43
44 #include <acpi/acpi.h>
45 #include "accommon.h"
46
47 #define _COMPONENT          ACPI_UTILITIES
48 ACPI_MODULE_NAME("utprint")
49
50 #define ACPI_FORMAT_SIGN            0x01
51 #define ACPI_FORMAT_SIGN_PLUS       0x02
52 #define ACPI_FORMAT_SIGN_PLUS_SPACE 0x04
53 #define ACPI_FORMAT_ZERO            0x08
54 #define ACPI_FORMAT_LEFT            0x10
55 #define ACPI_FORMAT_UPPER           0x20
56 #define ACPI_FORMAT_PREFIX          0x40
57 /* Local prototypes */
58 static acpi_size
59 acpi_ut_bound_string_length(const char *string, acpi_size count);
60
61 static char *acpi_ut_bound_string_output(char *string, const char *end, char c);
62
63 static char *acpi_ut_format_number(char *string,
64                                    char *end,
65                                    u64 number,
66                                    u8 base, s32 width, s32 precision, u8 type);
67
68 static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper);
69
70 /* Module globals */
71
72 static const char acpi_gbl_lower_hex_digits[] = "0123456789abcdef";
73 static const char acpi_gbl_upper_hex_digits[] = "0123456789ABCDEF";
74
75 /*******************************************************************************
76  *
77  * FUNCTION:    acpi_ut_bound_string_length
78  *
79  * PARAMETERS:  string              - String with boundary
80  *              count               - Boundary of the string
81  *
82  * RETURN:      Length of the string. Less than or equal to Count.
83  *
84  * DESCRIPTION: Calculate the length of a string with boundary.
85  *
86  ******************************************************************************/
87
88 static acpi_size
89 acpi_ut_bound_string_length(const char *string, acpi_size count)
90 {
91         u32 length = 0;
92
93         while (*string && count) {
94                 length++;
95                 string++;
96                 count--;
97         }
98
99         return (length);
100 }
101
102 /*******************************************************************************
103  *
104  * FUNCTION:    acpi_ut_bound_string_output
105  *
106  * PARAMETERS:  string              - String with boundary
107  *              end                 - Boundary of the string
108  *              c                   - Character to be output to the string
109  *
110  * RETURN:      Updated position for next valid character
111  *
112  * DESCRIPTION: Output a character into a string with boundary check.
113  *
114  ******************************************************************************/
115
116 static char *acpi_ut_bound_string_output(char *string, const char *end, char c)
117 {
118
119         if (string < end) {
120                 *string = c;
121         }
122
123         ++string;
124         return (string);
125 }
126
127 /*******************************************************************************
128  *
129  * FUNCTION:    acpi_ut_put_number
130  *
131  * PARAMETERS:  string              - Buffer to hold reverse-ordered string
132  *              number              - Integer to be converted
133  *              base                - Base of the integer
134  *              upper               - Whether or not using upper cased digits
135  *
136  * RETURN:      Updated position for next valid character
137  *
138  * DESCRIPTION: Convert an integer into a string, note that, the string holds a
139  *              reversed ordered number without the trailing zero.
140  *
141  ******************************************************************************/
142
143 static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper)
144 {
145         const char *digits;
146         u64 digit_index;
147         char *pos;
148
149         pos = string;
150         digits = upper ? acpi_gbl_upper_hex_digits : acpi_gbl_lower_hex_digits;
151
152         if (number == 0) {
153                 *(pos++) = '0';
154         } else {
155                 while (number) {
156                         (void)acpi_ut_divide(number, base, &number,
157                                              &digit_index);
158                         *(pos++) = digits[digit_index];
159                 }
160         }
161
162         /* *(Pos++) = '0'; */
163         return (pos);
164 }
165
166 /*******************************************************************************
167  *
168  * FUNCTION:    acpi_ut_scan_number
169  *
170  * PARAMETERS:  string              - String buffer
171  *              number_ptr          - Where the number is returned
172  *
173  * RETURN:      Updated position for next valid character
174  *
175  * DESCRIPTION: Scan a string for a decimal integer.
176  *
177  ******************************************************************************/
178
179 const char *acpi_ut_scan_number(const char *string, u64 *number_ptr)
180 {
181         u64 number = 0;
182
183         while (ACPI_IS_DIGIT(*string)) {
184                 number *= 10;
185                 number += *(string++) - '0';
186         }
187
188         *number_ptr = number;
189         return (string);
190 }
191
192 /*******************************************************************************
193  *
194  * FUNCTION:    acpi_ut_print_number
195  *
196  * PARAMETERS:  string              - String buffer
197  *              number              - The number to be converted
198  *
199  * RETURN:      Updated position for next valid character
200  *
201  * DESCRIPTION: Print a decimal integer into a string.
202  *
203  ******************************************************************************/
204
205 const char *acpi_ut_print_number(char *string, u64 number)
206 {
207         char ascii_string[20];
208         const char *pos1;
209         char *pos2;
210
211         pos1 = acpi_ut_put_number(ascii_string, number, 10, FALSE);
212         pos2 = string;
213
214         while (pos1 != ascii_string) {
215                 *(pos2++) = *(--pos1);
216         }
217
218         *pos2 = 0;
219         return (string);
220 }
221
222 /*******************************************************************************
223  *
224  * FUNCTION:    acpi_ut_format_number
225  *
226  * PARAMETERS:  string              - String buffer with boundary
227  *              end                 - Boundary of the string
228  *              number              - The number to be converted
229  *              base                - Base of the integer
230  *              width               - Field width
231  *              precision           - Precision of the integer
232  *              type                - Special printing flags
233  *
234  * RETURN:      Updated position for next valid character
235  *
236  * DESCRIPTION: Print an integer into a string with any base and any precision.
237  *
238  ******************************************************************************/
239
240 static char *acpi_ut_format_number(char *string,
241                                    char *end,
242                                    u64 number,
243                                    u8 base, s32 width, s32 precision, u8 type)
244 {
245         char *pos;
246         char sign;
247         char zero;
248         u8 need_prefix;
249         u8 upper;
250         s32 i;
251         char reversed_string[66];
252
253         /* Parameter validation */
254
255         if (base < 2 || base > 16) {
256                 return (NULL);
257         }
258
259         if (type & ACPI_FORMAT_LEFT) {
260                 type &= ~ACPI_FORMAT_ZERO;
261         }
262
263         need_prefix = ((type & ACPI_FORMAT_PREFIX)
264                        && base != 10) ? TRUE : FALSE;
265         upper = (type & ACPI_FORMAT_UPPER) ? TRUE : FALSE;
266         zero = (type & ACPI_FORMAT_ZERO) ? '0' : ' ';
267
268         /* Calculate size according to sign and prefix */
269
270         sign = '\0';
271         if (type & ACPI_FORMAT_SIGN) {
272                 if ((s64) number < 0) {
273                         sign = '-';
274                         number = -(s64) number;
275                         width--;
276                 } else if (type & ACPI_FORMAT_SIGN_PLUS) {
277                         sign = '+';
278                         width--;
279                 } else if (type & ACPI_FORMAT_SIGN_PLUS_SPACE) {
280                         sign = ' ';
281                         width--;
282                 }
283         }
284         if (need_prefix) {
285                 width--;
286                 if (base == 16) {
287                         width--;
288                 }
289         }
290
291         /* Generate full string in reverse order */
292
293         pos = acpi_ut_put_number(reversed_string, number, base, upper);
294         i = ACPI_PTR_DIFF(pos, reversed_string);
295
296         /* Printing 100 using %2d gives "100", not "00" */
297
298         if (i > precision) {
299                 precision = i;
300         }
301
302         width -= precision;
303
304         /* Output the string */
305
306         if (!(type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT))) {
307                 while (--width >= 0) {
308                         string = acpi_ut_bound_string_output(string, end, ' ');
309                 }
310         }
311         if (sign) {
312                 string = acpi_ut_bound_string_output(string, end, sign);
313         }
314         if (need_prefix) {
315                 string = acpi_ut_bound_string_output(string, end, '0');
316                 if (base == 16) {
317                         string = acpi_ut_bound_string_output(string, end,
318                                                              upper ? 'X' : 'x');
319                 }
320         }
321         if (!(type & ACPI_FORMAT_LEFT)) {
322                 while (--width >= 0) {
323                         string = acpi_ut_bound_string_output(string, end, zero);
324                 }
325         }
326
327         while (i <= --precision) {
328                 string = acpi_ut_bound_string_output(string, end, '0');
329         }
330         while (--i >= 0) {
331                 string = acpi_ut_bound_string_output(string, end,
332                                                      reversed_string[i]);
333         }
334         while (--width >= 0) {
335                 string = acpi_ut_bound_string_output(string, end, ' ');
336         }
337
338         return (string);
339 }
340
341 /*******************************************************************************
342  *
343  * FUNCTION:    acpi_ut_vsnprintf
344  *
345  * PARAMETERS:  string              - String with boundary
346  *              size                - Boundary of the string
347  *              format              - Standard printf format
348  *              args                - Argument list
349  *
350  * RETURN:      Number of bytes actually written.
351  *
352  * DESCRIPTION: Formatted output to a string using argument list pointer.
353  *
354  ******************************************************************************/
355
356 int
357 acpi_ut_vsnprintf(char *string,
358                   acpi_size size, const char *format, va_list args)
359 {
360         u8 base;
361         u8 type;
362         s32 width;
363         s32 precision;
364         char qualifier;
365         u64 number;
366         char *pos;
367         char *end;
368         char c;
369         const char *s;
370         const void *p;
371         s32 length;
372         int i;
373
374         pos = string;
375         end = string + size;
376
377         for (; *format; ++format) {
378                 if (*format != '%') {
379                         pos = acpi_ut_bound_string_output(pos, end, *format);
380                         continue;
381                 }
382
383                 type = 0;
384                 base = 10;
385
386                 /* Process sign */
387
388                 do {
389                         ++format;
390                         if (*format == '#') {
391                                 type |= ACPI_FORMAT_PREFIX;
392                         } else if (*format == '0') {
393                                 type |= ACPI_FORMAT_ZERO;
394                         } else if (*format == '+') {
395                                 type |= ACPI_FORMAT_SIGN_PLUS;
396                         } else if (*format == ' ') {
397                                 type |= ACPI_FORMAT_SIGN_PLUS_SPACE;
398                         } else if (*format == '-') {
399                                 type |= ACPI_FORMAT_LEFT;
400                         } else {
401                                 break;
402                         }
403                 } while (1);
404
405                 /* Process width */
406
407                 width = -1;
408                 if (ACPI_IS_DIGIT(*format)) {
409                         format = acpi_ut_scan_number(format, &number);
410                         width = (s32) number;
411                 } else if (*format == '*') {
412                         ++format;
413                         width = va_arg(args, int);
414                         if (width < 0) {
415                                 width = -width;
416                                 type |= ACPI_FORMAT_LEFT;
417                         }
418                 }
419
420                 /* Process precision */
421
422                 precision = -1;
423                 if (*format == '.') {
424                         ++format;
425                         if (ACPI_IS_DIGIT(*format)) {
426                                 format = acpi_ut_scan_number(format, &number);
427                                 precision = (s32) number;
428                         } else if (*format == '*') {
429                                 ++format;
430                                 precision = va_arg(args, int);
431                         }
432                         if (precision < 0) {
433                                 precision = 0;
434                         }
435                 }
436
437                 /* Process qualifier */
438
439                 qualifier = -1;
440                 if (*format == 'h' || *format == 'l' || *format == 'L') {
441                         qualifier = *format;
442                         ++format;
443
444                         if (qualifier == 'l' && *format == 'l') {
445                                 qualifier = 'L';
446                                 ++format;
447                         }
448                 }
449
450                 switch (*format) {
451                 case '%':
452
453                         pos = acpi_ut_bound_string_output(pos, end, '%');
454                         continue;
455
456                 case 'c':
457
458                         if (!(type & ACPI_FORMAT_LEFT)) {
459                                 while (--width > 0) {
460                                         pos =
461                                             acpi_ut_bound_string_output(pos,
462                                                                         end,
463                                                                         ' ');
464                                 }
465                         }
466
467                         c = (char)va_arg(args, int);
468                         pos = acpi_ut_bound_string_output(pos, end, c);
469
470                         while (--width > 0) {
471                                 pos =
472                                     acpi_ut_bound_string_output(pos, end, ' ');
473                         }
474                         continue;
475
476                 case 's':
477
478                         s = va_arg(args, char *);
479                         if (!s) {
480                                 s = "<NULL>";
481                         }
482                         length = acpi_ut_bound_string_length(s, precision);
483                         if (!(type & ACPI_FORMAT_LEFT)) {
484                                 while (length < width--) {
485                                         pos =
486                                             acpi_ut_bound_string_output(pos,
487                                                                         end,
488                                                                         ' ');
489                                 }
490                         }
491                         for (i = 0; i < length; ++i) {
492                                 pos = acpi_ut_bound_string_output(pos, end, *s);
493                                 ++s;
494                         }
495                         while (length < width--) {
496                                 pos =
497                                     acpi_ut_bound_string_output(pos, end, ' ');
498                         }
499                         continue;
500
501                 case 'o':
502
503                         base = 8;
504                         break;
505
506                 case 'X':
507
508                         type |= ACPI_FORMAT_UPPER;
509
510                 case 'x':
511
512                         base = 16;
513                         break;
514
515                 case 'd':
516                 case 'i':
517
518                         type |= ACPI_FORMAT_SIGN;
519
520                 case 'u':
521
522                         break;
523
524                 case 'p':
525
526                         if (width == -1) {
527                                 width = 2 * sizeof(void *);
528                                 type |= ACPI_FORMAT_ZERO;
529                         }
530
531                         p = va_arg(args, void *);
532                         pos = acpi_ut_format_number(pos, end,
533                                                     ACPI_TO_INTEGER(p), 16,
534                                                     width, precision, type);
535                         continue;
536
537                 default:
538
539                         pos = acpi_ut_bound_string_output(pos, end, '%');
540                         if (*format) {
541                                 pos =
542                                     acpi_ut_bound_string_output(pos, end,
543                                                                 *format);
544                         } else {
545                                 --format;
546                         }
547                         continue;
548                 }
549
550                 if (qualifier == 'L') {
551                         number = va_arg(args, u64);
552                         if (type & ACPI_FORMAT_SIGN) {
553                                 number = (s64) number;
554                         }
555                 } else if (qualifier == 'l') {
556                         number = va_arg(args, unsigned long);
557                         if (type & ACPI_FORMAT_SIGN) {
558                                 number = (s32) number;
559                         }
560                 } else if (qualifier == 'h') {
561                         number = (u16)va_arg(args, int);
562                         if (type & ACPI_FORMAT_SIGN) {
563                                 number = (s16) number;
564                         }
565                 } else {
566                         number = va_arg(args, unsigned int);
567                         if (type & ACPI_FORMAT_SIGN) {
568                                 number = (signed int)number;
569                         }
570                 }
571
572                 pos = acpi_ut_format_number(pos, end, number, base,
573                                             width, precision, type);
574         }
575
576         if (size > 0) {
577                 if (pos < end) {
578                         *pos = '\0';
579                 } else {
580                         end[-1] = '\0';
581                 }
582         }
583
584         return (ACPI_PTR_DIFF(pos, string));
585 }
586
587 /*******************************************************************************
588  *
589  * FUNCTION:    acpi_ut_snprintf
590  *
591  * PARAMETERS:  string              - String with boundary
592  *              size                - Boundary of the string
593  *              Format, ...         - Standard printf format
594  *
595  * RETURN:      Number of bytes actually written.
596  *
597  * DESCRIPTION: Formatted output to a string.
598  *
599  ******************************************************************************/
600
601 int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...)
602 {
603         va_list args;
604         int length;
605
606         va_start(args, format);
607         length = acpi_ut_vsnprintf(string, size, format, args);
608         va_end(args);
609
610         return (length);
611 }
612
613 #ifdef ACPI_APPLICATION
614 /*******************************************************************************
615  *
616  * FUNCTION:    acpi_ut_file_vprintf
617  *
618  * PARAMETERS:  file                - File descriptor
619  *              format              - Standard printf format
620  *              args                - Argument list
621  *
622  * RETURN:      Number of bytes actually written.
623  *
624  * DESCRIPTION: Formatted output to a file using argument list pointer.
625  *
626  ******************************************************************************/
627
628 int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args)
629 {
630         acpi_cpu_flags flags;
631         int length;
632
633         flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
634         length = acpi_ut_vsnprintf(acpi_gbl_print_buffer,
635                                    sizeof(acpi_gbl_print_buffer), format, args);
636
637         (void)acpi_os_write_file(file, acpi_gbl_print_buffer, length, 1);
638         acpi_os_release_lock(acpi_gbl_print_lock, flags);
639
640         return (length);
641 }
642
643 /*******************************************************************************
644  *
645  * FUNCTION:    acpi_ut_file_printf
646  *
647  * PARAMETERS:  file                - File descriptor
648  *              Format, ...         - Standard printf format
649  *
650  * RETURN:      Number of bytes actually written.
651  *
652  * DESCRIPTION: Formatted output to a file.
653  *
654  ******************************************************************************/
655
656 int acpi_ut_file_printf(ACPI_FILE file, const char *format, ...)
657 {
658         va_list args;
659         int length;
660
661         va_start(args, format);
662         length = acpi_ut_file_vprintf(file, format, args);
663         va_end(args);
664
665         return (length);
666 }
667 #endif