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 = { 69*143452f7SWarner Losh .dv_name = "md", 70*143452f7SWarner Losh .dv_type = DEVT_DISK, 71*143452f7SWarner Losh .dv_init = md_init, 72*143452f7SWarner Losh .dv_strategy = md_strategy, 73*143452f7SWarner Losh .dv_open = md_open, 74*143452f7SWarner Losh .dv_close = md_close, 75*143452f7SWarner Losh .dv_ioctl = noioctl, 76*143452f7SWarner Losh .dv_print = md_print, 77ca987d46SWarner Losh }; 78ca987d46SWarner Losh 79ca987d46SWarner Losh static int 80ca987d46SWarner Losh md_init(void) 81ca987d46SWarner Losh { 82ca987d46SWarner Losh 83ca987d46SWarner Losh return (0); 84ca987d46SWarner Losh } 85ca987d46SWarner Losh 86ca987d46SWarner Losh static int 87ca987d46SWarner Losh md_strategy(void *devdata, int rw, daddr_t blk, size_t size, 88ca987d46SWarner Losh char *buf, size_t *rsize) 89ca987d46SWarner Losh { 90ca987d46SWarner Losh struct devdesc *dev = (struct devdesc *)devdata; 91ca987d46SWarner Losh size_t ofs; 92ca987d46SWarner Losh 93ca987d46SWarner Losh if (dev->d_unit != 0) 94ca987d46SWarner Losh return (ENXIO); 95ca987d46SWarner Losh 96ca987d46SWarner Losh if (blk < 0 || blk >= (MD_IMAGE_SIZE / MD_BLOCK_SIZE)) 97ca987d46SWarner Losh return (EIO); 98ca987d46SWarner Losh 99ca987d46SWarner Losh if (size % MD_BLOCK_SIZE) 100ca987d46SWarner Losh return (EIO); 101ca987d46SWarner Losh 102ca987d46SWarner Losh ofs = blk * MD_BLOCK_SIZE; 103ca987d46SWarner Losh if ((ofs + size) > MD_IMAGE_SIZE) 104ca987d46SWarner Losh size = MD_IMAGE_SIZE - ofs; 105ca987d46SWarner Losh 106ca987d46SWarner Losh if (rsize != NULL) 107ca987d46SWarner Losh *rsize = size; 108ca987d46SWarner Losh 109ca987d46SWarner Losh switch (rw & F_MASK) { 110ca987d46SWarner Losh case F_READ: 111ca987d46SWarner Losh bcopy(md_image.start + ofs, buf, size); 112ca987d46SWarner Losh return (0); 113ca987d46SWarner Losh case F_WRITE: 114ca987d46SWarner Losh bcopy(buf, md_image.start + ofs, size); 115ca987d46SWarner Losh return (0); 116ca987d46SWarner Losh } 117ca987d46SWarner Losh 118ca987d46SWarner Losh return (ENODEV); 119ca987d46SWarner Losh } 120ca987d46SWarner Losh 121ca987d46SWarner Losh static int 122ca987d46SWarner Losh md_open(struct open_file *f, ...) 123ca987d46SWarner Losh { 124ca987d46SWarner Losh va_list ap; 125ca987d46SWarner Losh struct devdesc *dev; 126ca987d46SWarner Losh 127ca987d46SWarner Losh va_start(ap, f); 128ca987d46SWarner Losh dev = va_arg(ap, struct devdesc *); 129ca987d46SWarner Losh va_end(ap); 130ca987d46SWarner Losh 131ca987d46SWarner Losh if (dev->d_unit != 0) 132ca987d46SWarner Losh return (ENXIO); 133ca987d46SWarner Losh 134ca987d46SWarner Losh return (0); 135ca987d46SWarner Losh } 136ca987d46SWarner Losh 137ca987d46SWarner Losh static int 138ca987d46SWarner Losh md_close(struct open_file *f) 139ca987d46SWarner Losh { 140ca987d46SWarner Losh struct devdesc *dev; 141ca987d46SWarner Losh 142ca987d46SWarner Losh dev = (struct devdesc *)(f->f_devdata); 143ca987d46SWarner Losh return ((dev->d_unit != 0) ? ENXIO : 0); 144ca987d46SWarner Losh } 145ca987d46SWarner Losh 146ca987d46SWarner Losh static int 147ca987d46SWarner Losh md_print(int verbose) 148ca987d46SWarner Losh { 149ca987d46SWarner Losh 150ca987d46SWarner Losh printf("%s devices:", md_dev.dv_name); 151ca987d46SWarner Losh if (pager_output("\n") != 0) 152ca987d46SWarner Losh return (1); 153ca987d46SWarner Losh 154ca987d46SWarner Losh printf("MD (%u bytes)", MD_IMAGE_SIZE); 155ca987d46SWarner Losh return (pager_output("\n")); 156ca987d46SWarner Losh } 157