Subversion Repositories Kolibri OS

Rev

Rev 1633 | 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 <linux/spinlock.h>
  6. #include <pci.h>
  7. #include <syscall.h>
  8.  
  9. #include "acpi.h"
  10. #include "acpi_bus.h"
  11.  
  12. #define PREFIX "ACPI: "
  13.  
  14. struct acpi_prt_entry
  15. {
  16.     struct list_head    list;
  17.     ACPI_PCI_ID         id;
  18.     u8                  pin;
  19.     ACPI_HANDLE         link;
  20.     u32                 index;      /* GSI, or link _CRS index */
  21. };
  22.  
  23. static LIST_HEAD(acpi_prt_list);
  24. static DEFINE_SPINLOCK(acpi_prt_lock);
  25.  
  26. static inline char pin_name(int pin)
  27. {
  28.     return 'A' + pin - 1;
  29. }
  30.  
  31.  
  32. static int acpi_pci_irq_add_entry(ACPI_HANDLE handle, struct pci_bus *bus,
  33.                   struct acpi_pci_routing_table *prt)
  34. {
  35.     struct acpi_prt_entry *entry;
  36.  
  37.     entry = kzalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL);
  38.     if (!entry)
  39.         return -ENOMEM;
  40.  
  41.     /*
  42.      * Note that the _PRT uses 0=INTA, 1=INTB, etc, while PCI uses
  43.      * 1=INTA, 2=INTB.  We use the PCI encoding throughout, so convert
  44.      * it here.
  45.      */
  46.     entry->id.Segment = pci_domain_nr(bus);
  47.     entry->id.Bus = bus->number;
  48.     entry->id.Device = (prt->Address >> 16) & 0xFFFF;
  49.     entry->pin = prt->Pin + 1;
  50.  
  51. //    do_prt_fixups(entry, prt);
  52.  
  53.     entry->index = prt->SourceIndex;
  54.  
  55.     /*
  56.      * Type 1: Dynamic
  57.      * ---------------
  58.      * The 'source' field specifies the PCI interrupt link device used to
  59.      * configure the IRQ assigned to this slot|dev|pin.  The 'source_index'
  60.      * indicates which resource descriptor in the resource template (of
  61.      * the link device) this interrupt is allocated from.
  62.      *
  63.      * NOTE: Don't query the Link Device for IRQ information at this time
  64.      *       because Link Device enumeration may not have occurred yet
  65.      *       (e.g. exists somewhere 'below' this _PRT entry in the ACPI
  66.      *       namespace).
  67.      */
  68.     if (prt->Source[0])
  69.         AcpiGetHandle(handle, prt->Source, &entry->link);
  70.  
  71.     /*
  72.      * Type 2: Static
  73.      * --------------
  74.      * The 'source' field is NULL, and the 'source_index' field specifies
  75.      * the IRQ value, which is hardwired to specific interrupt inputs on
  76.      * the interrupt controller.
  77.      */
  78.  
  79.     dbgprintf(PREFIX "      %04x:%02x:%02x[%c] -> %s[%d]\n",
  80.                   entry->id.Segment, entry->id.Bus,
  81.                   entry->id.Device, pin_name(entry->pin),
  82.                   prt->Source, entry->index);
  83.  
  84.     spin_lock(&acpi_prt_lock);
  85.     list_add_tail(&entry->list, &acpi_prt_list);
  86.     spin_unlock(&acpi_prt_lock);
  87.  
  88.     return 0;
  89. }
  90.  
  91.  
  92.  
  93. int acpi_pci_irq_add_prt(ACPI_HANDLE handle, struct pci_bus *bus)
  94. {
  95.     ACPI_STATUS status;
  96.     struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
  97.     struct acpi_pci_routing_table *entry;
  98.  
  99.     /* 'handle' is the _PRT's parent (root bridge or PCI-PCI bridge) */
  100.     status = AcpiGetName(handle, ACPI_FULL_PATHNAME, &buffer);
  101.     if (ACPI_FAILURE(status))
  102.         return -ENODEV;
  103.  
  104.     printk(KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n",
  105.            (char *) buffer.Pointer);
  106.  
  107.     kfree(buffer.Pointer);
  108.  
  109.     buffer.Length = ACPI_ALLOCATE_BUFFER;
  110.     buffer.Pointer = NULL;
  111.  
  112.     status = AcpiGetIrqRoutingTable(handle, &buffer);
  113.     if (ACPI_FAILURE(status))
  114.     {
  115.         dbgprintf("AcpiGetIrqRoutingTable failed "
  116.                   "evaluating _PRT [%s]\n",AcpiFormatException(status));
  117.         kfree(buffer.Pointer);
  118.         return -ENODEV;
  119.     }
  120.  
  121.     entry = buffer.Pointer;
  122.     while (entry && (entry->Length > 0)) {
  123.         acpi_pci_irq_add_entry(handle, bus, entry);
  124.         entry = (struct acpi_pci_routing_table *)
  125.             ((unsigned long)entry + entry->Length);
  126.     }
  127.  
  128.     kfree(buffer.Pointer);
  129.     return 0;
  130. }
  131.  
  132.