Eric, for your viewing pleasure, patches to arch/i386/kernel/process.c #define CONFIG_LINUXBIOS_PM #ifdef CONFIG_LINUXBIOS_PM #include <linux/pci.h> // reset for sis 503 void sis503_reset(struct pci_dev *dev) { unsigned char b; unsigned short acpi_base; printk(KERN_ERR __FUNCTION__ ": starting reset operation. \n"); /* Enable ACPI by set B7 on Reg 0x40, LPC */ pci_read_config_byte(dev, 0x40, &b); pci_write_config_byte(dev, 0x40, b | 0x80); printk(KERN_ERR __FUNCTION__ ": enabled ACPI. \n"); /* get the ACPI base address for register 0x74,0x75 of LPC */ pci_read_config_word(dev, 0x74, &acpi_base); printk(KERN_ERR __FUNCTION__ ":acpi base: %x\n", acpi_base); /* Set software watchdog timer init value */ outb(0x03, 0x4a + acpi_base); printk(KERN_ERR __FUNCTION__ ": set the dog. \n"); printk(KERN_ERR __FUNCTION__ ": enabling dog. \n"); /* Software watchdog enable, issue PCIRST# when time expire */ outb(0x8f, 0x4b + acpi_base); printk(KERN_ERR __FUNCTION__ ": We should reset soon. \n"); } // power off for sis 503 void sis503_off(struct pci_dev *dev) { unsigned char b; unsigned short acpi_base; printk(KERN_ERR __FUNCTION__ ": starting reset operation. \n"); /* Enable ACPI by set B7 on Reg 0x40, LPC */ pci_read_config_byte(dev, 0x40, &b); pci_write_config_byte(dev, 0x40, b | 0x80); printk(KERN_ERR __FUNCTION__ ": enabled ACPI. \n"); /* get the ACPI base address for register 0x74,0x75 of LPC */ pci_read_config_word(dev, 0x74, &acpi_base); printk (KERN_ERR __FUNCTION__ ":acpi base: %x\n", acpi_base); /* ACPI Register 5, Bit 10-12, Sleeping Type, set to 101 -> S5, soft_off */ outb(0x14, 0x05 + acpi_base); printk(KERN_ERR __FUNCTION__ ": DONE setting sleep type. \n"); /* ACPI Register 5, Bit 13, Sleep Enable */ outb(0x20 | 0x14, 0x05 + acpi_base); printk(KERN_ERR __FUNCTION__ ": DONE sleep enable. \n"); } struct linuxbios_control { u_short vendor, device; void (*poweroff)(struct pci_dev *); void (*reset)(struct pci_dev *); }; struct linuxbios_control controls[] = { {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, sis503_off, sis503_reset} }; // for the machine we're on, find the reset/power off control stuff. struct linuxbios_control *findcontrol(struct pci_dev **d) { struct linuxbios_control *lb = controls, *retval = 0; int i; printk(KERN_ERR __FUNCTION__ ": Find vendor 0x%x device 0x%x\n", lb->vendor, lb->device); for(lb = controls, i = 0; (i < sizeof(controls)/sizeof(controls[0])) && (! retval); i++, lb++) { *d = pci_find_device(lb->vendor, lb->device, 0); if (*d) retval = lb; } printk(KERN_ERR __FUNCTION__ ": result of find is %p\n", retval); return retval; } // power off in the linuxbios world void linuxbios_poweroff(void) { struct linuxbios_control *lb = 0; struct pci_dev *dev; printk(KERN_ERR __FUNCTION__ ": find an lb\n"); lb = findcontrol(&dev); printk(KERN_ERR __FUNCTION__ ": found lb %p, call %p\n", lb, lb ? lb->poweroff : 0); if (lb && (lb->poweroff)) lb->poweroff(dev); printk(KERN_ERR __FUNCTION__ ": Returning? Can't happen, I thought?\n"); } // reset in the linuxbios world void linuxbios_reset(void) { struct linuxbios_control *lb = 0; struct pci_dev *dev; printk(KERN_ERR __FUNCTION__ ": find an lb\n"); lb = findcontrol(&dev); printk(KERN_ERR __FUNCTION__ ": found lb %p, call %p\n", lb, lb ? lb->reset : 0); if (lb && (lb->reset)) lb->reset(dev); printk(KERN_ERR __FUNCTION__ ": Returning? Can't happen, I thought?\n"); } #endif // modified for the linuxbios power off stuff. void machine_power_off(void) { printk("MACHINE_POWER_OFF\n"); #ifdef CONFIG_LINUXBIOS_PM linuxbios_poweroff(); #endif if (pm_power_off) pm_power_off(); }