summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/IPMI.txt13
-rw-r--r--drivers/char/ipmi/ipmi_poweroff.c132
-rw-r--r--include/linux/sysctl.h6
3 files changed, 71 insertions, 80 deletions
diff --git a/Documentation/IPMI.txt b/Documentation/IPMI.txt
index 84d3d4d10c17..bf1cf98d2a27 100644
--- a/Documentation/IPMI.txt
+++ b/Documentation/IPMI.txt
@@ -605,12 +605,13 @@ is in the ipmi_poweroff module. When the system requests a powerdown,
it will send the proper IPMI commands to do this. This is supported on
several platforms.
-There is a module parameter named "poweroff_control" that may either be zero
-(do a power down) or 2 (do a power cycle, power the system off, then power
-it on in a few seconds). Setting ipmi_poweroff.poweroff_control=x will do
-the same thing on the kernel command line. The parameter is also available
-via the proc filesystem in /proc/ipmi/poweroff_control. Note that if the
-system does not support power cycling, it will always to the power off.
+There is a module parameter named "poweroff_powercycle" that may
+either be zero (do a power down) or non-zero (do a power cycle, power
+the system off, then power it on in a few seconds). Setting
+ipmi_poweroff.poweroff_control=x will do the same thing on the kernel
+command line. The parameter is also available via the proc filesystem
+in /proc/sys/dev/ipmi/poweroff_powercycle. Note that if the system
+does not support power cycling, it will always do the power off.
Note that if you have ACPI enabled, the system will prefer using ACPI to
power off.
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c
index 42ea9843b394..e82a96ba396b 100644
--- a/drivers/char/ipmi/ipmi_poweroff.c
+++ b/drivers/char/ipmi/ipmi_poweroff.c
@@ -52,11 +52,11 @@ extern void (*pm_power_off)(void);
#define IPMI_CHASSIS_POWER_CYCLE 0x02 /* power cycle */
/* the IPMI data command */
-static int poweroff_control = IPMI_CHASSIS_POWER_DOWN;
+static int poweroff_powercycle;
/* parameter definition to allow user to flag power cycle */
-module_param(poweroff_control, int, IPMI_CHASSIS_POWER_DOWN);
-MODULE_PARM_DESC(poweroff_control, " Set to 2 to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down.");
+module_param(poweroff_powercycle, int, 0);
+MODULE_PARM_DESC(poweroff_powercycles, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down.");
/* Stuff from the get device id command. */
static unsigned int mfg_id;
@@ -385,37 +385,34 @@ static void ipmi_poweroff_chassis (ipmi_user_t user)
powercyclefailed:
printk(KERN_INFO PFX "Powering %s via IPMI chassis control command\n",
- ((poweroff_control != IPMI_CHASSIS_POWER_CYCLE) ? "down" : "cycle"));
+ (poweroff_powercycle ? "cycle" : "down"));
/*
* Power down
*/
send_msg.netfn = IPMI_NETFN_CHASSIS_REQUEST;
send_msg.cmd = IPMI_CHASSIS_CONTROL_CMD;
- data[0] = poweroff_control;
+ if (poweroff_powercycle)
+ data[0] = IPMI_CHASSIS_POWER_CYCLE;
+ else
+ data[0] = IPMI_CHASSIS_POWER_DOWN;
send_msg.data = data;
send_msg.data_len = sizeof(data);
rv = ipmi_request_in_rc_mode(user,
(struct ipmi_addr *) &smi_addr,
&send_msg);
if (rv) {
- switch (poweroff_control) {
- case IPMI_CHASSIS_POWER_CYCLE:
- /* power cycle failed, default to power down */
- printk(KERN_ERR PFX "Unable to send chassis power " \
- "cycle message, IPMI error 0x%x\n", rv);
- poweroff_control = IPMI_CHASSIS_POWER_DOWN;
- goto powercyclefailed;
-
- case IPMI_CHASSIS_POWER_DOWN:
- default:
- printk(KERN_ERR PFX "Unable to send chassis power " \
- "down message, IPMI error 0x%x\n", rv);
- break;
+ if (poweroff_powercycle) {
+ /* power cycle failed, default to power down */
+ printk(KERN_ERR PFX "Unable to send chassis power " \
+ "cycle message, IPMI error 0x%x\n", rv);
+ poweroff_powercycle = 0;
+ goto powercyclefailed;
}
- }
- return;
+ printk(KERN_ERR PFX "Unable to send chassis power " \
+ "down message, IPMI error 0x%x\n", rv);
+ }
}
@@ -561,39 +558,35 @@ static struct ipmi_smi_watcher smi_watcher =
#ifdef CONFIG_PROC_FS
-/* displays properties to proc */
-static int proc_read_chassctrl(char *page, char **start, off_t off, int count,
- int *eof, void *data)
-{
- return sprintf(page, "%d\t[ 0=powerdown 2=powercycle ]\n",
- poweroff_control);
-}
+#include <linux/sysctl.h>
+
+static ctl_table ipmi_table[] = {
+ { .ctl_name = DEV_IPMI_POWEROFF_POWERCYCLE,
+ .procname = "poweroff_powercycle",
+ .data = &poweroff_powercycle,
+ .maxlen = sizeof(poweroff_powercycle),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec },
+ { }
+};
-/* process property writes from proc */
-static int proc_write_chassctrl(struct file *file, const char *buffer,
- unsigned long count, void *data)
-{
- int rv = count;
- unsigned int newval = 0;
-
- sscanf(buffer, "%d", &newval);
- switch (newval) {
- case IPMI_CHASSIS_POWER_CYCLE:
- printk(KERN_INFO PFX "power cycle is now enabled\n");
- poweroff_control = newval;
- break;
-
- case IPMI_CHASSIS_POWER_DOWN:
- poweroff_control = IPMI_CHASSIS_POWER_DOWN;
- break;
-
- default:
- rv = -EINVAL;
- break;
- }
+static ctl_table ipmi_dir_table[] = {
+ { .ctl_name = DEV_IPMI,
+ .procname = "ipmi",
+ .mode = 0555,
+ .child = ipmi_table },
+ { }
+};
- return rv;
-}
+static ctl_table ipmi_root_table[] = {
+ { .ctl_name = CTL_DEV,
+ .procname = "dev",
+ .mode = 0555,
+ .child = ipmi_dir_table },
+ { }
+};
+
+static struct ctl_table_header *ipmi_table_header;
#endif /* CONFIG_PROC_FS */
/*
@@ -601,41 +594,32 @@ static int proc_write_chassctrl(struct file *file, const char *buffer,
*/
static int ipmi_poweroff_init (void)
{
- int rv;
- struct proc_dir_entry *file;
+ int rv;
printk ("Copyright (C) 2004 MontaVista Software -"
" IPMI Powerdown via sys_reboot.\n");
- switch (poweroff_control) {
- case IPMI_CHASSIS_POWER_CYCLE:
- printk(KERN_INFO PFX "Power cycle is enabled.\n");
- break;
+ if (poweroff_powercycle)
+ printk(KERN_INFO PFX "Power cycle is enabled.\n");
- case IPMI_CHASSIS_POWER_DOWN:
- default:
- poweroff_control = IPMI_CHASSIS_POWER_DOWN;
- break;
+#ifdef CONFIG_PROC_FS
+ ipmi_table_header = register_sysctl_table(ipmi_root_table, 1);
+ if (!ipmi_table_header) {
+ printk(KERN_ERR PFX "Unable to register powercycle sysctl\n");
+ rv = -ENOMEM;
+ goto out_err;
}
+#endif
+#ifdef CONFIG_PROC_FS
rv = ipmi_smi_watcher_register(&smi_watcher);
+#endif
if (rv) {
+ unregister_sysctl_table(ipmi_table_header);
printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv);
goto out_err;
}
-#ifdef CONFIG_PROC_FS
- file = create_proc_entry("poweroff_control", 0, proc_ipmi_root);
- if (!file) {
- printk(KERN_ERR PFX "Unable to create proc power control\n");
- } else {
- file->nlink = 1;
- file->read_proc = proc_read_chassctrl;
- file->write_proc = proc_write_chassctrl;
- file->owner = THIS_MODULE;
- }
-#endif
-
out_err:
return rv;
}
@@ -646,7 +630,7 @@ static __exit void ipmi_poweroff_cleanup(void)
int rv;
#ifdef CONFIG_PROC_FS
- remove_proc_entry("poweroff_control", proc_ipmi_root);
+ unregister_sysctl_table(ipmi_table_header);
#endif
ipmi_smi_watcher_unregister(&smi_watcher);
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index e82be96d4906..532a6c5c24e9 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -711,6 +711,7 @@ enum {
DEV_RAID=4,
DEV_MAC_HID=5,
DEV_SCSI=6,
+ DEV_IPMI=7,
};
/* /proc/sys/dev/cdrom */
@@ -776,6 +777,11 @@ enum {
DEV_SCSI_LOGGING_LEVEL=1,
};
+/* /proc/sys/dev/ipmi */
+enum {
+ DEV_IPMI_POWEROFF_POWERCYCLE=1,
+};
+
/* /proc/sys/abi */
enum
{