vserver 1.9.5.x5
[linux-2.6.git] / drivers / acpi / pci_link.c
index 86e8a0c..3191b5f 100644 (file)
@@ -110,13 +110,13 @@ acpi_pci_link_check_possible (
 
        switch (resource->id) {
        case ACPI_RSTYPE_START_DPF:
-               return AE_OK;
+               return_ACPI_STATUS(AE_OK);
        case ACPI_RSTYPE_IRQ:
        {
                struct acpi_resource_irq *p = &resource->data.irq;
                if (!p || !p->number_of_interrupts) {
                        ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Blank IRQ resource\n"));
-                       return AE_OK;
+                       return_ACPI_STATUS(AE_OK);
                }
                for (i = 0; (i<p->number_of_interrupts && i<ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
                        if (!p->interrupts[i]) {
@@ -137,7 +137,7 @@ acpi_pci_link_check_possible (
                if (!p || !p->number_of_interrupts) {
                        ACPI_DEBUG_PRINT((ACPI_DB_WARN, 
                                "Blank EXT IRQ resource\n"));
-                       return AE_OK;
+                       return_ACPI_STATUS(AE_OK);
                }
                for (i = 0; (i<p->number_of_interrupts && i<ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
                        if (!p->interrupts[i]) {
@@ -155,10 +155,10 @@ acpi_pci_link_check_possible (
        default:
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
                        "Resource is not an IRQ entry\n"));
-               return AE_OK;
+               return_ACPI_STATUS(AE_OK);
        }
 
-       return AE_CTRL_TERMINATE;
+       return_ACPI_STATUS(AE_CTRL_TERMINATE);
 }
 
 
@@ -207,7 +207,7 @@ acpi_pci_link_check_current (
                         */
                        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                "Blank IRQ resource\n")); 
-                       return AE_OK;
+                       return_ACPI_STATUS(AE_OK);
                }
                *irq = p->interrupts[0];
                break;
@@ -222,7 +222,7 @@ acpi_pci_link_check_current (
                         */
                        ACPI_DEBUG_PRINT((ACPI_DB_WARN,
                                "Blank EXT IRQ resource\n"));
-                       return AE_OK;
+                       return_ACPI_STATUS(AE_OK);
                }
                *irq = p->interrupts[0];
                break;
@@ -230,9 +230,9 @@ acpi_pci_link_check_current (
        default:
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
                        "Resource isn't an IRQ\n"));
-               return AE_OK;
+               return_ACPI_STATUS(AE_OK);
        }
-       return AE_CTRL_TERMINATE;
+       return_ACPI_STATUS(AE_CTRL_TERMINATE);
 }
 
 /*
@@ -307,50 +307,57 @@ acpi_pci_link_set (
        struct {
                struct acpi_resource    res;
                struct acpi_resource    end;
-       }                       resource;
-       struct acpi_buffer      buffer = {sizeof(resource)+1, &resource};
+       }    *resource;
+       struct acpi_buffer      buffer = {0, NULL};
 
        ACPI_FUNCTION_TRACE("acpi_pci_link_set");
 
        if (!link || !irq)
                return_VALUE(-EINVAL);
 
-       memset(&resource, 0, sizeof(resource));
+       resource = kmalloc( sizeof(*resource)+1, GFP_KERNEL);
+       if(!resource)
+               return_VALUE(-ENOMEM);
+
+       memset(resource, 0, sizeof(*resource)+1);
+       buffer.length = sizeof(*resource) +1;
+       buffer.pointer = resource;
 
        switch(link->irq.resource_type) {
        case ACPI_RSTYPE_IRQ:
-               resource.res.id = ACPI_RSTYPE_IRQ;
-               resource.res.length = sizeof(struct acpi_resource);
-               resource.res.data.irq.edge_level = link->irq.edge_level;
-               resource.res.data.irq.active_high_low = link->irq.active_high_low;
+               resource->res.id = ACPI_RSTYPE_IRQ;
+               resource->res.length = sizeof(struct acpi_resource);
+               resource->res.data.irq.edge_level = link->irq.edge_level;
+               resource->res.data.irq.active_high_low = link->irq.active_high_low;
                if (link->irq.edge_level == ACPI_EDGE_SENSITIVE)
-                       resource.res.data.irq.shared_exclusive = ACPI_EXCLUSIVE;
+                       resource->res.data.irq.shared_exclusive = ACPI_EXCLUSIVE;
                else
-                       resource.res.data.irq.shared_exclusive = ACPI_SHARED;
-               resource.res.data.irq.number_of_interrupts = 1;
-               resource.res.data.irq.interrupts[0] = irq;
+                       resource->res.data.irq.shared_exclusive = ACPI_SHARED;
+               resource->res.data.irq.number_of_interrupts = 1;
+               resource->res.data.irq.interrupts[0] = irq;
                break;
           
        case ACPI_RSTYPE_EXT_IRQ:
-               resource.res.id = ACPI_RSTYPE_EXT_IRQ;
-               resource.res.length = sizeof(struct acpi_resource);
-               resource.res.data.extended_irq.producer_consumer = ACPI_CONSUMER;
-               resource.res.data.extended_irq.edge_level = link->irq.edge_level;
-               resource.res.data.extended_irq.active_high_low = link->irq.active_high_low;
+               resource->res.id = ACPI_RSTYPE_EXT_IRQ;
+               resource->res.length = sizeof(struct acpi_resource);
+               resource->res.data.extended_irq.producer_consumer = ACPI_CONSUMER;
+               resource->res.data.extended_irq.edge_level = link->irq.edge_level;
+               resource->res.data.extended_irq.active_high_low = link->irq.active_high_low;
                if (link->irq.edge_level == ACPI_EDGE_SENSITIVE)
-                       resource.res.data.irq.shared_exclusive = ACPI_EXCLUSIVE;
+                       resource->res.data.irq.shared_exclusive = ACPI_EXCLUSIVE;
                else
-                       resource.res.data.irq.shared_exclusive = ACPI_SHARED;
-               resource.res.data.extended_irq.number_of_interrupts = 1;
-               resource.res.data.extended_irq.interrupts[0] = irq;
+                       resource->res.data.irq.shared_exclusive = ACPI_SHARED;
+               resource->res.data.extended_irq.number_of_interrupts = 1;
+               resource->res.data.extended_irq.interrupts[0] = irq;
                /* ignore resource_source, it's optional */
                break;
        default:
                printk("ACPI BUG: resource_type %d\n", link->irq.resource_type);
-               return_VALUE(-EINVAL);
+               result = -EINVAL;
+               goto end;
 
        }
-       resource.end.id = ACPI_RSTYPE_END_TAG;
+       resource->end.id = ACPI_RSTYPE_END_TAG;
 
        /* Attempt to set the resource */
        status = acpi_set_current_resources(link->handle, &buffer);
@@ -358,14 +365,15 @@ acpi_pci_link_set (
        /* check for total failure */
        if (ACPI_FAILURE(status)) {
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _SRS\n"));
-               return_VALUE(-ENODEV);
+               result = -ENODEV;
+               goto end;
        }
 
        /* Query _STA, set device->status */
        result = acpi_bus_get_status(link->device);
        if (result) {
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to read status\n"));
-               return_VALUE(result);
+               goto end;
        }
        if (!link->device->status.enabled) {
                printk(KERN_WARNING PREFIX
@@ -377,7 +385,7 @@ acpi_pci_link_set (
        /* Query _CRS, set link->irq.active */
        result = acpi_pci_link_get_current(link);
        if (result) {
-               return_VALUE(result);
+               goto end;
        }
 
        /*
@@ -399,7 +407,9 @@ acpi_pci_link_set (
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Set IRQ %d\n", link->irq.active));
        
-       return_VALUE(0);
+end:
+       kfree(resource);
+       return_VALUE(result);
 }
 
 
@@ -577,6 +587,11 @@ static int acpi_pci_link_allocate(struct acpi_pci_link* link) {
        return_VALUE(0);
 }
 
+/*
+ * acpi_pci_link_get_irq
+ * success: return IRQ >= 0
+ * failure: return -1
+ */
 
 int
 acpi_pci_link_get_irq (
@@ -594,27 +609,27 @@ acpi_pci_link_get_irq (
        result = acpi_bus_get_device(handle, &device);
        if (result) {
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link device\n"));
-               return_VALUE(0);
+               return_VALUE(-1);
        }
 
        link = (struct acpi_pci_link *) acpi_driver_data(device);
        if (!link) {
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
-               return_VALUE(0);
+               return_VALUE(-1);
        }
 
        /* TBD: Support multiple index (IRQ) entries per Link Device */
        if (index) {
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid index %d\n", index));
-               return_VALUE(0);
+               return_VALUE(-1);
        }
 
        if (acpi_pci_link_allocate(link))
-               return_VALUE(0);
+               return_VALUE(-1);
           
        if (!link->irq.active) {
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link active IRQ is 0!\n"));
-               return_VALUE(0);
+               return_VALUE(-1);
        }
 
        if (edge_level) *edge_level = link->irq.edge_level;
@@ -786,6 +801,18 @@ static int __init acpi_irq_penalty_update(char *str, int used)
        return 1;
 }
 
+/*
+ * We'd like PNP to call this routine for the
+ * single ISA_USED value for each legacy device.
+ * But instead it calls us with each POSSIBLE setting.
+ * There is no ISA_POSSIBLE weight, so we simply use
+ * the (small) PCI_USING penalty.
+ */
+void acpi_penalize_isa_irq(int irq)
+{
+       acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING;
+}
+
 /*
  * Over-ride default table to reserve additional IRQs for use by ISA
  * e.g. acpi_irq_isa=5
@@ -793,7 +820,7 @@ static int __init acpi_irq_penalty_update(char *str, int used)
  */
 static int __init acpi_irq_isa(char *str)
 {
-       return(acpi_irq_penalty_update(str, 1));
+       return acpi_irq_penalty_update(str, 1);
 }
 __setup("acpi_irq_isa=", acpi_irq_isa);
 
@@ -804,21 +831,21 @@ __setup("acpi_irq_isa=", acpi_irq_isa);
  */
 static int __init acpi_irq_pci(char *str)
 {
-       return(acpi_irq_penalty_update(str, 0));
+       return acpi_irq_penalty_update(str, 0);
 }
 __setup("acpi_irq_pci=", acpi_irq_pci);
 
 static int __init acpi_irq_nobalance_set(char *str)
 {
        acpi_irq_balance = 0;
-       return(1);
+       return 1;
 }
 __setup("acpi_irq_nobalance", acpi_irq_nobalance_set);
 
 int __init acpi_irq_balance_set(char *str)
 {
        acpi_irq_balance = 1;
-       return(1);
+       return 1;
 }
 __setup("acpi_irq_balance", acpi_irq_balance_set);