Commit 965c7eca authored by Ingo Molnar's avatar Ingo Molnar

x86: remove the Voyager 32-bit subarch

Impact: remove unused/broken code

The Voyager subarch last built successfully on the v2.6.26 kernel
and has been stale since then and does not build on the v2.6.27,
v2.6.28 and v2.6.29-rc5 kernels.

No actual users beyond the maintainer reported this breakage.
Patches were sent and most of the fixes were accepted but the
discussion around how to do a few remaining issues cleanly
fizzled out with no resolution and the code remained broken.

In the v2.6.30 x86 tree development cycle 32-bit subarch support
has been reworked and removed - and the Voyager code, beyond the
build problems already known, needs serious and significant
changes and probably a rewrite to support it.

CONFIG_X86_VOYAGER has been marked BROKEN then. The maintainer has
been notified but no patches have been sent so far to fix it.

While all other subarchs have been converted to the new scheme,
voyager is still broken. We'd prefer to receive patches which
clean up the current situation in a constructive way, but even in
case of removal there is no obstacle to add that support back
after the issues have been sorted out in a mutually acceptable
fashion.

So remove this inactive code for now.
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 8425091f
......@@ -302,7 +302,6 @@ config X86_EXTENDED_PLATFORM
SGI 320/540 (Visual Workstation)
Summit/EXA (IBM x440)
Unisys ES7000 IA32 series
Voyager (NCR)
If you have one of these systems, or if you want to build a
generic distribution kernel, say Y here - otherwise say N.
......@@ -423,19 +422,6 @@ config X86_ES7000
Support for Unisys ES7000 systems. Say 'Y' here if this kernel is
supposed to run on an IA32-based Unisys ES7000 system.
config X86_VOYAGER
bool "Voyager (NCR)"
depends on SMP && !PCI && BROKEN
depends on X86_32_NON_STANDARD
---help---
Voyager is an MCA-based 32-way capable SMP architecture proprietary
to NCR Corp. Machine classes 345x/35xx/4100/51xx are Voyager-based.
*** WARNING ***
If you do not specifically know you have a Voyager based machine,
say N here, otherwise the kernel you build will not be bootable.
config SCHED_OMIT_FRAME_POINTER
def_bool y
prompt "Single-depth WCHAN output"
......
......@@ -32,7 +32,6 @@ setup-y += a20.o cmdline.o copy.o cpu.o cpucheck.o edd.o
setup-y += header.o main.o mca.o memory.o pm.o pmjump.o
setup-y += printf.o string.o tty.o video.o video-mode.o version.o
setup-$(CONFIG_X86_APM_BOOT) += apm.o
setup-$(CONFIG_X86_VOYAGER) += voyager.o
# The link order of the video-*.o modules can matter. In particular,
# video-vga.o *must* be listed first, followed by video-vesa.o.
......
......@@ -126,11 +126,6 @@ static void enable_a20_fast(void)
int enable_a20(void)
{
#ifdef CONFIG_X86_VOYAGER
/* On Voyager, a20_test() is unsafe? */
enable_a20_kbc();
return 0;
#else
int loops = A20_ENABLE_LOOPS;
int kbc_err;
......@@ -164,5 +159,4 @@ int enable_a20(void)
}
return -1;
#endif
}
......@@ -302,9 +302,6 @@ void probe_cards(int unsafe);
/* video-vesa.c */
void vesa_store_edid(void);
/* voyager.c */
int query_voyager(void);
#endif /* __ASSEMBLY__ */
#endif /* BOOT_BOOT_H */
......@@ -149,11 +149,6 @@ void main(void)
/* Query MCA information */
query_mca();
/* Voyager */
#ifdef CONFIG_X86_VOYAGER
query_voyager();
#endif
/* Query Intel SpeedStep (IST) information */
query_ist();
......
/* -*- linux-c -*- ------------------------------------------------------- *
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
*
* ----------------------------------------------------------------------- */
/*
* Get the Voyager config information
*/
#include "boot.h"
int query_voyager(void)
{
u8 err;
u16 es, di;
/* Abuse the apm_bios_info area for this */
u8 *data_ptr = (u8 *)&boot_params.apm_bios_info;
data_ptr[0] = 0xff; /* Flag on config not found(?) */
asm("pushw %%es ; "
"int $0x15 ; "
"setc %0 ; "
"movw %%es, %1 ; "
"popw %%es"
: "=q" (err), "=r" (es), "=D" (di)
: "a" (0xffc0));
if (err)
return -1; /* Not Voyager */
set_fs(es);
copy_from_fs(data_ptr, di, 7); /* Table is 7 bytes apparently */
return 0;
}
......@@ -197,7 +197,6 @@ CONFIG_SPARSE_IRQ=y
CONFIG_X86_FIND_SMP_CONFIG=y
CONFIG_X86_MPPARSE=y
# CONFIG_X86_ELAN is not set
# CONFIG_X86_VOYAGER is not set
# CONFIG_X86_GENERICARCH is not set
# CONFIG_X86_VSMP is not set
# CONFIG_X86_RDC321X is not set
......
......@@ -199,7 +199,6 @@ CONFIG_SPARSE_IRQ=y
CONFIG_X86_FIND_SMP_CONFIG=y
CONFIG_X86_MPPARSE=y
# CONFIG_X86_ELAN is not set
# CONFIG_X86_VOYAGER is not set
# CONFIG_X86_GENERICARCH is not set
# CONFIG_X86_VSMP is not set
CONFIG_SCHED_OMIT_FRAME_POINTER=y
......
/* defines for inline arch setup functions */
#include <linux/clockchips.h>
#include <asm/voyager.h>
#include <asm/i8253.h>
/**
* do_timer_interrupt_hook - hook into timer tick
*
* Call the pit clock event handler. see asm/i8253.h
**/
static inline void do_timer_interrupt_hook(void)
{
global_clock_event->event_handler(global_clock_event);
voyager_timer_interrupt();
}
/* -*- mode: c; c-basic-offset: 8 -*- */
/* Copyright (C) 2002
*
* Author: James.Bottomley@HansenPartnership.com
*
* linux/arch/i386/voyager/entry_arch.h
*
* This file builds the VIC and QIC CPI gates
*/
/* initialise the voyager interrupt gates
*
* This uses the macros in irq.h to set up assembly jump gates. The
* calls are then redirected to the same routine with smp_ prefixed */
BUILD_INTERRUPT(vic_sys_interrupt, VIC_SYS_INT)
BUILD_INTERRUPT(vic_cmn_interrupt, VIC_CMN_INT)
BUILD_INTERRUPT(vic_cpi_interrupt, VIC_CPI_LEVEL0);
/* do all the QIC interrupts */
BUILD_INTERRUPT(qic_timer_interrupt, QIC_TIMER_CPI);
BUILD_INTERRUPT(qic_invalidate_interrupt, QIC_INVALIDATE_CPI);
BUILD_INTERRUPT(qic_reschedule_interrupt, QIC_RESCHEDULE_CPI);
BUILD_INTERRUPT(qic_enable_irq_interrupt, QIC_ENABLE_IRQ_CPI);
BUILD_INTERRUPT(qic_call_function_interrupt, QIC_CALL_FUNCTION_CPI);
BUILD_INTERRUPT(qic_call_function_single_interrupt, QIC_CALL_FUNCTION_SINGLE_CPI);
#include <asm/voyager.h>
#include <asm/setup.h>
#define VOYAGER_BIOS_INFO ((struct voyager_bios_info *) \
(&boot_params.apm_bios_info))
/* Hook to call BIOS initialisation function */
/* for voyager, pass the voyager BIOS/SUS info area to the detection
* routines */
#define ARCH_SETUP voyager_detect(VOYAGER_BIOS_INFO);
/* Copyright (C) 1999,2001
*
* Author: J.E.J.Bottomley@HansenPartnership.com
*
* Standard include definitions for the NCR Voyager Interrupt Controller */
/* The eight CPI vectors. To activate a CPI, you write a bit mask
* corresponding to the processor set to be interrupted into the
* relevant register. That set of CPUs will then be interrupted with
* the CPI */
static const int VIC_CPI_Registers[] =
{0xFC00, 0xFC01, 0xFC08, 0xFC09,
0xFC10, 0xFC11, 0xFC18, 0xFC19 };
#define VIC_PROC_WHO_AM_I 0xfc29
# define QUAD_IDENTIFIER 0xC0
# define EIGHT_SLOT_IDENTIFIER 0xE0
#define QIC_EXTENDED_PROCESSOR_SELECT 0xFC72
#define VIC_CPI_BASE_REGISTER 0xFC41
#define VIC_PROCESSOR_ID 0xFC21
# define VIC_CPU_MASQUERADE_ENABLE 0x8
#define VIC_CLAIM_REGISTER_0 0xFC38
#define VIC_CLAIM_REGISTER_1 0xFC39
#define VIC_REDIRECT_REGISTER_0 0xFC60
#define VIC_REDIRECT_REGISTER_1 0xFC61
#define VIC_PRIORITY_REGISTER 0xFC20
#define VIC_PRIMARY_MC_BASE 0xFC48
#define VIC_SECONDARY_MC_BASE 0xFC49
#define QIC_PROCESSOR_ID 0xFC71
# define QIC_CPUID_ENABLE 0x08
#define QIC_VIC_CPI_BASE_REGISTER 0xFC79
#define QIC_CPI_BASE_REGISTER 0xFC7A
#define QIC_MASK_REGISTER0 0xFC80
/* NOTE: these are masked high, enabled low */
# define QIC_PERF_TIMER 0x01
# define QIC_LPE 0x02
# define QIC_SYS_INT 0x04
# define QIC_CMN_INT 0x08
/* at the moment, just enable CMN_INT, disable SYS_INT */
# define QIC_DEFAULT_MASK0 (~(QIC_CMN_INT /* | VIC_SYS_INT */))
#define QIC_MASK_REGISTER1 0xFC81
# define QIC_BOOT_CPI_MASK 0xFE
/* Enable CPI's 1-6 inclusive */
# define QIC_CPI_ENABLE 0x81
#define QIC_INTERRUPT_CLEAR0 0xFC8A
#define QIC_INTERRUPT_CLEAR1 0xFC8B
/* this is where we place the CPI vectors */
#define VIC_DEFAULT_CPI_BASE 0xC0
/* this is where we place the QIC CPI vectors */
#define QIC_DEFAULT_CPI_BASE 0xD0
#define VIC_BOOT_INTERRUPT_MASK 0xfe
extern void smp_vic_timer_interrupt(void);
This diff is collapsed.
......@@ -3,7 +3,6 @@ config LGUEST_GUEST
select PARAVIRT
depends on X86_32
depends on !X86_PAE
depends on !X86_VOYAGER
select VIRTIO
select VIRTIO_RING
select VIRTIO_CONSOLE
......
#
# Makefile for the linux kernel.
#
EXTRA_CFLAGS := -Iarch/x86/kernel
obj-y := setup.o voyager_basic.o voyager_thread.o
obj-$(CONFIG_SMP) += voyager_smp.o voyager_cat.o
/*
* Machine specific setup for generic
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <asm/arch_hooks.h>
#include <asm/voyager.h>
#include <asm/e820.h>
#include <asm/io.h>
#include <asm/setup.h>
#include <asm/cpu.h>
void __init pre_intr_init_hook(void)
{
init_ISA_irqs();
}
/*
* IRQ2 is cascade interrupt to second interrupt controller
*/
static struct irqaction irq2 = {
.handler = no_action,
.mask = CPU_MASK_NONE,
.name = "cascade",
};
void __init intr_init_hook(void)
{
#ifdef CONFIG_SMP
voyager_smp_intr_init();
#endif
setup_irq(2, &irq2);
}
static void voyager_disable_tsc(void)
{
/* Voyagers run their CPUs from independent clocks, so disable
* the TSC code because we can't sync them */
setup_clear_cpu_cap(X86_FEATURE_TSC);
}
void __init pre_setup_arch_hook(void)
{
voyager_disable_tsc();
}
void __init pre_time_init_hook(void)
{
voyager_disable_tsc();
}
void __init trap_init_hook(void)
{
}
static struct irqaction irq0 = {
.handler = timer_interrupt,
.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
.mask = CPU_MASK_NONE,
.name = "timer"
};
void __init time_init_hook(void)
{
irq0.mask = cpumask_of_cpu(safe_smp_processor_id());
setup_irq(0, &irq0);
}
/* Hook for machine specific memory setup. */
char *__init machine_specific_memory_setup(void)
{
char *who;
int new_nr;
who = "NOT VOYAGER";
if (voyager_level == 5) {
__u32 addr, length;
int i;
who = "Voyager-SUS";
e820.nr_map = 0;
for (i = 0; voyager_memory_detect(i, &addr, &length); i++) {
e820_add_region(addr, length, E820_RAM);
}
return who;
} else if (voyager_level == 4) {
__u32 tom;
__u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT) << 8;
/* select the DINO config space */
outb(VOYAGER_DINO, VOYAGER_CAT_CONFIG_PORT);
/* Read DINO top of memory register */
tom = ((inb(catbase + 0x4) & 0xf0) << 16)
+ ((inb(catbase + 0x5) & 0x7f) << 24);
if (inb(catbase) != VOYAGER_DINO) {
printk(KERN_ERR
"Voyager: Failed to get DINO for L4, setting tom to EXT_MEM_K\n");
tom = (boot_params.screen_info.ext_mem_k) << 10;
}
who = "Voyager-TOM";
e820_add_region(0, 0x9f000, E820_RAM);
/* map from 1M to top of memory */
e820_add_region(1 * 1024 * 1024, tom - 1 * 1024 * 1024,
E820_RAM);
/* FIXME: Should check the ASICs to see if I need to
* take out the 8M window. Just do it at the moment
* */
e820_add_region(8 * 1024 * 1024, 8 * 1024 * 1024,
E820_RESERVED);
return who;
}
return default_machine_specific_memory_setup();
}
/* Copyright (C) 1999,2001
*
* Author: J.E.J.Bottomley@HansenPartnership.com
*
* This file contains all the voyager specific routines for getting
* initialisation of the architecture to function. For additional
* features see:
*
* voyager_cat.c - Voyager CAT bus interface
* voyager_smp.c - Voyager SMP hal (emulates linux smp.c)
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/reboot.h>
#include <linux/sysrq.h>
#include <linux/smp.h>
#include <linux/nodemask.h>
#include <asm/io.h>
#include <asm/voyager.h>
#include <asm/vic.h>
#include <linux/pm.h>
#include <asm/tlbflush.h>
#include <asm/arch_hooks.h>
#include <asm/i8253.h>
/*
* Power off function, if any
*/
void (*pm_power_off) (void);
EXPORT_SYMBOL(pm_power_off);
int voyager_level = 0;
struct voyager_SUS *voyager_SUS = NULL;
#ifdef CONFIG_SMP
static void voyager_dump(int dummy1, struct tty_struct *dummy3)
{
/* get here via a sysrq */
voyager_smp_dump();
}
static struct sysrq_key_op sysrq_voyager_dump_op = {
.handler = voyager_dump,
.help_msg = "Voyager",
.action_msg = "Dump Voyager Status",
};
#endif
void voyager_detect(struct voyager_bios_info *bios)
{
if (bios->len != 0xff) {
int class = (bios->class_1 << 8)
| (bios->class_2 & 0xff);
printk("Voyager System detected.\n"
" Class %x, Revision %d.%d\n",
class, bios->major, bios->minor);
if (class == VOYAGER_LEVEL4)
voyager_level = 4;
else if (class < VOYAGER_LEVEL5_AND_ABOVE)
voyager_level = 3;
else
voyager_level = 5;
printk(" Architecture Level %d\n", voyager_level);
if (voyager_level < 4)
printk
("\n**WARNING**: Voyager HAL only supports Levels 4 and 5 Architectures at the moment\n\n");
/* install the power off handler */
pm_power_off = voyager_power_off;
#ifdef CONFIG_SMP
register_sysrq_key('v', &sysrq_voyager_dump_op);
#endif
} else {
printk("\n\n**WARNING**: No Voyager Subsystem Found\n");
}
}
void voyager_system_interrupt(int cpl, void *dev_id)
{
printk("Voyager: detected system interrupt\n");
}
/* Routine to read information from the extended CMOS area */
__u8 voyager_extended_cmos_read(__u16 addr)
{
outb(addr & 0xff, 0x74);
outb((addr >> 8) & 0xff, 0x75);
return inb(0x76);
}
/* internal definitions for the SUS Click Map of memory */
#define CLICK_ENTRIES 16
#define CLICK_SIZE 4096 /* click to byte conversion for Length */
typedef struct ClickMap {
struct Entry {
__u32 Address;
__u32 Length;
} Entry[CLICK_ENTRIES];
} ClickMap_t;
/* This routine is pretty much an awful hack to read the bios clickmap by
* mapping it into page 0. There are usually three regions in the map:
* Base Memory
* Extended Memory
* zero length marker for end of map
*
* Returns are 0 for failure and 1 for success on extracting region.
*/
int __init voyager_memory_detect(int region, __u32 * start, __u32 * length)
{
int i;
int retval = 0;
__u8 cmos[4];
ClickMap_t *map;
unsigned long map_addr;
unsigned long old;
if (region >= CLICK_ENTRIES) {
printk("Voyager: Illegal ClickMap region %d\n", region);
return 0;
}
for (i = 0; i < sizeof(cmos); i++)
cmos[i] =
voyager_extended_cmos_read(VOYAGER_MEMORY_CLICKMAP + i);
map_addr = *(unsigned long *)cmos;
/* steal page 0 for this */
old = pg0[0];
pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
local_flush_tlb();
/* now clear everything out but page 0 */
map = (ClickMap_t *) (map_addr & (~PAGE_MASK));
/* zero length is the end of the clickmap */
if (map->Entry[region].Length != 0) {
*length = map->Entry[region].Length * CLICK_SIZE;
*start = map->Entry[region].Address;
retval = 1;
}
/* replace the mapping */
pg0[0] = old;
local_flush_tlb();
return retval;
}
/* voyager specific handling code for timer interrupts. Used to hand
* off the timer tick to the SMP code, since the VIC doesn't have an
* internal timer (The QIC does, but that's another story). */
void voyager_timer_interrupt(void)
{
if ((jiffies & 0x3ff) == 0) {
/* There seems to be something flaky in either
* hardware or software that is resetting the timer 0
* count to something much higher than it should be
* This seems to occur in the boot sequence, just
* before root is mounted. Therefore, every 10
* seconds or so, we sanity check the timer zero count
* and kick it back to where it should be.
*
* FIXME: This is the most awful hack yet seen. I
* should work out exactly what is interfering with
* the timer count settings early in the boot sequence
* and swiftly introduce it to something sharp and
* pointy. */
__u16 val;
spin_lock(&i8253_lock);
outb_p(0x00, 0x43);
val = inb_p(0x40);
val |= inb(0x40) << 8;
spin_unlock(&i8253_lock);
if (val > LATCH) {
printk
("\nVOYAGER: countdown timer value too high (%d), resetting\n\n",
val);
spin_lock(&i8253_lock);
outb(0x34, 0x43);
outb_p(LATCH & 0xff, 0x40); /* LSB */
outb(LATCH >> 8, 0x40); /* MSB */
spin_unlock(&i8253_lock);
}
}
#ifdef CONFIG_SMP
smp_vic_timer_interrupt();
#endif
}
void voyager_power_off(void)
{
printk("VOYAGER Power Off\n");
if (voyager_level == 5) {
voyager_cat_power_off();
} else if (voyager_level == 4) {
/* This doesn't apparently work on most L4 machines,
* but the specs say to do this to get automatic power
* off. Unfortunately, if it doesn't power off the
* machine, it ends up doing a cold restart, which
* isn't really intended, so comment out the code */
#if 0
int port;
/* enable the voyager Configuration Space */
outb((inb(VOYAGER_MC_SETUP) & 0xf0) | 0x8, VOYAGER_MC_SETUP);
/* the port for the power off flag is an offset from the
floating base */
port = (inb(VOYAGER_SSPB_RELOCATION_PORT) << 8) + 0x21;
/* set the power off flag */
outb(inb(port) | 0x1, port);
#endif
}
/* and wait for it to happen */
local_irq_disable();
for (;;)
halt();
}
/* copied from process.c */
static inline void kb_wait(void)
{
int i;
for (i = 0; i < 0x10000; i++)
if ((inb_p(0x64) & 0x02) == 0)
break;
}
void machine_shutdown(void)
{
/* Architecture specific shutdown needed before a kexec */
}
void machine_restart(char *cmd)
{
printk("Voyager Warm Restart\n");
kb_wait();
if (voyager_level == 5) {
/* write magic values to the RTC to inform system that
* shutdown is beginning */
outb(0x8f, 0x70);
outb(0x5, 0x71);
udelay(50);
outb(0xfe, 0x64); /* pull reset low */
} else if (voyager_level == 4) {
__u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT) << 8;
__u8 basebd = inb(VOYAGER_MC_SETUP);
outb(basebd | 0x08, VOYAGER_MC_SETUP);
outb(0x02, catbase + 0x21);
}
local_irq_disable();
for (;;)
halt();
}
void machine_emergency_restart(void)
{
/*for now, just hook this to a warm restart */
machine_restart(NULL);
}
void mca_nmi_hook(void)
{
__u8 dumpval __maybe_unused = inb(0xf823);
__u8 swnmi __maybe_unused = inb(0xf813);
/* FIXME: assume dump switch pressed */
/* check to see if the dump switch was pressed */
VDEBUG(("VOYAGER: dumpval = 0x%x, swnmi = 0x%x\n", dumpval, swnmi));
/* clear swnmi */
outb(0xff, 0xf813);
/* tell SUS to ignore dump */
if (voyager_level == 5 && voyager_SUS != NULL) {
if (voyager_SUS->SUS_mbox == VOYAGER_DUMP_BUTTON_NMI) {
voyager_SUS->kernel_mbox = VOYAGER_NO_COMMAND;
voyager_SUS->kernel_flags |= VOYAGER_OS_IN_PROGRESS;
udelay(1000);
voyager_SUS->kernel_mbox = VOYAGER_IGNORE_DUMP;
voyager_SUS->kernel_flags &= ~VOYAGER_OS_IN_PROGRESS;
}
}
printk(KERN_ERR
"VOYAGER: Dump switch pressed, printing CPU%d tracebacks\n",
smp_processor_id());
show_stack(NULL, NULL);
show_state();
}
void machine_halt(void)
{
/* treat a halt like a power off */
machine_power_off();
}
void machine_power_off(void)
{
if (pm_power_off)
pm_power_off();
}
This diff is collapsed.
This diff is collapsed.
/* -*- mode: c; c-basic-offset: 8 -*- */
/* Copyright (C) 2001
*
* Author: J.E.J.Bottomley@HansenPartnership.com
*
* This module provides the machine status monitor thread for the
* voyager architecture. This allows us to monitor the machine
* environment (temp, voltage, fan function) and the front panel and
* internal UPS. If a fault is detected, this thread takes corrective
* action (usually just informing init)
* */
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/kernel_stat.h>
#include <linux/delay.h>
#include <linux/mc146818rtc.h>
#include <linux/init.h>
#include <linux/bootmem.h>
#include <linux/kmod.h>
#include <linux/completion.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <asm/desc.h>
#include <asm/voyager.h>
#include <asm/vic.h>
#include <asm/mtrr.h>
#include <asm/msr.h>
struct task_struct *voyager_thread;
static __u8 set_timeout;
static int execute(const char *string)
{
int ret;
char *envp[] = {
"HOME=/",
"TERM=linux",
"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
NULL,
};
char *argv[] = {
"/bin/bash",
"-c",
(char *)string,
NULL,
};
if ((ret =
call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC)) != 0) {
printk(KERN_ERR "Voyager failed to run \"%s\": %i\n", string,
ret);
}
return ret;
}
static void check_from_kernel(void)
{
if (voyager_status.switch_off) {
/* FIXME: This should be configurable via proc */
execute("umask 600; echo 0 > /etc/initrunlvl; kill -HUP 1");
} else if (voyager_status.power_fail) {
VDEBUG(("Voyager daemon detected AC power failure\n"));
/* FIXME: This should be configureable via proc */
execute("umask 600; echo F > /etc/powerstatus; kill -PWR 1");
set_timeout = 1;
}
}
static void check_continuing_condition(void)
{
if (voyager_status.power_fail) {
__u8 data;
voyager_cat_psi(VOYAGER_PSI_SUBREAD,
VOYAGER_PSI_AC_FAIL_REG, &data);
if ((data & 0x1f) == 0) {
/* all power restored */
printk(KERN_NOTICE
"VOYAGER AC power restored, cancelling shutdown\n");
/* FIXME: should be user configureable */
execute
("umask 600; echo O > /etc/powerstatus; kill -PWR 1");
set_timeout = 0;
}
}
}
static int thread(void *unused)
{
printk(KERN_NOTICE "Voyager starting monitor thread\n");
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(set_timeout ? HZ : MAX_SCHEDULE_TIMEOUT);
VDEBUG(("Voyager Daemon awoken\n"));
if (voyager_status.request_from_kernel == 0) {
/* probably awoken from timeout */
check_continuing_condition();
} else {
check_from_kernel();
voyager_status.request_from_kernel = 0;
}
}
}
static int __init voyager_thread_start(void)
{
voyager_thread = kthread_run(thread, NULL, "kvoyagerd");
if (IS_ERR(voyager_thread)) {
printk(KERN_ERR
"Voyager: Failed to create system monitor thread.\n");
return PTR_ERR(voyager_thread);
}
return 0;
}
static void __exit voyager_thread_stop(void)
{
kthread_stop(voyager_thread);
}
module_init(voyager_thread_start);
module_exit(voyager_thread_stop);
......@@ -6,7 +6,7 @@ config XEN
bool "Xen guest support"
select PARAVIRT
select PARAVIRT_CLOCK
depends on X86_64 || (X86_32 && X86_PAE && !(X86_VISWS || X86_VOYAGER))
depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS)
depends on X86_CMPXCHG && X86_TSC
help
This is the Linux Xen port. Enabling this will allow the
......
config LGUEST
tristate "Linux hypervisor example code"
depends on X86_32 && EXPERIMENTAL && !X86_PAE && FUTEX && !X86_VOYAGER
depends on X86_32 && EXPERIMENTAL && !X86_PAE && FUTEX
select HVC_DRIVER
---help---
This is a very simple module which allows you to run
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment