Subversion Repositories Kolibri OS

Rev

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 <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. /* --------------------------------------------------------------------------
  33.                          PCI IRQ Routing Table (PRT) Support
  34.    -------------------------------------------------------------------------- */
  35.  
  36. static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(struct pci_dev *dev,
  37.                               int pin)
  38. {
  39.     struct acpi_prt_entry *entry;
  40.     int segment = pci_domain_nr(dev->bus);
  41.     int bus = dev->bus->number;
  42.     int device = PCI_SLOT(dev->devfn);
  43.  
  44.     spin_lock(&acpi_prt_lock);
  45.     list_for_each_entry(entry, &acpi_prt_list, list) {
  46.         if ((segment == entry->id.Segment)
  47.             && (bus == entry->id.Bus)
  48.             && (device == entry->id.Device)
  49.             && (pin == entry->pin)) {
  50.             spin_unlock(&acpi_prt_lock);
  51.             return entry;
  52.         }
  53.     }
  54.     spin_unlock(&acpi_prt_lock);
  55.     return NULL;
  56. }
  57.  
  58. static int acpi_pci_irq_add_entry(ACPI_HANDLE handle, struct pci_bus *bus,
  59.                   struct acpi_pci_routing_table *prt)
  60. {
  61.     struct acpi_prt_entry *entry;
  62.  
  63.     entry = kzalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL);
  64.     if (!entry)
  65.         return -ENOMEM;
  66.  
  67.     /*
  68.      * Note that the _PRT uses 0=INTA, 1=INTB, etc, while PCI uses
  69.      * 1=INTA, 2=INTB.  We use the PCI encoding throughout, so convert
  70.      * it here.
  71.      */
  72.     entry->id.Segment = pci_domain_nr(bus);
  73.     entry->id.Bus = bus->number;
  74.     entry->id.Device = (prt->Address >> 16) & 0xFFFF;
  75.     entry->pin = prt->Pin + 1;
  76.  
  77. //    do_prt_fixups(entry, prt);
  78.  
  79.     entry->index = prt->SourceIndex;
  80.  
  81.     /*
  82.      * Type 1: Dynamic
  83.      * ---------------
  84.      * The 'source' field specifies the PCI interrupt link device used to
  85.      * configure the IRQ assigned to this slot|dev|pin.  The 'source_index'
  86.      * indicates which resource descriptor in the resource template (of
  87.      * the link device) this interrupt is allocated from.
  88.      *
  89.      * NOTE: Don't query the Link Device for IRQ information at this time
  90.      *       because Link Device enumeration may not have occurred yet
  91.      *       (e.g. exists somewhere 'below' this _PRT entry in the ACPI
  92.      *       namespace).
  93.      */
  94.     if (prt->Source[0])
  95.         AcpiGetHandle(handle, prt->Source, &entry->link);
  96.  
  97.     /*
  98.      * Type 2: Static
  99.      * --------------
  100.      * The 'source' field is NULL, and the 'source_index' field specifies
  101.      * the IRQ value, which is hardwired to specific interrupt inputs on
  102.      * the interrupt controller.
  103.      */
  104.  
  105.     dbgprintf(PREFIX "      %04x:%02x:%02x[%c] -> %s[%d]\n",
  106.                   entry->id.Segment, entry->id.Bus,
  107.                   entry->id.Device, pin_name(entry->pin),
  108.                   prt->Source, entry->index);
  109.  
  110.     spin_lock(&acpi_prt_lock);
  111.     list_add_tail(&entry->list, &acpi_prt_list);
  112.     spin_unlock(&acpi_prt_lock);
  113.  
  114.     return 0;
  115. }
  116.  
  117.  
  118.  
  119. int acpi_pci_irq_add_prt(ACPI_HANDLE handle, struct pci_bus *bus)
  120. {
  121.     ACPI_STATUS status;
  122.     struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
  123.     struct acpi_pci_routing_table *entry;
  124.  
  125.     /* 'handle' is the _PRT's parent (root bridge or PCI-PCI bridge) */
  126.     status = AcpiGetName(handle, ACPI_FULL_PATHNAME, &buffer);
  127.     if (ACPI_FAILURE(status))
  128.         return -ENODEV;
  129.  
  130.     printk(KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n",
  131.            (char *) buffer.Pointer);
  132.  
  133.     kfree(buffer.Pointer);
  134.  
  135.     buffer.Length = ACPI_ALLOCATE_BUFFER;
  136.     buffer.Pointer = NULL;
  137.  
  138.     status = AcpiGetIrqRoutingTable(handle, &buffer);
  139.     if (ACPI_FAILURE(status))
  140.     {
  141.         dbgprintf("AcpiGetIrqRoutingTable failed "
  142.                   "evaluating _PRT [%s]\n",AcpiFormatException(status));
  143.         kfree(buffer.Pointer);
  144.         return -ENODEV;
  145.     }
  146.  
  147.     entry = buffer.Pointer;
  148.     while (entry && (entry->Length > 0)) {
  149.         acpi_pci_irq_add_entry(handle, bus, entry);
  150.         entry = (struct acpi_pci_routing_table *)
  151.             ((unsigned long)entry + entry->Length);
  152.     }
  153.  
  154.     kfree(buffer.Pointer);
  155.     return 0;
  156. }
  157.  
  158. static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin)
  159. {
  160.     struct acpi_prt_entry *entry;
  161.     struct pci_dev *bridge;
  162.     u8 bridge_pin, orig_pin = pin;
  163.  
  164.     entry = acpi_pci_irq_find_prt_entry(dev, pin);
  165.     if (entry) {
  166.         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %s[%c] _PRT entry\n",
  167.                   pci_name(dev), pin_name(pin)));
  168.         return entry;
  169.     }
  170.  
  171.     /*
  172.      * Attempt to derive an IRQ for this device from a parent bridge's
  173.      * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge).
  174.      */
  175.     bridge = dev->bus->self;
  176.     while (bridge)
  177.     {
  178.         pin = pci_swizzle_interrupt_pin(dev, pin);
  179.  
  180.         if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) {
  181.             /* PC card has the same IRQ as its cardbridge */
  182.             bridge_pin = bridge->pin;
  183.             if (!bridge_pin) {
  184.                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  185.                           "No interrupt pin configured for device %s\n",
  186.                           pci_name(bridge)));
  187.                 return NULL;
  188.             }
  189.             pin = bridge_pin;
  190.         }
  191.  
  192.         entry = acpi_pci_irq_find_prt_entry(bridge, pin);
  193.         if (entry) {
  194.             ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  195.                      "Derived GSI for %s INT %c from %s\n",
  196.                      pci_name(dev), pin_name(orig_pin),
  197.                      pci_name(bridge)));
  198.             return entry;
  199.         }
  200.  
  201.         dev = bridge;
  202.         bridge = dev->bus->self;
  203.     }
  204.  
  205.     dbgprintf("can't derive routing for PCI INT %c\n",
  206.          pin_name(orig_pin));
  207.     return NULL;
  208. }
  209.  
  210.  
  211. int acpi_get_irq(struct pci_dev *dev)
  212. {
  213.     struct acpi_prt_entry *entry;
  214.     int gsi = -1;
  215.     u8 pin;
  216.  
  217.     int triggering = ACPI_LEVEL_SENSITIVE;
  218.     int polarity = ACPI_ACTIVE_LOW;
  219.  
  220.     char *link = NULL;
  221.     char link_desc[16];
  222.     int rc;
  223.  
  224.     pin = dev->pin;
  225.     if (!pin) {
  226.         dbgprintf(("No interrupt pin configured for device %s\n",
  227.                   pci_name(dev)));
  228.         return 0;
  229.     }
  230.  
  231.     entry = acpi_pci_irq_lookup(dev, pin);
  232.     if (!entry) {
  233.         /*
  234.          * IDE legacy mode controller IRQs are magic. Why do compat
  235.          * extensions always make such a nasty mess.
  236.          */
  237.         if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE &&
  238.                 (dev->class & 0x05) == 0)
  239.             return 0;
  240.     }
  241.  
  242.     if (entry)
  243.     {
  244.         if (entry->link)
  245.         {
  246.             gsi = acpi_pci_link_allocate_irq(entry->link,
  247.                              entry->index,
  248.                              &triggering, &polarity,
  249.                              &link);
  250. //            dbgprintf("link not implemen\n");
  251.         }
  252.         else
  253.             gsi = entry->index;
  254.     } else
  255.         gsi = -1;
  256.  
  257. #if 0
  258.  
  259.     /*
  260.      * No IRQ known to the ACPI subsystem - maybe the BIOS /
  261.      * driver reported one, then use it. Exit in any case.
  262.      */
  263.     if (gsi < 0) {
  264.         u32 dev_gsi;
  265.         dev_warn(&dev->dev, "PCI INT %c: no GSI", pin_name(pin));
  266.         /* Interrupt Line values above 0xF are forbidden */
  267.         if (dev->irq > 0 && (dev->irq <= 0xF) &&
  268.             (acpi_isa_irq_to_gsi(dev->irq, &dev_gsi) == 0)) {
  269.             printk(" - using ISA IRQ %d\n", dev->irq);
  270.             acpi_register_gsi(&dev->dev, dev_gsi,
  271.                       ACPI_LEVEL_SENSITIVE,
  272.                       ACPI_ACTIVE_LOW);
  273.             return 0;
  274.         } else {
  275.             printk("\n");
  276.             return 0;
  277.         }
  278.     }
  279.  
  280.     rc = acpi_register_gsi(&dev->dev, gsi, triggering, polarity);
  281.     if (rc < 0) {
  282.         dev_warn(&dev->dev, "PCI INT %c: failed to register GSI\n",
  283.              pin_name(pin));
  284.         return rc;
  285.     }
  286.     dev->irq = rc;
  287.  
  288.     if (link)
  289.         snprintf(link_desc, sizeof(link_desc), " -> Link[%s]", link);
  290.     else
  291.         link_desc[0] = '\0';
  292.  
  293.     dev_info(&dev->dev, "PCI INT %c%s -> GSI %u (%s, %s) -> IRQ %d\n",
  294.          pin_name(pin), link_desc, gsi,
  295.          (triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
  296.          (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq);
  297. #endif
  298.  
  299.     return gsi;
  300. }
  301.  
  302.  
  303. #define ACPI_PCI_LINK_MAX_POSSIBLE  16
  304.  
  305. /*
  306.  * If a link is initialized, we never change its active and initialized
  307.  * later even the link is disable. Instead, we just repick the active irq
  308.  */
  309. struct acpi_pci_link_irq {
  310.     u8 active;      /* Current IRQ */
  311.     u8 triggering;      /* All IRQs */
  312.     u8 polarity;        /* All IRQs */
  313.     u8 resource_type;
  314.     u8 possible_count;
  315.     u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
  316.     u8 initialized:1;
  317.     u8 reserved:7;
  318. };
  319.  
  320. struct acpi_pci_link {
  321.     struct list_head        list;
  322.     struct acpi_device      *device;
  323.     struct acpi_pci_link_irq    irq;
  324.     int             refcnt;
  325. };
  326.  
  327. static LIST_HEAD(acpi_link_list);
  328. static DEFINE_MUTEX(acpi_link_lock);
  329.  
  330.  
  331. static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
  332. {
  333.     int result;
  334.     ACPI_STATUS status;
  335.     struct {
  336.         struct acpi_resource res;
  337.         struct acpi_resource end;
  338.     } *resource;
  339.  
  340.     ACPI_BUFFER buffer = { 0, NULL };
  341.  
  342.     if (!irq)
  343.         return -EINVAL;
  344.  
  345.     resource = kzalloc(sizeof(*resource) + 1, GFP_KERNEL);
  346.     if (!resource)
  347.         return -ENOMEM;
  348.  
  349.     buffer.Length = sizeof(*resource) + 1;
  350.     buffer.Pointer = resource;
  351.  
  352.     switch (link->irq.resource_type) {
  353.     case ACPI_RESOURCE_TYPE_IRQ:
  354.         resource->res.Type = ACPI_RESOURCE_TYPE_IRQ;
  355.         resource->res.Length = sizeof(struct acpi_resource);
  356.         resource->res.Data.Irq.Triggering = link->irq.triggering;
  357.         resource->res.Data.Irq.Polarity =
  358.             link->irq.polarity;
  359.         if (link->irq.triggering == ACPI_EDGE_SENSITIVE)
  360.             resource->res.Data.Irq.Sharable =
  361.                 ACPI_EXCLUSIVE;
  362.         else
  363.             resource->res.Data.Irq.Sharable = ACPI_SHARED;
  364.         resource->res.Data.Irq.InterruptCount = 1;
  365.         resource->res.Data.Irq.Interrupts[0] = irq;
  366.         break;
  367.  
  368.     case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
  369.         resource->res.Type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ;
  370.         resource->res.Length = sizeof(struct acpi_resource);
  371.         resource->res.Data.ExtendedIrq.ProducerConsumer =
  372.             ACPI_CONSUMER;
  373.         resource->res.Data.ExtendedIrq.Triggering =
  374.             link->irq.triggering;
  375.         resource->res.Data.ExtendedIrq.Polarity =
  376.             link->irq.polarity;
  377.         if (link->irq.triggering == ACPI_EDGE_SENSITIVE)
  378.             resource->res.Data.Irq.Sharable =
  379.                 ACPI_EXCLUSIVE;
  380.         else
  381.             resource->res.Data.Irq.Sharable = ACPI_SHARED;
  382.         resource->res.Data.ExtendedIrq.InterruptCount = 1;
  383.         resource->res.Data.ExtendedIrq.Interrupts[0] = irq;
  384.         /* ignore resource_source, it's optional */
  385.         break;
  386.     default:
  387.         printk(KERN_ERR PREFIX "Invalid Resource_type %d\n", link->irq.resource_type);
  388.         result = -EINVAL;
  389.         goto end;
  390.  
  391.     }
  392.     resource->end.Type = ACPI_RESOURCE_TYPE_END_TAG;
  393.  
  394. #if 0
  395.     /* Attempt to set the resource */
  396.     status = acpi_set_current_resources(link->device->handle, &buffer);
  397.  
  398.     /* check for total failure */
  399.     if (ACPI_FAILURE(status)) {
  400.         dbgprintf("%s failure Evaluating _SRS", __FUNCTION__);
  401.         result = -ENODEV;
  402.         goto end;
  403.     }
  404.  
  405.     /* Query _STA, set device->status */
  406.     result = acpi_bus_get_status(link->device);
  407.     if (result) {
  408.         printk(KERN_ERR PREFIX "Unable to read status\n");
  409.         goto end;
  410.     }
  411.     if (!link->device->status.enabled) {
  412.         printk(KERN_WARNING PREFIX
  413.                   "%s [%s] disabled and referenced, BIOS bug\n",
  414.                   acpi_device_name(link->device),
  415.                   acpi_device_bid(link->device));
  416.     }
  417.  
  418.     /* Query _CRS, set link->irq.active */
  419.     result = acpi_pci_link_get_current(link);
  420.     if (result) {
  421.         goto end;
  422.     }
  423.  
  424.     /*
  425.      * Is current setting not what we set?
  426.      * set link->irq.active
  427.      */
  428.     if (link->irq.active != irq) {
  429.         /*
  430.          * policy: when _CRS doesn't return what we just _SRS
  431.          * assume _SRS worked and override _CRS value.
  432.          */
  433.         printk(KERN_WARNING PREFIX
  434.                   "%s [%s] BIOS reported IRQ %d, using IRQ %d\n",
  435.                   acpi_device_name(link->device),
  436.                   acpi_device_bid(link->device), link->irq.active, irq);
  437.         link->irq.active = irq;
  438.     }
  439. #endif
  440.  
  441.     ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Set IRQ %d\n", link->irq.active));
  442.  
  443. end:
  444.     kfree(resource);
  445.     return result;
  446. }
  447.  
  448.  
  449.  
  450. #define ACPI_MAX_IRQS       256
  451. #define ACPI_MAX_ISA_IRQ    16
  452.  
  453. #define PIRQ_PENALTY_PCI_AVAILABLE  (0)
  454. #define PIRQ_PENALTY_PCI_POSSIBLE   (16*16)
  455. #define PIRQ_PENALTY_PCI_USING      (16*16*16)
  456. #define PIRQ_PENALTY_ISA_TYPICAL    (16*16*16*16)
  457. #define PIRQ_PENALTY_ISA_USED       (16*16*16*16*16)
  458. #define PIRQ_PENALTY_ISA_ALWAYS     (16*16*16*16*16*16)
  459.  
  460. static int acpi_irq_penalty[ACPI_MAX_IRQS] = {
  461.     PIRQ_PENALTY_ISA_ALWAYS,    /* IRQ0 timer */
  462.     PIRQ_PENALTY_ISA_ALWAYS,    /* IRQ1 keyboard */
  463.     PIRQ_PENALTY_ISA_ALWAYS,    /* IRQ2 cascade */
  464.     PIRQ_PENALTY_ISA_TYPICAL,   /* IRQ3 serial */
  465.     PIRQ_PENALTY_ISA_TYPICAL,   /* IRQ4 serial */
  466.     PIRQ_PENALTY_ISA_TYPICAL,   /* IRQ5 sometimes SoundBlaster */
  467.     PIRQ_PENALTY_ISA_TYPICAL,   /* IRQ6 */
  468.     PIRQ_PENALTY_ISA_TYPICAL,   /* IRQ7 parallel, spurious */
  469.     PIRQ_PENALTY_ISA_TYPICAL,   /* IRQ8 rtc, sometimes */
  470.     PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ9  PCI, often acpi */
  471.     PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ10 PCI */
  472.     PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ11 PCI */
  473.     PIRQ_PENALTY_ISA_USED,      /* IRQ12 mouse */
  474.     PIRQ_PENALTY_ISA_USED,      /* IRQ13 fpe, sometimes */
  475.     PIRQ_PENALTY_ISA_USED,      /* IRQ14 ide0 */
  476.     PIRQ_PENALTY_ISA_USED,      /* IRQ15 ide1 */
  477.     /* >IRQ15 */
  478. };
  479.  
  480.  
  481.  
  482.  
  483. static int acpi_irq_balance = 0;
  484.  
  485. static int acpi_pci_link_allocate(struct acpi_pci_link *link)
  486. {
  487.     int irq;
  488.     int i;
  489.  
  490.     if (link->irq.initialized) {
  491.         if (link->refcnt == 0)
  492.             /* This means the link is disabled but initialized */
  493.             acpi_pci_link_set(link, link->irq.active);
  494.         return 0;
  495.     }
  496.  
  497.     /*
  498.      * search for active IRQ in list of possible IRQs.
  499.      */
  500.     for (i = 0; i < link->irq.possible_count; ++i) {
  501.         if (link->irq.active == link->irq.possible[i])
  502.             break;
  503.     }
  504.     /*
  505.      * forget active IRQ that is not in possible list
  506.      */
  507.     if (i == link->irq.possible_count) {
  508.         printk(KERN_WARNING PREFIX "_CRS %d not found"
  509.                       " in _PRS\n", link->irq.active);
  510.         link->irq.active = 0;
  511.     }
  512.  
  513.     /*
  514.      * if active found, use it; else pick entry from end of possible list.
  515.      */
  516.     if (link->irq.active)
  517.         irq = link->irq.active;
  518.     else
  519.         irq = link->irq.possible[link->irq.possible_count - 1];
  520.  
  521.     if (acpi_irq_balance || !link->irq.active) {
  522.         /*
  523.          * Select the best IRQ.  This is done in reverse to promote
  524.          * the use of IRQs 9, 10, 11, and >15.
  525.          */
  526.         for (i = (link->irq.possible_count - 1); i >= 0; i--) {
  527.             if (acpi_irq_penalty[irq] >
  528.                 acpi_irq_penalty[link->irq.possible[i]])
  529.                 irq = link->irq.possible[i];
  530.         }
  531.     }
  532.  
  533.     /* Attempt to enable the link device at this IRQ. */
  534.     if (acpi_pci_link_set(link, irq)) {
  535.         printk(KERN_ERR PREFIX "Unable to set IRQ for %s [%s]. "
  536.                 "Try pci=noacpi or acpi=off\n",
  537.                 acpi_device_name(link->device),
  538.                 acpi_device_bid(link->device));
  539.         return -ENODEV;
  540.     } else {
  541.         acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING;
  542.         printk(KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n",
  543.                acpi_device_name(link->device),
  544.                acpi_device_bid(link->device), link->irq.active);
  545.     }
  546.  
  547.     link->irq.initialized = 1;
  548.     return 0;
  549. }
  550.  
  551.  
  552. /*
  553.  * acpi_pci_link_allocate_irq
  554.  * success: return IRQ >= 0
  555.  * failure: return -1
  556.  */
  557. int acpi_pci_link_allocate_irq(ACPI_HANDLE handle, int index,
  558.                                int *triggering, int *polarity, char **name)
  559. {
  560.     int result;
  561.     struct acpi_device *device;
  562.     struct acpi_pci_link *link;
  563.  
  564.     result = acpi_bus_get_device(handle, &device);
  565.     if (result) {
  566.         printk(KERN_ERR PREFIX "Invalid link device\n");
  567.         return -1;
  568.     }
  569.  
  570.     link = acpi_driver_data(device);
  571.     if (!link) {
  572.         printk(KERN_ERR PREFIX "Invalid link context\n");
  573.         return -1;
  574.     }
  575.  
  576.     /* TBD: Support multiple index (IRQ) entries per Link Device */
  577.     if (index) {
  578.         printk(KERN_ERR PREFIX "Invalid index %d\n", index);
  579.         return -1;
  580.     }
  581.  
  582.     mutex_lock(&acpi_link_lock);
  583.     if (acpi_pci_link_allocate(link)) {
  584.         mutex_unlock(&acpi_link_lock);
  585.         return -1;
  586.     }
  587.  
  588.     if (!link->irq.active) {
  589.         mutex_unlock(&acpi_link_lock);
  590.         printk(KERN_ERR PREFIX "Link active IRQ is 0!\n");
  591.         return -1;
  592.     }
  593.     link->refcnt++;
  594.     mutex_unlock(&acpi_link_lock);
  595.  
  596.     if (triggering)
  597.         *triggering = link->irq.triggering;
  598.     if (polarity)
  599.         *polarity = link->irq.polarity;
  600.     if (name)
  601.         *name = acpi_device_bid(link->device);
  602.     ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  603.               "Link %s is referenced\n",
  604.               acpi_device_bid(link->device)));
  605.     return (link->irq.active);
  606. }
  607.  
  608.  
  609.