From owner-p4-projects@FreeBSD.ORG Wed Sep 24 11:05:38 2003 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id F33ED16A4C0; Wed, 24 Sep 2003 11:05:37 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id AE99616A4B3 for ; Wed, 24 Sep 2003 11:05:37 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0C74644014 for ; Wed, 24 Sep 2003 11:05:37 -0700 (PDT) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.9/8.12.9) with ESMTP id h8OI5aXJ099411 for ; Wed, 24 Sep 2003 11:05:36 -0700 (PDT) (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.9/8.12.9/Submit) id h8OI5alR099408 for perforce@freebsd.org; Wed, 24 Sep 2003 11:05:36 -0700 (PDT) (envelope-from jhb@freebsd.org) Date: Wed, 24 Sep 2003 11:05:36 -0700 (PDT) Message-Id: <200309241805.h8OI5alR099408@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin To: Perforce Change Reviews Subject: PERFORCE change 38520 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Sep 2003 18:05:38 -0000 http://perforce.freebsd.org/chv.cgi?CH=38520 Change 38520 by jhb@jhb_laptop on 2003/09/24 11:05:16 Update the ACPI PCI bus driver to set the ACPI device power state "outside" of the PCI power state. Affected files ... .. //depot/projects/power/sys/dev/acpica/acpi_pci.c#2 edit Differences ... ==== //depot/projects/power/sys/dev/acpica/acpi_pci.c#2 (text+ko) ==== @@ -65,11 +65,8 @@ static int acpi_pci_attach(device_t dev); static int acpi_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result); -#if 0 static int acpi_pci_set_powerstate_method(device_t dev, device_t child, int state); -static int acpi_pci_get_powerstate_method(device_t dev, device_t child); -#endif static ACPI_STATUS acpi_pci_save_handle(ACPI_HANDLE handle, UINT32 level, void *context, void **status); @@ -108,9 +105,8 @@ DEVMETHOD(pci_disable_busmaster, pci_disable_busmaster_method), DEVMETHOD(pci_enable_io, pci_enable_io_method), DEVMETHOD(pci_disable_io, pci_disable_io_method), - /* XXX: We should override these two. */ DEVMETHOD(pci_get_powerstate, pci_get_powerstate_method), - DEVMETHOD(pci_set_powerstate, pci_set_powerstate_method), + DEVMETHOD(pci_set_powerstate, acpi_pci_set_powerstate_method), DEVMETHOD(pci_assign_interrupt, pci_assign_interrupt_method), { 0, 0 } @@ -140,24 +136,58 @@ return(pci_read_ivar(dev, child, which, result)); } -#if 0 /* * PCI power manangement */ static int acpi_pci_set_powerstate_method(device_t dev, device_t child, int state) { - /* XXX: TODO */ - return (ENXIO); -} + ACPI_STATUS status; + int acpi_state, old_state, error; + + switch (state) { + case PCI_POWERSTATE_D0: + acpi_state = ACPI_STATE_D0; + break; + case PCI_POWERSTATE_D1: + acpi_state = ACPI_STATE_D1; + break; + case PCI_POWERSTATE_D2: + acpi_state = ACPI_STATE_D2; + break; + case PCI_POWERSTATE_D3: + acpi_state = ACPI_STATE_D3; + break; + default: + return (EINVAL); + } -static int -acpi_pci_get_powerstate_method(device_t dev, device_t child) -{ - /* XXX: TODO */ - return (ENXIO); + /* + * We set the state using PCI Power Management outside of setting + * the ACPI state. This means that when powering down a device, we + * first shut it down using PCI, and then using ACPI, which lets ACPI + * try to power down any Power Resources that are now no longer used. + * When powering up a device, we let ACPI set the state first so that + * it can enable any needed Power Resources before changing the PCI + * power state. + */ + old_state = pci_get_powerstate(child); + if (old_state < state) { + error = pci_set_powerstate_method(dev, child, state); + if (error) + return (error); + } + status = acpi_SetPowerState(acpi_get_handle(child), acpi_state); + if (ACPI_FAILURE(status)) + device_printf(dev, + "Failed to set ACPI power state D%d on %s: %s\n", + acpi_state, device_get_nameunit(child), + AcpiFormatException(status)); + if (state > old_state) + return (pci_set_powerstate_method(dev, child, state)); + else + return (0); } -#endif static ACPI_STATUS acpi_pci_save_handle(ACPI_HANDLE handle, UINT32 level, void *context,