Subversion Repositories Kolibri OS

Rev

Rev 1500 | Rev 1627 | 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.  
  10. #define ACPI_BUS_CLASS          "system_bus"
  11. #define ACPI_BUS_HID            "KLBSYBUS"
  12. #define ACPI_BUS_DEVICE_NAME    "System Bus"
  13.  
  14.  
  15. #define ACPI_IS_ROOT_DEVICE(device)    (!(device)->parent)
  16.  
  17. static LIST_HEAD(acpi_device_list);
  18. static LIST_HEAD(acpi_bus_id_list);
  19. DEFINE_MUTEX(acpi_device_lock);
  20.  
  21. struct acpi_device_bus_id
  22. {
  23.     char bus_id[15];
  24.     unsigned int instance_no;
  25.     struct list_head node;
  26. };
  27.  
  28.  
  29. #define ACPI_NS_ROOT_PATH       "\\"
  30. #define ACPI_NS_SYSTEM_BUS      "_SB_"
  31.  
  32. enum acpi_irq_model_id {
  33.         ACPI_IRQ_MODEL_PIC = 0,
  34.         ACPI_IRQ_MODEL_IOAPIC,
  35.         ACPI_IRQ_MODEL_IOSAPIC,
  36.         ACPI_IRQ_MODEL_PLATFORM,
  37.         ACPI_IRQ_MODEL_COUNT
  38. };
  39.  
  40. enum acpi_bus_removal_type {
  41.     ACPI_BUS_REMOVAL_NORMAL = 0,
  42.     ACPI_BUS_REMOVAL_EJECT,
  43.     ACPI_BUS_REMOVAL_SUPRISE,
  44.     ACPI_BUS_REMOVAL_TYPE_COUNT
  45. };
  46.  
  47. enum acpi_bus_device_type {
  48.     ACPI_BUS_TYPE_DEVICE = 0,
  49.     ACPI_BUS_TYPE_POWER,
  50.     ACPI_BUS_TYPE_PROCESSOR,
  51.     ACPI_BUS_TYPE_THERMAL,
  52.     ACPI_BUS_TYPE_POWER_BUTTON,
  53.     ACPI_BUS_TYPE_SLEEP_BUTTON,
  54.     ACPI_BUS_DEVICE_TYPE_COUNT
  55. };
  56.  
  57. /*
  58.  * _HID definitions
  59.  * HIDs must conform to ACPI spec(6.1.4)
  60.  * KolibriOS specific HIDs do not apply to this and begin with KOS:
  61.  */
  62.  
  63. #define ACPI_POWER_HID              "KLBPOWER"
  64. #define ACPI_PROCESSOR_OBJECT_HID   "KLBCPU"
  65. #define ACPI_SYSTEM_HID             "KLBSYSTM"
  66. #define ACPI_THERMAL_HID            "KLBTHERM"
  67. #define ACPI_BUTTON_HID_POWERF      "KLBPWRBN"
  68. #define ACPI_BUTTON_HID_SLEEPF      "KLBSLPBN"
  69. #define ACPI_VIDEO_HID              "KLBVIDEO"
  70. #define ACPI_BAY_HID                "KLBIOBAY"
  71. #define ACPI_DOCK_HID               "KLBDOCK"
  72. /* Quirk for broken IBM BIOSes */
  73. #define ACPI_SMBUS_IBM_HID      "SMBUSIBM"
  74.  
  75.  
  76. #define STRUCT_TO_INT(s)        (*((int*)&s))
  77.  
  78. #define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \
  79.               ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING)
  80.  
  81. #define PCI_MAX_DEVICES 32
  82. #define PCI_MAX_PINS    4
  83.  
  84. #define IRQ_TABLE_ENTRIES   (PCI_MAX_DEVICES * PCI_MAX_PINS)
  85.  
  86. static int irqtable[IRQ_TABLE_ENTRIES];
  87. static ACPI_HANDLE pci_root_handle;
  88.  
  89.  
  90. #define  addr_offset(addr, off) \
  91.     (addr_t)((addr_t)(addr) + (addr_t)(off))
  92.  
  93. //#define acpi_remap( addr ) \
  94. //    (addr_t)((addr_t)(addr) + OS_BASE)
  95.  
  96. #define acpi_remap( addr ) MapIoMem((void*)(addr),4096, 0x01)
  97.  
  98.  
  99. struct acpi_bus_ops
  100. {
  101.     u32_t acpi_op_add:1;
  102.     u32_t acpi_op_start:1;
  103. };
  104.  
  105. struct acpi_device_flags {
  106.     u32 dynamic_status:1;
  107.     u32 bus_address:1;
  108.     u32 removable:1;
  109.     u32 ejectable:1;
  110.     u32 lockable:1;
  111.     u32 suprise_removal_ok:1;
  112.     u32 power_manageable:1;
  113.     u32 performance_manageable:1;
  114.     u32 wake_capable:1; /* Wakeup(_PRW) supported? */
  115.     u32 force_power_state:1;
  116.     u32 reserved:22;
  117. };
  118.  
  119. struct acpi_device_status {
  120.     u32 present:1;
  121.     u32 enabled:1;
  122.     u32 show_in_ui:1;
  123.     u32 functional:1;
  124.     u32 battery_present:1;
  125.     u32 reserved:27;
  126. };
  127.  
  128.  
  129. typedef char acpi_bus_id[8];
  130. typedef unsigned long acpi_bus_address;
  131. typedef char acpi_device_name[40];
  132. typedef char acpi_device_class[20];
  133.  
  134. struct acpi_hardware_id {
  135.     struct list_head list;
  136.     char *id;
  137. };
  138.  
  139. struct acpi_device_pnp
  140. {
  141.     acpi_bus_id       bus_id;       /* Object name */
  142.     acpi_bus_address  bus_address;  /* _ADR */
  143.     char *unique_id;                /* _UID */
  144.     struct list_head  ids;          /* _HID and _CIDs */
  145.     acpi_device_name  device_name;  /* Driver-determined */
  146.     acpi_device_class device_class; /*        "          */
  147. };
  148.  
  149.  
  150. struct acpi_device
  151. {
  152.     int device_type;
  153.     ACPI_HANDLE handle;     /* no handle for fixed hardware */
  154.     struct acpi_device *parent;
  155.     struct list_head children;
  156.     struct list_head node;
  157. //    struct list_head wakeup_list;
  158.     struct acpi_device_status status;
  159.     struct acpi_device_flags flags;
  160.     struct acpi_device_pnp pnp;
  161. //    struct acpi_device_power power;
  162. //    struct acpi_device_wakeup wakeup;
  163. //    struct acpi_device_perf performance;
  164. //    struct acpi_device_dir dir;
  165. //    struct acpi_device_ops ops;
  166. //    struct acpi_driver *driver;
  167.     void *driver_data;
  168. //    struct device dev;
  169.     struct acpi_bus_ops bus_ops;    /* workaround for different code path for hotplug */
  170.  //   enum acpi_bus_removal_type removal_type;    /* indicate for different removal type */
  171. };
  172.  
  173. struct acpi_device *acpi_root;
  174.  
  175.  
  176. static void
  177. acpi_util_eval_error(ACPI_HANDLE h, ACPI_STRING p, ACPI_STATUS s)
  178. {
  179. #ifdef ACPI_DEBUG_OUTPUT
  180.     char prefix[80] = {'\0'};
  181.     ACPI_BUFFER buffer = {sizeof(prefix), prefix};
  182.     AcpiGetName(h, ACPI_FULL_PATHNAME, &buffer);
  183.     ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s\n",
  184.         (char *) prefix, p, AcpiFormatException(s)));
  185. #else
  186.     return;
  187. #endif
  188. }
  189.  
  190. ACPI_STATUS
  191. acpi_evaluate_integer(ACPI_HANDLE handle, ACPI_STRING pathname,
  192.               ACPI_OBJECT_LIST *arguments, unsigned long long *data)
  193. {
  194.     ACPI_STATUS status = AE_OK;
  195.     ACPI_OBJECT element;
  196.     ACPI_BUFFER buffer = { 0, NULL };
  197.  
  198.     if (!data)
  199.         return AE_BAD_PARAMETER;
  200.  
  201.     buffer.Length = sizeof(ACPI_OBJECT);
  202.     buffer.Pointer = &element;
  203.     status = AcpiEvaluateObject(handle, pathname, arguments, &buffer);
  204.     if (ACPI_FAILURE(status)) {
  205.         acpi_util_eval_error(handle, pathname, status);
  206.         return status;
  207.     }
  208.  
  209.     if (element.Type != ACPI_TYPE_INTEGER) {
  210.         acpi_util_eval_error(handle, pathname, AE_BAD_DATA);
  211.         return AE_BAD_DATA;
  212.     }
  213.  
  214.     *data = element.Integer.Value;
  215.  
  216.     ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%llu]\n", *data));
  217.  
  218.     return AE_OK;
  219. }
  220.  
  221. void acpi_bus_data_handler(ACPI_HANDLE handle, void *context)
  222. {
  223.  
  224.     /* TBD */
  225.  
  226.     return;
  227. }
  228.  
  229.  
  230. int acpi_bus_get_device(ACPI_HANDLE handle, struct acpi_device **device)
  231. {
  232.     ACPI_STATUS status = AE_OK;
  233.  
  234.     if (!device)
  235.     {
  236.         return -EINVAL;
  237.     };
  238.  
  239.     /* TBD: Support fixed-feature devices */
  240.  
  241.     status = AcpiGetData(handle, acpi_bus_data_handler, (void **)device);
  242.     if (ACPI_FAILURE(status) || !*device) {
  243.         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n",
  244.                   handle));
  245.         return -ENODEV;
  246.     }
  247.     return 0;
  248. }
  249.  
  250.  
  251. ACPI_STATUS acpi_bus_get_status_handle(ACPI_HANDLE handle,
  252.                        unsigned long long *sta)
  253. {
  254.     ACPI_STATUS status;
  255.  
  256.     status = acpi_evaluate_integer(handle, "_STA", NULL, sta);
  257.     if (ACPI_SUCCESS(status))
  258.     {
  259.         return AE_OK;
  260.     };
  261.  
  262.     if (status == AE_NOT_FOUND)
  263.     {
  264.         *sta = ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
  265.                ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING;
  266.         return AE_OK;
  267.     }
  268.     return status;
  269. }
  270.  
  271.  
  272.  
  273. static int acpi_bus_type_and_status(ACPI_HANDLE handle, int *type,
  274.                     unsigned long long *sta)
  275. {
  276.     ACPI_STATUS status;
  277.     ACPI_OBJECT_TYPE acpi_type;
  278.  
  279.     status = AcpiGetType(handle, &acpi_type);
  280.     if (ACPI_FAILURE(status))
  281.     {
  282.         return -ENODEV;
  283.     };
  284.  
  285.     switch (acpi_type)
  286.     {
  287.         case ACPI_TYPE_ANY:     /* for ACPI_ROOT_OBJECT */
  288.         case ACPI_TYPE_DEVICE:
  289.             *type = ACPI_BUS_TYPE_DEVICE;
  290.             status = acpi_bus_get_status_handle(handle, sta);
  291.             if (ACPI_FAILURE(status))
  292.             {
  293.                 return -ENODEV;
  294.             };
  295.             break;
  296.  
  297.         case ACPI_TYPE_PROCESSOR:
  298.             *type = ACPI_BUS_TYPE_PROCESSOR;
  299.             status = acpi_bus_get_status_handle(handle, sta);
  300.             if (ACPI_FAILURE(status))
  301.             {
  302.                 return -ENODEV;
  303.             };
  304.             break;
  305.         case ACPI_TYPE_THERMAL:
  306.             *type = ACPI_BUS_TYPE_THERMAL;
  307.             *sta = ACPI_STA_DEFAULT;
  308.             break;
  309.         case ACPI_TYPE_POWER:
  310.             *type = ACPI_BUS_TYPE_POWER;
  311.             *sta = ACPI_STA_DEFAULT;
  312.             break;
  313.         default:
  314.             return -ENODEV;
  315.     }
  316.  
  317.     return 0;
  318. }
  319.  
  320. static struct acpi_device *acpi_bus_get_parent(ACPI_HANDLE handle)
  321. {
  322.     ACPI_STATUS status;
  323.     struct      acpi_device *device;
  324.     int         ret;
  325.  
  326.     /*
  327.      * Fixed hardware devices do not appear in the namespace and do not
  328.      * have handles, but we fabricate acpi_devices for them, so we have
  329.      * to deal with them specially.
  330.      */
  331.     if (handle == NULL)
  332.     {
  333.         return acpi_root;
  334.     };
  335.  
  336.     do
  337.     {
  338.         status = AcpiGetParent(handle, &handle);
  339.         if (status == AE_NULL_ENTRY)
  340.         {
  341.             return NULL;
  342.         };
  343.         if (ACPI_FAILURE(status))
  344.         {
  345.             return acpi_root;
  346.         };
  347.  
  348.         ret = acpi_bus_get_device(handle, &device);
  349.         if (ret == 0)
  350.         {
  351.             return device;
  352.         };
  353.     } while (1);
  354. }
  355.  
  356.  
  357. static void acpi_device_get_busid(struct acpi_device *device)
  358. {
  359.     char bus_id[5] = { '?', 0 };
  360.     struct acpi_buffer buffer = { sizeof(bus_id), bus_id };
  361.     int i = 0;
  362.  
  363.     /*
  364.      * Bus ID
  365.      * ------
  366.      * The device's Bus ID is simply the object name.
  367.      * TBD: Shouldn't this value be unique (within the ACPI namespace)?
  368.      */
  369.     if (ACPI_IS_ROOT_DEVICE(device)) {
  370.         strcpy(device->pnp.bus_id, "ACPI");
  371.         return;
  372.     }
  373.  
  374.     switch (device->device_type)
  375.     {
  376.         case ACPI_BUS_TYPE_POWER_BUTTON:
  377.             strcpy(device->pnp.bus_id, "PWRF");
  378.             break;
  379.         case ACPI_BUS_TYPE_SLEEP_BUTTON:
  380.             strcpy(device->pnp.bus_id, "SLPF");
  381.             break;
  382.         default:
  383.             AcpiGetName(device->handle, ACPI_SINGLE_NAME, &buffer);
  384.         /* Clean up trailing underscores (if any) */
  385.             for (i = 3; i > 1; i--)
  386.             {
  387.                 if (bus_id[i] == '_')
  388.                     bus_id[i] = '\0';
  389.                 else
  390.                     break;
  391.             }
  392.             strcpy(device->pnp.bus_id, bus_id);
  393.             break;
  394.     }
  395. }
  396.  
  397.  
  398. static int acpi_bus_get_flags(struct acpi_device *device)
  399. {
  400.     ACPI_STATUS status = AE_OK;
  401.     ACPI_HANDLE temp   = NULL;
  402.  
  403.     /* Presence of _STA indicates 'dynamic_status' */
  404.     status = AcpiGetHandle(device->handle, "_STA", &temp);
  405.     if (ACPI_SUCCESS(status))
  406.         device->flags.dynamic_status = 1;
  407.  
  408.     /* Presence of _RMV indicates 'removable' */
  409.     status = AcpiGetHandle(device->handle, "_RMV", &temp);
  410.     if (ACPI_SUCCESS(status))
  411.         device->flags.removable = 1;
  412.  
  413.     /* Presence of _EJD|_EJ0 indicates 'ejectable' */
  414.     status = AcpiGetHandle(device->handle, "_EJD", &temp);
  415.     if (ACPI_SUCCESS(status))
  416.         device->flags.ejectable = 1;
  417.     else {
  418.         status = AcpiGetHandle(device->handle, "_EJ0", &temp);
  419.         if (ACPI_SUCCESS(status))
  420.             device->flags.ejectable = 1;
  421.     }
  422.  
  423.     /* Presence of _LCK indicates 'lockable' */
  424.     status = AcpiGetHandle(device->handle, "_LCK", &temp);
  425.     if (ACPI_SUCCESS(status))
  426.         device->flags.lockable = 1;
  427.  
  428.     /* Presence of _PS0|_PR0 indicates 'power manageable' */
  429.     status = AcpiGetHandle(device->handle, "_PS0", &temp);
  430.     if (ACPI_FAILURE(status))
  431.         status = AcpiGetHandle(device->handle, "_PR0", &temp);
  432.     if (ACPI_SUCCESS(status))
  433.         device->flags.power_manageable = 1;
  434.  
  435.     /* Presence of _PRW indicates wake capable */
  436.     status = AcpiGetHandle(device->handle, "_PRW", &temp);
  437.     if (ACPI_SUCCESS(status))
  438.         device->flags.wake_capable = 1;
  439.  
  440.     /* TBD: Performance management */
  441.  
  442.     return 0;
  443. }
  444.  
  445. /*
  446.  * acpi_bay_match - see if a device is an ejectable driver bay
  447.  *
  448.  * If an acpi object is ejectable and has one of the ACPI ATA methods defined,
  449.  * then we can safely call it an ejectable drive bay
  450.  */
  451. static int acpi_bay_match(struct acpi_device *device){
  452.     ACPI_STATUS status;
  453.     ACPI_HANDLE handle;
  454.     ACPI_HANDLE tmp;
  455.     ACPI_HANDLE phandle;
  456.  
  457.     handle = device->handle;
  458.  
  459.     status = AcpiGetHandle(handle, "_EJ0", &tmp);
  460.     if (ACPI_FAILURE(status))
  461.         return -ENODEV;
  462.  
  463.     if ((ACPI_SUCCESS(AcpiGetHandle(handle, "_GTF", &tmp))) ||
  464.         (ACPI_SUCCESS(AcpiGetHandle(handle, "_GTM", &tmp))) ||
  465.         (ACPI_SUCCESS(AcpiGetHandle(handle, "_STM", &tmp))) ||
  466.         (ACPI_SUCCESS(AcpiGetHandle(handle, "_SDD", &tmp))))
  467.         return 0;
  468.  
  469.     if (AcpiGetParent(handle, &phandle))
  470.         return -ENODEV;
  471.  
  472.     if ((ACPI_SUCCESS(AcpiGetHandle(phandle, "_GTF", &tmp))) ||
  473.         (ACPI_SUCCESS(AcpiGetHandle(phandle, "_GTM", &tmp))) ||
  474.         (ACPI_SUCCESS(AcpiGetHandle(phandle, "_STM", &tmp))) ||
  475.         (ACPI_SUCCESS(AcpiGetHandle(phandle, "_SDD", &tmp))))
  476.         return 0;
  477.  
  478.     return -ENODEV;
  479. }
  480.  
  481. /*
  482.  * acpi_dock_match - see if a device has a _DCK method
  483.  */
  484. static int acpi_dock_match(struct acpi_device *device)
  485. {
  486.     ACPI_HANDLE tmp;
  487.     return AcpiGetHandle(device->handle, "_DCK", &tmp);
  488. }
  489.  
  490. char *acpi_device_hid(struct acpi_device *device)
  491. {
  492.     struct acpi_hardware_id *hid;
  493.  
  494.     hid = list_first_entry(&device->pnp.ids, struct acpi_hardware_id, list);
  495.     return hid->id;
  496. }
  497.  
  498.  
  499.  
  500. static void acpi_add_id(struct acpi_device *device, const char *dev_id)
  501. {
  502.     struct acpi_hardware_id *id;
  503.  
  504.     id = kmalloc(sizeof(*id), GFP_KERNEL);
  505.     if (!id)
  506.     {
  507.         return;
  508.     };
  509.  
  510.     INIT_LIST_HEAD(&id->list);
  511.  
  512.     id->id = kmalloc(strlen(dev_id) + 1, GFP_KERNEL);
  513.     if (!id->id) {
  514.         kfree(id);
  515.         return;
  516.     }
  517.  
  518.     strcpy(id->id, dev_id);
  519.  
  520.     list_add_tail(&id->list, &device->pnp.ids);
  521. }
  522.  
  523. #define ACPI_VIDEO_OUTPUT_SWITCHING         0x0001
  524. #define ACPI_VIDEO_DEVICE_POSTING           0x0002
  525. #define ACPI_VIDEO_ROM_AVAILABLE            0x0004
  526. #define ACPI_VIDEO_BACKLIGHT                0x0008
  527. #define ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR       0x0010
  528. #define ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO        0x0020
  529. #define ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR    0x0040
  530. #define ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO     0x0080
  531. #define ACPI_VIDEO_BACKLIGHT_DMI_VENDOR         0x0100
  532. #define ACPI_VIDEO_BACKLIGHT_DMI_VIDEO          0x0200
  533. #define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR      0x0400
  534. #define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO       0x0800
  535.  
  536.  
  537. long acpi_is_video_device(struct acpi_device *device)
  538. {
  539.     ACPI_HANDLE h_dummy;
  540.     long video_caps = 0;
  541.  
  542.     if (!device)
  543.         return 0;
  544.  
  545.     /* Is this device able to support video switching ? */
  546.     if (ACPI_SUCCESS(AcpiGetHandle(device->handle, "_DOD", &h_dummy)) ||
  547.         ACPI_SUCCESS(AcpiGetHandle(device->handle, "_DOS", &h_dummy)))
  548.         video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING;
  549.  
  550.     /* Is this device able to retrieve a video ROM ? */
  551.     if (ACPI_SUCCESS(AcpiGetHandle(device->handle, "_ROM", &h_dummy)))
  552.         video_caps |= ACPI_VIDEO_ROM_AVAILABLE;
  553.  
  554.     /* Is this device able to configure which video head to be POSTed ? */
  555.     if (ACPI_SUCCESS(AcpiGetHandle(device->handle, "_VPO", &h_dummy)) &&
  556.         ACPI_SUCCESS(AcpiGetHandle(device->handle, "_GPD", &h_dummy)) &&
  557.         ACPI_SUCCESS(AcpiGetHandle(device->handle, "_SPD", &h_dummy)))
  558.         video_caps |= ACPI_VIDEO_DEVICE_POSTING;
  559.  
  560.      return video_caps;
  561. }
  562.  
  563.  
  564. static void acpi_device_set_id(struct acpi_device *device)
  565. {
  566.     ACPI_STATUS status;
  567.     ACPI_DEVICE_INFO *info;
  568.     ACPI_DEVICE_ID_LIST *cid_list;
  569.     int i;
  570.  
  571.     switch (device->device_type)
  572.     {
  573.         case ACPI_BUS_TYPE_DEVICE:
  574.             if (ACPI_IS_ROOT_DEVICE(device))
  575.             {
  576.                 acpi_add_id(device, ACPI_SYSTEM_HID);
  577.                 break;
  578.             }
  579.  
  580.             status = AcpiGetObjectInfo(device->handle, &info);
  581.             if (ACPI_FAILURE(status)) {
  582.                 printk(KERN_ERR "%s: Error reading device info\n", __func__);
  583.                 return;
  584.             }
  585.  
  586.             if (info->Valid & ACPI_VALID_HID)
  587.                 acpi_add_id(device, info->HardwareId.String);
  588.             if (info->Valid & ACPI_VALID_CID)
  589.             {
  590.                 cid_list = &info->CompatibleIdList;
  591.                 for (i = 0; i < cid_list->Count; i++)
  592.                     acpi_add_id(device, cid_list->Ids[i].String);
  593.             }
  594.             if (info->Valid & ACPI_VALID_ADR) {
  595.                 device->pnp.bus_address = info->Address;
  596.                 device->flags.bus_address = 1;
  597.             }
  598.  
  599.             kfree(info);
  600.  
  601.         /*
  602.          * Some devices don't reliably have _HIDs & _CIDs, so add
  603.          * synthetic HIDs to make sure drivers can find them.
  604.          */
  605.         if (acpi_is_video_device(device))
  606.             acpi_add_id(device, ACPI_VIDEO_HID);
  607.         else if (ACPI_SUCCESS(acpi_bay_match(device)))
  608.             acpi_add_id(device, ACPI_BAY_HID);
  609.         else if (ACPI_SUCCESS(acpi_dock_match(device)))
  610.             acpi_add_id(device, ACPI_DOCK_HID);
  611.         else if (!acpi_device_hid(device) &&
  612.              ACPI_IS_ROOT_DEVICE(device->parent)) {
  613.             acpi_add_id(device, ACPI_BUS_HID); /* \_SB, LNXSYBUS */
  614.             strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
  615.             strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
  616.         }
  617.  
  618.         break;
  619.     case ACPI_BUS_TYPE_POWER:
  620.         acpi_add_id(device, ACPI_POWER_HID);
  621.         break;
  622.     case ACPI_BUS_TYPE_PROCESSOR:
  623.         acpi_add_id(device, ACPI_PROCESSOR_OBJECT_HID);
  624.         break;
  625.     case ACPI_BUS_TYPE_THERMAL:
  626.         acpi_add_id(device, ACPI_THERMAL_HID);
  627.         break;
  628.     case ACPI_BUS_TYPE_POWER_BUTTON:
  629.         acpi_add_id(device, ACPI_BUTTON_HID_POWERF);
  630.         break;
  631.     case ACPI_BUS_TYPE_SLEEP_BUTTON:
  632.         acpi_add_id(device, ACPI_BUTTON_HID_SLEEPF);
  633.         break;
  634.     }
  635.  
  636.     /*
  637.      * We build acpi_devices for some objects that don't have _HID or _CID,
  638.      * e.g., PCI bridges and slots.  Drivers can't bind to these objects,
  639.      * but we do use them indirectly by traversing the acpi_device tree.
  640.      * This generic ID isn't useful for driver binding, but it provides
  641.      * the useful property that "every acpi_device has an ID."
  642.      */
  643.     if (list_empty(&device->pnp.ids))
  644.         acpi_add_id(device, "device");
  645. }
  646.  
  647.  
  648. static int acpi_device_set_context(struct acpi_device *device)
  649. {
  650.     ACPI_STATUS status;
  651.  
  652.     /*
  653.      * Context
  654.      * -------
  655.      * Attach this 'struct acpi_device' to the ACPI object.  This makes
  656.      * resolutions from handle->device very efficient.  Fixed hardware
  657.      * devices have no handles, so we skip them.
  658.      */
  659.     if (!device->handle)
  660.         return 0;
  661.  
  662.     status = AcpiAttachData(device->handle,
  663.                   acpi_bus_data_handler, device);
  664.     if (ACPI_SUCCESS(status))
  665.         return 0;
  666.  
  667.     dbgprintf(KERN_ERR "Error attaching device data\n");
  668.     return -ENODEV;
  669. }
  670.  
  671.  
  672. static int acpi_device_register(struct acpi_device *device)
  673. {
  674.     int result;
  675.     struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id;
  676.     int found = 0;
  677.  
  678.     /*
  679.      * Linkage
  680.      * -------
  681.      * Link this device to its parent and siblings.
  682.      */
  683.     INIT_LIST_HEAD(&device->children);
  684.     INIT_LIST_HEAD(&device->node);
  685.  
  686.     new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
  687.     if (!new_bus_id) {
  688.         dbgprintf(KERN_ERR "Memory allocation error\n");
  689.         return -ENOMEM;
  690.     }
  691.  
  692.     mutex_lock(&acpi_device_lock);
  693.     /*
  694.      * Find suitable bus_id and instance number in acpi_bus_id_list
  695.      * If failed, create one and link it into acpi_bus_id_list
  696.      */
  697.     list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node)
  698.     {
  699.         if (!strcmp(acpi_device_bus_id->bus_id, acpi_device_hid(device)))
  700.         {
  701.             acpi_device_bus_id->instance_no++;
  702.             found = 1;
  703.             kfree(new_bus_id);
  704.             break;
  705.         }
  706.     }
  707.     if (!found)
  708.     {
  709.         acpi_device_bus_id = new_bus_id;
  710.         strcpy(acpi_device_bus_id->bus_id, acpi_device_hid(device));
  711.         acpi_device_bus_id->instance_no = 0;
  712.         list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list);
  713.     }
  714.  
  715. //    dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no);
  716.  
  717.     if (device->parent)
  718.         list_add_tail(&device->node, &device->parent->children);
  719.  
  720.     mutex_unlock(&acpi_device_lock);
  721.  
  722. //    device->dev.bus = &acpi_bus_type;
  723. //    device->dev.release = &acpi_device_release;
  724. //    result = device_register(&device->dev);
  725. //    if (result) {
  726. //        dev_err(&device->dev, "Error registering device\n");
  727. //        goto end;
  728. //    }
  729.  
  730.  
  731. //    device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
  732.     return 0;
  733. end:
  734.     mutex_lock(&acpi_device_lock);
  735.     if (device->parent)
  736.         list_del(&device->node);
  737.     mutex_unlock(&acpi_device_lock);
  738.     return result;
  739. }
  740.  
  741.  
  742.  
  743. static int acpi_add_single_object(struct acpi_device **child,
  744.                   ACPI_HANDLE handle, int type,
  745.                   unsigned long long sta,
  746.                   struct acpi_bus_ops *ops)
  747. {
  748.     int result;
  749.     struct acpi_device *device;
  750.     ACPI_BUFFER buffer = { ACPI_ALLOCATE_BUFFER, NULL };
  751.  
  752.     device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL);
  753.     if (!device) {
  754.         dbgprintf("%s: Memory allocation error\n", __FUNCTION__);
  755.         return -ENOMEM;
  756.     }
  757.  
  758.     INIT_LIST_HEAD(&device->pnp.ids);
  759.     device->device_type = type;
  760.     device->handle = handle;
  761.     device->parent = acpi_bus_get_parent(handle);
  762.     device->bus_ops = *ops; /* workround for not call .start */
  763.     STRUCT_TO_INT(device->status) = sta;
  764.  
  765.     acpi_device_get_busid(device);
  766.  
  767.     /*
  768.      * Flags
  769.      * -----
  770.      * Note that we only look for object handles -- cannot evaluate objects
  771.      * until we know the device is present and properly initialized.
  772.      */
  773.     result = acpi_bus_get_flags(device);
  774.     if (result)
  775.         goto end;
  776.  
  777.     /*
  778.      * Initialize Device
  779.      * -----------------
  780.      * TBD: Synch with Core's enumeration/initialization process.
  781.      */
  782.     acpi_device_set_id(device);
  783.  
  784.  
  785.     if ((result = acpi_device_set_context(device)))
  786.         goto end;
  787.  
  788.     result = acpi_device_register(device);
  789.  
  790.     /*
  791.      * Bind _ADR-Based Devices when hot add
  792.      */
  793. //    if (device->flags.bus_address) {
  794. //        if (device->parent && device->parent->ops.bind)
  795. //            device->parent->ops.bind(device);
  796. //    }
  797.  
  798. end:
  799.     if (!result) {
  800.         AcpiGetName(handle, ACPI_FULL_PATHNAME, &buffer);
  801.         dbgprintf("Adding [%s]\n", (char *)buffer.Pointer);
  802.         kfree(buffer.Pointer);
  803.         *child = device;
  804.     };
  805.     return result;
  806. }
  807.  
  808.  
  809.  
  810.  
  811. static ACPI_STATUS acpi_bus_check_add(ACPI_HANDLE handle, u32 lvl,
  812.                       void *context, void **return_value)
  813. {
  814.     struct acpi_bus_ops *ops = context;
  815.     int type;
  816.     unsigned long long sta;
  817.     struct acpi_device *device;
  818.     ACPI_STATUS status;
  819.     int result;
  820.  
  821.     result = acpi_bus_type_and_status(handle, &type, &sta);
  822.  
  823.     if (result)
  824.     {
  825.         return AE_OK;
  826.     };
  827.  
  828.     if (!(sta & ACPI_STA_DEVICE_PRESENT) &&
  829.         !(sta & ACPI_STA_DEVICE_FUNCTIONING))
  830.     {
  831.         return AE_CTRL_DEPTH;
  832.     };
  833.  
  834.     /*
  835.      * We may already have an acpi_device from a previous enumeration.  If
  836.      * so, we needn't add it again, but we may still have to start it.
  837.      */
  838.     device = NULL;
  839.     acpi_bus_get_device(handle, &device);
  840.     if (ops->acpi_op_add && !device)
  841.         acpi_add_single_object(&device, handle, type, sta, ops);
  842.  
  843.     if (!device)
  844.     {
  845.         return AE_CTRL_DEPTH;
  846.     };
  847. /*
  848.     if (ops->acpi_op_start && !(ops->acpi_op_add)) {
  849.         status = acpi_start_single_object(device);
  850.         if (ACPI_FAILURE(status))
  851.             return AE_CTRL_DEPTH;
  852.     }
  853. */
  854.  
  855.     if (!*return_value)
  856.         *return_value = device;
  857.  
  858.     return AE_OK;
  859. }
  860.  
  861.  
  862.  
  863. static int acpi_bus_scan(ACPI_HANDLE handle, struct acpi_bus_ops *ops,
  864.              struct acpi_device **child)
  865. {
  866.     ACPI_STATUS status;
  867.     void *device = NULL;
  868.  
  869.     ENTER();
  870.  
  871.     status = acpi_bus_check_add(handle, 0, ops, &device);
  872.  
  873.     if (ACPI_SUCCESS(status))
  874.         AcpiWalkNamespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
  875.                     acpi_bus_check_add, NULL, ops, &device);
  876.  
  877.     if (child)
  878.         *child = device;
  879.  
  880.     LEAVE();
  881.  
  882.     if (device)
  883.         return 0;
  884.     else
  885.         return -ENODEV;
  886. }
  887.  
  888.  
  889.  
  890. int acpi_scan()
  891. {
  892.     int err;
  893.     struct acpi_bus_ops ops;
  894.  
  895.     memset(&ops, 0, sizeof(ops));
  896.     ops.acpi_op_add = 1;
  897.     ops.acpi_op_start = 1;
  898.  
  899.     err = acpi_bus_scan(ACPI_ROOT_OBJECT, &ops, &acpi_root);
  900.  
  901.     return err;
  902. };
  903.  
  904.  
  905. enum pic_mode
  906. {
  907.     IO_PIC  = 0,
  908.     IO_APIC
  909. };
  910.  
  911. static void set_pic_mode(enum pic_mode mode)
  912. {
  913.     ACPI_OBJECT arg1;
  914.     ACPI_OBJECT_LIST args;
  915.     ACPI_STATUS as;
  916.  
  917.     arg1.Type = ACPI_TYPE_INTEGER;
  918.     arg1.Integer.Value = mode;
  919.     args.Count = 1;
  920.     args.Pointer = &arg1;
  921.  
  922.     as = AcpiEvaluateObject(ACPI_ROOT_OBJECT, "_PIC", &args, NULL);
  923.     /*
  924.      * We can silently ignore failure as it may not be implemented, ACPI should
  925.      * provide us with correct information anyway
  926.      */
  927.     if (ACPI_SUCCESS(as))
  928.         dbgprintf("ACPI: machine set to %s mode\n", mode ? "APIC" : "PIC");
  929. }
  930.  
  931. void print_device_tree(struct acpi_device *device)
  932. {
  933.     struct acpi_device *child;
  934.  
  935.     dbgprintf("%s\n", device->pnp.bus_id);
  936.  
  937.     list_for_each_entry(child, &device->children, node)
  938.     {
  939.         print_device_tree(child);
  940.     };
  941. };
  942.  
  943. u32_t drvEntry(int action, char *cmdline)
  944. {
  945.     u32_t retval;
  946.  
  947.     ACPI_STATUS status;
  948.  
  949.     int i;
  950.  
  951.     if(action != 1)
  952.         return 0;
  953.  
  954.     if( !dbg_open("/rd/1/drivers/acpi.log") )
  955.     {
  956.         printf("Can't open /rd/1/drivers/acpi.log\nExit\n");
  957.         return 0;
  958.     }
  959.  
  960.     status = AcpiReallocateRootTable();
  961.     if (ACPI_FAILURE(status)) {
  962.         dbgprintf("Unable to reallocate ACPI tables\n");
  963.         goto err;
  964.     }
  965.  
  966.     status = AcpiInitializeSubsystem();
  967.     if (status != AE_OK) {
  968.           dbgprintf("AcpiInitializeSubsystem failed (%s)\n",
  969.                      AcpiFormatException(status));
  970.           goto err;
  971.     }
  972.  
  973.     status = AcpiInitializeTables(NULL, 0, TRUE);
  974.     if (status != AE_OK) {
  975.           dbgprintf("AcpiInitializeTables failed (%s)\n",
  976.                      AcpiFormatException(status));
  977.           goto err;
  978.     }
  979.  
  980.     status = AcpiLoadTables();
  981.     if (status != AE_OK) {
  982.           dbgprintf("AcpiLoadTables failed (%s)\n",
  983.                      AcpiFormatException(status));
  984.           goto err;
  985.     }
  986.  
  987. //    u32_t mode = ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE;
  988.  
  989.     status = AcpiEnableSubsystem(0);
  990.     if (status != AE_OK) {
  991.         dbgprintf("AcpiEnableSubsystem failed (%s)\n",
  992.             AcpiFormatException(status));
  993.         goto err;
  994.     }
  995.  
  996.     status = AcpiInitializeObjects (0);
  997.     if (ACPI_FAILURE (status))
  998.     {
  999.         dbgprintf("AcpiInitializeObjects failed (%s)\n",
  1000.             AcpiFormatException(status));
  1001.         goto err;
  1002.     }
  1003.  
  1004.  
  1005.     set_pic_mode(IO_APIC);
  1006.  
  1007. #if 0
  1008.     scan_devices();
  1009.  
  1010.     {
  1011.         bool retval = false;
  1012.         u32_t bus, last_bus;
  1013.  
  1014.         if( (last_bus = PciApi(1))==-1)
  1015.             return retval;
  1016.  
  1017.         dbgprintf("last bus %x\n", last_bus);
  1018.  
  1019.         for(bus=0; bus <= last_bus; bus++)
  1020.         {
  1021.             u32_t dev;
  1022.  
  1023.             for(dev = 0; dev < 32; dev++)
  1024.             {
  1025.                 u32_t fn;
  1026.  
  1027.                 for(fn = 0; fn < 8; fn++)
  1028.                 {
  1029.  
  1030.                     u32_t id;
  1031.                     u32_t irq_bios, irq_acpi;
  1032.                     u32_t irq_pin;
  1033.                     u16_t pcicmd;
  1034.                     u32_t tmp;
  1035.  
  1036.                     u32_t devfn = (dev<<3 )|fn;
  1037.  
  1038.                     id = PciRead32(bus,devfn, PCI_VENDOR_ID);
  1039.  
  1040.     /* some broken boards return 0 or ~0 if a slot is empty: */
  1041.                 if (id == 0xffffffff || id == 0x00000000 ||
  1042.                     id == 0x0000ffff || id == 0xffff0000)
  1043.                     continue;
  1044.  
  1045.                 pcicmd = PciRead16(bus,devfn, PCI_COMMAND);
  1046.                 if (! pcicmd & PCI_COMMAND_IO)
  1047.                     continue;
  1048.  
  1049.                 tmp = PciRead32(bus,devfn, 0x3C);
  1050.  
  1051.                 irq_bios = tmp & 0xFF;
  1052.                 irq_pin  = (tmp >> 8) & 0xFF;
  1053.  
  1054.                 int slot = (fn >> 3) & 0x1f;
  1055.  
  1056.                 irq_acpi = irqtable[ dev * PCI_MAX_PINS +(irq_pin-1) ];
  1057.  
  1058.                 if( irq_acpi < 0)
  1059.                     dbgprintf("PCI: no ACPI IRQ routing for "
  1060.                     "device %d.%d.%d INT%c\n",bus,dev,fn,'A'+irq_pin-1);
  1061.  
  1062.                 dbgprintf("pci device %x_%x bus %d dev %d fn %d,"
  1063.                           "IRQ PIN %d BIOS IRQ %d ACPI IRQ %d\n",
  1064.                           id & 0xFFFF, id>>16, bus, dev, fn, irq_pin, irq_bios, irq_acpi);
  1065.                 };
  1066.             }
  1067.         };
  1068.     };
  1069. #endif
  1070.  
  1071.     acpi_scan();
  1072.  
  1073.     print_device_tree(acpi_root);
  1074.  
  1075. /*
  1076.     ACPI_HANDLE bus_handle;
  1077.     ACPI_HANDLE pci_root;
  1078.  
  1079.     status = AcpiGetHandle(0, "\\_SB_", &bus_handle);
  1080.     dbgprintf("system bus handle %x\n", bus_handle);
  1081.  
  1082.     status = AcpiGetHandle(bus_handle, "PCI0", &pci_root);
  1083.     if (status != AE_OK) {
  1084.           dbgprintf("AcpiGetHandle failed (%s)\n",
  1085.                      AcpiFormatException(status));
  1086.           goto err;
  1087.     }
  1088.  
  1089.     AcpiWalkNamespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 100,
  1090.                       get_device_by_hid_callback, NULL, NULL, NULL);
  1091. */
  1092.  
  1093. #if 0
  1094.  
  1095.     AcpiWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 4,
  1096.                       get_device_by_hid_callback, NULL, NULL, NULL);
  1097.  
  1098.     ACPI_OBJECT obj;
  1099.     ACPI_HANDLE bus_handle;
  1100.     ACPI_HANDLE pci_root;
  1101.  
  1102.     status = AcpiGetHandle(0, "\\_SB_", &bus_handle);
  1103.     dbgprintf("system bus handle %x\n", bus_handle);
  1104.  
  1105.     status = AcpiGetHandle(bus_handle, "PCI0", &pci_root);
  1106.  
  1107.     if (status != AE_OK) {
  1108.         dbgprintf("AcpiGetHandle failed (%s)\n",
  1109.             AcpiFormatException(status));
  1110.         goto err;
  1111.     }
  1112.  
  1113.     dbgprintf("pci root handle %x\n\n", pci_root);
  1114.  
  1115.     ACPI_BUFFER prt_buffer;
  1116.  
  1117.     prt_buffer.Length = ACPI_ALLOCATE_BUFFER;
  1118.     prt_buffer.Pointer = NULL;
  1119.  
  1120.     status = AcpiGetIrqRoutingTable(pci_root, &prt_buffer);
  1121.  
  1122.     if (status != AE_OK) {
  1123.         dbgprintf("AcpiGetIrqRoutingTable failed (%s)\n",
  1124.             AcpiFormatException(status));
  1125.         goto err;
  1126.     }
  1127.  
  1128.     prt_walk_table(&prt_buffer);
  1129.  
  1130.  
  1131.     ACPI_OBJECT arg = { ACPI_TYPE_INTEGER };
  1132.     ACPI_OBJECT_LIST arg_list = { 1, &arg };
  1133.  
  1134.     arg.Integer.Value = ACPI_IRQ_MODEL_IOAPIC;
  1135.  
  1136.     dbgprintf("\nset ioapic mode\n\n");
  1137.  
  1138.     status = AcpiEvaluateObject(NULL, "\\_PIC", &arg_list, NULL);
  1139.  
  1140.     if (ACPI_FAILURE(status)) {
  1141.         dbgprintf("AcpiEvaluateObject failed (%s)\n",
  1142.             AcpiFormatException(status));
  1143.  //       goto err;
  1144.     }
  1145.  
  1146.  
  1147.     status = AcpiGetIrqRoutingTable(pci_root, &prt_buffer);
  1148.  
  1149.     if (status != AE_OK) {
  1150.         dbgprintf("AcpiGetIrqRoutingTable failed (%s)\n",
  1151.             AcpiFormatException(status));
  1152.         goto err;
  1153.     }
  1154.  
  1155.     prt_walk_table(&prt_buffer);
  1156.  
  1157.     u8_t pin = PciRead8 (0, (31<<3) | 1, 0x3D);
  1158.     dbgprintf("bus 0 device 31 function 1 pin %d\n", pin-1);
  1159.  
  1160.     pin = PciRead8 (0, (31<<3) | 2, 0x3D);
  1161.     dbgprintf("bus 0 device 31 function 2 pin %d\n", pin-1);
  1162.  
  1163.     pin = PciRead8 (0, (31<<3) | 3, 0x3D);
  1164.     dbgprintf("bus 0 device 31 function 3 pin %d\n", pin-1);
  1165.  
  1166.     pin = PciRead8 (0, (31<<3) | 4, 0x3D);
  1167.     dbgprintf("bus 0 device 31 function 4 pin %d\n", pin-1);
  1168.  
  1169.     pin = PciRead8 (0, (31<<3) | 5, 0x3D);
  1170.     dbgprintf("bus 0 device 31 function 5 pin %d\n", pin-1);
  1171.  
  1172.     pin = PciRead8 (0, (31<<3) | 6, 0x3D);
  1173.     dbgprintf("bus 0 device 31 function 6 pin %d\n", pin-1);
  1174.  
  1175.     pin = PciRead8 (0, (31<<3) | 7, 0x3D);
  1176.     dbgprintf("bus 0 device 31 function 7 pin %d\n", pin-1);
  1177. #endif
  1178.  
  1179. err:
  1180.  
  1181.     return 0;
  1182.  
  1183. };
  1184.  
  1185.  
  1186. #if 0
  1187.  
  1188. ACPI_STATUS
  1189. get_device_by_hid_callback(ACPI_HANDLE obj, u32_t depth, void* context,
  1190.     void** retval)
  1191. {
  1192.     static u32_t counter = 0;
  1193.     static char buff[256];
  1194.  
  1195.     ACPI_STATUS status;
  1196.  
  1197.     ACPI_BUFFER buffer;
  1198.  
  1199.     ACPI_DEVICE_INFO *info;
  1200.  
  1201.    // *retval = NULL;
  1202.  
  1203.     buffer.Length = 255;
  1204.     buffer.Pointer = buff;
  1205.  
  1206.     status = AcpiGetName(obj, ACPI_FULL_PATHNAME, &buffer);
  1207.     if (status != AE_OK) {
  1208.         return AE_CTRL_TERMINATE;
  1209.     }
  1210.  
  1211.     buff[buffer.Length] = '\0';
  1212.  
  1213.     dbgprintf("device %d %s ", counter, buff);
  1214.  
  1215.     status = AcpiGetObjectInfo(obj, &info);
  1216.  
  1217.     if (ACPI_SUCCESS (status))
  1218.     {
  1219.         if (info->Valid & ACPI_VALID_HID)
  1220.             dbgprintf (" HID: %s", info->HardwareId.String);
  1221.  
  1222.     };
  1223.  
  1224.     dbgprintf("\n");
  1225.     counter++;
  1226.  
  1227.     return AE_OK;
  1228. }
  1229.  
  1230. prt_walk_table(ACPI_BUFFER *prt)
  1231. {
  1232.     ACPI_PCI_ROUTING_TABLE *entry;
  1233.     char *prtptr;
  1234.  
  1235.     /* First check to see if there is a table to walk. */
  1236.     if (prt == NULL || prt->Pointer == NULL)
  1237.         return;
  1238.  
  1239.     /* Walk the table executing the handler function for each entry. */
  1240.     prtptr = prt->Pointer;
  1241.     entry = (ACPI_PCI_ROUTING_TABLE *)prtptr;
  1242.     while (entry->Length != 0)
  1243.     {
  1244.  
  1245.         dbgprintf("adress: %x %x  ", (u32_t)(entry->Address>>32),
  1246.                   (u32_t)entry->Address);
  1247.         dbgprintf("pin: %d  index: %d  source: %s\n",
  1248.                    entry->Pin,
  1249.                    entry->SourceIndex,
  1250.                    entry->Source);
  1251.  
  1252. //      handler(entry, arg);
  1253.         prtptr += entry->Length;
  1254.         entry = (ACPI_PCI_ROUTING_TABLE *)prtptr;
  1255.     }
  1256. }
  1257.  
  1258.  
  1259. static void add_irq(unsigned dev, unsigned pin, u8_t irq)
  1260. {
  1261. //    assert(dev < PCI_MAX_DEVICES && pin < PCI_MAX_PINS);
  1262.  
  1263.     irqtable[dev * PCI_MAX_PINS + pin] = irq;
  1264. }
  1265.  
  1266. static ACPI_STATUS get_irq_resource(ACPI_RESOURCE *res, void *context)
  1267. {
  1268.     ACPI_PCI_ROUTING_TABLE *tbl = (ACPI_PCI_ROUTING_TABLE *) context;
  1269.  
  1270.     if (res->Type == ACPI_RESOURCE_TYPE_IRQ)
  1271.     {
  1272.         ACPI_RESOURCE_IRQ *irq;
  1273.  
  1274.         irq = &res->Data.Irq;
  1275.         add_irq(tbl->Address >> 16, tbl->Pin,
  1276.                 irq->Interrupts[tbl->SourceIndex]);
  1277.     } else if (res->Type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ)
  1278.     {
  1279.         ACPI_RESOURCE_EXTENDED_IRQ *irq;
  1280.  
  1281.         add_irq(tbl->Address >> 16, tbl->Pin,
  1282.                 irq->Interrupts[tbl->SourceIndex]);
  1283.     }
  1284.  
  1285.     return AE_OK;
  1286. }
  1287.  
  1288. char buff[4096];
  1289.  
  1290. static ACPI_STATUS get_pci_irq_routing(ACPI_HANDLE handle)
  1291. {
  1292.     ACPI_STATUS status;
  1293.     ACPI_BUFFER abuff;
  1294.     ACPI_PCI_ROUTING_TABLE *tbl;
  1295.  
  1296.     abuff.Length = sizeof(buff);
  1297.     abuff.Pointer = buff;
  1298.  
  1299.     status = AcpiGetIrqRoutingTable(handle, &abuff);
  1300.     if (ACPI_FAILURE(status)) {
  1301.         return AE_OK;
  1302.     }
  1303.  
  1304.     for (tbl = (ACPI_PCI_ROUTING_TABLE *)abuff.Pointer; tbl->Length;
  1305.             tbl = (ACPI_PCI_ROUTING_TABLE *)
  1306.             ((char *)tbl + tbl->Length))
  1307.     {
  1308.         ACPI_HANDLE src_handle;
  1309.  
  1310.         if (*(char*)tbl->Source == '\0') {
  1311.             add_irq(tbl->Address >> 16, tbl->Pin, tbl->SourceIndex);
  1312.             continue;
  1313.         }
  1314.  
  1315.         status = AcpiGetHandle(handle, tbl->Source, &src_handle);
  1316.         if (ACPI_FAILURE(status)) {
  1317.             printf("Failed AcpiGetHandle\n");
  1318.             continue;
  1319.         }
  1320.         status = AcpiWalkResources(src_handle, METHOD_NAME__CRS,
  1321.                 get_irq_resource, tbl);
  1322.         if (ACPI_FAILURE(status)) {
  1323.             printf("Failed IRQ resource\n");
  1324.             continue;
  1325.         }
  1326.     }
  1327.  
  1328.     return AE_OK;
  1329. }
  1330.  
  1331. static ACPI_STATUS add_pci_root_dev(ACPI_HANDLE handle,
  1332.                 UINT32 level,
  1333.                 void *context,
  1334.                 void **retval)
  1335. {
  1336.     int i;
  1337.     static unsigned called;
  1338.  
  1339.     if (++called > 1) {
  1340.         dbgprintf("ACPI: Warning! Multi rooted PCI is not supported!\n");
  1341.         return AE_OK;
  1342.     }
  1343.  
  1344.     for (i = 0; i < IRQ_TABLE_ENTRIES; i++)
  1345.         irqtable[i] = -1;
  1346.  
  1347.     return get_pci_irq_routing(handle);
  1348. }
  1349.  
  1350. static ACPI_STATUS add_pci_dev(ACPI_HANDLE handle,
  1351.                 UINT32 level,
  1352.                 void *context,
  1353.                 void **retval)
  1354. {
  1355.     /* skip pci root when we get to it again */
  1356.     if (handle == pci_root_handle)
  1357.         return AE_OK;
  1358.  
  1359.     return get_pci_irq_routing(handle);
  1360. }
  1361.  
  1362. static void scan_devices(void)
  1363. {
  1364.     ACPI_STATUS status;
  1365.  
  1366.     /* get the root first */
  1367.     status = AcpiGetDevices("PNP0A03", add_pci_root_dev, NULL, NULL);
  1368.     if (status != AE_OK) {
  1369.         dbgprintf("scan_devices failed (%s)\n",
  1370.                    AcpiFormatException(status));
  1371.           return;
  1372.     }
  1373.  
  1374. //    assert(ACPI_SUCCESS(status));
  1375.  
  1376.     /* get the rest of the devices that implement _PRT */
  1377.     status = AcpiGetDevices(NULL, add_pci_dev, NULL, NULL);
  1378. //    assert(ACPI_SUCCESS(status));
  1379. }
  1380.  
  1381. #endif
  1382.