Subversion Repositories Kolibri OS

Rev

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