ipmi: Differentiate between reset and firmware update in maintenance
This allows later changes to have different behaviour during a reset verses a firmware update. Signed-off-by: Corey Minyard <corey@minyard.net> Tested-by: Frederick Lawler <fred@cloudflare.com>pull/1354/merge
parent
121f4a7e47
commit
e5feb030d9
|
|
@ -541,7 +541,11 @@ struct ipmi_smi {
|
|||
|
||||
/* For handling of maintenance mode. */
|
||||
int maintenance_mode;
|
||||
bool maintenance_mode_enable;
|
||||
|
||||
#define IPMI_MAINTENANCE_MODE_STATE_OFF 0
|
||||
#define IPMI_MAINTENANCE_MODE_STATE_FIRMWARE 1
|
||||
#define IPMI_MAINTENANCE_MODE_STATE_RESET 2
|
||||
int maintenance_mode_state;
|
||||
int auto_maintenance_timeout;
|
||||
spinlock_t maintenance_mode_lock; /* Used in a timer... */
|
||||
|
||||
|
|
@ -1530,8 +1534,15 @@ EXPORT_SYMBOL(ipmi_get_maintenance_mode);
|
|||
static void maintenance_mode_update(struct ipmi_smi *intf)
|
||||
{
|
||||
if (intf->handlers->set_maintenance_mode)
|
||||
/*
|
||||
* Lower level drivers only care about firmware mode
|
||||
* as it affects their timing. They don't care about
|
||||
* reset, which disables all commands for a while.
|
||||
*/
|
||||
intf->handlers->set_maintenance_mode(
|
||||
intf->send_info, intf->maintenance_mode_enable);
|
||||
intf->send_info,
|
||||
(intf->maintenance_mode_state ==
|
||||
IPMI_MAINTENANCE_MODE_STATE_FIRMWARE));
|
||||
}
|
||||
|
||||
int ipmi_set_maintenance_mode(struct ipmi_user *user, int mode)
|
||||
|
|
@ -1548,16 +1559,17 @@ int ipmi_set_maintenance_mode(struct ipmi_user *user, int mode)
|
|||
if (intf->maintenance_mode != mode) {
|
||||
switch (mode) {
|
||||
case IPMI_MAINTENANCE_MODE_AUTO:
|
||||
intf->maintenance_mode_enable
|
||||
= (intf->auto_maintenance_timeout > 0);
|
||||
/* Just leave it alone. */
|
||||
break;
|
||||
|
||||
case IPMI_MAINTENANCE_MODE_OFF:
|
||||
intf->maintenance_mode_enable = false;
|
||||
intf->maintenance_mode_state =
|
||||
IPMI_MAINTENANCE_MODE_STATE_OFF;
|
||||
break;
|
||||
|
||||
case IPMI_MAINTENANCE_MODE_ON:
|
||||
intf->maintenance_mode_enable = true;
|
||||
intf->maintenance_mode_state =
|
||||
IPMI_MAINTENANCE_MODE_STATE_FIRMWARE;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -1917,13 +1929,18 @@ static int i_ipmi_req_sysintf(struct ipmi_smi *intf,
|
|||
|
||||
if (is_maintenance_mode_cmd(msg)) {
|
||||
unsigned long flags;
|
||||
int newst;
|
||||
|
||||
if (msg->netfn == IPMI_NETFN_FIRMWARE_REQUEST)
|
||||
newst = IPMI_MAINTENANCE_MODE_STATE_FIRMWARE;
|
||||
else
|
||||
newst = IPMI_MAINTENANCE_MODE_STATE_RESET;
|
||||
|
||||
spin_lock_irqsave(&intf->maintenance_mode_lock, flags);
|
||||
intf->auto_maintenance_timeout
|
||||
= maintenance_mode_timeout_ms;
|
||||
intf->auto_maintenance_timeout = maintenance_mode_timeout_ms;
|
||||
if (!intf->maintenance_mode
|
||||
&& !intf->maintenance_mode_enable) {
|
||||
intf->maintenance_mode_enable = true;
|
||||
&& intf->maintenance_mode_state < newst) {
|
||||
intf->maintenance_mode_state = newst;
|
||||
maintenance_mode_update(intf);
|
||||
}
|
||||
spin_unlock_irqrestore(&intf->maintenance_mode_lock,
|
||||
|
|
@ -5028,7 +5045,8 @@ static bool ipmi_timeout_handler(struct ipmi_smi *intf,
|
|||
-= timeout_period;
|
||||
if (!intf->maintenance_mode
|
||||
&& (intf->auto_maintenance_timeout <= 0)) {
|
||||
intf->maintenance_mode_enable = false;
|
||||
intf->maintenance_mode_state =
|
||||
IPMI_MAINTENANCE_MODE_STATE_OFF;
|
||||
maintenance_mode_update(intf);
|
||||
}
|
||||
}
|
||||
|
|
@ -5044,7 +5062,7 @@ static bool ipmi_timeout_handler(struct ipmi_smi *intf,
|
|||
static void ipmi_request_event(struct ipmi_smi *intf)
|
||||
{
|
||||
/* No event requests when in maintenance mode. */
|
||||
if (intf->maintenance_mode_enable)
|
||||
if (intf->maintenance_mode_state)
|
||||
return;
|
||||
|
||||
if (!intf->in_shutdown)
|
||||
|
|
|
|||
Loading…
Reference in New Issue