int toi_activate_storage(int force)
{
	int tries = 1;

	if (usm_helper_data.pid == -1 || !usm_ops.enabled)
		return 0;

	message_received = 0;
	activations++;

	if (activations > 1 && !force)
		return 0;

	while ((!message_received || message_received == USM_MSG_FAILED) && tries < 2) {
		toi_prepare_status(DONT_CLEAR_BAR, "Activate storage attempt " "%d.\n", tries);

		init_completion(&usm_helper_data.wait_for_process);

		toi_send_netlink_message(&usm_helper_data, USM_MSG_CONNECT, NULL, 0);

		/* Wait 2 seconds for the userspace process to make contact */
		wait_for_completion_timeout(&usm_helper_data.wait_for_process, 2 * HZ);

		tries++;
	}

	return 0;
}
/**
 * toi_atomic_restore - prepare to do the atomic restore
 *
 * Get ready to do the atomic restore. This part gets us into the same
 * state we are in prior to do calling do_toi_lowlevel while
 * hibernating: hot-unplugging secondary cpus and freeze processes,
 * before starting the thread that will do the restore.
 **/
int toi_atomic_restore(void)
{
	int error;

	toi_running = 1;

	toi_prepare_status(DONT_CLEAR_BAR, "Atomic restore.");

	memcpy(&toi_bkd.toi_nosave_commandline, saved_command_line, strlen(saved_command_line));

	toi_pre_atomic_restore_modules(&toi_bkd);

	if (add_boot_kernel_data_pbe())
		goto Failed;

	toi_prepare_status(DONT_CLEAR_BAR, "Doing atomic copy/restore.");

	if (toi_go_atomic(PMSG_QUIESCE, 0))
		goto Failed;

	/* We'll ignore saved state, but this gets preempt count (etc) right */
	save_processor_state();

	error = swsusp_arch_resume();
	/*
	 * Code below is only ever reached in case of failure. Otherwise
	 * execution continues at place where swsusp_arch_suspend was called.
	 *
	 * We don't know whether it's safe to continue (this shouldn't happen),
	 * so lets err on the side of caution.
	 */
	BUG();

 Failed:
	free_pbe_list(&restore_pblist, 0);
#ifdef CONFIG_HIGHMEM
	pr_warn("[%s] 0x%p 0x%p 0x%p\n", __func__,
			restore_highmem_pblist->address, restore_highmem_pblist->orig_address, restore_highmem_pblist->next);
	if (restore_highmem_pblist->next != NULL)
		free_pbe_list(&restore_highmem_pblist, 1);
#endif
	toi_running = 0;
	return 1;
}
예제 #3
0
/**
 * toi_end_atomic - post atomic copy/restore routines
 * @stage:		What step to start at.
 * @suspend_time:	Whether we're suspending or resuming.
 * @error:		Whether we're recovering from an error.
 **/
void toi_end_atomic(int stage, int suspend_time, int error)
{
	pm_message_t msg = suspend_time ? (error ? PMSG_RECOVER : PMSG_THAW) :
		PMSG_RESTORE;

	switch (stage) {
	case ATOMIC_ALL_STEPS:
		if (!suspend_time) {
			events_check_enabled = false;
			platform_leave(1);
		}
	case ATOMIC_STEP_SYSCORE_RESUME:
		syscore_resume();
	case ATOMIC_STEP_IRQS:
		local_irq_enable();
	case ATOMIC_STEP_CPU_HOTPLUG:
		if (test_action_state(TOI_LATE_CPU_HOTPLUG))
			enable_nonboot_cpus();
	case ATOMIC_STEP_PLATFORM_FINISH:
		if (!suspend_time && error & 2)
			platform_restore_cleanup(1);
		else 
			platform_finish(1);
		dpm_resume_start(msg);
	case ATOMIC_STEP_DEVICE_RESUME:
		if (suspend_time && (error & 2))
			platform_recover(1);
		dpm_resume(msg);
		if (error || !toi_in_suspend())
			pm_restore_gfp_mask();
		ftrace_start();
		resume_console();
	case ATOMIC_STEP_DPM_COMPLETE:
		dpm_complete(msg);
	case ATOMIC_STEP_PLATFORM_END:
		platform_end(1);

		toi_prepare_status(DONT_CLEAR_BAR, "Post atomic.");
	}
}