[PATCH] swsusp: remove encryption
[powerpc.git] / kernel / power / swsusp.c
1 /*
2  * linux/kernel/power/swsusp.c
3  *
4  * This file provides code to write suspend image to swap and read it back.
5  *
6  * Copyright (C) 1998-2001 Gabor Kuti <seasons@fornax.hu>
7  * Copyright (C) 1998,2001-2005 Pavel Machek <pavel@suse.cz>
8  *
9  * This file is released under the GPLv2.
10  *
11  * I'd like to thank the following people for their work:
12  *
13  * Pavel Machek <pavel@ucw.cz>:
14  * Modifications, defectiveness pointing, being with me at the very beginning,
15  * suspend to swap space, stop all tasks. Port to 2.4.18-ac and 2.5.17.
16  *
17  * Steve Doddi <dirk@loth.demon.co.uk>:
18  * Support the possibility of hardware state restoring.
19  *
20  * Raph <grey.havens@earthling.net>:
21  * Support for preserving states of network devices and virtual console
22  * (including X and svgatextmode)
23  *
24  * Kurt Garloff <garloff@suse.de>:
25  * Straightened the critical function in order to prevent compilers from
26  * playing tricks with local variables.
27  *
28  * Andreas Mohr <a.mohr@mailto.de>
29  *
30  * Alex Badea <vampire@go.ro>:
31  * Fixed runaway init
32  *
33  * More state savers are welcome. Especially for the scsi layer...
34  *
35  * For TODOs,FIXMEs also look in Documentation/power/swsusp.txt
36  */
37
38 #include <linux/module.h>
39 #include <linux/mm.h>
40 #include <linux/suspend.h>
41 #include <linux/smp_lock.h>
42 #include <linux/file.h>
43 #include <linux/utsname.h>
44 #include <linux/version.h>
45 #include <linux/delay.h>
46 #include <linux/bitops.h>
47 #include <linux/spinlock.h>
48 #include <linux/genhd.h>
49 #include <linux/kernel.h>
50 #include <linux/major.h>
51 #include <linux/swap.h>
52 #include <linux/pm.h>
53 #include <linux/device.h>
54 #include <linux/buffer_head.h>
55 #include <linux/swapops.h>
56 #include <linux/bootmem.h>
57 #include <linux/syscalls.h>
58 #include <linux/highmem.h>
59 #include <linux/bio.h>
60
61 #include <asm/uaccess.h>
62 #include <asm/mmu_context.h>
63 #include <asm/pgtable.h>
64 #include <asm/tlbflush.h>
65 #include <asm/io.h>
66
67 #include "power.h"
68
69 #ifdef CONFIG_HIGHMEM
70 int save_highmem(void);
71 int restore_highmem(void);
72 #else
73 static int save_highmem(void) { return 0; }
74 static int restore_highmem(void) { return 0; }
75 #endif
76
77 extern char resume_file[];
78
79 /* Local variables that should not be affected by save */
80 unsigned int nr_copy_pages __nosavedata = 0;
81
82 /* Suspend pagedir is allocated before final copy, therefore it
83    must be freed after resume
84
85    Warning: this is even more evil than it seems. Pagedirs this file
86    talks about are completely different from page directories used by
87    MMU hardware.
88  */
89 suspend_pagedir_t *pagedir_nosave __nosavedata = NULL;
90
91 #define SWSUSP_SIG      "S1SUSPEND"
92
93 static struct swsusp_header {
94         char reserved[PAGE_SIZE - 20 - sizeof(swp_entry_t)];
95         swp_entry_t swsusp_info;
96         char    orig_sig[10];
97         char    sig[10];
98 } __attribute__((packed, aligned(PAGE_SIZE))) swsusp_header;
99
100 static struct swsusp_info swsusp_info;
101
102 /*
103  * Saving part...
104  */
105
106 /* We memorize in swapfile_used what swap devices are used for suspension */
107 #define SWAPFILE_UNUSED    0
108 #define SWAPFILE_SUSPEND   1    /* This is the suspending device */
109 #define SWAPFILE_IGNORED   2    /* Those are other swap devices ignored for suspension */
110
111 static unsigned short swapfile_used[MAX_SWAPFILES];
112 static unsigned short root_swap;
113
114 static int mark_swapfiles(swp_entry_t prev)
115 {
116         int error;
117
118         rw_swap_page_sync(READ,
119                           swp_entry(root_swap, 0),
120                           virt_to_page((unsigned long)&swsusp_header));
121         if (!memcmp("SWAP-SPACE",swsusp_header.sig, 10) ||
122             !memcmp("SWAPSPACE2",swsusp_header.sig, 10)) {
123                 memcpy(swsusp_header.orig_sig,swsusp_header.sig, 10);
124                 memcpy(swsusp_header.sig,SWSUSP_SIG, 10);
125                 swsusp_header.swsusp_info = prev;
126                 error = rw_swap_page_sync(WRITE,
127                                           swp_entry(root_swap, 0),
128                                           virt_to_page((unsigned long)
129                                                        &swsusp_header));
130         } else {
131                 pr_debug("swsusp: Partition is not swap space.\n");
132                 error = -ENODEV;
133         }
134         return error;
135 }
136
137 /*
138  * Check whether the swap device is the specified resume
139  * device, irrespective of whether they are specified by
140  * identical names.
141  *
142  * (Thus, device inode aliasing is allowed.  You can say /dev/hda4
143  * instead of /dev/ide/host0/bus0/target0/lun0/part4 [if using devfs]
144  * and they'll be considered the same device.  This is *necessary* for
145  * devfs, since the resume code can only recognize the form /dev/hda4,
146  * but the suspend code would see the long name.)
147  */
148 static int is_resume_device(const struct swap_info_struct *swap_info)
149 {
150         struct file *file = swap_info->swap_file;
151         struct inode *inode = file->f_dentry->d_inode;
152
153         return S_ISBLK(inode->i_mode) &&
154                 swsusp_resume_device == MKDEV(imajor(inode), iminor(inode));
155 }
156
157 static int swsusp_swap_check(void) /* This is called before saving image */
158 {
159         int i, len;
160
161         len=strlen(resume_file);
162         root_swap = 0xFFFF;
163
164         spin_lock(&swap_lock);
165         for (i=0; i<MAX_SWAPFILES; i++) {
166                 if (!(swap_info[i].flags & SWP_WRITEOK)) {
167                         swapfile_used[i]=SWAPFILE_UNUSED;
168                 } else {
169                         if (!len) {
170                                 printk(KERN_WARNING "resume= option should be used to set suspend device" );
171                                 if (root_swap == 0xFFFF) {
172                                         swapfile_used[i] = SWAPFILE_SUSPEND;
173                                         root_swap = i;
174                                 } else
175                                         swapfile_used[i] = SWAPFILE_IGNORED;
176                         } else {
177                                 /* we ignore all swap devices that are not the resume_file */
178                                 if (is_resume_device(&swap_info[i])) {
179                                         swapfile_used[i] = SWAPFILE_SUSPEND;
180                                         root_swap = i;
181                                 } else {
182                                         swapfile_used[i] = SWAPFILE_IGNORED;
183                                 }
184                         }
185                 }
186         }
187         spin_unlock(&swap_lock);
188         return (root_swap != 0xffff) ? 0 : -ENODEV;
189 }
190
191 /**
192  * This is called after saving image so modification
193  * will be lost after resume... and that's what we want.
194  * we make the device unusable. A new call to
195  * lock_swapdevices can unlock the devices.
196  */
197 static void lock_swapdevices(void)
198 {
199         int i;
200
201         spin_lock(&swap_lock);
202         for (i = 0; i< MAX_SWAPFILES; i++)
203                 if (swapfile_used[i] == SWAPFILE_IGNORED) {
204                         swap_info[i].flags ^= SWP_WRITEOK;
205                 }
206         spin_unlock(&swap_lock);
207 }
208
209 /**
210  *      write_page - Write one page to a fresh swap location.
211  *      @addr:  Address we're writing.
212  *      @loc:   Place to store the entry we used.
213  *
214  *      Allocate a new swap entry and 'sync' it. Note we discard -EIO
215  *      errors. That is an artifact left over from swsusp. It did not
216  *      check the return of rw_swap_page_sync() at all, since most pages
217  *      written back to swap would return -EIO.
218  *      This is a partial improvement, since we will at least return other
219  *      errors, though we need to eventually fix the damn code.
220  */
221 static int write_page(unsigned long addr, swp_entry_t *loc)
222 {
223         swp_entry_t entry;
224         int error = 0;
225
226         entry = get_swap_page();
227         if (swp_offset(entry) &&
228             swapfile_used[swp_type(entry)] == SWAPFILE_SUSPEND) {
229                 error = rw_swap_page_sync(WRITE, entry,
230                                           virt_to_page(addr));
231                 if (error == -EIO)
232                         error = 0;
233                 if (!error)
234                         *loc = entry;
235         } else
236                 error = -ENOSPC;
237         return error;
238 }
239
240 /**
241  *      data_free - Free the swap entries used by the saved image.
242  *
243  *      Walk the list of used swap entries and free each one.
244  *      This is only used for cleanup when suspend fails.
245  */
246 static void data_free(void)
247 {
248         swp_entry_t entry;
249         struct pbe *p;
250
251         for_each_pbe (p, pagedir_nosave) {
252                 entry = p->swap_address;
253                 if (entry.val)
254                         swap_free(entry);
255                 else
256                         break;
257         }
258 }
259
260 /**
261  *      data_write - Write saved image to swap.
262  *
263  *      Walk the list of pages in the image and sync each one to swap.
264  */
265 static int data_write(void)
266 {
267         int error = 0, i = 0;
268         unsigned int mod = nr_copy_pages / 100;
269         struct pbe *p;
270
271         if (!mod)
272                 mod = 1;
273
274         printk( "Writing data to swap (%d pages)...     ", nr_copy_pages );
275         for_each_pbe (p, pagedir_nosave) {
276                 if (!(i%mod))
277                         printk( "\b\b\b\b%3d%%", i / mod );
278                 if ((error = write_page(p->address, &p->swap_address)))
279                         return error;
280                 i++;
281         }
282         printk("\b\b\b\bdone\n");
283         return error;
284 }
285
286 static void dump_info(void)
287 {
288         pr_debug(" swsusp: Version: %u\n",swsusp_info.version_code);
289         pr_debug(" swsusp: Num Pages: %ld\n",swsusp_info.num_physpages);
290         pr_debug(" swsusp: UTS Sys: %s\n",swsusp_info.uts.sysname);
291         pr_debug(" swsusp: UTS Node: %s\n",swsusp_info.uts.nodename);
292         pr_debug(" swsusp: UTS Release: %s\n",swsusp_info.uts.release);
293         pr_debug(" swsusp: UTS Version: %s\n",swsusp_info.uts.version);
294         pr_debug(" swsusp: UTS Machine: %s\n",swsusp_info.uts.machine);
295         pr_debug(" swsusp: UTS Domain: %s\n",swsusp_info.uts.domainname);
296         pr_debug(" swsusp: CPUs: %d\n",swsusp_info.cpus);
297         pr_debug(" swsusp: Image: %ld Pages\n",swsusp_info.image_pages);
298         pr_debug(" swsusp: Pagedir: %ld Pages\n",swsusp_info.pagedir_pages);
299 }
300
301 static void init_header(void)
302 {
303         memset(&swsusp_info, 0, sizeof(swsusp_info));
304         swsusp_info.version_code = LINUX_VERSION_CODE;
305         swsusp_info.num_physpages = num_physpages;
306         memcpy(&swsusp_info.uts, &system_utsname, sizeof(system_utsname));
307
308         swsusp_info.suspend_pagedir = pagedir_nosave;
309         swsusp_info.cpus = num_online_cpus();
310         swsusp_info.image_pages = nr_copy_pages;
311 }
312
313 static int close_swap(void)
314 {
315         swp_entry_t entry;
316         int error;
317
318         dump_info();
319         error = write_page((unsigned long)&swsusp_info, &entry);
320         if (!error) {
321                 printk( "S" );
322                 error = mark_swapfiles(entry);
323                 printk( "|\n" );
324         }
325         return error;
326 }
327
328 /**
329  *      free_pagedir_entries - Free pages used by the page directory.
330  *
331  *      This is used during suspend for error recovery.
332  */
333
334 static void free_pagedir_entries(void)
335 {
336         int i;
337
338         for (i = 0; i < swsusp_info.pagedir_pages; i++)
339                 swap_free(swsusp_info.pagedir[i]);
340 }
341
342
343 /**
344  *      write_pagedir - Write the array of pages holding the page directory.
345  *      @last:  Last swap entry we write (needed for header).
346  */
347
348 static int write_pagedir(void)
349 {
350         int error = 0;
351         unsigned int n = 0;
352         struct pbe *pbe;
353
354         printk( "Writing pagedir...");
355         for_each_pb_page (pbe, pagedir_nosave) {
356                 if ((error = write_page((unsigned long)pbe, &swsusp_info.pagedir[n++])))
357                         return error;
358         }
359
360         swsusp_info.pagedir_pages = n;
361         printk("done (%u pages)\n", n);
362         return error;
363 }
364
365 /**
366  *      enough_swap - Make sure we have enough swap to save the image.
367  *
368  *      Returns TRUE or FALSE after checking the total amount of swap
369  *      space avaiable.
370  *
371  *      FIXME: si_swapinfo(&i) returns all swap devices information.
372  *      We should only consider resume_device.
373  */
374
375 static int enough_swap(unsigned int nr_pages)
376 {
377         struct sysinfo i;
378
379         si_swapinfo(&i);
380         pr_debug("swsusp: available swap: %lu pages\n", i.freeswap);
381         return i.freeswap > (nr_pages + PAGES_FOR_IO +
382                 (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
383 }
384
385 /**
386  *      write_suspend_image - Write entire image and metadata.
387  *
388  */
389 static int write_suspend_image(void)
390 {
391         int error;
392
393         if (!enough_swap(nr_copy_pages)) {
394                 printk(KERN_ERR "swsusp: Not enough free swap\n");
395                 return -ENOSPC;
396         }
397
398         init_header();
399         if ((error = data_write()))
400                 goto FreeData;
401
402         if ((error = write_pagedir()))
403                 goto FreePagedir;
404
405         if ((error = close_swap()))
406                 goto FreePagedir;
407  Done:
408         return error;
409  FreePagedir:
410         free_pagedir_entries();
411  FreeData:
412         data_free();
413         goto Done;
414 }
415
416 /* It is important _NOT_ to umount filesystems at this point. We want
417  * them synced (in case something goes wrong) but we DO not want to mark
418  * filesystem clean: it is not. (And it does not matter, if we resume
419  * correctly, we'll mark system clean, anyway.)
420  */
421 int swsusp_write(void)
422 {
423         int error;
424
425         if ((error = swsusp_swap_check())) {
426                 printk(KERN_ERR "swsusp: cannot find swap device, try swapon -a.\n");
427                 return error;
428         }
429         lock_swapdevices();
430         error = write_suspend_image();
431         /* This will unlock ignored swap devices since writing is finished */
432         lock_swapdevices();
433         return error;
434 }
435
436
437
438 int swsusp_suspend(void)
439 {
440         int error;
441
442         if ((error = arch_prepare_suspend()))
443                 return error;
444         local_irq_disable();
445         /* At this point, device_suspend() has been called, but *not*
446          * device_power_down(). We *must* device_power_down() now.
447          * Otherwise, drivers for some devices (e.g. interrupt controllers)
448          * become desynchronized with the actual state of the hardware
449          * at resume time, and evil weirdness ensues.
450          */
451         if ((error = device_power_down(PMSG_FREEZE))) {
452                 printk(KERN_ERR "Some devices failed to power down, aborting suspend\n");
453                 goto Enable_irqs;
454         }
455
456         if ((error = save_highmem())) {
457                 printk(KERN_ERR "swsusp: Not enough free pages for highmem\n");
458                 goto Restore_highmem;
459         }
460
461         save_processor_state();
462         if ((error = swsusp_arch_suspend()))
463                 printk(KERN_ERR "Error %d suspending\n", error);
464         /* Restore control flow magically appears here */
465         restore_processor_state();
466 Restore_highmem:
467         restore_highmem();
468         device_power_up();
469 Enable_irqs:
470         local_irq_enable();
471         return error;
472 }
473
474 int swsusp_resume(void)
475 {
476         int error;
477         local_irq_disable();
478         if (device_power_down(PMSG_FREEZE))
479                 printk(KERN_ERR "Some devices failed to power down, very bad\n");
480         /* We'll ignore saved state, but this gets preempt count (etc) right */
481         save_processor_state();
482         error = swsusp_arch_resume();
483         /* Code below is only ever reached in case of failure. Otherwise
484          * execution continues at place where swsusp_arch_suspend was called
485          */
486         BUG_ON(!error);
487         /* The only reason why swsusp_arch_resume() can fail is memory being
488          * very tight, so we have to free it as soon as we can to avoid
489          * subsequent failures
490          */
491         swsusp_free();
492         restore_processor_state();
493         restore_highmem();
494         touch_softlockup_watchdog();
495         device_power_up();
496         local_irq_enable();
497         return error;
498 }
499
500 /**
501  *      mark_unsafe_pages - mark the pages that cannot be used for storing
502  *      the image during resume, because they conflict with the pages that
503  *      had been used before suspend
504  */
505
506 static void mark_unsafe_pages(struct pbe *pblist)
507 {
508         struct zone *zone;
509         unsigned long zone_pfn;
510         struct pbe *p;
511
512         if (!pblist) /* a sanity check */
513                 return;
514
515         /* Clear page flags */
516         for_each_zone (zone) {
517                 for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
518                         if (pfn_valid(zone_pfn + zone->zone_start_pfn))
519                                 ClearPageNosaveFree(pfn_to_page(zone_pfn +
520                                         zone->zone_start_pfn));
521         }
522
523         /* Mark orig addresses */
524         for_each_pbe (p, pblist)
525                 SetPageNosaveFree(virt_to_page(p->orig_address));
526
527 }
528
529 static void copy_page_backup_list(struct pbe *dst, struct pbe *src)
530 {
531         /* We assume both lists contain the same number of elements */
532         while (src) {
533                 dst->orig_address = src->orig_address;
534                 dst->swap_address = src->swap_address;
535                 dst = dst->next;
536                 src = src->next;
537         }
538 }
539
540 /*
541  *      Using bio to read from swap.
542  *      This code requires a bit more work than just using buffer heads
543  *      but, it is the recommended way for 2.5/2.6.
544  *      The following are to signal the beginning and end of I/O. Bios
545  *      finish asynchronously, while we want them to happen synchronously.
546  *      A simple atomic_t, and a wait loop take care of this problem.
547  */
548
549 static atomic_t io_done = ATOMIC_INIT(0);
550
551 static int end_io(struct bio *bio, unsigned int num, int err)
552 {
553         if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
554                 panic("I/O error reading memory image");
555         atomic_set(&io_done, 0);
556         return 0;
557 }
558
559 static struct block_device *resume_bdev;
560
561 /**
562  *      submit - submit BIO request.
563  *      @rw:    READ or WRITE.
564  *      @off    physical offset of page.
565  *      @page:  page we're reading or writing.
566  *
567  *      Straight from the textbook - allocate and initialize the bio.
568  *      If we're writing, make sure the page is marked as dirty.
569  *      Then submit it and wait.
570  */
571
572 static int submit(int rw, pgoff_t page_off, void *page)
573 {
574         int error = 0;
575         struct bio *bio;
576
577         bio = bio_alloc(GFP_ATOMIC, 1);
578         if (!bio)
579                 return -ENOMEM;
580         bio->bi_sector = page_off * (PAGE_SIZE >> 9);
581         bio_get(bio);
582         bio->bi_bdev = resume_bdev;
583         bio->bi_end_io = end_io;
584
585         if (bio_add_page(bio, virt_to_page(page), PAGE_SIZE, 0) < PAGE_SIZE) {
586                 printk("swsusp: ERROR: adding page to bio at %ld\n",page_off);
587                 error = -EFAULT;
588                 goto Done;
589         }
590
591         if (rw == WRITE)
592                 bio_set_pages_dirty(bio);
593
594         atomic_set(&io_done, 1);
595         submit_bio(rw | (1 << BIO_RW_SYNC), bio);
596         while (atomic_read(&io_done))
597                 yield();
598
599  Done:
600         bio_put(bio);
601         return error;
602 }
603
604 static int bio_read_page(pgoff_t page_off, void *page)
605 {
606         return submit(READ, page_off, page);
607 }
608
609 static int bio_write_page(pgoff_t page_off, void *page)
610 {
611         return submit(WRITE, page_off, page);
612 }
613
614 /*
615  * Sanity check if this image makes sense with this kernel/swap context
616  * I really don't think that it's foolproof but more than nothing..
617  */
618
619 static const char *sanity_check(void)
620 {
621         dump_info();
622         if (swsusp_info.version_code != LINUX_VERSION_CODE)
623                 return "kernel version";
624         if (swsusp_info.num_physpages != num_physpages)
625                 return "memory size";
626         if (strcmp(swsusp_info.uts.sysname,system_utsname.sysname))
627                 return "system type";
628         if (strcmp(swsusp_info.uts.release,system_utsname.release))
629                 return "kernel release";
630         if (strcmp(swsusp_info.uts.version,system_utsname.version))
631                 return "version";
632         if (strcmp(swsusp_info.uts.machine,system_utsname.machine))
633                 return "machine";
634 #if 0
635         /* We can't use number of online CPUs when we use hotplug to remove them ;-))) */
636         if (swsusp_info.cpus != num_possible_cpus())
637                 return "number of cpus";
638 #endif
639         return NULL;
640 }
641
642
643 static int check_header(void)
644 {
645         const char *reason = NULL;
646         int error;
647
648         if ((error = bio_read_page(swp_offset(swsusp_header.swsusp_info), &swsusp_info)))
649                 return error;
650
651         /* Is this same machine? */
652         if ((reason = sanity_check())) {
653                 printk(KERN_ERR "swsusp: Resume mismatch: %s\n",reason);
654                 return -EPERM;
655         }
656         nr_copy_pages = swsusp_info.image_pages;
657         return error;
658 }
659
660 static int check_sig(void)
661 {
662         int error;
663
664         memset(&swsusp_header, 0, sizeof(swsusp_header));
665         if ((error = bio_read_page(0, &swsusp_header)))
666                 return error;
667         if (!memcmp(SWSUSP_SIG, swsusp_header.sig, 10)) {
668                 memcpy(swsusp_header.sig, swsusp_header.orig_sig, 10);
669
670                 /*
671                  * Reset swap signature now.
672                  */
673                 error = bio_write_page(0, &swsusp_header);
674         } else {
675                 return -EINVAL;
676         }
677         if (!error)
678                 pr_debug("swsusp: Signature found, resuming\n");
679         return error;
680 }
681
682 /**
683  *      data_read - Read image pages from swap.
684  *
685  *      You do not need to check for overlaps, check_pagedir()
686  *      already did that.
687  */
688
689 static int data_read(struct pbe *pblist)
690 {
691         struct pbe *p;
692         int error = 0;
693         int i = 0;
694         int mod = swsusp_info.image_pages / 100;
695
696         if (!mod)
697                 mod = 1;
698
699         printk("swsusp: Reading image data (%lu pages):     ",
700                         swsusp_info.image_pages);
701
702         for_each_pbe (p, pblist) {
703                 if (!(i % mod))
704                         printk("\b\b\b\b%3d%%", i / mod);
705
706                 if ((error = bio_read_page(swp_offset(p->swap_address),
707                                                 (void *)p->address)))
708                         return error;
709
710                 i++;
711         }
712         printk("\b\b\b\bdone\n");
713         return error;
714 }
715
716 /**
717  *      read_pagedir - Read page backup list pages from swap
718  */
719
720 static int read_pagedir(struct pbe *pblist)
721 {
722         struct pbe *pbpage, *p;
723         unsigned int i = 0;
724         int error;
725
726         if (!pblist)
727                 return -EFAULT;
728
729         printk("swsusp: Reading pagedir (%lu pages)\n",
730                         swsusp_info.pagedir_pages);
731
732         for_each_pb_page (pbpage, pblist) {
733                 unsigned long offset = swp_offset(swsusp_info.pagedir[i++]);
734
735                 error = -EFAULT;
736                 if (offset) {
737                         p = (pbpage + PB_PAGE_SKIP)->next;
738                         error = bio_read_page(offset, (void *)pbpage);
739                         (pbpage + PB_PAGE_SKIP)->next = p;
740                 }
741                 if (error)
742                         break;
743         }
744
745         if (!error)
746                 BUG_ON(i != swsusp_info.pagedir_pages);
747
748         return error;
749 }
750
751
752 static int check_suspend_image(void)
753 {
754         int error = 0;
755
756         if ((error = check_sig()))
757                 return error;
758
759         if ((error = check_header()))
760                 return error;
761
762         return 0;
763 }
764
765 static int read_suspend_image(void)
766 {
767         int error = 0;
768         struct pbe *p;
769
770         if (!(p = alloc_pagedir(nr_copy_pages, GFP_ATOMIC, 0)))
771                 return -ENOMEM;
772
773         if ((error = read_pagedir(p)))
774                 return error;
775         create_pbe_list(p, nr_copy_pages);
776         mark_unsafe_pages(p);
777         pagedir_nosave = alloc_pagedir(nr_copy_pages, GFP_ATOMIC, 1);
778         if (pagedir_nosave) {
779                 create_pbe_list(pagedir_nosave, nr_copy_pages);
780                 copy_page_backup_list(pagedir_nosave, p);
781         }
782         free_pagedir(p);
783         if (!pagedir_nosave)
784                 return -ENOMEM;
785
786         /* Allocate memory for the image and read the data from swap */
787
788         error = alloc_data_pages(pagedir_nosave, GFP_ATOMIC, 1);
789
790         if (!error)
791                 error = data_read(pagedir_nosave);
792
793         return error;
794 }
795
796 /**
797  *      swsusp_check - Check for saved image in swap
798  */
799
800 int swsusp_check(void)
801 {
802         int error;
803
804         resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ);
805         if (!IS_ERR(resume_bdev)) {
806                 set_blocksize(resume_bdev, PAGE_SIZE);
807                 error = check_suspend_image();
808                 if (error)
809                     blkdev_put(resume_bdev);
810         } else
811                 error = PTR_ERR(resume_bdev);
812
813         if (!error)
814                 pr_debug("swsusp: resume file found\n");
815         else
816                 pr_debug("swsusp: Error %d check for resume file\n", error);
817         return error;
818 }
819
820 /**
821  *      swsusp_read - Read saved image from swap.
822  */
823
824 int swsusp_read(void)
825 {
826         int error;
827
828         if (IS_ERR(resume_bdev)) {
829                 pr_debug("swsusp: block device not initialised\n");
830                 return PTR_ERR(resume_bdev);
831         }
832
833         error = read_suspend_image();
834         blkdev_put(resume_bdev);
835
836         if (!error)
837                 pr_debug("swsusp: Reading resume file was successful\n");
838         else
839                 pr_debug("swsusp: Error %d resuming\n", error);
840         return error;
841 }
842
843 /**
844  *      swsusp_close - close swap device.
845  */
846
847 void swsusp_close(void)
848 {
849         if (IS_ERR(resume_bdev)) {
850                 pr_debug("swsusp: block device not initialised\n");
851                 return;
852         }
853
854         blkdev_put(resume_bdev);
855 }