static ACPI_STATUS
acpi_pci_link_srs_from_crs(struct acpi_pci_link_softc *sc, ACPI_BUFFER *srsbuf)
{
	ACPI_RESOURCE *end, *res;
	ACPI_STATUS status;
	struct link *link;
	int i, in_dpf;

	/* Fetch the _CRS. */
	ACPI_SERIAL_ASSERT(pci_link);
	srsbuf->Pointer = NULL;
	srsbuf->Length = ACPI_ALLOCATE_BUFFER;
	status = AcpiGetCurrentResources(acpi_get_handle(sc->pl_dev), srsbuf);
	if (ACPI_SUCCESS(status) && srsbuf->Pointer == NULL)
		status = AE_NO_MEMORY;
	if (ACPI_FAILURE(status)) {
		if (bootverbose)
			device_printf(sc->pl_dev,
			    "Unable to fetch current resources: %s\n",
			    AcpiFormatException(status));
		return (status);
	}

	/* Fill in IRQ resources via link structures. */
	link = sc->pl_links;
	i = 0;
	in_dpf = DPF_OUTSIDE;
	res = (ACPI_RESOURCE *)srsbuf->Pointer;
	end = (ACPI_RESOURCE *)((char *)srsbuf->Pointer + srsbuf->Length);
	for (;;) {
		switch (res->Type) {
		case ACPI_RESOURCE_TYPE_START_DEPENDENT:
			switch (in_dpf) {
			case DPF_OUTSIDE:
				/* We've started the first DPF. */
				in_dpf = DPF_FIRST;
				break;
			case DPF_FIRST:
				/* We've started the second DPF. */
				panic(
		"%s: Multiple dependent functions within a current resource",
				    __func__);
				break;
			}
			break;
		case ACPI_RESOURCE_TYPE_END_DEPENDENT:
			/* We are finished with DPF parsing. */
			KASSERT(in_dpf != DPF_OUTSIDE,
			    ("%s: end dpf when not parsing a dpf", __func__));
			in_dpf = DPF_OUTSIDE;
			break;
		case ACPI_RESOURCE_TYPE_IRQ:
			MPASS(i < sc->pl_num_links);
			res->Data.Irq.InterruptCount = 1;
			if (PCI_INTERRUPT_VALID(link->l_irq)) {
				KASSERT(link->l_irq < NUM_ISA_INTERRUPTS,
		("%s: can't put non-ISA IRQ %d in legacy IRQ resource type",
				    __func__, link->l_irq));
				res->Data.Irq.Interrupts[0] = link->l_irq;
			} else
				res->Data.Irq.Interrupts[0] = 0;
			link++;
			i++;
			break;
		case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
			MPASS(i < sc->pl_num_links);
			res->Data.ExtendedIrq.InterruptCount = 1;
			if (PCI_INTERRUPT_VALID(link->l_irq))
				res->Data.ExtendedIrq.Interrupts[0] =
				    link->l_irq;
			else
				res->Data.ExtendedIrq.Interrupts[0] = 0;
			link++;
			i++;
			break;
		}
		if (res->Type == ACPI_RESOURCE_TYPE_END_TAG)
			break;
		res = ACPI_NEXT_RESOURCE(res);
		if (res >= end)
			break;
	}
	return (AE_OK);
}
Beispiel #2
0
static ACPI_STATUS
AcpiDbDeviceResources (
    ACPI_HANDLE             ObjHandle,
    UINT32                  NestingLevel,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_NAMESPACE_NODE     *PrtNode = NULL;
    ACPI_NAMESPACE_NODE     *CrsNode = NULL;
    ACPI_NAMESPACE_NODE     *PrsNode = NULL;
    ACPI_NAMESPACE_NODE     *AeiNode = NULL;
    char                    *ParentPath;
    ACPI_BUFFER             ReturnObj;
    ACPI_STATUS             Status;


    Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
    ParentPath = AcpiNsGetExternalPathname (Node);
    if (!ParentPath)
    {
        return (AE_NO_MEMORY);
    }

    /* Get handles to the resource methods for this device */

    (void) AcpiGetHandle (Node, METHOD_NAME__PRT, ACPI_CAST_PTR (ACPI_HANDLE, &PrtNode));
    (void) AcpiGetHandle (Node, METHOD_NAME__CRS, ACPI_CAST_PTR (ACPI_HANDLE, &CrsNode));
    (void) AcpiGetHandle (Node, METHOD_NAME__PRS, ACPI_CAST_PTR (ACPI_HANDLE, &PrsNode));
    (void) AcpiGetHandle (Node, METHOD_NAME__AEI, ACPI_CAST_PTR (ACPI_HANDLE, &AeiNode));
    if (!PrtNode && !CrsNode && !PrsNode && !AeiNode)
    {
        goto Cleanup;   /* Nothing to do */
    }

    AcpiOsPrintf ("\nDevice: %s\n", ParentPath);

    /* Prepare for a return object of arbitrary size */

    ReturnObj.Pointer = AcpiGbl_DbBuffer;
    ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;


    /* _PRT */

    if (PrtNode)
    {
        AcpiOsPrintf ("Evaluating _PRT\n");

        Status = AcpiEvaluateObject (PrtNode, NULL, NULL, &ReturnObj);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("Could not evaluate _PRT: %s\n",
                AcpiFormatException (Status));
            goto GetCrs;
        }

        ReturnObj.Pointer = AcpiGbl_DbBuffer;
        ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;

        Status = AcpiGetIrqRoutingTable (Node, &ReturnObj);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n",
                AcpiFormatException (Status));
            goto GetCrs;
        }

        AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer));
    }


    /* _CRS */

GetCrs:
    if (CrsNode)
    {
        AcpiOsPrintf ("Evaluating _CRS\n");

        ReturnObj.Pointer = AcpiGbl_DbBuffer;
        ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;

        Status = AcpiEvaluateObject (CrsNode, NULL, NULL, &ReturnObj);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("Could not evaluate _CRS: %s\n",
                AcpiFormatException (Status));
            goto GetPrs;
        }

        /* This code is here to exercise the AcpiWalkResources interface */

        Status = AcpiWalkResources (Node, METHOD_NAME__CRS,
            AcpiDbResourceCallback, NULL);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("AcpiWalkResources failed: %s\n",
                AcpiFormatException (Status));
            goto GetPrs;
        }

        /* Get the _CRS resource list */

        ReturnObj.Pointer = AcpiGbl_DbBuffer;
        ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;

        Status = AcpiGetCurrentResources (Node, &ReturnObj);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
                AcpiFormatException (Status));
            goto GetPrs;
        }

        /* Dump the _CRS resource list */

        AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
            ReturnObj.Pointer));

        /*
         * Perform comparison of original AML to newly created AML. This tests both
         * the AML->Resource conversion and the Resource->Aml conversion.
         */
        Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS);

        /* Execute _SRS with the resource list */

        Status = AcpiSetCurrentResources (Node, &ReturnObj);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n",
                AcpiFormatException (Status));
            goto GetPrs;
        }
    }


    /* _PRS */

GetPrs:
    if (PrsNode)
    {
        AcpiOsPrintf ("Evaluating _PRS\n");

        ReturnObj.Pointer = AcpiGbl_DbBuffer;
        ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;

        Status = AcpiEvaluateObject (PrsNode, NULL, NULL, &ReturnObj);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("Could not evaluate _PRS: %s\n",
                AcpiFormatException (Status));
            goto GetAei;
        }

        ReturnObj.Pointer = AcpiGbl_DbBuffer;
        ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;

        Status = AcpiGetPossibleResources (Node, &ReturnObj);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n",
                AcpiFormatException (Status));
            goto GetAei;
        }

        AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
    }


    /* _AEI */

GetAei:
    if (AeiNode)
    {
        AcpiOsPrintf ("Evaluating _AEI\n");

        ReturnObj.Pointer = AcpiGbl_DbBuffer;
        ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;

        Status = AcpiEvaluateObject (AeiNode, NULL, NULL, &ReturnObj);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("Could not evaluate _AEI: %s\n",
                AcpiFormatException (Status));
            goto Cleanup;
        }

        ReturnObj.Pointer = AcpiGbl_DbBuffer;
        ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;

        Status = AcpiGetEventResources (Node, &ReturnObj);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("AcpiGetEventResources failed: %s\n",
                AcpiFormatException (Status));
            goto Cleanup;
        }

        AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
    }


Cleanup:
    ACPI_FREE (ParentPath);
    return (AE_OK);
}
Beispiel #3
0
static ACPI_STATUS
AcpiDmTestResourceConversion (
    ACPI_NAMESPACE_NODE     *Node,
    char                    *Name)
{
    ACPI_STATUS             Status;
    ACPI_BUFFER             ReturnObj;
    ACPI_BUFFER             ResourceObj;
    ACPI_BUFFER             NewAml;
    ACPI_OBJECT             *OriginalAml;


    AcpiOsPrintf ("Resource Conversion Comparison:\n");

    NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
    ReturnObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
    ResourceObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;

    /* Get the original _CRS AML resource template */

    Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnObj);
    if (ACPI_FAILURE (Status))
    {
        AcpiOsPrintf ("Could not obtain %s: %s\n",
            Name, AcpiFormatException (Status));
        return (Status);
    }

    /* Get the AML resource template, converted to internal resource structs */

    Status = AcpiGetCurrentResources (Node, &ResourceObj);
    if (ACPI_FAILURE (Status))
    {
        AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
            AcpiFormatException (Status));
        goto Exit1;
    }

    /* Convert internal resource list to external AML resource template */

    Status = AcpiRsCreateAmlResources (ResourceObj.Pointer, &NewAml);
    if (ACPI_FAILURE (Status))
    {
        AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n",
            AcpiFormatException (Status));
        goto Exit2;
    }

    /* Compare original AML to the newly created AML resource list */

    OriginalAml = ReturnObj.Pointer;

    AcpiDmCompareAmlResources (
        OriginalAml->Buffer.Pointer, (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length,
        NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length);

    /* Cleanup and exit */

    ACPI_FREE (NewAml.Pointer);
Exit2:
    ACPI_FREE (ResourceObj.Pointer);
Exit1:
    ACPI_FREE (ReturnObj.Pointer);
    return (Status);
}
Beispiel #4
0
status_t
get_current_resources(acpi_handle busDeviceHandle, acpi_data *retBuffer)
{
    return AcpiGetCurrentResources(busDeviceHandle, (ACPI_BUFFER*)retBuffer)
           == AE_OK ? B_OK : B_ERROR;
}
/*
 * Retrieves the current irq setting for the interrrupt link device.
 *
 * Stores polarity and sensitivity in the structure pointed to by
 * intr_flagp, and irqno in the value pointed to by pci_irqp.
 *
 * Returns ACPI_PSM_SUCCESS on success, ACPI_PSM_FAILURE upon failure.
 */
int
acpi_get_current_irq_resource(acpi_psm_lnk_t *acpipsmlnkp, int *pci_irqp,
    iflag_t *intr_flagp)
{
	ACPI_HANDLE lnkobj;
	ACPI_BUFFER rb;
	ACPI_RESOURCE *rp;
	int irq;
	int status = ACPI_PSM_FAILURE;

	ASSERT(acpipsmlnkp != NULL);
	lnkobj = acpipsmlnkp->lnkobj;

	if (!(acpipsmlnkp->device_status & STA_PRESENT) ||
	    !(acpipsmlnkp->device_status & STA_ENABLE)) {
		PSM_VERBOSE_IRQ((CE_WARN, "!psm: crs device either not "
		    "present or disabled, status 0x%x",
		    acpipsmlnkp->device_status));
		return (ACPI_PSM_FAILURE);
	}

	rb.Pointer = NULL;
	rb.Length = ACPI_ALLOCATE_BUFFER;
	if (AcpiGetCurrentResources(lnkobj, &rb) != AE_OK) {
		PSM_VERBOSE_IRQ((CE_WARN, "!psm: no crs object found or"
		" evaluation failed"));
		return (ACPI_PSM_FAILURE);
	}

	irq = -1;
	for (rp = rb.Pointer; rp->Type != ACPI_RESOURCE_TYPE_END_TAG;
	    rp = ACPI_NEXT_RESOURCE(rp)) {
		if (rp->Type == ACPI_RESOURCE_TYPE_IRQ) {
			if (irq > 0) {
				PSM_VERBOSE_IRQ((CE_WARN, "!psm: multiple IRQ"
				" from _CRS "));
				status = ACPI_PSM_FAILURE;
				break;
			}

			if (rp->Data.Irq.InterruptCount != 1) {
				PSM_VERBOSE_IRQ((CE_WARN, "!psm: <>1 interrupt"
				" from _CRS "));
				status = ACPI_PSM_FAILURE;
				break;
			}

			intr_flagp->intr_el = psm_acpi_edgelevel(
			    rp->Data.Irq.Triggering);
			intr_flagp->intr_po = psm_acpi_po(
			    rp->Data.Irq.Polarity);
			irq = rp->Data.Irq.Interrupts[0];
			status = ACPI_PSM_SUCCESS;
		} else if (rp->Type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) {
			if (irq > 0) {
				PSM_VERBOSE_IRQ((CE_WARN, "!psm: multiple IRQ"
				" from _CRS "));
				status = ACPI_PSM_FAILURE;
				break;
			}

			if (rp->Data.ExtendedIrq.InterruptCount != 1) {
				PSM_VERBOSE_IRQ((CE_WARN, "!psm: <>1 interrupt"
				" from _CRS "));
				status = ACPI_PSM_FAILURE;
				break;
			}

			intr_flagp->intr_el = psm_acpi_edgelevel(
			    rp->Data.ExtendedIrq.Triggering);
			intr_flagp->intr_po = psm_acpi_po(
			    rp->Data.ExtendedIrq.Polarity);
			irq = rp->Data.ExtendedIrq.Interrupts[0];
			status = ACPI_PSM_SUCCESS;
		}
	}

	AcpiOsFree(rb.Pointer);
	if (status == ACPI_PSM_SUCCESS) {
		*pci_irqp =  irq;
	}

	return (status);
}
/*
 * Fetch a device's resources and associate them with the device.
 *
 * Note that it might be nice to also locate ACPI-specific resource items, such
 * as GPE bits.
 *
 * We really need to split the resource-fetching code out from the
 * resource-parsing code, since we may want to use the parsing
 * code for _PRS someday.
 */
ACPI_STATUS
acpi_parse_resources(device_t dev, ACPI_HANDLE handle,
		     struct acpi_parse_resource_set *set, void *arg)
{
    ACPI_BUFFER		buf;
    ACPI_RESOURCE	*res;
    char		*curr, *last;
    ACPI_STATUS		status;
    void		*context;

    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)
	    kprintf("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);
    return_ACPI_STATUS (AE_OK);
}