1ca987d46SWarner Losh /*- 2ca987d46SWarner Losh * Copyright (c) 2009 Marcel Moolenaar 3ca987d46SWarner Losh * All rights reserved. 4ca987d46SWarner Losh * 5ca987d46SWarner Losh * Redistribution and use in source and binary forms, with or without 6ca987d46SWarner Losh * modification, are permitted provided that the following conditions 7ca987d46SWarner Losh * are met: 8ca987d46SWarner Losh * 1. Redistributions of source code must retain the above copyright 9ca987d46SWarner Losh * notice, this list of conditions and the following disclaimer. 10ca987d46SWarner Losh * 2. Redistributions in binary form must reproduce the above copyright 11ca987d46SWarner Losh * notice, this list of conditions and the following disclaimer in the 12ca987d46SWarner Losh * documentation and/or other materials provided with the distribution. 13ca987d46SWarner Losh * 14ca987d46SWarner Losh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15ca987d46SWarner Losh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16ca987d46SWarner Losh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17ca987d46SWarner Losh * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18ca987d46SWarner Losh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19ca987d46SWarner Losh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20ca987d46SWarner Losh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21ca987d46SWarner Losh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22ca987d46SWarner Losh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23ca987d46SWarner Losh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24ca987d46SWarner Losh * SUCH DAMAGE. 25ca987d46SWarner Losh */ 26ca987d46SWarner Losh 27ca987d46SWarner Losh #include <sys/cdefs.h> 28ca987d46SWarner Losh __FBSDID("$FreeBSD$"); 29ca987d46SWarner Losh 30ca987d46SWarner Losh #include <stand.h> 31ca987d46SWarner Losh #include <sys/param.h> 32ca987d46SWarner Losh #include <sys/endian.h> 33ca987d46SWarner Losh #include <sys/queue.h> 34ca987d46SWarner Losh #include <machine/stdarg.h> 35ca987d46SWarner Losh 36ca987d46SWarner Losh #include "bootstrap.h" 37ca987d46SWarner Losh 38ca987d46SWarner Losh #define MD_BLOCK_SIZE 512 39ca987d46SWarner Losh 40ca987d46SWarner Losh #ifndef MD_IMAGE_SIZE 41ca987d46SWarner Losh #error Must be compiled with MD_IMAGE_SIZE defined 42ca987d46SWarner Losh #endif 43ca987d46SWarner Losh #if (MD_IMAGE_SIZE == 0 || MD_IMAGE_SIZE % MD_BLOCK_SIZE) 44ca987d46SWarner Losh #error Image size must be a multiple of 512. 45ca987d46SWarner Losh #endif 46ca987d46SWarner Losh 47ca987d46SWarner Losh /* 48ca987d46SWarner Losh * Preloaded image gets put here. 49ca987d46SWarner Losh * Applications that patch the object with the image can determine 50ca987d46SWarner Losh * the size looking at the start and end markers (strings), 51ca987d46SWarner Losh * so we want them contiguous. 52ca987d46SWarner Losh */ 53ca987d46SWarner Losh static struct { 54ca987d46SWarner Losh u_char start[MD_IMAGE_SIZE]; 55ca987d46SWarner Losh u_char end[128]; 56ca987d46SWarner Losh } md_image = { 57ca987d46SWarner Losh .start = "MFS Filesystem goes here", 58ca987d46SWarner Losh .end = "MFS Filesystem had better STOP here", 59ca987d46SWarner Losh }; 60ca987d46SWarner Losh 61ca987d46SWarner Losh /* devsw I/F */ 62ca987d46SWarner Losh static int md_init(void); 63ca987d46SWarner Losh static int md_strategy(void *, int, daddr_t, size_t, char *, size_t *); 64ca987d46SWarner Losh static int md_open(struct open_file *, ...); 65ca987d46SWarner Losh static int md_close(struct open_file *); 66ca987d46SWarner Losh static int md_print(int); 67ca987d46SWarner Losh 68ca987d46SWarner Losh struct devsw md_dev = { 69143452f7SWarner Losh .dv_name = "md", 70143452f7SWarner Losh .dv_type = DEVT_DISK, 71143452f7SWarner Losh .dv_init = md_init, 72143452f7SWarner Losh .dv_strategy = md_strategy, 73143452f7SWarner Losh .dv_open = md_open, 74143452f7SWarner Losh .dv_close = md_close, 75143452f7SWarner Losh .dv_ioctl = noioctl, 76143452f7SWarner Losh .dv_print = md_print, 77*e98f952cSWarner Losh .dv_cleanup = nullsys, 78ca987d46SWarner Losh }; 79ca987d46SWarner Losh 80ca987d46SWarner Losh static int 81ca987d46SWarner Losh md_init(void) 82ca987d46SWarner Losh { 83ca987d46SWarner Losh 84ca987d46SWarner Losh return (0); 85ca987d46SWarner Losh } 86ca987d46SWarner Losh 87ca987d46SWarner Losh static int 88ca987d46SWarner Losh md_strategy(void *devdata, int rw, daddr_t blk, size_t size, 89ca987d46SWarner Losh char *buf, size_t *rsize) 90ca987d46SWarner Losh { 91ca987d46SWarner Losh struct devdesc *dev = (struct devdesc *)devdata; 92ca987d46SWarner Losh size_t ofs; 93ca987d46SWarner Losh 94ca987d46SWarner Losh if (dev->d_unit != 0) 95ca987d46SWarner Losh return (ENXIO); 96ca987d46SWarner Losh 97ca987d46SWarner Losh if (blk < 0 || blk >= (MD_IMAGE_SIZE / MD_BLOCK_SIZE)) 98ca987d46SWarner Losh return (EIO); 99ca987d46SWarner Losh 100ca987d46SWarner Losh if (size % MD_BLOCK_SIZE) 101ca987d46SWarner Losh return (EIO); 102ca987d46SWarner Losh 103ca987d46SWarner Losh ofs = blk * MD_BLOCK_SIZE; 104ca987d46SWarner Losh if ((ofs + size) > MD_IMAGE_SIZE) 105ca987d46SWarner Losh size = MD_IMAGE_SIZE - ofs; 106ca987d46SWarner Losh 107ca987d46SWarner Losh if (rsize != NULL) 108ca987d46SWarner Losh *rsize = size; 109ca987d46SWarner Losh 110ca987d46SWarner Losh switch (rw & F_MASK) { 111ca987d46SWarner Losh case F_READ: 112ca987d46SWarner Losh bcopy(md_image.start + ofs, buf, size); 113ca987d46SWarner Losh return (0); 114ca987d46SWarner Losh case F_WRITE: 115ca987d46SWarner Losh bcopy(buf, md_image.start + ofs, size); 116ca987d46SWarner Losh return (0); 117ca987d46SWarner Losh } 118ca987d46SWarner Losh 119ca987d46SWarner Losh return (ENODEV); 120ca987d46SWarner Losh } 121ca987d46SWarner Losh 122ca987d46SWarner Losh static int 123ca987d46SWarner Losh md_open(struct open_file *f, ...) 124ca987d46SWarner Losh { 125ca987d46SWarner Losh va_list ap; 126ca987d46SWarner Losh struct devdesc *dev; 127ca987d46SWarner Losh 128ca987d46SWarner Losh va_start(ap, f); 129ca987d46SWarner Losh dev = va_arg(ap, struct devdesc *); 130ca987d46SWarner Losh va_end(ap); 131ca987d46SWarner Losh 132ca987d46SWarner Losh if (dev->d_unit != 0) 133ca987d46SWarner Losh return (ENXIO); 134ca987d46SWarner Losh 135ca987d46SWarner Losh return (0); 136ca987d46SWarner Losh } 137ca987d46SWarner Losh 138ca987d46SWarner Losh static int 139ca987d46SWarner Losh md_close(struct open_file *f) 140ca987d46SWarner Losh { 141ca987d46SWarner Losh struct devdesc *dev; 142ca987d46SWarner Losh 143ca987d46SWarner Losh dev = (struct devdesc *)(f->f_devdata); 144ca987d46SWarner Losh return ((dev->d_unit != 0) ? ENXIO : 0); 145ca987d46SWarner Losh } 146ca987d46SWarner Losh 147ca987d46SWarner Losh static int 148ca987d46SWarner Losh md_print(int verbose) 149ca987d46SWarner Losh { 150ca987d46SWarner Losh 151ca987d46SWarner Losh printf("%s devices:", md_dev.dv_name); 152ca987d46SWarner Losh if (pager_output("\n") != 0) 153ca987d46SWarner Losh return (1); 154ca987d46SWarner Losh 155ca987d46SWarner Losh printf("MD (%u bytes)", MD_IMAGE_SIZE); 156ca987d46SWarner Losh return (pager_output("\n")); 157ca987d46SWarner Losh } 158