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 <stand.h>
28ca987d46SWarner Losh #include <sys/param.h>
29ca987d46SWarner Losh #include <sys/endian.h>
30ca987d46SWarner Losh #include <sys/queue.h>
31ca987d46SWarner Losh #include <machine/stdarg.h>
32ca987d46SWarner Losh
33ca987d46SWarner Losh #include "bootstrap.h"
34ca987d46SWarner Losh
35ca987d46SWarner Losh #define MD_BLOCK_SIZE 512
36ca987d46SWarner Losh
37ca987d46SWarner Losh #ifndef MD_IMAGE_SIZE
38ca987d46SWarner Losh #error Must be compiled with MD_IMAGE_SIZE defined
39ca987d46SWarner Losh #endif
40ca987d46SWarner Losh #if (MD_IMAGE_SIZE == 0 || MD_IMAGE_SIZE % MD_BLOCK_SIZE)
41ca987d46SWarner Losh #error Image size must be a multiple of 512.
42ca987d46SWarner Losh #endif
43ca987d46SWarner Losh
44ca987d46SWarner Losh /*
45ca987d46SWarner Losh * Preloaded image gets put here.
46ca987d46SWarner Losh * Applications that patch the object with the image can determine
47ca987d46SWarner Losh * the size looking at the start and end markers (strings),
48ca987d46SWarner Losh * so we want them contiguous.
49ca987d46SWarner Losh */
50ca987d46SWarner Losh static struct {
51ca987d46SWarner Losh u_char start[MD_IMAGE_SIZE];
52ca987d46SWarner Losh u_char end[128];
53ca987d46SWarner Losh } md_image = {
54ca987d46SWarner Losh .start = "MFS Filesystem goes here",
55ca987d46SWarner Losh .end = "MFS Filesystem had better STOP here",
56ca987d46SWarner Losh };
57ca987d46SWarner Losh
58ca987d46SWarner Losh /* devsw I/F */
59ca987d46SWarner Losh static int md_init(void);
60ca987d46SWarner Losh static int md_strategy(void *, int, daddr_t, size_t, char *, size_t *);
61ca987d46SWarner Losh static int md_open(struct open_file *, ...);
62ca987d46SWarner Losh static int md_close(struct open_file *);
63ca987d46SWarner Losh static int md_print(int);
64ca987d46SWarner Losh
65ca987d46SWarner Losh struct devsw md_dev = {
66143452f7SWarner Losh .dv_name = "md",
67143452f7SWarner Losh .dv_type = DEVT_DISK,
68143452f7SWarner Losh .dv_init = md_init,
69143452f7SWarner Losh .dv_strategy = md_strategy,
70143452f7SWarner Losh .dv_open = md_open,
71143452f7SWarner Losh .dv_close = md_close,
72143452f7SWarner Losh .dv_ioctl = noioctl,
73143452f7SWarner Losh .dv_print = md_print,
74*e98f952cSWarner Losh .dv_cleanup = nullsys,
75ca987d46SWarner Losh };
76ca987d46SWarner Losh
77ca987d46SWarner Losh static int
md_init(void)78ca987d46SWarner Losh md_init(void)
79ca987d46SWarner Losh {
80ca987d46SWarner Losh
81ca987d46SWarner Losh return (0);
82ca987d46SWarner Losh }
83ca987d46SWarner Losh
84ca987d46SWarner Losh static int
md_strategy(void * devdata,int rw,daddr_t blk,size_t size,char * buf,size_t * rsize)85ca987d46SWarner Losh md_strategy(void *devdata, int rw, daddr_t blk, size_t size,
86ca987d46SWarner Losh char *buf, size_t *rsize)
87ca987d46SWarner Losh {
88ca987d46SWarner Losh struct devdesc *dev = (struct devdesc *)devdata;
89ca987d46SWarner Losh size_t ofs;
90ca987d46SWarner Losh
91ca987d46SWarner Losh if (dev->d_unit != 0)
92ca987d46SWarner Losh return (ENXIO);
93ca987d46SWarner Losh
94ca987d46SWarner Losh if (blk < 0 || blk >= (MD_IMAGE_SIZE / MD_BLOCK_SIZE))
95ca987d46SWarner Losh return (EIO);
96ca987d46SWarner Losh
97ca987d46SWarner Losh if (size % MD_BLOCK_SIZE)
98ca987d46SWarner Losh return (EIO);
99ca987d46SWarner Losh
100ca987d46SWarner Losh ofs = blk * MD_BLOCK_SIZE;
101ca987d46SWarner Losh if ((ofs + size) > MD_IMAGE_SIZE)
102ca987d46SWarner Losh size = MD_IMAGE_SIZE - ofs;
103ca987d46SWarner Losh
104ca987d46SWarner Losh if (rsize != NULL)
105ca987d46SWarner Losh *rsize = size;
106ca987d46SWarner Losh
107ca987d46SWarner Losh switch (rw & F_MASK) {
108ca987d46SWarner Losh case F_READ:
109ca987d46SWarner Losh bcopy(md_image.start + ofs, buf, size);
110ca987d46SWarner Losh return (0);
111ca987d46SWarner Losh case F_WRITE:
112ca987d46SWarner Losh bcopy(buf, md_image.start + ofs, size);
113ca987d46SWarner Losh return (0);
114ca987d46SWarner Losh }
115ca987d46SWarner Losh
116ca987d46SWarner Losh return (ENODEV);
117ca987d46SWarner Losh }
118ca987d46SWarner Losh
119ca987d46SWarner Losh static int
md_open(struct open_file * f,...)120ca987d46SWarner Losh md_open(struct open_file *f, ...)
121ca987d46SWarner Losh {
122ca987d46SWarner Losh va_list ap;
123ca987d46SWarner Losh struct devdesc *dev;
124ca987d46SWarner Losh
125ca987d46SWarner Losh va_start(ap, f);
126ca987d46SWarner Losh dev = va_arg(ap, struct devdesc *);
127ca987d46SWarner Losh va_end(ap);
128ca987d46SWarner Losh
129ca987d46SWarner Losh if (dev->d_unit != 0)
130ca987d46SWarner Losh return (ENXIO);
131ca987d46SWarner Losh
132ca987d46SWarner Losh return (0);
133ca987d46SWarner Losh }
134ca987d46SWarner Losh
135ca987d46SWarner Losh static int
md_close(struct open_file * f)136ca987d46SWarner Losh md_close(struct open_file *f)
137ca987d46SWarner Losh {
138ca987d46SWarner Losh struct devdesc *dev;
139ca987d46SWarner Losh
140ca987d46SWarner Losh dev = (struct devdesc *)(f->f_devdata);
141ca987d46SWarner Losh return ((dev->d_unit != 0) ? ENXIO : 0);
142ca987d46SWarner Losh }
143ca987d46SWarner Losh
144ca987d46SWarner Losh static int
md_print(int verbose)145ca987d46SWarner Losh md_print(int verbose)
146ca987d46SWarner Losh {
147ca987d46SWarner Losh
148ca987d46SWarner Losh printf("%s devices:", md_dev.dv_name);
149ca987d46SWarner Losh if (pager_output("\n") != 0)
150ca987d46SWarner Losh return (1);
151ca987d46SWarner Losh
152ca987d46SWarner Losh printf("MD (%u bytes)", MD_IMAGE_SIZE);
153ca987d46SWarner Losh return (pager_output("\n"));
154ca987d46SWarner Losh }
155