X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fpnp%2Fpnpacpi%2Frsparser.c;h=46c791adb8947dbf4e12005199f9a7179e35e8d6;hb=b4ba0ba24b57ec975482f4ba2d350fbee7557240;hp=000a1b39f0b6d15da640d8d60708761f870c9e50;hpb=7e2cf31f1c97ac14b6d9dc5f1ce9e1e01aef9c18;p=linux-2.6 diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 000a1b39f0..46c791adb8 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include "../base.h" #include "pnpacpi.h" #ifdef CONFIG_IA64 @@ -48,15 +50,17 @@ static int irq_flags(int triggering, int polarity, int shareable) flags = IORESOURCE_IRQ_HIGHEDGE; } - if (shareable) + if (shareable == ACPI_SHARED) flags |= IORESOURCE_IRQ_SHAREABLE; return flags; } -static void decode_irq_flags(int flag, int *triggering, int *polarity) +static void decode_irq_flags(struct pnp_dev *dev, int flags, int *triggering, + int *polarity, int *shareable) { - switch (flag) { + switch (flags & (IORESOURCE_IRQ_LOWLEVEL | IORESOURCE_IRQ_HIGHLEVEL | + IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE)) { case IORESOURCE_IRQ_LOWLEVEL: *triggering = ACPI_LEVEL_SENSITIVE; *polarity = ACPI_ACTIVE_LOW; @@ -73,33 +77,30 @@ static void decode_irq_flags(int flag, int *triggering, int *polarity) *triggering = ACPI_EDGE_SENSITIVE; *polarity = ACPI_ACTIVE_HIGH; break; + default: + dev_err(&dev->dev, "can't encode invalid IRQ mode %#x\n", + flags); + *triggering = ACPI_EDGE_SENSITIVE; + *polarity = ACPI_ACTIVE_HIGH; + break; } + + if (flags & IORESOURCE_IRQ_SHAREABLE) + *shareable = ACPI_SHARED; + else + *shareable = ACPI_EXCLUSIVE; } static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev, u32 gsi, int triggering, int polarity, int shareable) { - struct pnp_resource_table *res = &dev->res; - int i = 0; - int irq; + int irq, flags; int p, t; - static unsigned char warned; if (!valid_IRQ(gsi)) return; - while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) && - i < PNP_MAX_IRQ) - i++; - if (i >= PNP_MAX_IRQ) { - if (!warned) { - printk(KERN_WARNING "pnpacpi: exceeded the max number" - " of IRQ resources: %d\n", PNP_MAX_IRQ); - warned = 1; - } - return; - } /* * in IO-APIC mode, use overrided attribute. Two reasons: * 1. BIOS bug in DSDT @@ -117,17 +118,14 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev, } } - res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag - res->irq_resource[i].flags |= irq_flags(triggering, polarity, shareable); + flags = irq_flags(triggering, polarity, shareable); irq = acpi_register_gsi(gsi, triggering, polarity); - if (irq < 0) { - res->irq_resource[i].flags |= IORESOURCE_DISABLED; - return; - } + if (irq >= 0) + pcibios_penalize_isa_irq(irq, 1); + else + flags |= IORESOURCE_DISABLED; - res->irq_resource[i].start = irq; - res->irq_resource[i].end = irq; - pcibios_penalize_isa_irq(irq, 1); + pnp_add_irq_resource(dev, irq, flags); } static int dma_flags(int type, int bus_master, int transfer) @@ -173,86 +171,33 @@ static int dma_flags(int type, int bus_master, int transfer) return flags; } -static void pnpacpi_parse_allocated_dmaresource(struct pnp_dev *dev, - u32 dma, int flags) +static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start, + u64 len, int io_decode) { - struct pnp_resource_table *res = &dev->res; - int i = 0; - static unsigned char warned; - - while (i < PNP_MAX_DMA && - !(res->dma_resource[i].flags & IORESOURCE_UNSET)) - i++; - if (i < PNP_MAX_DMA) { - res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag - res->dma_resource[i].flags |= flags; - if (dma == -1) { - res->dma_resource[i].flags |= IORESOURCE_DISABLED; - return; - } - res->dma_resource[i].start = dma; - res->dma_resource[i].end = dma; - } else if (!warned) { - printk(KERN_WARNING "pnpacpi: exceeded the max number of DMA " - "resources: %d \n", PNP_MAX_DMA); - warned = 1; - } -} + int flags = 0; + u64 end = start + len - 1; -static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, - u64 io, u64 len, int io_decode) -{ - struct pnp_resource_table *res = &dev->res; - int i = 0; - static unsigned char warned; + if (io_decode == ACPI_DECODE_16) + flags |= PNP_PORT_FLAG_16BITADDR; + if (len == 0 || end >= 0x10003) + flags |= IORESOURCE_DISABLED; - while (!(res->port_resource[i].flags & IORESOURCE_UNSET) && - i < PNP_MAX_PORT) - i++; - if (i < PNP_MAX_PORT) { - res->port_resource[i].flags = IORESOURCE_IO; // Also clears _UNSET flag - if (io_decode == ACPI_DECODE_16) - res->port_resource[i].flags |= PNP_PORT_FLAG_16BITADDR; - if (len <= 0 || (io + len - 1) >= 0x10003) { - res->port_resource[i].flags |= IORESOURCE_DISABLED; - return; - } - res->port_resource[i].start = io; - res->port_resource[i].end = io + len - 1; - } else if (!warned) { - printk(KERN_WARNING "pnpacpi: exceeded the max number of IO " - "resources: %d \n", PNP_MAX_PORT); - warned = 1; - } + pnp_add_io_resource(dev, start, end, flags); } static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev, - u64 mem, u64 len, + u64 start, u64 len, int write_protect) { - struct pnp_resource_table *res = &dev->res; - int i = 0; - static unsigned char warned; + int flags = 0; + u64 end = start + len - 1; - while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) && - (i < PNP_MAX_MEM)) - i++; - if (i < PNP_MAX_MEM) { - res->mem_resource[i].flags = IORESOURCE_MEM; // Also clears _UNSET flag - if (len <= 0) { - res->mem_resource[i].flags |= IORESOURCE_DISABLED; - return; - } - if (write_protect == ACPI_READ_WRITE_MEMORY) - res->mem_resource[i].flags |= IORESOURCE_MEM_WRITEABLE; - - res->mem_resource[i].start = mem; - res->mem_resource[i].end = mem + len - 1; - } else if (!warned) { - printk(KERN_WARNING "pnpacpi: exceeded the max number of mem " - "resources: %d\n", PNP_MAX_MEM); - warned = 1; - } + if (len == 0) + flags |= IORESOURCE_DISABLED; + if (write_protect == ACPI_READ_WRITE_MEMORY) + flags |= IORESOURCE_MEM_WRITEABLE; + + pnp_add_mem_resource(dev, start, end, flags); } static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev, @@ -294,7 +239,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, struct acpi_resource_memory32 *memory32; struct acpi_resource_fixed_memory32 *fixed_memory32; struct acpi_resource_extended_irq *extended_irq; - int i; + int i, flags; switch (res->type) { case ACPI_RESOURCE_TYPE_IRQ: @@ -314,11 +259,13 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, case ACPI_RESOURCE_TYPE_DMA: dma = &res->data.dma; - if (dma->channel_count > 0) - pnpacpi_parse_allocated_dmaresource(dev, - dma->channels[0], - dma_flags(dma->type, dma->bus_master, - dma->transfer)); + if (dma->channel_count > 0) { + flags = dma_flags(dma->type, dma->bus_master, + dma->transfer); + if (dma->channels[0] == (u8) -1) + flags |= IORESOURCE_DISABLED; + pnp_add_dma_resource(dev, dma->channels[0], flags); + } break; case ACPI_RESOURCE_TYPE_IO: @@ -405,16 +352,24 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, return AE_OK; } -acpi_status pnpacpi_parse_allocated_resource(struct pnp_dev *dev) +int pnpacpi_parse_allocated_resource(struct pnp_dev *dev) { acpi_handle handle = dev->data; + acpi_status status; dev_dbg(&dev->dev, "parse allocated resources\n"); pnp_init_resources(dev); - return acpi_walk_resources(handle, METHOD_NAME__CRS, - pnpacpi_allocated_resource, dev); + status = acpi_walk_resources(handle, METHOD_NAME__CRS, + pnpacpi_allocated_resource, dev); + + if (ACPI_FAILURE(status)) { + if (status != AE_NOT_FOUND) + dev_err(&dev->dev, "can't evaluate _CRS: %d", status); + return -EPERM; + } + return 0; } static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev, @@ -736,7 +691,7 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, return AE_OK; } -acpi_status __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev) +int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev) { acpi_handle handle = dev->data; acpi_status status; @@ -746,13 +701,19 @@ acpi_status __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev) parse_data.option = pnp_register_independent_option(dev); if (!parse_data.option) - return AE_ERROR; + return -ENOMEM; + parse_data.option_independent = parse_data.option; parse_data.dev = dev; status = acpi_walk_resources(handle, METHOD_NAME__PRS, pnpacpi_option_resource, &parse_data); - return status; + if (ACPI_FAILURE(status)) { + if (status != AE_NOT_FOUND) + dev_err(&dev->dev, "can't evaluate _PRS: %d", status); + return -EPERM; + } + return 0; } static int pnpacpi_supported_resource(struct acpi_resource *res) @@ -794,6 +755,9 @@ static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data) if (pnpacpi_supported_resource(res)) { (*resource)->type = res->type; (*resource)->length = sizeof(struct acpi_resource); + if (res->type == ACPI_RESOURCE_TYPE_IRQ) + (*resource)->data.irq.descriptor_length = + res->data.irq.descriptor_length; (*resource)++; } @@ -811,7 +775,7 @@ int pnpacpi_build_resource_template(struct pnp_dev *dev, status = acpi_walk_resources(handle, METHOD_NAME__CRS, pnpacpi_count_resources, &res_cnt); if (ACPI_FAILURE(status)) { - dev_err(&dev->dev, "can't evaluate _CRS\n"); + dev_err(&dev->dev, "can't evaluate _CRS: %d\n", status); return -EINVAL; } if (!res_cnt) @@ -826,7 +790,7 @@ int pnpacpi_build_resource_template(struct pnp_dev *dev, pnpacpi_type_resources, &resource); if (ACPI_FAILURE(status)) { kfree(buffer->pointer); - dev_err(&dev->dev, "can't evaluate _CRS\n"); + dev_err(&dev->dev, "can't evaluate _CRS: %d\n", status); return -EINVAL; } /* resource will pointer the end resource now */ @@ -840,22 +804,21 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev, struct resource *p) { struct acpi_resource_irq *irq = &resource->data.irq; - int triggering, polarity; + int triggering, polarity, shareable; - decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); + decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable); irq->triggering = triggering; irq->polarity = polarity; - if (triggering == ACPI_EDGE_SENSITIVE) - irq->sharable = ACPI_EXCLUSIVE; - else - irq->sharable = ACPI_SHARED; + irq->sharable = shareable; irq->interrupt_count = 1; irq->interrupts[0] = p->start; - dev_dbg(&dev->dev, " encode irq %d %s %s %s\n", (int) p->start, + dev_dbg(&dev->dev, " encode irq %d %s %s %s (%d-byte descriptor)\n", + (int) p->start, triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge", polarity == ACPI_ACTIVE_LOW ? "low" : "high", - irq->sharable == ACPI_SHARED ? "shared" : "exclusive"); + irq->sharable == ACPI_SHARED ? "shared" : "exclusive", + irq->descriptor_length); } static void pnpacpi_encode_ext_irq(struct pnp_dev *dev, @@ -863,16 +826,13 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev, struct resource *p) { struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq; - int triggering, polarity; + int triggering, polarity, shareable; - decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); + decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable); extended_irq->producer_consumer = ACPI_CONSUMER; extended_irq->triggering = triggering; extended_irq->polarity = polarity; - if (triggering == ACPI_EDGE_SENSITIVE) - extended_irq->sharable = ACPI_EXCLUSIVE; - else - extended_irq->sharable = ACPI_SHARED; + extended_irq->sharable = shareable; extended_irq->interrupt_count = 1; extended_irq->interrupts[0] = p->start;