diff options
author | Mike Larkin <mlarkin@cvs.openbsd.org> | 2011-07-11 03:30:33 +0000 |
---|---|---|
committer | Mike Larkin <mlarkin@cvs.openbsd.org> | 2011-07-11 03:30:33 +0000 |
commit | 327054b12b2159c4ee15475bc999f4e1f4f1c13e (patch) | |
tree | f0c76386a2854baa62514769310c814625fdde82 | |
parent | b97e0a0488930c2f92fc845f40f67dcaee962660 (diff) |
Add hibernate_read_block and fix a couple of typos in the previous commit.
-rw-r--r-- | sys/arch/i386/i386/hibernate_machdep.c | 12 | ||||
-rw-r--r-- | sys/kern/subr_hibernate.c | 68 | ||||
-rw-r--r-- | sys/sys/hibernate.h | 3 |
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 *, |