mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
Merge linux-2.6 with linux-acpi-2.6
This commit is contained in:
commit
64e47488c9
1968 changed files with 57918 additions and 48538 deletions
|
|
@ -29,7 +29,7 @@ config PM_DEBUG
|
|||
|
||||
config SOFTWARE_SUSPEND
|
||||
bool "Software Suspend"
|
||||
depends on EXPERIMENTAL && PM && SWAP && ((X86 && SMP) || ((FVR || PPC32 || X86) && !SMP))
|
||||
depends on PM && SWAP && (X86 || ((FVR || PPC32) && !SMP))
|
||||
---help---
|
||||
Enable the possibility of suspending the machine.
|
||||
It doesn't need APM.
|
||||
|
|
@ -73,6 +73,18 @@ config PM_STD_PARTITION
|
|||
suspended image to. It will simply pick the first available swap
|
||||
device.
|
||||
|
||||
config SWSUSP_ENCRYPT
|
||||
bool "Encrypt suspend image"
|
||||
depends on SOFTWARE_SUSPEND && CRYPTO=y && (CRYPTO_AES=y || CRYPTO_AES_586=y || CRYPTO_AES_X86_64=y)
|
||||
default ""
|
||||
---help---
|
||||
To prevent data gathering from swap after resume you can encrypt
|
||||
the suspend image with a temporary key that is deleted on
|
||||
resume.
|
||||
|
||||
Note that the temporary key is stored unencrypted on disk while the
|
||||
system is suspended.
|
||||
|
||||
config SUSPEND_SMP
|
||||
bool
|
||||
depends on HOTPLUG_CPU && X86 && PM
|
||||
|
|
|
|||
|
|
@ -112,24 +112,12 @@ static inline void platform_finish(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void finish(void)
|
||||
{
|
||||
device_resume();
|
||||
platform_finish();
|
||||
thaw_processes();
|
||||
enable_nonboot_cpus();
|
||||
pm_restore_console();
|
||||
}
|
||||
|
||||
|
||||
static int prepare_processes(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
pm_prepare_console();
|
||||
|
||||
sys_sync();
|
||||
|
||||
disable_nonboot_cpus();
|
||||
|
||||
if (freeze_processes()) {
|
||||
|
|
@ -162,15 +150,6 @@ static void unprepare_processes(void)
|
|||
pm_restore_console();
|
||||
}
|
||||
|
||||
static int prepare_devices(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
if ((error = device_suspend(PMSG_FREEZE)))
|
||||
printk("Some devices failed to suspend\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_suspend_disk - The granpappy of power management.
|
||||
*
|
||||
|
|
@ -187,17 +166,14 @@ int pm_suspend_disk(void)
|
|||
error = prepare_processes();
|
||||
if (error)
|
||||
return error;
|
||||
error = prepare_devices();
|
||||
|
||||
error = device_suspend(PMSG_FREEZE);
|
||||
if (error) {
|
||||
printk("Some devices failed to suspend\n");
|
||||
unprepare_processes();
|
||||
return error;
|
||||
}
|
||||
|
||||
pr_debug("PM: Attempting to suspend to disk.\n");
|
||||
if (pm_disk_mode == PM_DISK_FIRMWARE)
|
||||
return pm_ops->enter(PM_SUSPEND_DISK);
|
||||
|
||||
pr_debug("PM: snapshotting memory.\n");
|
||||
in_suspend = 1;
|
||||
if ((error = swsusp_suspend()))
|
||||
|
|
@ -208,11 +184,20 @@ int pm_suspend_disk(void)
|
|||
error = swsusp_write();
|
||||
if (!error)
|
||||
power_down(pm_disk_mode);
|
||||
else {
|
||||
/* swsusp_write can not fail in device_resume,
|
||||
no need to do second device_resume */
|
||||
swsusp_free();
|
||||
unprepare_processes();
|
||||
return error;
|
||||
}
|
||||
} else
|
||||
pr_debug("PM: Image restored successfully.\n");
|
||||
|
||||
swsusp_free();
|
||||
Done:
|
||||
finish();
|
||||
device_resume();
|
||||
unprepare_processes();
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
@ -233,9 +218,12 @@ static int software_resume(void)
|
|||
{
|
||||
int error;
|
||||
|
||||
down(&pm_sem);
|
||||
if (!swsusp_resume_device) {
|
||||
if (!strlen(resume_file))
|
||||
if (!strlen(resume_file)) {
|
||||
up(&pm_sem);
|
||||
return -ENOENT;
|
||||
}
|
||||
swsusp_resume_device = name_to_dev_t(resume_file);
|
||||
pr_debug("swsusp: Resume From Partition %s\n", resume_file);
|
||||
} else {
|
||||
|
|
@ -248,6 +236,7 @@ static int software_resume(void)
|
|||
* FIXME: If noresume is specified, we need to find the partition
|
||||
* and reset it back to normal swap space.
|
||||
*/
|
||||
up(&pm_sem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -270,20 +259,24 @@ static int software_resume(void)
|
|||
|
||||
pr_debug("PM: Preparing devices for restore.\n");
|
||||
|
||||
if ((error = prepare_devices()))
|
||||
if ((error = device_suspend(PMSG_FREEZE))) {
|
||||
printk("Some devices failed to suspend\n");
|
||||
goto Free;
|
||||
}
|
||||
|
||||
mb();
|
||||
|
||||
pr_debug("PM: Restoring saved image.\n");
|
||||
swsusp_resume();
|
||||
pr_debug("PM: Restore failed, recovering.n");
|
||||
finish();
|
||||
device_resume();
|
||||
Free:
|
||||
swsusp_free();
|
||||
Cleanup:
|
||||
unprepare_processes();
|
||||
Done:
|
||||
/* For success case, the suspend path will release the lock */
|
||||
up(&pm_sem);
|
||||
pr_debug("PM: Resume from disk failed.\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -390,7 +383,9 @@ static ssize_t resume_store(struct subsystem * subsys, const char * buf, size_t
|
|||
if (sscanf(buf, "%u:%u", &maj, &min) == 2) {
|
||||
res = MKDEV(maj,min);
|
||||
if (maj == MAJOR(res) && min == MINOR(res)) {
|
||||
down(&pm_sem);
|
||||
swsusp_resume_device = res;
|
||||
up(&pm_sem);
|
||||
printk("Attempting manual resume\n");
|
||||
noresume = 0;
|
||||
software_resume();
|
||||
|
|
|
|||
|
|
@ -143,11 +143,12 @@ static void suspend_finish(suspend_state_t state)
|
|||
|
||||
|
||||
|
||||
static char * pm_states[] = {
|
||||
static char *pm_states[PM_SUSPEND_MAX] = {
|
||||
[PM_SUSPEND_STANDBY] = "standby",
|
||||
[PM_SUSPEND_MEM] = "mem",
|
||||
#ifdef CONFIG_SOFTWARE_SUSPEND
|
||||
[PM_SUSPEND_DISK] = "disk",
|
||||
NULL,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -60,9 +60,8 @@ struct pm_dev *pm_register(pm_dev_t type,
|
|||
unsigned long id,
|
||||
pm_callback callback)
|
||||
{
|
||||
struct pm_dev *dev = kmalloc(sizeof(struct pm_dev), GFP_KERNEL);
|
||||
struct pm_dev *dev = kzalloc(sizeof(struct pm_dev), GFP_KERNEL);
|
||||
if (dev) {
|
||||
memset(dev, 0, sizeof(*dev));
|
||||
dev->type = type;
|
||||
dev->id = id;
|
||||
dev->callback = callback;
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ void refrigerator(void)
|
|||
processes around? */
|
||||
long save;
|
||||
save = current->state;
|
||||
current->state = TASK_UNINTERRUPTIBLE;
|
||||
pr_debug("%s entered refrigerator\n", current->comm);
|
||||
printk("=");
|
||||
|
||||
|
|
@ -47,8 +46,10 @@ void refrigerator(void)
|
|||
recalc_sigpending(); /* We sent fake signal, clean it up */
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
while (frozen(current))
|
||||
while (frozen(current)) {
|
||||
current->state = TASK_UNINTERRUPTIBLE;
|
||||
schedule();
|
||||
}
|
||||
pr_debug("%s left refrigerator\n", current->comm);
|
||||
current->state = save;
|
||||
}
|
||||
|
|
@ -80,13 +81,33 @@ int freeze_processes(void)
|
|||
} while_each_thread(g, p);
|
||||
read_unlock(&tasklist_lock);
|
||||
yield(); /* Yield is okay here */
|
||||
if (time_after(jiffies, start_time + TIMEOUT)) {
|
||||
if (todo && time_after(jiffies, start_time + TIMEOUT)) {
|
||||
printk( "\n" );
|
||||
printk(KERN_ERR " stopping tasks failed (%d tasks remaining)\n", todo );
|
||||
return todo;
|
||||
break;
|
||||
}
|
||||
} while(todo);
|
||||
|
||||
/* This does not unfreeze processes that are already frozen
|
||||
* (we have slightly ugly calling convention in that respect,
|
||||
* and caller must call thaw_processes() if something fails),
|
||||
* but it cleans up leftover PF_FREEZE requests.
|
||||
*/
|
||||
if (todo) {
|
||||
read_lock(&tasklist_lock);
|
||||
do_each_thread(g, p)
|
||||
if (freezing(p)) {
|
||||
pr_debug(" clean up: %s\n", p->comm);
|
||||
p->flags &= ~PF_FREEZE;
|
||||
spin_lock_irqsave(&p->sighand->siglock, flags);
|
||||
recalc_sigpending_tsk(p);
|
||||
spin_unlock_irqrestore(&p->sighand->siglock, flags);
|
||||
}
|
||||
while_each_thread(g, p);
|
||||
read_unlock(&tasklist_lock);
|
||||
return todo;
|
||||
}
|
||||
|
||||
printk( "|\n" );
|
||||
BUG_ON(in_atomic());
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@
|
|||
* Alex Badea <vampire@go.ro>:
|
||||
* Fixed runaway init
|
||||
*
|
||||
* Andreas Steinmetz <ast@domdv.de>:
|
||||
* Added encrypted suspend option
|
||||
*
|
||||
* More state savers are welcome. Especially for the scsi layer...
|
||||
*
|
||||
* For TODOs,FIXMEs also look in Documentation/power/swsusp.txt
|
||||
|
|
@ -71,8 +74,16 @@
|
|||
#include <asm/tlbflush.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <linux/random.h>
|
||||
#include <linux/crypto.h>
|
||||
#include <asm/scatterlist.h>
|
||||
|
||||
#include "power.h"
|
||||
|
||||
#define CIPHER "aes"
|
||||
#define MAXKEY 32
|
||||
#define MAXIV 32
|
||||
|
||||
/* References to section boundaries */
|
||||
extern const void __nosave_begin, __nosave_end;
|
||||
|
||||
|
|
@ -103,7 +114,8 @@ static suspend_pagedir_t *pagedir_save;
|
|||
#define SWSUSP_SIG "S1SUSPEND"
|
||||
|
||||
static struct swsusp_header {
|
||||
char reserved[PAGE_SIZE - 20 - sizeof(swp_entry_t)];
|
||||
char reserved[PAGE_SIZE - 20 - MAXKEY - MAXIV - sizeof(swp_entry_t)];
|
||||
u8 key_iv[MAXKEY+MAXIV];
|
||||
swp_entry_t swsusp_info;
|
||||
char orig_sig[10];
|
||||
char sig[10];
|
||||
|
|
@ -129,6 +141,131 @@ static struct swsusp_info swsusp_info;
|
|||
static unsigned short swapfile_used[MAX_SWAPFILES];
|
||||
static unsigned short root_swap;
|
||||
|
||||
static int write_page(unsigned long addr, swp_entry_t * loc);
|
||||
static int bio_read_page(pgoff_t page_off, void * page);
|
||||
|
||||
static u8 key_iv[MAXKEY+MAXIV];
|
||||
|
||||
#ifdef CONFIG_SWSUSP_ENCRYPT
|
||||
|
||||
static int crypto_init(int mode, void **mem)
|
||||
{
|
||||
int error = 0;
|
||||
int len;
|
||||
char *modemsg;
|
||||
struct crypto_tfm *tfm;
|
||||
|
||||
modemsg = mode ? "suspend not possible" : "resume not possible";
|
||||
|
||||
tfm = crypto_alloc_tfm(CIPHER, CRYPTO_TFM_MODE_CBC);
|
||||
if(!tfm) {
|
||||
printk(KERN_ERR "swsusp: no tfm, %s\n", modemsg);
|
||||
error = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(MAXKEY < crypto_tfm_alg_min_keysize(tfm)) {
|
||||
printk(KERN_ERR "swsusp: key buffer too small, %s\n", modemsg);
|
||||
error = -ENOKEY;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (mode)
|
||||
get_random_bytes(key_iv, MAXKEY+MAXIV);
|
||||
|
||||
len = crypto_tfm_alg_max_keysize(tfm);
|
||||
if (len > MAXKEY)
|
||||
len = MAXKEY;
|
||||
|
||||
if (crypto_cipher_setkey(tfm, key_iv, len)) {
|
||||
printk(KERN_ERR "swsusp: key setup failure, %s\n", modemsg);
|
||||
error = -EKEYREJECTED;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
len = crypto_tfm_alg_ivsize(tfm);
|
||||
|
||||
if (MAXIV < len) {
|
||||
printk(KERN_ERR "swsusp: iv buffer too small, %s\n", modemsg);
|
||||
error = -EOVERFLOW;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
crypto_cipher_set_iv(tfm, key_iv+MAXKEY, len);
|
||||
|
||||
*mem=(void *)tfm;
|
||||
|
||||
goto out;
|
||||
|
||||
fail: crypto_free_tfm(tfm);
|
||||
out: return error;
|
||||
}
|
||||
|
||||
static __inline__ void crypto_exit(void *mem)
|
||||
{
|
||||
crypto_free_tfm((struct crypto_tfm *)mem);
|
||||
}
|
||||
|
||||
static __inline__ int crypto_write(struct pbe *p, void *mem)
|
||||
{
|
||||
int error = 0;
|
||||
struct scatterlist src, dst;
|
||||
|
||||
src.page = virt_to_page(p->address);
|
||||
src.offset = 0;
|
||||
src.length = PAGE_SIZE;
|
||||
dst.page = virt_to_page((void *)&swsusp_header);
|
||||
dst.offset = 0;
|
||||
dst.length = PAGE_SIZE;
|
||||
|
||||
error = crypto_cipher_encrypt((struct crypto_tfm *)mem, &dst, &src,
|
||||
PAGE_SIZE);
|
||||
|
||||
if (!error)
|
||||
error = write_page((unsigned long)&swsusp_header,
|
||||
&(p->swap_address));
|
||||
return error;
|
||||
}
|
||||
|
||||
static __inline__ int crypto_read(struct pbe *p, void *mem)
|
||||
{
|
||||
int error = 0;
|
||||
struct scatterlist src, dst;
|
||||
|
||||
error = bio_read_page(swp_offset(p->swap_address), (void *)p->address);
|
||||
if (!error) {
|
||||
src.offset = 0;
|
||||
src.length = PAGE_SIZE;
|
||||
dst.offset = 0;
|
||||
dst.length = PAGE_SIZE;
|
||||
src.page = dst.page = virt_to_page((void *)p->address);
|
||||
|
||||
error = crypto_cipher_decrypt((struct crypto_tfm *)mem, &dst,
|
||||
&src, PAGE_SIZE);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
#else
|
||||
static __inline__ int crypto_init(int mode, void *mem)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __inline__ void crypto_exit(void *mem)
|
||||
{
|
||||
}
|
||||
|
||||
static __inline__ int crypto_write(struct pbe *p, void *mem)
|
||||
{
|
||||
return write_page(p->address, &(p->swap_address));
|
||||
}
|
||||
|
||||
static __inline__ int crypto_read(struct pbe *p, void *mem)
|
||||
{
|
||||
return bio_read_page(swp_offset(p->swap_address), (void *)p->address);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int mark_swapfiles(swp_entry_t prev)
|
||||
{
|
||||
int error;
|
||||
|
|
@ -140,6 +277,7 @@ static int mark_swapfiles(swp_entry_t prev)
|
|||
!memcmp("SWAPSPACE2",swsusp_header.sig, 10)) {
|
||||
memcpy(swsusp_header.orig_sig,swsusp_header.sig, 10);
|
||||
memcpy(swsusp_header.sig,SWSUSP_SIG, 10);
|
||||
memcpy(swsusp_header.key_iv, key_iv, MAXKEY+MAXIV);
|
||||
swsusp_header.swsusp_info = prev;
|
||||
error = rw_swap_page_sync(WRITE,
|
||||
swp_entry(root_swap, 0),
|
||||
|
|
@ -179,9 +317,9 @@ static int swsusp_swap_check(void) /* This is called before saving image */
|
|||
len=strlen(resume_file);
|
||||
root_swap = 0xFFFF;
|
||||
|
||||
swap_list_lock();
|
||||
spin_lock(&swap_lock);
|
||||
for (i=0; i<MAX_SWAPFILES; i++) {
|
||||
if (swap_info[i].flags == 0) {
|
||||
if (!(swap_info[i].flags & SWP_WRITEOK)) {
|
||||
swapfile_used[i]=SWAPFILE_UNUSED;
|
||||
} else {
|
||||
if (!len) {
|
||||
|
|
@ -202,7 +340,7 @@ static int swsusp_swap_check(void) /* This is called before saving image */
|
|||
}
|
||||
}
|
||||
}
|
||||
swap_list_unlock();
|
||||
spin_unlock(&swap_lock);
|
||||
return (root_swap != 0xffff) ? 0 : -ENODEV;
|
||||
}
|
||||
|
||||
|
|
@ -216,12 +354,12 @@ static void lock_swapdevices(void)
|
|||
{
|
||||
int i;
|
||||
|
||||
swap_list_lock();
|
||||
spin_lock(&swap_lock);
|
||||
for (i = 0; i< MAX_SWAPFILES; i++)
|
||||
if (swapfile_used[i] == SWAPFILE_IGNORED) {
|
||||
swap_info[i].flags ^= 0xFF;
|
||||
swap_info[i].flags ^= SWP_WRITEOK;
|
||||
}
|
||||
swap_list_unlock();
|
||||
spin_unlock(&swap_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -286,6 +424,10 @@ static int data_write(void)
|
|||
int error = 0, i = 0;
|
||||
unsigned int mod = nr_copy_pages / 100;
|
||||
struct pbe *p;
|
||||
void *tfm;
|
||||
|
||||
if ((error = crypto_init(1, &tfm)))
|
||||
return error;
|
||||
|
||||
if (!mod)
|
||||
mod = 1;
|
||||
|
|
@ -294,11 +436,14 @@ static int data_write(void)
|
|||
for_each_pbe (p, pagedir_nosave) {
|
||||
if (!(i%mod))
|
||||
printk( "\b\b\b\b%3d%%", i / mod );
|
||||
if ((error = write_page(p->address, &(p->swap_address))))
|
||||
if ((error = crypto_write(p, tfm))) {
|
||||
crypto_exit(tfm);
|
||||
return error;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
printk("\b\b\b\bdone\n");
|
||||
crypto_exit(tfm);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
@ -385,7 +530,6 @@ static int write_pagedir(void)
|
|||
* write_suspend_image - Write entire image and metadata.
|
||||
*
|
||||
*/
|
||||
|
||||
static int write_suspend_image(void)
|
||||
{
|
||||
int error;
|
||||
|
|
@ -400,6 +544,7 @@ static int write_suspend_image(void)
|
|||
if ((error = close_swap()))
|
||||
goto FreePagedir;
|
||||
Done:
|
||||
memset(key_iv, 0, MAXKEY+MAXIV);
|
||||
return error;
|
||||
FreePagedir:
|
||||
free_pagedir_entries();
|
||||
|
|
@ -591,18 +736,7 @@ static void copy_data_pages(void)
|
|||
|
||||
static int calc_nr(int nr_copy)
|
||||
{
|
||||
int extra = 0;
|
||||
int mod = !!(nr_copy % PBES_PER_PAGE);
|
||||
int diff = (nr_copy / PBES_PER_PAGE) + mod;
|
||||
|
||||
do {
|
||||
extra += diff;
|
||||
nr_copy += diff;
|
||||
mod = !!(nr_copy % PBES_PER_PAGE);
|
||||
diff = (nr_copy / PBES_PER_PAGE) + mod - extra;
|
||||
} while (diff > 0);
|
||||
|
||||
return nr_copy;
|
||||
return nr_copy + (nr_copy+PBES_PER_PAGE-2)/(PBES_PER_PAGE-1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -886,20 +1020,21 @@ int swsusp_suspend(void)
|
|||
* at resume time, and evil weirdness ensues.
|
||||
*/
|
||||
if ((error = device_power_down(PMSG_FREEZE))) {
|
||||
printk(KERN_ERR "Some devices failed to power down, aborting suspend\n");
|
||||
local_irq_enable();
|
||||
return error;
|
||||
}
|
||||
|
||||
if ((error = swsusp_swap_check())) {
|
||||
printk(KERN_ERR "swsusp: FATAL: cannot find swap device, try "
|
||||
"swapon -a!\n");
|
||||
printk(KERN_ERR "swsusp: cannot find swap device, try swapon -a.\n");
|
||||
device_power_up();
|
||||
local_irq_enable();
|
||||
return error;
|
||||
}
|
||||
|
||||
save_processor_state();
|
||||
if ((error = swsusp_arch_suspend()))
|
||||
printk("Error %d suspending\n", error);
|
||||
printk(KERN_ERR "Error %d suspending\n", error);
|
||||
/* Restore control flow magically appears here */
|
||||
restore_processor_state();
|
||||
BUG_ON (nr_copy_pages_check != nr_copy_pages);
|
||||
|
|
@ -924,6 +1059,7 @@ int swsusp_resume(void)
|
|||
BUG_ON(!error);
|
||||
restore_processor_state();
|
||||
restore_highmem();
|
||||
touch_softlockup_watchdog();
|
||||
device_power_up();
|
||||
local_irq_enable();
|
||||
return error;
|
||||
|
|
@ -1179,7 +1315,8 @@ static const char * sanity_check(void)
|
|||
if (strcmp(swsusp_info.uts.machine,system_utsname.machine))
|
||||
return "machine";
|
||||
#if 0
|
||||
if(swsusp_info.cpus != num_online_cpus())
|
||||
/* We can't use number of online CPUs when we use hotplug to remove them ;-))) */
|
||||
if (swsusp_info.cpus != num_possible_cpus())
|
||||
return "number of cpus";
|
||||
#endif
|
||||
return NULL;
|
||||
|
|
@ -1212,13 +1349,14 @@ static int check_sig(void)
|
|||
return error;
|
||||
if (!memcmp(SWSUSP_SIG, swsusp_header.sig, 10)) {
|
||||
memcpy(swsusp_header.sig, swsusp_header.orig_sig, 10);
|
||||
memcpy(key_iv, swsusp_header.key_iv, MAXKEY+MAXIV);
|
||||
memset(swsusp_header.key_iv, 0, MAXKEY+MAXIV);
|
||||
|
||||
/*
|
||||
* Reset swap signature now.
|
||||
*/
|
||||
error = bio_write_page(0, &swsusp_header);
|
||||
} else {
|
||||
printk(KERN_ERR "swsusp: Suspend partition has wrong signature?\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!error)
|
||||
|
|
@ -1239,6 +1377,10 @@ static int data_read(struct pbe *pblist)
|
|||
int error = 0;
|
||||
int i = 0;
|
||||
int mod = swsusp_info.image_pages / 100;
|
||||
void *tfm;
|
||||
|
||||
if ((error = crypto_init(0, &tfm)))
|
||||
return error;
|
||||
|
||||
if (!mod)
|
||||
mod = 1;
|
||||
|
|
@ -1250,14 +1392,15 @@ static int data_read(struct pbe *pblist)
|
|||
if (!(i % mod))
|
||||
printk("\b\b\b\b%3d%%", i / mod);
|
||||
|
||||
error = bio_read_page(swp_offset(p->swap_address),
|
||||
(void *)p->address);
|
||||
if (error)
|
||||
if ((error = crypto_read(p, tfm))) {
|
||||
crypto_exit(tfm);
|
||||
return error;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
printk("\b\b\b\bdone\n");
|
||||
crypto_exit(tfm);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
@ -1385,6 +1528,7 @@ int swsusp_read(void)
|
|||
|
||||
error = read_suspend_image();
|
||||
blkdev_put(resume_bdev);
|
||||
memset(key_iv, 0, MAXKEY+MAXIV);
|
||||
|
||||
if (!error)
|
||||
pr_debug("swsusp: Reading resume file was successful\n");
|
||||
|
|
|
|||
Loading…
Reference in a new issue