summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Larkin <mlarkin@cvs.openbsd.org>2011-07-11 03:30:33 +0000
committerMike Larkin <mlarkin@cvs.openbsd.org>2011-07-11 03:30:33 +0000
commit327054b12b2159c4ee15475bc999f4e1f4f1c13e (patch)
treef0c76386a2854baa62514769310c814625fdde82
parentb97e0a0488930c2f92fc845f40f67dcaee962660 (diff)
Add hibernate_read_block and fix a couple of typos in the previous commit.
-rw-r--r--sys/arch/i386/i386/hibernate_machdep.c12
-rw-r--r--sys/kern/subr_hibernate.c68
-rw-r--r--sys/sys/hibernate.h3
3 files changed, 76 insertions, 7 deletions
diff --git a/sys/arch/i386/i386/hibernate_machdep.c b/sys/arch/i386/i386/hibernate_machdep.c
index 3cc9899ebcd..f9b4ba73c5d 100644
--- a/sys/arch/i386/i386/hibernate_machdep.c
+++ b/sys/arch/i386/i386/hibernate_machdep.c
@@ -302,6 +302,7 @@ hibernate_populate_resume_pt(paddr_t image_start, paddr_t image_end)
* been set. This means that there can be no side effects once the
* write has started, and the write function itself can also have no
* side effects.
+ */
int
hibernate_write_image()
{
@@ -326,10 +327,11 @@ hibernate_write_image()
pmap_kenter_pa(HIBERNATE_IO_PAGE, HIBERNATE_IO_PAGE, VM_PROT_ALL);
pmap_kenter_pa(HIBERNATE_TEMP_PAGE, HIBERNATE_TEMP_PAGE,
VM_PROT_ALL);
- pmap_kenter_pa(HIBERNATE_ZLIB_SCRATCH, HIBERNATE_ZLIB_SCRATCH, VM_PROT_ALL);
+ pmap_kenter_pa(HIBERNATE_ZLIB_SCRATCH, HIBERNATE_ZLIB_SCRATCH,
+ VM_PROT_ALL);
/* Map the zlib allocation ranges */
- for(zlib_range = HIBERNATE_ZLIB_START; zlib < HIBERNATE_ZLIB_END;
+ for(zlib_range = HIBERNATE_ZLIB_START; zlib_range < HIBERNATE_ZLIB_END;
zlib_range += PAGE_SIZE) {
pmap_kenter_pa((vaddr_t)(zlib_range+i),
(paddr_t)(zlib_range+i),
@@ -338,8 +340,8 @@ hibernate_write_image()
/* Identity map the chunktable */
for(i=0; i < HIBERNATE_CHUNK_TABLE_SIZE; i += PAGE_SIZE) {
- pmap_kenter_pa((vaddr_t)(HIBERNATE_CHUNK_TABLE+i),
- (paddr_t)(HIBERNATE_CHUNK_TABLE+i),
+ pmap_kenter_pa((vaddr_t)(HIBERNATE_CHUNK_TABLE_START+i),
+ (paddr_t)(HIBERNATE_CHUNK_TABLE_START+i),
VM_PROT_ALL);
}
@@ -348,7 +350,7 @@ hibernate_write_image()
blkctr = hiber_info.image_offset;
hiber_info.chunk_ctr = 0;
offset = 0;
- chunks = (struct hibernate_disk_chunk *)HIBERNATE_CHUNK_TABLE;
+ chunks = (struct hibernate_disk_chunk *)HIBERNATE_CHUNK_TABLE_START;
/* Calculate the chunk regions */
for (i=0; i < hiber_info.nranges; i++) {
diff --git a/sys/kern/subr_hibernate.c b/sys/kern/subr_hibernate.c
index 1e01e618a8e..9e7b737c993 100644
--- a/sys/kern/subr_hibernate.c
+++ b/sys/kern/subr_hibernate.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_hibernate.c,v 1.12 2011/07/09 03:10:27 mlarkin Exp $ */
+/* $OpenBSD: subr_hibernate.c,v 1.13 2011/07/11 03:30:32 mlarkin Exp $ */
/*
* Copyright (c) 2011 Ariane van der Steldt <ariane@stack.nl>
@@ -24,6 +24,9 @@
#include <sys/systm.h>
#include <sys/disklabel.h>
#include <sys/conf.h>
+#include <sys/buf.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
#include <uvm/uvm.h>
#include <machine/hibernate.h>
@@ -850,3 +853,66 @@ hibernate_compare_signature(union hibernate_info *mine,
return (0);
}
+/*
+ * hibernate_read_block
+ *
+ * Reads read_size blocks from the hibernate device specified in
+ * hib_info at offset blkctr. Output is placed into the vaddr specified
+ * at dest.
+ *
+ * Separate offsets and pages are used to handle misaligned reads (reads
+ * that span a page boundary).
+ *
+ * blkctr specifies a relative offset (relative to the start of swap),
+ * not an absolute disk offset
+ *
+ */
+int
+hibernate_read_block(union hibernate_info *hib_info, daddr_t blkctr,
+ size_t read_size, vaddr_t dest)
+{
+ struct buf *bp;
+ struct bdevsw *bdsw;
+ int error;
+
+ bp = geteblk(read_size);
+ bdsw = &bdevsw[major(hib_info->device)];
+
+ error = (*bdsw->d_open)(hib_info->device, FREAD, S_IFCHR, curproc);
+ if (error) {
+ printf("hibernate_read_block open failed\n");
+ return (1);
+ }
+
+ bp->b_bcount = read_size;
+ bp->b_blkno = blkctr;
+ CLR(bp->b_flags, B_READ | B_WRITE | B_DONE);
+ SET(bp->b_flags, B_BUSY | B_READ | B_RAW);
+ bp->b_dev = hib_info->device;
+ bp->b_cylinder = 0;
+ (*bdsw->d_strategy)(bp);
+
+ error = biowait(bp);
+ if (error) {
+ printf("hibernate_read_block biowait failed %d\n", error);
+ error = (*bdsw->d_close)(hib_info->device, 0, S_IFCHR,
+ curproc);
+ if (error)
+ printf("hibernate_read_block error close failed\n");
+ return (1);
+ }
+
+ error = (*bdsw->d_close)(hib_info->device, FREAD, S_IFCHR, curproc);
+ if (error) {
+ printf("hibernate_read_block close failed\n");
+ return (1);
+ }
+
+ bcopy(bp->b_data, (caddr_t)dest, read_size);
+
+ bp->b_flags |= B_INVAL;
+ brelse(bp);
+
+ return (0);
+}
+
diff --git a/sys/sys/hibernate.h b/sys/sys/hibernate.h
index 6a4b7a4b15f..95c0fda28fe 100644
--- a/sys/sys/hibernate.h
+++ b/sys/sys/hibernate.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hibernate.h,v 1.11 2011/07/09 03:10:27 mlarkin Exp $ */
+/* $OpenBSD: hibernate.h,v 1.12 2011/07/11 03:30:32 mlarkin Exp $ */
/*
* Copyright (c) 2011 Ariane van der Steldt <ariane@stack.nl>
@@ -119,6 +119,7 @@ void hibernate_zlib_free(void *, void *);
void hibernate_inflate(paddr_t, paddr_t, size_t);
size_t hibernate_deflate(paddr_t, size_t *);
+int hibernate_read_block(union hibernate_info *, daddr_t, size_t, vaddr_t);
int hibernate_write_signature(union hibernate_info *);
int hibernate_clear_signature(void);
int hibernate_compare_signature(union hibernate_info *,