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