Example #1
0
uint32
get_object_type(const char* path)
{
    ACPI_HANDLE handle;
    ACPI_OBJECT_TYPE type;

    if (AcpiGetHandle(NULL, (ACPI_STRING)path, &handle) != AE_OK)
        return B_ENTRY_NOT_FOUND;

    AcpiGetType(handle, &type);
    return type;
}
Example #2
0
/*
 * fujitsu_hk_cap:
 *
 *	Returns true if and only if (a) the object handle.path exists and
 *	(b) this object is a method or has the given type.
 */
static bool
fujitsu_hk_cap(ACPI_HANDLE handle, const char *path, ACPI_OBJECT_TYPE type)
{
    ACPI_HANDLE hdl;
    ACPI_OBJECT_TYPE typ;

    KASSERT(handle != NULL);

    if (ACPI_FAILURE(AcpiGetHandle(handle, path, &hdl)))
        return false;

    if (ACPI_FAILURE(AcpiGetType(hdl, &typ)))
        return false;

    if (typ != ACPI_TYPE_METHOD && typ != type)
        return false;

    return true;
}
Example #3
0
static void
AfInstallGpeBlock (
    void)
{
    ACPI_STATUS                 Status;
    ACPI_HANDLE                 Handle;
    ACPI_GENERIC_ADDRESS        BlockAddress;
    ACPI_HANDLE                 GpeDevice;
    ACPI_OBJECT_TYPE            Type;


    /* _GPE should always exist */

    Status = AcpiGetHandle (NULL, "\\_GPE", &Handle);
    ACPI_CHECK_OK (AcpiGetHandle, Status);
    if (ACPI_FAILURE (Status))
    {
        return;
    }

    memset (&BlockAddress, 0, sizeof (ACPI_GENERIC_ADDRESS));
    BlockAddress.SpaceId = ACPI_ADR_SPACE_SYSTEM_MEMORY;
    BlockAddress.Address = 0x76540000;

    /* Attempt to install a GPE block on GPE2 (if present) */

    Status = AcpiGetHandle (NULL, "\\GPE2", &Handle);
    if (ACPI_SUCCESS (Status))
    {
        Status = AcpiGetType (Handle, &Type);
        if (ACPI_FAILURE (Status) ||
           (Type != ACPI_TYPE_DEVICE))
        {
            return;
        }

        Status = AcpiInstallGpeBlock (Handle, &BlockAddress, 7, 8);
        ACPI_CHECK_OK (AcpiInstallGpeBlock, Status);

        Status = AcpiInstallGpeHandler (Handle, 8,
            ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL);
        ACPI_CHECK_OK (AcpiInstallGpeHandler, Status);

        Status = AcpiEnableGpe (Handle, 8);
        ACPI_CHECK_OK (AcpiEnableGpe, Status);

        Status = AcpiGetGpeDevice (0x30, &GpeDevice);
        ACPI_CHECK_OK (AcpiGetGpeDevice, Status);

        Status = AcpiGetGpeDevice (0x42, &GpeDevice);
        ACPI_CHECK_OK (AcpiGetGpeDevice, Status);

        Status = AcpiGetGpeDevice (AcpiCurrentGpeCount-1, &GpeDevice);
        ACPI_CHECK_OK (AcpiGetGpeDevice, Status);

        Status = AcpiGetGpeDevice (AcpiCurrentGpeCount, &GpeDevice);
        ACPI_CHECK_STATUS (AcpiGetGpeDevice, Status, AE_NOT_EXIST);

        Status = AcpiRemoveGpeHandler (Handle, 8, AeGpeHandler);
        ACPI_CHECK_OK (AcpiRemoveGpeHandler, Status);
    }

    /* Attempt to install a GPE block on GPE3 (if present) */

    Status = AcpiGetHandle (NULL, "\\GPE3", &Handle);
    if (ACPI_SUCCESS (Status))
    {
        Status = AcpiGetType (Handle, &Type);
        if (ACPI_FAILURE (Status) ||
           (Type != ACPI_TYPE_DEVICE))
        {
            return;
        }

        Status = AcpiInstallGpeBlock (Handle, &BlockAddress, 8, 11);
        ACPI_CHECK_OK (AcpiInstallGpeBlock, Status);
    }
}
Example #4
0
static ACPI_STATUS
AcpiHwGetPciDeviceInfo (
    ACPI_PCI_ID             *PciId,
    ACPI_HANDLE             PciDevice,
    UINT16                  *BusNumber,
    BOOLEAN                 *IsBridge)
{
    ACPI_STATUS             Status;
    ACPI_OBJECT_TYPE        ObjectType;
    UINT64                  ReturnValue;
    UINT64                  PciValue;


    /* We only care about objects of type Device */

    Status = AcpiGetType (PciDevice, &ObjectType);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    if (ObjectType != ACPI_TYPE_DEVICE)
    {
        return (AE_OK);
    }

    /* We need an _ADR. Ignore device if not present */

    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR,
        PciDevice, &ReturnValue);
    if (ACPI_FAILURE (Status))
    {
        return (AE_OK);
    }

    /*
     * From _ADR, get the PCI Device and Function and
     * update the PCI ID.
     */
    PciId->Device = ACPI_HIWORD (ACPI_LODWORD (ReturnValue));
    PciId->Function = ACPI_LOWORD (ACPI_LODWORD (ReturnValue));

    /*
     * If the previous device was a bridge, use the previous
     * device bus number
     */
    if (*IsBridge)
    {
        PciId->Bus = *BusNumber;
    }

    /*
     * Get the bus numbers from PCI Config space:
     *
     * First, get the PCI HeaderType
     */
    *IsBridge = FALSE;
    Status = AcpiOsReadPciConfiguration (PciId,
        PCI_CFG_HEADER_TYPE_REG, &PciValue, 8);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    /* We only care about bridges (1=PciBridge, 2=CardBusBridge) */

    PciValue &= PCI_HEADER_TYPE_MASK;

    if ((PciValue != PCI_TYPE_BRIDGE) &&
        (PciValue != PCI_TYPE_CARDBUS_BRIDGE))
    {
        return (AE_OK);
    }

    /* Bridge: Get the Primary BusNumber */

    Status = AcpiOsReadPciConfiguration (PciId,
        PCI_CFG_PRIMARY_BUS_NUMBER_REG, &PciValue, 8);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    *IsBridge = TRUE;
    PciId->Bus = (UINT16) PciValue;

    /* Bridge: Get the Secondary BusNumber */

    Status = AcpiOsReadPciConfiguration (PciId,
        PCI_CFG_SECONDARY_BUS_NUMBER_REG, &PciValue, 8);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    *BusNumber = (UINT16) PciValue;
    return (AE_OK);
}
Example #5
0
/*
 * Install/uninstall ACPI system event handler for child objects of hdl.
 * Return DDI_SUCCESS on success, and DDI_FAILURE on failure.
 */
static int
acpinex_event_walk(boolean_t init, acpinex_softstate_t *sp, ACPI_HANDLE hdl)
{
	int rc;
	int retval = DDI_SUCCESS;
	dev_info_t *dip;
	ACPI_HANDLE child = NULL;
	ACPI_OBJECT_TYPE type;
	ACPI_DEVICE_INFO *infop;
	acpidev_data_handle_t dhdl;

	/* Walk all child objects. */
	ASSERT(hdl != NULL);
	while (ACPI_SUCCESS(AcpiGetNextObject(ACPI_TYPE_ANY, hdl, child,
	    &child))) {
		/* Skip unwanted object types. */
		if (ACPI_FAILURE(AcpiGetType(child, &type)) ||
		    type > ACPI_TYPE_NS_NODE_MAX ||
		    BT_TEST(acpinex_object_type_mask, type) == 0) {
			continue;
		}

		/* Get data associated with the object. Skip it if fails. */
		dhdl = acpidev_data_get_handle(child);
		if (dhdl == NULL) {
			ACPINEX_DEBUG(CE_NOTE, "!acpinex: failed to get data "
			    "associated with %p, skip.", child);
			continue;
		}

		/* Query ACPI object info for the object. */
		if (ACPI_FAILURE(AcpiGetObjectInfo(child, &infop))) {
			cmn_err(CE_WARN,
			    "!acpidnex: failed to get object info for %p.",
			    child);
			continue;
		}

		if (init) {
			rc = acpinex_event_install_handler(child, sp, infop,
			    dhdl);
			if (rc != DDI_SUCCESS) {
				ACPINEX_DEBUG(CE_WARN, "!acpinex: failed to "
				    "install handler for child %p of %s.",
				    child, sp->ans_path);
				retval = DDI_FAILURE;
			/*
			 * Try to handle descendants if both of the
			 * following two conditions are true:
			 * 1) Device corresponding to the current object is
			 *    enabled. If the device is absent/disabled,
			 *    no notification should be generated from
			 *    descendant objects of it.
			 * 2) No Solaris device node has been created for the
			 *    current object yet. If the device node has been
			 *    created for the current object, notification
			 *    events from child objects should be handled by
			 *    the corresponding driver.
			 */
			} else if (acpidev_check_device_enabled(
			    acpidev_data_get_status(dhdl)) &&
			    ACPI_FAILURE(acpica_get_devinfo(child, &dip))) {
				rc = acpinex_event_walk(B_TRUE, sp, child);
				if (rc != DDI_SUCCESS) {
					ACPINEX_DEBUG(CE_WARN,
					    "!acpinex: failed to install "
					    "handler for descendants of %s.",
					    sp->ans_path);
					retval = DDI_FAILURE;
				}
			}
		} else {
			rc = DDI_SUCCESS;
			/* Uninstall handler for descendants if needed. */
			if (ACPI_FAILURE(acpica_get_devinfo(child, &dip))) {
				rc = acpinex_event_walk(B_FALSE, sp, child);
			}
			if (rc == DDI_SUCCESS) {
				rc = acpinex_event_uninstall_handler(child,
				    infop, dhdl);
			}
			/* Undo will be done by caller in case of failure. */
			if (rc != DDI_SUCCESS) {
				ACPINEX_DEBUG(CE_WARN, "!acpinex: failed to "
				    "uninstall handler for descendants of %s.",
				    sp->ans_path);
				AcpiOsFree(infop);
				retval = DDI_FAILURE;
				break;
			}
		}

		/* Release cached resources. */
		AcpiOsFree(infop);
	}

	return (retval);
}