Date: Fri, 15 Apr 2011 03:37:46 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 191526 for review Message-ID: <201104150337.p3F3bkbL031703@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@191526?ac=10 Change 191526 by jhb@jhb_fiver on 2011/04/15 03:36:45 Use AcpiWalkResources() to implement acpi_parse_resources(). While here, use common code for all of the address space resource types and add support for Address64 and ExtAddress64 types. Affected files ... .. //depot/projects/pci/sys/dev/acpica/acpi_resource.c#2 edit Differences ... ==== //depot/projects/pci/sys/dev/acpica/acpi_resource.c#2 (text+ko) ==== @@ -139,6 +139,217 @@ INTR_POLARITY_HIGH : INTR_POLARITY_LOW); } +struct acpi_resource_context { + struct acpi_parse_resource_set *set; + void *context; +}; + +static ACPI_STATUS +acpi_parse_resource(ACPI_RESOURCE *res, void *context) +{ + struct acpi_parse_resource_set *set; + struct acpi_resource_context *arc; + UINT64 min, max, length, gran; + const char *name; + +#define ADDRESS_RANGE_NAME(type) \ + ((type) == ACPI_MEMORY_RANGE ? "Memory" : (type) == ACPI_IO_RANGE ? "IO" : \ + "Bus Number") + + arc = context; + set = arc->set; + + switch (res->Type) { + case ACPI_RESOURCE_TYPE_END_TAG: + ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "EndTag\n")); + break; + case ACPI_RESOURCE_TYPE_FIXED_IO: + if (res->Data.FixedIo.AddressLength <= 0) + break; + ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "FixedIo 0x%x/%d\n", + res->Data.FixedIo.Address, res->Data.FixedIo.AddressLength)); + set->set_ioport(dev, arc->context, res->Data.FixedIo.Address, + res->Data.FixedIo.AddressLength); + break; + case ACPI_RESOURCE_TYPE_IO: + if (res->Data.Io.AddressLength <= 0) + break; + if (res->Data.Io.Minimum == res->Data.Io.Maximum) { + ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Io 0x%x/%d\n", + res->Data.Io.Minimum, res->Data.Io.AddressLength)); + set->set_ioport(dev, arc->context, res->Data.Io.Minimum, + res->Data.Io.AddressLength); + } else { + ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Io 0x%x-0x%x/%d\n", + res->Data.Io.Minimum, res->Data.Io.Maximum, + res->Data.Io.AddressLength)); + set->set_iorange(dev, arc->context, res->Data.Io.Minimum, + res->Data.Io.Maximum, res->Data.Io.AddressLength, + res->Data.Io.Alignment); + } + break; + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: + if (res->Data.FixedMemory32.AddressLength <= 0) + break; + ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "FixedMemory32 0x%x/%d\n", + res->Data.FixedMemory32.Address, + res->Data.FixedMemory32.AddressLength)); + set->set_memory(dev, arc->context, res->Data.FixedMemory32.Address, + res->Data.FixedMemory32.AddressLength); + break; + case ACPI_RESOURCE_TYPE_MEMORY32: + if (res->Data.Memory32.AddressLength <= 0) + break; + if (res->Data.Memory32.Minimum == res->Data.Memory32.Maximum) { + ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Memory32 0x%x/%d\n", + res->Data.Memory32.Minimum, res->Data.Memory32.AddressLength)); + set->set_memory(dev, arc->context, res->Data.Memory32.Minimum, + res->Data.Memory32.AddressLength); + } else { + ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Memory32 0x%x-0x%x/%d\n", + res->Data.Memory32.Minimum, res->Data.Memory32.Maximum, + res->Data.Memory32.AddressLength)); + set->set_memoryrange(dev, arc->context, res->Data.Memory32.Minimum, + res->Data.Memory32.Maximum, res->Data.Memory32.AddressLength, + res->Data.Memory32.Alignment); + } + break; + case ACPI_RESOURCE_TYPE_MEMORY24: + if (res->Data.Memory24.AddressLength <= 0) + break; + if (res->Data.Memory24.Minimum == res->Data.Memory24.Maximum) { + ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Memory24 0x%x/%d\n", + res->Data.Memory24.Minimum, res->Data.Memory24.AddressLength)); + set->set_memory(dev, arc->context, res->Data.Memory24.Minimum, + res->Data.Memory24.AddressLength); + } else { + ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Memory24 0x%x-0x%x/%d\n", + res->Data.Memory24.Minimum, res->Data.Memory24.Maximum, + res->Data.Memory24.AddressLength)); + set->set_memoryrange(dev, arc->context, res->Data.Memory24.Minimum, + res->Data.Memory24.Maximum, res->Data.Memory24.AddressLength, + res->Data.Memory24.Alignment); + } + break; + case ACPI_RESOURCE_TYPE_IRQ: + /* + * from 1.0b 6.4.2 + * "This structure is repeated for each separate interrupt + * required" + */ + set->set_irq(dev, arc->context, res->Data.Irq.Interrupts, + res->Data.Irq.InterruptCount, res->Data.Irq.Triggering, + res->Data.Irq.Polarity); + break; + case ACPI_RESOURCE_TYPE_DMA: + /* + * from 1.0b 6.4.3 + * "This structure is repeated for each separate DMA channel + * required" + */ + set->set_drq(dev, arc->context, res->Data.Dma.Channels, + res->Data.Dma.ChannelCount); + break; + case ACPI_RESOURCE_TYPE_START_DEPENDENT: + ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "start dependent functions\n")); + set->set_start_dependent(dev, arc->context, + res->Data.StartDpf.CompatibilityPriority); + break; + case ACPI_RESOURCE_TYPE_END_DEPENDENT: + ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "end dependent functions\n")); + set->set_end_dependent(dev, arc->context); + break; + case ACPI_RESOURCE_TYPE_ADDRESS16: + case ACPI_RESOURCE_TYPE_ADDRESS32: + case ACPI_RESOURCE_TYPE_ADDRESS64: + case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: + switch (res->type) { + case ACPI_RESOURCE_TYPE_ADDRESS16: + gran = res->Data.Address16.Granularity; + min = res->Data.Address16.Minimum; + max = res->Data.Address16.Maximum; + length = res->Data.Address16.AddressLength; + name = "Address16"; + break; + case ACPI_RESOURCE_TYPE_ADDRESS32: + gran = res->Data.Address32.Granularity; + min = res->Data.Address32.Minimum; + max = res->Data.Address32.Maximum; + length = res->Data.Address32.AddressLength; + name = "Address32"; + break; + case ACPI_RESOURCE_TYPE_ADDRESS64: + gran = res->Data.Address64.Granularity; + min = res->Data.Address64.Minimum; + max = res->Data.Address64.Maximum; + length = res->Data.Address64.AddressLength; + name = "Address64"; + break; + case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: + gran = res->Data.ExtAddress64.Granularity; + min = res->Data.ExtAddress64.Minimum; + max = res->Data.ExtAddress64.Maximum; + length = res->Data.ExtAddress64.AddressLength; + name = "ExtAddress64"; + break; + } + if (len <= 0) + break; + if (res->Data.Address.ProducerConsumer != ACPI_CONSUMER) { + ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, + "ignored %s %s producer\n", name, + ADDRESS_RANGE_NAME(res->Data.Address.ResourceType))); + break; + } + if (res->Data.Address.ResourceType != ACPI_MEMORY_RANGE && + res->Data.Address.ResourceType != ACPI_IO_RANGE) { + ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, + "ignored %s for non-memory, non-I/O\n", name)); + break; + } + + if (res->Data.Address.MinAddressFixed == ACPI_ADDRESS_FIXED && + res->Data.Address.MaxAddressFixed == ACPI_ADDRESS_FIXED) { + if (res->Data.Address.ResourceType == ACPI_MEMORY_RANGE) { + ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "%s/Memory 0x%x/%d\n", + name, min, length)); + set->set_memory(dev, arc->context, min, length); + } else { + ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "%s/IO 0x%x/%d\n", name, + min, length)); + set->set_ioport(dev, arc->context, min, length); + } + } else { + if (res->Data.Address32.ResourceType == ACPI_MEMORY_RANGE) { + ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "%s/Memory 0x%x-0x%x/%d\n", + name, min, max, length)); + set->set_memoryrange(dev, arc->context, min, max, length, gran); + } else { + ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "%s/IO 0x%x-0x%x/%d\n", + name, min, max, length)); + set->set_iorange(dev, arc->context, min, max, length, gran); + } + } + break; + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: + if (res->Data.ExtendedIrq.ProducerConsumer != ACPI_CONSUMER) { + ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "ignored ExtIRQ producer\n")); + break; + } + set->set_ext_irq(dev, arc->context, res->Data.ExtendedIrq.Interrupts, + res->Data.ExtendedIrq.InterruptCount, + res->Data.ExtendedIrq.Triggering, res->Data.ExtendedIrq.Polarity); + break; + case ACPI_RESOURCE_TYPE_VENDOR: + ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, + "unimplemented VendorSpecific resource\n")); + break; + default: + break; + } + return (AE_OK); +} + /* * Fetch a device's resources and associate them with the device. * @@ -157,314 +368,19 @@ ACPI_RESOURCE *res; char *curr, *last; ACPI_STATUS status; - void *context; + struct acpi_resource_context arc; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); - /* - * Special-case some devices that abuse _PRS/_CRS to mean - * something other than "I consume this resource". - * - * XXX do we really need this? It's only relevant once - * we start always-allocating these resources, and even - * then, the only special-cased device is likely to be - * the PCI interrupt link. - */ - - /* Fetch the device's current resources. */ - buf.Length = ACPI_ALLOCATE_BUFFER; - if (ACPI_FAILURE((status = AcpiGetCurrentResources(handle, &buf)))) { - if (status != AE_NOT_FOUND && status != AE_TYPE) - printf("can't fetch resources for %s - %s\n", - acpi_name(handle), AcpiFormatException(status)); + set->set_init(dev, arg, &arc.context); + arc.set = set; + status = AcpiWalkResources(handle, "_CRS", acpi_parse_resource, &arc); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { + printf("can't fetch resources for %s - %s\n", + acpi_name(handle), AcpiFormatException(status)); return_ACPI_STATUS (status); } - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "%s - got %ld bytes of resources\n", - acpi_name(handle), (long)buf.Length)); - set->set_init(dev, arg, &context); - - /* Iterate through the resources */ - curr = buf.Pointer; - last = (char *)buf.Pointer + buf.Length; - while (curr < last) { - res = (ACPI_RESOURCE *)curr; - curr += res->Length; - - /* Handle the individual resource types */ - switch(res->Type) { - case ACPI_RESOURCE_TYPE_END_TAG: - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "EndTag\n")); - curr = last; - break; - case ACPI_RESOURCE_TYPE_FIXED_IO: - if (res->Data.FixedIo.AddressLength <= 0) - break; - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "FixedIo 0x%x/%d\n", - res->Data.FixedIo.Address, - res->Data.FixedIo.AddressLength)); - set->set_ioport(dev, context, - res->Data.FixedIo.Address, - res->Data.FixedIo.AddressLength); - break; - case ACPI_RESOURCE_TYPE_IO: - if (res->Data.Io.AddressLength <= 0) - break; - if (res->Data.Io.Minimum == res->Data.Io.Maximum) { - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Io 0x%x/%d\n", - res->Data.Io.Minimum, - res->Data.Io.AddressLength)); - set->set_ioport(dev, context, - res->Data.Io.Minimum, - res->Data.Io.AddressLength); - } else { - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Io 0x%x-0x%x/%d\n", - res->Data.Io.Minimum, - res->Data.Io.Maximum, - res->Data.Io.AddressLength)); - set->set_iorange(dev, context, - res->Data.Io.Minimum, - res->Data.Io.Maximum, - res->Data.Io.AddressLength, - res->Data.Io.Alignment); - } - break; - case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: - if (res->Data.FixedMemory32.AddressLength <= 0) - break; - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "FixedMemory32 0x%x/%d\n", - res->Data.FixedMemory32.Address, - res->Data.FixedMemory32.AddressLength)); - set->set_memory(dev, context, - res->Data.FixedMemory32.Address, - res->Data.FixedMemory32.AddressLength); - break; - case ACPI_RESOURCE_TYPE_MEMORY32: - if (res->Data.Memory32.AddressLength <= 0) - break; - if (res->Data.Memory32.Minimum == - res->Data.Memory32.Maximum) { - - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Memory32 0x%x/%d\n", - res->Data.Memory32.Minimum, - res->Data.Memory32.AddressLength)); - set->set_memory(dev, context, - res->Data.Memory32.Minimum, - res->Data.Memory32.AddressLength); - } else { - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Memory32 0x%x-0x%x/%d\n", - res->Data.Memory32.Minimum, - res->Data.Memory32.Maximum, - res->Data.Memory32.AddressLength)); - set->set_memoryrange(dev, context, - res->Data.Memory32.Minimum, - res->Data.Memory32.Maximum, - res->Data.Memory32.AddressLength, - res->Data.Memory32.Alignment); - } - break; - case ACPI_RESOURCE_TYPE_MEMORY24: - if (res->Data.Memory24.AddressLength <= 0) - break; - if (res->Data.Memory24.Minimum == - res->Data.Memory24.Maximum) { - - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Memory24 0x%x/%d\n", - res->Data.Memory24.Minimum, - res->Data.Memory24.AddressLength)); - set->set_memory(dev, context, res->Data.Memory24.Minimum, - res->Data.Memory24.AddressLength); - } else { - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Memory24 0x%x-0x%x/%d\n", - res->Data.Memory24.Minimum, - res->Data.Memory24.Maximum, - res->Data.Memory24.AddressLength)); - set->set_memoryrange(dev, context, - res->Data.Memory24.Minimum, - res->Data.Memory24.Maximum, - res->Data.Memory24.AddressLength, - res->Data.Memory24.Alignment); - } - break; - case ACPI_RESOURCE_TYPE_IRQ: - /* - * from 1.0b 6.4.2 - * "This structure is repeated for each separate interrupt - * required" - */ - set->set_irq(dev, context, res->Data.Irq.Interrupts, - res->Data.Irq.InterruptCount, res->Data.Irq.Triggering, - res->Data.Irq.Polarity); - break; - case ACPI_RESOURCE_TYPE_DMA: - /* - * from 1.0b 6.4.3 - * "This structure is repeated for each separate dma channel - * required" - */ - set->set_drq(dev, context, res->Data.Dma.Channels, - res->Data.Dma.ChannelCount); - break; - case ACPI_RESOURCE_TYPE_START_DEPENDENT: - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "start dependent functions\n")); - set->set_start_dependent(dev, context, - res->Data.StartDpf.CompatibilityPriority); - break; - case ACPI_RESOURCE_TYPE_END_DEPENDENT: - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "end dependent functions\n")); - set->set_end_dependent(dev, context); - break; - case ACPI_RESOURCE_TYPE_ADDRESS32: - if (res->Data.Address32.AddressLength <= 0) - break; - if (res->Data.Address32.ProducerConsumer != ACPI_CONSUMER) { - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, - "ignored Address32 %s producer\n", - res->Data.Address32.ResourceType == ACPI_IO_RANGE ? - "IO" : "Memory")); - break; - } - if (res->Data.Address32.ResourceType != ACPI_MEMORY_RANGE && - res->Data.Address32.ResourceType != ACPI_IO_RANGE) { - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, - "ignored Address32 for non-memory, non-I/O\n")); - break; - } - - if (res->Data.Address32.MinAddressFixed == ACPI_ADDRESS_FIXED && - res->Data.Address32.MaxAddressFixed == ACPI_ADDRESS_FIXED) { - - if (res->Data.Address32.ResourceType == ACPI_MEMORY_RANGE) { - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, - "Address32/Memory 0x%x/%d\n", - res->Data.Address32.Minimum, - res->Data.Address32.AddressLength)); - set->set_memory(dev, context, - res->Data.Address32.Minimum, - res->Data.Address32.AddressLength); - } else { - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, - "Address32/IO 0x%x/%d\n", - res->Data.Address32.Minimum, - res->Data.Address32.AddressLength)); - set->set_ioport(dev, context, - res->Data.Address32.Minimum, - res->Data.Address32.AddressLength); - } - } else { - if (res->Data.Address32.ResourceType == ACPI_MEMORY_RANGE) { - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, - "Address32/Memory 0x%x-0x%x/%d\n", - res->Data.Address32.Minimum, - res->Data.Address32.Maximum, - res->Data.Address32.AddressLength)); - set->set_memoryrange(dev, context, - res->Data.Address32.Minimum, - res->Data.Address32.Maximum, - res->Data.Address32.AddressLength, - res->Data.Address32.Granularity); - } else { - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, - "Address32/IO 0x%x-0x%x/%d\n", - res->Data.Address32.Minimum, - res->Data.Address32.Maximum, - res->Data.Address32.AddressLength)); - set->set_iorange(dev, context, - res->Data.Address32.Minimum, - res->Data.Address32.Maximum, - res->Data.Address32.AddressLength, - res->Data.Address32.Granularity); - } - } - break; - case ACPI_RESOURCE_TYPE_ADDRESS16: - if (res->Data.Address16.AddressLength <= 0) - break; - if (res->Data.Address16.ProducerConsumer != ACPI_CONSUMER) { - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, - "ignored Address16 %s producer\n", - res->Data.Address16.ResourceType == ACPI_IO_RANGE ? - "IO" : "Memory")); - break; - } - if (res->Data.Address16.ResourceType != ACPI_MEMORY_RANGE && - res->Data.Address16.ResourceType != ACPI_IO_RANGE) { - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, - "ignored Address16 for non-memory, non-I/O\n")); - break; - } - - if (res->Data.Address16.MinAddressFixed == ACPI_ADDRESS_FIXED && - res->Data.Address16.MaxAddressFixed == ACPI_ADDRESS_FIXED) { - - if (res->Data.Address16.ResourceType == ACPI_MEMORY_RANGE) { - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, - "Address16/Memory 0x%x/%d\n", - res->Data.Address16.Minimum, - res->Data.Address16.AddressLength)); - set->set_memory(dev, context, - res->Data.Address16.Minimum, - res->Data.Address16.AddressLength); - } else { - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, - "Address16/IO 0x%x/%d\n", - res->Data.Address16.Minimum, - res->Data.Address16.AddressLength)); - set->set_ioport(dev, context, - res->Data.Address16.Minimum, - res->Data.Address16.AddressLength); - } - } else { - if (res->Data.Address16.ResourceType == ACPI_MEMORY_RANGE) { - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, - "Address16/Memory 0x%x-0x%x/%d\n", - res->Data.Address16.Minimum, - res->Data.Address16.Maximum, - res->Data.Address16.AddressLength)); - set->set_memoryrange(dev, context, - res->Data.Address16.Minimum, - res->Data.Address16.Maximum, - res->Data.Address16.AddressLength, - res->Data.Address16.Granularity); - } else { - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, - "Address16/IO 0x%x-0x%x/%d\n", - res->Data.Address16.Minimum, - res->Data.Address16.Maximum, - res->Data.Address16.AddressLength)); - set->set_iorange(dev, context, - res->Data.Address16.Minimum, - res->Data.Address16.Maximum, - res->Data.Address16.AddressLength, - res->Data.Address16.Granularity); - } - } - break; - case ACPI_RESOURCE_TYPE_ADDRESS64: - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, - "unimplemented Address64 resource\n")); - break; - case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: - if (res->Data.ExtendedIrq.ProducerConsumer != ACPI_CONSUMER) { - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, - "ignored ExtIRQ producer\n")); - break; - } - set->set_ext_irq(dev, context, res->Data.ExtendedIrq.Interrupts, - res->Data.ExtendedIrq.InterruptCount, - res->Data.ExtendedIrq.Triggering, - res->Data.ExtendedIrq.Polarity); - break; - case ACPI_RESOURCE_TYPE_VENDOR: - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, - "unimplemented VendorSpecific resource\n")); - break; - default: - break; - } - } - - AcpiOsFree(buf.Pointer); - set->set_done(dev, context); + set->set_done(dev, arc.context); return_ACPI_STATUS (AE_OK); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104150337.p3F3bkbL031703>
