Subversion Repositories Kolibri OS

Rev

Rev 1867 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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