Subversion Repositories Kolibri OS

Rev

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