xref: /freebsd/stand/common/md.c (revision 3e15b01d)
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,
74e98f952cSWarner 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