|
@@ -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);
|