So, is this the bottom line of the hwsleep patch: If there is a second FACS in the system (pointed to by the unused RSDT), then set the firmware waking vectors in BOTH FACS tables? >-----Original Message----- >From: Zhang, Rui >Sent: Monday, October 13, 2008 1:11 AM >To: Len Brown >Cc: linux-acpi; Moore, Robert; Rafael J. Wysocki; Zhang, Rui >Subject: [PATCH 5/6] ACPI: set waking vector in inactive facs table > > >RSDT and XSDT may export different FACS tables. >Some of the BIOSes only checks one of them when resuming. >And Linux reboots instead of resuming because BIOS can't find >the waking vector. >For example, >I have a platform which suspends well, but always reboots instead of >resuming when pressing the power button. >I found that there are two FACS tables on this platform, >XSDT-->FADT1-->Xfacs-->FACS1 > |----->facs-| > |->FACS2 >RSDT-->FADT2-->facs-| >Linux uses XSDT on this platform and sets the waking vector in FACS1 >when suspending. >But it seems that the BIOS only cares for the waking vector in FACS2, >thus it reboots when resuming because the waking vector is not set at all. > >Set the waking vector in inactive FACS table in this patch. > >Signed-off-by: Zhang Rui <rui.zhang@xxxxxxxxx> >--- > drivers/acpi/hardware/hwsleep.c | 20 ++++++++++++++++++++ > drivers/acpi/tables/tbfadt.c | 6 ++++-- > 2 files changed, 24 insertions(+), 2 deletions(-) > >Index: linux-2.6/drivers/acpi/hardware/hwsleep.c >=================================================================== >--- linux-2.6.orig/drivers/acpi/hardware/hwsleep.c >+++ linux-2.6/drivers/acpi/hardware/hwsleep.c >@@ -65,6 +65,7 @@ acpi_set_firmware_waking_vector(acpi_phy > { > struct acpi_table_facs *facs; > acpi_status status; >+ u32 table_index; > > ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector); > >@@ -92,6 +93,25 @@ acpi_set_firmware_waking_vector(acpi_phy > facs->xfirmware_waking_vector = physical_address; > } > >+ /* set the firmware vector in the inactive facs table */ >+ for (table_index = 0, facs = NULL; ; table_index++) { >+ status = acpi_get_inactive_table_by_index(table_index, >+ ACPI_CAST_INDIRECT_PTR(struct >acpi_table_header, >+ &facs)); >+ if (status == AE_TABLE_NOT_SUPPORTED) >+ continue; >+ if (ACPI_FAILURE(status)) >+ break; >+ >+ if (!ACPI_COMPARE_NAME(&facs->signature, ACPI_SIG_FACS)) >+ continue; >+ >+ if (facs->version >= 1) >+ facs->xfirmware_waking_vector = 0; >+ facs->firmware_waking_vector = (u32)physical_address; >+ break; >+ } >+ > return_ACPI_STATUS(AE_OK); > } > >Index: linux-2.6/drivers/acpi/tables/tbfadt.c >=================================================================== >--- linux-2.6.orig/drivers/acpi/tables/tbfadt.c >+++ linux-2.6/drivers/acpi/tables/tbfadt.c >@@ -290,11 +290,13 @@ static void acpi_tb_convert_fadt(void) > > if (!acpi_gbl_FADT.Xfacs) { > acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs; >- } >+ } else if (acpi_gbl_FADT.Xfacs != acpi_gbl_FADT.facs) >+ ACPI_WARNING((AE_INFO, "32 bit FACS and 64 bit FACS not >match\n")); > > if (!acpi_gbl_FADT.Xdsdt) { > acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt; >- } >+ } else if (acpi_gbl_FADT.Xdsdt != acpi_gbl_FADT.dsdt) >+ ACPI_WARNING((AE_INFO, "32 bit DSDT and 64 bit DSDT not >match\n")); > > /* > * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved >fields which > ��.n��������+%������w��{.n�����{�����ܨ}���Ơz�j:+v�����w����ޙ��&�)ߡ�a����z�ޗ���ݢj��w�f