Subversion Repositories Kolibri OS

Rev

Rev 1867 | Rev 2216 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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