Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/char/ipmi/ipmi_poweroff.c
26282 views
1
// SPDX-License-Identifier: GPL-2.0+
2
/*
3
* ipmi_poweroff.c
4
*
5
* MontaVista IPMI Poweroff extension to sys_reboot
6
*
7
* Author: MontaVista Software, Inc.
8
* Steven Dake <[email protected]>
9
* Corey Minyard <[email protected]>
10
* [email protected]
11
*
12
* Copyright 2002,2004 MontaVista Software Inc.
13
*/
14
15
#define pr_fmt(fmt) "IPMI poweroff: " fmt
16
17
#include <linux/module.h>
18
#include <linux/moduleparam.h>
19
#include <linux/proc_fs.h>
20
#include <linux/string.h>
21
#include <linux/completion.h>
22
#include <linux/pm.h>
23
#include <linux/kdev_t.h>
24
#include <linux/ipmi.h>
25
#include <linux/ipmi_smi.h>
26
27
static void ipmi_po_smi_gone(int if_num);
28
static void ipmi_po_new_smi(int if_num, struct device *device);
29
30
/* Definitions for controlling power off (if the system supports it). It
31
* conveniently matches the IPMI chassis control values. */
32
#define IPMI_CHASSIS_POWER_DOWN 0 /* power down, the default. */
33
#define IPMI_CHASSIS_POWER_CYCLE 0x02 /* power cycle */
34
35
/* the IPMI data command */
36
static int poweroff_powercycle;
37
38
/* Which interface to use, -1 means the first we see. */
39
static int ifnum_to_use = -1;
40
41
/* Our local state. */
42
static int ready;
43
static struct ipmi_user *ipmi_user;
44
static int ipmi_ifnum;
45
static void (*specific_poweroff_func)(struct ipmi_user *user);
46
47
/* Holds the old poweroff function so we can restore it on removal. */
48
static void (*old_poweroff_func)(void);
49
50
static int set_param_ifnum(const char *val, const struct kernel_param *kp)
51
{
52
int rv = param_set_int(val, kp);
53
if (rv)
54
return rv;
55
if ((ifnum_to_use < 0) || (ifnum_to_use == ipmi_ifnum))
56
return 0;
57
58
ipmi_po_smi_gone(ipmi_ifnum);
59
ipmi_po_new_smi(ifnum_to_use, NULL);
60
return 0;
61
}
62
63
module_param_call(ifnum_to_use, set_param_ifnum, param_get_int,
64
&ifnum_to_use, 0644);
65
MODULE_PARM_DESC(ifnum_to_use, "The interface number to use for the watchdog "
66
"timer. Setting to -1 defaults to the first registered "
67
"interface");
68
69
/* parameter definition to allow user to flag power cycle */
70
module_param(poweroff_powercycle, int, 0644);
71
MODULE_PARM_DESC(poweroff_powercycle,
72
" Set to non-zero to enable power cycle instead of power"
73
" down. Power cycle is contingent on hardware support,"
74
" otherwise it defaults back to power down.");
75
76
/* Stuff from the get device id command. */
77
static unsigned int mfg_id;
78
static unsigned int prod_id;
79
static unsigned char capabilities;
80
static unsigned char ipmi_version;
81
82
/*
83
* We use our own messages for this operation, we don't let the system
84
* allocate them, since we may be in a panic situation. The whole
85
* thing is single-threaded, anyway, so multiple messages are not
86
* required.
87
*/
88
static atomic_t dummy_count = ATOMIC_INIT(0);
89
static void dummy_smi_free(struct ipmi_smi_msg *msg)
90
{
91
atomic_dec(&dummy_count);
92
}
93
static void dummy_recv_free(struct ipmi_recv_msg *msg)
94
{
95
atomic_dec(&dummy_count);
96
}
97
static struct ipmi_smi_msg halt_smi_msg = INIT_IPMI_SMI_MSG(dummy_smi_free);
98
static struct ipmi_recv_msg halt_recv_msg = INIT_IPMI_RECV_MSG(dummy_recv_free);
99
100
101
/*
102
* Code to send a message and wait for the response.
103
*/
104
105
static void receive_handler(struct ipmi_recv_msg *recv_msg, void *handler_data)
106
{
107
struct completion *comp = recv_msg->user_msg_data;
108
109
if (comp)
110
complete(comp);
111
}
112
113
static const struct ipmi_user_hndl ipmi_poweroff_handler = {
114
.ipmi_recv_hndl = receive_handler
115
};
116
117
118
static int ipmi_request_wait_for_response(struct ipmi_user *user,
119
struct ipmi_addr *addr,
120
struct kernel_ipmi_msg *send_msg)
121
{
122
int rv;
123
struct completion comp;
124
125
init_completion(&comp);
126
127
rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, &comp,
128
&halt_smi_msg, &halt_recv_msg, 0);
129
if (rv)
130
return rv;
131
132
wait_for_completion(&comp);
133
134
return halt_recv_msg.msg.data[0];
135
}
136
137
/* Wait for message to complete, spinning. */
138
static int ipmi_request_in_rc_mode(struct ipmi_user *user,
139
struct ipmi_addr *addr,
140
struct kernel_ipmi_msg *send_msg)
141
{
142
int rv;
143
144
atomic_set(&dummy_count, 2);
145
rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, NULL,
146
&halt_smi_msg, &halt_recv_msg, 0);
147
if (rv) {
148
atomic_set(&dummy_count, 0);
149
return rv;
150
}
151
152
/*
153
* Spin until our message is done.
154
*/
155
while (atomic_read(&dummy_count) > 0) {
156
ipmi_poll_interface(user);
157
cpu_relax();
158
}
159
160
return halt_recv_msg.msg.data[0];
161
}
162
163
/*
164
* ATCA Support
165
*/
166
167
#define IPMI_NETFN_ATCA 0x2c
168
#define IPMI_ATCA_SET_POWER_CMD 0x11
169
#define IPMI_ATCA_GET_ADDR_INFO_CMD 0x01
170
#define IPMI_PICMG_ID 0
171
172
#define IPMI_NETFN_OEM 0x2e
173
#define IPMI_ATCA_PPS_GRACEFUL_RESTART 0x11
174
#define IPMI_ATCA_PPS_IANA "\x00\x40\x0A"
175
#define IPMI_MOTOROLA_MANUFACTURER_ID 0x0000A1
176
#define IPMI_MOTOROLA_PPS_IPMC_PRODUCT_ID 0x0051
177
178
static void (*atca_oem_poweroff_hook)(struct ipmi_user *user);
179
180
static void pps_poweroff_atca(struct ipmi_user *user)
181
{
182
struct ipmi_system_interface_addr smi_addr;
183
struct kernel_ipmi_msg send_msg;
184
int rv;
185
/*
186
* Configure IPMI address for local access
187
*/
188
smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
189
smi_addr.channel = IPMI_BMC_CHANNEL;
190
smi_addr.lun = 0;
191
192
pr_info("PPS powerdown hook used\n");
193
194
send_msg.netfn = IPMI_NETFN_OEM;
195
send_msg.cmd = IPMI_ATCA_PPS_GRACEFUL_RESTART;
196
send_msg.data = IPMI_ATCA_PPS_IANA;
197
send_msg.data_len = 3;
198
rv = ipmi_request_in_rc_mode(user,
199
(struct ipmi_addr *) &smi_addr,
200
&send_msg);
201
if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE)
202
pr_err("Unable to send ATCA, IPMI error 0x%x\n", rv);
203
204
return;
205
}
206
207
static int ipmi_atca_detect(struct ipmi_user *user)
208
{
209
struct ipmi_system_interface_addr smi_addr;
210
struct kernel_ipmi_msg send_msg;
211
int rv;
212
unsigned char data[1];
213
214
/*
215
* Configure IPMI address for local access
216
*/
217
smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
218
smi_addr.channel = IPMI_BMC_CHANNEL;
219
smi_addr.lun = 0;
220
221
/*
222
* Use get address info to check and see if we are ATCA
223
*/
224
send_msg.netfn = IPMI_NETFN_ATCA;
225
send_msg.cmd = IPMI_ATCA_GET_ADDR_INFO_CMD;
226
data[0] = IPMI_PICMG_ID;
227
send_msg.data = data;
228
send_msg.data_len = sizeof(data);
229
rv = ipmi_request_wait_for_response(user,
230
(struct ipmi_addr *) &smi_addr,
231
&send_msg);
232
233
pr_info("ATCA Detect mfg 0x%X prod 0x%X\n", mfg_id, prod_id);
234
if ((mfg_id == IPMI_MOTOROLA_MANUFACTURER_ID)
235
&& (prod_id == IPMI_MOTOROLA_PPS_IPMC_PRODUCT_ID)) {
236
pr_info("Installing Pigeon Point Systems Poweroff Hook\n");
237
atca_oem_poweroff_hook = pps_poweroff_atca;
238
}
239
return !rv;
240
}
241
242
static void ipmi_poweroff_atca(struct ipmi_user *user)
243
{
244
struct ipmi_system_interface_addr smi_addr;
245
struct kernel_ipmi_msg send_msg;
246
int rv;
247
unsigned char data[4];
248
249
/*
250
* Configure IPMI address for local access
251
*/
252
smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
253
smi_addr.channel = IPMI_BMC_CHANNEL;
254
smi_addr.lun = 0;
255
256
pr_info("Powering down via ATCA power command\n");
257
258
/*
259
* Power down
260
*/
261
send_msg.netfn = IPMI_NETFN_ATCA;
262
send_msg.cmd = IPMI_ATCA_SET_POWER_CMD;
263
data[0] = IPMI_PICMG_ID;
264
data[1] = 0; /* FRU id */
265
data[2] = 0; /* Power Level */
266
data[3] = 0; /* Don't change saved presets */
267
send_msg.data = data;
268
send_msg.data_len = sizeof(data);
269
rv = ipmi_request_in_rc_mode(user,
270
(struct ipmi_addr *) &smi_addr,
271
&send_msg);
272
/*
273
* At this point, the system may be shutting down, and most
274
* serial drivers (if used) will have interrupts turned off
275
* it may be better to ignore IPMI_UNKNOWN_ERR_COMPLETION_CODE
276
* return code
277
*/
278
if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE) {
279
pr_err("Unable to send ATCA powerdown message, IPMI error 0x%x\n",
280
rv);
281
goto out;
282
}
283
284
if (atca_oem_poweroff_hook)
285
atca_oem_poweroff_hook(user);
286
out:
287
return;
288
}
289
290
/*
291
* CPI1 Support
292
*/
293
294
#define IPMI_NETFN_OEM_1 0xf8
295
#define OEM_GRP_CMD_SET_RESET_STATE 0x84
296
#define OEM_GRP_CMD_SET_POWER_STATE 0x82
297
#define IPMI_NETFN_OEM_8 0xf8
298
#define OEM_GRP_CMD_REQUEST_HOTSWAP_CTRL 0x80
299
#define OEM_GRP_CMD_GET_SLOT_GA 0xa3
300
#define IPMI_NETFN_SENSOR_EVT 0x10
301
#define IPMI_CMD_GET_EVENT_RECEIVER 0x01
302
303
#define IPMI_CPI1_PRODUCT_ID 0x000157
304
#define IPMI_CPI1_MANUFACTURER_ID 0x0108
305
306
static int ipmi_cpi1_detect(struct ipmi_user *user)
307
{
308
return ((mfg_id == IPMI_CPI1_MANUFACTURER_ID)
309
&& (prod_id == IPMI_CPI1_PRODUCT_ID));
310
}
311
312
static void ipmi_poweroff_cpi1(struct ipmi_user *user)
313
{
314
struct ipmi_system_interface_addr smi_addr;
315
struct ipmi_ipmb_addr ipmb_addr;
316
struct kernel_ipmi_msg send_msg;
317
int rv;
318
unsigned char data[1];
319
int slot;
320
unsigned char hotswap_ipmb;
321
unsigned char aer_addr;
322
unsigned char aer_lun;
323
324
/*
325
* Configure IPMI address for local access
326
*/
327
smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
328
smi_addr.channel = IPMI_BMC_CHANNEL;
329
smi_addr.lun = 0;
330
331
pr_info("Powering down via CPI1 power command\n");
332
333
/*
334
* Get IPMI ipmb address
335
*/
336
send_msg.netfn = IPMI_NETFN_OEM_8 >> 2;
337
send_msg.cmd = OEM_GRP_CMD_GET_SLOT_GA;
338
send_msg.data = NULL;
339
send_msg.data_len = 0;
340
rv = ipmi_request_in_rc_mode(user,
341
(struct ipmi_addr *) &smi_addr,
342
&send_msg);
343
if (rv)
344
goto out;
345
slot = halt_recv_msg.msg.data[1];
346
hotswap_ipmb = (slot > 9) ? (0xb0 + 2 * slot) : (0xae + 2 * slot);
347
348
/*
349
* Get active event receiver
350
*/
351
send_msg.netfn = IPMI_NETFN_SENSOR_EVT >> 2;
352
send_msg.cmd = IPMI_CMD_GET_EVENT_RECEIVER;
353
send_msg.data = NULL;
354
send_msg.data_len = 0;
355
rv = ipmi_request_in_rc_mode(user,
356
(struct ipmi_addr *) &smi_addr,
357
&send_msg);
358
if (rv)
359
goto out;
360
aer_addr = halt_recv_msg.msg.data[1];
361
aer_lun = halt_recv_msg.msg.data[2];
362
363
/*
364
* Setup IPMB address target instead of local target
365
*/
366
ipmb_addr.addr_type = IPMI_IPMB_ADDR_TYPE;
367
ipmb_addr.channel = 0;
368
ipmb_addr.slave_addr = aer_addr;
369
ipmb_addr.lun = aer_lun;
370
371
/*
372
* Send request hotswap control to remove blade from dpv
373
*/
374
send_msg.netfn = IPMI_NETFN_OEM_8 >> 2;
375
send_msg.cmd = OEM_GRP_CMD_REQUEST_HOTSWAP_CTRL;
376
send_msg.data = &hotswap_ipmb;
377
send_msg.data_len = 1;
378
ipmi_request_in_rc_mode(user,
379
(struct ipmi_addr *) &ipmb_addr,
380
&send_msg);
381
382
/*
383
* Set reset asserted
384
*/
385
send_msg.netfn = IPMI_NETFN_OEM_1 >> 2;
386
send_msg.cmd = OEM_GRP_CMD_SET_RESET_STATE;
387
send_msg.data = data;
388
data[0] = 1; /* Reset asserted state */
389
send_msg.data_len = 1;
390
rv = ipmi_request_in_rc_mode(user,
391
(struct ipmi_addr *) &smi_addr,
392
&send_msg);
393
if (rv)
394
goto out;
395
396
/*
397
* Power down
398
*/
399
send_msg.netfn = IPMI_NETFN_OEM_1 >> 2;
400
send_msg.cmd = OEM_GRP_CMD_SET_POWER_STATE;
401
send_msg.data = data;
402
data[0] = 1; /* Power down state */
403
send_msg.data_len = 1;
404
rv = ipmi_request_in_rc_mode(user,
405
(struct ipmi_addr *) &smi_addr,
406
&send_msg);
407
if (rv)
408
goto out;
409
410
out:
411
return;
412
}
413
414
/*
415
* ipmi_dell_chassis_detect()
416
* Dell systems with IPMI < 1.5 don't set the chassis capability bit
417
* but they can handle a chassis poweroff or powercycle command.
418
*/
419
420
#define DELL_IANA_MFR_ID {0xA2, 0x02, 0x00}
421
static int ipmi_dell_chassis_detect(struct ipmi_user *user)
422
{
423
const char ipmi_version_major = ipmi_version & 0xF;
424
const char ipmi_version_minor = (ipmi_version >> 4) & 0xF;
425
const char mfr[3] = DELL_IANA_MFR_ID;
426
if (!memcmp(mfr, &mfg_id, sizeof(mfr)) &&
427
ipmi_version_major <= 1 &&
428
ipmi_version_minor < 5)
429
return 1;
430
return 0;
431
}
432
433
/*
434
* ipmi_hp_chassis_detect()
435
* HP PA-RISC servers rp3410/rp3440, the C8000 workstation and the rx2600 and
436
* zx6000 machines support IPMI vers 1 and don't set the chassis capability bit
437
* but they can handle a chassis poweroff or powercycle command.
438
*/
439
440
#define HP_IANA_MFR_ID 0x0b
441
#define HP_BMC_PROD_ID 0x8201
442
static int ipmi_hp_chassis_detect(struct ipmi_user *user)
443
{
444
if (mfg_id == HP_IANA_MFR_ID
445
&& prod_id == HP_BMC_PROD_ID
446
&& ipmi_version == 1)
447
return 1;
448
return 0;
449
}
450
451
/*
452
* Standard chassis support
453
*/
454
455
#define IPMI_NETFN_CHASSIS_REQUEST 0
456
#define IPMI_CHASSIS_CONTROL_CMD 0x02
457
458
static int ipmi_chassis_detect(struct ipmi_user *user)
459
{
460
/* Chassis support, use it. */
461
return (capabilities & 0x80);
462
}
463
464
static void ipmi_poweroff_chassis(struct ipmi_user *user)
465
{
466
struct ipmi_system_interface_addr smi_addr;
467
struct kernel_ipmi_msg send_msg;
468
int rv;
469
unsigned char data[1];
470
471
/*
472
* Configure IPMI address for local access
473
*/
474
smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
475
smi_addr.channel = IPMI_BMC_CHANNEL;
476
smi_addr.lun = 0;
477
478
powercyclefailed:
479
pr_info("Powering %s via IPMI chassis control command\n",
480
(poweroff_powercycle ? "cycle" : "down"));
481
482
/*
483
* Power down
484
*/
485
send_msg.netfn = IPMI_NETFN_CHASSIS_REQUEST;
486
send_msg.cmd = IPMI_CHASSIS_CONTROL_CMD;
487
if (poweroff_powercycle)
488
data[0] = IPMI_CHASSIS_POWER_CYCLE;
489
else
490
data[0] = IPMI_CHASSIS_POWER_DOWN;
491
send_msg.data = data;
492
send_msg.data_len = sizeof(data);
493
rv = ipmi_request_in_rc_mode(user,
494
(struct ipmi_addr *) &smi_addr,
495
&send_msg);
496
if (rv) {
497
if (poweroff_powercycle) {
498
/* power cycle failed, default to power down */
499
pr_err("Unable to send chassis power cycle message, IPMI error 0x%x\n",
500
rv);
501
poweroff_powercycle = 0;
502
goto powercyclefailed;
503
}
504
505
pr_err("Unable to send chassis power down message, IPMI error 0x%x\n",
506
rv);
507
}
508
}
509
510
511
/* Table of possible power off functions. */
512
struct poweroff_function {
513
char *platform_type;
514
int (*detect)(struct ipmi_user *user);
515
void (*poweroff_func)(struct ipmi_user *user);
516
};
517
518
static struct poweroff_function poweroff_functions[] = {
519
{ .platform_type = "ATCA",
520
.detect = ipmi_atca_detect,
521
.poweroff_func = ipmi_poweroff_atca },
522
{ .platform_type = "CPI1",
523
.detect = ipmi_cpi1_detect,
524
.poweroff_func = ipmi_poweroff_cpi1 },
525
{ .platform_type = "chassis",
526
.detect = ipmi_dell_chassis_detect,
527
.poweroff_func = ipmi_poweroff_chassis },
528
{ .platform_type = "chassis",
529
.detect = ipmi_hp_chassis_detect,
530
.poweroff_func = ipmi_poweroff_chassis },
531
/* Chassis should generally be last, other things should override
532
it. */
533
{ .platform_type = "chassis",
534
.detect = ipmi_chassis_detect,
535
.poweroff_func = ipmi_poweroff_chassis },
536
};
537
#define NUM_PO_FUNCS ARRAY_SIZE(poweroff_functions)
538
539
540
/* Called on a powerdown request. */
541
static void ipmi_poweroff_function(void)
542
{
543
if (!ready)
544
return;
545
546
/* Use run-to-completion mode, since interrupts may be off. */
547
specific_poweroff_func(ipmi_user);
548
}
549
550
/* Wait for an IPMI interface to be installed, the first one installed
551
will be grabbed by this code and used to perform the powerdown. */
552
static void ipmi_po_new_smi(int if_num, struct device *device)
553
{
554
struct ipmi_system_interface_addr smi_addr;
555
struct kernel_ipmi_msg send_msg;
556
int rv;
557
int i;
558
559
if (ready)
560
return;
561
562
if ((ifnum_to_use >= 0) && (ifnum_to_use != if_num))
563
return;
564
565
rv = ipmi_create_user(if_num, &ipmi_poweroff_handler, NULL,
566
&ipmi_user);
567
if (rv) {
568
pr_err("could not create IPMI user, error %d\n", rv);
569
return;
570
}
571
572
ipmi_ifnum = if_num;
573
574
/*
575
* Do a get device ide and store some results, since this is
576
* used by several functions.
577
*/
578
smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
579
smi_addr.channel = IPMI_BMC_CHANNEL;
580
smi_addr.lun = 0;
581
582
send_msg.netfn = IPMI_NETFN_APP_REQUEST;
583
send_msg.cmd = IPMI_GET_DEVICE_ID_CMD;
584
send_msg.data = NULL;
585
send_msg.data_len = 0;
586
rv = ipmi_request_wait_for_response(ipmi_user,
587
(struct ipmi_addr *) &smi_addr,
588
&send_msg);
589
if (rv) {
590
pr_err("Unable to send IPMI get device id info, IPMI error 0x%x\n",
591
rv);
592
goto out_err;
593
}
594
595
if (halt_recv_msg.msg.data_len < 12) {
596
pr_err("(chassis) IPMI get device id info too short, was %d bytes, needed %d bytes\n",
597
halt_recv_msg.msg.data_len, 12);
598
goto out_err;
599
}
600
601
mfg_id = (halt_recv_msg.msg.data[7]
602
| (halt_recv_msg.msg.data[8] << 8)
603
| (halt_recv_msg.msg.data[9] << 16));
604
prod_id = (halt_recv_msg.msg.data[10]
605
| (halt_recv_msg.msg.data[11] << 8));
606
capabilities = halt_recv_msg.msg.data[6];
607
ipmi_version = halt_recv_msg.msg.data[5];
608
609
610
/* Scan for a poweroff method */
611
for (i = 0; i < NUM_PO_FUNCS; i++) {
612
if (poweroff_functions[i].detect(ipmi_user))
613
goto found;
614
}
615
616
out_err:
617
pr_err("Unable to find a poweroff function that will work, giving up\n");
618
ipmi_destroy_user(ipmi_user);
619
return;
620
621
found:
622
pr_info("Found a %s style poweroff function\n",
623
poweroff_functions[i].platform_type);
624
specific_poweroff_func = poweroff_functions[i].poweroff_func;
625
old_poweroff_func = pm_power_off;
626
pm_power_off = ipmi_poweroff_function;
627
ready = 1;
628
}
629
630
static void ipmi_po_smi_gone(int if_num)
631
{
632
if (!ready)
633
return;
634
635
if (ipmi_ifnum != if_num)
636
return;
637
638
ready = 0;
639
ipmi_destroy_user(ipmi_user);
640
pm_power_off = old_poweroff_func;
641
}
642
643
static struct ipmi_smi_watcher smi_watcher = {
644
.owner = THIS_MODULE,
645
.new_smi = ipmi_po_new_smi,
646
.smi_gone = ipmi_po_smi_gone
647
};
648
649
650
#ifdef CONFIG_PROC_FS
651
#include <linux/sysctl.h>
652
653
static const struct ctl_table ipmi_table[] = {
654
{ .procname = "poweroff_powercycle",
655
.data = &poweroff_powercycle,
656
.maxlen = sizeof(poweroff_powercycle),
657
.mode = 0644,
658
.proc_handler = proc_dointvec },
659
};
660
661
static struct ctl_table_header *ipmi_table_header;
662
#endif /* CONFIG_PROC_FS */
663
664
/*
665
* Startup and shutdown functions.
666
*/
667
static int __init ipmi_poweroff_init(void)
668
{
669
int rv;
670
671
pr_info("Copyright (C) 2004 MontaVista Software - IPMI Powerdown via sys_reboot\n");
672
673
if (poweroff_powercycle)
674
pr_info("Power cycle is enabled\n");
675
676
#ifdef CONFIG_PROC_FS
677
ipmi_table_header = register_sysctl("dev/ipmi", ipmi_table);
678
if (!ipmi_table_header) {
679
pr_err("Unable to register powercycle sysctl\n");
680
rv = -ENOMEM;
681
goto out_err;
682
}
683
#endif
684
685
rv = ipmi_smi_watcher_register(&smi_watcher);
686
687
#ifdef CONFIG_PROC_FS
688
if (rv) {
689
unregister_sysctl_table(ipmi_table_header);
690
pr_err("Unable to register SMI watcher: %d\n", rv);
691
goto out_err;
692
}
693
694
out_err:
695
#endif
696
return rv;
697
}
698
699
#ifdef MODULE
700
static void __exit ipmi_poweroff_cleanup(void)
701
{
702
#ifdef CONFIG_PROC_FS
703
unregister_sysctl_table(ipmi_table_header);
704
#endif
705
706
ipmi_smi_watcher_unregister(&smi_watcher);
707
708
if (ready) {
709
ipmi_destroy_user(ipmi_user);
710
pm_power_off = old_poweroff_func;
711
}
712
}
713
module_exit(ipmi_poweroff_cleanup);
714
#endif
715
716
module_init(ipmi_poweroff_init);
717
MODULE_LICENSE("GPL");
718
MODULE_AUTHOR("Corey Minyard <[email protected]>");
719
MODULE_DESCRIPTION("IPMI Poweroff extension to sys_reboot");
720
721