Esempio n. 1
0
static void panic_halt_ipmi_heartbeat(void)
{
	struct kernel_ipmi_msg             msg;
	struct ipmi_system_interface_addr addr;


	/* Don't reset the timer if we have the timer turned off, that
           re-enables the watchdog. */
	if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE)
		return;

	addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
	addr.channel = IPMI_BMC_CHANNEL;
	addr.lun = 0;

	msg.netfn = 0x06;
	msg.cmd = IPMI_WDOG_RESET_TIMER;
	msg.data = NULL;
	msg.data_len = 0;
	ipmi_request_supply_msgs(watchdog_user,
				 (struct ipmi_addr *) &addr,
				 0,
				 &msg,
				 NULL,
				 &panic_halt_heartbeat_smi_msg,
				 &panic_halt_heartbeat_recv_msg,
				 1);
}
Esempio n. 2
0
static void panic_halt_ipmi_heartbeat(void)
{
	struct kernel_ipmi_msg             msg;
	struct ipmi_system_interface_addr addr;
	int rv;

	
	if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE)
		return;

	addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
	addr.channel = IPMI_BMC_CHANNEL;
	addr.lun = 0;

	msg.netfn = 0x06;
	msg.cmd = IPMI_WDOG_RESET_TIMER;
	msg.data = NULL;
	msg.data_len = 0;
	rv = ipmi_request_supply_msgs(watchdog_user,
				      (struct ipmi_addr *) &addr,
				      0,
				      &msg,
				      NULL,
				      &panic_halt_heartbeat_smi_msg,
				      &panic_halt_heartbeat_recv_msg,
				      1);
	if (!rv)
		atomic_add(2, &panic_done_count);
}
Esempio n. 3
0
/* We are in run-to-completion mode, no completion is desired. */
static int ipmi_request_in_rc_mode(ipmi_user_t            user,
				   struct ipmi_addr       *addr,
				   struct kernel_ipmi_msg *send_msg)
{
	int rv;

	rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, NULL,
				      &halt_smi_msg, &halt_recv_msg, 0);
	if (rv)
		return rv;

	return halt_recv_msg.msg.data[0];
}
Esempio n. 4
0
static int ipmi_request_wait_for_response(ipmi_user_t            user,
					  struct ipmi_addr       *addr,
					  struct kernel_ipmi_msg *send_msg)
{
	int               rv;
	struct completion comp;

	init_completion(&comp);

	rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, &comp,
				      &halt_smi_msg, &halt_recv_msg, 0);
	if (rv)
		return rv;

	wait_for_completion(&comp);

	return halt_recv_msg.msg.data[0];
}
Esempio n. 5
0
static int ipmi_request_wait_for_response(ipmi_user_t            user,
					  struct ipmi_addr       *addr,
					  struct kernel_ipmi_msg *send_msg)
{
	int              rv;
	struct semaphore sem;

	sema_init (&sem, 0);

	rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, &sem,
				      &halt_smi_msg, &halt_recv_msg, 0);
	if (rv)
		return rv;

	down (&sem);

	return halt_recv_msg.msg.data[0];
}
/* Wait for message to complete, spinning. */
static int ipmi_request_in_rc_mode(ipmi_user_t            user,
				   struct ipmi_addr       *addr,
				   struct kernel_ipmi_msg *send_msg)
{
	int rv;

	atomic_set(&dummy_count, 2);
	rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, NULL,
				      &halt_smi_msg, &halt_recv_msg, 0);
	if (rv) {
		atomic_set(&dummy_count, 0);
		return rv;
	}

	/*
	 * Spin until our message is done.
	 */
	while (atomic_read(&dummy_count) > 0) {
		ipmi_poll_interface(user);
		cpu_relax();
	}

	return halt_recv_msg.msg.data[0];
}
Esempio n. 7
0
static int ipmi_heartbeat(void)
{
	struct kernel_ipmi_msg            msg;
	int                               rv;
	struct ipmi_system_interface_addr addr;

	if (ipmi_ignore_heartbeat) {
		return 0;
	}

	if (ipmi_start_timer_on_heartbeat) {
		ipmi_start_timer_on_heartbeat = 0;
		ipmi_watchdog_state = action_val;
		return ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
	} else if (pretimeout_since_last_heartbeat) {
		/* A pretimeout occurred, make sure we set the timeout.
		   We don't want to set the action, though, we want to
		   leave that alone (thus it can't be combined with the
		   above operation. */
		pretimeout_since_last_heartbeat = 0;
		return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
	}

	down(&heartbeat_lock);

	atomic_set(&heartbeat_tofree, 2);

	/* Don't reset the timer if we have the timer turned off, that
           re-enables the watchdog. */
	if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) {
		up(&heartbeat_lock);
		return 0;
	}

	addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
	addr.channel = IPMI_BMC_CHANNEL;
	addr.lun = 0;

	msg.netfn = 0x06;
	msg.cmd = IPMI_WDOG_RESET_TIMER;
	msg.data = NULL;
	msg.data_len = 0;
	rv = ipmi_request_supply_msgs(watchdog_user,
				      (struct ipmi_addr *) &addr,
				      0,
				      &msg,
				      NULL,
				      &heartbeat_smi_msg,
				      &heartbeat_recv_msg,
				      1);
	if (rv) {
		up(&heartbeat_lock);
		printk(KERN_WARNING PFX "heartbeat failure: %d\n",
		       rv);
		return rv;
	}

	/* Wait for the heartbeat to be sent. */
	down(&heartbeat_wait_lock);

	if (heartbeat_recv_msg.msg.data[0] != 0) {
	    /* Got an error in the heartbeat response.  It was already
	       reported in ipmi_wdog_msg_handler, but we should return
	       an error here. */
	    rv = -EINVAL;
	}

	up(&heartbeat_lock);

	return rv;
}
Esempio n. 8
0
static int i_ipmi_set_timeout(struct ipmi_smi_msg  *smi_msg,
			      struct ipmi_recv_msg *recv_msg,
			      int                  *send_heartbeat_now)
{
	struct kernel_ipmi_msg            msg;
	unsigned char                     data[6];
	int                               rv;
	struct ipmi_system_interface_addr addr;
	int                               hbnow = 0;


	data[0] = 0;
	WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS);

	if ((ipmi_version_major > 1)
	    || ((ipmi_version_major == 1) && (ipmi_version_minor >= 5)))
	{
		/* This is an IPMI 1.5-only feature. */
		data[0] |= WDOG_DONT_STOP_ON_SET;
	} else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) {
		/* In ipmi 1.0, setting the timer stops the watchdog, we
		   need to start it back up again. */
		hbnow = 1;
	}

	data[1] = 0;
	WDOG_SET_TIMEOUT_ACT(data[1], ipmi_watchdog_state);
	if ((pretimeout > 0) && (ipmi_watchdog_state != WDOG_TIMEOUT_NONE)) {
	    WDOG_SET_PRETIMEOUT_ACT(data[1], preaction_val);
	    data[2] = pretimeout;
	} else {
	    WDOG_SET_PRETIMEOUT_ACT(data[1], WDOG_PRETIMEOUT_NONE);
	    data[2] = 0; /* No pretimeout. */
	}
	data[3] = 0;
	WDOG_SET_TIMEOUT(data[4], data[5], timeout);

	addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
	addr.channel = IPMI_BMC_CHANNEL;
	addr.lun = 0;

	msg.netfn = 0x06;
	msg.cmd = IPMI_WDOG_SET_TIMER;
	msg.data = data;
	msg.data_len = sizeof(data);
	rv = ipmi_request_supply_msgs(watchdog_user,
				      (struct ipmi_addr *) &addr,
				      0,
				      &msg,
				      NULL,
				      smi_msg,
				      recv_msg,
				      1);
	if (rv) {
		printk(KERN_WARNING PFX "set timeout error: %d\n",
		       rv);
	}

	if (send_heartbeat_now)
	    *send_heartbeat_now = hbnow;

	return rv;
}
Esempio n. 9
0
static int ipmi_heartbeat(void)
{
	struct kernel_ipmi_msg            msg;
	int                               rv;
	struct ipmi_system_interface_addr addr;
	int				  timeout_retries = 0;

	if (ipmi_ignore_heartbeat)
		return 0;

	if (ipmi_start_timer_on_heartbeat) {
		ipmi_start_timer_on_heartbeat = 0;
		ipmi_watchdog_state = action_val;
		return ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
	} else if (pretimeout_since_last_heartbeat) {
		/*
		 * A pretimeout occurred, make sure we set the timeout.
		 * We don't want to set the action, though, we want to
		 * leave that alone (thus it can't be combined with the
		 * above operation.
		 */
		return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
	}

	mutex_lock(&heartbeat_lock);

restart:
	atomic_set(&heartbeat_tofree, 2);

	/*
	 * Don't reset the timer if we have the timer turned off, that
	 * re-enables the watchdog.
	 */
	if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) {
		mutex_unlock(&heartbeat_lock);
		return 0;
	}

	addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
	addr.channel = IPMI_BMC_CHANNEL;
	addr.lun = 0;

	msg.netfn = 0x06;
	msg.cmd = IPMI_WDOG_RESET_TIMER;
	msg.data = NULL;
	msg.data_len = 0;
	rv = ipmi_request_supply_msgs(watchdog_user,
				      (struct ipmi_addr *) &addr,
				      0,
				      &msg,
				      NULL,
				      &heartbeat_smi_msg,
				      &heartbeat_recv_msg,
				      1);
	if (rv) {
		mutex_unlock(&heartbeat_lock);
		printk(KERN_WARNING PFX "heartbeat failure: %d\n",
		       rv);
		return rv;
	}

	/* Wait for the heartbeat to be sent. */
	wait_for_completion(&heartbeat_wait);

	if (heartbeat_recv_msg.msg.data[0] == IPMI_WDOG_TIMER_NOT_INIT_RESP)  {
		timeout_retries++;
		if (timeout_retries > 3) {
			printk(KERN_ERR PFX ": Unable to restore the IPMI"
			       " watchdog's settings, giving up.\n");
			rv = -EIO;
			goto out_unlock;
		}

		/*
		 * The timer was not initialized, that means the BMC was
		 * probably reset and lost the watchdog information.  Attempt
		 * to restore the timer's info.  Note that we still hold
		 * the heartbeat lock, to keep a heartbeat from happening
		 * in this process, so must say no heartbeat to avoid a
		 * deadlock on this mutex.
		 */
		rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
		if (rv) {
			printk(KERN_ERR PFX ": Unable to send the command to"
			       " set the watchdog's settings, giving up.\n");
			goto out_unlock;
		}

		/* We might need a new heartbeat, so do it now */
		goto restart;
	} else if (heartbeat_recv_msg.msg.data[0] != 0) {
		/*
		 * Got an error in the heartbeat response.  It was already
		 * reported in ipmi_wdog_msg_handler, but we should return
		 * an error here.
		 */
		rv = -EINVAL;
	}

out_unlock:
	mutex_unlock(&heartbeat_lock);

	return rv;
}
Esempio n. 10
0
static int ipmi_heartbeat(void)
{
	struct kernel_ipmi_msg            msg;
	int                               rv;
	struct ipmi_system_interface_addr addr;

	if (ipmi_ignore_heartbeat)
		return 0;

	if (ipmi_start_timer_on_heartbeat) {
		ipmi_start_timer_on_heartbeat = 0;
		ipmi_watchdog_state = action_val;
		return ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
	} else if (pretimeout_since_last_heartbeat) {
		
		return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
	}

	mutex_lock(&heartbeat_lock);

	atomic_set(&heartbeat_tofree, 2);

	
	if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) {
		mutex_unlock(&heartbeat_lock);
		return 0;
	}

	addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
	addr.channel = IPMI_BMC_CHANNEL;
	addr.lun = 0;

	msg.netfn = 0x06;
	msg.cmd = IPMI_WDOG_RESET_TIMER;
	msg.data = NULL;
	msg.data_len = 0;
	rv = ipmi_request_supply_msgs(watchdog_user,
				      (struct ipmi_addr *) &addr,
				      0,
				      &msg,
				      NULL,
				      &heartbeat_smi_msg,
				      &heartbeat_recv_msg,
				      1);
	if (rv) {
		mutex_unlock(&heartbeat_lock);
		printk(KERN_WARNING PFX "heartbeat failure: %d\n",
		       rv);
		return rv;
	}

	
	wait_for_completion(&heartbeat_wait);

	if (heartbeat_recv_msg.msg.data[0] != 0) {
		
		rv = -EINVAL;
	}

	mutex_unlock(&heartbeat_lock);

	return rv;
}