Merge branches 'x86-reboot-for-linus' and 'x86-setup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'x86-reboot-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86: Reorder reboot method preferences

* 'x86-setup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86, setup: Fix EDD3.0 data verification.
This commit is contained in:
Linus Torvalds 2011-05-19 18:09:45 -07:00
commit 08839ff827
2 changed files with 34 additions and 12 deletions

View File

@ -36,7 +36,7 @@ EXPORT_SYMBOL(pm_power_off);
static const struct desc_ptr no_idt = {}; static const struct desc_ptr no_idt = {};
static int reboot_mode; static int reboot_mode;
enum reboot_type reboot_type = BOOT_KBD; enum reboot_type reboot_type = BOOT_ACPI;
int reboot_force; int reboot_force;
#if defined(CONFIG_X86_32) && defined(CONFIG_SMP) #if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
@ -478,9 +478,24 @@ void __attribute__((weak)) mach_reboot_fixups(void)
{ {
} }
/*
* Windows compatible x86 hardware expects the following on reboot:
*
* 1) If the FADT has the ACPI reboot register flag set, try it
* 2) If still alive, write to the keyboard controller
* 3) If still alive, write to the ACPI reboot register again
* 4) If still alive, write to the keyboard controller again
*
* If the machine is still alive at this stage, it gives up. We default to
* following the same pattern, except that if we're still alive after (4) we'll
* try to force a triple fault and then cycle between hitting the keyboard
* controller and doing that
*/
static void native_machine_emergency_restart(void) static void native_machine_emergency_restart(void)
{ {
int i; int i;
int attempt = 0;
int orig_reboot_type = reboot_type;
if (reboot_emergency) if (reboot_emergency)
emergency_vmx_disable_all(); emergency_vmx_disable_all();
@ -502,6 +517,13 @@ static void native_machine_emergency_restart(void)
outb(0xfe, 0x64); /* pulse reset low */ outb(0xfe, 0x64); /* pulse reset low */
udelay(50); udelay(50);
} }
if (attempt == 0 && orig_reboot_type == BOOT_ACPI) {
attempt = 1;
reboot_type = BOOT_ACPI;
} else {
reboot_type = BOOT_TRIPLE;
}
break;
case BOOT_TRIPLE: case BOOT_TRIPLE:
load_idt(&no_idt); load_idt(&no_idt);

View File

@ -531,8 +531,8 @@ static int
edd_has_edd30(struct edd_device *edev) edd_has_edd30(struct edd_device *edev)
{ {
struct edd_info *info; struct edd_info *info;
int i, nonzero_path = 0; int i;
char c; u8 csum = 0;
if (!edev) if (!edev)
return 0; return 0;
@ -544,16 +544,16 @@ edd_has_edd30(struct edd_device *edev)
return 0; return 0;
} }
for (i = 30; i <= 73; i++) {
c = *(((uint8_t *) info) + i + 4); /* We support only T13 spec */
if (c) { if (info->params.device_path_info_length != 44)
nonzero_path++; return 0;
break;
} for (i = 30; i < info->params.device_path_info_length + 30; i++)
} csum += *(((u8 *)&info->params) + i);
if (!nonzero_path) {
if (csum)
return 0; return 0;
}
return 1; return 1;
} }