iPXE
Functions
acpipwr.h File Reference

ACPI power off. More...

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
int acpi_poweroff (void)
 Power off the computer using ACPI.

Detailed Description

ACPI power off.

Definition in file acpipwr.h.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
int acpi_poweroff ( void  )

Power off the computer using ACPI.

Return values:
rcReturn status code

Definition at line 50 of file acpipwr.c.

References acpi_find(), ACPI_PM1_CNT, ACPI_PM1_CNT_SLP_EN, ACPI_PM1_CNT_SLP_TYP, acpi_sx(), colour, copy_from_user(), DBGC, ENOENT, EPROTO, FADT_SIGNATURE, le32_to_cpu, mdelay(), outw(), acpi_fadt::pm1a_cnt_blk, acpi_fadt::pm1b_cnt_blk, rc, S5_SIGNATURE, and strerror().

Referenced by bios_poweroff().

                           {
        struct acpi_fadt fadtab;
        userptr_t fadt;
        unsigned int pm1a_cnt_blk;
        unsigned int pm1b_cnt_blk;
        unsigned int pm1a_cnt;
        unsigned int pm1b_cnt;
        unsigned int slp_typa;
        unsigned int slp_typb;
        int s5;
        int rc;

        /* Locate FADT */
        fadt = acpi_find ( FADT_SIGNATURE, 0 );
        if ( ! fadt ) {
                DBGC ( colour, "ACPI could not find FADT\n" );
                return -ENOENT;
        }

        /* Read FADT */
        copy_from_user ( &fadtab, fadt, 0, sizeof ( fadtab ) );
        pm1a_cnt_blk = le32_to_cpu ( fadtab.pm1a_cnt_blk );
        pm1b_cnt_blk = le32_to_cpu ( fadtab.pm1b_cnt_blk );
        pm1a_cnt = ( pm1a_cnt_blk + ACPI_PM1_CNT );
        pm1b_cnt = ( pm1b_cnt_blk + ACPI_PM1_CNT );

        /* Extract \_S5 from DSDT or any SSDT */
        s5 = acpi_sx ( S5_SIGNATURE );
        if ( s5 < 0 ) {
                rc = s5;
                DBGC ( colour, "ACPI could not extract \\_S5: %s\n",
                       strerror ( rc ) );
                return rc;
        }

        /* Power off system */
        if ( pm1a_cnt_blk ) {
                slp_typa = ( ( s5 >> 0 ) & 0xff );
                DBGC ( colour, "ACPI PM1a sleep type %#x => %04x\n",
                       slp_typa, pm1a_cnt );
                outw ( ( ACPI_PM1_CNT_SLP_TYP ( slp_typa ) |
                         ACPI_PM1_CNT_SLP_EN ), pm1a_cnt );
        }
        if ( pm1b_cnt_blk ) {
                slp_typb = ( ( s5 >> 8 ) & 0xff );
                DBGC ( colour, "ACPI PM1b sleep type %#x => %04x\n",
                       slp_typb, pm1b_cnt );
                outw ( ( ACPI_PM1_CNT_SLP_TYP ( slp_typb ) |
                         ACPI_PM1_CNT_SLP_EN ), pm1b_cnt );
        }

        /* On some systems, execution will continue briefly.  Delay to
         * avoid potentially confusing log messages.
         */
        mdelay ( 1000 );

        DBGC ( colour, "ACPI power off failed\n" );
        return -EPROTO;
}