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; }
/** * 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."); } }