1200460Smarcel/*- 2200460Smarcel * Copyright (c) 2009 Marcel Moolenaar 3200460Smarcel * All rights reserved. 4200460Smarcel * 5200460Smarcel * Redistribution and use in source and binary forms, with or without 6200460Smarcel * modification, are permitted provided that the following conditions 7200460Smarcel * are met: 8200460Smarcel * 1. Redistributions of source code must retain the above copyright 9200460Smarcel * notice, this list of conditions and the following disclaimer. 10200460Smarcel * 2. Redistributions in binary form must reproduce the above copyright 11200460Smarcel * notice, this list of conditions and the following disclaimer in the 12200460Smarcel * documentation and/or other materials provided with the distribution. 13200460Smarcel * 14200460Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15200460Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16200460Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17200460Smarcel * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18200460Smarcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19200460Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20200460Smarcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21200460Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22200460Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23200460Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24200460Smarcel * SUCH DAMAGE. 25200460Smarcel */ 26200460Smarcel 27200460Smarcel#include <sys/cdefs.h> 28200460Smarcel__FBSDID("$FreeBSD$"); 29200460Smarcel 30200460Smarcel#include <sys/param.h> 31200460Smarcel#include <sys/endian.h> 32200460Smarcel#include <sys/queue.h> 33200460Smarcel#include <machine/stdarg.h> 34200460Smarcel#include <stand.h> 35200460Smarcel 36200460Smarcel#include "bootstrap.h" 37200460Smarcel 38200460Smarcel#define MD_BLOCK_SIZE 512 39200460Smarcel 40200460Smarcel#ifndef MD_IMAGE_SIZE 41200460Smarcel#error Must be compiled with MD_IMAGE_SIZE defined 42200460Smarcel#endif 43200460Smarcel#if (MD_IMAGE_SIZE == 0 || MD_IMAGE_SIZE % MD_BLOCK_SIZE) 44200460Smarcel#error Image size must be a multiple of 512. 45200460Smarcel#endif 46200460Smarcel 47200460Smarcel/* 48200460Smarcel * Preloaded image gets put here. 49200460Smarcel * Applications that patch the object with the image can determine 50200460Smarcel * the size looking at the start and end markers (strings), 51200460Smarcel * so we want them contiguous. 52200460Smarcel */ 53200460Smarcelstatic struct { 54200460Smarcel u_char start[MD_IMAGE_SIZE]; 55200460Smarcel u_char end[128]; 56200460Smarcel} md_image = { 57200460Smarcel .start = "MFS Filesystem goes here", 58200460Smarcel .end = "MFS Filesystem had better STOP here", 59200460Smarcel}; 60200460Smarcel 61200460Smarcel/* devsw I/F */ 62200460Smarcelstatic int md_init(void); 63200460Smarcelstatic int md_strategy(void *, int, daddr_t, size_t, char *, size_t *); 64200460Smarcelstatic int md_open(struct open_file *, ...); 65200460Smarcelstatic int md_close(struct open_file *); 66200460Smarcelstatic void md_print(int); 67200460Smarcel 68200460Smarcelstruct devsw md_dev = { 69200460Smarcel "md", 70200460Smarcel DEVT_DISK, 71200460Smarcel md_init, 72200460Smarcel md_strategy, 73200460Smarcel md_open, 74200460Smarcel md_close, 75200460Smarcel noioctl, 76200460Smarcel md_print 77200460Smarcel}; 78200460Smarcel 79200460Smarcelstatic int 80200460Smarcelmd_init(void) 81200460Smarcel{ 82200460Smarcel 83200460Smarcel return (0); 84200460Smarcel} 85200460Smarcel 86200460Smarcelstatic int 87200460Smarcelmd_strategy(void *devdata, int rw, daddr_t blk, size_t size, char *buf, 88200460Smarcel size_t *rsize) 89200460Smarcel{ 90200460Smarcel struct devdesc *dev = (struct devdesc *)devdata; 91200460Smarcel size_t ofs; 92200460Smarcel 93200460Smarcel if (dev->d_unit != 0) 94200460Smarcel return (ENXIO); 95200460Smarcel 96200460Smarcel if (blk < 0 || blk >= (MD_IMAGE_SIZE / MD_BLOCK_SIZE)) 97200460Smarcel return (EIO); 98200460Smarcel 99200460Smarcel if (size % MD_BLOCK_SIZE) 100200460Smarcel return (EIO); 101200460Smarcel 102200460Smarcel ofs = blk * MD_BLOCK_SIZE; 103200460Smarcel if ((ofs + size) > MD_IMAGE_SIZE) 104200460Smarcel size = MD_IMAGE_SIZE - ofs; 105200460Smarcel 106200460Smarcel if (rsize != 0) 107200460Smarcel *rsize = size; 108200460Smarcel 109200460Smarcel switch (rw) { 110200460Smarcel case F_READ: 111200460Smarcel bcopy(md_image.start + ofs, buf, size); 112200460Smarcel return (0); 113200460Smarcel case F_WRITE: 114200460Smarcel bcopy(buf, md_image.start + ofs, size); 115200460Smarcel return (0); 116200460Smarcel } 117200460Smarcel 118200460Smarcel return (ENODEV); 119200460Smarcel} 120200460Smarcel 121200460Smarcelstatic int 122200460Smarcelmd_open(struct open_file *f, ...) 123200460Smarcel{ 124200460Smarcel va_list ap; 125200460Smarcel struct devdesc *dev; 126200460Smarcel 127200460Smarcel va_start(ap, f); 128200460Smarcel dev = va_arg(ap, struct devdesc *); 129200460Smarcel va_end(ap); 130200460Smarcel 131200460Smarcel if (dev->d_unit != 0) 132200460Smarcel return (ENXIO); 133200460Smarcel 134200460Smarcel return (0); 135200460Smarcel} 136200460Smarcel 137200460Smarcelstatic int 138200460Smarcelmd_close(struct open_file *f) 139200460Smarcel{ 140200460Smarcel struct devdesc *dev; 141200460Smarcel 142200460Smarcel dev = (struct devdesc *)(f->f_devdata); 143200460Smarcel return ((dev->d_unit != 0) ? ENXIO : 0); 144200460Smarcel} 145200460Smarcel 146200460Smarcelstatic void 147200460Smarcelmd_print(int verbose) 148200460Smarcel{ 149200460Smarcel 150200460Smarcel printf("MD (%u bytes)\n", MD_IMAGE_SIZE); 151200460Smarcel} 152