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