Merge remote-tracking branch 'asoc/fix/rt5670' into asoc-linus
[firefly-linux-kernel-4.4.55.git] / 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 = 10;
361         u8 type = 0;
362         s32 width = -1;
363         s32 precision = -1;
364         char qualifier = 0;
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                 /* Process sign */
384
385                 do {
386                         ++format;
387                         if (*format == '#') {
388                                 type |= ACPI_FORMAT_PREFIX;
389                         } else if (*format == '0') {
390                                 type |= ACPI_FORMAT_ZERO;
391                         } else if (*format == '+') {
392                                 type |= ACPI_FORMAT_SIGN_PLUS;
393                         } else if (*format == ' ') {
394                                 type |= ACPI_FORMAT_SIGN_PLUS_SPACE;
395                         } else if (*format == '-') {
396                                 type |= ACPI_FORMAT_LEFT;
397                         } else {
398                                 break;
399                         }
400                 } while (1);
401
402                 /* Process width */
403
404                 width = -1;
405                 if (ACPI_IS_DIGIT(*format)) {
406                         format = acpi_ut_scan_number(format, &number);
407                         width = (s32) number;
408                 } else if (*format == '*') {
409                         ++format;
410                         width = va_arg(args, int);
411                         if (width < 0) {
412                                 width = -width;
413                                 type |= ACPI_FORMAT_LEFT;
414                         }
415                 }
416
417                 /* Process precision */
418
419                 precision = -1;
420                 if (*format == '.') {
421                         ++format;
422                         if (ACPI_IS_DIGIT(*format)) {
423                                 format = acpi_ut_scan_number(format, &number);
424                                 precision = (s32) number;
425                         } else if (*format == '*') {
426                                 ++format;
427                                 precision = va_arg(args, int);
428                         }
429                         if (precision < 0) {
430                                 precision = 0;
431                         }
432                 }
433
434                 /* Process qualifier */
435
436                 qualifier = -1;
437                 if (*format == 'h' || *format == 'l' || *format == 'L') {
438                         qualifier = *format;
439                         ++format;
440
441                         if (qualifier == 'l' && *format == 'l') {
442                                 qualifier = 'L';
443                                 ++format;
444                         }
445                 }
446
447                 switch (*format) {
448                 case '%':
449
450                         pos = acpi_ut_bound_string_output(pos, end, '%');
451                         continue;
452
453                 case 'c':
454
455                         if (!(type & ACPI_FORMAT_LEFT)) {
456                                 while (--width > 0) {
457                                         pos =
458                                             acpi_ut_bound_string_output(pos,
459                                                                         end,
460                                                                         ' ');
461                                 }
462                         }
463
464                         c = (char)va_arg(args, int);
465                         pos = acpi_ut_bound_string_output(pos, end, c);
466
467                         while (--width > 0) {
468                                 pos =
469                                     acpi_ut_bound_string_output(pos, end, ' ');
470                         }
471                         continue;
472
473                 case 's':
474
475                         s = va_arg(args, char *);
476                         if (!s) {
477                                 s = "<NULL>";
478                         }
479                         length = acpi_ut_bound_string_length(s, precision);
480                         if (!(type & ACPI_FORMAT_LEFT)) {
481                                 while (length < width--) {
482                                         pos =
483                                             acpi_ut_bound_string_output(pos,
484                                                                         end,
485                                                                         ' ');
486                                 }
487                         }
488                         for (i = 0; i < length; ++i) {
489                                 pos = acpi_ut_bound_string_output(pos, end, *s);
490                                 ++s;
491                         }
492                         while (length < width--) {
493                                 pos =
494                                     acpi_ut_bound_string_output(pos, end, ' ');
495                         }
496                         continue;
497
498                 case 'o':
499
500                         base = 8;
501                         break;
502
503                 case 'X':
504
505                         type |= ACPI_FORMAT_UPPER;
506
507                 case 'x':
508
509                         base = 16;
510                         break;
511
512                 case 'd':
513                 case 'i':
514
515                         type |= ACPI_FORMAT_SIGN;
516
517                 case 'u':
518
519                         break;
520
521                 case 'p':
522
523                         if (width == -1) {
524                                 width = 2 * sizeof(void *);
525                                 type |= ACPI_FORMAT_ZERO;
526                         }
527
528                         p = va_arg(args, void *);
529                         pos = acpi_ut_format_number(pos, end,
530                                                     ACPI_TO_INTEGER(p), 16,
531                                                     width, precision, type);
532                         continue;
533
534                 default:
535
536                         pos = acpi_ut_bound_string_output(pos, end, '%');
537                         if (*format) {
538                                 pos =
539                                     acpi_ut_bound_string_output(pos, end,
540                                                                 *format);
541                         } else {
542                                 --format;
543                         }
544                         continue;
545                 }
546
547                 if (qualifier == 'L') {
548                         number = va_arg(args, u64);
549                         if (type & ACPI_FORMAT_SIGN) {
550                                 number = (s64) number;
551                         }
552                 } else if (qualifier == 'l') {
553                         number = va_arg(args, unsigned long);
554                         if (type & ACPI_FORMAT_SIGN) {
555                                 number = (s32) number;
556                         }
557                 } else if (qualifier == 'h') {
558                         number = (u16)va_arg(args, int);
559                         if (type & ACPI_FORMAT_SIGN) {
560                                 number = (s16) number;
561                         }
562                 } else {
563                         number = va_arg(args, unsigned int);
564                         if (type & ACPI_FORMAT_SIGN) {
565                                 number = (signed int)number;
566                         }
567                 }
568
569                 pos = acpi_ut_format_number(pos, end, number, base,
570                                             width, precision, type);
571         }
572
573         if (size > 0) {
574                 if (pos < end) {
575                         *pos = '\0';
576                 } else {
577                         end[-1] = '\0';
578                 }
579         }
580
581         return (ACPI_PTR_DIFF(pos, string));
582 }
583
584 /*******************************************************************************
585  *
586  * FUNCTION:    acpi_ut_snprintf
587  *
588  * PARAMETERS:  string              - String with boundary
589  *              size                - Boundary of the string
590  *              Format, ...         - Standard printf format
591  *
592  * RETURN:      Number of bytes actually written.
593  *
594  * DESCRIPTION: Formatted output to a string.
595  *
596  ******************************************************************************/
597
598 int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...)
599 {
600         va_list args;
601         int length;
602
603         va_start(args, format);
604         length = acpi_ut_vsnprintf(string, size, format, args);
605         va_end(args);
606
607         return (length);
608 }
609
610 #ifdef ACPI_APPLICATION
611 /*******************************************************************************
612  *
613  * FUNCTION:    acpi_ut_file_vprintf
614  *
615  * PARAMETERS:  file                - File descriptor
616  *              format              - Standard printf format
617  *              args                - Argument list
618  *
619  * RETURN:      Number of bytes actually written.
620  *
621  * DESCRIPTION: Formatted output to a file using argument list pointer.
622  *
623  ******************************************************************************/
624
625 int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args)
626 {
627         acpi_cpu_flags flags;
628         int length;
629
630         flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
631         length = acpi_ut_vsnprintf(acpi_gbl_print_buffer,
632                                    sizeof(acpi_gbl_print_buffer), format, args);
633
634         (void)acpi_os_write_file(file, acpi_gbl_print_buffer, length, 1);
635         acpi_os_release_lock(acpi_gbl_print_lock, flags);
636
637         return (length);
638 }
639
640 /*******************************************************************************
641  *
642  * FUNCTION:    acpi_ut_file_printf
643  *
644  * PARAMETERS:  file                - File descriptor
645  *              Format, ...         - Standard printf format
646  *
647  * RETURN:      Number of bytes actually written.
648  *
649  * DESCRIPTION: Formatted output to a file.
650  *
651  ******************************************************************************/
652
653 int acpi_ut_file_printf(ACPI_FILE file, const char *format, ...)
654 {
655         va_list args;
656         int length;
657
658         va_start(args, format);
659         length = acpi_ut_file_vprintf(file, format, args);
660         va_end(args);
661
662         return (length);
663 }
664 #endif