Subversion Repositories Kolibri OS

Rev

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

Rev 9499 Rev 9583
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
#include "dmdev.h"
9
#include "dmdev.h"
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
LIST_HEAD(acpi_device_list);
20
LIST_HEAD(acpi_device_list);
21
LIST_HEAD(acpi_bus_id_list);
21
LIST_HEAD(acpi_bus_id_list);
22
LIST_HEAD(dmdev_tree);
22
LIST_HEAD(dmdev_tree);
23
 
23
 
24
 
24
 
25
struct acpi_device_bus_id
25
struct acpi_device_bus_id
26
{
26
{
27
    char bus_id[15];
27
    char bus_id[15];
28
    unsigned int instance_no;
28
    unsigned int instance_no;
29
    struct list_head node;
29
    struct list_head node;
30
};
30
};
31
 
31
 
32
 
32
 
33
#define ACPI_NS_ROOT_PATH       "\\"
33
#define ACPI_NS_ROOT_PATH       "\\"
34
#define ACPI_NS_SYSTEM_BUS      "_SB_"
34
#define ACPI_NS_SYSTEM_BUS      "_SB_"
35
 
35
 
36
enum acpi_irq_model_id {
36
enum acpi_irq_model_id {
37
	ACPI_IRQ_MODEL_PIC = 0,
37
	ACPI_IRQ_MODEL_PIC = 0,
38
	ACPI_IRQ_MODEL_IOAPIC,
38
	ACPI_IRQ_MODEL_IOAPIC,
39
	ACPI_IRQ_MODEL_IOSAPIC,
39
	ACPI_IRQ_MODEL_IOSAPIC,
40
	ACPI_IRQ_MODEL_PLATFORM,
40
	ACPI_IRQ_MODEL_PLATFORM,
41
	ACPI_IRQ_MODEL_COUNT
41
	ACPI_IRQ_MODEL_COUNT
42
};
42
};
43
 
43
 
44
enum acpi_bus_removal_type {
44
enum acpi_bus_removal_type {
45
    ACPI_BUS_REMOVAL_NORMAL = 0,
45
    ACPI_BUS_REMOVAL_NORMAL = 0,
46
    ACPI_BUS_REMOVAL_EJECT,
46
    ACPI_BUS_REMOVAL_EJECT,
47
    ACPI_BUS_REMOVAL_SUPRISE,
47
    ACPI_BUS_REMOVAL_SUPRISE,
48
    ACPI_BUS_REMOVAL_TYPE_COUNT
48
    ACPI_BUS_REMOVAL_TYPE_COUNT
49
};
49
};
50
 
50
 
51
 
51
 
52
#define PCI_MAX_DEVICES 32
52
#define PCI_MAX_DEVICES 32
53
#define PCI_MAX_PINS    4
53
#define PCI_MAX_PINS    4
54
 
54
 
55
#define IRQ_TABLE_ENTRIES   (PCI_MAX_DEVICES * PCI_MAX_PINS)
55
#define IRQ_TABLE_ENTRIES   (PCI_MAX_DEVICES * PCI_MAX_PINS)
56
 
56
 
57
static int irqtable[IRQ_TABLE_ENTRIES];
57
static int irqtable[IRQ_TABLE_ENTRIES];
58
static ACPI_HANDLE pci_root_handle;
58
static ACPI_HANDLE pci_root_handle;
59
 
59
 
60
 
60
 
61
#define  addr_offset(addr, off) \
61
#define  addr_offset(addr, off) \
62
    (addr_t)((addr_t)(addr) + (addr_t)(off))
62
    (addr_t)((addr_t)(addr) + (addr_t)(off))
63
 
63
 
64
//#define acpi_remap( addr ) \
64
//#define acpi_remap( addr ) \
65
//    (addr_t)((addr_t)(addr) + OS_BASE)
65
//    (addr_t)((addr_t)(addr) + OS_BASE)
66
 
66
 
67
#define acpi_remap( addr ) MapIoMem((void*)(addr),4096, 0x01)
67
#define acpi_remap( addr ) MapIoMem((void*)(addr),4096, 0x01)
68
 
68
 
69
char* strdup(const char *str);
69
char* strdup(const char *str);
70
int sprintf(char *buf, const char *fmt, ...);
70
int sprintf(char *buf, const char *fmt, ...);
71
 
71
 
72
void print_pci_irqs();
72
void print_pci_irqs();
73
 
73
 
74
 
74
 
75
struct acpi_device *acpi_root;
75
struct acpi_device *acpi_root;
76
 
76
 
77
extern struct resource iomem_resource;
77
extern struct resource iomem_resource;
78
extern struct resource ioport_resource;
78
extern struct resource ioport_resource;
79
 
79
 
80
enum pic_mode
80
enum pic_mode
81
{
81
{
82
    IO_PIC  = 0,
82
    IO_PIC  = 0,
83
    IO_APIC
83
    IO_APIC
84
};
84
};
85
 
85
 
86
static ACPI_STATUS
86
static ACPI_STATUS
87
resource_to_addr(ACPI_RESOURCE *resource, ACPI_RESOURCE_ADDRESS64 *addr);
87
resource_to_addr(ACPI_RESOURCE *resource, ACPI_RESOURCE_ADDRESS64 *addr);
88
 
88
 
89
static void create_dm_list();
89
static void create_dm_list();
90
 
90
 
91
static void print_dm_list();
91
static void print_dm_list();
92
 
92
 
93
int write_device_dat(char *path);
93
int write_device_dat(char *path);
94
 
94
 
95
 
95
 
96
static void set_pic_mode(enum pic_mode mode)
96
static void set_pic_mode(enum pic_mode mode)
97
{
97
{
98
    ACPI_OBJECT arg1;
98
    ACPI_OBJECT arg1;
99
    ACPI_OBJECT_LIST args;
99
    ACPI_OBJECT_LIST args;
100
    ACPI_STATUS as;
100
    ACPI_STATUS as;
101
 
101
 
102
    arg1.Type = ACPI_TYPE_INTEGER;
102
    arg1.Type = ACPI_TYPE_INTEGER;
103
    arg1.Integer.Value = mode;
103
    arg1.Integer.Value = mode;
104
    args.Count = 1;
104
    args.Count = 1;
105
    args.Pointer = &arg1;
105
    args.Pointer = &arg1;
106
 
106
 
107
    as = AcpiEvaluateObject(ACPI_ROOT_OBJECT, "_PIC", &args, NULL);
107
    as = AcpiEvaluateObject(ACPI_ROOT_OBJECT, "_PIC", &args, NULL);
108
    /*
108
    /*
109
     * We can silently ignore failure as it may not be implemented, ACPI should
109
     * We can silently ignore failure as it may not be implemented, ACPI should
110
     * provide us with correct information anyway
110
     * provide us with correct information anyway
111
     */
111
     */
112
    if (ACPI_SUCCESS(as))
112
    if (ACPI_SUCCESS(as))
113
        dbgprintf(PREFIX "machine set to %s mode\n", mode ? "APIC" : "PIC");
113
        dbgprintf(PREFIX "machine set to %s mode\n", mode ? "APIC" : "PIC");
114
}
114
}
115
 
115
 
116
 
116
 
117
 
117
 
118
static bool pci_use_crs = false;
118
static bool pci_use_crs = false;
119
 
119
 
120
#define IORESOURCE_BUS      0x00001000
120
#define IORESOURCE_BUS      0x00001000
121
 
121
 
122
 
122
 
123
extern struct list_head acpi_pci_roots;
123
extern struct list_head acpi_pci_roots;
124
 
124
 
125
#define ACPI_PCI_ROOT_CLASS     "pci_bridge"
125
#define ACPI_PCI_ROOT_CLASS     "pci_bridge"
126
#define ACPI_PCI_ROOT_DEVICE_NAME   "PCI Root Bridge"
126
#define ACPI_PCI_ROOT_DEVICE_NAME   "PCI Root Bridge"
127
 
127
 
128
static ACPI_STATUS
128
static ACPI_STATUS
129
get_root_bridge_busnr_callback(ACPI_RESOURCE *resource, void *data)
129
get_root_bridge_busnr_callback(ACPI_RESOURCE *resource, void *data)
130
{
130
{
131
    struct resource *res = data;
131
    struct resource *res = data;
132
    ACPI_RESOURCE_ADDRESS64 address;
132
    ACPI_RESOURCE_ADDRESS64 address;
133
 
133
 
134
    if (resource->Type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
134
    if (resource->Type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
135
        resource->Type != ACPI_RESOURCE_TYPE_ADDRESS32 &&
135
        resource->Type != ACPI_RESOURCE_TYPE_ADDRESS32 &&
136
        resource->Type != ACPI_RESOURCE_TYPE_ADDRESS64)
136
        resource->Type != ACPI_RESOURCE_TYPE_ADDRESS64)
137
        return AE_OK;
137
        return AE_OK;
138
 
138
 
139
    AcpiResourceToAddress64(resource, &address);
139
    AcpiResourceToAddress64(resource, &address);
140
    if ((address.AddressLength > 0) &&
140
    if ((address.AddressLength > 0) &&
141
        (address.ResourceType == ACPI_BUS_NUMBER_RANGE)) {
141
        (address.ResourceType == ACPI_BUS_NUMBER_RANGE)) {
142
        res->start = address.Minimum;
142
        res->start = address.Minimum;
143
        res->end = address.Minimum + address.AddressLength - 1;
143
        res->end = address.Minimum + address.AddressLength - 1;
144
    }
144
    }
145
 
145
 
146
    return AE_OK;
146
    return AE_OK;
147
}
147
}
148
 
148
 
149
 
149
 
150
 
150
 
151
static ACPI_STATUS try_get_root_bridge_busnr(ACPI_HANDLE handle,
151
static ACPI_STATUS try_get_root_bridge_busnr(ACPI_HANDLE handle,
152
                         struct resource *res)
152
                         struct resource *res)
153
{
153
{
154
    ACPI_STATUS status;
154
    ACPI_STATUS status;
155
 
155
 
156
    res->start = -1;
156
    res->start = -1;
157
    status =
157
    status =
158
        AcpiWalkResources(handle, METHOD_NAME__CRS,
158
        AcpiWalkResources(handle, METHOD_NAME__CRS,
159
                get_root_bridge_busnr_callback, res);
159
                get_root_bridge_busnr_callback, res);
160
    if (ACPI_FAILURE(status))
160
    if (ACPI_FAILURE(status))
161
        return status;
161
        return status;
162
    if (res->start == -1)
162
    if (res->start == -1)
163
        return AE_ERROR;
163
        return AE_ERROR;
164
    return AE_OK;
164
    return AE_OK;
165
}
165
}
166
 
166
 
167
 
167
 
168
static void acpi_pci_bridge_scan(struct acpi_device *device)
168
static void acpi_pci_bridge_scan(struct acpi_device *device)
169
{
169
{
170
    int status;
170
    int status;
171
    struct acpi_device *child = NULL;
171
    struct acpi_device *child = NULL;
172
 
172
 
173
    if (device->flags.bus_address)
173
    if (device->flags.bus_address)
174
        if (device->parent && device->parent->ops.bind) {
174
        if (device->parent && device->parent->ops.bind) {
175
            status = device->parent->ops.bind(device);
175
            status = device->parent->ops.bind(device);
176
            if (!status) {
176
            if (!status) {
177
                list_for_each_entry(child, &device->children, node)
177
                list_for_each_entry(child, &device->children, node)
178
                    acpi_pci_bridge_scan(child);
178
                    acpi_pci_bridge_scan(child);
179
            }
179
            }
180
        }
180
        }
181
}
181
}
182
 
182
 
183
 
183
 
184
 
184
 
185
struct pci_root_info
185
struct pci_root_info
186
{
186
{
187
    struct acpi_device *bridge;
187
    struct acpi_device *bridge;
188
    char *name;
188
    char *name;
189
    unsigned int res_num;
189
    unsigned int res_num;
190
    struct resource *res;
190
    struct resource *res;
191
    struct pci_bus *bus;
191
    struct pci_bus *bus;
192
    int busnum;
192
    int busnum;
193
};
193
};
194
 
194
 
195
 
195
 
196
static ACPI_STATUS
196
static ACPI_STATUS
197
resource_to_addr(ACPI_RESOURCE *resource, ACPI_RESOURCE_ADDRESS64 *addr)
197
resource_to_addr(ACPI_RESOURCE *resource, ACPI_RESOURCE_ADDRESS64 *addr)
198
{
198
{
199
    ACPI_STATUS status;
199
    ACPI_STATUS status;
200
    struct acpi_resource_memory24 *memory24;
200
    struct acpi_resource_memory24 *memory24;
201
    struct acpi_resource_memory32 *memory32;
201
    struct acpi_resource_memory32 *memory32;
202
    struct acpi_resource_fixed_memory32 *fixed_memory32;
202
    struct acpi_resource_fixed_memory32 *fixed_memory32;
203
 
203
 
204
    memset(addr, 0, sizeof(*addr));
204
    memset(addr, 0, sizeof(*addr));
205
    switch (resource->Type) {
205
    switch (resource->Type) {
206
    case ACPI_RESOURCE_TYPE_MEMORY24:
206
    case ACPI_RESOURCE_TYPE_MEMORY24:
207
        memory24 = &resource->Data.Memory24;
207
        memory24 = &resource->Data.Memory24;
208
        addr->ResourceType = ACPI_MEMORY_RANGE;
208
        addr->ResourceType = ACPI_MEMORY_RANGE;
209
        addr->Minimum = memory24->Minimum;
209
        addr->Minimum = memory24->Minimum;
210
        addr->AddressLength = memory24->AddressLength;
210
        addr->AddressLength = memory24->AddressLength;
211
        addr->Maximum = addr->Minimum + addr->AddressLength - 1;
211
        addr->Maximum = addr->Minimum + addr->AddressLength - 1;
212
        return AE_OK;
212
        return AE_OK;
213
    case ACPI_RESOURCE_TYPE_MEMORY32:
213
    case ACPI_RESOURCE_TYPE_MEMORY32:
214
        memory32 = &resource->Data.Memory32;
214
        memory32 = &resource->Data.Memory32;
215
        addr->ResourceType = ACPI_MEMORY_RANGE;
215
        addr->ResourceType = ACPI_MEMORY_RANGE;
216
        addr->Minimum = memory32->Minimum;
216
        addr->Minimum = memory32->Minimum;
217
        addr->AddressLength = memory32->AddressLength;
217
        addr->AddressLength = memory32->AddressLength;
218
        addr->Maximum = addr->Minimum + addr->AddressLength - 1;
218
        addr->Maximum = addr->Minimum + addr->AddressLength - 1;
219
        return AE_OK;
219
        return AE_OK;
220
    case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
220
    case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
221
        fixed_memory32 = &resource->Data.FixedMemory32;
221
        fixed_memory32 = &resource->Data.FixedMemory32;
222
        addr->ResourceType = ACPI_MEMORY_RANGE;
222
        addr->ResourceType = ACPI_MEMORY_RANGE;
223
        addr->Minimum = fixed_memory32->Address;
223
        addr->Minimum = fixed_memory32->Address;
224
        addr->AddressLength = fixed_memory32->AddressLength;
224
        addr->AddressLength = fixed_memory32->AddressLength;
225
        addr->Maximum = addr->Minimum + addr->AddressLength - 1;
225
        addr->Maximum = addr->Minimum + addr->AddressLength - 1;
226
        return AE_OK;
226
        return AE_OK;
227
    case ACPI_RESOURCE_TYPE_ADDRESS16:
227
    case ACPI_RESOURCE_TYPE_ADDRESS16:
228
    case ACPI_RESOURCE_TYPE_ADDRESS32:
228
    case ACPI_RESOURCE_TYPE_ADDRESS32:
229
    case ACPI_RESOURCE_TYPE_ADDRESS64:
229
    case ACPI_RESOURCE_TYPE_ADDRESS64:
230
        status = AcpiResourceToAddress64(resource, addr);
230
        status = AcpiResourceToAddress64(resource, addr);
231
        if (ACPI_SUCCESS(status) &&
231
        if (ACPI_SUCCESS(status) &&
232
            (addr->ResourceType == ACPI_MEMORY_RANGE ||
232
            (addr->ResourceType == ACPI_MEMORY_RANGE ||
233
            addr->ResourceType == ACPI_IO_RANGE) &&
233
            addr->ResourceType == ACPI_IO_RANGE) &&
234
            addr->AddressLength > 0) {
234
            addr->AddressLength > 0) {
235
            return AE_OK;
235
            return AE_OK;
236
        }
236
        }
237
        break;
237
        break;
238
    }
238
    }
239
    return AE_ERROR;
239
    return AE_ERROR;
240
}
240
}
241
 
241
 
242
 
242
 
243
static ACPI_STATUS
243
static ACPI_STATUS
244
count_resource(ACPI_RESOURCE *acpi_res, void *data)
244
count_resource(ACPI_RESOURCE *acpi_res, void *data)
245
{
245
{
246
    struct pci_root_info *info = data;
246
    struct pci_root_info *info = data;
247
    ACPI_RESOURCE_ADDRESS64 addr;
247
    ACPI_RESOURCE_ADDRESS64 addr;
248
    ACPI_STATUS status;
248
    ACPI_STATUS status;
249
 
249
 
250
    status = resource_to_addr(acpi_res, &addr);
250
    status = resource_to_addr(acpi_res, &addr);
251
    if (ACPI_SUCCESS(status))
251
    if (ACPI_SUCCESS(status))
252
        info->res_num++;
252
        info->res_num++;
253
    return AE_OK;
253
    return AE_OK;
254
}
254
}
255
 
255
 
256
 
256
 
257
static ACPI_STATUS setup_resource(ACPI_RESOURCE *acpi_res, void *data)
257
static ACPI_STATUS setup_resource(ACPI_RESOURCE *acpi_res, void *data)
258
{
258
{
259
    struct pci_root_info *info = data;
259
    struct pci_root_info *info = data;
260
    struct resource *res;
260
    struct resource *res;
261
    struct acpi_resource_address64 addr;
261
    struct acpi_resource_address64 addr;
262
    ACPI_STATUS status;
262
    ACPI_STATUS status;
263
    unsigned long flags;
263
    unsigned long flags;
264
    u64 start, end;
264
    u64 start, end;
265
 
265
 
266
    status = resource_to_addr(acpi_res, &addr);
266
    status = resource_to_addr(acpi_res, &addr);
267
    if (!ACPI_SUCCESS(status))
267
    if (!ACPI_SUCCESS(status))
268
        return AE_OK;
268
        return AE_OK;
269
 
269
 
270
    if (addr.ResourceType == ACPI_MEMORY_RANGE)
270
    if (addr.ResourceType == ACPI_MEMORY_RANGE)
271
    {
271
    {
272
        flags = IORESOURCE_MEM;
272
        flags = IORESOURCE_MEM;
273
        if (addr.Info.Mem.Caching == ACPI_PREFETCHABLE_MEMORY)
273
        if (addr.Info.Mem.Caching == ACPI_PREFETCHABLE_MEMORY)
274
            flags |= IORESOURCE_PREFETCH;
274
            flags |= IORESOURCE_PREFETCH;
275
    }
275
    }
276
    else if (addr.ResourceType == ACPI_IO_RANGE)
276
    else if (addr.ResourceType == ACPI_IO_RANGE)
277
    {
277
    {
278
        flags = IORESOURCE_IO;
278
        flags = IORESOURCE_IO;
279
    } else
279
    } else
280
        return AE_OK;
280
        return AE_OK;
281
 
281
 
282
    start = addr.Minimum + addr.TranslationOffset;
282
    start = addr.Minimum + addr.TranslationOffset;
283
    end = addr.Maximum + addr.TranslationOffset;
283
    end = addr.Maximum + addr.TranslationOffset;
284
 
284
 
285
    res = &info->res[info->res_num];
285
    res = &info->res[info->res_num];
286
    res->name = info->name;
286
    res->name = info->name;
287
    res->flags = flags;
287
    res->flags = flags;
288
    res->start = start;
288
    res->start = start;
289
    res->end = end;
289
    res->end = end;
290
    res->child = NULL;
290
    res->child = NULL;
291
 
291
 
292
    if (!pci_use_crs) {
292
    if (!pci_use_crs) {
293
        printk("host bridge window %pR (ignored)\n", res);
293
        printk("host bridge window %pR (ignored)\n", res);
294
        return AE_OK;
294
        return AE_OK;
295
    }
295
    }
296
 
296
 
297
    info->res_num++;
297
    info->res_num++;
298
    if (addr.TranslationOffset)
298
    if (addr.TranslationOffset)
299
        dev_info(NULL, "host bridge window %pR "
299
        dev_info(NULL, "host bridge window %pR "
300
             "(PCI address [%#llx-%#llx])\n",
300
             "(PCI address [%#llx-%#llx])\n",
301
             res, res->start - addr.TranslationOffset,
301
             res, res->start - addr.TranslationOffset,
302
             res->end - addr.TranslationOffset);
302
             res->end - addr.TranslationOffset);
303
    else
303
    else
304
        dev_info(NULL,
304
        dev_info(NULL,
305
             "host bridge window %pR\n", res);
305
             "host bridge window %pR\n", res);
306
 
306
 
307
    return AE_OK;
307
    return AE_OK;
308
}
308
}
309
 
309
 
310
 
310
 
311
 
311
 
312
static void
312
static void
313
get_current_resources(struct acpi_device *device, int busnum,
313
get_current_resources(struct acpi_device *device, int busnum,
314
            int domain, struct pci_bus *bus)
314
            int domain, struct pci_bus *bus)
315
{
315
{
316
    struct pci_root_info info;
316
    struct pci_root_info info;
317
    size_t size;
317
    size_t size;
318
 
318
 
319
    char buf[64];
319
    char buf[64];
320
 
320
 
321
//    if (pci_use_crs)
321
//    if (pci_use_crs)
322
//        pci_bus_remove_resources(bus);
322
//        pci_bus_remove_resources(bus);
323
 
323
 
324
    info.bridge = device;
324
    info.bridge = device;
325
    info.bus = bus;
325
    info.bus = bus;
326
    info.res_num = 0;
326
    info.res_num = 0;
327
    AcpiWalkResources(device->handle, METHOD_NAME__CRS, count_resource,
327
    AcpiWalkResources(device->handle, METHOD_NAME__CRS, count_resource,
328
                &info);
328
                &info);
329
    if (!info.res_num)
329
    if (!info.res_num)
330
        return;
330
        return;
331
 
331
 
332
    size = sizeof(*info.res) * info.res_num;
332
    size = sizeof(*info.res) * info.res_num;
333
    info.res = kmalloc(size, GFP_KERNEL);
333
    info.res = kmalloc(size, GFP_KERNEL);
334
    if (!info.res)
334
    if (!info.res)
335
        goto res_alloc_fail;
335
        goto res_alloc_fail;
336
 
336
 
337
    sprintf(buf,"PCI Bus %04x:%02x", domain, busnum);
337
    sprintf(buf,"PCI Bus %04x:%02x", domain, busnum);
338
 
338
 
339
    info.name = strdup(buf);
339
    info.name = strdup(buf);
340
 
340
 
341
    if (!info.name)
341
    if (!info.name)
342
        goto name_alloc_fail;
342
        goto name_alloc_fail;
343
 
343
 
344
    info.res_num = 0;
344
    info.res_num = 0;
345
    AcpiWalkResources(device->handle, METHOD_NAME__CRS, setup_resource,
345
    AcpiWalkResources(device->handle, METHOD_NAME__CRS, setup_resource,
346
                &info);
346
                &info);
347
 
347
 
348
    return;
348
    return;
349
 
349
 
350
name_alloc_fail:
350
name_alloc_fail:
351
    kfree(info.res);
351
    kfree(info.res);
352
res_alloc_fail:
352
res_alloc_fail:
353
    return;
353
    return;
354
}
354
}
355
 
355
 
356
 
356
 
357
struct pci_ops pci_root_ops = {
357
struct pci_ops pci_root_ops = {
358
    .read = NULL,
358
    .read = NULL,
359
    .write = NULL,
359
    .write = NULL,
360
};
360
};
361
 
361
 
362
 
362
 
363
struct pci_bus*  pci_acpi_scan_root(struct acpi_pci_root *root)
363
struct pci_bus*  pci_acpi_scan_root(struct acpi_pci_root *root)
364
{
364
{
365
    struct acpi_device *device = root->device;
365
    struct acpi_device *device = root->device;
366
    int domain = root->segment;
366
    int domain = root->segment;
367
    int busnum = root->secondary.start;
367
    int busnum = root->secondary.start;
368
    struct pci_bus *bus;
368
    struct pci_bus *bus;
369
    struct pci_sysdata *sd;
369
    struct pci_sysdata *sd;
370
	int node = 0;
370
	int node = 0;
371
 
371
 
372
    if (domain ) {
372
    if (domain ) {
373
        printk(KERN_WARNING "pci_bus %04x:%02x: "
373
        printk(KERN_WARNING "pci_bus %04x:%02x: "
374
               "ignored (multiple domains not supported)\n",
374
               "ignored (multiple domains not supported)\n",
375
               domain, busnum);
375
               domain, busnum);
376
        return NULL;
376
        return NULL;
377
    }
377
    }
378
 
378
 
379
	node = -1;
379
	node = -1;
380
    /* Allocate per-root-bus (not per bus) arch-specific data.
380
    /* Allocate per-root-bus (not per bus) arch-specific data.
381
     * TODO: leak; this memory is never freed.
381
     * TODO: leak; this memory is never freed.
382
     * It's arguable whether it's worth the trouble to care.
382
     * It's arguable whether it's worth the trouble to care.
383
     */
383
     */
384
    sd = kzalloc(sizeof(*sd), GFP_KERNEL);
384
    sd = kzalloc(sizeof(*sd), GFP_KERNEL);
385
    if (!sd) {
385
    if (!sd) {
386
        printk(KERN_WARNING "pci_bus %04x:%02x: "
386
        printk(KERN_WARNING "pci_bus %04x:%02x: "
387
               "ignored (out of memory)\n", domain, busnum);
387
               "ignored (out of memory)\n", domain, busnum);
388
        return NULL;
388
        return NULL;
389
    }
389
    }
390
 
390
 
391
    sd->domain = domain;
391
    sd->domain = domain;
392
    sd->node = node;
392
    sd->node = node;
393
    /*
393
    /*
394
     * Maybe the desired pci bus has been already scanned. In such case
394
     * Maybe the desired pci bus has been already scanned. In such case
395
     * it is unnecessary to scan the pci bus with the given domain,busnum.
395
     * it is unnecessary to scan the pci bus with the given domain,busnum.
396
     */
396
     */
397
    bus = pci_find_bus(domain, busnum);
397
    bus = pci_find_bus(domain, busnum);
398
    if (bus) {
398
    if (bus) {
399
        /*
399
        /*
400
         * If the desired bus exits, the content of bus->sysdata will
400
         * If the desired bus exits, the content of bus->sysdata will
401
         * be replaced by sd.
401
         * be replaced by sd.
402
         */
402
         */
403
        memcpy(bus->sysdata, sd, sizeof(*sd));
403
        memcpy(bus->sysdata, sd, sizeof(*sd));
404
        kfree(sd);
404
        kfree(sd);
405
    } else {
405
    } else {
406
        bus = pci_create_bus(busnum, &pci_root_ops, sd);
406
        bus = pci_create_bus(busnum, &pci_root_ops, sd);
407
        if (bus) {
407
        if (bus) {
408
            get_current_resources(device, busnum, domain, bus);
408
            get_current_resources(device, busnum, domain, bus);
409
            bus->subordinate = pci_scan_child_bus(bus);
409
            bus->subordinate = pci_scan_child_bus(bus);
410
        }
410
        }
411
    }
411
    }
412
 
412
 
413
    if (!bus)
413
    if (!bus)
414
        kfree(sd);
414
        kfree(sd);
415
 
415
 
416
    if (bus && node != -1) {
416
    if (bus && node != -1) {
417
        printk("on NUMA node %d\n", node);
417
        printk("on NUMA node %d\n", node);
418
    }
418
    }
419
 
419
 
420
    return bus;
420
    return bus;
421
}
421
}
422
 
422
 
423
 
423
 
424
 
424
 
425
static int acpi_pci_root_add(struct acpi_device *device)
425
static int acpi_pci_root_add(struct acpi_device *device)
426
{
426
{
427
    unsigned long long segment, bus;
427
    unsigned long long segment, bus;
428
    ACPI_STATUS status;
428
    ACPI_STATUS status;
429
    int result;
429
    int result;
430
    struct acpi_pci_root *root;
430
    struct acpi_pci_root *root;
431
    ACPI_HANDLE handle;
431
    ACPI_HANDLE handle;
432
    struct acpi_device *child;
432
    struct acpi_device *child;
433
    u32 flags, base_flags;
433
    u32 flags, base_flags;
434
 
434
 
435
    root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
435
    root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
436
    if (!root)
436
    if (!root)
437
        return -ENOMEM;
437
        return -ENOMEM;
438
 
438
 
439
    segment = 0;
439
    segment = 0;
440
    status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL,
440
    status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL,
441
                       &segment);
441
                       &segment);
442
    if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
442
    if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
443
        printk(KERN_ERR PREFIX "can't evaluate _SEG\n");
443
        printk(KERN_ERR PREFIX "can't evaluate _SEG\n");
444
        result = -ENODEV;
444
        result = -ENODEV;
445
        goto end;
445
        goto end;
446
    }
446
    }
447
 
447
 
448
    /* Check _CRS first, then _BBN.  If no _BBN, default to zero. */
448
    /* Check _CRS first, then _BBN.  If no _BBN, default to zero. */
449
    root->secondary.flags = IORESOURCE_BUS;
449
    root->secondary.flags = IORESOURCE_BUS;
450
    status = try_get_root_bridge_busnr(device->handle, &root->secondary);
450
    status = try_get_root_bridge_busnr(device->handle, &root->secondary);
451
    if (ACPI_FAILURE(status))
451
    if (ACPI_FAILURE(status))
452
    {
452
    {
453
        /*
453
        /*
454
         * We need both the start and end of the downstream bus range
454
         * We need both the start and end of the downstream bus range
455
         * to interpret _CBA (MMCONFIG base address), so it really is
455
         * to interpret _CBA (MMCONFIG base address), so it really is
456
         * supposed to be in _CRS.  If we don't find it there, all we
456
         * supposed to be in _CRS.  If we don't find it there, all we
457
         * can do is assume [_BBN-0xFF] or [0-0xFF].
457
         * can do is assume [_BBN-0xFF] or [0-0xFF].
458
         */
458
         */
459
        root->secondary.end = 0xFF;
459
        root->secondary.end = 0xFF;
460
        printk(KERN_WARNING PREFIX
460
        printk(KERN_WARNING PREFIX
461
               "no secondary bus range in _CRS\n");
461
               "no secondary bus range in _CRS\n");
462
        status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN,                           NULL, &bus);
462
        status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN,                           NULL, &bus);
463
        if (ACPI_SUCCESS(status))
463
        if (ACPI_SUCCESS(status))
464
            root->secondary.start = bus;
464
            root->secondary.start = bus;
465
        else if (status == AE_NOT_FOUND)
465
        else if (status == AE_NOT_FOUND)
466
            root->secondary.start = 0;
466
            root->secondary.start = 0;
467
        else {
467
        else {
468
            printk(KERN_ERR PREFIX "can't evaluate _BBN\n");
468
            printk(KERN_ERR PREFIX "can't evaluate _BBN\n");
469
            result = -ENODEV;
469
            result = -ENODEV;
470
            goto end;
470
            goto end;
471
        }
471
        }
472
    }
472
    }
473
 
473
 
474
    INIT_LIST_HEAD(&root->node);
474
    INIT_LIST_HEAD(&root->node);
475
    root->device = device;
475
    root->device = device;
476
    root->segment = segment & 0xFFFF;
476
    root->segment = segment & 0xFFFF;
477
    strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
477
    strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
478
    strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
478
    strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
479
    device->driver_data = root;
479
    device->driver_data = root;
480
 
480
 
481
    /*
481
    /*
482
     * All supported architectures that use ACPI have support for
482
     * All supported architectures that use ACPI have support for
483
     * PCI domains, so we indicate this in _OSC support capabilities.
483
     * PCI domains, so we indicate this in _OSC support capabilities.
484
     */
484
     */
485
//    flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
485
//    flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
486
//    acpi_pci_osc_support(root, flags);
486
//    acpi_pci_osc_support(root, flags);
487
 
487
 
488
    /*
488
    /*
489
     * TBD: Need PCI interface for enumeration/configuration of roots.
489
     * TBD: Need PCI interface for enumeration/configuration of roots.
490
     */
490
     */
491
 
491
 
492
    /* TBD: Locking */
492
    /* TBD: Locking */
493
    list_add_tail(&root->node, &acpi_pci_roots);
493
    list_add_tail(&root->node, &acpi_pci_roots);
494
 
494
 
495
    printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n",
495
    printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n",
496
           acpi_device_name(device), acpi_device_bid(device),
496
           acpi_device_name(device), acpi_device_bid(device),
497
           root->segment, &root->secondary);
497
           root->segment, &root->secondary);
498
 
498
 
499
    /*
499
    /*
500
     * Scan the Root Bridge
500
     * Scan the Root Bridge
501
     * --------------------
501
     * --------------------
502
     * Must do this prior to any attempt to bind the root device, as the
502
     * Must do this prior to any attempt to bind the root device, as the
503
     * PCI namespace does not get created until this call is made (and
503
     * PCI namespace does not get created until this call is made (and
504
     * thus the root bridge's pci_dev does not exist).
504
     * thus the root bridge's pci_dev does not exist).
505
     */
505
     */
506
 
506
 
507
    root->bus = pci_acpi_scan_root(root);
507
    root->bus = pci_acpi_scan_root(root);
508
    if (!root->bus) {
508
    if (!root->bus) {
509
        printk(KERN_ERR PREFIX
509
        printk(KERN_ERR PREFIX
510
                "Bus %04x:%02x not present in PCI namespace\n",
510
                "Bus %04x:%02x not present in PCI namespace\n",
511
                root->segment, (unsigned int)root->secondary.start);
511
                root->segment, (unsigned int)root->secondary.start);
512
        result = -ENODEV;
512
        result = -ENODEV;
513
        goto end;
513
        goto end;
514
    }
514
    }
515
 
515
 
516
    /*
516
    /*
517
     * Attach ACPI-PCI Context
517
     * Attach ACPI-PCI Context
518
     * -----------------------
518
     * -----------------------
519
     * Thus binding the ACPI and PCI devices.
519
     * Thus binding the ACPI and PCI devices.
520
     */
520
     */
521
    result = acpi_pci_bind_root(device);
521
    result = acpi_pci_bind_root(device);
522
    if (result)
522
    if (result)
523
        goto end;
523
        goto end;
524
 
524
 
525
    /*
525
    /*
526
     * PCI Routing Table
526
     * PCI Routing Table
527
     * -----------------
527
     * -----------------
528
     * Evaluate and parse _PRT, if exists.
528
     * Evaluate and parse _PRT, if exists.
529
     */
529
     */
530
    status = AcpiGetHandle(device->handle, METHOD_NAME__PRT, &handle);
530
    status = AcpiGetHandle(device->handle, METHOD_NAME__PRT, &handle);
531
    if (ACPI_SUCCESS(status))
531
    if (ACPI_SUCCESS(status))
532
        result = acpi_pci_irq_add_prt(device->handle, root->bus);
532
        result = acpi_pci_irq_add_prt(device->handle, root->bus);
533
 
533
 
534
    /*
534
    /*
535
     * Scan and bind all _ADR-Based Devices
535
     * Scan and bind all _ADR-Based Devices
536
     */
536
     */
537
    list_for_each_entry(child, &device->children, node)
537
    list_for_each_entry(child, &device->children, node)
538
        acpi_pci_bridge_scan(child);
538
        acpi_pci_bridge_scan(child);
539
 
539
 
540
    return 0;
540
    return 0;
541
 
541
 
542
end:
542
end:
543
    if (!list_empty(&root->node))
543
    if (!list_empty(&root->node))
544
        list_del(&root->node);
544
        list_del(&root->node);
545
    kfree(root);
545
    kfree(root);
546
    return result;
546
    return result;
547
}
547
}
548
 
548
 
549
 
549
 
550
static const struct acpi_device_ids root_device_ids[] =
550
static const struct acpi_device_ids root_device_ids[] =
551
{
551
{
552
    {"PNP0A03", 0},
552
    {"PNP0A03", 0},
553
    {"",        0},
553
    {"",        0},
554
};
554
};
555
 
555
 
556
void acpi_init_pci(struct acpi_device *device)
556
void acpi_init_pci(struct acpi_device *device)
557
{
557
{
558
    struct acpi_device *child;
558
    struct acpi_device *child;
559
 
559
 
560
    if ( !acpi_match_device_ids(device, root_device_ids) )
560
    if ( !acpi_match_device_ids(device, root_device_ids) )
561
    {
561
    {
562
        dbgprintf(PREFIX "PCI root %s\n", device->pnp.bus_id);
562
        dbgprintf(PREFIX "PCI root %s\n", device->pnp.bus_id);
563
        acpi_pci_root_add(device);
563
        acpi_pci_root_add(device);
564
    };
564
    };
565
 
565
 
566
    list_for_each_entry(child, &device->children, node)
566
    list_for_each_entry(child, &device->children, node)
567
    {
567
    {
568
        acpi_init_pci(child);
568
        acpi_init_pci(child);
569
    };
569
    };
570
 
570
 
571
};
571
};
572
 
572
 
573
uint32_t drvEntry(int action, char *cmdline)
573
uint32_t drvEntry(int action, char *cmdline)
574
{
574
{
575
    uint32_t retval;
575
    uint32_t retval;
576
    ACPI_STATUS status;
576
    ACPI_STATUS status;
577
    int i;
577
    int i;
578
 
578
 
579
    if(action != 1)
579
    if(action != 1)
580
        return 0;
580
        return 0;
581
 
581
 
582
    status = AcpiInitializeSubsystem();
582
    status = AcpiInitializeSubsystem();
583
    if (status != AE_OK) {
583
    if (status != AE_OK) {
584
          printf("AcpiInitializeSubsystem failed (%s)\n",
584
          printf("AcpiInitializeSubsystem failed (%s)\n",
585
                     AcpiFormatException(status));
585
                     AcpiFormatException(status));
586
          goto err;
586
          goto err;
587
    }
587
    }
588
 
588
 
589
    status = AcpiInitializeTables (NULL, 16, FALSE);
589
    status = AcpiInitializeTables (NULL, 16, FALSE);
590
    if (status != AE_OK) {
590
    if (status != AE_OK) {
591
          printf("AcpiInitializeTables failed (%s)\n",
591
          printf("AcpiInitializeTables failed (%s)\n",
592
                     AcpiFormatException(status));
592
                     AcpiFormatException(status));
593
          goto err;
593
          goto err;
594
    }
594
    }
595
 
595
 
596
    status = AcpiLoadTables();
596
    status = AcpiLoadTables();
597
    if (status != AE_OK) {
597
    if (status != AE_OK) {
598
          printf("AcpiLoadTables failed (%s)\n",
598
          printf("AcpiLoadTables failed (%s)\n",
599
                     AcpiFormatException(status));
599
                     AcpiFormatException(status));
600
          goto err;
600
          goto err;
601
    }
601
    }
602
 
602
 
603
    // u32_t mode = ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE;
603
    // u32_t mode = ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE;
604
 
604
 
605
    status = AcpiEnableSubsystem(ACPI_NO_HANDLER_INIT | ACPI_NO_HARDWARE_INIT);
605
    status = AcpiEnableSubsystem(ACPI_NO_HANDLER_INIT | ACPI_NO_HARDWARE_INIT);
606
    if (status != AE_OK) {
606
    if (status != AE_OK) {
607
        dbgprintf("AcpiEnableSubsystem failed (%s)\n",
607
        dbgprintf("AcpiEnableSubsystem failed (%s)\n",
608
            AcpiFormatException(status));
608
            AcpiFormatException(status));
609
        goto err;
609
        goto err;
610
    }
610
    }
611
 
611
 
612
    status = AcpiInitializeObjects (ACPI_FULL_INITIALIZATION);
612
    status = AcpiInitializeObjects (ACPI_FULL_INITIALIZATION);
613
    if (ACPI_FAILURE (status))
613
    if (ACPI_FAILURE (status))
614
    {
614
    {
615
        dbgprintf("AcpiInitializeObjects failed (%s)\n",
615
        dbgprintf("AcpiInitializeObjects failed (%s)\n",
616
            AcpiFormatException(status));
616
            AcpiFormatException(status));
617
        goto err;
617
        goto err;
618
    }
618
    }
619
 
619
 
620
    set_pic_mode(IO_APIC);
620
    set_pic_mode(IO_APIC);
621
    acpi_scan();
621
    acpi_scan();
622
    acpi_init_pci(acpi_root);
622
    acpi_init_pci(acpi_root);
623
    print_pci_irqs();
623
    print_pci_irqs();
624
    create_dm_list();
624
    create_dm_list();
625
    print_dm_list();
625
    print_dm_list();
626
 
626
 
627
    write_device_dat("/RD/1/DRIVERS/DEVICES.DAT");
627
    write_device_dat("/SYS/DRIVERS/DEVICES.DAT");
628
 
628
 
629
err:
629
err:
630
    return 0;
630
    return 0;
631
};
631
};
632
 
632
 
633
char* strdup(const char *str)
633
char* strdup(const char *str)
634
{
634
{
635
    size_t len = strlen (str) + 1;
635
    size_t len = strlen (str) + 1;
636
    char *copy = malloc(len);
636
    char *copy = malloc(len);
637
    if (copy)
637
    if (copy)
638
    {
638
    {
639
        memcpy (copy, str, len);
639
        memcpy (copy, str, len);
640
    }
640
    }
641
    return copy;
641
    return copy;
642
}
642
}
643
 
643
 
644
 
644
 
645
static void dm_add_pci_bus(struct pci_bus *bus)
645
static void dm_add_pci_bus(struct pci_bus *bus)
646
{
646
{
647
    struct pci_bus *tbus;
647
    struct pci_bus *tbus;
648
    struct pci_dev *dev;
648
    struct pci_dev *dev;
649
    dmdev_t        *dmdev;
649
    dmdev_t        *dmdev;
650
 
650
 
651
    dmdev = (dmdev_t*)kzalloc(sizeof(dmdev_t),GFP_KERNEL);
651
    dmdev = (dmdev_t*)kzalloc(sizeof(dmdev_t),GFP_KERNEL);
652
 
652
 
653
//    INIT_LIST_HEAD(&dmdev->list);
653
//    INIT_LIST_HEAD(&dmdev->list);
654
//    dmdev->type = 1;
654
//    dmdev->type = 1;
655
//    dmdev->acpi_dev = bus->self->acpi_dev;
655
//    dmdev->acpi_dev = bus->self->acpi_dev;
656
//    dmdev->pci_dev = bus->self;
656
//    dmdev->pci_dev = bus->self;
657
//    list_add_tail(&dmdev->list, &dmdev_tree);
657
//    list_add_tail(&dmdev->list, &dmdev_tree);
658
 
658
 
659
    list_for_each_entry(dev, &bus->devices, bus_list)
659
    list_for_each_entry(dev, &bus->devices, bus_list)
660
    {
660
    {
661
        dmdev = (dmdev_t*)kzalloc(sizeof(dmdev_t),GFP_KERNEL);
661
        dmdev = (dmdev_t*)kzalloc(sizeof(dmdev_t),GFP_KERNEL);
662
 
662
 
663
        INIT_LIST_HEAD(&dmdev->list);
663
        INIT_LIST_HEAD(&dmdev->list);
664
        dmdev->type = 1;
664
        dmdev->type = 1;
665
        dmdev->acpi_dev = dev->acpi_dev;
665
        dmdev->acpi_dev = dev->acpi_dev;
666
        dmdev->pci_dev = dev;
666
        dmdev->pci_dev = dev;
667
        list_add_tail(&dmdev->list, &dmdev_tree);
667
        list_add_tail(&dmdev->list, &dmdev_tree);
668
    };
668
    };
669
 
669
 
670
    list_for_each_entry(tbus, &bus->children, node)
670
    list_for_each_entry(tbus, &bus->children, node)
671
    {
671
    {
672
        dm_add_pci_bus(tbus);
672
        dm_add_pci_bus(tbus);
673
    };
673
    };
674
 
674
 
675
};
675
};
676
 
676
 
677
static ACPI_STATUS
677
static ACPI_STATUS
678
count_dev_resources(ACPI_RESOURCE *acpi_res, void *data)
678
count_dev_resources(ACPI_RESOURCE *acpi_res, void *data)
679
{
679
{
680
    (*(int*)data)++;
680
    (*(int*)data)++;
681
    return AE_OK;
681
    return AE_OK;
682
}
682
}
683
 
683
 
684
static void dm_add_acpi(struct acpi_device *device)
684
static void dm_add_acpi(struct acpi_device *device)
685
{
685
{
686
    struct acpi_device *child;
686
    struct acpi_device *child;
687
    ACPI_DEVICE_INFO *info = NULL;
687
    ACPI_DEVICE_INFO *info = NULL;
688
    ACPI_STATUS status;
688
    ACPI_STATUS status;
689
 
689
 
690
    dmdev_t  *dmdev;
690
    dmdev_t  *dmdev;
691
    uint32_t  res_num = 0;
691
    uint32_t  res_num = 0;
692
 
692
 
693
    status = AcpiGetObjectInfo(device->handle, &info);
693
    status = AcpiGetObjectInfo(device->handle, &info);
694
 
694
 
695
    if ( (status == AE_OK) && (info->Valid & ACPI_VALID_HID))
695
    if ( (status == AE_OK) && (info->Valid & ACPI_VALID_HID))
696
    {
696
    {
697
        if( strcmp(info->HardwareId.String,"PNP0C0F") == 0)
697
        if( strcmp(info->HardwareId.String,"PNP0C0F") == 0)
698
        {
698
        {
699
            kfree(info);
699
            kfree(info);
700
            return;
700
            return;
701
        };
701
        };
702
    };
702
    };
703
 
703
 
704
    kfree(info);
704
    kfree(info);
705
 
705
 
706
    if(device->pci_dev == NULL)
706
    if(device->pci_dev == NULL)
707
    {
707
    {
708
        AcpiWalkResources(device->handle, METHOD_NAME__CRS,
708
        AcpiWalkResources(device->handle, METHOD_NAME__CRS,
709
                          count_dev_resources, &res_num);
709
                          count_dev_resources, &res_num);
710
 
710
 
711
        if(res_num != 0)
711
        if(res_num != 0)
712
        {
712
        {
713
            dmdev = (dmdev_t*)kzalloc(sizeof(dmdev_t),GFP_KERNEL);
713
            dmdev = (dmdev_t*)kzalloc(sizeof(dmdev_t),GFP_KERNEL);
714
 
714
 
715
            INIT_LIST_HEAD(&dmdev->list);
715
            INIT_LIST_HEAD(&dmdev->list);
716
            dmdev->type = 0;
716
            dmdev->type = 0;
717
            dmdev->acpi_dev = device;
717
            dmdev->acpi_dev = device;
718
            dmdev->pci_dev = NULL;
718
            dmdev->pci_dev = NULL;
719
            list_add_tail(&dmdev->list, &dmdev_tree);
719
            list_add_tail(&dmdev->list, &dmdev_tree);
720
        };
720
        };
721
    };
721
    };
722
    list_for_each_entry(child, &device->children, node)
722
    list_for_each_entry(child, &device->children, node)
723
    {
723
    {
724
        dm_add_acpi(child);
724
        dm_add_acpi(child);
725
    };
725
    };
726
};
726
};
727
 
727
 
728
static void create_dm_list()
728
static void create_dm_list()
729
{
729
{
730
    struct acpi_pci_root *root;
730
    struct acpi_pci_root *root;
731
 
731
 
732
    list_for_each_entry(root, &acpi_pci_roots, node)
732
    list_for_each_entry(root, &acpi_pci_roots, node)
733
    {
733
    {
734
        struct pci_bus *pbus, *tbus;
734
        struct pci_bus *pbus, *tbus;
735
        struct pci_dev *dev;
735
        struct pci_dev *dev;
736
 
736
 
737
        pbus = root->bus;
737
        pbus = root->bus;
738
 
738
 
739
        dm_add_pci_bus(pbus);
739
        dm_add_pci_bus(pbus);
740
    };
740
    };
741
 
741
 
742
    dm_add_acpi(acpi_root);
742
    dm_add_acpi(acpi_root);
743
};
743
};
744
 
744
 
745
static void print_pci_resource(struct resource *res)
745
static void print_pci_resource(struct resource *res)
746
{
746
{
747
    if(res->flags !=0 )
747
    if(res->flags !=0 )
748
    {
748
    {
749
        if(res->flags & IORESOURCE_IO)
749
        if(res->flags & IORESOURCE_IO)
750
            dbgprintf("  IO range ");
750
            dbgprintf("  IO range ");
751
        else if(res->flags & IORESOURCE_MEM)
751
        else if(res->flags & IORESOURCE_MEM)
752
            dbgprintf("  MMIO range ");
752
            dbgprintf("  MMIO range ");
753
        dbgprintf("%x - %x\n", res->start, res->end);
753
        dbgprintf("%x - %x\n", res->start, res->end);
754
    };
754
    };
755
};
755
};
756
 
756
 
757
static ACPI_STATUS
757
static ACPI_STATUS
758
print_acpi_resource(ACPI_RESOURCE *acpi_res, void *data)
758
print_acpi_resource(ACPI_RESOURCE *acpi_res, void *data)
759
{
759
{
760
    ACPI_RESOURCE_ADDRESS64 addr;
760
    ACPI_RESOURCE_ADDRESS64 addr;
761
    ACPI_STATUS status;
761
    ACPI_STATUS status;
762
    int i;
762
    int i;
763
 
763
 
764
    switch (acpi_res->Type)
764
    switch (acpi_res->Type)
765
    {
765
    {
766
        case ACPI_RESOURCE_TYPE_IRQ:
766
        case ACPI_RESOURCE_TYPE_IRQ:
767
        {
767
        {
768
            ACPI_RESOURCE_IRQ *irq_data = (ACPI_RESOURCE_IRQ*)&acpi_res->Data;
768
            ACPI_RESOURCE_IRQ *irq_data = (ACPI_RESOURCE_IRQ*)&acpi_res->Data;
769
            dbgprintf(" IRQ %d\n", irq_data->Interrupts[0]);
769
            dbgprintf(" IRQ %d\n", irq_data->Interrupts[0]);
770
        };
770
        };
771
        break;
771
        break;
772
 
772
 
773
        case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
773
        case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
774
        {
774
        {
775
            ACPI_RESOURCE_EXTENDED_IRQ *irq_data = (ACPI_RESOURCE_EXTENDED_IRQ*)&acpi_res->Data;
775
            ACPI_RESOURCE_EXTENDED_IRQ *irq_data = (ACPI_RESOURCE_EXTENDED_IRQ*)&acpi_res->Data;
776
            dbgprintf(" IRQ %d\n", irq_data->Interrupts[0]);
776
            dbgprintf(" IRQ %d\n", irq_data->Interrupts[0]);
777
        };
777
        };
778
        break;
778
        break;
779
 
779
 
780
        case ACPI_RESOURCE_TYPE_DMA:
780
        case ACPI_RESOURCE_TYPE_DMA:
781
        {
781
        {
782
            ACPI_RESOURCE_DMA *dma_data = (ACPI_RESOURCE_DMA*) &acpi_res->Data;
782
            ACPI_RESOURCE_DMA *dma_data = (ACPI_RESOURCE_DMA*) &acpi_res->Data;
783
            for(i=0; i < dma_data->ChannelCount; i++)
783
            for(i=0; i < dma_data->ChannelCount; i++)
784
            {
784
            {
785
                dbgprintf(" DMA %s channel %d\n",
785
                dbgprintf(" DMA %s channel %d\n",
786
                          dma_data->Type == ACPI_TYPE_A ? "Type A":
786
                          dma_data->Type == ACPI_TYPE_A ? "Type A":
787
                          dma_data->Type == ACPI_TYPE_B ? "Type B" :
787
                          dma_data->Type == ACPI_TYPE_B ? "Type B" :
788
                          dma_data->Type == ACPI_TYPE_F ? "Type F" : "",
788
                          dma_data->Type == ACPI_TYPE_F ? "Type F" : "",
789
                          dma_data->Channels[i]);
789
                          dma_data->Channels[i]);
790
            }
790
            }
791
        };
791
        };
792
        break;
792
        break;
793
 
793
 
794
        case ACPI_RESOURCE_TYPE_IO:
794
        case ACPI_RESOURCE_TYPE_IO:
795
        {
795
        {
796
            ACPI_RESOURCE_IO *io_data = (ACPI_RESOURCE_IO*) &acpi_res->Data;
796
            ACPI_RESOURCE_IO *io_data = (ACPI_RESOURCE_IO*) &acpi_res->Data;
797
 
797
 
798
            dbgprintf(" IO range 0%x-0%x\n",io_data->Minimum,
798
            dbgprintf(" IO range 0%x-0%x\n",io_data->Minimum,
799
                       io_data->Minimum+io_data->AddressLength-1);
799
                       io_data->Minimum+io_data->AddressLength-1);
800
        }
800
        }
801
        break;
801
        break;
802
 
802
 
803
        case ACPI_RESOURCE_TYPE_FIXED_IO:
803
        case ACPI_RESOURCE_TYPE_FIXED_IO:
804
        {
804
        {
805
            ACPI_RESOURCE_FIXED_IO *io_data = (ACPI_RESOURCE_FIXED_IO*) &acpi_res->Data;
805
            ACPI_RESOURCE_FIXED_IO *io_data = (ACPI_RESOURCE_FIXED_IO*) &acpi_res->Data;
806
            dbgprintf(" Fixed IO range 0%x-0%x\n",io_data->Address,
806
            dbgprintf(" Fixed IO range 0%x-0%x\n",io_data->Address,
807
                       io_data->Address+io_data->AddressLength-1);
807
                       io_data->Address+io_data->AddressLength-1);
808
        };
808
        };
809
        break;
809
        break;
810
 
810
 
811
        case ACPI_RESOURCE_TYPE_MEMORY24:
811
        case ACPI_RESOURCE_TYPE_MEMORY24:
812
        case ACPI_RESOURCE_TYPE_MEMORY32:
812
        case ACPI_RESOURCE_TYPE_MEMORY32:
813
        case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
813
        case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
814
        {
814
        {
815
            ACPI_RESOURCE_ADDRESS64 addr64;
815
            ACPI_RESOURCE_ADDRESS64 addr64;
816
            resource_to_addr(acpi_res, &addr64);
816
            resource_to_addr(acpi_res, &addr64);
817
            dbgprintf(" Memory range 0%x-0%x\n",
817
            dbgprintf(" Memory range 0%x-0%x\n",
818
                       (uint32_t)addr64.Minimum, (uint32_t)addr64.Maximum);
818
                       (uint32_t)addr64.Minimum, (uint32_t)addr64.Maximum);
819
        }
819
        }
820
        break;
820
        break;
821
 
821
 
822
        case ACPI_RESOURCE_TYPE_ADDRESS16:
822
        case ACPI_RESOURCE_TYPE_ADDRESS16:
823
        case ACPI_RESOURCE_TYPE_ADDRESS32:
823
        case ACPI_RESOURCE_TYPE_ADDRESS32:
824
        case ACPI_RESOURCE_TYPE_ADDRESS64:
824
        case ACPI_RESOURCE_TYPE_ADDRESS64:
825
        {
825
        {
826
            ACPI_RESOURCE_ADDRESS64 addr64;
826
            ACPI_RESOURCE_ADDRESS64 addr64;
827
            ACPI_STATUS status;
827
            ACPI_STATUS status;
828
 
828
 
829
            status = AcpiResourceToAddress64(acpi_res, &addr64);
829
            status = AcpiResourceToAddress64(acpi_res, &addr64);
830
            if (ACPI_SUCCESS(status))
830
            if (ACPI_SUCCESS(status))
831
            {
831
            {
832
                dbgprintf(" Address range 0%x-0%x\n",
832
                dbgprintf(" Address range 0%x-0%x\n",
833
                       (uint32_t)addr64.Minimum, (uint32_t)addr64.Maximum);
833
                       (uint32_t)addr64.Minimum, (uint32_t)addr64.Maximum);
834
            }
834
            }
835
        };
835
        };
836
        break;
836
        break;
837
    };
837
    };
838
 
838
 
839
    return AE_OK;
839
    return AE_OK;
840
};
840
};
841
 
841
 
842
 
842
 
843
static void print_dm_list()
843
static void print_dm_list()
844
{
844
{
845
    struct pci_dev     *pcidev;
845
    struct pci_dev     *pcidev;
846
    struct acpi_device *acpidev;
846
    struct acpi_device *acpidev;
847
    dmdev_t  *dmdev;
847
    dmdev_t  *dmdev;
848
    uint32_t  i;
848
    uint32_t  i;
849
 
849
 
850
    dbgprintf("\nDevices:\n");
850
    dbgprintf("\nDevices:\n");
851
 
851
 
852
    list_for_each_entry(dmdev, &dmdev_tree, list)
852
    list_for_each_entry(dmdev, &dmdev_tree, list)
853
    {
853
    {
854
        switch(dmdev->type)
854
        switch(dmdev->type)
855
        {
855
        {
856
            case 0:
856
            case 0:
857
               if(dmdev->acpi_dev != NULL)
857
               if(dmdev->acpi_dev != NULL)
858
               {
858
               {
859
                    acpidev = dmdev->acpi_dev;
859
                    acpidev = dmdev->acpi_dev;
860
                    dbgprintf("\n%s\n", acpidev->pnp.bus_id);
860
                    dbgprintf("\n%s\n", acpidev->pnp.bus_id);
861
                    AcpiWalkResources(acpidev->handle, METHOD_NAME__CRS,
861
                    AcpiWalkResources(acpidev->handle, METHOD_NAME__CRS,
862
                                      print_acpi_resource, NULL);
862
                                      print_acpi_resource, NULL);
863
               };
863
               };
864
               break;
864
               break;
865
 
865
 
866
            case 1:
866
            case 1:
867
               if(dmdev->pci_dev != NULL)
867
               if(dmdev->pci_dev != NULL)
868
               {
868
               {
869
                   pcidev = dmdev->pci_dev;
869
                   pcidev = dmdev->pci_dev;
870
                   dbgprintf("\nPCI_%x_%x bus:%d devfn: %x\n",
870
                   dbgprintf("\nPCI_%x_%x bus:%d devfn: %x\n",
871
                               pcidev->vendor, pcidev->device,
871
                               pcidev->vendor, pcidev->device,
872
                               pcidev->busnr, pcidev->devfn);
872
                               pcidev->busnr, pcidev->devfn);
873
 
873
 
874
                   for(i = 0; i < DEVICE_COUNT_RESOURCE; i++)
874
                   for(i = 0; i < DEVICE_COUNT_RESOURCE; i++)
875
                       print_pci_resource(&pcidev->resource[i]);
875
                       print_pci_resource(&pcidev->resource[i]);
876
 
876
 
877
                   if(pcidev->pin)
877
                   if(pcidev->pin)
878
                       dbgprintf("  APIC IRQ: %d\n", acpi_get_irq(pcidev));
878
                       dbgprintf("  APIC IRQ: %d\n", acpi_get_irq(pcidev));
879
               };
879
               };
880
               break;
880
               break;
881
        };
881
        };
882
    };
882
    };
883
};
883
};
884
 
884
 
885
 
885
 
886
typedef struct
886
typedef struct
887
{
887
{
888
    uint32_t  busaddr;
888
    uint32_t  busaddr;
889
    uint32_t  devid;
889
    uint32_t  devid;
890
    uint32_t  irq;
890
    uint32_t  irq;
891
    uint32_t  unused;
891
    uint32_t  unused;
892
}devinfo_t;
892
}devinfo_t;
893
 
893
 
894
#pragma pack(push, 1)
894
#pragma pack(push, 1)
895
typedef struct
895
typedef struct
896
{
896
{
897
  char sec;
897
  char sec;
898
  char min;
898
  char min;
899
  char hour;
899
  char hour;
900
  char rsv;
900
  char rsv;
901
}detime_t;
901
}detime_t;
902
 
902
 
903
typedef struct
903
typedef struct
904
{
904
{
905
  char  day;
905
  char  day;
906
  char  month;
906
  char  month;
907
  short year;
907
  short year;
908
}dedate_t;
908
}dedate_t;
909
 
909
 
910
typedef struct
910
typedef struct
911
{
911
{
912
  unsigned    attr;
912
  unsigned    attr;
913
  unsigned    flags;
913
  unsigned    flags;
914
  union
914
  union
915
  {
915
  {
916
     detime_t  ctime;
916
     detime_t  ctime;
917
     unsigned  cr_time;
917
     unsigned  cr_time;
918
  };
918
  };
919
  union
919
  union
920
  {
920
  {
921
     dedate_t  cdate;
921
     dedate_t  cdate;
922
     unsigned  cr_date;
922
     unsigned  cr_date;
923
  };
923
  };
924
  union
924
  union
925
  {
925
  {
926
     detime_t  atime;
926
     detime_t  atime;
927
     unsigned  acc_time;
927
     unsigned  acc_time;
928
  };
928
  };
929
  union
929
  union
930
  {
930
  {
931
     dedate_t  adate;
931
     dedate_t  adate;
932
     unsigned  acc_date;
932
     unsigned  acc_date;
933
  };
933
  };
934
  union
934
  union
935
  {
935
  {
936
     detime_t  mtime;
936
     detime_t  mtime;
937
     unsigned  mod_time;
937
     unsigned  mod_time;
938
  };
938
  };
939
  union
939
  union
940
  {
940
  {
941
     dedate_t  mdate;
941
     dedate_t  mdate;
942
     unsigned  mod_date;
942
     unsigned  mod_date;
943
  };
943
  };
944
  unsigned    size;
944
  unsigned    size;
945
  unsigned    size_high;
945
  unsigned    size_high;
946
} FILEINFO;
946
} FILEINFO;
947
 
947
 
948
#pragma pack(pop)
948
#pragma pack(pop)
949
 
949
 
950
 
950
 
951
int write_device_dat(char *path)
951
int write_device_dat(char *path)
952
{
952
{
953
    struct pci_dev   *pcidev;
953
    struct pci_dev   *pcidev;
954
    dmdev_t          *dmdev;
954
    dmdev_t          *dmdev;
955
    devinfo_t        *data;
955
    devinfo_t        *data;
956
    int               writes;
956
    int               writes;
957
    int               len;
957
    int               len;
958
    int i = 0;
958
    int i = 0;
959
 
959
 
960
    list_for_each_entry(dmdev, &dmdev_tree, list)
960
    list_for_each_entry(dmdev, &dmdev_tree, list)
961
    {
961
    {
962
        if(dmdev->type ==1)
962
        if(dmdev->type ==1)
963
        {
963
        {
964
            if(dmdev->pci_dev != NULL)
964
            if(dmdev->pci_dev != NULL)
965
            {
965
            {
966
                pcidev = dmdev->pci_dev;
966
                pcidev = dmdev->pci_dev;
967
                if(pcidev->pin)
967
                if(pcidev->pin)
968
                    i++;
968
                    i++;
969
            };
969
            };
970
        };
970
        };
971
    };
971
    };
972
 
972
 
973
    len = sizeof(devinfo_t)*i + 4;
973
    len = sizeof(devinfo_t)*i + 4;
974
    data = (devinfo_t*)malloc(len);
974
    data = (devinfo_t*)malloc(len);
975
 
975
 
976
    i = 0;
976
    i = 0;
977
 
977
 
978
    list_for_each_entry(dmdev, &dmdev_tree, list)
978
    list_for_each_entry(dmdev, &dmdev_tree, list)
979
    {
979
    {
980
        if(dmdev->type == 1)
980
        if(dmdev->type == 1)
981
        {
981
        {
982
 
982
 
983
            if(dmdev->pci_dev != NULL)
983
            if(dmdev->pci_dev != NULL)
984
            {
984
            {
985
                pcidev = dmdev->pci_dev;
985
                pcidev = dmdev->pci_dev;
986
                if(pcidev->pin && (acpi_get_irq(pcidev) != -1) )
986
                if(pcidev->pin && (acpi_get_irq(pcidev) != -1) )
987
                {
987
                {
988
                    data[i].busaddr = (pcidev->busnr<<8)|pcidev->devfn;
988
                    data[i].busaddr = (pcidev->busnr<<8)|pcidev->devfn;
989
                    data[i].devid   = ((uint32_t)pcidev->device<<16) |
989
                    data[i].devid   = ((uint32_t)pcidev->device<<16) |
990
                                       pcidev->vendor;
990
                                       pcidev->vendor;
991
                    data[i].irq     =  acpi_get_irq(pcidev);
991
                    data[i].irq     =  acpi_get_irq(pcidev);
992
                    data[i].unused  =  0;
992
                    data[i].unused  =  0;
993
                    i++;
993
                    i++;
994
                }
994
                }
995
            };
995
            };
996
        };
996
        };
997
    };
997
    };
998
 
998
 
999
    data[i].busaddr = -1;
999
    data[i].busaddr = -1;
1000
 
1000
 
1001
    FILEINFO info;
1001
    FILEINFO info;
1002
 
1002
 
1003
    int offset = 0;
1003
    int offset = 0;
1004
 
1004
 
1005
    if(get_fileinfo(path,&info))
1005
    if(get_fileinfo(path,&info))
1006
    {
1006
    {
1007
        if( create_file(path))
1007
        if( create_file(path))
1008
        {
1008
        {
1009
            free(data);
1009
            free(data);
1010
            return false;
1010
            return false;
1011
        }
1011
        }
1012
    }
1012
    }
1013
    else
1013
    else
1014
        set_file_size(path, 0);
1014
        set_file_size(path, 0);
1015
 
1015
 
1016
    write_file(path, data, 0, len, &writes);
1016
    write_file(path, data, 0, len, &writes);
1017
 
1017
 
1018
    return true;
1018
    return true;
1019
};
1019
};