X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fpnp%2Fpnpacpi%2Frsparser.c;h=46c791adb8947dbf4e12005199f9a7179e35e8d6;hb=b4ba0ba24b57ec975482f4ba2d350fbee7557240;hp=0b67dff1e7c3eb6d9da961745f00729007e7fa40;hpb=dbddd0383c59d588f8db5e773b062756e39117ec;p=linux-2.6 diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 0b67dff1e7..46c791adb8 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -50,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; @@ -75,7 +77,18 @@ 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, @@ -158,92 +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 resource *res; - int i; - static unsigned char warned; - - for (i = 0; i < PNP_MAX_DMA; i++) { - res = pnp_get_resource(dev, IORESOURCE_DMA, i); - if (!pnp_resource_valid(res)) - break; - } - if (i < PNP_MAX_DMA) { - res->flags = IORESOURCE_DMA; // Also clears _UNSET flag - res->flags |= flags; - if (dma == -1) { - res->flags |= IORESOURCE_DISABLED; - return; - } - res->start = dma; - res->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 resource *res; - int i; - static unsigned char warned; + if (io_decode == ACPI_DECODE_16) + flags |= PNP_PORT_FLAG_16BITADDR; + if (len == 0 || end >= 0x10003) + flags |= IORESOURCE_DISABLED; - for (i = 0; i < PNP_MAX_PORT; i++) { - res = pnp_get_resource(dev, IORESOURCE_IO, i); - if (!pnp_resource_valid(res)) - break; - } - if (i < PNP_MAX_PORT) { - res->flags = IORESOURCE_IO; // Also clears _UNSET flag - if (io_decode == ACPI_DECODE_16) - res->flags |= PNP_PORT_FLAG_16BITADDR; - if (len <= 0 || (io + len - 1) >= 0x10003) { - res->flags |= IORESOURCE_DISABLED; - return; - } - res->start = io; - res->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 resource *res; - int i; - static unsigned char warned; + int flags = 0; + u64 end = start + len - 1; - for (i = 0; i < PNP_MAX_MEM; i++) { - res = pnp_get_resource(dev, IORESOURCE_MEM, i); - if (!pnp_resource_valid(res)) - break; - } - if (i < PNP_MAX_MEM) { - res->flags = IORESOURCE_MEM; // Also clears _UNSET flag - if (len <= 0) { - res->flags |= IORESOURCE_DISABLED; - return; - } - if (write_protect == ACPI_READ_WRITE_MEMORY) - res->flags |= IORESOURCE_MEM_WRITEABLE; - - res->start = mem; - res->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, @@ -285,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: @@ -305,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: @@ -396,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, @@ -727,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; @@ -737,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) @@ -785,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)++; } @@ -802,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) @@ -817,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 */ @@ -831,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, @@ -854,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;