OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [acpi/] [utilities/] [utmisc.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*******************************************************************************
2
 *
3
 * Module Name: utmisc - common utility procedures
4
 *
5
 ******************************************************************************/
6
 
7
/*
8
 * Copyright (C) 2000 - 2004, R. Byron Moore
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
 
45
#include <acpi/acpi.h>
46
#include <acpi/acnamesp.h>
47
 
48
 
49
#define _COMPONENT          ACPI_UTILITIES
50
         ACPI_MODULE_NAME    ("utmisc")
51
 
52
 
53
/*******************************************************************************
54
 *
55
 * FUNCTION:    acpi_ut_print_string
56
 *
57
 * PARAMETERS:  String          - Null terminated ASCII string
58
 *
59
 * RETURN:      None
60
 *
61
 * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
62
 *              sequences.
63
 *
64
 ******************************************************************************/
65
 
66
void
67
acpi_ut_print_string (
68
        char                            *string,
69
        u8                              max_length)
70
{
71
        u32                             i;
72
 
73
 
74
        if (!string) {
75
                acpi_os_printf ("<\"NULL STRING PTR\">");
76
                return;
77
        }
78
 
79
        acpi_os_printf ("\"");
80
        for (i = 0; string[i] && (i < max_length); i++) {
81
                /* Escape sequences */
82
 
83
                switch (string[i]) {
84
                case 0x07:
85
                        acpi_os_printf ("\\a");      /* BELL */
86
                        break;
87
 
88
                case 0x08:
89
                        acpi_os_printf ("\\b");     /* BACKSPACE */
90
                        break;
91
 
92
                case 0x0C:
93
                        acpi_os_printf ("\\f");     /* FORMFEED */
94
                        break;
95
 
96
                case 0x0A:
97
                        acpi_os_printf ("\\n");     /* LINEFEED */
98
                        break;
99
 
100
                case 0x0D:
101
                        acpi_os_printf ("\\r");     /* CARRIAGE RETURN*/
102
                        break;
103
 
104
                case 0x09:
105
                        acpi_os_printf ("\\t");     /* HORIZONTAL TAB */
106
                        break;
107
 
108
                case 0x0B:
109
                        acpi_os_printf ("\\v");     /* VERTICAL TAB */
110
                        break;
111
 
112
                case '\'':                      /* Single Quote */
113
                case '\"':                      /* Double Quote */
114
                case '\\':                      /* Backslash */
115
                        acpi_os_printf ("\\%c", (int) string[i]);
116
                        break;
117
 
118
                default:
119
 
120
                        /* Check for printable character or hex escape */
121
 
122
                        if (ACPI_IS_PRINT (string[i]))
123
                        {
124
                                /* This is a normal character */
125
 
126
                                acpi_os_printf ("%c", (int) string[i]);
127
                        }
128
                        else
129
                        {
130
                                /* All others will be Hex escapes */
131
 
132
                                acpi_os_printf ("\\x%2.2X", (s32) string[i]);
133
                        }
134
                        break;
135
                }
136
        }
137
        acpi_os_printf ("\"");
138
 
139
        if (i == max_length && string[i]) {
140
                acpi_os_printf ("...");
141
        }
142
}
143
 
144
 
145
/*******************************************************************************
146
 *
147
 * FUNCTION:    acpi_ut_dword_byte_swap
148
 *
149
 * PARAMETERS:  Value           - Value to be converted
150
 *
151
 * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
152
 *
153
 ******************************************************************************/
154
 
155
u32
156
acpi_ut_dword_byte_swap (
157
        u32                             value)
158
{
159
        union {
160
                u32                         value;
161
                u8                          bytes[4];
162
        } out;
163
 
164
        union {
165
                u32                         value;
166
                u8                          bytes[4];
167
        } in;
168
 
169
 
170
        ACPI_FUNCTION_ENTRY ();
171
 
172
 
173
        in.value = value;
174
 
175
        out.bytes[0] = in.bytes[3];
176
        out.bytes[1] = in.bytes[2];
177
        out.bytes[2] = in.bytes[1];
178
        out.bytes[3] = in.bytes[0];
179
 
180
        return (out.value);
181
}
182
 
183
 
184
/*******************************************************************************
185
 *
186
 * FUNCTION:    acpi_ut_set_integer_width
187
 *
188
 * PARAMETERS:  Revision            From DSDT header
189
 *
190
 * RETURN:      None
191
 *
192
 * DESCRIPTION: Set the global integer bit width based upon the revision
193
 *              of the DSDT.  For Revision 1 and 0, Integers are 32 bits.
194
 *              For Revision 2 and above, Integers are 64 bits.  Yes, this
195
 *              makes a difference.
196
 *
197
 ******************************************************************************/
198
 
199
void
200
acpi_ut_set_integer_width (
201
        u8                              revision)
202
{
203
 
204
        if (revision <= 1) {
205
                acpi_gbl_integer_bit_width = 32;
206
                acpi_gbl_integer_nybble_width = 8;
207
                acpi_gbl_integer_byte_width = 4;
208
        }
209
        else {
210
                acpi_gbl_integer_bit_width = 64;
211
                acpi_gbl_integer_nybble_width = 16;
212
                acpi_gbl_integer_byte_width = 8;
213
        }
214
}
215
 
216
 
217
#ifdef ACPI_DEBUG_OUTPUT
218
/*******************************************************************************
219
 *
220
 * FUNCTION:    acpi_ut_display_init_pathname
221
 *
222
 * PARAMETERS:  obj_handle          - Handle whose pathname will be displayed
223
 *              Path                - Additional path string to be appended.
224
 *                                      (NULL if no extra path)
225
 *
226
 * RETURN:      acpi_status
227
 *
228
 * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
229
 *
230
 ******************************************************************************/
231
 
232
void
233
acpi_ut_display_init_pathname (
234
        u8                              type,
235
        struct acpi_namespace_node      *obj_handle,
236
        char                            *path)
237
{
238
        acpi_status                     status;
239
        struct acpi_buffer              buffer;
240
 
241
 
242
        ACPI_FUNCTION_ENTRY ();
243
 
244
 
245
        /* Only print the path if the appropriate debug level is enabled */
246
 
247
        if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
248
                return;
249
        }
250
 
251
        /* Get the full pathname to the node */
252
 
253
        buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
254
        status = acpi_ns_handle_to_pathname (obj_handle, &buffer);
255
        if (ACPI_FAILURE (status)) {
256
                return;
257
        }
258
 
259
        /* Print what we're doing */
260
 
261
        switch (type) {
262
        case ACPI_TYPE_METHOD:
263
                acpi_os_printf ("Executing  ");
264
                break;
265
 
266
        default:
267
                acpi_os_printf ("Initializing ");
268
                break;
269
        }
270
 
271
        /* Print the object type and pathname */
272
 
273
        acpi_os_printf ("%-12s %s", acpi_ut_get_type_name (type), (char *) buffer.pointer);
274
 
275
        /* Extra path is used to append names like _STA, _INI, etc. */
276
 
277
        if (path) {
278
                acpi_os_printf (".%s", path);
279
        }
280
        acpi_os_printf ("\n");
281
 
282
        ACPI_MEM_FREE (buffer.pointer);
283
}
284
#endif
285
 
286
 
287
/*******************************************************************************
288
 *
289
 * FUNCTION:    acpi_ut_valid_acpi_name
290
 *
291
 * PARAMETERS:  Character           - The character to be examined
292
 *
293
 * RETURN:      1 if Character may appear in a name, else 0
294
 *
295
 * DESCRIPTION: Check for a valid ACPI name.  Each character must be one of:
296
 *              1) Upper case alpha
297
 *              2) numeric
298
 *              3) underscore
299
 *
300
 ******************************************************************************/
301
 
302
u8
303
acpi_ut_valid_acpi_name (
304
        u32                             name)
305
{
306
        char                            *name_ptr = (char *) &name;
307
        char                            character;
308
        acpi_native_uint                i;
309
 
310
 
311
        ACPI_FUNCTION_ENTRY ();
312
 
313
 
314
        for (i = 0; i < ACPI_NAME_SIZE; i++) {
315
                character = *name_ptr;
316
                name_ptr++;
317
 
318
                if (!((character == '_') ||
319
                          (character >= 'A' && character <= 'Z') ||
320
                          (character >= '0' && character <= '9'))) {
321
                        return (FALSE);
322
                }
323
        }
324
 
325
        return (TRUE);
326
}
327
 
328
 
329
/*******************************************************************************
330
 *
331
 * FUNCTION:    acpi_ut_valid_acpi_character
332
 *
333
 * PARAMETERS:  Character           - The character to be examined
334
 *
335
 * RETURN:      1 if Character may appear in a name, else 0
336
 *
337
 * DESCRIPTION: Check for a printable character
338
 *
339
 ******************************************************************************/
340
 
341
u8
342
acpi_ut_valid_acpi_character (
343
        char                            character)
344
{
345
 
346
        ACPI_FUNCTION_ENTRY ();
347
 
348
        return ((u8)   ((character == '_') ||
349
                           (character >= 'A' && character <= 'Z') ||
350
                           (character >= '0' && character <= '9')));
351
}
352
 
353
 
354
/*******************************************************************************
355
 *
356
 * FUNCTION:    acpi_ut_strtoul64
357
 *
358
 * PARAMETERS:  String          - Null terminated string
359
 *              Terminater      - Where a pointer to the terminating byte is returned
360
 *              Base            - Radix of the string
361
 *
362
 * RETURN:      Converted value
363
 *
364
 * DESCRIPTION: Convert a string into an unsigned value.
365
 *
366
 ******************************************************************************/
367
#define NEGATIVE    1
368
#define POSITIVE    0
369
 
370
acpi_status
371
acpi_ut_strtoul64 (
372
        char                            *string,
373
        u32                             base,
374
        acpi_integer                    *ret_integer)
375
{
376
        u32                             index;
377
        acpi_integer                    return_value = 0;
378
        acpi_status                     status = AE_OK;
379
        acpi_integer                    dividend;
380
        acpi_integer                    quotient;
381
 
382
 
383
        *ret_integer = 0;
384
 
385
        switch (base) {
386
        case 0:
387
        case 8:
388
        case 10:
389
        case 16:
390
                break;
391
 
392
        default:
393
                /*
394
                 * The specified Base parameter is not in the domain of
395
                 * this function:
396
                 */
397
                return (AE_BAD_PARAMETER);
398
        }
399
 
400
        /*
401
         * skip over any white space in the buffer:
402
         */
403
        while (ACPI_IS_SPACE (*string) || *string == '\t') {
404
                ++string;
405
        }
406
 
407
        /*
408
         * If the input parameter Base is zero, then we need to
409
         * determine if it is octal, decimal, or hexadecimal:
410
         */
411
        if (base == 0) {
412
                if (*string == '0') {
413
                        if (ACPI_TOLOWER (*(++string)) == 'x') {
414
                                base = 16;
415
                                ++string;
416
                        }
417
                        else {
418
                                base = 8;
419
                        }
420
                }
421
                else {
422
                        base = 10;
423
                }
424
        }
425
 
426
        /*
427
         * For octal and hexadecimal bases, skip over the leading
428
         * 0 or 0x, if they are present.
429
         */
430
        if (base == 8 && *string == '0') {
431
                string++;
432
        }
433
 
434
        if (base == 16 &&
435
                *string == '0' &&
436
                ACPI_TOLOWER (*(++string)) == 'x') {
437
                string++;
438
        }
439
 
440
        /* Main loop: convert the string to an unsigned long */
441
 
442
        while (*string) {
443
                if (ACPI_IS_DIGIT (*string)) {
444
                        index = ((u8) *string) - '0';
445
                }
446
                else {
447
                        index = (u8) ACPI_TOUPPER (*string);
448
                        if (ACPI_IS_UPPER ((char) index)) {
449
                                index = index - 'A' + 10;
450
                        }
451
                        else {
452
                                goto error_exit;
453
                        }
454
                }
455
 
456
                if (index >= base) {
457
                        goto error_exit;
458
                }
459
 
460
                /* Check to see if value is out of range: */
461
 
462
                dividend = ACPI_INTEGER_MAX - (acpi_integer) index;
463
                (void) acpi_ut_short_divide (&dividend, base, &quotient, NULL);
464
                if (return_value > quotient) {
465
                        goto error_exit;
466
                }
467
 
468
                return_value *= base;
469
                return_value += index;
470
                ++string;
471
        }
472
 
473
        *ret_integer = return_value;
474
        return (status);
475
 
476
 
477
error_exit:
478
        switch (base) {
479
        case 8:
480
                status = AE_BAD_OCTAL_CONSTANT;
481
                break;
482
 
483
        case 10:
484
                status = AE_BAD_DECIMAL_CONSTANT;
485
                break;
486
 
487
        case 16:
488
                status = AE_BAD_HEX_CONSTANT;
489
                break;
490
 
491
        default:
492
                /* Base validated above */
493
                break;
494
        }
495
 
496
        return (status);
497
}
498
 
499
 
500
/*******************************************************************************
501
 *
502
 * FUNCTION:    acpi_ut_strupr
503
 *
504
 * PARAMETERS:  src_string      - The source string to convert to
505
 *
506
 * RETURN:      src_string
507
 *
508
 * DESCRIPTION: Convert string to uppercase
509
 *
510
 ******************************************************************************/
511
 
512
char *
513
acpi_ut_strupr (
514
        char                            *src_string)
515
{
516
        char                            *string;
517
 
518
 
519
        ACPI_FUNCTION_ENTRY ();
520
 
521
 
522
        /* Walk entire string, uppercasing the letters */
523
 
524
        for (string = src_string; *string; ) {
525
                *string = (char) ACPI_TOUPPER (*string);
526
                string++;
527
        }
528
 
529
        return (src_string);
530
}
531
 
532
 
533
/*******************************************************************************
534
 *
535
 * FUNCTION:    acpi_ut_mutex_initialize
536
 *
537
 * PARAMETERS:  None.
538
 *
539
 * RETURN:      Status
540
 *
541
 * DESCRIPTION: Create the system mutex objects.
542
 *
543
 ******************************************************************************/
544
 
545
acpi_status
546
acpi_ut_mutex_initialize (
547
        void)
548
{
549
        u32                             i;
550
        acpi_status                     status;
551
 
552
 
553
        ACPI_FUNCTION_TRACE ("ut_mutex_initialize");
554
 
555
 
556
        /*
557
         * Create each of the predefined mutex objects
558
         */
559
        for (i = 0; i < NUM_MUTEX; i++) {
560
                status = acpi_ut_create_mutex (i);
561
                if (ACPI_FAILURE (status)) {
562
                        return_ACPI_STATUS (status);
563
                }
564
        }
565
 
566
        status = acpi_os_create_lock (&acpi_gbl_gpe_lock);
567
        return_ACPI_STATUS (status);
568
}
569
 
570
 
571
/*******************************************************************************
572
 *
573
 * FUNCTION:    acpi_ut_mutex_terminate
574
 *
575
 * PARAMETERS:  None.
576
 *
577
 * RETURN:      None.
578
 *
579
 * DESCRIPTION: Delete all of the system mutex objects.
580
 *
581
 ******************************************************************************/
582
 
583
void
584
acpi_ut_mutex_terminate (
585
        void)
586
{
587
        u32                             i;
588
 
589
 
590
        ACPI_FUNCTION_TRACE ("ut_mutex_terminate");
591
 
592
 
593
        /*
594
         * Delete each predefined mutex object
595
         */
596
        for (i = 0; i < NUM_MUTEX; i++) {
597
                (void) acpi_ut_delete_mutex (i);
598
        }
599
 
600
        acpi_os_delete_lock (acpi_gbl_gpe_lock);
601
        return_VOID;
602
}
603
 
604
 
605
/*******************************************************************************
606
 *
607
 * FUNCTION:    acpi_ut_create_mutex
608
 *
609
 * PARAMETERS:  mutex_iD        - ID of the mutex to be created
610
 *
611
 * RETURN:      Status
612
 *
613
 * DESCRIPTION: Create a mutex object.
614
 *
615
 ******************************************************************************/
616
 
617
acpi_status
618
acpi_ut_create_mutex (
619
        acpi_mutex_handle               mutex_id)
620
{
621
        acpi_status                     status = AE_OK;
622
 
623
 
624
        ACPI_FUNCTION_TRACE_U32 ("ut_create_mutex", mutex_id);
625
 
626
 
627
        if (mutex_id > MAX_MUTEX) {
628
                return_ACPI_STATUS (AE_BAD_PARAMETER);
629
        }
630
 
631
        if (!acpi_gbl_mutex_info[mutex_id].mutex) {
632
                status = acpi_os_create_semaphore (1, 1,
633
                                  &acpi_gbl_mutex_info[mutex_id].mutex);
634
                acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
635
                acpi_gbl_mutex_info[mutex_id].use_count = 0;
636
        }
637
 
638
        return_ACPI_STATUS (status);
639
}
640
 
641
 
642
/*******************************************************************************
643
 *
644
 * FUNCTION:    acpi_ut_delete_mutex
645
 *
646
 * PARAMETERS:  mutex_iD        - ID of the mutex to be deleted
647
 *
648
 * RETURN:      Status
649
 *
650
 * DESCRIPTION: Delete a mutex object.
651
 *
652
 ******************************************************************************/
653
 
654
acpi_status
655
acpi_ut_delete_mutex (
656
        acpi_mutex_handle               mutex_id)
657
{
658
        acpi_status                     status;
659
 
660
 
661
        ACPI_FUNCTION_TRACE_U32 ("ut_delete_mutex", mutex_id);
662
 
663
 
664
        if (mutex_id > MAX_MUTEX) {
665
                return_ACPI_STATUS (AE_BAD_PARAMETER);
666
        }
667
 
668
        status = acpi_os_delete_semaphore (acpi_gbl_mutex_info[mutex_id].mutex);
669
 
670
        acpi_gbl_mutex_info[mutex_id].mutex = NULL;
671
        acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
672
 
673
        return_ACPI_STATUS (status);
674
}
675
 
676
 
677
/*******************************************************************************
678
 *
679
 * FUNCTION:    acpi_ut_acquire_mutex
680
 *
681
 * PARAMETERS:  mutex_iD        - ID of the mutex to be acquired
682
 *
683
 * RETURN:      Status
684
 *
685
 * DESCRIPTION: Acquire a mutex object.
686
 *
687
 ******************************************************************************/
688
 
689
acpi_status
690
acpi_ut_acquire_mutex (
691
        acpi_mutex_handle               mutex_id)
692
{
693
        acpi_status                     status;
694
        u32                             i;
695
        u32                             this_thread_id;
696
 
697
 
698
        ACPI_FUNCTION_NAME ("ut_acquire_mutex");
699
 
700
 
701
        if (mutex_id > MAX_MUTEX) {
702
                return (AE_BAD_PARAMETER);
703
        }
704
 
705
        this_thread_id = acpi_os_get_thread_id ();
706
 
707
        /*
708
         * Deadlock prevention.  Check if this thread owns any mutexes of value
709
         * greater than or equal to this one.  If so, the thread has violated
710
         * the mutex ordering rule.  This indicates a coding error somewhere in
711
         * the ACPI subsystem code.
712
         */
713
        for (i = mutex_id; i < MAX_MUTEX; i++) {
714
                if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
715
                        if (i == mutex_id) {
716
                                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
717
                                                "Mutex [%s] already acquired by this thread [%X]\n",
718
                                                acpi_ut_get_mutex_name (mutex_id), this_thread_id));
719
 
720
                                return (AE_ALREADY_ACQUIRED);
721
                        }
722
 
723
                        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
724
                                        "Invalid acquire order: Thread %X owns [%s], wants [%s]\n",
725
                                        this_thread_id, acpi_ut_get_mutex_name (i),
726
                                        acpi_ut_get_mutex_name (mutex_id)));
727
 
728
                        return (AE_ACQUIRE_DEADLOCK);
729
                }
730
        }
731
 
732
        ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
733
                         "Thread %X attempting to acquire Mutex [%s]\n",
734
                         this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
735
 
736
        status = acpi_os_wait_semaphore (acpi_gbl_mutex_info[mutex_id].mutex,
737
                           1, ACPI_WAIT_FOREVER);
738
        if (ACPI_SUCCESS (status)) {
739
                ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X acquired Mutex [%s]\n",
740
                                 this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
741
 
742
                acpi_gbl_mutex_info[mutex_id].use_count++;
743
                acpi_gbl_mutex_info[mutex_id].owner_id = this_thread_id;
744
        }
745
        else {
746
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not acquire Mutex [%s] %s\n",
747
                                 this_thread_id, acpi_ut_get_mutex_name (mutex_id),
748
                                 acpi_format_exception (status)));
749
        }
750
 
751
        return (status);
752
}
753
 
754
 
755
/*******************************************************************************
756
 *
757
 * FUNCTION:    acpi_ut_release_mutex
758
 *
759
 * PARAMETERS:  mutex_iD        - ID of the mutex to be released
760
 *
761
 * RETURN:      Status
762
 *
763
 * DESCRIPTION: Release a mutex object.
764
 *
765
 ******************************************************************************/
766
 
767
acpi_status
768
acpi_ut_release_mutex (
769
        acpi_mutex_handle               mutex_id)
770
{
771
        acpi_status                     status;
772
        u32                             i;
773
        u32                             this_thread_id;
774
 
775
 
776
        ACPI_FUNCTION_NAME ("ut_release_mutex");
777
 
778
 
779
        this_thread_id = acpi_os_get_thread_id ();
780
        ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
781
                "Thread %X releasing Mutex [%s]\n", this_thread_id,
782
                acpi_ut_get_mutex_name (mutex_id)));
783
 
784
        if (mutex_id > MAX_MUTEX) {
785
                return (AE_BAD_PARAMETER);
786
        }
787
 
788
        /*
789
         * Mutex must be acquired in order to release it!
790
         */
791
        if (acpi_gbl_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) {
792
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
793
                                "Mutex [%s] is not acquired, cannot release\n",
794
                                acpi_ut_get_mutex_name (mutex_id)));
795
 
796
                return (AE_NOT_ACQUIRED);
797
        }
798
 
799
        /*
800
         * Deadlock prevention.  Check if this thread owns any mutexes of value
801
         * greater than this one.  If so, the thread has violated the mutex
802
         * ordering rule.  This indicates a coding error somewhere in
803
         * the ACPI subsystem code.
804
         */
805
        for (i = mutex_id; i < MAX_MUTEX; i++) {
806
                if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
807
                        if (i == mutex_id) {
808
                                continue;
809
                        }
810
 
811
                        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
812
                                        "Invalid release order: owns [%s], releasing [%s]\n",
813
                                        acpi_ut_get_mutex_name (i), acpi_ut_get_mutex_name (mutex_id)));
814
 
815
                        return (AE_RELEASE_DEADLOCK);
816
                }
817
        }
818
 
819
        /* Mark unlocked FIRST */
820
 
821
        acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
822
 
823
        status = acpi_os_signal_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, 1);
824
 
825
        if (ACPI_FAILURE (status)) {
826
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not release Mutex [%s] %s\n",
827
                                 this_thread_id, acpi_ut_get_mutex_name (mutex_id),
828
                                 acpi_format_exception (status)));
829
        }
830
        else {
831
                ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X released Mutex [%s]\n",
832
                                 this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
833
        }
834
 
835
        return (status);
836
}
837
 
838
 
839
/*******************************************************************************
840
 *
841
 * FUNCTION:    acpi_ut_create_update_state_and_push
842
 *
843
 * PARAMETERS:  *Object         - Object to be added to the new state
844
 *              Action          - Increment/Decrement
845
 *              state_list      - List the state will be added to
846
 *
847
 * RETURN:      None
848
 *
849
 * DESCRIPTION: Create a new state and push it
850
 *
851
 ******************************************************************************/
852
 
853
acpi_status
854
acpi_ut_create_update_state_and_push (
855
        union acpi_operand_object       *object,
856
        u16                             action,
857
        union acpi_generic_state        **state_list)
858
{
859
        union acpi_generic_state         *state;
860
 
861
 
862
        ACPI_FUNCTION_ENTRY ();
863
 
864
 
865
        /* Ignore null objects; these are expected */
866
 
867
        if (!object) {
868
                return (AE_OK);
869
        }
870
 
871
        state = acpi_ut_create_update_state (object, action);
872
        if (!state) {
873
                return (AE_NO_MEMORY);
874
        }
875
 
876
        acpi_ut_push_generic_state (state_list, state);
877
        return (AE_OK);
878
}
879
 
880
 
881
/*******************************************************************************
882
 *
883
 * FUNCTION:    acpi_ut_create_pkg_state_and_push
884
 *
885
 * PARAMETERS:  *Object         - Object to be added to the new state
886
 *              Action          - Increment/Decrement
887
 *              state_list      - List the state will be added to
888
 *
889
 * RETURN:      None
890
 *
891
 * DESCRIPTION: Create a new state and push it
892
 *
893
 ******************************************************************************/
894
 
895
acpi_status
896
acpi_ut_create_pkg_state_and_push (
897
        void                            *internal_object,
898
        void                            *external_object,
899
        u16                             index,
900
        union acpi_generic_state        **state_list)
901
{
902
        union acpi_generic_state         *state;
903
 
904
 
905
        ACPI_FUNCTION_ENTRY ();
906
 
907
 
908
        state = acpi_ut_create_pkg_state (internal_object, external_object, index);
909
        if (!state) {
910
                return (AE_NO_MEMORY);
911
        }
912
 
913
        acpi_ut_push_generic_state (state_list, state);
914
        return (AE_OK);
915
}
916
 
917
 
918
/*******************************************************************************
919
 *
920
 * FUNCTION:    acpi_ut_push_generic_state
921
 *
922
 * PARAMETERS:  list_head           - Head of the state stack
923
 *              State               - State object to push
924
 *
925
 * RETURN:      Status
926
 *
927
 * DESCRIPTION: Push a state object onto a state stack
928
 *
929
 ******************************************************************************/
930
 
931
void
932
acpi_ut_push_generic_state (
933
        union acpi_generic_state        **list_head,
934
        union acpi_generic_state        *state)
935
{
936
        ACPI_FUNCTION_TRACE ("ut_push_generic_state");
937
 
938
 
939
        /* Push the state object onto the front of the list (stack) */
940
 
941
        state->common.next = *list_head;
942
        *list_head = state;
943
 
944
        return_VOID;
945
}
946
 
947
 
948
/*******************************************************************************
949
 *
950
 * FUNCTION:    acpi_ut_pop_generic_state
951
 *
952
 * PARAMETERS:  list_head           - Head of the state stack
953
 *
954
 * RETURN:      Status
955
 *
956
 * DESCRIPTION: Pop a state object from a state stack
957
 *
958
 ******************************************************************************/
959
 
960
union acpi_generic_state *
961
acpi_ut_pop_generic_state (
962
        union acpi_generic_state        **list_head)
963
{
964
        union acpi_generic_state        *state;
965
 
966
 
967
        ACPI_FUNCTION_TRACE ("ut_pop_generic_state");
968
 
969
 
970
        /* Remove the state object at the head of the list (stack) */
971
 
972
        state = *list_head;
973
        if (state) {
974
                /* Update the list head */
975
 
976
                *list_head = state->common.next;
977
        }
978
 
979
        return_PTR (state);
980
}
981
 
982
 
983
/*******************************************************************************
984
 *
985
 * FUNCTION:    acpi_ut_create_generic_state
986
 *
987
 * PARAMETERS:  None
988
 *
989
 * RETURN:      Status
990
 *
991
 * DESCRIPTION: Create a generic state object.  Attempt to obtain one from
992
 *              the global state cache;  If none available, create a new one.
993
 *
994
 ******************************************************************************/
995
 
996
union acpi_generic_state *
997
acpi_ut_create_generic_state (void)
998
{
999
        union acpi_generic_state        *state;
1000
 
1001
 
1002
        ACPI_FUNCTION_ENTRY ();
1003
 
1004
 
1005
        state = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_STATE);
1006
 
1007
        /* Initialize */
1008
 
1009
        if (state) {
1010
                state->common.data_type = ACPI_DESC_TYPE_STATE;
1011
        }
1012
 
1013
        return (state);
1014
}
1015
 
1016
 
1017
/*******************************************************************************
1018
 *
1019
 * FUNCTION:    acpi_ut_create_thread_state
1020
 *
1021
 * PARAMETERS:  None
1022
 *
1023
 * RETURN:      Thread State
1024
 *
1025
 * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used
1026
 *              to track per-thread info during method execution
1027
 *
1028
 ******************************************************************************/
1029
 
1030
struct acpi_thread_state *
1031
acpi_ut_create_thread_state (
1032
        void)
1033
{
1034
        union acpi_generic_state        *state;
1035
 
1036
 
1037
        ACPI_FUNCTION_TRACE ("ut_create_thread_state");
1038
 
1039
 
1040
        /* Create the generic state object */
1041
 
1042
        state = acpi_ut_create_generic_state ();
1043
        if (!state) {
1044
                return_PTR (NULL);
1045
        }
1046
 
1047
        /* Init fields specific to the update struct */
1048
 
1049
        state->common.data_type = ACPI_DESC_TYPE_STATE_THREAD;
1050
        state->thread.thread_id = acpi_os_get_thread_id ();
1051
 
1052
        return_PTR ((struct acpi_thread_state *) state);
1053
}
1054
 
1055
 
1056
/*******************************************************************************
1057
 *
1058
 * FUNCTION:    acpi_ut_create_update_state
1059
 *
1060
 * PARAMETERS:  Object              - Initial Object to be installed in the
1061
 *                                    state
1062
 *              Action              - Update action to be performed
1063
 *
1064
 * RETURN:      Status
1065
 *
1066
 * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
1067
 *              to update reference counts and delete complex objects such
1068
 *              as packages.
1069
 *
1070
 ******************************************************************************/
1071
 
1072
union acpi_generic_state *
1073
acpi_ut_create_update_state (
1074
        union acpi_operand_object       *object,
1075
        u16                             action)
1076
{
1077
        union acpi_generic_state        *state;
1078
 
1079
 
1080
        ACPI_FUNCTION_TRACE_PTR ("ut_create_update_state", object);
1081
 
1082
 
1083
        /* Create the generic state object */
1084
 
1085
        state = acpi_ut_create_generic_state ();
1086
        if (!state) {
1087
                return_PTR (NULL);
1088
        }
1089
 
1090
        /* Init fields specific to the update struct */
1091
 
1092
        state->common.data_type = ACPI_DESC_TYPE_STATE_UPDATE;
1093
        state->update.object = object;
1094
        state->update.value  = action;
1095
 
1096
        return_PTR (state);
1097
}
1098
 
1099
 
1100
/*******************************************************************************
1101
 *
1102
 * FUNCTION:    acpi_ut_create_pkg_state
1103
 *
1104
 * PARAMETERS:  Object              - Initial Object to be installed in the
1105
 *                                    state
1106
 *              Action              - Update action to be performed
1107
 *
1108
 * RETURN:      Status
1109
 *
1110
 * DESCRIPTION: Create a "Package State"
1111
 *
1112
 ******************************************************************************/
1113
 
1114
union acpi_generic_state *
1115
acpi_ut_create_pkg_state (
1116
        void                            *internal_object,
1117
        void                            *external_object,
1118
        u16                             index)
1119
{
1120
        union acpi_generic_state        *state;
1121
 
1122
 
1123
        ACPI_FUNCTION_TRACE_PTR ("ut_create_pkg_state", internal_object);
1124
 
1125
 
1126
        /* Create the generic state object */
1127
 
1128
        state = acpi_ut_create_generic_state ();
1129
        if (!state) {
1130
                return_PTR (NULL);
1131
        }
1132
 
1133
        /* Init fields specific to the update struct */
1134
 
1135
        state->common.data_type = ACPI_DESC_TYPE_STATE_PACKAGE;
1136
        state->pkg.source_object = (union acpi_operand_object *) internal_object;
1137
        state->pkg.dest_object  = external_object;
1138
        state->pkg.index        = index;
1139
        state->pkg.num_packages = 1;
1140
 
1141
        return_PTR (state);
1142
}
1143
 
1144
 
1145
/*******************************************************************************
1146
 *
1147
 * FUNCTION:    acpi_ut_create_control_state
1148
 *
1149
 * PARAMETERS:  None
1150
 *
1151
 * RETURN:      Status
1152
 *
1153
 * DESCRIPTION: Create a "Control State" - a flavor of the generic state used
1154
 *              to support nested IF/WHILE constructs in the AML.
1155
 *
1156
 ******************************************************************************/
1157
 
1158
union acpi_generic_state *
1159
acpi_ut_create_control_state (
1160
        void)
1161
{
1162
        union acpi_generic_state        *state;
1163
 
1164
 
1165
        ACPI_FUNCTION_TRACE ("ut_create_control_state");
1166
 
1167
 
1168
        /* Create the generic state object */
1169
 
1170
        state = acpi_ut_create_generic_state ();
1171
        if (!state) {
1172
                return_PTR (NULL);
1173
        }
1174
 
1175
        /* Init fields specific to the control struct */
1176
 
1177
        state->common.data_type = ACPI_DESC_TYPE_STATE_CONTROL;
1178
        state->common.state     = ACPI_CONTROL_CONDITIONAL_EXECUTING;
1179
 
1180
        return_PTR (state);
1181
}
1182
 
1183
 
1184
/*******************************************************************************
1185
 *
1186
 * FUNCTION:    acpi_ut_delete_generic_state
1187
 *
1188
 * PARAMETERS:  State               - The state object to be deleted
1189
 *
1190
 * RETURN:      Status
1191
 *
1192
 * DESCRIPTION: Put a state object back into the global state cache.  The object
1193
 *              is not actually freed at this time.
1194
 *
1195
 ******************************************************************************/
1196
 
1197
void
1198
acpi_ut_delete_generic_state (
1199
        union acpi_generic_state        *state)
1200
{
1201
        ACPI_FUNCTION_TRACE ("ut_delete_generic_state");
1202
 
1203
 
1204
        acpi_ut_release_to_cache (ACPI_MEM_LIST_STATE, state);
1205
        return_VOID;
1206
}
1207
 
1208
 
1209
/*******************************************************************************
1210
 *
1211
 * FUNCTION:    acpi_ut_delete_generic_state_cache
1212
 *
1213
 * PARAMETERS:  None
1214
 *
1215
 * RETURN:      Status
1216
 *
1217
 * DESCRIPTION: Purge the global state object cache.  Used during subsystem
1218
 *              termination.
1219
 *
1220
 ******************************************************************************/
1221
 
1222
void
1223
acpi_ut_delete_generic_state_cache (
1224
        void)
1225
{
1226
        ACPI_FUNCTION_TRACE ("ut_delete_generic_state_cache");
1227
 
1228
 
1229
        acpi_ut_delete_generic_cache (ACPI_MEM_LIST_STATE);
1230
        return_VOID;
1231
}
1232
 
1233
 
1234
/*******************************************************************************
1235
 *
1236
 * FUNCTION:    acpi_ut_walk_package_tree
1237
 *
1238
 * PARAMETERS:  obj_desc        - The Package object on which to resolve refs
1239
 *
1240
 * RETURN:      Status
1241
 *
1242
 * DESCRIPTION: Walk through a package
1243
 *
1244
 ******************************************************************************/
1245
 
1246
acpi_status
1247
acpi_ut_walk_package_tree (
1248
        union acpi_operand_object       *source_object,
1249
        void                            *target_object,
1250
        acpi_pkg_callback               walk_callback,
1251
        void                            *context)
1252
{
1253
        acpi_status                     status = AE_OK;
1254
        union acpi_generic_state        *state_list = NULL;
1255
        union acpi_generic_state        *state;
1256
        u32                             this_index;
1257
        union acpi_operand_object       *this_source_obj;
1258
 
1259
 
1260
        ACPI_FUNCTION_TRACE ("ut_walk_package_tree");
1261
 
1262
 
1263
        state = acpi_ut_create_pkg_state (source_object, target_object, 0);
1264
        if (!state) {
1265
                return_ACPI_STATUS (AE_NO_MEMORY);
1266
        }
1267
 
1268
        while (state) {
1269
                /* Get one element of the package */
1270
 
1271
                this_index    = state->pkg.index;
1272
                this_source_obj = (union acpi_operand_object *)
1273
                                  state->pkg.source_object->package.elements[this_index];
1274
 
1275
                /*
1276
                 * Check for:
1277
                 * 1) An uninitialized package element.  It is completely
1278
                 *    legal to declare a package and leave it uninitialized
1279
                 * 2) Not an internal object - can be a namespace node instead
1280
                 * 3) Any type other than a package.  Packages are handled in else
1281
                 *    case below.
1282
                 */
1283
                if ((!this_source_obj) ||
1284
                        (ACPI_GET_DESCRIPTOR_TYPE (this_source_obj) != ACPI_DESC_TYPE_OPERAND) ||
1285
                        (ACPI_GET_OBJECT_TYPE (this_source_obj) != ACPI_TYPE_PACKAGE)) {
1286
                        status = walk_callback (ACPI_COPY_TYPE_SIMPLE, this_source_obj,
1287
                                         state, context);
1288
                        if (ACPI_FAILURE (status)) {
1289
                                return_ACPI_STATUS (status);
1290
                        }
1291
 
1292
                        state->pkg.index++;
1293
                        while (state->pkg.index >= state->pkg.source_object->package.count) {
1294
                                /*
1295
                                 * We've handled all of the objects at this level,  This means
1296
                                 * that we have just completed a package.  That package may
1297
                                 * have contained one or more packages itself.
1298
                                 *
1299
                                 * Delete this state and pop the previous state (package).
1300
                                 */
1301
                                acpi_ut_delete_generic_state (state);
1302
                                state = acpi_ut_pop_generic_state (&state_list);
1303
 
1304
                                /* Finished when there are no more states */
1305
 
1306
                                if (!state) {
1307
                                        /*
1308
                                         * We have handled all of the objects in the top level
1309
                                         * package just add the length of the package objects
1310
                                         * and exit
1311
                                         */
1312
                                        return_ACPI_STATUS (AE_OK);
1313
                                }
1314
 
1315
                                /*
1316
                                 * Go back up a level and move the index past the just
1317
                                 * completed package object.
1318
                                 */
1319
                                state->pkg.index++;
1320
                        }
1321
                }
1322
                else {
1323
                        /* This is a subobject of type package */
1324
 
1325
                        status = walk_callback (ACPI_COPY_TYPE_PACKAGE, this_source_obj,
1326
                                          state, context);
1327
                        if (ACPI_FAILURE (status)) {
1328
                                return_ACPI_STATUS (status);
1329
                        }
1330
 
1331
                        /*
1332
                         * Push the current state and create a new one
1333
                         * The callback above returned a new target package object.
1334
                         */
1335
                        acpi_ut_push_generic_state (&state_list, state);
1336
                        state = acpi_ut_create_pkg_state (this_source_obj,
1337
                                           state->pkg.this_target_obj, 0);
1338
                        if (!state) {
1339
                                return_ACPI_STATUS (AE_NO_MEMORY);
1340
                        }
1341
                }
1342
        }
1343
 
1344
        /* We should never get here */
1345
 
1346
        return_ACPI_STATUS (AE_AML_INTERNAL);
1347
}
1348
 
1349
 
1350
/*******************************************************************************
1351
 *
1352
 * FUNCTION:    acpi_ut_generate_checksum
1353
 *
1354
 * PARAMETERS:  Buffer          - Buffer to be scanned
1355
 *              Length          - number of bytes to examine
1356
 *
1357
 * RETURN:      checksum
1358
 *
1359
 * DESCRIPTION: Generate a checksum on a raw buffer
1360
 *
1361
 ******************************************************************************/
1362
 
1363
u8
1364
acpi_ut_generate_checksum (
1365
        u8                              *buffer,
1366
        u32                             length)
1367
{
1368
        u32                             i;
1369
        signed char                     sum = 0;
1370
 
1371
 
1372
        for (i = 0; i < length; i++) {
1373
                sum = (signed char) (sum + buffer[i]);
1374
        }
1375
 
1376
        return ((u8) (0 - sum));
1377
}
1378
 
1379
 
1380
/*******************************************************************************
1381
 *
1382
 * FUNCTION:    acpi_ut_get_resource_end_tag
1383
 *
1384
 * PARAMETERS:  obj_desc        - The resource template buffer object
1385
 *
1386
 * RETURN:      Pointer to the end tag
1387
 *
1388
 * DESCRIPTION: Find the END_TAG resource descriptor in a resource template
1389
 *
1390
 ******************************************************************************/
1391
 
1392
 
1393
u8 *
1394
acpi_ut_get_resource_end_tag (
1395
        union acpi_operand_object       *obj_desc)
1396
{
1397
        u8                              buffer_byte;
1398
        u8                              *buffer;
1399
        u8                              *end_buffer;
1400
 
1401
 
1402
        buffer    = obj_desc->buffer.pointer;
1403
        end_buffer = buffer + obj_desc->buffer.length;
1404
 
1405
        while (buffer < end_buffer) {
1406
                buffer_byte = *buffer;
1407
                if (buffer_byte & ACPI_RDESC_TYPE_MASK) {
1408
                        /* Large Descriptor - Length is next 2 bytes */
1409
 
1410
                        buffer += ((*(buffer+1) | (*(buffer+2) << 8)) + 3);
1411
                }
1412
                else {
1413
                        /* Small Descriptor.  End Tag will be found here */
1414
 
1415
                        if ((buffer_byte & ACPI_RDESC_SMALL_MASK) == ACPI_RDESC_TYPE_END_TAG) {
1416
                                /* Found the end tag descriptor, all done. */
1417
 
1418
                                return (buffer);
1419
                        }
1420
 
1421
                        /* Length is in the header */
1422
 
1423
                        buffer += ((buffer_byte & 0x07) + 1);
1424
                }
1425
        }
1426
 
1427
        /* End tag not found */
1428
 
1429
        return (NULL);
1430
}
1431
 
1432
 
1433
/*******************************************************************************
1434
 *
1435
 * FUNCTION:    acpi_ut_report_error
1436
 *
1437
 * PARAMETERS:  module_name         - Caller's module name (for error output)
1438
 *              line_number         - Caller's line number (for error output)
1439
 *              component_id        - Caller's component ID (for error output)
1440
 *              Message             - Error message to use on failure
1441
 *
1442
 * RETURN:      None
1443
 *
1444
 * DESCRIPTION: Print error message
1445
 *
1446
 ******************************************************************************/
1447
 
1448
void
1449
acpi_ut_report_error (
1450
        char                            *module_name,
1451
        u32                             line_number,
1452
        u32                             component_id)
1453
{
1454
 
1455
 
1456
        acpi_os_printf ("%8s-%04d: *** Error: ", module_name, line_number);
1457
}
1458
 
1459
 
1460
/*******************************************************************************
1461
 *
1462
 * FUNCTION:    acpi_ut_report_warning
1463
 *
1464
 * PARAMETERS:  module_name         - Caller's module name (for error output)
1465
 *              line_number         - Caller's line number (for error output)
1466
 *              component_id        - Caller's component ID (for error output)
1467
 *              Message             - Error message to use on failure
1468
 *
1469
 * RETURN:      None
1470
 *
1471
 * DESCRIPTION: Print warning message
1472
 *
1473
 ******************************************************************************/
1474
 
1475
void
1476
acpi_ut_report_warning (
1477
        char                            *module_name,
1478
        u32                             line_number,
1479
        u32                             component_id)
1480
{
1481
 
1482
        acpi_os_printf ("%8s-%04d: *** Warning: ", module_name, line_number);
1483
}
1484
 
1485
 
1486
/*******************************************************************************
1487
 *
1488
 * FUNCTION:    acpi_ut_report_info
1489
 *
1490
 * PARAMETERS:  module_name         - Caller's module name (for error output)
1491
 *              line_number         - Caller's line number (for error output)
1492
 *              component_id        - Caller's component ID (for error output)
1493
 *              Message             - Error message to use on failure
1494
 *
1495
 * RETURN:      None
1496
 *
1497
 * DESCRIPTION: Print information message
1498
 *
1499
 ******************************************************************************/
1500
 
1501
void
1502
acpi_ut_report_info (
1503
        char                            *module_name,
1504
        u32                             line_number,
1505
        u32                             component_id)
1506
{
1507
 
1508
        acpi_os_printf ("%8s-%04d: *** Info: ", module_name, line_number);
1509
}
1510
 
1511
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.