Subversion Repositories Kolibri OS

Rev

Rev 1627 | Rev 1867 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1627 serge 1
 
2
 
3
#include 
4
#include 
5
#include 
6
7
#include "acpi.h"
8
 
9
10
11
 
12
 
13
#define ACPI_BUS_CLASS          "system_bus"
14
 
15
#define ACPI_BUS_DEVICE_NAME    "System Bus"
16
17
18
 
19
 
20
#define STRUCT_TO_INT(s)        (*((int*)&s))
21
 
22
23
 
24
 
25
static LIST_HEAD(acpi_device_list);
26
 
27
DEFINE_MUTEX(acpi_device_lock);
28
29
30
 
31
 
32
	unsigned int instance_no;
33
	struct list_head node;
34
};
35
36
37
 
38
 
39
    char *id;
40
};
41
42
#define acpi_device_name(d) ((d)->pnp.device_name)
43
 
44
45
46
 
47
 
48
{
49
#ifdef ACPI_DEBUG_OUTPUT
50
    char prefix[80] = {'\0'};
51
    ACPI_BUFFER buffer = {sizeof(prefix), prefix};
52
    AcpiGetName(h, ACPI_FULL_PATHNAME, &buffer);
53
    ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s\n",
54
        (char *) prefix, p, AcpiFormatException(s)));
55
#else
56
    return;
57
#endif
58
}
59
60
ACPI_STATUS
61
 
62
              ACPI_OBJECT_LIST *arguments, unsigned long long *data)
63
{
64
    ACPI_STATUS status = AE_OK;
65
    ACPI_OBJECT element;
66
    ACPI_BUFFER buffer = { 0, NULL };
67
68
    if (!data)
69
 
70
71
    buffer.Length = sizeof(ACPI_OBJECT);
72
 
73
    status = AcpiEvaluateObject(handle, pathname, arguments, &buffer);
74
    if (ACPI_FAILURE(status)) {
75
        acpi_util_eval_error(handle, pathname, status);
76
        return status;
77
    }
78
79
    if (element.Type != ACPI_TYPE_INTEGER) {
80
 
81
        return AE_BAD_DATA;
82
    }
83
84
    *data = element.Integer.Value;
85
 
86
    ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%llu]\n", *data));
87
 
88
    return AE_OK;
89
 
90
91
92
 
93
 
94
95
    /* TBD */
96
 
97
    return;
98
 
99
100
int acpi_bus_get_device(ACPI_HANDLE handle, struct acpi_device **device)
101
 
102
    ACPI_STATUS status = AE_OK;
103
104
    if (!device)
105
 
106
        return -EINVAL;
107
    };
108
109
    /* TBD: Support fixed-feature devices */
110
 
111
    status = AcpiGetData(handle, acpi_bus_data_handler, (void **)device);
112
 
113
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n",
114
                  handle));
115
        return -ENODEV;
116
    }
117
    return 0;
118
}
119
120
121
 
122
 
123
{
124
    ACPI_STATUS status;
125
126
    status = acpi_evaluate_integer(handle, "_STA", NULL, sta);
127
 
128
    {
129
        return AE_OK;
130
    };
131
132
    if (status == AE_NOT_FOUND)
133
 
134
        *sta = ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
135
               ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING;
136
        return AE_OK;
137
    }
138
    return status;
139
}
140
141
142
 
143
 
144
 
145
   -------------------------------------------------------------------------- */
146
147
int acpi_match_device_ids(struct acpi_device *device,
148
 
149
{
150
    const struct acpi_device_ids *id;
151
    struct acpi_hardware_id *hwid;
152
153
    /*
154
 
155
     * driver for it.
156
     */
157
//    if (!device->status.present)
158
//        return -ENODEV;
159
160
    for (id = ids; id->id[0]; id++)
161
 
162
            if (!strcmp((char *) id->id, hwid->id))
163
                return 0;
164
165
    return -ENOENT;
166
 
167
168
169
 
170
 
171
    int result;
172
    struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id;
173
    int found = 0;
174
175
    /*
176
 
177
     * -------
178
     * Link this device to its parent and siblings.
179
     */
180
    INIT_LIST_HEAD(&device->children);
181
    INIT_LIST_HEAD(&device->node);
182
183
    new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
184
 
185
		printk(KERN_ERR PREFIX "Memory allocation error\n");
186
        return -ENOMEM;
187
    }
188
189
    mutex_lock(&acpi_device_lock);
190
 
191
     * Find suitable bus_id and instance number in acpi_bus_id_list
192
     * If failed, create one and link it into acpi_bus_id_list
193
     */
194
    list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node)
195
    {
196
		if (!strcmp(acpi_device_bus_id->bus_id,
197
                acpi_device_hid(device)))
198
        {
199
            acpi_device_bus_id->instance_no++;
200
            found = 1;
201
            kfree(new_bus_id);
202
            break;
203
        }
204
    };
205
206
    if (!found)
207
 
208
        acpi_device_bus_id = new_bus_id;
209
        strcpy(acpi_device_bus_id->bus_id, acpi_device_hid(device));
210
        acpi_device_bus_id->instance_no = 0;
211
        list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list);
212
    }
213
214
//    dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no);
215
 
216
    if (device->parent)
217
 
218
219
    mutex_unlock(&acpi_device_lock);
220
 
221
//    device->dev.bus = &acpi_bus_type;
222
 
223
//    result = device_register(&device->dev);
224
//    if (result) {
225
//        dev_err(&device->dev, "Error registering device\n");
226
//        goto end;
227
//    }
228
229
230
 
231
 
232
end:
233
    mutex_lock(&acpi_device_lock);
234
    if (device->parent)
235
        list_del(&device->node);
236
    mutex_unlock(&acpi_device_lock);
237
    return result;
238
}
239
240
241
 
242
 
243
    ACPI_STATUS status;
244
    struct      acpi_device *device;
245
    int         ret;
246
247
    /*
248
 
249
     * have handles, but we fabricate acpi_devices for them, so we have
250
     * to deal with them specially.
251
     */
252
    if (handle == NULL)
253
        return acpi_root;
254
255
	do {
256
 
257
        if (status == AE_NULL_ENTRY)
258
            return NULL;
259
        if (ACPI_FAILURE(status))
260
            return acpi_root;
261
262
        ret = acpi_bus_get_device(handle, &device);
263
 
264
            return device;
265
    } while (1);
266
}
267
268
269
 
270
 
271
    ACPI_STATUS status = AE_OK;
272
    ACPI_HANDLE temp   = NULL;
273
274
    /* Presence of _STA indicates 'dynamic_status' */
275
 
276
    if (ACPI_SUCCESS(status))
277
        device->flags.dynamic_status = 1;
278
279
    /* Presence of _RMV indicates 'removable' */
280
 
281
    if (ACPI_SUCCESS(status))
282
        device->flags.removable = 1;
283
284
    /* Presence of _EJD|_EJ0 indicates 'ejectable' */
285
 
286
    if (ACPI_SUCCESS(status))
287
        device->flags.ejectable = 1;
288
    else {
289
        status = AcpiGetHandle(device->handle, "_EJ0", &temp);
290
        if (ACPI_SUCCESS(status))
291
            device->flags.ejectable = 1;
292
    }
293
294
    /* Presence of _LCK indicates 'lockable' */
295
 
296
    if (ACPI_SUCCESS(status))
297
        device->flags.lockable = 1;
298
299
    /* Presence of _PS0|_PR0 indicates 'power manageable' */
300
 
301
    if (ACPI_FAILURE(status))
302
        status = AcpiGetHandle(device->handle, "_PR0", &temp);
303
    if (ACPI_SUCCESS(status))
304
        device->flags.power_manageable = 1;
305
306
    /* Presence of _PRW indicates wake capable */
307
 
308
    if (ACPI_SUCCESS(status))
309
        device->flags.wake_capable = 1;
310
311
    /* TBD: Performance management */
312
 
313
    return 0;
314
 
315
316
static void acpi_device_get_busid(struct acpi_device *device)
317
 
318
    char bus_id[5] = { '?', 0 };
319
    struct acpi_buffer buffer = { sizeof(bus_id), bus_id };
320
    int i = 0;
321
322
    /*
323
 
324
     * ------
325
     * The device's Bus ID is simply the object name.
326
     * TBD: Shouldn't this value be unique (within the ACPI namespace)?
327
     */
328
    if (ACPI_IS_ROOT_DEVICE(device)) {
329
        strcpy(device->pnp.bus_id, "ACPI");
330
        return;
331
    }
332
333
    switch (device->device_type)
334
 
335
        case ACPI_BUS_TYPE_POWER_BUTTON:
336
            strcpy(device->pnp.bus_id, "PWRF");
337
            break;
338
        case ACPI_BUS_TYPE_SLEEP_BUTTON:
339
            strcpy(device->pnp.bus_id, "SLPF");
340
            break;
341
        default:
342
            AcpiGetName(device->handle, ACPI_SINGLE_NAME, &buffer);
343
        /* Clean up trailing underscores (if any) */
344
		for (i = 3; i > 1; i--) {
345
                if (bus_id[i] == '_')
346
                    bus_id[i] = '\0';
347
                else
348
                    break;
349
            }
350
            strcpy(device->pnp.bus_id, bus_id);
351
            break;
352
    }
353
}
354
355
356
 
357
 
358
#define ACPI_VIDEO_ROM_AVAILABLE            0x0004
359
#define ACPI_VIDEO_BACKLIGHT                0x0008
360
#define ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR       0x0010
361
#define ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO        0x0020
362
#define ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR    0x0040
363
#define ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO     0x0080
364
#define ACPI_VIDEO_BACKLIGHT_DMI_VENDOR         0x0100
365
#define ACPI_VIDEO_BACKLIGHT_DMI_VIDEO          0x0200
366
#define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR      0x0400
367
#define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO       0x0800
368
369
370
 
371
 
372
    ACPI_HANDLE h_dummy;
373
    long video_caps = 0;
374
375
    if (!device)
376
 
377
378
    /* Is this device able to support video switching ? */
379
 
380
        ACPI_SUCCESS(AcpiGetHandle(device->handle, "_DOS", &h_dummy)))
381
        video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING;
382
383
    /* Is this device able to retrieve a video ROM ? */
384
 
385
        video_caps |= ACPI_VIDEO_ROM_AVAILABLE;
386
387
    /* Is this device able to configure which video head to be POSTed ? */
388
 
389
        ACPI_SUCCESS(AcpiGetHandle(device->handle, "_GPD", &h_dummy)) &&
390
        ACPI_SUCCESS(AcpiGetHandle(device->handle, "_SPD", &h_dummy)))
391
        video_caps |= ACPI_VIDEO_DEVICE_POSTING;
392
393
     return video_caps;
394
 
395
396
/*
397
 
398
 *
399
 * If an acpi object is ejectable and has one of the ACPI ATA methods defined,
400
 * then we can safely call it an ejectable drive bay
401
 */
402
static int acpi_bay_match(struct acpi_device *device){
403
    ACPI_STATUS status;
404
    ACPI_HANDLE handle;
405
    ACPI_HANDLE tmp;
406
    ACPI_HANDLE phandle;
407
408
    handle = device->handle;
409
 
410
    status = AcpiGetHandle(handle, "_EJ0", &tmp);
411
 
412
        return -ENODEV;
413
414
    if ((ACPI_SUCCESS(AcpiGetHandle(handle, "_GTF", &tmp))) ||
415
 
416
        (ACPI_SUCCESS(AcpiGetHandle(handle, "_STM", &tmp))) ||
417
        (ACPI_SUCCESS(AcpiGetHandle(handle, "_SDD", &tmp))))
418
        return 0;
419
420
    if (AcpiGetParent(handle, &phandle))
421
 
422
423
    if ((ACPI_SUCCESS(AcpiGetHandle(phandle, "_GTF", &tmp))) ||
424
 
425
        (ACPI_SUCCESS(AcpiGetHandle(phandle, "_STM", &tmp))) ||
426
        (ACPI_SUCCESS(AcpiGetHandle(phandle, "_SDD", &tmp))))
427
        return 0;
428
429
    return -ENODEV;
430
 
431
432
/*
433
 
434
 */
435
static int acpi_dock_match(struct acpi_device *device)
436
{
437
    ACPI_HANDLE tmp;
438
    return AcpiGetHandle(device->handle, "_DCK", &tmp);
439
}
440
441
char *acpi_device_hid(struct acpi_device *device)
442
 
443
    struct acpi_hardware_id *hid;
444
445
    hid = list_first_entry(&device->pnp.ids, struct acpi_hardware_id, list);
446
 
447
}
448
449
static void acpi_add_id(struct acpi_device *device, const char *dev_id)
450
 
451
    struct acpi_hardware_id *id;
452
453
    id = kmalloc(sizeof(*id), GFP_KERNEL);
454
 
455
        return;
456
457
    INIT_LIST_HEAD(&id->list);
458
 
459
    id->id = kmalloc(strlen(dev_id) + 1, GFP_KERNEL);
460
 
461
        kfree(id);
462
        return;
463
    }
464
465
    strcpy(id->id, dev_id);
466
 
467
}
468
469
470
 
471
 
472
 
473
    ACPI_STATUS status;
474
    ACPI_DEVICE_INFO *info;
475
    ACPI_DEVICE_ID_LIST *cid_list;
476
    int i;
477
478
    switch (device->device_type)
479
 
480
        case ACPI_BUS_TYPE_DEVICE:
481
		if (ACPI_IS_ROOT_DEVICE(device)) {
482
                acpi_add_id(device, ACPI_SYSTEM_HID);
483
                break;
484
            }
485
486
            status = AcpiGetObjectInfo(device->handle, &info);
487
 
488
                printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__);
489
                return;
490
            }
491
492
            if (info->Valid & ACPI_VALID_HID)
493
 
494
            if (info->Valid & ACPI_VALID_CID)
495
            {
496
                cid_list = &info->CompatibleIdList;
497
                for (i = 0; i < cid_list->Count; i++)
498
                    acpi_add_id(device, cid_list->Ids[i].String);
499
            }
500
            if (info->Valid & ACPI_VALID_ADR) {
501
                device->pnp.bus_address = info->Address;
502
                device->flags.bus_address = 1;
503
            }
504
505
            kfree(info);
506
 
507
        /*
508
 
509
         * synthetic HIDs to make sure drivers can find them.
510
         */
511
        if (acpi_is_video_device(device))
512
            acpi_add_id(device, ACPI_VIDEO_HID);
513
        else if (ACPI_SUCCESS(acpi_bay_match(device)))
514
            acpi_add_id(device, ACPI_BAY_HID);
515
        else if (ACPI_SUCCESS(acpi_dock_match(device)))
516
            acpi_add_id(device, ACPI_DOCK_HID);
517
        else if (!acpi_device_hid(device) &&
518
             ACPI_IS_ROOT_DEVICE(device->parent)) {
519
            acpi_add_id(device, ACPI_BUS_HID); /* \_SB, LNXSYBUS */
520
            strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
521
            strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
522
        }
523
524
        break;
525
 
526
        acpi_add_id(device, ACPI_POWER_HID);
527
        break;
528
    case ACPI_BUS_TYPE_PROCESSOR:
529
        acpi_add_id(device, ACPI_PROCESSOR_OBJECT_HID);
530
        break;
531
    case ACPI_BUS_TYPE_THERMAL:
532
        acpi_add_id(device, ACPI_THERMAL_HID);
533
        break;
534
    case ACPI_BUS_TYPE_POWER_BUTTON:
535
        acpi_add_id(device, ACPI_BUTTON_HID_POWERF);
536
        break;
537
    case ACPI_BUS_TYPE_SLEEP_BUTTON:
538
        acpi_add_id(device, ACPI_BUTTON_HID_SLEEPF);
539
        break;
540
    }
541
542
    /*
543
 
544
     * e.g., PCI bridges and slots.  Drivers can't bind to these objects,
545
     * but we do use them indirectly by traversing the acpi_device tree.
546
     * This generic ID isn't useful for driver binding, but it provides
547
     * the useful property that "every acpi_device has an ID."
548
     */
549
    if (list_empty(&device->pnp.ids))
550
        acpi_add_id(device, "device");
551
}
552
553
static int acpi_device_set_context(struct acpi_device *device)
554
 
555
    ACPI_STATUS status;
556
557
    /*
558
 
559
     * -------
560
     * Attach this 'struct acpi_device' to the ACPI object.  This makes
561
     * resolutions from handle->device very efficient.  Fixed hardware
562
     * devices have no handles, so we skip them.
563
     */
564
    if (!device->handle)
565
        return 0;
566
567
    status = AcpiAttachData(device->handle,
568
 
569
    if (ACPI_SUCCESS(status))
570
        return 0;
571
572
	printk(KERN_ERR PREFIX "Error attaching device data\n");
573
 
574
}
575
576
577
 
578
 
579
                  unsigned long long sta,
580
                  struct acpi_bus_ops *ops)
581
{
582
    int result;
583
    struct acpi_device *device;
584
    ACPI_BUFFER buffer = { ACPI_ALLOCATE_BUFFER, NULL };
585
586
    device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL);
587
 
588
		printk(KERN_ERR PREFIX "Memory allocation error\n");
589
        return -ENOMEM;
590
    }
591
592
    INIT_LIST_HEAD(&device->pnp.ids);
593
 
594
    device->handle = handle;
595
    device->parent = acpi_bus_get_parent(handle);
596
    device->bus_ops = *ops; /* workround for not call .start */
597
    STRUCT_TO_INT(device->status) = sta;
598
599
    acpi_device_get_busid(device);
600
 
601
    /*
602
 
603
     * -----
604
     * Note that we only look for object handles -- cannot evaluate objects
605
     * until we know the device is present and properly initialized.
606
     */
607
    result = acpi_bus_get_flags(device);
608
    if (result)
609
        goto end;
610
611
    /*
612
 
613
     * -----------------
614
     * TBD: Synch with Core's enumeration/initialization process.
615
     */
616
    acpi_device_set_id(device);
617
618
619
 
620
 
621
622
    result = acpi_device_register(device);
623
 
624
    /*
625
 
626
     */
627
    if (device->flags.bus_address) {
628
        if (device->parent && device->parent->ops.bind)
1628 serge 629
            device->parent->ops.bind(device);
630
    }
631
632
end:
1627 serge 633
 
634
        AcpiGetName(handle, ACPI_FULL_PATHNAME, &buffer);
635
        dbgprintf(PREFIX "Adding [%s]\n", (char *)buffer.Pointer);
636
        kfree(buffer.Pointer);
637
        *child = device;
638
    };
639
    return result;
640
}
641
642
#define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \
643
 
644
645
static int acpi_bus_type_and_status(ACPI_HANDLE handle, int *type,
646
 
647
{
648
    ACPI_STATUS status;
649
    ACPI_OBJECT_TYPE acpi_type;
650
651
    status = AcpiGetType(handle, &acpi_type);
652
 
653
        return -ENODEV;
654
655
    switch (acpi_type)
656
 
657
        case ACPI_TYPE_ANY:     /* for ACPI_ROOT_OBJECT */
658
        case ACPI_TYPE_DEVICE:
659
            *type = ACPI_BUS_TYPE_DEVICE;
660
            status = acpi_bus_get_status_handle(handle, sta);
661
            if (ACPI_FAILURE(status))
662
                return -ENODEV;
663
            break;
664
        case ACPI_TYPE_PROCESSOR:
665
            *type = ACPI_BUS_TYPE_PROCESSOR;
666
            status = acpi_bus_get_status_handle(handle, sta);
667
            if (ACPI_FAILURE(status))
668
                return -ENODEV;
669
            break;
670
        case ACPI_TYPE_THERMAL:
671
            *type = ACPI_BUS_TYPE_THERMAL;
672
            *sta = ACPI_STA_DEFAULT;
673
            break;
674
        case ACPI_TYPE_POWER:
675
            *type = ACPI_BUS_TYPE_POWER;
676
            *sta = ACPI_STA_DEFAULT;
677
            break;
678
        default:
679
            return -ENODEV;
680
    }
681
682
    return 0;
683
 
684
685
686
 
687
 
688
{
689
    struct acpi_bus_ops *ops = context;
690
    int type;
691
    unsigned long long sta;
692
    struct acpi_device *device;
693
    ACPI_STATUS status;
694
    int result;
695
696
    result = acpi_bus_type_and_status(handle, &type, &sta);
697
 
698
        return AE_OK;
699
700
    if (!(sta & ACPI_STA_DEVICE_PRESENT) &&
701
 
702
        return AE_CTRL_DEPTH;
703
704
    /*
705
 
706
     * so, we needn't add it again, but we may still have to start it.
707
     */
708
    device = NULL;
709
    acpi_bus_get_device(handle, &device);
710
    if (ops->acpi_op_add && !device)
711
        acpi_add_single_object(&device, handle, type, sta, ops);
712
713
    if (!device)
714
 
715
716
/*
717
 
718
        status = acpi_start_single_object(device);
719
        if (ACPI_FAILURE(status))
720
            return AE_CTRL_DEPTH;
721
    }
722
*/
723
724
    if (!*return_value)
725
 
726
    return AE_OK;
727
}
728
729
730
 
731
 
732
{
733
    ACPI_STATUS status;
734
    void *device = NULL;
735
736
    status = acpi_bus_check_add(handle, 0, ops, &device);
737
 
738
        AcpiWalkNamespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
739
                    acpi_bus_check_add, NULL, ops, &device);
740
741
    if (child)
742
 
743
744
    if (device)
745
 
746
    else
747
        return -ENODEV;
748
}
749
750
751
 
752
 
753
    int err;
754
    struct acpi_bus_ops ops;
755
756
    memset(&ops, 0, sizeof(ops));
757
 
758
    ops.acpi_op_start = 1;
759
760
    err = acpi_bus_scan(ACPI_ROOT_OBJECT, &ops, &acpi_root);
761
 
762
    return err;
763
 
764